JDK-8127874 : SceneBuilder is out of sync with the native OS window size while resizing.
  • Type: Bug
  • Component: javafx
  • Sub-Component: graphics
  • Affected Version: fx2.0.2,fx2.0.3,fx2.1
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2012-02-01
  • Updated: 2015-06-17
  • Resolved: 2013-07-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
SceneBuilder looks terrible while being resized.

To reproduce launch SceneBuilder and resize the window quickly.
Comments
Verified in SB 2.0-b91 with cobundled JDK in Linux and MacOS
30-12-2013

This has been fixed for a while.
10-07-2013

The fix for Mac has been pushed. Investigating Window (more) and Linux ...
28-02-2013

+1 on the latest version of the patch. As Steve mentioned, we would like a property to disable it.
28-02-2013

I no longer see the popup / hover problems. So one of the earlier fixes has also fixed that.
28-02-2013

The latest patches disable live resize for Applets and wait in the UI thread rather than use doPriv(). Felipe was able to run the applet cases and they work for him. This leaves only the popup / hovers problems that you saw such as HelloMenuButton that I cannot recreate.
28-02-2013

I checked the log file for SwingInterop and there is no exception. However, it isn't a regression. I can reproduce the SwingInterop garbage without your patch. The Ensemble slowness is a regression. I suspect it is because we are now drawing for every single resize event, whereas the current system will naturally collapse them (since we don't schedule a pulse if one is already running).
27-02-2013

Resize of Ensemble was very slow and bad for Felipe too. The SwingInterop is drawing garbage so there is likely an exception in the log file.
27-02-2013

The exceptions are gone and all applets run for me. I'm getting some very strange resize behavior in the browser. The resize lags very badly when running Ensemble (if I resize the browser window). Additionally, SwingInterop draws garbage wehn resizing the page with CMD + and CMD - keys. See attached SwingInterop.png file.
27-02-2013

Please try the latest patch an confirm that applets run. After this, the only remaining mystery shoud be popup / hover cases fail (ie. HelloMenuButton).
27-02-2013

Adding this patch to steve last patch made all applets work for me: dhcp-santaclara22-2fl-west-10-132-185-141:rt felipe$ hg diff decora-prism-ps/src/com/sun/scenario/effect/impl/prism/ps/PPSRenderer.java diff -r ebae2fca2dec decora-prism-ps/src/com/sun/scenario/effect/impl/prism/ps/PPSRenderer.java --- a/decora-prism-ps/src/com/sun/scenario/effect/impl/prism/ps/PPSRenderer.java Tue Feb 26 13:54:06 2013 -0800 +++ b/decora-prism-ps/src/com/sun/scenario/effect/impl/prism/ps/PPSRenderer.java Tue Feb 26 16:59:39 2013 -0800 @@ -180,12 +180,22 @@ prismTex.update(img); } - public Shader createShader(String name, + public Shader createShader(final String name, Map<String, Integer> samplers, Map<String, Integer> params, boolean isPixcoordUsed) { - InputStream pscode = shaderSource.loadSource(name); + +// InputStream pscode = shaderSource.loadSource(name); + InputStream pscode = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction<InputStream>() { + public InputStream run() { + return shaderSource.loadSource(name); + } + } + ); + + System.out.println("***** create shader " + name + " stream " + pscode); int maxTexCoordIndex = samplers.keySet().size()-1; ShaderFactory factory = (ShaderFactory) GraphicsPipeline.getPipeline().getResourceFactory(screen);
27-02-2013

I tried Steve's lastest patch, which avoids live resize in this case: if (PlatformUtil.isMac() && w != null && w.isVisible()) { collector.liveRepaintRenderJob(scene); } I tested the applet in here http://jfx.us.oracle.com/hudson/job/8.0-graphics-scrum/label=macosx-universal-30/lastSuccessfulBuild/artifact/artifacts/apps/ga-samples/ the only that failed was StopWatch.html where it only draws the background. It seems the code is missing another "doPriv" somewhere.. this is the stack java.lang.NullPointerException �� ��at java.io.Reader.<init>(Reader.java:78) �� ��at java.io.InputStreamReader.<init>(InputStreamReader.java:72) �� ��at com.sun.prism.es2.ES2Shader.readStreamIntoString(ES2Shader.java:167) �� ��at com.sun.prism.es2.ES2Shader.createFromSource(ES2Shader.java:126) �� ��at com.sun.prism.es2.ES2ResourceFactory.createShader(ES2ResourceFactory.java:157) �� ��at com.sun.scenario.effect.impl.prism.ps.PPSRenderer.createShader(PPSRenderer.java:192) �� ��at com.sun.scenario.effect.impl.prism.ps.PPSLinearConvolvePeer.createShader(PPSLinearConvolvePeer.java:110) �� ��at com.sun.scenario.effect.impl.prism.ps.PPSOneSamplerPeer.filterImpl(PPSOneSamplerPeer.java:89) �� ��at com.sun.scenario.effect.impl.prism.ps.PPSEffectPeer.filter(PPSEffectPeer.java:51) �� ��at com.sun.scenario.effect.impl.state.LinearConvolveKernel.filterImageDatas(LinearConvolveKernel.java:403) �� ��at com.sun.scenario.effect.GaussianBlur.filterImageDatas(GaussianBlur.java:171) �� ��at com.sun.scenario.effect.FilterEffect.filter(FilterEffect.java:178) �� ��at com.sun.scenario.effect.impl.prism.PrEffectHelper.render(PrEffectHelper.java:164) �� ��at com.sun.javafx.sg.prism.NGNode$EffectFilter.render(NGNode.java:958) �� ��at com.sun.javafx.sg.prism.NGNode.renderEffect(NGNode.java:717) �� ��at com.sun.javafx.sg.prism.NGNode.renderForClip(NGNode.java:647) �� ��at com.sun.javafx.sg.prism.NGNode.renderClip(NGNode.java:617) �� ��at com.sun.javafx.sg.prism.NGNode.renderOpacity(NGNode.java:668) �� ��at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:420) �� ��at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:69) �� ��at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1278) �� ��at com.sun.javafx.sg.prism.NGGroup.renderChildren(NGGroup.java:242) �� ��at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:208) �� ��at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:428) �� ��at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:69) �� ��at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1278) �� ��at com.sun.javafx.sg.prism.NGGroup.renderChildren(NGGroup.java:242) �� ��at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:208) �� ��at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:428) �� ��at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:69) �� ��at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1278) �� ��at com.sun.javafx.sg.prism.NGGroup.renderChildren(NGGroup.java:242) �� ��at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:208) �� ��at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:428) �� ��at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:69) �� ��at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1278) �� ��at com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:119) �� ��at com.sun.javafx.tk.quantum.AbstractPainter.paintImpl(AbstractPainter.java:221) �� ��at com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:92) �� ��at com.sun.javafx.tk.quantum.PaintCollector.liveRepaintRenderJob(PaintCollector.java:334)
27-02-2013

The horror screen shots that you attached should all be caused by the assertion. Please reapply the patch and let me know if they have gone away.
26-02-2013

Sigh ... yes of course you get the assertion error. The code was lost in the move to open source.
26-02-2013

Yes, I can instrument the code with some print statements. Will post results.
26-02-2013

I was thinking more of using an existing flag to mean "ignore live resize" something like "window has not yet been repainted". Btw, I still get the assertion errors, always from startup. I also see rendering artifacts with a couple of the test apps (see attached screenshots).
26-02-2013

The log with the assertions is: run-many-2013-02-26.log The first assertion error is in closing a full-screen window. The rest come from Window.show.
26-02-2013

Can you be more specific about "ready to go"? What isn't ready and why? I hate the idea of having a flag that says "ignore live resize" then flipping it on/off. I suppose it could be done around show() but I would rather understand why we are failing in case there is another condition like this in the code.
26-02-2013

It seems our comments overlapped somehow. Will investigate.
26-02-2013

... ok not a break but a print, unless you can magically debug in a browser.
26-02-2013

> 1) I cannot make Ensemble in a browser fail (I am only able to run as JNLP). Yes, I can't debug this. I don't want to guess at the problem. It is most likely a zero size resize but I can't know. Can you put a break in liveRepaintRenderJob() and see what is going on?
26-02-2013

It seems that the problem in this case is that we are running a pulse before we are really ready to do it. Maybe a solution to this problem, and the problem of having to add extra doPrivileged calls is to not run a live resize while the stage is being initialized? Note that the call originates from Windows.show(). Do you know if that was also the case for the use case that required the doPriv?
26-02-2013

I still get the Ensemble exception. com.sun.javafx.geom.transform.SingularMatrixException at com.sun.javafx.geom.transform.GeneralTransform3D.invert(GeneralTransform3D.java:389) at com.sun.javafx.geom.transform.GeneralTransform3D.invert(GeneralTransform3D.java:366) at com.sun.prism.camera.PrismPerspectiveCameraImpl.computeProjection(PrismPerspectiveCameraImpl.java:79) at com.sun.prism.camera.PrismCameraImpl.validate(PrismCameraImpl.java:193) at com.sun.prism.camera.PrismCameraImpl.getScreenProjViewTx(PrismCameraImpl.java:174) at com.sun.javafx.sg.prism.NGCamera.getScreenProjViewTx(NGCamera.java:86) at javafx.scene.Camera.computeProjViewTx(Camera.java:185) at javafx.scene.Scene.snapshotCameraParameters(Scene.java:2089) at javafx.scene.Scene.access$3000(Scene.java:183) at javafx.scene.Scene$ScenePulseListener.synchronizeSceneNodes(Scene.java:2152) at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2268) at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:351) at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:529) at com.sun.javafx.tk.quantum.PaintCollector.liveRepaintRenderJob(PaintCollector.java:332) at com.sun.javafx.tk.quantum.GlassViewEventHandler$ViewEventNotification.run(GlassViewEventHandler.java:660) at com.sun.javafx.tk.quantum.GlassViewEventHandler$ViewEventNotification.run(GlassViewEventHandler.java:631) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleViewEvent(GlassViewEventHandler.java:688) at com.sun.glass.ui.View.handleViewEvent(View.java:503) at com.sun.glass.ui.View.notifyResize(View.java:820) at com.sun.glass.ui.mac.MacWindow._setView(Native Method) at com.sun.glass.ui.Window.setView(Window.java:354) at com.sun.javafx.tk.quantum.WindowStage.setScene(WindowStage.java:205) at javafx.stage.Window$10.invalidated(Window.java:720) at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:107) at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:141) at javafx.stage.Window.setShowing(Window.java:784) at javafx.stage.Window.show(Window.java:799) at javafx.stage.Stage.show(Stage.java:242) at ensemble.Ensemble2.start(Ensemble2.java:422) at com.sun.javafx.applet.FXApplet2$1.run(FXApplet2.java:132) at com.sun.javafx.application.PlatformImpl$5$1.run(PlatformImpl.java:223) at com.sun.javafx.application.PlatformImpl$5$1.run(PlatformImpl.java:220) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:220) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:94)
26-02-2013

I have built with your latest patch, and am ready to test. Will post results here.
26-02-2013

Kevin, please test the latest patch. 1) I cannot make Ensemble in a browser fail (I am only able to run as JNLP). 2) I cannot make popup / hover cases fail (ie. HelloMenuButton) We need to get this code in sooner rather than later in order to allow time to test for 8.0. Felipe, can you recreate the problems that Kevin is seeing?
25-02-2013

1) I can confirm that using doPriv() where the shader is loaded fixes the problem. 2) I cannot run Ensemble as an applet so I can't see the Ensemble error (I can run as JNLP) 3) I cannot make HelloMenuButton or any of the popup / hover help examples fail.
22-02-2013

Any idea why the shader can't be loaded for BouncingBalls when running in resize? basic: Applet initialized basic: Starting applet basic: completed perf rollup basic: Applet made visible basic: Applet started basic: Told clients applet is started basic: JNLP2ClassLoader.findClass: balls.BallsScreen: try again .. basic: JNLP2ClassLoader.findClass: balls.component.InfoPanel: try again .. basic: JNLP2ClassLoader.findClass: balls.component.InfoPanel$1: try again .. basic: JNLP2ClassLoader.findClass: balls.BallsPane: try again .. basic: JNLP2ClassLoader.findClass: balls.component.Ball: try again .. basic: JNLP2ClassLoader.findClass: balls.Constants: try again .. basic: JNLP2ClassLoader.findClass: balls.component.Ball$1: try again .. java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at com.sun.prism.es2.ES2ResourceFactory.createStockShader(ES2ResourceFactory.java:220) at com.sun.prism.impl.ps.BaseShaderContext.getPaintShader(BaseShaderContext.java:196) at com.sun.prism.impl.ps.BaseShaderContext.validatePaintOp(BaseShaderContext.java:417) at com.sun.prism.impl.ps.BaseShaderContext.validatePaintOp(BaseShaderContext.java:303) at com.sun.prism.impl.ps.BaseShaderGraphics.fillQuad(BaseShaderGraphics.java:1432) at com.sun.prism.impl.shape.BasicRoundRectRep.fillRoundRect(BasicRoundRectRep.java:36) at com.sun.prism.impl.shape.BasicRoundRectRep.fill(BasicRoundRectRep.java:22) at com.sun.javafx.sg.prism.NGShape.renderContent(NGShape.java:218) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:426) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:67) at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1277) at com.sun.javafx.sg.prism.NGGroup.renderChildren(NGGroup.java:241) at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:207) at com.sun.javafx.sg.prism.NodeEffectInput.getImageDataForBoundedNode(NodeEffectInput.java:214) at com.sun.javafx.sg.prism.NodeEffectInput.filter(NodeEffectInput.java:107) at com.sun.scenario.effect.FilterEffect.filter(FilterEffect.java:167) at com.sun.scenario.effect.impl.prism.PrEffectHelper.render(PrEffectHelper.java:164) at com.sun.javafx.sg.prism.NGNode$EffectFilter.render(NGNode.java:957) at com.sun.javafx.sg.prism.NGNode.renderEffect(NGNode.java:715) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:424) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:67) at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1277) at com.sun.javafx.sg.prism.NGGroup.renderChildren(NGGroup.java:241) at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:207) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:426) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:67) at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1277) at com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:103) at com.sun.javafx.tk.quantum.AbstractPainter.paintImpl(AbstractPainter.java:205) at com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:75) at com.sun.javafx.tk.quantum.PaintCollector.liveRepaintRenderJob(PaintCollector.java:316) at com.sun.javafx.tk.quantum.GlassViewEventHandler$ViewEventNotification.run(GlassViewEventHandler.java:641) at com.sun.javafx.tk.quantum.GlassViewEventHandler$ViewEventNotification.run(GlassViewEventHandler.java:612) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleViewEvent(GlassViewEventHandler.java:669) at com.sun.glass.ui.View.handleViewEvent(Unknown Source) at com.sun.glass.ui.View.notifyResize(Unknown Source) at com.sun.glass.ui.mac.MacWindow._setBounds(Native Method) at com.sun.glass.ui.Window.setBounds(Unknown Source) at com.sun.javafx.tk.quantum.WindowStage.setBounds(WindowStage.java:221) at javafx.stage.Window$TKBoundsConfigurator.apply(Window.java:1093) at javafx.stage.Window.applyBounds(Window.java:1014) at javafx.stage.Window$10.invalidated(Window.java:739) at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:106) at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:140) at javafx.stage.Window.setShowing(Window.java:783) at javafx.stage.Window.show(Window.java:798) at javafx.stage.Stage.show(Stage.java:242) at balls.BallsScreen.run(BallsScreen.java:61) at balls.Main.start(Main.java:43) at com.sun.javafx.applet.FXApplet2$1.run(FXApplet2.java:132) at com.sun.javafx.application.PlatformImpl$5$1.run(PlatformImpl.java:223) at com.sun.javafx.application.PlatformImpl$5$1.run(PlatformImpl.java:220) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:220) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source) Caused by: java.lang.NullPointerException at java.io.Reader.<init>(Reader.java:78) at java.io.InputStreamReader.<init>(InputStreamReader.java:72) at com.sun.prism.es2.ES2Shader.readStreamIntoString(ES2Shader.java:164) at com.sun.prism.es2.ES2Shader.createFromSource(ES2Shader.java:123) at com.sun.prism.es2.ES2ResourceFactory.createShader(ES2ResourceFactory.java:135) at com.sun.prism.shader.Solid_Color_Loader.loadShader(Solid_Color_Loader.java:45) ... 60 more java.lang.InternalError: Error loading stock shader Solid_Color at com.sun.prism.es2.ES2ResourceFactory.createStockShader(ES2ResourceFactory.java:223) at com.sun.prism.impl.ps.BaseShaderContext.getPaintShader(BaseShaderContext.java:196) at com.sun.prism.impl.ps.BaseShaderContext.validatePaintOp(BaseShaderContext.java:417) at com.sun.prism.impl.ps.BaseShaderContext.validatePaintOp(BaseShaderContext.java:303) at com.sun.prism.impl.ps.BaseShaderGraphics.fillQuad(BaseShaderGraphics.java:1432) at com.sun.prism.impl.shape.BasicRoundRectRep.fillRoundRect(BasicRoundRectRep.java:36) at com.sun.prism.impl.shape.BasicRoundRectRep.fill(BasicRoundRectRep.java:22) at com.sun.javafx.sg.prism.NGShape.renderContent(NGShape.java:218) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:426) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:67) at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1277) at com.sun.javafx.sg.prism.NGGroup.renderChildren(NGGroup.java:241) at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:207) at com.sun.javafx.sg.prism.NodeEffectInput.getImageDataForBoundedNode(NodeEffectInput.java:214) at com.sun.javafx.sg.prism.NodeEffectInput.filter(NodeEffectInput.java:107) at com.sun.scenario.effect.FilterEffect.filter(FilterEffect.java:167) at com.sun.scenario.effect.impl.prism.PrEffectHelper.render(PrEffectHelper.java:164) at com.sun.javafx.sg.prism.NGNode$EffectFilter.render(NGNode.java:957) at com.sun.javafx.sg.prism.NGNode.renderEffect(NGNode.java:715) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:424) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:67) at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1277) at com.sun.javafx.sg.prism.NGGroup.renderChildren(NGGroup.java:241) at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:207) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:426) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:67) at com.sun.javafx.sg.BaseNode.render(BaseNode.java:1277) at com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:103) at com.sun.javafx.tk.quantum.AbstractPainter.paintImpl(AbstractPainter.java:205) at com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:75) at com.sun.javafx.tk.quantum.PaintCollector.liveRepaintRenderJob(PaintCollector.java:316) at com.sun.javafx.tk.quantum.GlassViewEventHandler$ViewEventNotification.run(GlassViewEventHandler.java:641) at com.sun.javafx.tk.quantum.GlassViewEventHandler$ViewEventNotification.run(GlassViewEventHandler.java:612) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleViewEvent(GlassViewEventHandler.java:669) at com.sun.glass.ui.View.handleViewEvent(Unknown Source) at com.sun.glass.ui.View.notifyResize(Unknown Source) at com.sun.glass.ui.mac.MacWindow._setBounds(Native Method) at com.sun.glass.ui.Window.setBounds(Unknown Source) at com.sun.javafx.tk.quantum.WindowStage.setBounds(WindowStage.java:221) at javafx.stage.Window$TKBoundsConfigurator.apply(Window.java:1093) at javafx.stage.Window.applyBounds(Window.java:1014) at javafx.stage.Window$10.invalidated(Window.java:739) at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:106) at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:140) at javafx.stage.Window.setShowing(Window.java:783) at javafx.stage.Window.show(Window.java:798) at javafx.stage.Stage.show(Stage.java:242) at balls.BallsScreen.run(BallsScreen.java:61) at balls.Main.start(Main.java:43) at com.sun.javafx.applet.FXApplet2$1.run(FXApplet2.java:132) at com.sun.javafx.application.PlatformImpl$5$1.run(PlatformImpl.java:223) at com.sun.javafx.application.PlatformImpl$5$1.run(PlatformImpl.java:220) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:220) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source) cache: Resource file:/Users/steve/Documents/graphics-80/jfx/apps/ga-samples/BouncingBalls/dist/BouncingBalls.jnlp has expired. network: ResponseCode for file:/Users/steve/Documents/graphics-80/jfx/apps/ga-samples/BouncingBalls/dist/BouncingBalls.jnlp : 200 network: Encoding for file:/Users/steve/Documents/graphics-80/jfx/apps/ga-samples/BouncingBalls/dist/BouncingBalls.jnlp : null CacheEntry[file:/Users/steve/Documents/graphics-80/jfx/apps/ga-samples/BouncingBalls/dist/BouncingBalls.jnlp]: updateAvailable=false,lastModified=Mon Feb 18 19:11:58 EST 2013,length=937 network: JARUpdater: update check for file:/Users/steve/Documents/graphics-80/jfx/apps/ga-samples/BouncingBalls/dist/BouncingBalls.jar cache: Resource file:/Users/steve/Documents/graphics-80/jfx/apps/ga-samples/BouncingBalls/dist/BouncingBalls.jar has expired. network: ResponseCode for file:/Users/steve/Documents/graphics-80/jfx/apps/ga-samples/BouncingBalls/dist/BouncingBalls.jar : 200 network: Encoding for file:/Users/steve/Documents/graphics-80/jfx/apps/ga-samples/BouncingBalls/dist/BouncingBalls.jar : null CacheEntry[file:/Users/steve/Documents/graphics-80/jfx/apps/ga-samples/BouncingBalls/dist/BouncingBalls.jar]: updateAvailable=false,lastModified=Mon Feb 18 19:11:57 EST 2013,length=25380
19-02-2013

In run-many.sh, the failures are either assertion failures or hover help / popup null pointers. For the popup ones, is there anything I need to do to make them happen. For example, HelloMenuButton seems to work fine for me. I can only run JNLP and can confirm badness for BouncingBalls.
19-02-2013

Thanks Kevin. I am able to run FXML-LoginDemo as JNLP and will try the others. The patch needs work.
18-02-2013

I also ran several of our internal test programs in toys (using the run-many.sh script). Most of the failures are assertion errors which you only see if you run with "-ea". See LiveResize-test.log
16-02-2013

Applets do not work well with the latest patch. Here is the status for the apps in ga-samples: BouncingBalls.html -- Only background displayed BrickBreaker.html -- OK Calculator.html -- Only background displayed Ensemble.html -- throws exception (see ensemble-exception.log) StopWatch.html -- Only background displayed SwingInterop.html -- OK All of the above applets run fine without the patch. Note that there is bug elsewhere that prevents FXML-LoginDemo from running in any mode, with or without your patch.
16-02-2013

The easiest fix is to allow pulses to stack. This code allows it by moving the copying of the listeners list into the method. If we continue with this approach, we don't need to clear the list in a try {} finally. diff --git a/javafx-ui-common/src/com/sun/javafx/tk/Toolkit.java b/javafx-ui-common/src/com/sun/javafx/tk/Toolkit.java --- a/javafx-ui-common/src/com/sun/javafx/tk/Toolkit.java +++ b/javafx-ui-common/src/com/sun/javafx/tk/Toolkit.java @@ -331,15 +331,15 @@ // The set of shutdown hooks is strongly held to avoid premature GC. private final Set<Runnable> shutdownHooks = new HashSet<Runnable>(); - private final ArrayList<TKPulseListener> stagePulseList = new ArrayList<TKPulseListener>(); - private final ArrayList<TKPulseListener> scenePulseList = new ArrayList<TKPulseListener>(); - private final ArrayList<TKPulseListener> postScenePulseList = new ArrayList<TKPulseListener>(); public void firePulse() { // Stages need to be notified of pulses before scenes so the Stage can resized // and those changes propogated to scene before it gets its pulse to update - try { + final ArrayList<TKPulseListener> stagePulseList = new ArrayList<TKPulseListener>(); + final ArrayList<TKPulseListener> scenePulseList = new ArrayList<TKPulseListener>(); + final ArrayList<TKPulseListener> postScenePulseList = new ArrayList<TKPulseListener>(); + try { synchronized (this) { stagePulseList.addAll(stagePulseListeners.keySet()); scenePulseList.addAll(scenePulseListeners.keySet());
12-02-2013

Yes, I can confirm this. I have been testing with: ... if (!isApplet) { //stage.initStyle(StageStyle.UNDECORATED); // create window resize button windowResizeButton = new WindowResizeButton(stage, 1020,700); // create root .... This is needed so that the operating system handles (and resizing) is used. Ensemble does not use native resizing. I'm not sure why this should make a difference but I expect is causes pulses to stack. Will look into it.
12-02-2013

When I run Ensemble with the attached patch, and resize it during animation, I get a steady stream of the following errors: java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819) at java.util.ArrayList$Itr.next(ArrayList.java:791) at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:348) at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:511) at com.sun.javafx.tk.quantum.QuantumToolkit$12.run(QuantumToolkit.java:379) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source) java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819) at java.util.ArrayList$Itr.next(ArrayList.java:791) at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:348) at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:511) at com.sun.javafx.tk.quantum.QuantumToolkit$12.run(QuantumToolkit.java:379) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source) java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819) at java.util.ArrayList$Itr.next(ArrayList.java:791) at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:348) at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:511) at com.sun.javafx.tk.quantum.QuantumToolkit$12.run(QuantumToolkit.java:379) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source) ...
12-02-2013

Felipe, I'm not an expert in this code, too, but your description of the code flow sounds reasonable. Thanks. As long as all tests pass with this fix, I'm fine with it.
12-02-2013

I just wanted to re-assess how eager we (Scene Builder team) are to see this fix which (together with a fix for RT-20279) will hopefully allow our app window to resize as smoothly as a native app. This is really what we need to show off.
11-02-2013

Felipe beat me to it. I believe that we are fine as long as we lock our access around the render lock. It's still not clear to me why we hang when we call lockFocus/unlockFocus and that bothers me a bit. It seemed to me that the locks were stacked and that it should not matter. I have tried Ensemble with multiple stages from the stages tab. It draw fine.
11-02-2013

Hi Anthony, For the simple case (regular NSView drawing from different thread) what you said is 100% true. But we are not rendering to the NSView window storage. Our case is very special. At that point we are preparing to render to the FBO (GlassView3D.m begin), some time later the content of this FBO is blit to the layer (GlassLayer3D.m#drawInCGLContext), some time later the content of the layer is blit to the view/screen (this last phase happens in the OS I'm not sure of the details). The idea is that we are not going to render to the view, thus locking the view is unnecessary (and if we do, it will deadlock when rendering during resize since the OS thread has the NSView lock and needs render lock, and the pulse thread has the render lock and is requesting the view lock, by calling NSView#lockFocus). Note that in GlassOffscreen.m#bindForWidth we call CGLSetCurrentContext, and in GlassFrameBufferObject.m#bindForWidth we bind the FBO. That is how I believe all the GL calls get render to the right destination. All said, I'm not an expert on this area of the code, please correct me if I'm wrong.
11-02-2013

Actually, I think we do have to call -lock/unlockFocus, because otherwise how would the OS know where to direct rendering performed by Prism? Please remember that we use only one OpenGL context on the Mac, and locking the focus is a way to select a view to render to. Steve: please try a multi-window test and see how it goes with your current fix.
11-02-2013

I'm not an expert in rendering but FWIW, processing PAINT requests from OS on the Event Thread synchronously seems to be the only way to implement synchronous live-resizing. The reason it may not work if we delegate to the render thread is because the render thread may be busy doing other rendering job (e.g. for the next frame), and thus we will block the event thread. Note that running a nested event loop is not an option because in this case the synchronous nature of the live-resize PAINT event goes away - the OS will think that we've finished with painting when the nested event loop is asking for more events. So, generally I approve of Steve's idea. However, I'm not sure if it is OK to omit the -lock/-unlockFocus calls for the view. The spec for these methods suggests they may do something more than just acquiring an internal native lock, but I don't know the details. We need to ask a Mac expert about this.
11-02-2013

I will test this early next week as I am not in the office today. I have some concerns over drawing in the UI thread which I have expressed before. The fact that this is Mac-only may alleviate those concerns, but I still would like to understand why delegating to the Renderer thread, and waiting for it to finish, doesn't accomplish the same thing (Felipe tried it with no success, but it should be identical unless a nested event loop is spinning up).
08-02-2013

Please review the patch that is attached. It fixes the problem for Mac only. The strategy is to redraw in the UI thread. Quantum locking has been fixed recently so that Glass/Prism/Quantum perform drawing operations inside the render lock. This means that it is safe to draw from either the render thread or the the UI thread. The Objective-C lockFocus/unlockFocus calls add an unnecessary level of operating system locking and cause a hang. Since the render lock is used by FX to keep drawing consistent and avoid crashing, I commented out the operating system lock. I am not sure why it hangs. I am unable to run FX in the browser right now for some reason and I am unable to test it there. Otherwise, I have been running the code for a while and testing with FX. We should put it in (after testing the browser) and make sure SQE tests pass. Kevin?
08-02-2013

Great! Then I will focus on Mac resizing, then Linux.
15-01-2013

I agree with you, native Windows applications don't do that better than FX one.
15-01-2013

I don't see the garbage on Windows. Have not got to Linux yet. It seems that native Windows applications have drawing problems similar to FX on it is harder to see them because they draw faster. I am resizing IE horixzontally by dragging the right window frame. I am watching as IE fills the background area with gray, then the toolbar and window content draw. I believe this is the best that is possible on Windows (ie. the application can ask FX to fill with a nice color rather than black). Note that Mac applications don't have this problem and can do better. Do you agree that native Windows applications have the same drawing problem as FX (you will need something natrive that draws slowly)? This is important as I don't believe any resize specific work will improove FX on Windows (other than getting FX to draw faster which is great and will make FX look faster, but there will always be the issue that the background is filled first and then FX draws). Thoughts?
07-01-2013

Steve, the flash of pixel garbage you report is not supposed to occur, see RT-21057. I've never seen it again since this fix so it's a concern if it's back. Or it may be another issue, with a similar visible effect ? Do you see it as well on Windows or Linux ?
07-01-2013

I am running SceneBuilder 2.0 on a Mac and can confirm that SceneBuilder is using the operating resize mechanism. When SceneBuilder first comes up, there is a flash of pixel garbage (I believe there is a JIRA elsewhere that is tracking this). There are also warnings about "headless" and an assertion error but SceneBuilder runs: [java] 2013-01-04 12:46:04.783 java[3542:707] [JRSAppKitAWT markAppIsDaemon]: Process manager already initialized: can't fully enable headless mode. [java] WARNING: there are 0 scrollbars - 2 expected [java] java.lang.AssertionError [java] at com.oracle.javafx.authoring.StageView$13.invalidated(StageView.java:235) [java] at com.sun.javafx.collections.ListListenerHelper$SingleInvalidation.fireValueChangedEvent(ListListenerHelper.java:124) [java] at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:72) When I resize using the bottom right corner, it is very smooth. It seems that the background color matches the default for the operating system. I can see a flash of the wrong color if I watch 'Properties: AnchorPane' in the top right. I would not consider this critical. When I resize using the maximize button (NOTE: not the Mac full screen button, the green (+) maximize), then the operating system does an animation and resizes the window is steps and I see the gray rectangle
04-01-2013

Thanks Yves. Ensemble doesn't use the native resize trim and behaves better when resizing by dragging the bottom left corner on Windows (please confirm if you can). If you comment out the UNDECORATED style int Ensemble2.start(), then it is more suitable for testing resize. ... if (!isApplet) { //stage.initStyle(StageStyle.UNDECORATED); // create window resize button windowResizeButton = new WindowResizeButton(stage, 1020,700); // create root .... With this line commented out, Ensemble displays the resize lag on both Window and Mac (will try Linux when we get closer to a solution). I will get SceneBuilder 2.0 as well to run the same thing you are running. The issue is this: FX does not draw synchronously when the operating system asks it to paint. Until we do this, we will always look terrible during resize because we return to the operating system from the user-interface thread without drawing, allowing the user interface to process more resize events and get futher out of sync. There may be horrible hacks to get around this (AWT/Swing had a similar issue because it did not draw right away) but by far the easiest thing to do is draw when the operating system wants us to.
04-01-2013

I gave a try to Ensemble: all in all user experience is very similar to the one you get with SceneBuilder. When maximizing the issue is more visible with SceneBuilder (tried on the same Mac), and when resizing manually both applications behave the same.
04-01-2013

I'm pretty sure that the lag in drawing when resizing is the same for Ensemble and SceneBuilder and it would be good to run the latest FX and SceneBuilder together, however, I can debug with Ensemble for now. Whether the lag is a catastrophe is open to debate but it is clear that native applications do not have it.
03-01-2013

I would like to run the latest SceneBuilder against the latest JavaFX. Some changes have been made to private CSS API that SceneBuilder uses causing compile errors. Is there a more up to date version that I can use?
03-01-2013

I am running ScenBuilder from hg clone http://jfxsrc.us.oracle.com/javafx/tools/authoringtool on the Mac. I see a white area when I resize the bottom right corner but this disappears quickly for me when JavaFX repaints. I can observe the same white are when I resize Ensemble. Yves, can you run Ensemble and confirm that SceneBuilder resizing is equivalent? Thanks.
03-01-2013

The current layer based Mac Glass implementation does use the window background to clear its offscreen, so the clients should never see the garbage (ie. random bits in window), though Prism still needs to handle system repaints to draw more than window background.
30-05-2012

The summary here is that with the above changes the live resize actually looks much better, which I personally doubted it would help much.
16-03-2012

Attaching current snapshot of Glass in case something goes wrong. I will be checking the current code into 2.2 as soon as I can.
16-03-2012

Also, we need glClear with background color in View.begin in those cases where a live resize still comes through from behind disabling window flush. So we still get full surface repaintings, but at least they are done using the background color.
16-03-2012

Looks like my local changes are needed.
16-03-2012

If we set the color explicitly on the javafx Scene as I pointed out during the conference call, i.e.: private Frame(Project project) { setProject(project); this.scene = SceneBuilder.create() .width(cssToolWidth).height(cssToolHeight) .root(rootParent) // .fill(Style.COLOR_50) .build(); this.scene.setFill(javafx.scene.paint.Color.rgb(225, 225, 225)); in com.oracle.javafx.authoring.Frame, then the resizing actually looks reasonable, and there is no white flashes of uncovered window area. This is running against my local build of Glass/Prism. I need to verify that none of my local changes are required for this workaround.
15-03-2012

Ok / sqe
12-03-2012

Following discussion w/ Graphics team, I am changing sb-21-critical label into sb-22-critical. Let us know when you have a test build with the workaround (I understand this will be only on Mac) and we will try that. Thx.
12-03-2012

Based on the bug evaluation, this is way too risky for 2.1. We propose to defer it to 2.2 and are working with the Scene builder team on a possible workaround for 2.1.
12-03-2012

Applet windows don't resize in response to a resize of the browser window, but in response to a zoom operation, it would probably be affected the same way.
12-03-2012

Does this problem also show up in the browser or is this just limited to standalone?
12-03-2012

We need to be able to synchronously resize JFX content, followed by synchronous painting in response to live resize repaint.
10-03-2012

Updated use case.
09-03-2012

WARNING: GlassView3D unlocked, but not drawn. WARNING: GlassView3D unlocked, but not drawn. 2012-03-09 17:04:27.686 java[48506:603] !!!!!!!!!!! reshape 2012-03-09 17:04:27.686 java[48506:603] !!!!!!!!!!! reshape 2012-03-09 17:04:27.687 java[48506:603] !!!!!!!!!!! reshape 2012-03-09 17:04:27.688 java[48506:603] !!!!!!!!!!! BEGIN setFrameSize 2012-03-09 17:04:27.688 java[48506:603] !!!!!!!!!!! END setFrameSize 2012-03-09 17:04:27.688 java[48506:603] !!!!!!!!!!! BEGIN setFrame 2012-03-09 17:04:27.689 java[48506:603] !!!!!!!!!!! END setFrame 2012-03-09 17:04:27.696 java[48506:603] !!!!!!!!!!! update 2012-03-09 17:04:27.697 java[48506:603] !!!!!!!!!!! reshape 2012-03-09 17:04:27.698 java[48506:603] !!!!!!!!!!! BEGIN drawRect ViewEvent.REPAINT scene.sceneListener: javafx.scene.Scene$ScenePeerListener@125b8827 2012-03-09 17:04:27.698 java[48506:603] BEGIN begin on main thread: 1 >>>>>>>>>>>>>> ES2SwapChain present physical size: 509x505 content size: 509x505 bounds: {{0, 0}, {509, 505}} viewport: {{0, 0}, {509, 505}} 2012-03-09 17:04:27.706 java[48506:603] END begin flush: 1 2012-03-09 17:04:27.706 java[48506:603] !!!!!!!!!!! END drawRect 2012-03-09 17:04:27.707 java[48506:603] !!!!!!!!!!! reshape >>>>>>>>>>>>>> JFX resize 509.0x505.0 2012-03-09 17:04:27.716 java[48506:e003] BEGIN begin on main thread: 0 >>>>>>>>>>>>>> ES2SwapChain present physical size: 509x505 content size: 509x505 bounds: {{0, 0}, {509, 505}} viewport: {{0, 0}, {509, 505}} 2012-03-09 17:04:27.733 java[48506:e003] END begin flush: 1 2012-03-09 17:04:47.925 java[48506:603] !!!!!!!!!!! reshape 2012-03-09 17:04:47.926 java[48506:603] !!!!!!!!!!! reshape The stack trace shows that we have 2 repaints during live resize: - the 1st repaint happens before JFX has the chance to resize, though Quantum and Glass sizes are in sync - the 2nd repaint finally shows JFX catching up to resize Which is how we get the uncovered white slivers to show up. The 1st repaint will clear all the surface but only draws JFX content at the old size.
09-03-2012

I was wrong. I just created a very simple JFX live resize use case that exhibits the same issue. It's good, however, that a very simple use case shows the problems - it should make debugging it much easier.
09-03-2012

Need to verify but it looks like the problem is with programmatical resize. HelloWorld samples, which do not resize the frame by themselves seem fine. Both Ensemble and SceneBuilder look to handle the resizing by changing the frame size on its own in response to mouse events.
08-03-2012

The ViewEvent.RESIZE+ViewEvent.REPAINT seem to generate as many as 3 repaints at the time when resources are needed the most. We should really just repaint once. Also, from Glass/Prism point of view the native size / viewport seem to be in sync always - need a simple JFX test case to figure out where the size inconstancies resulting in undrawn exposed size difference comes from.
08-03-2012

A related issue here, which is really annoying, is that the 1st time the Window is shown is displays just background, as well as the number of repaints issued by the time the system settles down after the app startups. Will need to file a separate issue to track these as even though not difficult, they are nonetheless significant to warrant a separate investigation.
08-03-2012

At this point I'm just working on conceptual proof of concept, and my findings do not represent the final solution. I call the painter's run directly just to prove that conceptually it's exactly what we need (ie. synchronous handling of painting). And as proof of concept it does indeed work. How exactly we will handle this in the final fix will still need to be evaluated. I still need to understand #2, but once I have the conceptual understanding (ie. requirements), we'll need a discussion on the exact fix.
07-03-2012

Regarding #1, you can't call the painter directly from that method, since that method is running on the FX app thread and the painter must be called on the renderer thread. Even if you could do this, a new layout pass is needed to handle the change in size (once #2 is fixed).
06-03-2012

The system repaints in Quantum are handled by using PaintCollector.liveRepaintRenderJob, however, it seems to have 2 problems: 1. it's asynchronous 2. it uses old size Re 1. If I do: PresentingPainter pp = (PresentingPainter)viewPainter; pp.run(); instead of renderer.submit(new RenderJob((Runnable)viewPainter, viewRepainted)); then we get synchronous paint. Re 2. Need to look into more.
06-03-2012

Can prove that JFX is not drawing due to system repaints as it should : Glass will draw a red rect in a window that must be drawn. The assumption is that the client will draw its content and we should never see the red. With my Glass use case all is good, but JFX apps, such as Ensemble show the red. Need to handle the system repaints that Glass sends to clients.
06-03-2012

Made good progress. Need more testing, code cleanup.
02-03-2012

Starting the work on this.
01-03-2012

We are currently running SB on promoted b15 and we still get the same issue. The reason the situation seems better than shown by the attached screenshots is because these are frames from a movie recorded by Kinsley, where he was resizing the window very quickly, in order to make the issue more obvious. When resizing at normal speed, the effect of the issue looks a bit less severe than that, but is still bad.
01-03-2012

Verified that this change set is causing the problem changeset: 601:cadeaec25e9a user: gerard.ziemski@oracle.com date: Mon Oct 24 14:54:03 2011 -0500 summary: RT-17345 Workaround - use shared GL context when View is not locked
21-02-2012

Verified that this exists in p202-b06
21-02-2012

Verified that this issue does not exist in p202-b04
21-02-2012

Verified that this exists in p202-b08
21-02-2012

Verified that this exists in p21-b08
21-02-2012

This is reproducible on both Windows and Mac
01-02-2012