diff options
Diffstat (limited to 'src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java')
-rw-r--r-- | src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java | 400 |
1 files changed, 400 insertions, 0 deletions
diff --git a/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java b/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java new file mode 100644 index 000000000..40536066f --- /dev/null +++ b/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java @@ -0,0 +1,400 @@ +/* + * 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 sun.awt.SunToolkit; +import sun.awt.image.*; +import sun.java2d.loops.*; +import sun.java2d.pipe.*; +import sun.java2d.*; +import java.awt.*; +import java.awt.geom.*; +import java.lang.ref.*; + +public class XRPMBlitLoops { + + static WeakReference<SunVolatileImage> argbTmpPM = new WeakReference<SunVolatileImage>(null); + static WeakReference<SunVolatileImage> rgbTmpPM = new WeakReference<SunVolatileImage>(null); + + public XRPMBlitLoops() { + } + + public static void register() { + GraphicsPrimitive[] primitives = { new XRPMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11), + new XRPMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbPreX11), + new XRPMBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntRgbX11), + new XRPMBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntArgbPreX11), + + new XRPMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11), + new XRPMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbPreX11), + new XRPMScaledBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntRgbX11), + new XRPMScaledBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntArgbPreX11), + + new XRPMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11), + new XRPMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbPreX11), + new XRPMTransformedBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntRgbX11), + new XRPMTransformedBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntArgbPreX11), + + /* SW -> Surface Blits */ + new XrSwToPMBlit(SurfaceType.IntArgb, XRSurfaceData.IntRgbX11), + new XrSwToPMBlit(SurfaceType.IntRgb, XRSurfaceData.IntRgbX11), + new XrSwToPMBlit(SurfaceType.IntBgr, XRSurfaceData.IntRgbX11), + new XrSwToPMBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntRgbX11), + new XrSwToPMBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntRgbX11), + new XrSwToPMBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntRgbX11), + new XrSwToPMBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntRgbX11), + + new XrSwToPMBlit(SurfaceType.IntArgb, XRSurfaceData.IntArgbPreX11), + new XrSwToPMBlit(SurfaceType.IntRgb, XRSurfaceData.IntArgbPreX11), + new XrSwToPMBlit(SurfaceType.IntBgr, XRSurfaceData.IntArgbPreX11), + new XrSwToPMBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntArgbPreX11), + new XrSwToPMBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntArgbPreX11), + new XrSwToPMBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntArgbPreX11), + new XrSwToPMBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntArgbPreX11), + + /* SW->Surface Scales */ + new XrSwToPMScaledBlit(SurfaceType.IntArgb, XRSurfaceData.IntRgbX11), + new XrSwToPMScaledBlit(SurfaceType.IntRgb, XRSurfaceData.IntRgbX11), + new XrSwToPMScaledBlit(SurfaceType.IntBgr, XRSurfaceData.IntRgbX11), + new XrSwToPMScaledBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntRgbX11), + new XrSwToPMScaledBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntRgbX11), + new XrSwToPMScaledBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntRgbX11), + new XrSwToPMScaledBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntRgbX11), + + new XrSwToPMScaledBlit(SurfaceType.IntArgb, XRSurfaceData.IntArgbPreX11), + new XrSwToPMScaledBlit(SurfaceType.IntRgb, XRSurfaceData.IntArgbPreX11), + new XrSwToPMScaledBlit(SurfaceType.IntBgr, XRSurfaceData.IntArgbPreX11), + new XrSwToPMScaledBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntArgbPreX11), + new XrSwToPMScaledBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntArgbPreX11), + new XrSwToPMScaledBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntArgbPreX11), + new XrSwToPMScaledBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntArgbPreX11), + + /* SW->Surface Transforms */ + new XrSwToPMTransformedBlit(SurfaceType.IntArgb, XRSurfaceData.IntRgbX11), + new XrSwToPMTransformedBlit(SurfaceType.IntRgb, XRSurfaceData.IntRgbX11), + new XrSwToPMTransformedBlit(SurfaceType.IntBgr, XRSurfaceData.IntRgbX11), + new XrSwToPMTransformedBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntRgbX11), + new XrSwToPMTransformedBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntRgbX11), + new XrSwToPMTransformedBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntRgbX11), + new XrSwToPMTransformedBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntRgbX11), + + new XrSwToPMTransformedBlit(SurfaceType.IntArgb, XRSurfaceData.IntArgbPreX11), + new XrSwToPMTransformedBlit(SurfaceType.IntRgb, XRSurfaceData.IntArgbPreX11), + new XrSwToPMTransformedBlit(SurfaceType.IntBgr, XRSurfaceData.IntArgbPreX11), + new XrSwToPMTransformedBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntArgbPreX11), + new XrSwToPMTransformedBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntArgbPreX11), + new XrSwToPMTransformedBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntArgbPreX11), + new XrSwToPMTransformedBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntArgbPreX11), }; + GraphicsPrimitiveMgr.register(primitives); + } + + /** + * Caches a SW surface using a temporary pixmap. The pixmap is held by a WeakReference, + * allowing it to shrink again after some time. + */ + protected static XRSurfaceData cacheToTmpSurface(SurfaceData src, XRSurfaceData dst, int w, int h, int sx, int sy) { + SunVolatileImage vImg; + SurfaceType vImgSurfaceType; + + if (src.getTransparency() == Transparency.OPAQUE) { + vImg = rgbTmpPM.get(); + vImgSurfaceType = SurfaceType.IntRgb; + } else { + vImg = argbTmpPM.get(); + vImgSurfaceType = SurfaceType.IntArgbPre; + } + + if (vImg == null || vImg.getWidth() < w || vImg.getHeight() < h) { + if (vImg != null) { + vImg.flush(); + } + vImg = (SunVolatileImage) dst.getGraphicsConfig().createCompatibleVolatileImage(w, h, src.getTransparency()); + vImg.setAccelerationPriority(1.0f); + + if (src.getTransparency() == SurfaceData.OPAQUE) { + rgbTmpPM = new WeakReference<SunVolatileImage>(vImg); + } else { + argbTmpPM = new WeakReference<SunVolatileImage>(vImg); + } + } + + Blit swToSurfaceBlit = Blit.getFromCache(src.getSurfaceType(), CompositeType.SrcNoEa, vImgSurfaceType); + XRSurfaceData vImgSurface = (XRSurfaceData) vImg.getDestSurface(); + swToSurfaceBlit.Blit(src, vImgSurface, null, null, sx, sy, 0, 0, w, h); + + return vImgSurface; + } +} + +class XRPMBlit extends Blit { + public XRPMBlit(SurfaceType srcType, SurfaceType dstType) { + super(srcType, CompositeType.AnyAlpha, dstType); + } + + public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) { + try { + SunToolkit.awtLock(); + + XRSurfaceData x11sdDst = (XRSurfaceData) dst; + x11sdDst.validateAsDestination(null, clip); + XRSurfaceData x11sdSrc = (XRSurfaceData) src; + x11sdSrc.validateAsSource(null, XRUtils.RepeatNone, XRUtils.FAST); + + x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null); + + x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, sx, sy, dx, dy, w, h); + } finally { + SunToolkit.awtUnlock(); + } + } +} + +class XRPMScaledBlit extends ScaledBlit { + public XRPMScaledBlit(SurfaceType srcType, SurfaceType dstType) { + super(srcType, CompositeType.AnyAlpha, dstType); + } + + /* + * TODO: This breaks scales with non-integer coordinates!?!?! + */ + public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1, + double dx2, double dy2) { + try { + SunToolkit.awtLock(); + + XRSurfaceData x11sdDst = (XRSurfaceData) dst; + x11sdDst.validateAsDestination(null, clip); + XRSurfaceData x11sdSrc = (XRSurfaceData) src; + x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null); + + double xScale = (dx2 - dx1) / (sx2 - sx1); + double yScale = (dy2 - dy1) / (sy2 - sy1); + + sx1 *= xScale; + sx2 *= xScale; + sy1 *= yScale; + sy2 *= yScale; + + AffineTransform xForm = AffineTransform.getScaleInstance(1 / xScale, 1 / yScale); + + x11sdSrc.validateAsSource(xForm, XRUtils.RepeatNone, XRUtils.FAST); /* + * TODO: + * padded + * blit + * required + * : + * - + * / + * ? + * ? + */ + x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1), (int) (dy2 - dy1)); + } finally { + SunToolkit.awtUnlock(); + } + } +} + +/** + * Called also if scale+transform is set + * + * @author Clemens Eisserer + */ +class XRPMTransformedBlit extends TransformBlit { + + public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) { + super(srcType, CompositeType.AnyAlpha, dstType); + } + + /* + * Calculates the composite-rectangle required for transformed blits. This + * method is functionally equal to: Shape shp = + * xform.createTransformedShape(rect); Rectangle bounds = shp.getBounds(); + * but performs significantly better. + */ + public Rectangle getCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) { + double[] compBounds = new double[8]; + compBounds[0] = dstx; + compBounds[1] = dsty; + compBounds[2] = dstx + width; + compBounds[3] = dsty; + compBounds[4] = dstx + width; + compBounds[5] = dsty + height; + compBounds[6] = dstx; + compBounds[7] = dsty + height; + + tr.transform(compBounds, 0, compBounds, 0, 4); + + double minX = Math.min(compBounds[0], Math.min(compBounds[2], Math.min(compBounds[4], compBounds[6]))); + double minY = Math.min(compBounds[1], Math.min(compBounds[3], Math.min(compBounds[5], compBounds[7]))); + double maxX = Math.max(compBounds[0], Math.max(compBounds[2], Math.max(compBounds[4], compBounds[6]))); + double maxY = Math.max(compBounds[1], Math.max(compBounds[3], Math.max(compBounds[5], compBounds[7]))); + + minX = Math.floor(minX); + minY = Math.floor(minY); + maxX = Math.ceil(maxX); + maxY = Math.ceil(maxY); + + return new Rectangle((int) minX, (int) minY, (int) (maxX - minX), (int) (maxY - minY)); + } + + public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int srcx, int srcy, + int dstx, int dsty, int width, int height) { + try { + SunToolkit.awtLock(); + + int filter = XRUtils.ATransOpToXRQuality(hint); + + XRSurfaceData x11sdDst = (XRSurfaceData) dst; + x11sdDst.validateAsDestination(null, clip); + XRSurfaceData x11sdSrc = (XRSurfaceData) src; + x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null); + + Rectangle bounds = getCompositeBounds(xform, dstx, dsty, width, height); + + AffineTransform trx = AffineTransform.getTranslateInstance((-bounds.x), (-bounds.y)); + trx.concatenate(xform); + AffineTransform maskTX = (AffineTransform) trx.clone(); + + trx.translate(-srcx, -srcy); + + try { + trx.invert(); + } catch (NoninvertibleTransformException ex) { + trx.setToIdentity(); + System.err.println("Reseted to identity!"); + } + + boolean omitMask = isMaskOmittable(trx, comp, filter); + + if (!omitMask) { + XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage(); + + x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter); + int maskPicture = mask.prepareBlitMask(x11sdDst, maskTX, width, height); + x11sdDst.maskBuffer.con.renderComposite(XRCompositeManager.getInstance(x11sdSrc).getCompRule(), x11sdSrc.picture, maskPicture, x11sdDst.picture, + 0, 0, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height); + } else { + int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad; + + x11sdSrc.validateAsSource(trx, repeat, filter); + x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height); + } + } finally { + SunToolkit.awtUnlock(); + } + } + + /* TODO: Is mask ever omitable??? ... should be for 90 degree rotation and no shear, but we always need to use RepeatPad */ + protected static boolean isMaskOmittable(AffineTransform trx, Composite comp, int filter) { + return (filter == XRUtils.FAST || trx.getTranslateX() == (int) trx.getTranslateX() /* + * If + * translate + * is + * integer + * only + */ + && trx.getTranslateY() == (int) trx.getTranslateY() && (trx.getShearX() == 0 && trx.getShearY() == 0 // Only + // 90 degree + // rotation + || trx.getShearX() == -trx.getShearY())) && ((AlphaComposite) comp).getAlpha() == 1.0f; // No + // ExtraAlpha!=1 + } +} + +class XrSwToPMBlit extends Blit { + Blit pmToSurfaceBlit; + + XrSwToPMBlit(SurfaceType srcType, SurfaceType dstType) { + super(srcType, CompositeType.AnyAlpha, dstType); + pmToSurfaceBlit = new XRPMBlit(dstType, dstType); + } + + public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) { + /* + * If the blit is write-only (putimge), no need for a temporary VI. + */ + if (CompositeType.SrcOverNoEa.equals(comp) && (src.getTransparency() == Transparency.OPAQUE)) { + Blit opaqueSwToSurfaceBlit = Blit.getFromCache(src.getSurfaceType(), CompositeType.SrcNoEa, dst.getSurfaceType()); + opaqueSwToSurfaceBlit.Blit(src, dst, comp, clip, sx, sy, dx, dy, w, h); + } else { + try { + SunToolkit.awtLock(); + + XRSurfaceData vImgSurface = XRPMBlitLoops.cacheToTmpSurface(src, (XRSurfaceData) dst, w, h, sx, sy); + pmToSurfaceBlit.Blit(vImgSurface, dst, comp, clip, 0, 0, dx, dy, w, h); + } finally { + SunToolkit.awtUnlock(); + } + } + } +} + +class XrSwToPMScaledBlit extends ScaledBlit { + ScaledBlit pmToSurfaceBlit; + + XrSwToPMScaledBlit(SurfaceType srcType, SurfaceType dstType) { + super(srcType, CompositeType.AnyAlpha, dstType); + pmToSurfaceBlit = new XRPMScaledBlit(dstType, dstType); + } + + public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1, + double dx2, double dy2) { + { + int w = sx2 - sx1; + int h = sy2 - sy1; + + try { + SunToolkit.awtLock(); + XRSurfaceData vImgSurface = XRPMBlitLoops.cacheToTmpSurface(src, (XRSurfaceData) dst, w, h, sx1, sy1); + pmToSurfaceBlit.Scale(vImgSurface, dst, comp, clip, 0, 0, w, h, dx1, dy1, dx2, dy2); + } finally { + SunToolkit.awtUnlock(); + } + } + } +} + +class XrSwToPMTransformedBlit extends TransformBlit { + TransformBlit pmToSurfaceBlit; + + XrSwToPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) { + super(srcType, CompositeType.AnyAlpha, dstType); + pmToSurfaceBlit = new XRPMTransformedBlit(dstType, dstType); + } + + public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int sx, int sy, int dstx, + int dsty, int w, int h) { + try { + SunToolkit.awtLock(); + + XRSurfaceData vImgSurface = XRPMBlitLoops.cacheToTmpSurface(src, (XRSurfaceData) dst, w, h, sx, sy); + pmToSurfaceBlit.Transform(vImgSurface, dst, comp, clip, xform, hint, 0, 0, dstx, dsty, w, h); + } finally { + SunToolkit.awtUnlock(); + } + } +} |