changeset 8031:114951fd1301

RT-38290: [WebView] HTML canvas clip() functionality broken Reviewed-by: ant, peterz Contributed by: anashaty
author ant <anton.tarasov@oracle.com>
date Wed, 10 Sep 2014 20:35:23 +0400
parents c9450b73265d
children 8335da240a33
files modules/web/src/main/java/com/sun/javafx/sg/prism/NGWebView.java modules/web/src/main/java/com/sun/javafx/webkit/prism/WCGraphicsPrismContext.java modules/web/src/main/java/com/sun/webkit/WebPage.java modules/web/src/main/java/com/sun/webkit/graphics/WCGraphicsContext.java modules/web/src/main/java/com/sun/webkit/graphics/WCRenderQueue.java modules/web/src/main/java/com/sun/webkit/perf/WCGraphicsPerfLogger.java
diffstat 6 files changed, 84 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/modules/web/src/main/java/com/sun/javafx/sg/prism/NGWebView.java	Wed Sep 10 17:11:16 2014 +0200
+++ b/modules/web/src/main/java/com/sun/javafx/sg/prism/NGWebView.java	Wed Sep 10 20:35:23 2014 +0400
@@ -94,6 +94,7 @@
             } else {
                 page.paint(gc, 0, 0, (int) width, (int) height);
             }
+            gc.flush();
         } finally {
             gc.dispose();
         }
--- a/modules/web/src/main/java/com/sun/javafx/webkit/prism/WCGraphicsPrismContext.java	Wed Sep 10 17:11:16 2014 +0200
+++ b/modules/web/src/main/java/com/sun/javafx/webkit/prism/WCGraphicsPrismContext.java	Wed Sep 10 20:35:23 2014 +0400
@@ -72,6 +72,7 @@
     private Graphics cachedGraphics = null;
 
     private int fontSmoothingType;
+    private boolean isRootLayerValid = false;
 
     WCGraphicsPrismContext(Graphics g) {
         init(g, true);
@@ -176,7 +177,6 @@
             layer.render(g);
         }
 
-        layer.dispose();
         //restore transform
         setTransform(cur);
     }
@@ -192,6 +192,7 @@
         state = states.remove(size - 1);
         if (layer != state.getLayerNoClone()) {
             renderLayer(layer);
+            layer.dispose();
             if (log.isLoggable(Level.FINE)) {
                 log.fine("Popped layer " + layer);
             }
@@ -208,6 +209,65 @@
         } while ( !state.isRestorePoint() );
     }
 
+    /**
+     *  Renders all layers to the underlaying Graphics, but preserves the
+     *  current state and the states stack
+     */
+    private void flushAllLayers() {
+        if (state == null) {
+            // context disposed
+            return;
+        }
+
+        if (isRootLayerValid) {
+            log.fine("FlushAllLayers: root layer is valid, skipping");
+            return;
+        }
+
+        if (log.isLoggable(Level.FINE)) {
+            log.fine("FlushAllLayers");
+        }
+
+        ContextState currentState = state;
+
+        for (int i = states.size() - 1; i >=0; i--) {
+            Layer layer = state.getLayerNoClone();
+            state = states.get(i);
+            if (layer != state.getLayerNoClone()) {
+                renderLayer(layer);
+            } else {
+                resetCachedGraphics();
+            }
+        }
+
+        Layer layer = state.getLayerNoClone();
+        if (layer != null) {
+            renderLayer(layer);
+        }
+
+        state = currentState;
+        isRootLayerValid = true;
+    }
+
+
+    public void dispose() {
+        if (!states.isEmpty()) {
+            log.fine("Unbalanced saveState/restoreState");
+        }
+        for (ContextState state: states) {
+            if (state.getLayerNoClone() != null) {
+                state.getLayerNoClone().dispose();
+            }
+        }
+        states.clear();
+
+        if (state.getLayerNoClone() != null) {
+            state.getLayerNoClone().dispose();
+        }
+        state = null;
+    }
+
+
     public void setClip(WCPath path, boolean isOut) {
         Affine3D tr = new Affine3D(state.getTransformNoClone());
         path.transform(
@@ -1171,8 +1231,8 @@
     }
 
     private abstract static class Layer {
-        final FilterContext fctx;
-        final PrDrawable buffer;
+        FilterContext fctx;
+        PrDrawable buffer;
         Graphics graphics;
         final Rectangle bounds;
 
@@ -1198,7 +1258,11 @@
         abstract void render(Graphics g);
 
         private void dispose() {
-            Effect.releaseCompatibleImage(fctx, buffer);
+            if (buffer != null) {
+                Effect.releaseCompatibleImage(fctx, buffer);
+                fctx = null;
+                buffer = null;
+            }
         }
 
         private double getX() { return (double) bounds.x; }
@@ -1329,6 +1393,7 @@
                         blend(g);
                         break;
                 }
+                isRootLayerValid = false;
             }
         }
 
@@ -1599,18 +1664,9 @@
         resetCachedGraphics();
     }
 
-    public void dispose() {
-        if (!states.isEmpty()) {
-            log.fine("Unbalanced saveState/restoreState");
-        }
-        while (!states.isEmpty()) {
-            restoreStateInternal();
-        }
-        // |state| is now the initial state. It may have a layer, too
-        Layer layer = state.getLayerNoClone();
-        if (layer != null) {
-            renderLayer(layer);
-        }
+    @Override
+    public void flush() {
+        flushAllLayers();
     }
 
     @Override
--- a/modules/web/src/main/java/com/sun/webkit/WebPage.java	Wed Sep 10 17:11:16 2014 +0200
+++ b/modules/web/src/main/java/com/sun/webkit/WebPage.java	Wed Sep 10 20:35:23 2014 +0400
@@ -651,6 +651,7 @@
                 WCGraphicsContext bgc = backbuffer.createGraphics();
                 try {
                     paint2GC(bgc);
+                    bgc.flush();
                 } finally {
                     backbuffer.disposeGraphics(bgc);
                 }
--- a/modules/web/src/main/java/com/sun/webkit/graphics/WCGraphicsContext.java	Wed Sep 10 17:11:16 2014 +0200
+++ b/modules/web/src/main/java/com/sun/webkit/graphics/WCGraphicsContext.java	Wed Sep 10 20:35:23 2014 +0400
@@ -133,5 +133,7 @@
     public abstract WCGradient createLinearGradient(WCPoint p1, WCPoint p2);
     public abstract WCGradient createRadialGradient(WCPoint p1, float r1, WCPoint p2, float r2);
 
+    public abstract void flush();
+
     public abstract void dispose();
 }
--- a/modules/web/src/main/java/com/sun/webkit/graphics/WCRenderQueue.java	Wed Sep 10 17:11:16 2014 +0200
+++ b/modules/web/src/main/java/com/sun/webkit/graphics/WCRenderQueue.java	Wed Sep 10 20:35:23 2014 +0400
@@ -100,6 +100,7 @@
     public synchronized void decode() {
         assert (gc != null);
         decode(gc);
+        gc.flush();
     }
 
     public synchronized void decode(int fontSmoothingType) {
--- a/modules/web/src/main/java/com/sun/webkit/perf/WCGraphicsPerfLogger.java	Wed Sep 10 17:11:16 2014 +0200
+++ b/modules/web/src/main/java/com/sun/webkit/perf/WCGraphicsPerfLogger.java	Wed Sep 10 20:35:23 2014 +0400
@@ -433,6 +433,13 @@
     }
 
     @Override
+    public void flush() {
+        logger.resumeCount("FLUSH");
+        gc.flush();
+        logger.suspendCount("FLUSH");
+    }
+
+    @Override
     public void setTransform(WCTransform t) {
         logger.resumeCount("SETTRANSFORM");
         gc.setTransform(t);