8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.marlin; 27 28 import java.awt.geom.Path2D; 29 import java.lang.ref.WeakReference; 30 import java.util.concurrent.atomic.AtomicInteger; 31 import com.sun.util.reentrant.ReentrantContext; 32 import com.sun.javafx.geom.Rectangle; 33 import com.sun.marlin.ArrayCacheConst.CacheStats; 34 35 /** 36 * This class is a renderer context dedicated to a single thread 37 */ 38 public final class RendererContext extends ReentrantContext implements MarlinConst { 39 40 // RendererContext creation counter 41 private static final AtomicInteger CTX_COUNT = new AtomicInteger(1); 42 43 /** 44 * Create a new renderer context 45 * 46 * @return new RendererContext instance 47 */ 48 public static RendererContext createContext() { 49 return new RendererContext("ctx" 50 + Integer.toString(CTX_COUNT.getAndIncrement())); 51 } 52 53 // Smallest object used as Cleaner's parent reference 54 private final Object cleanerObj; 55 // dirty flag indicating an exception occured during pipeline in pathTo() 56 public boolean dirty = false; 57 // shared data 58 public final float[] float6 = new float[6]; 59 // shared curve (dirty) (Renderer / Stroker) 60 final Curve curve = new Curve(); 61 // MarlinRenderingEngine.TransformingPathConsumer2D 62 public final TransformingPathConsumer2D transformerPC2D; 63 // recycled Path2D instance (weak) 64 private WeakReference<Path2D.Float> refPath2D = null; 65 public final Renderer renderer; 66 private RendererNoAA rendererNoAA = null; 67 public final Stroker stroker; 68 // Simplifies out collinear lines 69 public final CollinearSimplifier simplifier = new CollinearSimplifier(); 70 public final Dasher dasher; 71 // flag indicating the shape is stroked (1) or filled (0) 72 int stroking = 0; 73 74 // MarlinFX specific: 75 // dirty bbox rectangle 76 public final Rectangle clip = new Rectangle(); 77 // dirty MaskMarlinAlphaConsumer 78 public MaskMarlinAlphaConsumer consumer = null; 79 80 // Array caches: 81 /* clean int[] cache (zero-filled) = 5 refs */ 82 private final IntArrayCache cleanIntCache = new IntArrayCache(true, 5); 83 /* dirty int[] cache = 4 refs */ 84 private final IntArrayCache dirtyIntCache = new IntArrayCache(false, 4); 85 /* dirty float[] cache = 3 refs */ 86 private final FloatArrayCache dirtyFloatCache = new FloatArrayCache(false, 3); 87 /* dirty byte[] cache = 1 ref */ 88 private final ByteArrayCache dirtyByteCache = new ByteArrayCache(false, 1); 89 90 // RendererContext statistics 91 final RendererStats stats; 92 93 /** 94 * Constructor 95 * 96 * @param name context name (debugging) 97 */ 98 RendererContext(final String name) { 99 if (LOG_CREATE_CONTEXT) { 100 MarlinUtils.logInfo("new RendererContext = " + name); 101 } 102 this.cleanerObj = new Object(); 103 104 // create first stats (needed by newOffHeapArray): 105 if (DO_STATS || DO_MONITORS) { 106 stats = RendererStats.createInstance(cleanerObj, name); 107 // push cache stats: 108 stats.cacheStats = new CacheStats[] { cleanIntCache.stats, 109 dirtyIntCache.stats, dirtyFloatCache.stats, dirtyByteCache.stats 110 }; 111 } else { 112 stats = null; 113 } 114 115 // MarlinRenderingEngine.TransformingPathConsumer2D 116 transformerPC2D = new TransformingPathConsumer2D(); 117 118 // Renderer: 119 renderer = new Renderer(this); 120 121 stroker = new Stroker(this); 122 dasher = new Dasher(this); 123 } 124 125 /** 126 * Disposes this renderer context: 127 * clean up before reusing this context 128 */ 129 public void dispose() { 130 if (DO_STATS) { 131 if (stats.totalOffHeap > stats.totalOffHeapMax) { 132 stats.totalOffHeapMax = stats.totalOffHeap; 133 } 134 stats.totalOffHeap = 0L; 135 } 136 stroking = 0; 137 // if context is maked as DIRTY: 138 if (dirty) { 139 // may happen if an exception if thrown in the pipeline processing: 140 // force cleanup of all possible pipelined blocks (except Renderer): 141 142 // Dasher: 143 this.dasher.dispose(); 144 // Stroker: 145 this.stroker.dispose(); 146 147 // mark context as CLEAN: 148 dirty = false; 149 } 150 } 151 152 Path2D.Float getPath2D() { 153 // resolve reference: 154 Path2D.Float p2d 155 = (refPath2D != null) ? refPath2D.get() : null; 156 157 // create a new Path2D ? 158 if (p2d == null) { 159 p2d = new Path2D.Float(Path2D.WIND_NON_ZERO, INITIAL_EDGES_COUNT); // 32K 160 161 // update weak reference: 162 refPath2D = new WeakReference<Path2D.Float>(p2d); 163 } 164 // reset the path anyway: 165 p2d.reset(); 166 return p2d; 167 } 168 169 public RendererNoAA getRendererNoAA() { 170 if (rendererNoAA == null) { 171 rendererNoAA = new RendererNoAA(this); 172 } 173 return rendererNoAA; 174 } 175 176 OffHeapArray newOffHeapArray(final long initialSize) { 177 if (DO_STATS) { 178 stats.totalOffHeapInitial += initialSize; 179 } 180 return new OffHeapArray(cleanerObj, initialSize); 181 } 182 183 IntArrayCache.Reference newCleanIntArrayRef(final int initialSize) { 184 return cleanIntCache.createRef(initialSize); 185 } 186 187 IntArrayCache.Reference newDirtyIntArrayRef(final int initialSize) { 188 return dirtyIntCache.createRef(initialSize); 189 } 190 191 FloatArrayCache.Reference newDirtyFloatArrayRef(final int initialSize) { 192 return dirtyFloatCache.createRef(initialSize); 193 } 194 195 ByteArrayCache.Reference newDirtyByteArrayRef(final int initialSize) { 196 return dirtyByteCache.createRef(initialSize); 197 } 198 } | 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.marlin; 27 28 import java.util.concurrent.atomic.AtomicInteger; 29 import com.sun.util.reentrant.ReentrantContext; 30 import com.sun.javafx.geom.Rectangle; 31 import com.sun.marlin.ArrayCacheConst.CacheStats; 32 33 /** 34 * This class is a renderer context dedicated to a single thread 35 */ 36 public final class DRendererContext extends ReentrantContext implements MarlinConst { 37 38 // RendererContext creation counter 39 private static final AtomicInteger CTX_COUNT = new AtomicInteger(1); 40 41 /** 42 * Create a new renderer context 43 * 44 * @return new RendererContext instance 45 */ 46 public static DRendererContext createContext() { 47 return new DRendererContext("ctx" 48 + Integer.toString(CTX_COUNT.getAndIncrement())); 49 } 50 51 // Smallest object used as Cleaner's parent reference 52 private final Object cleanerObj; 53 // dirty flag indicating an exception occured during pipeline in pathTo() 54 public boolean dirty = false; 55 // shared data 56 public final float[] float6 = new float[6]; 57 // shared curve (dirty) (Renderer / Stroker) 58 final DCurve curve = new DCurve(); 59 // MarlinRenderingEngine.TransformingPathConsumer2D 60 public final DTransformingPathConsumer2D transformerPC2D; 61 public final DRenderer renderer; 62 private DRendererNoAA rendererNoAA = null; 63 public final DStroker stroker; 64 // Simplifies out collinear lines 65 public final DCollinearSimplifier simplifier = new DCollinearSimplifier(); 66 public final DDasher dasher; 67 // flag indicating the shape is stroked (1) or filled (0) 68 int stroking = 0; 69 70 // MarlinFX specific: 71 // dirty bbox rectangle 72 public final Rectangle clip = new Rectangle(); 73 // dirty MaskMarlinAlphaConsumer 74 public MaskMarlinAlphaConsumer consumer = null; 75 76 // Array caches: 77 /* clean int[] cache (zero-filled) = 5 refs */ 78 private final IntArrayCache cleanIntCache = new IntArrayCache(true, 5); 79 /* dirty int[] cache = 4 refs */ 80 private final IntArrayCache dirtyIntCache = new IntArrayCache(false, 4); 81 /* dirty double[] cache = 3 refs */ 82 private final DoubleArrayCache dirtyDoubleCache = new DoubleArrayCache(false, 3); 83 /* dirty byte[] cache = 1 ref */ 84 private final ByteArrayCache dirtyByteCache = new ByteArrayCache(false, 1); 85 86 // RendererContext statistics 87 final RendererStats stats; 88 89 /** 90 * Constructor 91 * 92 * @param name context name (debugging) 93 */ 94 DRendererContext(final String name) { 95 if (LOG_CREATE_CONTEXT) { 96 MarlinUtils.logInfo("new RendererContext = " + name); 97 } 98 this.cleanerObj = new Object(); 99 100 // create first stats (needed by newOffHeapArray): 101 if (DO_STATS || DO_MONITORS) { 102 stats = RendererStats.createInstance(cleanerObj, name); 103 // push cache stats: 104 stats.cacheStats = new CacheStats[] { cleanIntCache.stats, 105 dirtyIntCache.stats, dirtyDoubleCache.stats, dirtyByteCache.stats 106 }; 107 } else { 108 stats = null; 109 } 110 111 // MarlinRenderingEngine.TransformingPathConsumer2D 112 transformerPC2D = new DTransformingPathConsumer2D(); 113 114 // Renderer: 115 renderer = new DRenderer(this); 116 117 stroker = new DStroker(this); 118 dasher = new DDasher(this); 119 } 120 121 /** 122 * Disposes this renderer context: 123 * clean up before reusing this context 124 */ 125 public void dispose() { 126 if (DO_STATS) { 127 if (stats.totalOffHeap > stats.totalOffHeapMax) { 128 stats.totalOffHeapMax = stats.totalOffHeap; 129 } 130 stats.totalOffHeap = 0L; 131 } 132 stroking = 0; 133 // if context is maked as DIRTY: 134 if (dirty) { 135 // may happen if an exception if thrown in the pipeline processing: 136 // force cleanup of all possible pipelined blocks (except Renderer): 137 138 // Dasher: 139 this.dasher.dispose(); 140 // Stroker: 141 this.stroker.dispose(); 142 143 // mark context as CLEAN: 144 dirty = false; 145 } 146 } 147 148 public DRendererNoAA getRendererNoAA() { 149 if (rendererNoAA == null) { 150 rendererNoAA = new DRendererNoAA(this); 151 } 152 return rendererNoAA; 153 } 154 155 OffHeapArray newOffHeapArray(final long initialSize) { 156 if (DO_STATS) { 157 stats.totalOffHeapInitial += initialSize; 158 } 159 return new OffHeapArray(cleanerObj, initialSize); 160 } 161 162 IntArrayCache.Reference newCleanIntArrayRef(final int initialSize) { 163 return cleanIntCache.createRef(initialSize); 164 } 165 166 IntArrayCache.Reference newDirtyIntArrayRef(final int initialSize) { 167 return dirtyIntCache.createRef(initialSize); 168 } 169 170 DoubleArrayCache.Reference newDirtyDoubleArrayRef(final int initialSize) { 171 return dirtyDoubleCache.createRef(initialSize); 172 } 173 174 ByteArrayCache.Reference newDirtyByteArrayRef(final int initialSize) { 175 return dirtyByteCache.createRef(initialSize); 176 } 177 } |