1 /* 2 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 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 com.sun.javafx.geom.Path2D; 29 import java.util.concurrent.atomic.AtomicInteger; 30 import com.sun.util.reentrant.ReentrantContext; 31 import com.sun.javafx.geom.Rectangle; 32 import com.sun.marlin.ArrayCacheConst.CacheStats; 33 import java.lang.ref.WeakReference; 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> refPath2D = null; 65 // shared memory between renderer instances: 66 final RendererSharedMemory rdrMem; 67 public final Renderer renderer; 68 private RendererNoAA rendererNoAA = null; 69 public final Stroker stroker; 70 // Simplifies out collinear lines 71 public final CollinearSimplifier simplifier = new CollinearSimplifier(); 72 public final Dasher dasher; 73 // flag indicating the shape is stroked (1) or filled (0) 74 int stroking = 0; 75 // flag indicating to clip the shape 76 public boolean doClip = false; 77 // flag indicating if the path is closed or not (in advance) to handle properly caps 78 boolean closedPath = false; 79 // clip rectangle (ymin, ymax, xmin, xmax): 80 public final float[] clipRect = new float[4]; 81 82 // MarlinFX specific: 83 // dirty bbox rectangle 84 public final Rectangle clip = new Rectangle(); 85 // dirty MaskMarlinAlphaConsumer 86 public MaskMarlinAlphaConsumer consumer = null; 87 88 // Array caches: 89 /* clean int[] cache (zero-filled) = 5 refs */ 90 private final IntArrayCache cleanIntCache = new IntArrayCache(true, 5); 91 /* dirty int[] cache = 5 refs */ 92 private final IntArrayCache dirtyIntCache = new IntArrayCache(false, 5); 93 /* dirty float[] cache = 4 refs (2 polystack) */ 94 private final FloatArrayCache dirtyFloatCache = new FloatArrayCache(false, 4); 95 /* dirty byte[] cache = 2 ref (2 polystack) */ 96 private final ByteArrayCache dirtyByteCache = new ByteArrayCache(false, 2); 97 98 // RendererContext statistics 99 final RendererStats stats; 100 101 /** 102 * Constructor 103 * 104 * @param name context name (debugging) 105 */ 106 RendererContext(final String name) { 107 if (LOG_CREATE_CONTEXT) { 108 MarlinUtils.logInfo("new RendererContext = " + name); 109 } 110 this.cleanerObj = new Object(); 111 112 // create first stats (needed by newOffHeapArray): 113 if (DO_STATS || DO_MONITORS) { 114 stats = RendererStats.createInstance(cleanerObj, name); 115 // push cache stats: 116 stats.cacheStats = new CacheStats[] { cleanIntCache.stats, 117 dirtyIntCache.stats, dirtyFloatCache.stats, dirtyByteCache.stats 118 }; 119 } else { 120 stats = null; 121 } 122 123 // MarlinRenderingEngine.TransformingPathConsumer2D 124 transformerPC2D = new TransformingPathConsumer2D(this); 125 126 // Renderer shared memory: 127 rdrMem = new RendererSharedMemory(this); 128 129 // Renderer: 130 renderer = new Renderer(this); 131 132 stroker = new Stroker(this); 133 dasher = new Dasher(this); 134 } 135 136 /** 137 * Disposes this renderer context: 138 * clean up before reusing this context 139 */ 140 public void dispose() { 141 if (DO_STATS) { 142 if (stats.totalOffHeap > stats.totalOffHeapMax) { 224 225 // crossings ref (dirty) 226 final IntArrayCache.Reference crossings_ref; 227 // edgePtrs ref (dirty) 228 final IntArrayCache.Reference edgePtrs_ref; 229 // merge sort initial arrays 230 // aux_crossings ref (dirty) 231 final IntArrayCache.Reference aux_crossings_ref; 232 // aux_edgePtrs ref (dirty) 233 final IntArrayCache.Reference aux_edgePtrs_ref; 234 235 // blkFlags ref (clean) 236 final IntArrayCache.Reference blkFlags_ref; 237 238 RendererSharedMemory(final RendererContext rdrCtx) { 239 edges = rdrCtx.newOffHeapArray(INITIAL_EDGES_CAPACITY); // 96K 240 241 edgeBuckets_ref = rdrCtx.newCleanIntArrayRef(INITIAL_BUCKET_ARRAY); // 64K 242 edgeBucketCounts_ref = rdrCtx.newCleanIntArrayRef(INITIAL_BUCKET_ARRAY); // 64K 243 244 // 2048 (pixelsize) pixel large 245 alphaLine_ref = rdrCtx.newCleanIntArrayRef(INITIAL_AA_ARRAY); // 8K 246 247 crossings_ref = rdrCtx.newDirtyIntArrayRef(INITIAL_CROSSING_COUNT); // 2K 248 aux_crossings_ref = rdrCtx.newDirtyIntArrayRef(INITIAL_CROSSING_COUNT); // 2K 249 edgePtrs_ref = rdrCtx.newDirtyIntArrayRef(INITIAL_CROSSING_COUNT); // 2K 250 aux_edgePtrs_ref = rdrCtx.newDirtyIntArrayRef(INITIAL_CROSSING_COUNT); // 2K 251 252 blkFlags_ref = rdrCtx.newCleanIntArrayRef(INITIAL_ARRAY); // 1K = 1 tile line 253 } 254 } 255 } | 1 /* 2 * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 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.lang.ref.WeakReference; 29 import java.util.concurrent.atomic.AtomicInteger; 30 import com.sun.javafx.geom.Path2D; 31 import com.sun.javafx.geom.Rectangle; 32 import com.sun.marlin.ArrayCacheConst.CacheStats; 33 import com.sun.marlin.TransformingPathConsumer2D.CurveBasicMonotonizer; 34 import com.sun.marlin.TransformingPathConsumer2D.CurveClipSplitter; 35 import com.sun.util.reentrant.ReentrantContext; 36 37 /** 38 * This class is a renderer context dedicated to a single thread 39 */ 40 public final class RendererContext extends ReentrantContext implements MarlinConst { 41 42 // RendererContext creation counter 43 private static final AtomicInteger CTX_COUNT = new AtomicInteger(1); 44 45 /** 46 * Create a new renderer context 47 * 48 * @return new RendererContext instance 49 */ 50 public static RendererContext createContext() { 51 return new RendererContext("ctx" 52 + Integer.toString(CTX_COUNT.getAndIncrement())); 53 } 54 55 // Smallest object used as Cleaner's parent reference 56 private final Object cleanerObj; 57 // dirty flag indicating an exception occured during pipeline in pathTo() 58 public boolean dirty = false; 59 // shared data 60 public final float[] float6 = new float[6]; 61 // shared curve (dirty) (Renderer / Stroker) 62 final Curve curve = new Curve(); 63 // MarlinRenderingEngine.TransformingPathConsumer2D 64 public final TransformingPathConsumer2D transformerPC2D; 65 // recycled Path2D instance (weak) 66 private WeakReference<Path2D> refPath2D = null; 67 public final Renderer renderer; 68 public final Stroker stroker; 69 // Simplifies out collinear lines 70 public final CollinearSimplifier simplifier = new CollinearSimplifier(); 71 // Simplifies path 72 public final PathSimplifier pathSimplifier = new PathSimplifier(); 73 public final Dasher dasher; 74 // flag indicating the shape is stroked (1) or filled (0) 75 int stroking = 0; 76 // flag indicating to clip the shape 77 public boolean doClip = false; 78 // flag indicating if the path is closed or not (in advance) to handle properly caps 79 boolean closedPath = false; 80 // clip rectangle (ymin, ymax, xmin, xmax): 81 public final float[] clipRect = new float[4]; 82 // CurveBasicMonotonizer instance 83 public final CurveBasicMonotonizer monotonizer; 84 // CurveClipSplitter instance 85 final CurveClipSplitter curveClipSplitter; 86 87 // MarlinFX specific: 88 // shared memory between renderer instances: 89 final RendererSharedMemory rdrMem; 90 private RendererNoAA rendererNoAA = null; 91 // dirty bbox rectangle 92 public final Rectangle clip = new Rectangle(); 93 // dirty MaskMarlinAlphaConsumer 94 public MaskMarlinAlphaConsumer consumer = null; 95 96 // Array caches: 97 /* clean int[] cache (zero-filled) = 5 refs */ 98 private final IntArrayCache cleanIntCache = new IntArrayCache(true, 5); 99 /* dirty int[] cache = 5 refs */ 100 private final IntArrayCache dirtyIntCache = new IntArrayCache(false, 5); 101 /* dirty float[] cache = 4 refs (2 polystack) */ 102 private final FloatArrayCache dirtyFloatCache = new FloatArrayCache(false, 4); 103 /* dirty byte[] cache = 2 ref (2 polystack) */ 104 private final ByteArrayCache dirtyByteCache = new ByteArrayCache(false, 2); 105 106 // RendererContext statistics 107 final RendererStats stats; 108 109 /** 110 * Constructor 111 * 112 * @param name context name (debugging) 113 */ 114 RendererContext(final String name) { 115 if (LOG_CREATE_CONTEXT) { 116 MarlinUtils.logInfo("new RendererContext = " + name); 117 } 118 this.cleanerObj = new Object(); 119 120 // create first stats (needed by newOffHeapArray): 121 if (DO_STATS || DO_MONITORS) { 122 stats = RendererStats.createInstance(cleanerObj, name); 123 // push cache stats: 124 stats.cacheStats = new CacheStats[] { cleanIntCache.stats, 125 dirtyIntCache.stats, dirtyFloatCache.stats, dirtyByteCache.stats 126 }; 127 } else { 128 stats = null; 129 } 130 131 // curve monotonizer & clip subdivider (before transformerPC2D init) 132 monotonizer = new CurveBasicMonotonizer(this); 133 curveClipSplitter = new CurveClipSplitter(this); 134 135 // MarlinRenderingEngine.TransformingPathConsumer2D 136 transformerPC2D = new TransformingPathConsumer2D(this); 137 138 // Renderer shared memory: 139 rdrMem = new RendererSharedMemory(this); 140 141 // Renderer: 142 renderer = new Renderer(this); 143 144 stroker = new Stroker(this); 145 dasher = new Dasher(this); 146 } 147 148 /** 149 * Disposes this renderer context: 150 * clean up before reusing this context 151 */ 152 public void dispose() { 153 if (DO_STATS) { 154 if (stats.totalOffHeap > stats.totalOffHeapMax) { 236 237 // crossings ref (dirty) 238 final IntArrayCache.Reference crossings_ref; 239 // edgePtrs ref (dirty) 240 final IntArrayCache.Reference edgePtrs_ref; 241 // merge sort initial arrays 242 // aux_crossings ref (dirty) 243 final IntArrayCache.Reference aux_crossings_ref; 244 // aux_edgePtrs ref (dirty) 245 final IntArrayCache.Reference aux_edgePtrs_ref; 246 247 // blkFlags ref (clean) 248 final IntArrayCache.Reference blkFlags_ref; 249 250 RendererSharedMemory(final RendererContext rdrCtx) { 251 edges = rdrCtx.newOffHeapArray(INITIAL_EDGES_CAPACITY); // 96K 252 253 edgeBuckets_ref = rdrCtx.newCleanIntArrayRef(INITIAL_BUCKET_ARRAY); // 64K 254 edgeBucketCounts_ref = rdrCtx.newCleanIntArrayRef(INITIAL_BUCKET_ARRAY); // 64K 255 256 // 4096 pixels large 257 alphaLine_ref = rdrCtx.newCleanIntArrayRef(INITIAL_AA_ARRAY); // 16K 258 259 crossings_ref = rdrCtx.newDirtyIntArrayRef(INITIAL_CROSSING_COUNT); // 2K 260 aux_crossings_ref = rdrCtx.newDirtyIntArrayRef(INITIAL_CROSSING_COUNT); // 2K 261 edgePtrs_ref = rdrCtx.newDirtyIntArrayRef(INITIAL_CROSSING_COUNT); // 2K 262 aux_edgePtrs_ref = rdrCtx.newDirtyIntArrayRef(INITIAL_CROSSING_COUNT); // 2K 263 264 blkFlags_ref = rdrCtx.newCleanIntArrayRef(INITIAL_ARRAY); // 1K = 1 tile line 265 } 266 } 267 } |