58 final float[] float6 = new float[6]; 59 // shared curve (dirty) (Renderer / Stroker) 60 final Curve curve = new Curve(); 61 // MarlinRenderingEngine NormalizingPathIterator NearestPixelCenter: 62 final NormalizingPathIterator nPCPathIterator; 63 // MarlinRenderingEngine NearestPixelQuarter NormalizingPathIterator: 64 final NormalizingPathIterator nPQPathIterator; 65 // MarlinRenderingEngine.TransformingPathConsumer2D 66 final TransformingPathConsumer2D transformerPC2D; 67 // recycled Path2D instance (weak) 68 private WeakReference<Path2D.Float> refPath2D = null; 69 final Renderer renderer; 70 final Stroker stroker; 71 // Simplifies out collinear lines 72 final CollinearSimplifier simplifier = new CollinearSimplifier(); 73 final Dasher dasher; 74 final MarlinTileGenerator ptg; 75 final MarlinCache cache; 76 // flag indicating the shape is stroked (1) or filled (0) 77 int stroking = 0; 78 79 // Array caches: 80 /* clean int[] cache (zero-filled) = 5 refs */ 81 private final IntArrayCache cleanIntCache = new IntArrayCache(true, 5); 82 /* dirty int[] cache = 4 refs */ 83 private final IntArrayCache dirtyIntCache = new IntArrayCache(false, 4); 84 /* dirty float[] cache = 3 refs */ 85 private final FloatArrayCache dirtyFloatCache = new FloatArrayCache(false, 3); 86 /* dirty byte[] cache = 1 ref */ 87 private final ByteArrayCache dirtyByteCache = new ByteArrayCache(false, 1); 88 89 // RendererContext statistics 90 final RendererStats stats; 91 92 /** 93 * Constructor 94 * 95 * @param name context name (debugging) 96 */ 97 RendererContext(final String name) { 98 if (LOG_CREATE_CONTEXT) { 99 MarlinUtils.logInfo("new RendererContext = " + name); 100 } 101 this.cleanerObj = new Object(); 102 103 // create first stats (needed by newOffHeapArray): 104 if (DO_STATS || DO_MONITORS) { 105 stats = RendererStats.createInstance(cleanerObj, name); 106 // push cache stats: 107 stats.cacheStats = new CacheStats[] { cleanIntCache.stats, 108 dirtyIntCache.stats, dirtyFloatCache.stats, dirtyByteCache.stats 109 }; 110 } else { 111 stats = null; 112 } 113 114 // NormalizingPathIterator instances: 115 nPCPathIterator = new NormalizingPathIterator.NearestPixelCenter(float6); 116 nPQPathIterator = new NormalizingPathIterator.NearestPixelQuarter(float6); 117 118 // MarlinRenderingEngine.TransformingPathConsumer2D 119 transformerPC2D = new TransformingPathConsumer2D(); 120 121 // Renderer: 122 cache = new MarlinCache(this); 123 renderer = new Renderer(this); // needs MarlinCache from rdrCtx.cache 124 ptg = new MarlinTileGenerator(stats, renderer, cache); 125 126 stroker = new Stroker(this); 127 dasher = new Dasher(this); 128 } 129 130 /** 131 * Disposes this renderer context: 132 * clean up before reusing this context 133 */ 134 void dispose() { 135 if (DO_STATS) { 136 if (stats.totalOffHeap > stats.totalOffHeapMax) { 137 stats.totalOffHeapMax = stats.totalOffHeap; 138 } 139 stats.totalOffHeap = 0L; 140 } 141 stroking = 0; 142 // if context is maked as DIRTY: 143 if (dirty) { 144 // may happen if an exception if thrown in the pipeline processing: 145 // force cleanup of all possible pipelined blocks (except Renderer): 146 147 // NormalizingPathIterator instances: 148 this.nPCPathIterator.dispose(); 149 this.nPQPathIterator.dispose(); 150 // Dasher: 151 this.dasher.dispose(); 152 // Stroker: 153 this.stroker.dispose(); 154 155 // mark context as CLEAN: 156 dirty = false; 157 } 158 } 159 160 Path2D.Float getPath2D() { 161 // resolve reference: 162 Path2D.Float p2d 163 = (refPath2D != null) ? refPath2D.get() : null; 164 165 // create a new Path2D ? 166 if (p2d == null) { 167 p2d = new Path2D.Float(Path2D.WIND_NON_ZERO, INITIAL_EDGES_COUNT); // 32K 168 169 // update weak reference: 170 refPath2D = new WeakReference<Path2D.Float>(p2d); 171 } 172 // reset the path anyway: 173 p2d.reset(); 174 return p2d; 175 } 176 177 @Override 178 public RendererStats stats() { 179 return stats; 180 } 181 182 @Override 183 public OffHeapArray newOffHeapArray(final long initialSize) { 184 if (DO_STATS) { 185 stats.totalOffHeapInitial += initialSize; 186 } 187 return new OffHeapArray(cleanerObj, initialSize); | 58 final float[] float6 = new float[6]; 59 // shared curve (dirty) (Renderer / Stroker) 60 final Curve curve = new Curve(); 61 // MarlinRenderingEngine NormalizingPathIterator NearestPixelCenter: 62 final NormalizingPathIterator nPCPathIterator; 63 // MarlinRenderingEngine NearestPixelQuarter NormalizingPathIterator: 64 final NormalizingPathIterator nPQPathIterator; 65 // MarlinRenderingEngine.TransformingPathConsumer2D 66 final TransformingPathConsumer2D transformerPC2D; 67 // recycled Path2D instance (weak) 68 private WeakReference<Path2D.Float> refPath2D = null; 69 final Renderer renderer; 70 final Stroker stroker; 71 // Simplifies out collinear lines 72 final CollinearSimplifier simplifier = new CollinearSimplifier(); 73 final Dasher dasher; 74 final MarlinTileGenerator ptg; 75 final MarlinCache cache; 76 // flag indicating the shape is stroked (1) or filled (0) 77 int stroking = 0; 78 // flag indicating to clip the shape 79 boolean doClip = false; 80 // flag indicating if the path is closed or not (in advance) to handle properly caps 81 boolean closedPath = false; 82 // clip rectangle (ymin, ymax, xmin, xmax): 83 final float[] clipRect = new float[4]; 84 85 // Array caches: 86 /* clean int[] cache (zero-filled) = 5 refs */ 87 private final IntArrayCache cleanIntCache = new IntArrayCache(true, 5); 88 /* dirty int[] cache = 5 refs */ 89 private final IntArrayCache dirtyIntCache = new IntArrayCache(false, 5); 90 /* dirty float[] cache = 4 refs (2 polystack) */ 91 private final FloatArrayCache dirtyFloatCache = new FloatArrayCache(false, 4); 92 /* dirty byte[] cache = 2 ref (2 polystack) */ 93 private final ByteArrayCache dirtyByteCache = new ByteArrayCache(false, 2); 94 95 // RendererContext statistics 96 final RendererStats stats; 97 98 /** 99 * Constructor 100 * 101 * @param name context name (debugging) 102 */ 103 RendererContext(final String name) { 104 if (LOG_CREATE_CONTEXT) { 105 MarlinUtils.logInfo("new RendererContext = " + name); 106 } 107 this.cleanerObj = new Object(); 108 109 // create first stats (needed by newOffHeapArray): 110 if (DO_STATS || DO_MONITORS) { 111 stats = RendererStats.createInstance(cleanerObj, name); 112 // push cache stats: 113 stats.cacheStats = new CacheStats[] { cleanIntCache.stats, 114 dirtyIntCache.stats, dirtyFloatCache.stats, dirtyByteCache.stats 115 }; 116 } else { 117 stats = null; 118 } 119 120 // NormalizingPathIterator instances: 121 nPCPathIterator = new NormalizingPathIterator.NearestPixelCenter(float6); 122 nPQPathIterator = new NormalizingPathIterator.NearestPixelQuarter(float6); 123 124 // MarlinRenderingEngine.TransformingPathConsumer2D 125 transformerPC2D = new TransformingPathConsumer2D(this); 126 127 // Renderer: 128 cache = new MarlinCache(this); 129 renderer = new Renderer(this); // needs MarlinCache from rdrCtx.cache 130 ptg = new MarlinTileGenerator(stats, renderer, cache); 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 void dispose() { 141 if (DO_STATS) { 142 if (stats.totalOffHeap > stats.totalOffHeapMax) { 143 stats.totalOffHeapMax = stats.totalOffHeap; 144 } 145 stats.totalOffHeap = 0L; 146 } 147 stroking = 0; 148 doClip = false; 149 closedPath = false; 150 151 // if context is maked as DIRTY: 152 if (dirty) { 153 // may happen if an exception if thrown in the pipeline processing: 154 // force cleanup of all possible pipelined blocks (except Renderer): 155 156 // NormalizingPathIterator instances: 157 this.nPCPathIterator.dispose(); 158 this.nPQPathIterator.dispose(); 159 // Dasher: 160 this.dasher.dispose(); 161 // Stroker: 162 this.stroker.dispose(); 163 164 // mark context as CLEAN: 165 dirty = false; 166 } 167 } 168 169 Path2D.Float getPath2D() { 170 // resolve reference: 171 Path2D.Float p2d 172 = (refPath2D != null) ? refPath2D.get() : null; 173 174 // create a new Path2D ? 175 if (p2d == null) { 176 p2d = new Path2D.Float(WIND_NON_ZERO, INITIAL_EDGES_COUNT); // 32K 177 178 // update weak reference: 179 refPath2D = new WeakReference<Path2D.Float>(p2d); 180 } 181 // reset the path anyway: 182 p2d.reset(); 183 return p2d; 184 } 185 186 @Override 187 public RendererStats stats() { 188 return stats; 189 } 190 191 @Override 192 public OffHeapArray newOffHeapArray(final long initialSize) { 193 if (DO_STATS) { 194 stats.totalOffHeapInitial += initialSize; 195 } 196 return new OffHeapArray(cleanerObj, initialSize); |