Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
32288 views
/*1* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.java2d.xr;2627import sun.awt.SunToolkit;28import sun.awt.image.*;29import sun.java2d.loops.*;30import sun.java2d.pipe.*;31import sun.java2d.*;32import java.awt.*;33import java.awt.geom.*;34import java.lang.ref.*;3536public class XRPMBlitLoops {3738static WeakReference<SunVolatileImage> argbTmpPM = new WeakReference<SunVolatileImage>(null);39static WeakReference<SunVolatileImage> rgbTmpPM = new WeakReference<SunVolatileImage>(null);4041public XRPMBlitLoops() {42}4344public static void register() {45GraphicsPrimitive[] primitives = { new XRPMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11),46new XRPMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbPreX11),47new XRPMBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntRgbX11),48new XRPMBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntArgbPreX11),4950new XRPMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11),51new XRPMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbPreX11),52new XRPMScaledBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntRgbX11),53new XRPMScaledBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntArgbPreX11),5455new XRPMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11),56new XRPMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbPreX11),57new XRPMTransformedBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntRgbX11),58new XRPMTransformedBlit(XRSurfaceData.IntArgbPreX11, XRSurfaceData.IntArgbPreX11),5960/* SW -> Surface Blits */61new XrSwToPMBlit(SurfaceType.IntArgb, XRSurfaceData.IntRgbX11),62new XrSwToPMBlit(SurfaceType.IntRgb, XRSurfaceData.IntRgbX11),63new XrSwToPMBlit(SurfaceType.IntBgr, XRSurfaceData.IntRgbX11),64new XrSwToPMBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntRgbX11),65new XrSwToPMBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntRgbX11),66new XrSwToPMBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntRgbX11),67new XrSwToPMBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntRgbX11),6869new XrSwToPMBlit(SurfaceType.IntArgb, XRSurfaceData.IntArgbPreX11),70new XrSwToPMBlit(SurfaceType.IntRgb, XRSurfaceData.IntArgbPreX11),71new XrSwToPMBlit(SurfaceType.IntBgr, XRSurfaceData.IntArgbPreX11),72new XrSwToPMBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntArgbPreX11),73new XrSwToPMBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntArgbPreX11),74new XrSwToPMBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntArgbPreX11),75new XrSwToPMBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntArgbPreX11),7677/* SW->Surface Scales */78new XrSwToPMScaledBlit(SurfaceType.IntArgb, XRSurfaceData.IntRgbX11),79new XrSwToPMScaledBlit(SurfaceType.IntRgb, XRSurfaceData.IntRgbX11),80new XrSwToPMScaledBlit(SurfaceType.IntBgr, XRSurfaceData.IntRgbX11),81new XrSwToPMScaledBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntRgbX11),82new XrSwToPMScaledBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntRgbX11),83new XrSwToPMScaledBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntRgbX11),84new XrSwToPMScaledBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntRgbX11),8586new XrSwToPMScaledBlit(SurfaceType.IntArgb, XRSurfaceData.IntArgbPreX11),87new XrSwToPMScaledBlit(SurfaceType.IntRgb, XRSurfaceData.IntArgbPreX11),88new XrSwToPMScaledBlit(SurfaceType.IntBgr, XRSurfaceData.IntArgbPreX11),89new XrSwToPMScaledBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntArgbPreX11),90new XrSwToPMScaledBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntArgbPreX11),91new XrSwToPMScaledBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntArgbPreX11),92new XrSwToPMScaledBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntArgbPreX11),9394/* SW->Surface Transforms */95new XrSwToPMTransformedBlit(SurfaceType.IntArgb, XRSurfaceData.IntRgbX11),96new XrSwToPMTransformedBlit(SurfaceType.IntRgb, XRSurfaceData.IntRgbX11),97new XrSwToPMTransformedBlit(SurfaceType.IntBgr, XRSurfaceData.IntRgbX11),98new XrSwToPMTransformedBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntRgbX11),99new XrSwToPMTransformedBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntRgbX11),100new XrSwToPMTransformedBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntRgbX11),101new XrSwToPMTransformedBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntRgbX11),102103new XrSwToPMTransformedBlit(SurfaceType.IntArgb, XRSurfaceData.IntArgbPreX11),104new XrSwToPMTransformedBlit(SurfaceType.IntRgb, XRSurfaceData.IntArgbPreX11),105new XrSwToPMTransformedBlit(SurfaceType.IntBgr, XRSurfaceData.IntArgbPreX11),106new XrSwToPMTransformedBlit(SurfaceType.ThreeByteBgr, XRSurfaceData.IntArgbPreX11),107new XrSwToPMTransformedBlit(SurfaceType.Ushort565Rgb, XRSurfaceData.IntArgbPreX11),108new XrSwToPMTransformedBlit(SurfaceType.Ushort555Rgb, XRSurfaceData.IntArgbPreX11),109new XrSwToPMTransformedBlit(SurfaceType.ByteIndexed, XRSurfaceData.IntArgbPreX11), };110GraphicsPrimitiveMgr.register(primitives);111}112113/**114* Caches a SW surface using a temporary pixmap. The pixmap is held by a WeakReference,115* allowing it to shrink again after some time.116*/117protected static XRSurfaceData cacheToTmpSurface(SurfaceData src, XRSurfaceData dst, int w, int h, int sx, int sy) {118SunVolatileImage vImg;119SurfaceType vImgSurfaceType;120121if (src.getTransparency() == Transparency.OPAQUE) {122vImg = rgbTmpPM.get();123vImgSurfaceType = SurfaceType.IntRgb;124} else {125vImg = argbTmpPM.get();126vImgSurfaceType = SurfaceType.IntArgbPre;127}128129if (vImg == null || vImg.getWidth() < w || vImg.getHeight() < h ||130// Sometimes we get volatile image of wrong dest surface type,131// so recreating it132!(vImg.getDestSurface() instanceof XRSurfaceData))133{134if (vImg != null) {135vImg.flush();136}137vImg = (SunVolatileImage) dst.getGraphicsConfig().createCompatibleVolatileImage(w, h, src.getTransparency());138vImg.setAccelerationPriority(1.0f);139140if (!(vImg.getDestSurface() instanceof XRSurfaceData)) {141throw new InvalidPipeException("Could not create XRSurfaceData");142}143if (src.getTransparency() == SurfaceData.OPAQUE) {144rgbTmpPM = new WeakReference<SunVolatileImage>(vImg);145} else {146argbTmpPM = new WeakReference<SunVolatileImage>(vImg);147}148}149150Blit swToSurfaceBlit = Blit.getFromCache(src.getSurfaceType(), CompositeType.SrcNoEa, vImgSurfaceType);151152if (!(vImg.getDestSurface() instanceof XRSurfaceData)) {153throw new InvalidPipeException("wrong surface data type: " + vImg.getDestSurface());154}155156XRSurfaceData vImgSurface = (XRSurfaceData) vImg.getDestSurface();157swToSurfaceBlit.Blit(src, vImgSurface, AlphaComposite.Src, null,158sx, sy, 0, 0, w, h);159160return vImgSurface;161}162}163164class XRPMBlit extends Blit {165public XRPMBlit(SurfaceType srcType, SurfaceType dstType) {166super(srcType, CompositeType.AnyAlpha, dstType);167}168169public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) {170try {171SunToolkit.awtLock();172173XRSurfaceData x11sdDst = (XRSurfaceData) dst;174x11sdDst.validateAsDestination(null, clip);175XRSurfaceData x11sdSrc = (XRSurfaceData) src;176x11sdSrc.validateAsSource(null, XRUtils.RepeatNone, XRUtils.FAST);177178x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);179180x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, sx, sy, dx, dy, w, h);181} finally {182SunToolkit.awtUnlock();183}184}185}186187class XRPMScaledBlit extends ScaledBlit {188public XRPMScaledBlit(SurfaceType srcType, SurfaceType dstType) {189super(srcType, CompositeType.AnyAlpha, dstType);190}191192public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1,193double dx2, double dy2) {194try {195SunToolkit.awtLock();196197XRSurfaceData x11sdDst = (XRSurfaceData) dst;198x11sdDst.validateAsDestination(null, clip);199XRSurfaceData x11sdSrc = (XRSurfaceData) src;200x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);201202double xScale = (dx2 - dx1) / (sx2 - sx1);203double yScale = (dy2 - dy1) / (sy2 - sy1);204205sx1 *= xScale;206sx2 *= xScale;207sy1 *= yScale;208sy2 *= yScale;209210dx1 = Math.ceil(dx1 - 0.5);211dy1 = Math.ceil(dy1 - 0.5);212dx2 = Math.ceil(dx2 - 0.5);213dy2 = Math.ceil(dy2 - 0.5);214215AffineTransform xForm = AffineTransform.getScaleInstance(1 / xScale, 1 / yScale);216217x11sdSrc.validateAsSource(xForm, XRUtils.RepeatNone, XRUtils.FAST);218x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1), (int) (dy2 - dy1));219} finally {220SunToolkit.awtUnlock();221}222}223}224225/**226* Called also if scale+transform is set227*228* @author Clemens Eisserer229*/230class XRPMTransformedBlit extends TransformBlit {231final Rectangle compositeBounds = new Rectangle();232final double[] srcCoords = new double[8];233final double[] dstCoords = new double[8];234235public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {236super(srcType, CompositeType.AnyAlpha, dstType);237}238239/*240* Calculates the composition-rectangle required for transformed blits.241* For composite operations where the composition-rectangle defines242* the modified destination area, coordinates are rounded.243* Otherwise the composition window rectangle is sized large enough244* to not clip away any pixels.245*/246protected void adjustCompositeBounds(boolean isQuadrantRotated, AffineTransform tr,247int dstx, int dsty, int width, int height) {248srcCoords[0] = dstx;249srcCoords[1] = dsty;250srcCoords[2] = dstx + width;251srcCoords[3] = dsty + height;252253double minX, minY, maxX, maxY;254if (isQuadrantRotated) {255tr.transform(srcCoords, 0, dstCoords, 0, 2);256257minX = Math.min(dstCoords[0], dstCoords[2]);258minY = Math.min(dstCoords[1], dstCoords[3]);259maxX = Math.max(dstCoords[0], dstCoords[2]);260maxY = Math.max(dstCoords[1], dstCoords[3]);261262minX = Math.ceil(minX - 0.5);263minY = Math.ceil(minY - 0.5);264maxX = Math.ceil(maxX - 0.5);265maxY = Math.ceil(maxY - 0.5);266} else {267srcCoords[4] = dstx;268srcCoords[5] = dsty + height;269srcCoords[6] = dstx + width;270srcCoords[7] = dsty;271272tr.transform(srcCoords, 0, dstCoords, 0, 4);273274minX = Math.min(dstCoords[0], Math.min(dstCoords[2], Math.min(dstCoords[4], dstCoords[6])));275minY = Math.min(dstCoords[1], Math.min(dstCoords[3], Math.min(dstCoords[5], dstCoords[7])));276maxX = Math.max(dstCoords[0], Math.max(dstCoords[2], Math.max(dstCoords[4], dstCoords[6])));277maxY = Math.max(dstCoords[1], Math.max(dstCoords[3], Math.max(dstCoords[5], dstCoords[7])));278279minX = Math.floor(minX);280minY = Math.floor(minY);281maxX = Math.ceil(maxX);282maxY = Math.ceil(maxY);283}284285compositeBounds.x = (int) minX;286compositeBounds.y = (int) minY;287compositeBounds.width = (int) (maxX - minX);288compositeBounds.height = (int) (maxY - minY);289}290291public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform,292int hint, int srcx, int srcy, int dstx, int dsty, int width, int height) {293try {294SunToolkit.awtLock();295296XRSurfaceData x11sdDst = (XRSurfaceData) dst;297XRSurfaceData x11sdSrc = (XRSurfaceData) src;298XRCompositeManager xrMgr = XRCompositeManager.getInstance(x11sdSrc);299300float extraAlpha = ((AlphaComposite) comp).getAlpha();301int filter = XRUtils.ATransOpToXRQuality(hint);302boolean isQuadrantRotated = XRUtils.isTransformQuadrantRotated(xform);303304adjustCompositeBounds(isQuadrantRotated, xform, dstx, dsty, width, height);305306x11sdDst.validateAsDestination(null, clip);307x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);308309AffineTransform trx = AffineTransform.getTranslateInstance(-compositeBounds.x, -compositeBounds.y);310trx.concatenate(xform);311AffineTransform maskTX = (AffineTransform) trx.clone();312trx.translate(-srcx, -srcy);313314try {315trx.invert();316} catch (NoninvertibleTransformException ex) {317trx.setToIdentity();318}319320if (filter != XRUtils.FAST && (!isQuadrantRotated || extraAlpha != 1.0f)) {321XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage();322323// For quadrant-transformed blits geometry is not stored inside the mask324// therefore we can use a repeating 1x1 mask for applying extra alpha.325int maskPicture = isQuadrantRotated ? xrMgr.getExtraAlphaMask()326: mask.prepareBlitMask(x11sdDst, maskTX, width, height);327328x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter);329x11sdDst.maskBuffer.con.renderComposite(xrMgr.getCompRule(), x11sdSrc.picture,330maskPicture, x11sdDst.picture, 0, 0, 0, 0, compositeBounds.x, compositeBounds.y,331compositeBounds.width, compositeBounds.height);332} else {333int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;334335x11sdSrc.validateAsSource(trx, repeat, filter);336337// compositeBlit takes care of extra alpha338x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, compositeBounds.x,339compositeBounds.y, compositeBounds.width, compositeBounds.height);340}341} finally {342SunToolkit.awtUnlock();343}344}345}346347class XrSwToPMBlit extends Blit {348Blit pmToSurfaceBlit;349350XrSwToPMBlit(SurfaceType srcType, SurfaceType dstType) {351super(srcType, CompositeType.AnyAlpha, dstType);352pmToSurfaceBlit = new XRPMBlit(dstType, dstType);353}354355public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) {356// If the blit is write-only (putimge), no need for a temporary VI.357if (CompositeType.SrcOverNoEa.equals(comp) && (src.getTransparency() == Transparency.OPAQUE)) {358Blit opaqueSwToSurfaceBlit = Blit.getFromCache(src.getSurfaceType(), CompositeType.SrcNoEa, dst.getSurfaceType());359opaqueSwToSurfaceBlit.Blit(src, dst, comp, clip, sx, sy, dx, dy, w, h);360} else {361try {362SunToolkit.awtLock();363364XRSurfaceData vImgSurface = XRPMBlitLoops.cacheToTmpSurface(src, (XRSurfaceData) dst, w, h, sx, sy);365pmToSurfaceBlit.Blit(vImgSurface, dst, comp, clip, 0, 0, dx, dy, w, h);366} finally {367SunToolkit.awtUnlock();368}369}370}371}372373class XrSwToPMScaledBlit extends ScaledBlit {374ScaledBlit pmToSurfaceBlit;375376XrSwToPMScaledBlit(SurfaceType srcType, SurfaceType dstType) {377super(srcType, CompositeType.AnyAlpha, dstType);378pmToSurfaceBlit = new XRPMScaledBlit(dstType, dstType);379}380381public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1,382double dx2, double dy2) {383{384int w = sx2 - sx1;385int h = sy2 - sy1;386387try {388SunToolkit.awtLock();389XRSurfaceData vImgSurface = XRPMBlitLoops.cacheToTmpSurface(src, (XRSurfaceData) dst, w, h, sx1, sy1);390pmToSurfaceBlit.Scale(vImgSurface, dst, comp, clip, 0, 0, w, h, dx1, dy1, dx2, dy2);391} finally {392SunToolkit.awtUnlock();393}394}395}396}397398class XrSwToPMTransformedBlit extends TransformBlit {399TransformBlit pmToSurfaceBlit;400401XrSwToPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {402super(srcType, CompositeType.AnyAlpha, dstType);403pmToSurfaceBlit = new XRPMTransformedBlit(dstType, dstType);404}405406public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int sx, int sy, int dstx,407int dsty, int w, int h) {408try {409SunToolkit.awtLock();410411XRSurfaceData vImgSurface = XRPMBlitLoops.cacheToTmpSurface(src, (XRSurfaceData) dst, w, h, sx, sy);412pmToSurfaceBlit.Transform(vImgSurface, dst, comp, clip, xform, hint, 0, 0, dstx, dsty, w, h);413} finally {414SunToolkit.awtUnlock();415}416}417}418419420