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

Anton V. Tarasov anton.tarasov at oracle.com
Wed Dec 18 08:55:27 UTC 2013


Hi Sergey,

On 17.12.2013 23:38, Sergey Bylokhov wrote:
> Hi, Anton.
> Since OffScreenHiDPIImage looks similar to VolatileImage. Why we cannot use VolatileImage inside 
> Swing everywhere?

How Swing can use a VolatileImage when "swing.volatileImageBufferEnabled=false" is set? Could you 
please clarify your question?

Why there's the need to support that option is because of the SwingNode issue: 
https://javafx-jira.kenai.com/browse/RT-30035.

>
> What happens if the graphicsConfig for the particular offscreen image will be 
> changed/remoed/disposed? I suppose Volatile should became invalid in this case.

If you are asking about the OffScreenHiDPIImage.VolatileImage, then as I can see, we can rely on the 
VolatileSurfaceManager.validate(..) method. At the worst case, it will call the getBackupImage() 
which is overriden to return a new HiDPI buffer.

Also, I can't see any difference b/w how it behaved before, except for the getBackupImage call...

>
> CPlatformLWWindow :
> Why  did you check scale when you try to find a necessary GraphicsDevice?

When a Window is crossing the borders of two screens, FX switches to a new screen somewhere between 
and reports the scale factor change. At that moment the getGraphicsDevice is called and it finds the 
Window intersecting both the screens. However, as we know the scale factor has changed (otherwise, 
the method wouldn't be called) then we know the two devices have different scales, so we pick up the 
right device by additionally comparing the scale.

> Why not use the one correct device where the peer is located? Probably this code can be moved to 
> the PlatformWindow interface?

There's no a platform window for JLF, as I said. In the future, when (and if) we solve the problem 
with modality/z-order, JLF will be able to get the host window ID. But now it can't...

Also, why I think current approach is acceptable is because of the following:

- the configuration with three or four displays, when they are connected so that a Window can cross 
all of them at a time is a rare case
- it's still possible to move a Window to either of the screens only involving two of them when a 
border is crossed (as a workaround)
- even if a wrong device is picked up, it will work as JLF only needs its scale factor (so, the 
impact of the wrong behaviour is zero)

>
> FramePeer:
> Do we realy need notifyScaleFactorChanged? Probably notification about replacing GC is better? In 
> this case it should notify all listeners that GC was changed(as a result recreated all buffers). 
> Volatile handle this automatically?

But this still doesn't solve the problem I've described above... Until we have a platform Window ID. 
When (and if) we have it, the existing code can be easily adopted to it. The 
notifyScaleFactorChanged call will tell JLF that it should 1) just scale the buffer appropriately, 
or 2) ask for the the host window ID and match it to the device, thus pleasing the AWT machinary. 
The 2dn is just an implementation detail, which I think should not be exposed on the API level (via 
bringing there "screen" or "device" notions).

>
> I suppose you disable volatile buffer in repaint manager. Why?

If you mean the property: "swing.volatileImageBufferEnabled=false", then yes. The reason is the 
issue I've referred above: https://javafx-jira.kenai.com/browse/RT-30035.

>
> Note that we have a bug on Swing+retina+scroll, when we use volatiles as a buffer, I am not sure 
> what we will get in case of BI.
> https://bugs.openjdk.java.net/browse/JDK-8029253

Does switching off volatile makes any difference? I suppose SwingNode will experience the same 
slowness with "large text" scrolling. However, currently with volatile on, it performs badly even 
with a simple scroll (and not only with scroll, but with text typing as well). With buffered images, 
the perceived performance is quite close to a standalone Swing.

Thanks,
Anton.

>
> On 17.12.2013 22:21, 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