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