--- old/src/solaris/classes/sun/java2d/xr/MaskTileManager.java 2013-10-18 04:14:28.210679114 -0400 +++ new/src/solaris/classes/sun/java2d/xr/MaskTileManager.java 2013-10-18 04:14:28.065679055 -0400 @@ -76,8 +76,9 @@ public void fillMask(XRSurfaceData dst) { boolean maskRequired = xrMgr.maskRequired(); + boolean maskEvaluated = XRUtils.isMaskEvaluated(xrMgr.compRule); - if (maskRequired) { + if (maskRequired && maskEvaluated) { mainTile.calculateDirtyAreas(); DirtyRegion dirtyArea = mainTile.getDirtyArea().cloneRegion(); mainTile.translate(-dirtyArea.x, -dirtyArea.y); @@ -106,7 +107,15 @@ } } } else { - xrMgr.XRRenderRectangles(dst, mainTile.getRects()); + /* + * If a mask would be required to store geometry (maskRequired) + * composition has to be done rectangle-by-rectagle. + */ + if(xrMgr.isSolidPaintActive()) { + xrMgr.XRRenderRectangles(dst, mainTile.getRects()); + } else { + xrMgr.XRCompositeRectangles(dst, mainTile.getRects()); + } } mainTile.reset(); --- old/src/solaris/classes/sun/java2d/xr/XRColor.java 2013-10-18 04:14:28.606679276 -0400 +++ new/src/solaris/classes/sun/java2d/xr/XRColor.java 2013-10-18 04:14:28.447679211 -0400 @@ -54,6 +54,7 @@ } public XRColor(Color color) { + setColorValues(color); } public void setColorValues(Color color) { --- old/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java 2013-10-18 04:14:28.936679411 -0400 +++ new/src/solaris/classes/sun/java2d/xr/XRCompositeManager.java 2013-10-18 04:14:28.800679355 -0400 @@ -47,8 +47,13 @@ public class XRCompositeManager { private static boolean enableGradCache = true; private static XRCompositeManager instance; + + private final static int SOLID = 0; + private final static int TEXTURE = 1; + private final static int GRADIENT = 2; - XRSurfaceData src; + int srcType; + XRSolidSrcPict solidSrc32; XRSurfaceData texture; XRSurfaceData gradient; int alphaMask = XRUtils.None; @@ -84,7 +89,6 @@ private XRCompositeManager(XRSurfaceData surface) { con = new XRBackendNative(); - // con = XRBackendJava.getInstance(); String gradProp = AccessController.doPrivileged(new PrivilegedAction() { @@ -109,14 +113,7 @@ 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); + solidSrc32 = new XRSolidSrcPict(con, parentXid); setForeground(0); int extraAlphaMask = con.createPixmap(parentXid, 8, 1, 1); @@ -135,9 +132,7 @@ } public void setForeground(int pixel) { - solidColor.setColorValues(pixel, false); - con.renderRectangle(solidSrcPict.picture, XRUtils.PictOpSrc, - solidColor, 0, 0, 1, 1); + solidColor.setColorValues(pixel, true); } public void setGradientPaint(XRSurfaceData gradient) { @@ -145,16 +140,16 @@ con.freePicture(this.gradient.picture); } this.gradient = gradient; - src = gradient; + srcType = GRADIENT; } public void setTexturePaint(XRSurfaceData texture) { this.texture = texture; - src = texture; + this.srcType = TEXTURE; } public void XRResetPaint() { - src = solidSrcPict; + srcType = SOLID; } public void validateCompositeState(Composite comp, AffineTransform xform, @@ -175,7 +170,7 @@ validatedComp = comp; } - if (sg2d != null && validatedPixel != sg2d.pixel) { + if (sg2d != null && (validatedPixel != sg2d.pixel || updatePaint)) { validatedPixel = sg2d.pixel; setForeground(validatedPixel); } @@ -191,14 +186,14 @@ validatedPaint = paint; } - if (src != solidSrcPict) { + if (srcType != SOLID) { AffineTransform at = (AffineTransform) xform.clone(); try { at.invert(); } catch (NoninvertibleTransformException e) { at.setToIdentity(); } - src.validateAsSource(at, -1, -1); + getCurrentSource().validateAsSource(at, -1, -1); } } @@ -234,13 +229,13 @@ public boolean maskRequired() { return (!xorEnabled) - && ((src != solidSrcPict) - || (src == solidSrcPict && solidColor.alpha != 0xffff) || (extraAlpha != 1.0f)); + && ((srcType != SOLID) + || (srcType == SOLID && (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 cachedSrc = (src == XRUtils.None) ? getCurrentSource().picture : src; int cachedX = srcX; int cachedY = srcY; @@ -276,12 +271,12 @@ renderReferenceY = (int) Math.floor(XRUtils .XFixedToDouble(renderReferenceY)); - con.renderCompositeTrapezoids(compRule, src.picture, + con.renderCompositeTrapezoids(compRule, getCurrentSource().picture, XRUtils.PictStandardA8, dst, renderReferenceX, renderReferenceY, trapList); } - public void XRRenderRectangles(XRSurfaceData dst, GrowableRectArray rects) { + public void XRRenderRectangles(XRSurfaceData dst, GrowableRectArray rects) { if (xorEnabled) { con.GCRectangles(dst.getXid(), dst.getGC(), rects); } else { @@ -293,6 +288,32 @@ } } } + + public void XRCompositeRectangles(XRSurfaceData dst, GrowableRectArray rects) { + int srcPict = getCurrentSource().picture; + + for(int i=0; i < rects.getSize(); i++) { + int x = rects.getX(i); + int y = rects.getY(i); + int width = rects.getWidth(i); + int height = rects.getHeight(i); + + con.renderComposite(compRule, srcPict, XRUtils.None, dst.picture, x, y, 0, 0, x, y, width, height); + } + } + + protected XRSurfaceData getCurrentSource() { + switch(srcType) { + case SOLID: + return solidSrc32.prepareSrcPict(validatedPixel); + case TEXTURE: + return texture; + case GRADIENT: + return gradient; + } + + return null; + } public void compositeBlit(XRSurfaceData src, XRSurfaceData dst, int sx, int sy, int dx, int dy, int w, int h) { @@ -300,10 +321,15 @@ sy, 0, 0, dx, dy, w, h); } - public void compositeText(XRSurfaceData dst, int sx, int sy, - int glyphSet, int maskFormat, GrowableEltArray elts) { - con.XRenderCompositeText(compRule, src.picture, dst.picture, - maskFormat, sx, sy, 0, 0, glyphSet, elts); + public void compositeText(XRSurfaceData dst, int sx, int sy, int glyphSet, + int maskFormat, GrowableEltArray elts) { + /* + * Try to emulate the SRC blend mode with SRC_OVER. + * We bail out during pipe validation for cases where this is not possible. + */ + byte textCompRule = (compRule != XRUtils.PictOpSrc) ? compRule : XRUtils.PictOpOver; + con.XRenderCompositeText(textCompRule, getCurrentSource().picture, dst.picture, + maskFormat, sx, sy, 0, 0, glyphSet, elts); } public XRColor getMaskColor() { @@ -315,7 +341,11 @@ } public boolean isTexturePaintActive() { - return src == texture; + return srcType == TEXTURE; + } + + public boolean isSolidPaintActive() { + return srcType == SOLID; } public XRColor getAlphaColor() { --- old/src/solaris/classes/sun/java2d/xr/XRDrawImage.java 2013-10-18 04:14:29.397679621 -0400 +++ new/src/solaris/classes/sun/java2d/xr/XRDrawImage.java 2013-10-18 04:14:29.241679549 -0400 @@ -38,31 +38,36 @@ */ public class XRDrawImage extends DrawImage { + @Override - protected void renderImageXform(SunGraphics2D sg, Image img, - AffineTransform tx, int interpType, int sx1, int sy1, int sx2, - int sy2, Color bgColor) { - SurfaceData dstData = sg.surfaceData; - SurfaceData srcData = dstData.getSourceSurfaceData(img, - SunGraphics2D.TRANSFORM_GENERIC, sg.imageComp, bgColor); + protected void renderImageXform(SunGraphics2D sg, Image img, + AffineTransform tx, int interpType, int sx1, int sy1, int sx2, + int sy2, Color bgColor) { + SurfaceData dstData = sg.surfaceData; + SurfaceData srcData = dstData.getSourceSurfaceData(img, + SunGraphics2D.TRANSFORM_GENERIC, sg.imageComp, bgColor); + int compRule = ((AlphaComposite) sg.composite).getRule(); + float extraAlpha = ((AlphaComposite) sg.composite).getAlpha(); + + if (srcData != null && !isBgOperation(srcData, bgColor) + && interpType <= AffineTransformOp.TYPE_BILINEAR + && (XRUtils.isMaskEvaluated(XRUtils.j2dAlphaCompToXR(compRule)) + || (XRUtils.isTransformQuadrantRotated(tx)) && extraAlpha == 1.0f)) + { + SurfaceType srcType = srcData.getSurfaceType(); + SurfaceType dstType = dstData.getSurfaceType(); - if (srcData != null && !isBgOperation(srcData, bgColor) - && interpType <= AffineTransformOp.TYPE_BILINEAR) { - SurfaceType srcType = srcData.getSurfaceType(); - SurfaceType dstType = dstData.getSurfaceType(); + TransformBlit blit = TransformBlit.getFromCache(srcType, + sg.imageComp, dstType); + if (blit != null) { + blit.Transform(srcData, dstData, sg.composite, + sg.getCompClip(), tx, interpType, sx1, sy1, 0, 0, sx2 + - sx1, sy2 - sy1); + return; + } + } - TransformBlit blit = TransformBlit.getFromCache(srcType, - sg.imageComp, dstType); - - if (blit != null) { - blit.Transform(srcData, dstData, sg.composite, - sg.getCompClip(), tx, interpType, sx1, sy1, 0, 0, sx2 - - sx1, sy2 - sy1); - return; - } - } - - super.renderImageXform(sg, img, tx, interpType, sx1, sy1, sx2, sy2, - bgColor); + super.renderImageXform(sg, img, tx, interpType, sx1, sy1, sx2, sy2, + bgColor); } } --- old/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java 2013-10-18 04:14:29.752679786 -0400 +++ new/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java 2013-10-18 04:14:29.599679715 -0400 @@ -84,7 +84,7 @@ int maskPict = maskBuffer.getMaskBuffer(). uploadMask(width, height, maskscan, maskoff, mask); - maskBuffer.XRComposite(x11sd.getPicture(), maskPict, x11sd.picture, + maskBuffer.XRComposite(x11sd.getPicture(), maskPict, x11dst.getPicture(), srcx, srcy, 0, 0, dstx, dsty, width, height); maskBuffer.getMaskBuffer().clearUploadMask(maskPict, width, height); } finally { --- old/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java 2013-10-18 04:14:30.084679945 -0400 +++ new/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java 2013-10-18 04:14:29.945679876 -0400 @@ -109,22 +109,17 @@ return XRSurfaceDataProxy.createProxy(srcData, graphicsConfig); } + @Override public void validatePipe(SunGraphics2D sg2d) { TextPipe textpipe; boolean validated = false; - + /* * The textpipe for now can't handle TexturePaint when extra-alpha is * specified nore XOR mode */ - if (sg2d.compositeState < SunGraphics2D.COMP_XOR && - (sg2d.paintState < SunGraphics2D.PAINT_TEXTURE || - sg2d.composite == null || - !(sg2d.composite instanceof AlphaComposite) || - ((AlphaComposite) sg2d.composite).getAlpha() == 1.0f)) + if ((textpipe = getTextPipe(sg2d)) == null) { - textpipe = xrtextpipe; - } else { super.validatePipe(sg2d); textpipe = sg2d.textpipe; validated = true; @@ -183,14 +178,39 @@ // always override the image pipe with the specialized XRender pipe sg2d.imagepipe = xrDrawImage; } + + protected TextPipe getTextPipe(SunGraphics2D sg2d) { + boolean supportedPaint = sg2d.compositeState <= SunGraphics2D.COMP_ALPHA + && (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR || sg2d.composite == null); + + boolean supportedCompOp = false; + if (sg2d.composite instanceof AlphaComposite) { + int compRule = ((AlphaComposite) sg2d.composite).getRule(); + supportedCompOp = XRUtils.isMaskEvaluated(XRUtils.j2dAlphaCompToXR(compRule)) + || (compRule == AlphaComposite.SRC + && sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR); + } + return (supportedPaint && supportedCompOp) ? xrtextpipe : null; + } + protected MaskFill getMaskFill(SunGraphics2D sg2d) { - if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR && - !XRPaints.isValid(sg2d)) - { - return null; - } - return super.getMaskFill(sg2d); + AlphaComposite aComp = null; + if(sg2d.composite != null + && sg2d.composite instanceof AlphaComposite) { + aComp = (AlphaComposite) sg2d.composite; + } + + boolean supportedPaint = sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR + || XRPaints.isValid(sg2d); + + boolean supportedCompOp = false; + if(aComp != null) { + int rule = aComp.getRule(); + supportedCompOp = XRUtils.isMaskEvaluated(XRUtils.j2dAlphaCompToXR(rule)); + } + + return (supportedPaint && supportedCompOp) ? super.getMaskFill(sg2d) : null; } public RenderLoops getRenderLoops(SunGraphics2D sg2d) { --- old/src/solaris/classes/sun/java2d/xr/XRUtils.java 2013-10-18 04:14:30.418680119 -0400 +++ new/src/solaris/classes/sun/java2d/xr/XRUtils.java 2013-10-18 04:14:30.288680052 -0400 @@ -26,6 +26,7 @@ package sun.java2d.xr; import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.MultipleGradientPaint.*; import java.awt.image.*; import sun.java2d.loops.*; @@ -258,4 +259,21 @@ public static int clampToUShort(int x) { return (x > 65535 ? 65535 : (x < 0) ? 0 : x); } + + public static boolean isTransformQuadrantRotated(AffineTransform tr) { + return ((tr.getType() & (AffineTransform.TYPE_GENERAL_ROTATION | + AffineTransform.TYPE_GENERAL_TRANSFORM)) == 0); + } + + public static boolean isMaskEvaluated(byte xrCompRule) { + switch (xrCompRule) { + case PictOpOver: + case PictOpOverReverse: + case PictOpAtop: + case PictOpXor: + return true; + } + + return false; + } } --- /dev/null 2013-10-18 03:16:34.662218897 -0400 +++ new/src/solaris/classes/sun/java2d/xr/XRSolidSrcPict.java 2013-10-18 04:14:30.624680227 -0400 @@ -0,0 +1,31 @@ +package sun.java2d.xr; + +public class XRSolidSrcPict { + XRBackend con; + + XRSurfaceData srcPict; + XRColor xrCol; + int curPixVal = -1; + + public XRSolidSrcPict(XRBackend con, int parentXid) { + this.con = con; + + xrCol = new XRColor(); + 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); + srcPict = new XRSurfaceData.XRInternalSurfaceData(con, solidSrcPictXID, null); + } + + public XRSurfaceData prepareSrcPict(int pixelVal) { + if(pixelVal != curPixVal) { + xrCol.setColorValues(pixelVal, false); + con.renderRectangle(srcPict.picture, XRUtils.PictOpSrc, xrCol, 0, 0, 1, 1); + this.curPixVal = pixelVal; + } + + return srcPict; + } + +}