58 final double[] double6 = new double[6]; 59 // shared curve (dirty) (Renderer / Stroker) 60 final DCurve curve = new DCurve(); 61 // MarlinRenderingEngine NormalizingPathIterator NearestPixelCenter: 62 final NormalizingPathIterator nPCPathIterator; 63 // MarlinRenderingEngine NearestPixelQuarter NormalizingPathIterator: 64 final NormalizingPathIterator nPQPathIterator; 65 // MarlinRenderingEngine.TransformingPathConsumer2D 66 final DTransformingPathConsumer2D transformerPC2D; 67 // recycled Path2D instance (weak) 68 private WeakReference<Path2D.Double> refPath2D = null; 69 final DRenderer renderer; 70 final DStroker stroker; 71 // Simplifies out collinear lines 72 final DCollinearSimplifier simplifier = new DCollinearSimplifier(); 73 final DDasher 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 double[] cache = 3 refs */ 85 private final DoubleArrayCache dirtyDoubleCache = new DoubleArrayCache(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 final PathConsumer2DAdapter p2dAdapter = new PathConsumer2DAdapter(); 93 94 95 /** 96 * Constructor 97 * 98 * @param name context name (debugging) 99 */ 100 DRendererContext(final String name) { 101 if (LOG_CREATE_CONTEXT) { 102 MarlinUtils.logInfo("new RendererContext = " + name); 103 } 104 this.cleanerObj = new Object(); 105 106 // create first stats (needed by newOffHeapArray): 107 if (DO_STATS || DO_MONITORS) { 108 stats = RendererStats.createInstance(cleanerObj, name); 109 // push cache stats: 110 stats.cacheStats = new CacheStats[] { cleanIntCache.stats, 111 dirtyIntCache.stats, dirtyDoubleCache.stats, dirtyByteCache.stats 112 }; 113 } else { 114 stats = null; 115 } 116 117 // NormalizingPathIterator instances: 118 nPCPathIterator = new NormalizingPathIterator.NearestPixelCenter(double6); 119 nPQPathIterator = new NormalizingPathIterator.NearestPixelQuarter(double6); 120 121 // MarlinRenderingEngine.TransformingPathConsumer2D 122 transformerPC2D = new DTransformingPathConsumer2D(); 123 124 // Renderer: 125 cache = new MarlinCache(this); 126 renderer = new DRenderer(this); // needs MarlinCache from rdrCtx.cache 127 ptg = new MarlinTileGenerator(stats, renderer, cache); 128 129 stroker = new DStroker(this); 130 dasher = new DDasher(this); 131 } 132 133 /** 134 * Disposes this renderer context: 135 * clean up before reusing this context 136 */ 137 void dispose() { 138 if (DO_STATS) { 139 if (stats.totalOffHeap > stats.totalOffHeapMax) { 140 stats.totalOffHeapMax = stats.totalOffHeap; 141 } 142 stats.totalOffHeap = 0L; 143 } 144 stroking = 0; 145 // if context is maked as DIRTY: 146 if (dirty) { 147 // may happen if an exception if thrown in the pipeline processing: 148 // force cleanup of all possible pipelined blocks (except Renderer): 149 150 // NormalizingPathIterator instances: 151 this.nPCPathIterator.dispose(); 152 this.nPQPathIterator.dispose(); 153 // Dasher: 154 this.dasher.dispose(); 155 // Stroker: 156 this.stroker.dispose(); 157 158 // mark context as CLEAN: 159 dirty = false; 160 } 161 } 162 163 Path2D.Double getPath2D() { 164 // resolve reference: 165 Path2D.Double p2d 166 = (refPath2D != null) ? refPath2D.get() : null; 167 168 // create a new Path2D ? 169 if (p2d == null) { 170 p2d = new Path2D.Double(Path2D.WIND_NON_ZERO, INITIAL_EDGES_COUNT); // 32K 171 172 // update weak reference: 173 refPath2D = new WeakReference<Path2D.Double>(p2d); 174 } 175 // reset the path anyway: 176 p2d.reset(); 177 return p2d; 178 } 179 180 @Override 181 public RendererStats stats() { 182 return stats; 183 } 184 185 @Override 186 public OffHeapArray newOffHeapArray(final long initialSize) { 187 if (DO_STATS) { 188 stats.totalOffHeapInitial += initialSize; 189 } 190 return new OffHeapArray(cleanerObj, initialSize); | 58 final double[] double6 = new double[6]; 59 // shared curve (dirty) (Renderer / Stroker) 60 final DCurve curve = new DCurve(); 61 // MarlinRenderingEngine NormalizingPathIterator NearestPixelCenter: 62 final NormalizingPathIterator nPCPathIterator; 63 // MarlinRenderingEngine NearestPixelQuarter NormalizingPathIterator: 64 final NormalizingPathIterator nPQPathIterator; 65 // MarlinRenderingEngine.TransformingPathConsumer2D 66 final DTransformingPathConsumer2D transformerPC2D; 67 // recycled Path2D instance (weak) 68 private WeakReference<Path2D.Double> refPath2D = null; 69 final DRenderer renderer; 70 final DStroker stroker; 71 // Simplifies out collinear lines 72 final DCollinearSimplifier simplifier = new DCollinearSimplifier(); 73 final DDasher 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 double[] clipRect = new double[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 double[] cache = 4 refs (2 polystack) */ 91 private final DoubleArrayCache dirtyDoubleCache = new DoubleArrayCache(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 final PathConsumer2DAdapter p2dAdapter = new PathConsumer2DAdapter(); 99 100 101 /** 102 * Constructor 103 * 104 * @param name context name (debugging) 105 */ 106 DRendererContext(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, dirtyDoubleCache.stats, dirtyByteCache.stats 118 }; 119 } else { 120 stats = null; 121 } 122 123 // NormalizingPathIterator instances: 124 nPCPathIterator = new NormalizingPathIterator.NearestPixelCenter(double6); 125 nPQPathIterator = new NormalizingPathIterator.NearestPixelQuarter(double6); 126 127 // MarlinRenderingEngine.TransformingPathConsumer2D 128 transformerPC2D = new DTransformingPathConsumer2D(this); 129 130 // Renderer: 131 cache = new MarlinCache(this); 132 renderer = new DRenderer(this); // needs MarlinCache from rdrCtx.cache 133 ptg = new MarlinTileGenerator(stats, renderer, cache); 134 135 stroker = new DStroker(this); 136 dasher = new DDasher(this); 137 } 138 139 /** 140 * Disposes this renderer context: 141 * clean up before reusing this context 142 */ 143 void dispose() { 144 if (DO_STATS) { 145 if (stats.totalOffHeap > stats.totalOffHeapMax) { 146 stats.totalOffHeapMax = stats.totalOffHeap; 147 } 148 stats.totalOffHeap = 0L; 149 } 150 stroking = 0; 151 doClip = false; 152 closedPath = false; 153 154 // if context is maked as DIRTY: 155 if (dirty) { 156 // may happen if an exception if thrown in the pipeline processing: 157 // force cleanup of all possible pipelined blocks (except Renderer): 158 159 // NormalizingPathIterator instances: 160 this.nPCPathIterator.dispose(); 161 this.nPQPathIterator.dispose(); 162 // Dasher: 163 this.dasher.dispose(); 164 // Stroker: 165 this.stroker.dispose(); 166 167 // mark context as CLEAN: 168 dirty = false; 169 } 170 } 171 172 Path2D.Double getPath2D() { 173 // resolve reference: 174 Path2D.Double p2d 175 = (refPath2D != null) ? refPath2D.get() : null; 176 177 // create a new Path2D ? 178 if (p2d == null) { 179 p2d = new Path2D.Double(WIND_NON_ZERO, INITIAL_EDGES_COUNT); // 32K 180 181 // update weak reference: 182 refPath2D = new WeakReference<Path2D.Double>(p2d); 183 } 184 // reset the path anyway: 185 p2d.reset(); 186 return p2d; 187 } 188 189 @Override 190 public RendererStats stats() { 191 return stats; 192 } 193 194 @Override 195 public OffHeapArray newOffHeapArray(final long initialSize) { 196 if (DO_STATS) { 197 stats.totalOffHeapInitial += initialSize; 198 } 199 return new OffHeapArray(cleanerObj, initialSize); |