changeset 6903:8979d8ffbc06

Fix RT-24903: Canvas buffers rendering commands without consuming them if not visible. Approved by Kevin, also reviewed by Steve.
author flar <James.Graham@oracle.com>
date Fri, 25 Apr 2014 16:44:09 -0700
parents ea134f222605
children df050d476706
files modules/graphics/src/main/java/com/sun/javafx/scene/DirtyBits.java modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGCanvas.java modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGGroup.java modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGNode.java modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGSubScene.java modules/graphics/src/main/java/com/sun/javafx/tk/quantum/PresentingPainter.java modules/graphics/src/main/java/com/sun/javafx/tk/quantum/UploadingPainter.java modules/graphics/src/main/java/com/sun/javafx/tk/quantum/ViewPainter.java modules/graphics/src/main/java/javafx/scene/Node.java modules/graphics/src/main/java/javafx/scene/canvas/Canvas.java
diffstat 10 files changed, 70 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/modules/graphics/src/main/java/com/sun/javafx/scene/DirtyBits.java	Fri Apr 25 15:40:14 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/scene/DirtyBits.java	Fri Apr 25 16:44:09 2014 -0700
@@ -40,6 +40,7 @@
     NODE_DEPTH_TEST,
     NODE_BLENDMODE,
     NODE_CSS,
+    NODE_FORCE_SYNC,
 
     // Dirty bits for various subclasses of Node
     NODE_GEOMETRY,  // Used by ImageView, MediaView, and subclasses of Shape and Shape3D
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGCanvas.java	Fri Apr 25 15:40:14 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGCanvas.java	Fri Apr 25 16:44:09 2014 -0700
@@ -50,6 +50,7 @@
 import com.sun.prism.BasicStroke;
 import com.sun.prism.CompositeMode;
 import com.sun.prism.Graphics;
+import com.sun.prism.GraphicsPipeline;
 import com.sun.prism.Image;
 import com.sun.prism.PrinterGraphics;
 import com.sun.prism.RTTexture;
@@ -192,7 +193,9 @@
             }
             if (create) {
                 RTTexture oldtex = tex;
-                ResourceFactory factory = resg.getResourceFactory();
+                ResourceFactory factory = (resg == null)
+                    ? GraphicsPipeline.getDefaultResourceFactory()
+                    : resg.getResourceFactory();
                 RTTexture newtex =
                     factory.createRTTexture(tw, th, WrapMode.CLAMP_TO_ZERO);
                 this.tex = newtex;
@@ -223,7 +226,9 @@
                     this.g = tex.createGraphics();
                     if (this.g == null) {
                         tex.dispose();
-                        ResourceFactory factory = resg.getResourceFactory();
+                        ResourceFactory factory = (resg == null)
+                            ? GraphicsPipeline.getDefaultResourceFactory()
+                            : resg.getResourceFactory();
                         tex = factory.createRTTexture(tw, th, WrapMode.CLAMP_TO_ZERO);
                         this.g = tex.createGraphics();
                         this.input = new EffectInput(tex);
@@ -587,6 +592,20 @@
         this.temp.g = this.clip.g = this.cv.g = null;
     }
 
+    @Override
+    public void renderForcedContent(Graphics gOptional) {
+        if (thebuf != null) {
+            initCanvas(gOptional);
+            if (cv.tex != null) {
+                renderStream(thebuf);
+                GrowableDataBuffer.returnBuffer(thebuf);
+                thebuf = null;
+                cv.save(tw, th);
+            }
+            this.temp.g = this.clip.g = this.cv.g = null;
+        }
+    }
+
     private void initCanvas(Graphics g) {
         if (tw <= 0 || th <= 0) {
             cv.dispose();
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGGroup.java	Fri Apr 25 15:40:14 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGGroup.java	Fri Apr 25 16:44:09 2014 -0700
@@ -190,6 +190,16 @@
     }
 
     @Override
+    public void renderForcedContent(Graphics gOptional) {
+        if (children == null) {
+            return;
+        }
+        for (int i = 0; i < children.size(); i++) {
+            children.get(i).renderForcedContent(gOptional);
+        }
+    }
+
+    @Override
     protected void renderContent(Graphics g) {
         if (children == null) {
             return;
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGNode.java	Fri Apr 25 15:40:14 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGNode.java	Fri Apr 25 16:44:09 2014 -0700
@@ -1959,6 +1959,22 @@
         doRender(g);
     }
 
+    /**
+     * Called on every render pulse for all nodes in case they have render-time
+     * operations that must be completed on a pulse, but were not otherwise
+     * rendered by the ordinary damage management logic.
+     * The graphics argument will be the graphics that was used to render the
+     * scene if it is available, but may be null for cases when the scene
+     * required no visible updates and thus no back buffer graphics was
+     * actually obtained.  Implementors must have a backup plan for that
+     * case when the Graphics object is null.
+     * 
+     * @param gOptional the Graphics object that was used to render the
+     *                  Scene, or null
+     */
+    public void renderForcedContent(Graphics gOptional) {
+    }
+
     // This node requires 2D graphics state for rendering
     boolean isShape3D() {
         return false;
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGSubScene.java	Fri Apr 25 15:40:14 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGSubScene.java	Fri Apr 25 16:44:09 2014 -0700
@@ -154,6 +154,11 @@
     }
 
     @Override
+    public void renderForcedContent(Graphics gOptional) {
+        root.renderForcedContent(gOptional);
+    }
+
+    @Override
     protected void renderContent(Graphics g) {
         if (rtWidth <= 0.0 || rtHeight <= 0.0) { return; }
         if (rtt != null) {
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/PresentingPainter.java	Fri Apr 25 15:40:14 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/PresentingPainter.java	Fri Apr 25 16:44:09 2014 -0700
@@ -55,6 +55,7 @@
                 if (QuantumToolkit.verbose) {
                     System.err.println("PresentingPainter: validateStageGraphics failed");
                 }
+                paintImpl(null);
                 return;
             }
             
@@ -111,9 +112,8 @@
             errored = true;
             th.printStackTrace(System.err);
         } finally {
-            if (valid) {
-                Disposer.cleanUp();
-            }
+            Disposer.cleanUp();
+
             if (locked) {
                 sceneState.unlock();
             }
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/UploadingPainter.java	Fri Apr 25 15:40:14 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/UploadingPainter.java	Fri Apr 25 16:44:09 2014 -0700
@@ -84,6 +84,7 @@
                 if (QuantumToolkit.verbose) {
                     System.err.println("UploadingPainter: validateStageGraphics failed");
                 }
+                paintImpl(null);
                 return;
             }
             
@@ -175,11 +176,10 @@
         } finally {
             if (rttexture != null && rttexture.isLocked()) {
                 rttexture.unlock();
-            }            
-            if (valid) {
-                Disposer.cleanUp();
             }
 
+            Disposer.cleanUp();
+
             sceneState.getScene().setPainting(false);
 
             ManagedResource.freeDisposalRequestedAndCheckResources(errored);
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/ViewPainter.java	Fri Apr 25 15:40:14 2014 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/ViewPainter.java	Fri Apr 25 16:44:09 2014 -0700
@@ -164,7 +164,10 @@
     protected void paintImpl(final Graphics backBufferGraphics) {
         // We should not be painting anything with a width / height
         // that is <= 0, so we might as well bail right off.
-        if (width <= 0 || height <= 0) return;
+        if (width <= 0 || height <= 0 || backBufferGraphics == null) {
+            root.renderForcedContent(backBufferGraphics);
+            return;
+        }
 
         // This "g" variable might represent the back buffer graphics, or it
         // might be reassigned to the sceneBuffer graphics.
@@ -321,6 +324,7 @@
             g.setClipRect(null);
             this.doPaint(g, null);
         }
+        root.renderForcedContent(g);
 
         // If we have an overlay then we need to render it too.
         if (overlayRoot != null) {
--- a/modules/graphics/src/main/java/javafx/scene/Node.java	Fri Apr 25 15:40:14 2014 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/Node.java	Fri Apr 25 16:44:09 2014 -0700
@@ -494,7 +494,11 @@
     @Deprecated
     public final void impl_syncPeer() {
         // Do not synchronize invisible nodes unless their visibility has changed
-        if (!impl_isDirtyEmpty() && (treeVisible || impl_isDirty(DirtyBits.NODE_VISIBLE))) {
+        // or they have requested a forced synchronization
+        if (!impl_isDirtyEmpty() && (treeVisible
+                                     || impl_isDirty(DirtyBits.NODE_VISIBLE)
+                                     || impl_isDirty(DirtyBits.NODE_FORCE_SYNC)))
+        {
             impl_updatePeer();
             clearDirty();
         }
--- a/modules/graphics/src/main/java/javafx/scene/canvas/Canvas.java	Fri Apr 25 15:40:14 2014 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/canvas/Canvas.java	Fri Apr 25 16:44:09 2014 -0700
@@ -114,6 +114,7 @@
 
     GrowableDataBuffer getBuffer() {
         impl_markDirty(DirtyBits.NODE_CONTENTS);
+        impl_markDirty(DirtyBits.NODE_FORCE_SYNC);
         if (current == null) {
             int vsize = max(recentvalsizes, DEFAULT_VAL_BUF_SIZE);
             int osize = max(recentobjsizes, DEFAULT_OBJ_BUF_SIZE);