<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