<AWT Dev> [9] Review Request: JDK-8029455 JLightweightFrame: support scaled painting

Anton V. Tarasov anton.tarasov at oracle.com
Thu Dec 12 08:06:37 PST 2013


[cc'ing to j2d]

On 12.12.2013 1:54, Jim Graham wrote:
>
>
> On 12/11/13 5:13 AM, Anton V. Tarasov wrote:
>> On 11.12.2013 13:14, Jim Graham wrote:
>>> With the new support for scaled BufferedImages we now have a situation
>>> where some images return their logical dimensions from
>>> getWidth/Height(null) and some return physical dimensions. That's a
>>> little dicey as the method now has two meanings depending on how the
>>> images were created.  We're sort of between a rock and a hard place in
>>> that BufferedImage objects have a historical context for how their
>>> values relate to the pixels you can access, but we also have a
>>> relationship between how the return values of
>>> getWidth/Height(observer) relate to the size the image is drawn on the
>>> screen.  Is this only ever done for the backing store objects?  Do we
>>> ever expose them to developers?
>>
>> Well, this is the question I was waiting for... The methods
>> getWidth/Height will continue to return the physical size of an image,
>> regardless of was it scaled or not. However, for a scaled image the
>> physical size, and so the returned values will be auto-scaled. This is
>> applicable to the following "factory" methods I've overriden:
>>
>> 1) BufferedImageGraphicsConfig.createCompatibleImage(...)
>> 2) CGLGraphicsConfig.createCompatibleImage(...)
>> 3) LWLightweightFramePeer.createImage(...)
>>
>> The 1st depend on the scale factor of the GC instance the method is
>> called on. The scale factor of BufferedImageGraphicsConfig is taken from
>> the BI instance passed to its ctor. So, this won't affect any third
>> party code, as the BI.scale field has a private access.
>>
>> The 2nd depend on the scale factor of the device, which is set either by
>> the platform or by me (in case when I set it to the default device in
>> CPlatformLWView.java). So, theoretically it is possible for a user to
>> call this method on a Retina display and get a scaled image.
>
> We are subtly changing the meaning of createCompatibleImage() in both of those circumstances.  
> It's hard to understand the impact of that subtle change.  It looks like this fix is targeted at 
> JDK9 so we have time to vet it, but my initial gut feel on this is that we are going to confuse 
> some developers here unless we create a special "createCompatibleImage()" method variant (with 
> perhaps a different name) that specifically requests an image with an appropriate scale.  If we 
> are then going to service those requests with BufferedImage return values then we add an 
> additional issue in that we have conflicting needs for the various methods on BI in that case.

I rather agree with you. Another problem is that we need a solution for jdk8u20 as well...

>
>> The 3rd depend on the scale factor taken from the JLightweightFrame
>> instance. This affects only the code run inside the JLF, however a user
>> is able to call this method (on any of a component from the JLF's
>> hierarchy) and get a scaled image.
>>
>> So, we have situations when a user might create a BufferedImage with w*h
>
> Are they specifically creating a BufferedImage, or an Image that happens to be an instance of BI 
> in most current cases?

Component.createImage(..) is currently used by Swing in only two cases: as a double buffer factory 
method (by JViewport and RepaintManager). The javadoc for the method says just that: "an Image for 
double buffering". I don't know if this method is used by a third party code... Still, it is public.

GraphicsConfiguration.createCompatibleImage(..) returns BufferedImage. It's used 1) as a fallback 
for a createCompatibleVolatileImage when acceleration is not supported 2) directly from a number of 
places: d&d, custom cursor, tray icon, printing, 2/3 more minor cases.

Again, I don't know what's the rating of these methods among developers...

>
>> size but get back an image with w*h*4 size (on a Retina display). And
>> this might be unexpected. However, this image will produce a "context"
>> with the same scale factor. A BufferedImageGraphicsConfig will be
>> created with the same scale (see its ctor), a BufImgSurfaceData will be
>> created with the same scale (see its getDefaultScale() method), and a
>> SunGraphics2D will be created with the same scale ("devScale =
>> sd.getDefaultScale();" in its ctor). In this case, all drawings into the
>> image will take the scale into account, and should be correct. The only
>> concern is the size of the image itself. At least, this is not
>> documented...
>
> My big worry here is that we currently have 2 consumers of BI.getWidth(null) - one group that 
> expects the answer to relate to layout, and another that expects the answer to relate to pixel 
> access.
>
> Here is where someone dons their "genius hat" and comes up with a creative solution that works for 
> both groups.  Mine is unfortunately at the cleaners right now and they don't know when they'll 
> have it done... :(
>
> But, I feel there is a good common ground to be found there once we wrap our heads around the 
> problem the right way (and with the right "genius hat").  Also, perhaps we need to engage the 
> 2d-dev list as well here, since the results will affect them as well?

Well, let's find that right way :)

Thanks,
Anton.

>
>
>             ...jim



More information about the awt-dev mailing list