< prev index next >

src/java.desktop/share/classes/sun/java2d/pipe/AAShapePipe.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -26,42 +26,49 @@
 
 import java.awt.BasicStroke;
 import java.awt.Rectangle;
 import java.awt.Shape;
 import java.awt.geom.Rectangle2D;
+import java.util.concurrent.ConcurrentLinkedQueue;
 import sun.awt.SunHints;
+import sun.java2d.ReentrantContext;
+import sun.java2d.ReentrantContextProvider;
+import sun.java2d.ReentrantContextProviderTL;
 import sun.java2d.SunGraphics2D;
 
 /**
  * This class is used to convert raw geometry into 8-bit alpha tiles
  * using an AATileGenerator for application by the next stage of
  * the pipeline.
  * This class sets up the Generator and computes the alpha tiles
  * and then passes them on to a CompositePipe object for painting.
  */
-public class AAShapePipe
+public final class AAShapePipe
     implements ShapeDrawPipe, ParallelogramPipe
 {
-    static RenderingEngine renderengine = RenderingEngine.getInstance();
+    static final RenderingEngine renderengine = RenderingEngine.getInstance();
 
     // Per-thread TileState (~1K very small so do not use any Weak Reference)
-    private static final ThreadLocal<TileState> tileStateThreadLocal =
-            new ThreadLocal<TileState>() {
-        @Override
-        protected TileState initialValue() {
-            return new TileState();
-        }
-    };
+    private static final ReentrantContextProvider<TileState> tileStateProvider =
+            new ReentrantContextProviderTL<TileState>(
+                    ReentrantContextProvider.REF_HARD)
+            {
+                @Override
+                protected TileState newContext() {
+                    return new TileState();
+                }
+            };
 
-    CompositePipe outpipe;
+    final CompositePipe outpipe;
 
     public AAShapePipe(CompositePipe pipe) {
         outpipe = pipe;
     }
 
+    @Override
     public void draw(SunGraphics2D sg, Shape s) {
-        BasicStroke bs;
+        final BasicStroke bs;
 
         if (sg.stroke instanceof BasicStroke) {
             bs = (BasicStroke) sg.stroke;
         } else {
             s = sg.stroke.createStrokedShape(s);

@@ -69,107 +76,119 @@
         }
 
         renderPath(sg, s, bs);
     }
 
+    @Override
     public void fill(SunGraphics2D sg, Shape s) {
         renderPath(sg, s, null);
     }
 
+    @Override
     public void fillParallelogram(SunGraphics2D sg,
                                   double ux1, double uy1,
                                   double ux2, double uy2,
                                   double x, double y,
                                   double dx1, double dy1,
                                   double dx2, double dy2)
     {
-        Region clip = sg.getCompClip();
-        final TileState ts = tileStateThreadLocal.get();
-        final int[] abox = ts.abox;
-
-        AATileGenerator aatg =
-            renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0,
-                                            clip, abox);
-        if (aatg == null) {
-            // Nothing to render
-            return;
-        }
+        final TileState ts = tileStateProvider.acquire();
+        try {
+            final int[] abox = ts.abox;
 
-        renderTiles(sg, ts.computeBBox(ux1, uy1, ux2, uy2), aatg, abox, ts);
+            final AATileGenerator aatg =
+                renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0,
+                                                sg.getCompClip(), abox);
+            if (aatg != null) {
+                renderTiles(sg, ts.computeBBox(ux1, uy1, ux2, uy2),
+                            aatg, abox, ts);
+            }
+        } finally {
+            tileStateProvider.release(ts);
+        }
     }
 
+    @Override
     public void drawParallelogram(SunGraphics2D sg,
                                   double ux1, double uy1,
                                   double ux2, double uy2,
                                   double x, double y,
                                   double dx1, double dy1,
                                   double dx2, double dy2,
                                   double lw1, double lw2)
     {
-        Region clip = sg.getCompClip();
-        final TileState ts = tileStateThreadLocal.get();
-        final int[] abox = ts.abox;
-
-        AATileGenerator aatg =
-            renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, lw1, lw2,
-                                            clip, abox);
-        if (aatg == null) {
-            // Nothing to render
-            return;
-        }
+        final TileState ts = tileStateProvider.acquire();
+        try {
+            final int[] abox = ts.abox;
 
-        // Note that bbox is of the original shape, not the wide path.
-        // This is appropriate for handing to Paint methods...
-        renderTiles(sg, ts.computeBBox(ux1, uy1, ux2, uy2), aatg, abox, ts);
+            final AATileGenerator aatg =
+                renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, lw1,
+                                                lw2, sg.getCompClip(), abox);
+            if (aatg != null) {
+                // Note that bbox is of the original shape, not the wide path.
+                // This is appropriate for handing to Paint methods...
+                renderTiles(sg, ts.computeBBox(ux1, uy1, ux2, uy2),
+                            aatg, abox, ts);
+            }
+        } finally {
+            tileStateProvider.release(ts);
+        }
     }
 
     public void renderPath(SunGraphics2D sg, Shape s, BasicStroke bs) {
-        boolean adjust = (bs != null &&
+        final boolean adjust = (bs != null &&
                           sg.strokeHint != SunHints.INTVAL_STROKE_PURE);
-        boolean thin = (sg.strokeState <= SunGraphics2D.STROKE_THINDASHED);
+        final boolean thin = (sg.strokeState <= SunGraphics2D.STROKE_THINDASHED);
 
-        Region clip = sg.getCompClip();
-        final TileState ts = tileStateThreadLocal.get();
-        final int[] abox = ts.abox;
+        final TileState ts = tileStateProvider.acquire();
+        try {
+            final int[] abox = ts.abox;
 
-        AATileGenerator aatg =
-            renderengine.getAATileGenerator(s, sg.transform, clip,
-                                            bs, thin, adjust, abox);
-        if (aatg == null) {
-            // Nothing to render
-            return;
+            final AATileGenerator aatg =
+                renderengine.getAATileGenerator(s, sg.transform, sg.getCompClip(),
+                                                bs, thin, adjust, abox);
+            if (aatg != null) {
+                renderTiles(sg, s, aatg, abox, ts);
+            }
+        } finally {
+            tileStateProvider.release(ts);
         }
-
-        renderTiles(sg, s, aatg, abox, ts);
     }
 
     public void renderTiles(SunGraphics2D sg, Shape s,
-                            AATileGenerator aatg, int abox[], TileState ts)
+                            final AATileGenerator aatg,
+                            final int[] abox, final TileState ts)
     {
         Object context = null;
         try {
+            // reentrance: outpipe may also use AAShapePipe:
             context = outpipe.startSequence(sg, s,
                                             ts.computeDevBox(abox),
                                             abox);
 
+            // copy of int[] abox as local variables for performance:
+            final int x0 = abox[0];
+            final int y0 = abox[1];
+            final int x1 = abox[2];
+            final int y1 = abox[3];
+
             final int tw = aatg.getTileWidth();
             final int th = aatg.getTileHeight();
 
             // get tile from thread local storage:
             final byte[] alpha = ts.getAlphaTile(tw * th);
             byte[] atile;
 
-            for (int y = abox[1]; y < abox[3]; y += th) {
-                int h = Math.min(th, abox[3] - y);
+            for (int y = y0; y < y1; y += th) {
+                final int h = Math.min(th, y1 - y);
 
-                for (int x = abox[0]; x < abox[2]; x += tw) {
-                    int w = Math.min(tw, abox[2] - x);
+                for (int x = x0; x < x1; x += tw) {
+                    final int w = Math.min(tw, x1 - x);
 
-                    int a = aatg.getTypicalAlpha();
-                    if (a == 0x00 ||
-                        outpipe.needTile(context, x, y, w, h) == false)
-                    {
+                    final int a = aatg.getTypicalAlpha();
+
+                    if (a == 0x00 || !outpipe.needTile(context, x, y, w, h)) {
                         aatg.nextTile();
                         outpipe.skipTile(context, x, y);
                         continue;
                     }
                     if (a == 0xff) {

@@ -178,12 +197,11 @@
                     } else {
                         atile = alpha;
                         aatg.getAlpha(alpha, 0, tw);
                     }
 
-                    outpipe.renderPathTile(context, atile, 0, tw,
-                                           x, y, w, h);
+                    outpipe.renderPathTile(context, atile, 0, tw, x, y, w, h);
                 }
             }
         } finally {
             aatg.dispose();
             if (context != null) {

@@ -191,11 +209,11 @@
             }
         }
     }
 
     // Tile state used by AAShapePipe
-    static final class TileState {
+    static final class TileState extends ReentrantContext {
         // cached tile (32 x 32 tile by default)
         private byte[] theTile = new byte[32 * 32];
         // dirty aabox array
         final int[] abox = new int[4];
         // dirty bbox rectangle

@@ -238,7 +256,6 @@
             box.width = ux2;
             box.height = uy2;
             return box;
         }
     }
-
 }
< prev index next >