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

Jim Graham james.graham at oracle.com
Wed Dec 18 22:02:43 UTC 2013


Hi Anton,

I don't know enough about the overall architecture yet to be too 
specific about possible solutions at this point.  Here are some 
questions that I still don't know the answer to...

- I'm assuming that Swing gets its back buffer from the 
getOffscreenBuffer call because that was what you modified to return a 
HiDPI image.  When Swing calls it internally, does it ever leak that 
instance?  Could it use a different API to get that back buffer so that 
the public API doesn't change?

- The method returns Image.  If worse comes to worst then we could try 
to hide the identity of the BI that gets returned, but that would be an 
awkward wrapper object, so hopefully a different solution works.

- Do we need to provide "automatically scaled image buffers" to 
developers that request one?  I'm guessing that the standard practice 
for DB in Swing is that the Swing code manages the image used for the 
back buffer, but does the developer ever get involved in that process 
such that we need to have magically scaled images in their hands?

- My impression was that there is some code in Swing that allocates the 
backbuffer, tells the Swing tree of JComponents to render into it, then 
draws that image to the screen.  Logically it might look something like 
this:

backbuffer = createBackBuffer(w, h);
// ...
comp.paint(backbuffer.getGraphics());
// ...
screengraphics.drawImage(backbuffer, x, y, null);

(though those lines of code may be spread across a number of methods for 
all I know)

Instead if it did this:

backbuffer = createBackBuffer(w*scale, h*scale);
// backbuffer.getWidth,Height() return w*scale, h*scale, but we don't care
// ...
Graphics g = backbuffer.getGraphics();
g.scale(scale, scale);
comp.paint(g);
// ...
// this call forces the logical size of the image without any special
// processing or instance recognition in SG2D
screengraphics.drawImage(backbuffer, x, y, w, h, null);

then we don't need any fancy wrappers or anything.  This doesn't solve 
any "manual double buffering" that a developer would do, though, but it 
evades return values from public methods that have "mismatched 
BufferedImage objects"...

			...jim

On 12/18/13 1:25 AM, Anton V. Tarasov wrote:
> Hi Jim,
>
> Thanks for noticing (sorry, but I simply forgot to check we don't export
> the buffer...) What can we do about that? I have the following thoughts:
>
> 1) We can warn developers to be ready for a HiDPI raster when they call
> that method under the following conditions: 1) the interop mode, 2)
> MacOSX 3) a Retina display.
> 2) In case the method is called, we can create a "shadow  buffer" and
> start to sync it with the main buffer. The main buffer will be scaled to
> the shadow buffer on every repaint cycle.
> 3) We can introduce an internal property which will switch on/off the
> 2nd scenario. For instance, a developer may ask for the buffer and don't
> bother about its hidpi raster.
>
> Yes, I understand the solutions are far from perfect, but please take
> into account, the interop is a special mode where we (and developers)
> should be ready for compromises...
>
> What do you think? Do you have any better solutions in mind?
>
> Thanks,
> Anton.
>
>
> On 18.12.2013 5:03, Jim Graham wrote:
>> Hi Anton,
>>
>> javax.swing.RepaintManager.getOffscreenBuffer is a public method that
>> can now return one of the new HiDPI offscreen images which is a
>> subclass of BufferedImage.  This was what I was worried about in terms
>> of one of these internal double buffers leaking to developer code.  If
>> they test the image using instanceof they will see that it is a
>> BufferdImage and they may try to dig out the raster and get confused...
>>
>>             ...jim
>>
>> On 12/17/13 10:21 AM, Anton V. Tarasov wrote:
>>> Hi all,
>>>
>>> Please look at the new version:
>>>
>>> http://cr.openjdk.java.net/~ant/JDK-8029455/webrev.2
>>>
>>> It contains the following changes:
>>>
>>> - All the scale related stuff is moved to the new class:
>>> OffScreenHiDPIImage.java
>>>
>>> - JViewport and RepaintManager no longer cache buffers.
>>>
>>> - JLightweightFrame has new method: createHiDPIImage(w, h).
>>>
>>> - JViewport, RepaintManager and AbstractRegionPainter goes the new path
>>> to create a HiDPI buffered image.
>>>
>>> - A new internal property is added: "swing.jlf.hidpiImageEnabled". False
>>> by default. It makes JLF.createImage(w, h) forward the call to
>>> JLF.createHiDPIImage(w, h). This can be used by a third party code in
>>> case it creates a buffered image via Component.createImage(w, h) and
>>> uses the image so that it can benefit from being a HiDPI image on a
>>> Retina display.
>>>
>>> For instance, SwingSet2 has an animating Bezier curve demo. Switching
>>> the property on makes the curve auto scale smoothly. Please, look at the
>>> screenshots:
>>>
>>> -- http://cr.openjdk.java.net/~ant/JDK-8029455/RoughtCurve.png
>>> -- http://cr.openjdk.java.net/~ant/JDK-8029455/SmoothCurve.png
>>>
>>> - SunGraphics2D now draws a HiDPI buffered image the same way it draws a
>>> VolatileImage.
>>>
>>> - I've removed the copyArea() method from the BufImgSurfaceData, and
>>> modified the original version. The only question I have is: do I need to
>>> check for "instanceof OffScreenHiDPIImage.SurfaceData" in case when
>>> "transformState == TRANSFORM_TRANSLATESCALE"? If this method is invoked
>>> with some other SD, and the transform is SCALE, will it do the job with
>>> the coordinates conversion done?
>>>
>>> - I've left the new methods in FramePeer default... May yet we implement
>>> them in other peers when we really need it?
>>>
>>> - CPlatformLWWindow.getGraphicsDevice() checks for an intersection +
>>> scale. This heuristic actually may fail when a Window is moved b/w three
>>> or four displays so that it intersects them all at some time. JFX will
>>> set a new scale factor in between and AWT may pick up a wrong device. I
>>> don't know any simple solution for that. For two monitors this will
>>> work.
>>>
>>> Thanks,
>>> Anton.
>



More information about the 2d-dev mailing list