Path: blob/master/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java
41159 views
/*1* Copyright (c) 2007, 2014, 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.d3d;2627import java.awt.Composite;28import java.awt.Transparency;29import java.awt.geom.AffineTransform;30import java.awt.image.AffineTransformOp;31import java.awt.image.BufferedImage;32import java.awt.image.BufferedImageOp;33import java.lang.ref.WeakReference;34import java.lang.annotation.Native;35import sun.java2d.ScreenUpdateManager;36import sun.java2d.SurfaceData;37import sun.java2d.loops.Blit;38import sun.java2d.loops.CompositeType;39import sun.java2d.loops.GraphicsPrimitive;40import sun.java2d.loops.GraphicsPrimitiveMgr;41import sun.java2d.loops.ScaledBlit;42import sun.java2d.loops.SurfaceType;43import sun.java2d.loops.TransformBlit;44import sun.java2d.pipe.Region;45import sun.java2d.pipe.RenderBuffer;46import sun.java2d.pipe.RenderQueue;47import static sun.java2d.pipe.BufferedOpCodes.*;48import sun.java2d.windows.GDIWindowSurfaceData;4950final class D3DBlitLoops {5152static void register() {53Blit blitIntArgbPreToSurface =54new D3DSwToSurfaceBlit(SurfaceType.IntArgbPre,55D3DSurfaceData.ST_INT_ARGB_PRE);56Blit blitIntArgbPreToTexture =57new D3DSwToTextureBlit(SurfaceType.IntArgbPre,58D3DSurfaceData.ST_INT_ARGB_PRE);59TransformBlit transformBlitIntArgbPreToSurface =60new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre,61D3DSurfaceData.ST_INT_ARGB_PRE);62GraphicsPrimitive[] primitives = {63// prevent D3DSurface -> Screen blits64new D3DSurfaceToGDIWindowSurfaceBlit(),65new D3DSurfaceToGDIWindowSurfaceScale(),66new D3DSurfaceToGDIWindowSurfaceTransform(),6768// surface->surface ops69new D3DSurfaceToSurfaceBlit(),70new D3DSurfaceToSurfaceScale(),71new D3DSurfaceToSurfaceTransform(),7273// render-to-texture surface->surface ops74new D3DRTTSurfaceToSurfaceBlit(),75new D3DRTTSurfaceToSurfaceScale(),76new D3DRTTSurfaceToSurfaceTransform(),7778// surface->sw ops79new D3DSurfaceToSwBlit(SurfaceType.IntArgb,80D3DSurfaceData.ST_INT_ARGB),8182// sw->surface ops83blitIntArgbPreToSurface,84new D3DSwToSurfaceBlit(SurfaceType.IntArgb,85D3DSurfaceData.ST_INT_ARGB),86new D3DSwToSurfaceBlit(SurfaceType.IntRgb,87D3DSurfaceData.ST_INT_RGB),88new D3DSwToSurfaceBlit(SurfaceType.IntBgr,89D3DSurfaceData.ST_INT_BGR),90new D3DSwToSurfaceBlit(SurfaceType.ThreeByteBgr,91D3DSurfaceData.ST_3BYTE_BGR),92new D3DSwToSurfaceBlit(SurfaceType.Ushort565Rgb,93D3DSurfaceData.ST_USHORT_565_RGB),94new D3DSwToSurfaceBlit(SurfaceType.Ushort555Rgb,95D3DSurfaceData.ST_USHORT_555_RGB),96new D3DSwToSurfaceBlit(SurfaceType.ByteIndexed,97D3DSurfaceData.ST_BYTE_INDEXED),98// REMIND: we don't have a native sw loop to back this loop up99// new D3DSwToSurfaceBlit(SurfaceType.ByteIndexedBm,100// D3DSurfaceData.ST_BYTE_INDEXED_BM),101new D3DGeneralBlit(D3DSurfaceData.D3DSurface,102CompositeType.AnyAlpha,103blitIntArgbPreToSurface),104105new D3DSwToSurfaceScale(SurfaceType.IntArgb,106D3DSurfaceData.ST_INT_ARGB),107new D3DSwToSurfaceScale(SurfaceType.IntArgbPre,108D3DSurfaceData.ST_INT_ARGB_PRE),109new D3DSwToSurfaceScale(SurfaceType.IntRgb,110D3DSurfaceData.ST_INT_RGB),111new D3DSwToSurfaceScale(SurfaceType.IntBgr,112D3DSurfaceData.ST_INT_BGR),113new D3DSwToSurfaceScale(SurfaceType.ThreeByteBgr,114D3DSurfaceData.ST_3BYTE_BGR),115new D3DSwToSurfaceScale(SurfaceType.Ushort565Rgb,116D3DSurfaceData.ST_USHORT_565_RGB),117new D3DSwToSurfaceScale(SurfaceType.Ushort555Rgb,118D3DSurfaceData.ST_USHORT_555_RGB),119new D3DSwToSurfaceScale(SurfaceType.ByteIndexed,120D3DSurfaceData.ST_BYTE_INDEXED),121// REMIND: we don't have a native sw loop to back this loop up122// new D3DSwToSurfaceScale(SurfaceType.ByteIndexedBm,123// D3DSurfaceData.ST_BYTE_INDEXED_BM),124125new D3DSwToSurfaceTransform(SurfaceType.IntArgb,126D3DSurfaceData.ST_INT_ARGB),127new D3DSwToSurfaceTransform(SurfaceType.IntRgb,128D3DSurfaceData.ST_INT_RGB),129new D3DSwToSurfaceTransform(SurfaceType.IntBgr,130D3DSurfaceData.ST_INT_BGR),131new D3DSwToSurfaceTransform(SurfaceType.ThreeByteBgr,132D3DSurfaceData.ST_3BYTE_BGR),133new D3DSwToSurfaceTransform(SurfaceType.Ushort565Rgb,134D3DSurfaceData.ST_USHORT_565_RGB),135new D3DSwToSurfaceTransform(SurfaceType.Ushort555Rgb,136D3DSurfaceData.ST_USHORT_555_RGB),137new D3DSwToSurfaceTransform(SurfaceType.ByteIndexed,138D3DSurfaceData.ST_BYTE_INDEXED),139// REMIND: we don't have a native sw loop to back this loop up140// new D3DSwToSurfaceTransform(SurfaceType.ByteIndexedBm,141// D3DSurfaceData.ST_BYTE_INDEXED_BM),142transformBlitIntArgbPreToSurface,143144new D3DGeneralTransformedBlit(transformBlitIntArgbPreToSurface),145146// texture->surface ops147new D3DTextureToSurfaceBlit(),148new D3DTextureToSurfaceScale(),149new D3DTextureToSurfaceTransform(),150151// sw->texture ops152blitIntArgbPreToTexture,153new D3DSwToTextureBlit(SurfaceType.IntRgb,154D3DSurfaceData.ST_INT_RGB),155new D3DSwToTextureBlit(SurfaceType.IntArgb,156D3DSurfaceData.ST_INT_ARGB),157new D3DSwToTextureBlit(SurfaceType.IntBgr,158D3DSurfaceData.ST_INT_BGR),159new D3DSwToTextureBlit(SurfaceType.ThreeByteBgr,160D3DSurfaceData.ST_3BYTE_BGR),161new D3DSwToTextureBlit(SurfaceType.Ushort565Rgb,162D3DSurfaceData.ST_USHORT_565_RGB),163new D3DSwToTextureBlit(SurfaceType.Ushort555Rgb,164D3DSurfaceData.ST_USHORT_555_RGB),165new D3DSwToTextureBlit(SurfaceType.ByteIndexed,166D3DSurfaceData.ST_BYTE_INDEXED),167// REMIND: we don't have a native sw loop to back this loop up168// new D3DSwToTextureBlit(SurfaceType.ByteIndexedBm,169// D3DSurfaceData.ST_BYTE_INDEXED_BM),170new D3DGeneralBlit(D3DSurfaceData.D3DTexture,171CompositeType.SrcNoEa,172blitIntArgbPreToTexture),173};174GraphicsPrimitiveMgr.register(primitives);175}176177/**178* The following offsets are used to pack the parameters in179* createPackedParams(). (They are also used at the native level when180* unpacking the params.)181*/182@Native private static final int OFFSET_SRCTYPE = 16;183@Native private static final int OFFSET_HINT = 8;184@Native private static final int OFFSET_TEXTURE = 3;185@Native private static final int OFFSET_RTT = 2;186@Native private static final int OFFSET_XFORM = 1;187@Native private static final int OFFSET_ISOBLIT = 0;188189/**190* Packs the given parameters into a single int value in order to save191* space on the rendering queue.192*/193private static int createPackedParams(boolean isoblit, boolean texture,194boolean rtt, boolean xform,195int hint, int srctype)196{197return198((srctype << OFFSET_SRCTYPE) |199(hint << OFFSET_HINT ) |200((texture ? 1 : 0) << OFFSET_TEXTURE) |201((rtt ? 1 : 0) << OFFSET_RTT ) |202((xform ? 1 : 0) << OFFSET_XFORM ) |203((isoblit ? 1 : 0) << OFFSET_ISOBLIT));204}205206/**207* Enqueues a BLIT operation with the given parameters. Note that the208* RenderQueue lock must be held before calling this method.209*/210private static void enqueueBlit(RenderQueue rq,211SurfaceData src, SurfaceData dst,212int packedParams,213int sx1, int sy1,214int sx2, int sy2,215double dx1, double dy1,216double dx2, double dy2)217{218// assert rq.lock.isHeldByCurrentThread();219RenderBuffer buf = rq.getBuffer();220rq.ensureCapacityAndAlignment(72, 24);221buf.putInt(BLIT);222buf.putInt(packedParams);223buf.putInt(sx1).putInt(sy1);224buf.putInt(sx2).putInt(sy2);225buf.putDouble(dx1).putDouble(dy1);226buf.putDouble(dx2).putDouble(dy2);227buf.putLong(src.getNativeOps());228buf.putLong(dst.getNativeOps());229}230231static void Blit(SurfaceData srcData, SurfaceData dstData,232Composite comp, Region clip,233AffineTransform xform, int hint,234int sx1, int sy1,235int sx2, int sy2,236double dx1, double dy1,237double dx2, double dy2,238int srctype, boolean texture)239{240int ctxflags = 0;241if (srcData.getTransparency() == Transparency.OPAQUE) {242ctxflags |= D3DContext.SRC_IS_OPAQUE;243}244245D3DSurfaceData d3dDst = (D3DSurfaceData)dstData;246D3DRenderQueue rq = D3DRenderQueue.getInstance();247rq.lock();248try {249// make sure the RenderQueue keeps a hard reference to the250// source (sysmem) SurfaceData to prevent it from being251// disposed while the operation is processed on the QFT252rq.addReference(srcData);253254if (texture) {255// make sure we have a current context before uploading256// the sysmem data to the texture object257D3DContext.setScratchSurface(d3dDst.getContext());258} else {259D3DContext.validateContext(d3dDst, d3dDst,260clip, comp, xform, null, null,261ctxflags);262}263264int packedParams = createPackedParams(false, texture,265false, xform != null,266hint, srctype);267enqueueBlit(rq, srcData, dstData,268packedParams,269sx1, sy1, sx2, sy2,270dx1, dy1, dx2, dy2);271272// always flush immediately, since we (currently) have no means273// of tracking changes to the system memory surface274rq.flushNow();275} finally {276rq.unlock();277}278279if (d3dDst.getType() == D3DSurfaceData.WINDOW) {280// flush immediately when copying to the screen to improve281// responsiveness of applications using VI or BI backbuffers282D3DScreenUpdateManager mgr =283(D3DScreenUpdateManager)ScreenUpdateManager.getInstance();284mgr.runUpdateNow();285}286}287288/**289* Note: The srcImg and biop parameters are only used when invoked290* from the D3DBufImgOps.renderImageWithOp() method; in all other cases,291* this method can be called with null values for those two parameters,292* and they will be effectively ignored.293*/294static void IsoBlit(SurfaceData srcData, SurfaceData dstData,295BufferedImage srcImg, BufferedImageOp biop,296Composite comp, Region clip,297AffineTransform xform, int hint,298int sx1, int sy1,299int sx2, int sy2,300double dx1, double dy1,301double dx2, double dy2,302boolean texture)303{304int ctxflags = 0;305if (srcData.getTransparency() == Transparency.OPAQUE) {306ctxflags |= D3DContext.SRC_IS_OPAQUE;307}308309D3DSurfaceData d3dDst = (D3DSurfaceData)dstData;310D3DRenderQueue rq = D3DRenderQueue.getInstance();311boolean rtt = false;312rq.lock();313try {314D3DSurfaceData d3dSrc = (D3DSurfaceData)srcData;315int srctype = d3dSrc.getType();316D3DSurfaceData srcCtxData = d3dSrc;317if (srctype == D3DSurfaceData.TEXTURE) {318rtt = false;319} else {320// the source is a backbuffer, or render-to-texture321// surface; we set rtt to true to differentiate this kind322// of surface from a regular texture object323rtt = true;324}325326D3DContext.validateContext(srcCtxData, d3dDst,327clip, comp, xform, null, null,328ctxflags);329330if (biop != null) {331D3DBufImgOps.enableBufImgOp(rq, d3dSrc, srcImg, biop);332}333334int packedParams = createPackedParams(true, texture,335rtt, xform != null,336hint, 0 /*unused*/);337enqueueBlit(rq, srcData, dstData,338packedParams,339sx1, sy1, sx2, sy2,340dx1, dy1, dx2, dy2);341342if (biop != null) {343D3DBufImgOps.disableBufImgOp(rq, biop);344}345} finally {346rq.unlock();347}348349if (rtt && (d3dDst.getType() == D3DSurfaceData.WINDOW)) {350// we only have to flush immediately when copying from a351// (non-texture) surface to the screen; otherwise Swing apps352// might appear unresponsive until the auto-flush completes353D3DScreenUpdateManager mgr =354(D3DScreenUpdateManager)ScreenUpdateManager.getInstance();355mgr.runUpdateNow();356}357}358}359360class D3DSurfaceToSurfaceBlit extends Blit {361362D3DSurfaceToSurfaceBlit() {363super(D3DSurfaceData.D3DSurface,364CompositeType.AnyAlpha,365D3DSurfaceData.D3DSurface);366}367368public void Blit(SurfaceData src, SurfaceData dst,369Composite comp, Region clip,370int sx, int sy, int dx, int dy, int w, int h)371{372D3DBlitLoops.IsoBlit(src, dst,373null, null,374comp, clip, null,375AffineTransformOp.TYPE_NEAREST_NEIGHBOR,376sx, sy, sx+w, sy+h,377dx, dy, dx+w, dy+h,378false);379}380}381382class D3DSurfaceToSurfaceScale extends ScaledBlit {383384D3DSurfaceToSurfaceScale() {385super(D3DSurfaceData.D3DSurface,386CompositeType.AnyAlpha,387D3DSurfaceData.D3DSurface);388}389390public void Scale(SurfaceData src, SurfaceData dst,391Composite comp, Region clip,392int sx1, int sy1,393int sx2, int sy2,394double dx1, double dy1,395double dx2, double dy2)396{397D3DBlitLoops.IsoBlit(src, dst,398null, null,399comp, clip, null,400AffineTransformOp.TYPE_NEAREST_NEIGHBOR,401sx1, sy1, sx2, sy2,402dx1, dy1, dx2, dy2,403false);404}405}406407class D3DSurfaceToSurfaceTransform extends TransformBlit {408409D3DSurfaceToSurfaceTransform() {410super(D3DSurfaceData.D3DSurface,411CompositeType.AnyAlpha,412D3DSurfaceData.D3DSurface);413}414415public void Transform(SurfaceData src, SurfaceData dst,416Composite comp, Region clip,417AffineTransform at, int hint,418int sx, int sy, int dx, int dy,419int w, int h)420{421D3DBlitLoops.IsoBlit(src, dst,422null, null,423comp, clip, at, hint,424sx, sy, sx+w, sy+h,425dx, dy, dx+w, dy+h,426false);427}428}429430class D3DRTTSurfaceToSurfaceBlit extends Blit {431432D3DRTTSurfaceToSurfaceBlit() {433super(D3DSurfaceData.D3DSurfaceRTT,434CompositeType.AnyAlpha,435D3DSurfaceData.D3DSurface);436}437438public void Blit(SurfaceData src, SurfaceData dst,439Composite comp, Region clip,440int sx, int sy, int dx, int dy, int w, int h)441{442D3DBlitLoops.IsoBlit(src, dst,443null, null,444comp, clip, null,445AffineTransformOp.TYPE_NEAREST_NEIGHBOR,446sx, sy, sx+w, sy+h,447dx, dy, dx+w, dy+h,448true);449}450}451452class D3DRTTSurfaceToSurfaceScale extends ScaledBlit {453454D3DRTTSurfaceToSurfaceScale() {455super(D3DSurfaceData.D3DSurfaceRTT,456CompositeType.AnyAlpha,457D3DSurfaceData.D3DSurface);458}459460public void Scale(SurfaceData src, SurfaceData dst,461Composite comp, Region clip,462int sx1, int sy1,463int sx2, int sy2,464double dx1, double dy1,465double dx2, double dy2)466{467D3DBlitLoops.IsoBlit(src, dst,468null, null,469comp, clip, null,470AffineTransformOp.TYPE_NEAREST_NEIGHBOR,471sx1, sy1, sx2, sy2,472dx1, dy1, dx2, dy2,473true);474}475}476477class D3DRTTSurfaceToSurfaceTransform extends TransformBlit {478479D3DRTTSurfaceToSurfaceTransform() {480super(D3DSurfaceData.D3DSurfaceRTT,481CompositeType.AnyAlpha,482D3DSurfaceData.D3DSurface);483}484485public void Transform(SurfaceData src, SurfaceData dst,486Composite comp, Region clip,487AffineTransform at, int hint,488int sx, int sy, int dx, int dy, int w, int h)489{490D3DBlitLoops.IsoBlit(src, dst,491null, null,492comp, clip, at, hint,493sx, sy, sx+w, sy+h,494dx, dy, dx+w, dy+h,495true);496}497}498499class D3DSurfaceToSwBlit extends Blit {500501private int typeval;502private WeakReference<SurfaceData> srcTmp;503504// REMIND: destination will actually be opaque/premultiplied...505D3DSurfaceToSwBlit(SurfaceType dstType, int typeval) {506super(D3DSurfaceData.D3DSurface,507CompositeType.SrcNoEa,508dstType);509this.typeval = typeval;510}511512/*513* Clip value is ignored in D3D SurfaceToSw blit.514* Root Cause: The native interfaces to D3D use StretchRect API followed515* by custom copy of pixels from Surface to Sysmem. As a result, clipping516* in D3DSurfaceToSw works 'only' for Rect clips, provided, proper srcX,517* srcY, dstX, dstY, width and height are passed to native interfaces.518* Non rect clips (For example: Shape clips) are ignored completely.519*520* Solution: There are three solutions possible to fix this issue.521* 1. Convert the entire Surface to Sysmem and perform regular Blit.522* An optimized version of this is to take up the conversion only523* when Shape clips are needed. Existing native interface will suffice524* for supporting Rect clips.525* 2. With help of existing classes we could perform SwToSurface,526* SurfaceToSurface (implements clip) and SurfaceToSw (complete copy)527* in order.528* 3. Modify the native D3D interface to accept clip and perform same logic529* as the second approach but at native side.530*531* Upon multiple experiments, the first approach has been found to be532* faster than the others as it deploys 1-draw/copy operation for rect clip533* and 2-draw/copy operations for shape clip compared to 3-draws/copy534* operations deployed by the remaining approaches.535*536* complexClipBlit method helps to convert or copy the contents from537* D3DSurface onto Sysmem and perform a regular Blit with the clip538* information as required. This method is used when non-rectangular539* clip is needed.540*/541private synchronized void complexClipBlit(SurfaceData src, SurfaceData dst,542Composite comp, Region clip,543int sx, int sy, int dx, int dy,544int w, int h) {545SurfaceData cachedSrc = null;546if (srcTmp != null) {547// use cached intermediate surface, if available548cachedSrc = srcTmp.get();549}550551// Type- indicates the pixel format of Sysmem based BufferedImage.552// Native d3d interfaces support on the fly conversion of pixels from553// d3d surface to destination sysmem memory of type IntARGB only.554final int type = BufferedImage.TYPE_INT_ARGB;555src = convertFrom(this, src, sx, sy, w, h, cachedSrc, type);556557// copy intermediate SW to destination SW using complex clip558final Blit performop = Blit.getFromCache(src.getSurfaceType(),559CompositeType.SrcNoEa,560dst.getSurfaceType());561performop.Blit(src, dst, comp, clip, 0, 0, dx, dy, w, h);562563if (src != cachedSrc) {564// cache the intermediate surface565srcTmp = new WeakReference<>(src);566}567}568569public void Blit(SurfaceData src, SurfaceData dst,570Composite comp, Region clip,571int sx, int sy, int dx, int dy,572int w, int h)573{574if (clip != null) {575clip = clip.getIntersectionXYWH(dx, dy, w, h);576// At the end this method will flush the RenderQueue, we should exit577// from it as soon as possible.578if (clip.isEmpty()) {579return;580}581582// Adjust final dst(x,y) and src(x,y) based on the clip. The583// logic is that, when clip limits drawing on the destination,584// corresponding pixels from the src should be skipped.585sx += clip.getLoX() - dx;586sy += clip.getLoY() - dy;587dx = clip.getLoX();588dy = clip.getLoY();589w = clip.getWidth();590h = clip.getHeight();591592// Check if the clip is Rectangular. For non-rectangular clips593// complexClipBlit will convert Surface To Sysmem and perform594// regular Blit.595if (!clip.isRectangular()) {596complexClipBlit(src, dst, comp, clip,597sx, sy, dx, dy,598w, h);599return;600}601}602603D3DRenderQueue rq = D3DRenderQueue.getInstance();604rq.lock();605try {606// make sure the RenderQueue keeps a hard reference to the607// destination (sysmem) SurfaceData to prevent it from being608// disposed while the operation is processed on the QFT609rq.addReference(dst);610611RenderBuffer buf = rq.getBuffer();612D3DContext.setScratchSurface(((D3DSurfaceData)src).getContext());613614rq.ensureCapacityAndAlignment(48, 32);615buf.putInt(SURFACE_TO_SW_BLIT);616buf.putInt(sx).putInt(sy);617buf.putInt(dx).putInt(dy);618buf.putInt(w).putInt(h);619buf.putInt(typeval);620buf.putLong(src.getNativeOps());621buf.putLong(dst.getNativeOps());622623// always flush immediately624rq.flushNow();625} finally {626rq.unlock();627}628}629}630631class D3DSwToSurfaceBlit extends Blit {632633private int typeval;634635D3DSwToSurfaceBlit(SurfaceType srcType, int typeval) {636super(srcType,637CompositeType.AnyAlpha,638D3DSurfaceData.D3DSurface);639this.typeval = typeval;640}641642public void Blit(SurfaceData src, SurfaceData dst,643Composite comp, Region clip,644int sx, int sy, int dx, int dy, int w, int h)645{646D3DBlitLoops.Blit(src, dst,647comp, clip, null,648AffineTransformOp.TYPE_NEAREST_NEIGHBOR,649sx, sy, sx+w, sy+h,650dx, dy, dx+w, dy+h,651typeval, false);652}653}654655class D3DSwToSurfaceScale extends ScaledBlit {656657private int typeval;658659D3DSwToSurfaceScale(SurfaceType srcType, int typeval) {660super(srcType,661CompositeType.AnyAlpha,662D3DSurfaceData.D3DSurface);663this.typeval = typeval;664}665666public void Scale(SurfaceData src, SurfaceData dst,667Composite comp, Region clip,668int sx1, int sy1,669int sx2, int sy2,670double dx1, double dy1,671double dx2, double dy2)672{673D3DBlitLoops.Blit(src, dst,674comp, clip, null,675AffineTransformOp.TYPE_NEAREST_NEIGHBOR,676sx1, sy1, sx2, sy2,677dx1, dy1, dx2, dy2,678typeval, false);679}680}681682class D3DSwToSurfaceTransform extends TransformBlit {683684private int typeval;685686D3DSwToSurfaceTransform(SurfaceType srcType, int typeval) {687super(srcType,688CompositeType.AnyAlpha,689D3DSurfaceData.D3DSurface);690this.typeval = typeval;691}692693public void Transform(SurfaceData src, SurfaceData dst,694Composite comp, Region clip,695AffineTransform at, int hint,696int sx, int sy, int dx, int dy, int w, int h)697{698D3DBlitLoops.Blit(src, dst,699comp, clip, at, hint,700sx, sy, sx+w, sy+h,701dx, dy, dx+w, dy+h,702typeval, false);703}704}705706class D3DSwToTextureBlit extends Blit {707708private int typeval;709710D3DSwToTextureBlit(SurfaceType srcType, int typeval) {711super(srcType,712CompositeType.SrcNoEa,713D3DSurfaceData.D3DTexture);714this.typeval = typeval;715}716717public void Blit(SurfaceData src, SurfaceData dst,718Composite comp, Region clip,719int sx, int sy, int dx, int dy, int w, int h)720{721D3DBlitLoops.Blit(src, dst,722comp, clip, null,723AffineTransformOp.TYPE_NEAREST_NEIGHBOR,724sx, sy, sx+w, sy+h,725dx, dy, dx+w, dy+h,726typeval, true);727}728}729730class D3DTextureToSurfaceBlit extends Blit {731732D3DTextureToSurfaceBlit() {733super(D3DSurfaceData.D3DTexture,734CompositeType.AnyAlpha,735D3DSurfaceData.D3DSurface);736}737738public void Blit(SurfaceData src, SurfaceData dst,739Composite comp, Region clip,740int sx, int sy, int dx, int dy, int w, int h)741{742D3DBlitLoops.IsoBlit(src, dst,743null, null,744comp, clip, null,745AffineTransformOp.TYPE_NEAREST_NEIGHBOR,746sx, sy, sx+w, sy+h,747dx, dy, dx+w, dy+h,748true);749}750}751752class D3DTextureToSurfaceScale extends ScaledBlit {753754D3DTextureToSurfaceScale() {755super(D3DSurfaceData.D3DTexture,756CompositeType.AnyAlpha,757D3DSurfaceData.D3DSurface);758}759760public void Scale(SurfaceData src, SurfaceData dst,761Composite comp, Region clip,762int sx1, int sy1,763int sx2, int sy2,764double dx1, double dy1,765double dx2, double dy2)766{767D3DBlitLoops.IsoBlit(src, dst,768null, null,769comp, clip, null,770AffineTransformOp.TYPE_NEAREST_NEIGHBOR,771sx1, sy1, sx2, sy2,772dx1, dy1, dx2, dy2,773true);774}775}776777class D3DTextureToSurfaceTransform extends TransformBlit {778779D3DTextureToSurfaceTransform() {780super(D3DSurfaceData.D3DTexture,781CompositeType.AnyAlpha,782D3DSurfaceData.D3DSurface);783}784785public void Transform(SurfaceData src, SurfaceData dst,786Composite comp, Region clip,787AffineTransform at, int hint,788int sx, int sy, int dx, int dy,789int w, int h)790{791D3DBlitLoops.IsoBlit(src, dst,792null, null,793comp, clip, at, hint,794sx, sy, sx+w, sy+h,795dx, dy, dx+w, dy+h,796true);797}798}799800/**801* This general Blit implementation converts any source surface to an802* intermediate IntArgbPre surface, and then uses the more specific803* IntArgbPre->D3DSurface/Texture loop to get the intermediate804* (premultiplied) surface down to D3D using simple blit.805*/806class D3DGeneralBlit extends Blit {807808private final Blit performop;809private WeakReference<SurfaceData> srcTmp;810811D3DGeneralBlit(SurfaceType dstType,812CompositeType compType,813Blit performop)814{815super(SurfaceType.Any, compType, dstType);816this.performop = performop;817}818819public synchronized void Blit(SurfaceData src, SurfaceData dst,820Composite comp, Region clip,821int sx, int sy, int dx, int dy,822int w, int h)823{824Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),825CompositeType.SrcNoEa,826SurfaceType.IntArgbPre);827828SurfaceData cachedSrc = null;829if (srcTmp != null) {830// use cached intermediate surface, if available831cachedSrc = srcTmp.get();832}833834// convert source to IntArgbPre835src = convertFrom(convertsrc, src, sx, sy, w, h,836cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE);837838// copy IntArgbPre intermediate surface to D3D surface839performop.Blit(src, dst, comp, clip,8400, 0, dx, dy, w, h);841842if (src != cachedSrc) {843// cache the intermediate surface844srcTmp = new WeakReference<>(src);845}846}847}848849/**850* This general TransformedBlit implementation converts any source surface to an851* intermediate IntArgbPre surface, and then uses the more specific852* IntArgbPre->D3DSurface/Texture loop to get the intermediate853* (premultiplied) surface down to D3D using simple transformBlit.854*/855final class D3DGeneralTransformedBlit extends TransformBlit {856857private final TransformBlit performop;858private WeakReference<SurfaceData> srcTmp;859860D3DGeneralTransformedBlit(final TransformBlit performop) {861super(SurfaceType.Any, CompositeType.AnyAlpha,862D3DSurfaceData.D3DSurface);863this.performop = performop;864}865866@Override867public synchronized void Transform(SurfaceData src, SurfaceData dst,868Composite comp, Region clip,869AffineTransform at, int hint, int srcx,870int srcy, int dstx, int dsty, int width,871int height){872Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),873CompositeType.SrcNoEa,874SurfaceType.IntArgbPre);875// use cached intermediate surface, if available876final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null;877// convert source to IntArgbPre878src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc,879BufferedImage.TYPE_INT_ARGB_PRE);880881// transform IntArgbPre intermediate surface to D3D surface882performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty,883width, height);884885if (src != cachedSrc) {886// cache the intermediate surface887srcTmp = new WeakReference<>(src);888}889}890}891892/*893* The following classes prohibit copying D3DSurfaces to the screen894* (the D3D->sysmem->GDI path is known to be very very slow).895*896* Note: we used to disable hw acceleration for the surafce manager associated897* with the source surface in these loops but it proved to be too cautious.898*899* In most cases d3d->screen copy happens only during some transitional900* period where the accelerated destination surface is being recreated or901* restored (for example, when Swing's backbuffer VI is copied to the screen902* but the D3DScreenSurfaceManager couldn't restore its surface).903*904* An exception is if for some reason we could not enable accelerated on-screen905* rendering for this window for some permanent reason (like window being too906* small, or a present BufferStrategy).907*908* This meant that we'd disable hw acceleration after the first failure909* completely (at least until the src image is recreated which in case of910* Swing back-buffer happens only after resize).911*912* Now we delegate to the VISM to figure out if the acceleration needs to913* be disabled or if we can wait for a while until the onscreen accelerated914* can resume (by marking the source surface lost and making sure the915* VISM has a chance to use the backup surface).916*917*/918919class D3DSurfaceToGDIWindowSurfaceBlit extends Blit {920921D3DSurfaceToGDIWindowSurfaceBlit() {922super(D3DSurfaceData.D3DSurface,923CompositeType.AnyAlpha,924GDIWindowSurfaceData.AnyGdi);925}926@Override927public void Blit(SurfaceData src, SurfaceData dst,928Composite comp, Region clip,929int sx, int sy, int dx, int dy, int w, int h)930{931// see comment above932D3DVolatileSurfaceManager.handleVItoScreenOp(src, dst);933}934935}936937class D3DSurfaceToGDIWindowSurfaceScale extends ScaledBlit {938939D3DSurfaceToGDIWindowSurfaceScale() {940super(D3DSurfaceData.D3DSurface,941CompositeType.AnyAlpha,942GDIWindowSurfaceData.AnyGdi);943}944@Override945public void Scale(SurfaceData src, SurfaceData dst,946Composite comp, Region clip,947int sx1, int sy1,948int sx2, int sy2,949double dx1, double dy1,950double dx2, double dy2)951{952// see comment above953D3DVolatileSurfaceManager.handleVItoScreenOp(src, dst);954}955}956957class D3DSurfaceToGDIWindowSurfaceTransform extends TransformBlit {958959D3DSurfaceToGDIWindowSurfaceTransform() {960super(D3DSurfaceData.D3DSurface,961CompositeType.AnyAlpha,962GDIWindowSurfaceData.AnyGdi);963}964@Override965public void Transform(SurfaceData src, SurfaceData dst,966Composite comp, Region clip,967AffineTransform at, int hint,968int sx, int sy, int dx, int dy,969int w, int h)970{971// see comment above972D3DVolatileSurfaceManager.handleVItoScreenOp(src, dst);973}974}975976977