aboutsummaryrefslogtreecommitdiff
path: root/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/solaris/classes/sun/java2d/xr/XRCompositeManager.java')
-rw-r--r--src/solaris/classes/sun/java2d/xr/XRCompositeManager.java334
1 files changed, 334 insertions, 0 deletions
diff --git a/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java b/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java
new file mode 100644
index 000000000..8a6d4f65f
--- /dev/null
+++ b/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.java2d.xr;
+
+import java.awt.*;
+import java.awt.geom.*;
+
+import sun.font.*;
+import sun.java2d.*;
+import sun.java2d.jules.*;
+import sun.java2d.loops.*;
+
+/**
+ * Manages per-application resources, e.g. the 1x1 pixmap used for solid color
+ * fill as well as per-application state e.g. the currently set source picture
+ * used for composition .
+ *
+ * @author Clemens Eisserer
+ */
+
+public class XRCompositeManager {
+ private static boolean enableGradCache = true;
+ private static XRCompositeManager instance;
+
+ XRSurfaceData src;
+ XRSurfaceData texture;
+ XRSurfaceData gradient;
+ int alphaMask = XRUtils.None;
+
+ XRColor solidColor = new XRColor();
+ float extraAlpha = 1.0f;
+ byte compRule = XRUtils.PictOpOver;
+ XRColor alphaColor = new XRColor();
+
+ XRSurfaceData solidSrcPict;
+ int alphaMaskPict;
+ int gradCachePixmap;
+ int gradCachePicture;
+
+ boolean xorEnabled = false;
+ int validatedPixel = 0;
+ Composite validatedComp;
+ Paint validatedPaint;
+ float validatedExtraAlpha = 1.0f;
+
+ XRBackend con;
+ MaskTileManager maskBuffer;
+ XRTextRenderer textRenderer;
+ XRMaskImage maskImage;
+
+ public static synchronized XRCompositeManager getInstance(
+ XRSurfaceData surface) {
+ if (instance == null) {
+ instance = new XRCompositeManager(surface);
+ }
+ return instance;
+ }
+
+ private XRCompositeManager(XRSurfaceData surface) {
+ con = new XRBackendNative();
+ // con = XRBackendJava.getInstance();
+
+ String gradProp = System.getProperty("sun.java2d.xrgradcache");
+ enableGradCache = gradProp == null ||
+ !(gradProp.equalsIgnoreCase("false") ||
+ gradProp.equalsIgnoreCase("f"));
+
+ XRPaints.register(this);
+
+ initResources(surface);
+
+ maskBuffer = new MaskTileManager(this, surface.getXid());
+ textRenderer = new XRTextRenderer(this);
+ maskImage = new XRMaskImage(this, surface.getXid());
+ }
+
+ public void initResources(XRSurfaceData surface) {
+ int parentXid = surface.getXid();
+
+ int solidPixmap = con.createPixmap(parentXid, 32, 1, 1);
+ int solidSrcPictXID = con.createPicture(solidPixmap,
+ XRUtils.PictStandardARGB32);
+ con.setPictureRepeat(solidSrcPictXID, XRUtils.RepeatNormal);
+ con.renderRectangle(solidSrcPictXID, XRUtils.PictOpSrc,
+ XRColor.FULL_ALPHA, 0, 0, 1, 1);
+ solidSrcPict = new XRSurfaceData.XRInternalSurfaceData(con,
+ solidSrcPictXID, null);
+ setForeground(0);
+
+ int extraAlphaMask = con.createPixmap(parentXid, 8, 1, 1);
+ alphaMaskPict = con.createPicture(extraAlphaMask,
+ XRUtils.PictStandardA8);
+ con.setPictureRepeat(alphaMaskPict, XRUtils.RepeatNormal);
+ con.renderRectangle(alphaMaskPict, XRUtils.PictOpClear,
+ XRColor.NO_ALPHA, 0, 0, 1, 1);
+
+ if (enableGradCache) {
+ gradCachePixmap = con.createPixmap(parentXid, 32,
+ MaskTileManager.MASK_SIZE, MaskTileManager.MASK_SIZE);
+ gradCachePicture = con.createPicture(gradCachePixmap,
+ XRUtils.PictStandardARGB32);
+ }
+ }
+
+ public void setForeground(int pixel) {
+ solidColor.setColorValues(pixel, false);
+ con.renderRectangle(solidSrcPict.picture, XRUtils.PictOpSrc,
+ solidColor, 0, 0, 1, 1);
+ }
+
+ public void setGradientPaint(XRSurfaceData gradient) {
+ if (this.gradient != null) {
+ con.freePicture(this.gradient.picture);
+ }
+ this.gradient = gradient;
+ src = gradient;
+ }
+
+ public void setTexturePaint(XRSurfaceData texture) {
+ this.texture = texture;
+ src = texture;
+ }
+
+ public void XRResetPaint() {
+ src = solidSrcPict;
+ }
+
+ public void validateCompositeState(Composite comp, AffineTransform xform,
+ Paint paint, SunGraphics2D sg2d) {
+ boolean updatePaint = (paint != validatedPaint) || paint == null;
+
+ // validate composite
+ if ((comp != validatedComp)) {
+ if (comp != null) {
+ setComposite(comp);
+ } else {
+ comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
+ setComposite(comp);
+ }
+ // the paint state is dependent on the composite state, so make
+ // sure we update the color below
+ updatePaint = true;
+ validatedComp = comp;
+ }
+
+ if (sg2d != null && validatedPixel != sg2d.pixel) {
+ validatedPixel = sg2d.pixel;
+ setForeground(validatedPixel);
+ }
+
+ // validate paint
+ if (updatePaint) {
+ if (paint != null && sg2d != null
+ && sg2d.paintState >= SunGraphics2D.PAINT_GRADIENT) {
+ XRPaints.setPaint(sg2d, paint);
+ } else {
+ XRResetPaint();
+ }
+ validatedPaint = paint;
+ }
+
+ if (src != solidSrcPict) {
+ AffineTransform at = (AffineTransform) xform.clone();
+ try {
+ at.invert();
+ } catch (NoninvertibleTransformException e) {
+ at.setToIdentity();
+ }
+ src.validateAsSource(at, -1, -1);
+ }
+ }
+
+ private void setComposite(Composite comp) {
+ if (comp instanceof AlphaComposite) {
+ AlphaComposite aComp = (AlphaComposite) comp;
+ validatedExtraAlpha = aComp.getAlpha();
+
+ this.compRule = XRUtils.j2dAlphaCompToXR(aComp.getRule());
+ this.extraAlpha = validatedExtraAlpha;
+
+ if (extraAlpha == 1.0f) {
+ alphaMask = XRUtils.None;
+ alphaColor.alpha = XRColor.FULL_ALPHA.alpha;
+ } else {
+ alphaColor.alpha = XRColor
+ .byteToXRColorValue((int) (extraAlpha * 255));
+ alphaMask = alphaMaskPict;
+ con.renderRectangle(alphaMaskPict, XRUtils.PictOpSrc,
+ alphaColor, 0, 0, 1, 1);
+ }
+
+ xorEnabled = false;
+ } else if (comp instanceof XORComposite) {
+ /* XOR composite validation is handled in XRSurfaceData */
+ xorEnabled = true;
+ } else {
+ throw new InternalError(
+ "Composite accaleration not implemented for: "
+ + comp.getClass().getName());
+ }
+ }
+
+ public boolean maskRequired() {
+ return (!xorEnabled)
+ && ((src != solidSrcPict)
+ || (src == solidSrcPict && solidColor.alpha != 0xffff) || (extraAlpha != 1.0f));
+ }
+
+ public void XRComposite(int src, int mask, int dst, int srcX, int srcY,
+ int maskX, int maskY, int dstX, int dstY, int width, int height) {
+ int cachedSrc = (src == XRUtils.None) ? this.src.picture : src;
+ int cachedX = srcX;
+ int cachedY = srcY;
+
+ if (enableGradCache && gradient != null
+ && cachedSrc == gradient.picture) {
+ con.renderComposite(XRUtils.PictOpSrc, gradient.picture,
+ XRUtils.None, gradCachePicture, srcX, srcY, 0, 0, 0, 0,
+ width, height);
+ cachedX = 0;
+ cachedY = 0;
+ cachedSrc = gradCachePicture;
+ }
+
+ con.renderComposite(compRule, cachedSrc, mask, dst, cachedX, cachedY,
+ maskX, maskY, dstX, dstY, width, height);
+ }
+
+ public void XRCompositeTraps(int dst, int srcX, int srcY,
+ TrapezoidList trapList) {
+ int renderReferenceX = 0;
+ int renderReferenceY = 0;
+
+ if (trapList.getP1YLeft(0) < trapList.getP2YLeft(0)) {
+ renderReferenceX = trapList.getP1XLeft(0);
+ renderReferenceY = trapList.getP1YLeft(0);
+ } else {
+ renderReferenceX = trapList.getP2XLeft(0);
+ renderReferenceY = trapList.getP2YLeft(0);
+ }
+
+ renderReferenceX = (int) Math.floor(XRUtils
+ .XFixedToDouble(renderReferenceX));
+ renderReferenceY = (int) Math.floor(XRUtils
+ .XFixedToDouble(renderReferenceY));
+
+ con.renderCompositeTrapezoids(compRule, src.picture,
+ XRUtils.PictStandardA8, dst, renderReferenceX,
+ renderReferenceY, trapList);
+ }
+
+ public void XRRenderRectangles(XRSurfaceData dst, GrowableRectArray rects) {
+ if (xorEnabled) {
+ con.GCRectangles(dst.getXid(), dst.getGC(), rects);
+ } else {
+ con.renderRectangles(dst.getPicture(), compRule, solidColor, rects);
+ }
+ }
+
+ public void compositeBlit(XRSurfaceData src, XRSurfaceData dst, int sx,
+ int sy, int dx, int dy, int w, int h) {
+ con.renderComposite(compRule, src.picture, alphaMask, dst.picture, sx,
+ sy, 0, 0, dx, dy, w, h);
+ }
+
+ public void compositeText(int dst, int glyphSet, int maskFormat,
+ GrowableEltArray elts) {
+ con.XRenderCompositeText(compRule, src.picture, dst, maskFormat, 0, 0,
+ 0, 0, glyphSet, elts);
+ }
+
+ public XRColor getMaskColor() {
+ return !isTexturePaintActive() ? XRColor.FULL_ALPHA : getAlphaColor();
+ }
+
+ public int getExtraAlphaMask() {
+ return alphaMask;
+ }
+
+ public boolean isTexturePaintActive() {
+ return src == texture;
+ }
+
+ public XRColor getAlphaColor() {
+ return alphaColor;
+ }
+
+ public XRBackend getBackend() {
+ return con;
+ }
+
+ public float getExtraAlpha() {
+ return validatedExtraAlpha;
+ }
+
+ public byte getCompRule() {
+ return compRule;
+ }
+
+ public XRTextRenderer getTextRenderer() {
+ return textRenderer;
+ }
+
+ public MaskTileManager getMaskBuffer() {
+ return maskBuffer;
+ }
+
+ public XRMaskImage getMaskImage() {
+ return maskImage;
+ }
+}