< prev index next >
src/java.desktop/share/classes/sun/java2d/pipe/AAShapePipe.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 26,67 ****
import java.awt.BasicStroke;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import sun.awt.SunHints;
import sun.java2d.SunGraphics2D;
/**
* This class is used to convert raw geometry into 8-bit alpha tiles
* using an AATileGenerator for application by the next stage of
* the pipeline.
* This class sets up the Generator and computes the alpha tiles
* and then passes them on to a CompositePipe object for painting.
*/
! public class AAShapePipe
implements ShapeDrawPipe, ParallelogramPipe
{
! static RenderingEngine renderengine = RenderingEngine.getInstance();
// Per-thread TileState (~1K very small so do not use any Weak Reference)
! private static final ThreadLocal<TileState> tileStateThreadLocal =
! new ThreadLocal<TileState>() {
! @Override
! protected TileState initialValue() {
! return new TileState();
! }
! };
! CompositePipe outpipe;
public AAShapePipe(CompositePipe pipe) {
outpipe = pipe;
}
public void draw(SunGraphics2D sg, Shape s) {
! BasicStroke bs;
if (sg.stroke instanceof BasicStroke) {
bs = (BasicStroke) sg.stroke;
} else {
s = sg.stroke.createStrokedShape(s);
--- 26,74 ----
import java.awt.BasicStroke;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
+ import java.util.concurrent.ConcurrentLinkedQueue;
import sun.awt.SunHints;
+ import sun.java2d.ReentrantContext;
+ import sun.java2d.ReentrantContextProvider;
+ import sun.java2d.ReentrantContextProviderTL;
import sun.java2d.SunGraphics2D;
/**
* This class is used to convert raw geometry into 8-bit alpha tiles
* using an AATileGenerator for application by the next stage of
* the pipeline.
* This class sets up the Generator and computes the alpha tiles
* and then passes them on to a CompositePipe object for painting.
*/
! public final class AAShapePipe
implements ShapeDrawPipe, ParallelogramPipe
{
! static final RenderingEngine renderengine = RenderingEngine.getInstance();
// Per-thread TileState (~1K very small so do not use any Weak Reference)
! private static final ReentrantContextProvider<TileState> tileStateProvider =
! new ReentrantContextProviderTL<TileState>(
! ReentrantContextProvider.REF_HARD)
! {
! @Override
! protected TileState newContext() {
! return new TileState();
! }
! };
! final CompositePipe outpipe;
public AAShapePipe(CompositePipe pipe) {
outpipe = pipe;
}
+ @Override
public void draw(SunGraphics2D sg, Shape s) {
! final BasicStroke bs;
if (sg.stroke instanceof BasicStroke) {
bs = (BasicStroke) sg.stroke;
} else {
s = sg.stroke.createStrokedShape(s);
*** 69,175 ****
}
renderPath(sg, s, bs);
}
public void fill(SunGraphics2D sg, Shape s) {
renderPath(sg, s, null);
}
public void fillParallelogram(SunGraphics2D sg,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
! Region clip = sg.getCompClip();
! final TileState ts = tileStateThreadLocal.get();
! final int[] abox = ts.abox;
!
! AATileGenerator aatg =
! renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0,
! clip, abox);
! if (aatg == null) {
! // Nothing to render
! return;
! }
! renderTiles(sg, ts.computeBBox(ux1, uy1, ux2, uy2), aatg, abox, ts);
}
public void drawParallelogram(SunGraphics2D sg,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2)
{
! Region clip = sg.getCompClip();
! final TileState ts = tileStateThreadLocal.get();
! final int[] abox = ts.abox;
!
! AATileGenerator aatg =
! renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, lw1, lw2,
! clip, abox);
! if (aatg == null) {
! // Nothing to render
! return;
! }
! // Note that bbox is of the original shape, not the wide path.
! // This is appropriate for handing to Paint methods...
! renderTiles(sg, ts.computeBBox(ux1, uy1, ux2, uy2), aatg, abox, ts);
}
public void renderPath(SunGraphics2D sg, Shape s, BasicStroke bs) {
! boolean adjust = (bs != null &&
sg.strokeHint != SunHints.INTVAL_STROKE_PURE);
! boolean thin = (sg.strokeState <= SunGraphics2D.STROKE_THINDASHED);
! Region clip = sg.getCompClip();
! final TileState ts = tileStateThreadLocal.get();
! final int[] abox = ts.abox;
! AATileGenerator aatg =
! renderengine.getAATileGenerator(s, sg.transform, clip,
! bs, thin, adjust, abox);
! if (aatg == null) {
! // Nothing to render
! return;
}
-
- renderTiles(sg, s, aatg, abox, ts);
}
public void renderTiles(SunGraphics2D sg, Shape s,
! AATileGenerator aatg, int abox[], TileState ts)
{
Object context = null;
try {
context = outpipe.startSequence(sg, s,
ts.computeDevBox(abox),
abox);
final int tw = aatg.getTileWidth();
final int th = aatg.getTileHeight();
// get tile from thread local storage:
final byte[] alpha = ts.getAlphaTile(tw * th);
byte[] atile;
! for (int y = abox[1]; y < abox[3]; y += th) {
! int h = Math.min(th, abox[3] - y);
! for (int x = abox[0]; x < abox[2]; x += tw) {
! int w = Math.min(tw, abox[2] - x);
! int a = aatg.getTypicalAlpha();
! if (a == 0x00 ||
! outpipe.needTile(context, x, y, w, h) == false)
! {
aatg.nextTile();
outpipe.skipTile(context, x, y);
continue;
}
if (a == 0xff) {
--- 76,194 ----
}
renderPath(sg, s, bs);
}
+ @Override
public void fill(SunGraphics2D sg, Shape s) {
renderPath(sg, s, null);
}
+ @Override
public void fillParallelogram(SunGraphics2D sg,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
! final TileState ts = tileStateProvider.acquire();
! try {
! final int[] abox = ts.abox;
! final AATileGenerator aatg =
! renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0,
! sg.getCompClip(), abox);
! if (aatg != null) {
! renderTiles(sg, ts.computeBBox(ux1, uy1, ux2, uy2),
! aatg, abox, ts);
! }
! } finally {
! tileStateProvider.release(ts);
! }
}
+ @Override
public void drawParallelogram(SunGraphics2D sg,
double ux1, double uy1,
double ux2, double uy2,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2)
{
! final TileState ts = tileStateProvider.acquire();
! try {
! final int[] abox = ts.abox;
! final AATileGenerator aatg =
! renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, lw1,
! lw2, sg.getCompClip(), abox);
! if (aatg != null) {
! // Note that bbox is of the original shape, not the wide path.
! // This is appropriate for handing to Paint methods...
! renderTiles(sg, ts.computeBBox(ux1, uy1, ux2, uy2),
! aatg, abox, ts);
! }
! } finally {
! tileStateProvider.release(ts);
! }
}
public void renderPath(SunGraphics2D sg, Shape s, BasicStroke bs) {
! final boolean adjust = (bs != null &&
sg.strokeHint != SunHints.INTVAL_STROKE_PURE);
! final boolean thin = (sg.strokeState <= SunGraphics2D.STROKE_THINDASHED);
! final TileState ts = tileStateProvider.acquire();
! try {
! final int[] abox = ts.abox;
! final AATileGenerator aatg =
! renderengine.getAATileGenerator(s, sg.transform, sg.getCompClip(),
! bs, thin, adjust, abox);
! if (aatg != null) {
! renderTiles(sg, s, aatg, abox, ts);
! }
! } finally {
! tileStateProvider.release(ts);
}
}
public void renderTiles(SunGraphics2D sg, Shape s,
! final AATileGenerator aatg,
! final int[] abox, final TileState ts)
{
Object context = null;
try {
+ // reentrance: outpipe may also use AAShapePipe:
context = outpipe.startSequence(sg, s,
ts.computeDevBox(abox),
abox);
+ // copy of int[] abox as local variables for performance:
+ final int x0 = abox[0];
+ final int y0 = abox[1];
+ final int x1 = abox[2];
+ final int y1 = abox[3];
+
final int tw = aatg.getTileWidth();
final int th = aatg.getTileHeight();
// get tile from thread local storage:
final byte[] alpha = ts.getAlphaTile(tw * th);
byte[] atile;
! for (int y = y0; y < y1; y += th) {
! final int h = Math.min(th, y1 - y);
! for (int x = x0; x < x1; x += tw) {
! final int w = Math.min(tw, x1 - x);
! final int a = aatg.getTypicalAlpha();
!
! if (a == 0x00 || !outpipe.needTile(context, x, y, w, h)) {
aatg.nextTile();
outpipe.skipTile(context, x, y);
continue;
}
if (a == 0xff) {
*** 178,189 ****
} else {
atile = alpha;
aatg.getAlpha(alpha, 0, tw);
}
! outpipe.renderPathTile(context, atile, 0, tw,
! x, y, w, h);
}
}
} finally {
aatg.dispose();
if (context != null) {
--- 197,207 ----
} else {
atile = alpha;
aatg.getAlpha(alpha, 0, tw);
}
! outpipe.renderPathTile(context, atile, 0, tw, x, y, w, h);
}
}
} finally {
aatg.dispose();
if (context != null) {
*** 191,201 ****
}
}
}
// Tile state used by AAShapePipe
! static final class TileState {
// cached tile (32 x 32 tile by default)
private byte[] theTile = new byte[32 * 32];
// dirty aabox array
final int[] abox = new int[4];
// dirty bbox rectangle
--- 209,219 ----
}
}
}
// Tile state used by AAShapePipe
! static final class TileState extends ReentrantContext {
// cached tile (32 x 32 tile by default)
private byte[] theTile = new byte[32 * 32];
// dirty aabox array
final int[] abox = new int[4];
// dirty bbox rectangle
*** 238,244 ****
box.width = ux2;
box.height = uy2;
return box;
}
}
-
}
--- 256,261 ----
< prev index next >