package sun.java2d.marlin;
import java.awt.geom.Path2D;
import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicInteger;
import sun.java2d.ReentrantContext;
import sun.java2d.marlin.ArrayCacheConst.CacheStats;
import sun.java2d.marlin.DMarlinRenderingEngine.NormalizingPathIterator;
import sun.java2d.marlin.DTransformingPathConsumer2D.CurveBasicMonotonizer;
import sun.java2d.marlin.DTransformingPathConsumer2D.CurveClipSplitter;
final class DRendererContext extends ReentrantContext implements IRendererContext {
private static final AtomicInteger CTX_COUNT = new AtomicInteger(1);
static DRendererContext createContext() {
return new DRendererContext("ctx"
+ Integer.toString(CTX_COUNT.getAndIncrement()));
}
private final Object cleanerObj;
boolean dirty = false;
final double[] double6 = new double[6];
final DCurve curve = new DCurve();
final NormalizingPathIterator nPCPathIterator;
final NormalizingPathIterator nPQPathIterator;
final DTransformingPathConsumer2D transformerPC2D;
private WeakReference<Path2D.Double> refPath2D = null;
final DRenderer renderer;
final DStroker stroker;
final DCollinearSimplifier simplifier = new DCollinearSimplifier();
final DPathSimplifier pathSimplifier = new DPathSimplifier();
final DDasher dasher;
final MarlinTileGenerator ptg;
final MarlinCache cache;
int stroking = 0;
boolean doClip = false;
boolean closedPath = false;
final double[] clipRect = new double[4];
double clipInvScale = 0.0d;
final CurveBasicMonotonizer monotonizer;
final CurveClipSplitter curveClipSplitter;
private final IntArrayCache cleanIntCache = new IntArrayCache(true, 5);
private final IntArrayCache dirtyIntCache = new IntArrayCache(false, 5);
private final DoubleArrayCache dirtyDoubleCache = new DoubleArrayCache(false, 4);
private final ByteArrayCache dirtyByteCache = new ByteArrayCache(false, 2);
final RendererStats stats;
final PathConsumer2DAdapter p2dAdapter = new PathConsumer2DAdapter();
DRendererContext(final String name) {
if (LOG_CREATE_CONTEXT) {
MarlinUtils.logInfo("new RendererContext = " + name);
}
this.cleanerObj = new Object();
if (DO_STATS || DO_MONITORS) {
stats = RendererStats.createInstance(cleanerObj, name);
stats.cacheStats = new CacheStats[] { cleanIntCache.stats,
dirtyIntCache.stats, dirtyDoubleCache.stats, dirtyByteCache.stats
};
} else {
stats = null;
}
nPCPathIterator = new NormalizingPathIterator.NearestPixelCenter(double6);
nPQPathIterator = new NormalizingPathIterator.NearestPixelQuarter(double6);
monotonizer = new CurveBasicMonotonizer(this);
curveClipSplitter = new CurveClipSplitter(this);
transformerPC2D = new DTransformingPathConsumer2D(this);
cache = new MarlinCache(this);
renderer = new DRenderer(this);
ptg = new MarlinTileGenerator(stats, renderer, cache);
stroker = new DStroker(this);
dasher = new DDasher(this);
}
void dispose() {
if (DO_STATS) {
if (stats.totalOffHeap > stats.totalOffHeapMax) {
stats.totalOffHeapMax = stats.totalOffHeap;
}
stats.totalOffHeap = 0L;
}
stroking = 0;
doClip = false;
closedPath = false;
clipInvScale = 0.0d;
if (dirty) {
this.nPCPathIterator.dispose();
this.nPQPathIterator.dispose();
this.dasher.dispose();
this.stroker.dispose();
dirty = false;
}
}
Path2D.Double getPath2D() {
Path2D.Double p2d = (refPath2D != null) ? refPath2D.get() : null;
if (p2d == null) {
p2d = new Path2D.Double(WIND_NON_ZERO, INITIAL_EDGES_COUNT);
refPath2D = new WeakReference<Path2D.Double>(p2d);
}
p2d.reset();
return p2d;
}
@Override
public RendererStats stats() {
return stats;
}
@Override
public OffHeapArray newOffHeapArray(final long initialSize) {
if (DO_STATS) {
stats.totalOffHeapInitial += initialSize;
}
return new OffHeapArray(cleanerObj, initialSize);
}
@Override
public IntArrayCache.Reference newCleanIntArrayRef(final int initialSize) {
return cleanIntCache.createRef(initialSize);
}
IntArrayCache.Reference newDirtyIntArrayRef(final int initialSize) {
return dirtyIntCache.createRef(initialSize);
}
DoubleArrayCache.Reference newDirtyDoubleArrayRef(final int initialSize) {
return dirtyDoubleCache.createRef(initialSize);
}
ByteArrayCache.Reference newDirtyByteArrayRef(final int initialSize) {
return dirtyByteCache.createRef(initialSize);
}
static final class PathConsumer2DAdapter implements DPathConsumer2D {
private sun.awt.geom.PathConsumer2D out;
PathConsumer2DAdapter() {}
PathConsumer2DAdapter init(sun.awt.geom.PathConsumer2D out) {
this.out = out;
return this;
}
@Override
public void moveTo(double x0, double y0) {
out.moveTo((float)x0, (float)y0);
}
@Override
public void lineTo(double x1, double y1) {
out.lineTo((float)x1, (float)y1);
}
@Override
public void closePath() {
out.closePath();
}
@Override
public void pathDone() {
out.pathDone();
}
@Override
public void curveTo(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
out.curveTo((float)x1, (float)y1,
(float)x2, (float)y2,
(float)x3, (float)y3);
}
@Override
public void quadTo(double x1, double y1, double x2, double y2) {
out.quadTo((float)x1, (float)y1, (float)x2, (float)y2);
}
@Override
public long getNativeConsumer() {
throw new InternalError("Not using a native peer");
}
}
}