aboutsummaryrefslogtreecommitdiff
path: root/src/windows/classes/sun/java2d/d3d/D3DBlitLoops.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/windows/classes/sun/java2d/d3d/D3DBlitLoops.java')
-rw-r--r--src/windows/classes/sun/java2d/d3d/D3DBlitLoops.java862
1 files changed, 735 insertions, 127 deletions
diff --git a/src/windows/classes/sun/java2d/d3d/D3DBlitLoops.java b/src/windows/classes/sun/java2d/d3d/D3DBlitLoops.java
index 23aafd25f..459a197fa 100644
--- a/src/windows/classes/sun/java2d/d3d/D3DBlitLoops.java
+++ b/src/windows/classes/sun/java2d/d3d/D3DBlitLoops.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007-2008 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
@@ -29,131 +29,423 @@ import java.awt.Composite;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.lang.ref.WeakReference;
+import sun.java2d.ScreenUpdateManager;
+import sun.java2d.SurfaceData;
+import sun.java2d.loops.Blit;
+import sun.java2d.loops.CompositeType;
import sun.java2d.loops.GraphicsPrimitive;
import sun.java2d.loops.GraphicsPrimitiveMgr;
-import sun.java2d.loops.CompositeType;
-import sun.java2d.loops.SurfaceType;
-import sun.java2d.loops.Blit;
import sun.java2d.loops.ScaledBlit;
+import sun.java2d.loops.SurfaceType;
import sun.java2d.loops.TransformBlit;
import sun.java2d.pipe.Region;
-import sun.java2d.SurfaceData;
+import sun.java2d.pipe.RenderBuffer;
+import sun.java2d.pipe.RenderQueue;
+import static sun.java2d.pipe.BufferedOpCodes.*;
+import sun.java2d.windows.GDIWindowSurfaceData;
-import static sun.java2d.d3d.D3DSurfaceData.*;
+class D3DBlitLoops {
-/**
- * This class contains accelerated blits/scales/transforms
- * between textures and DD surfaces.
- */
-public class D3DBlitLoops {
+ static void register() {
+ Blit blitIntArgbPreToSurface =
+ new D3DSwToSurfaceBlit(SurfaceType.IntArgbPre,
+ D3DSurfaceData.ST_INT_ARGB_PRE);
+ Blit blitIntArgbPreToTexture =
+ new D3DSwToTextureBlit(SurfaceType.IntArgbPre,
+ D3DSurfaceData.ST_INT_ARGB_PRE);
- static void register()
- {
GraphicsPrimitive[] primitives = {
- new D3DTextureToSurfaceBlit(IntRgbD3D),
- new D3DTextureToSurfaceBlit(Ushort565RgbD3D),
- new D3DTextureToSurfaceBlit(IntRgbxD3D),
- new D3DTextureToSurfaceBlit(Ushort555RgbD3D),
- new D3DTextureToSurfaceBlit(ThreeByteBgrD3D),
-
- new D3DTextureToSurfaceScale(IntRgbD3D),
- new D3DTextureToSurfaceScale(Ushort565RgbD3D),
- new D3DTextureToSurfaceScale(IntRgbxD3D),
- new D3DTextureToSurfaceScale(Ushort555RgbD3D),
- new D3DTextureToSurfaceScale(ThreeByteBgrD3D),
-
- new D3DTextureToSurfaceTransform(D3DTexture, IntRgbD3D),
- new D3DTextureToSurfaceTransform(D3DTexture, Ushort565RgbD3D),
- new D3DTextureToSurfaceTransform(D3DTexture, IntRgbxD3D),
- new D3DTextureToSurfaceTransform(D3DTexture, Ushort555RgbD3D),
- new D3DTextureToSurfaceTransform(D3DTexture, ThreeByteBgrD3D),
-
- new DelegateSwToTextureLoop(),
+ // prevent D3DSurface -> Screen blits
+ new D3DSurfaceToGDIWindowSurfaceBlit(),
+ new D3DSurfaceToGDIWindowSurfaceScale(),
+ new D3DSurfaceToGDIWindowSurfaceTransform(),
+
+ // surface->surface ops
+ new D3DSurfaceToSurfaceBlit(),
+ new D3DSurfaceToSurfaceScale(),
+ new D3DSurfaceToSurfaceTransform(),
+
+ // render-to-texture surface->surface ops
+ new D3DRTTSurfaceToSurfaceBlit(),
+ new D3DRTTSurfaceToSurfaceScale(),
+ new D3DRTTSurfaceToSurfaceTransform(),
+
+ // surface->sw ops
+ new D3DSurfaceToSwBlit(SurfaceType.IntArgb,
+ D3DSurfaceData.ST_INT_ARGB),
+
+ // sw->surface ops
+ blitIntArgbPreToSurface,
+ new D3DSwToSurfaceBlit(SurfaceType.IntArgb,
+ D3DSurfaceData.ST_INT_ARGB),
+ new D3DSwToSurfaceBlit(SurfaceType.IntRgb,
+ D3DSurfaceData.ST_INT_RGB),
+ new D3DSwToSurfaceBlit(SurfaceType.IntBgr,
+ D3DSurfaceData.ST_INT_BGR),
+ new D3DSwToSurfaceBlit(SurfaceType.Ushort565Rgb,
+ D3DSurfaceData.ST_USHORT_565_RGB),
+ new D3DSwToSurfaceBlit(SurfaceType.Ushort555Rgb,
+ D3DSurfaceData.ST_USHORT_555_RGB),
+ new D3DSwToSurfaceBlit(SurfaceType.ByteIndexed,
+ D3DSurfaceData.ST_BYTE_INDEXED),
+ // REMIND: we don't have a native sw loop to back this loop up
+// new D3DSwToSurfaceBlit(SurfaceType.ByteIndexedBm,
+// D3DSurfaceData.ST_BYTE_INDEXED_BM),
+ new D3DGeneralBlit(D3DSurfaceData.D3DSurface,
+ CompositeType.AnyAlpha,
+ blitIntArgbPreToSurface),
+
+ new D3DSwToSurfaceScale(SurfaceType.IntArgb,
+ D3DSurfaceData.ST_INT_ARGB),
+ new D3DSwToSurfaceScale(SurfaceType.IntArgbPre,
+ D3DSurfaceData.ST_INT_ARGB_PRE),
+ new D3DSwToSurfaceScale(SurfaceType.IntRgb,
+ D3DSurfaceData.ST_INT_RGB),
+ new D3DSwToSurfaceScale(SurfaceType.IntBgr,
+ D3DSurfaceData.ST_INT_BGR),
+ new D3DSwToSurfaceScale(SurfaceType.Ushort565Rgb,
+ D3DSurfaceData.ST_USHORT_565_RGB),
+ new D3DSwToSurfaceScale(SurfaceType.Ushort555Rgb,
+ D3DSurfaceData.ST_USHORT_555_RGB),
+ new D3DSwToSurfaceScale(SurfaceType.ByteIndexed,
+ D3DSurfaceData.ST_BYTE_INDEXED),
+ // REMIND: we don't have a native sw loop to back this loop up
+// new D3DSwToSurfaceScale(SurfaceType.ByteIndexedBm,
+// D3DSurfaceData.ST_BYTE_INDEXED_BM),
+ new D3DSwToSurfaceTransform(SurfaceType.IntArgb,
+ D3DSurfaceData.ST_INT_ARGB),
+ new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre,
+ D3DSurfaceData.ST_INT_ARGB_PRE),
+ new D3DSwToSurfaceTransform(SurfaceType.IntRgb,
+ D3DSurfaceData.ST_INT_RGB),
+ new D3DSwToSurfaceTransform(SurfaceType.IntBgr,
+ D3DSurfaceData.ST_INT_BGR),
+ new D3DSwToSurfaceTransform(SurfaceType.Ushort565Rgb,
+ D3DSurfaceData.ST_USHORT_565_RGB),
+ new D3DSwToSurfaceTransform(SurfaceType.Ushort555Rgb,
+ D3DSurfaceData.ST_USHORT_555_RGB),
+ new D3DSwToSurfaceTransform(SurfaceType.ByteIndexed,
+ D3DSurfaceData.ST_BYTE_INDEXED),
+ // REMIND: we don't have a native sw loop to back this loop up
+// new D3DSwToSurfaceTransform(SurfaceType.ByteIndexedBm,
+// D3DSurfaceData.ST_BYTE_INDEXED_BM),
+
+ // texture->surface ops
+ new D3DTextureToSurfaceBlit(),
+ new D3DTextureToSurfaceScale(),
+ new D3DTextureToSurfaceTransform(),
+
+ // sw->texture ops
+ blitIntArgbPreToTexture,
+ new D3DSwToTextureBlit(SurfaceType.IntRgb,
+ D3DSurfaceData.ST_INT_RGB),
+ new D3DSwToTextureBlit(SurfaceType.IntArgb,
+ D3DSurfaceData.ST_INT_ARGB),
+ new D3DSwToTextureBlit(SurfaceType.IntBgr,
+ D3DSurfaceData.ST_INT_BGR),
+ new D3DSwToTextureBlit(SurfaceType.Ushort565Rgb,
+ D3DSurfaceData.ST_USHORT_565_RGB),
+ new D3DSwToTextureBlit(SurfaceType.Ushort555Rgb,
+ D3DSurfaceData.ST_USHORT_555_RGB),
+ new D3DSwToTextureBlit(SurfaceType.ByteIndexed,
+ D3DSurfaceData.ST_BYTE_INDEXED),
+ // REMIND: we don't have a native sw loop to back this loop up
+// new D3DSwToTextureBlit(SurfaceType.ByteIndexedBm,
+// D3DSurfaceData.ST_BYTE_INDEXED_BM),
+ new D3DGeneralBlit(D3DSurfaceData.D3DTexture,
+ CompositeType.SrcNoEa,
+ blitIntArgbPreToTexture),
};
GraphicsPrimitiveMgr.register(primitives);
}
- static native void doTransform(long pSrc, long pDst, long pCtx,
- int hint,
- int sx1, int sy1, int sx2, int sy2,
- float dx1, float dy1,
- float dx2, float dy2);
- static long getContext(SurfaceData src, SurfaceData dst,
- Region clip, Composite comp, AffineTransform at)
+ /**
+ * The following offsets are used to pack the parameters in
+ * createPackedParams(). (They are also used at the native level when
+ * unpacking the params.)
+ */
+ private static final int OFFSET_SRCTYPE = 16;
+ private static final int OFFSET_HINT = 8;
+ private static final int OFFSET_TEXTURE = 3;
+ private static final int OFFSET_RTT = 2;
+ private static final int OFFSET_XFORM = 1;
+ private static final int OFFSET_ISOBLIT = 0;
+
+ /**
+ * Packs the given parameters into a single int value in order to save
+ * space on the rendering queue.
+ */
+ private static int createPackedParams(boolean isoblit, boolean texture,
+ boolean rtt, boolean xform,
+ int hint, int srctype)
{
- int ctxFlags;
- if (src.getTransparency() == Transparency.OPAQUE) {
- ctxFlags = D3DContext.SRC_IS_OPAQUE;
- } else {
- ctxFlags = D3DContext.NO_CONTEXT_FLAGS;
- }
+ return
+ ((srctype << OFFSET_SRCTYPE) |
+ (hint << OFFSET_HINT ) |
+ ((texture ? 1 : 0) << OFFSET_TEXTURE) |
+ ((rtt ? 1 : 0) << OFFSET_RTT ) |
+ ((xform ? 1 : 0) << OFFSET_XFORM ) |
+ ((isoblit ? 1 : 0) << OFFSET_ISOBLIT));
+ }
- return D3DContext.getContext(src, dst, clip, comp, at,
- 0xffffffff /* rgb */, ctxFlags);
+ /**
+ * Enqueues a BLIT operation with the given parameters. Note that the
+ * RenderQueue lock must be held before calling this method.
+ */
+ private static void enqueueBlit(RenderQueue rq,
+ SurfaceData src, SurfaceData dst,
+ int packedParams,
+ int sx1, int sy1,
+ int sx2, int sy2,
+ double dx1, double dy1,
+ double dx2, double dy2)
+ {
+ // assert rq.lock.isHeldByCurrentThread();
+ RenderBuffer buf = rq.getBuffer();
+ rq.ensureCapacityAndAlignment(72, 24);
+ buf.putInt(BLIT);
+ buf.putInt(packedParams);
+ buf.putInt(sx1).putInt(sy1);
+ buf.putInt(sx2).putInt(sy2);
+ buf.putDouble(dx1).putDouble(dy1);
+ buf.putDouble(dx2).putDouble(dy2);
+ buf.putLong(src.getNativeOps());
+ buf.putLong(dst.getNativeOps());
}
-}
-class D3DTextureToSurfaceBlit extends Blit {
- D3DTextureToSurfaceBlit(SurfaceType dstType) {
- super(D3DTexture, CompositeType.AnyAlpha , dstType);
+ static void Blit(SurfaceData srcData, SurfaceData dstData,
+ Composite comp, Region clip,
+ AffineTransform xform, int hint,
+ int sx1, int sy1,
+ int sx2, int sy2,
+ double dx1, double dy1,
+ double dx2, double dy2,
+ int srctype, boolean texture)
+ {
+ int ctxflags = 0;
+ if (srcData.getTransparency() == Transparency.OPAQUE) {
+ ctxflags |= D3DContext.SRC_IS_OPAQUE;
+ }
+
+ D3DSurfaceData d3dDst = (D3DSurfaceData)dstData;
+ D3DRenderQueue rq = D3DRenderQueue.getInstance();
+ rq.lock();
+ try {
+ // make sure the RenderQueue keeps a hard reference to the
+ // source (sysmem) SurfaceData to prevent it from being
+ // disposed while the operation is processed on the QFT
+ rq.addReference(srcData);
+
+ if (texture) {
+ // make sure we have a current context before uploading
+ // the sysmem data to the texture object
+ D3DContext.setScratchSurface(d3dDst.getContext());
+ } else {
+ D3DContext.validateContext(d3dDst, d3dDst,
+ clip, comp, xform, null, null,
+ ctxflags);
+ }
+
+ int packedParams = createPackedParams(false, texture,
+ false, xform != null,
+ hint, srctype);
+ enqueueBlit(rq, srcData, dstData,
+ packedParams,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2);
+
+ // always flush immediately, since we (currently) have no means
+ // of tracking changes to the system memory surface
+ rq.flushNow();
+ } finally {
+ rq.unlock();
+ }
+
+ if (d3dDst.getType() == D3DSurfaceData.WINDOW) {
+ // flush immediately when copying to the screen to improve
+ // responsiveness of applications using VI or BI backbuffers
+ D3DScreenUpdateManager mgr =
+ (D3DScreenUpdateManager)ScreenUpdateManager.getInstance();
+ mgr.runUpdateNow();
+ }
}
/**
- * Blit
- * This native method is where all of the work happens in the
- * accelerated Blit.
+ * Note: The srcImg and biop parameters are only used when invoked
+ * from the D3DBufImgOps.renderImageWithOp() method; in all other cases,
+ * this method can be called with null values for those two parameters,
+ * and they will be effectively ignored.
*/
- @Override
+ static void IsoBlit(SurfaceData srcData, SurfaceData dstData,
+ BufferedImage srcImg, BufferedImageOp biop,
+ Composite comp, Region clip,
+ AffineTransform xform, int hint,
+ int sx1, int sy1,
+ int sx2, int sy2,
+ double dx1, double dy1,
+ double dx2, double dy2,
+ boolean texture)
+ {
+ int ctxflags = 0;
+ if (srcData.getTransparency() == Transparency.OPAQUE) {
+ ctxflags |= D3DContext.SRC_IS_OPAQUE;
+ }
+
+ D3DSurfaceData d3dDst = (D3DSurfaceData)dstData;
+ D3DRenderQueue rq = D3DRenderQueue.getInstance();
+ boolean rtt = false;
+ rq.lock();
+ try {
+ D3DSurfaceData d3dSrc = (D3DSurfaceData)srcData;
+ int srctype = d3dSrc.getType();
+ D3DSurfaceData srcCtxData = d3dSrc;
+ if (srctype == D3DSurfaceData.TEXTURE) {
+ rtt = false;
+ } else {
+ // the source is a backbuffer, or render-to-texture
+ // surface; we set rtt to true to differentiate this kind
+ // of surface from a regular texture object
+ rtt = true;
+ }
+
+ D3DContext.validateContext(srcCtxData, d3dDst,
+ clip, comp, xform, null, null,
+ ctxflags);
+
+ if (biop != null) {
+ D3DBufImgOps.enableBufImgOp(rq, d3dSrc, srcImg, biop);
+ }
+
+ int packedParams = createPackedParams(true, texture,
+ rtt, xform != null,
+ hint, 0 /*unused*/);
+ enqueueBlit(rq, srcData, dstData,
+ packedParams,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2);
+
+ if (biop != null) {
+ D3DBufImgOps.disableBufImgOp(rq, biop);
+ }
+ } finally {
+ rq.unlock();
+ }
+
+ if (rtt && (d3dDst.getType() == D3DSurfaceData.WINDOW)) {
+ // we only have to flush immediately when copying from a
+ // (non-texture) surface to the screen; otherwise Swing apps
+ // might appear unresponsive until the auto-flush completes
+ D3DScreenUpdateManager mgr =
+ (D3DScreenUpdateManager)ScreenUpdateManager.getInstance();
+ mgr.runUpdateNow();
+ }
+ }
+}
+
+class D3DSurfaceToSurfaceBlit extends Blit {
+
+ D3DSurfaceToSurfaceBlit() {
+ super(D3DSurfaceData.D3DSurface,
+ CompositeType.AnyAlpha,
+ D3DSurfaceData.D3DSurface);
+ }
+
public void Blit(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx, int sy, int dx, int dy, int w, int h)
{
- synchronized (D3DContext.LOCK) {
- long pCtx = D3DBlitLoops.getContext(src, dst, clip, comp, null);
- D3DBlitLoops.doTransform(src.getNativeOps(), dst.getNativeOps(),
- pCtx,
- AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
- sx, sy, sx+w, sy+h,
- (float)dx, (float)dy,
- (float)(dx+w), (float)(dy+h));
- }
+ D3DBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, null,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
+ sx, sy, sx+w, sy+h,
+ dx, dy, dx+w, dy+h,
+ false);
}
}
-class D3DTextureToSurfaceTransform extends TransformBlit {
+class D3DSurfaceToSurfaceScale extends ScaledBlit {
+
+ D3DSurfaceToSurfaceScale() {
+ super(D3DSurfaceData.D3DSurface,
+ CompositeType.AnyAlpha,
+ D3DSurfaceData.D3DSurface);
+ }
- D3DTextureToSurfaceTransform(SurfaceType srcType,
- SurfaceType 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)
{
- super(srcType, CompositeType.AnyAlpha, dstType);
+ D3DBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, null,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2,
+ false);
+ }
+}
+
+class D3DSurfaceToSurfaceTransform extends TransformBlit {
+
+ D3DSurfaceToSurfaceTransform() {
+ super(D3DSurfaceData.D3DSurface,
+ CompositeType.AnyAlpha,
+ D3DSurfaceData.D3DSurface);
}
- @Override
public void Transform(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
AffineTransform at, int hint,
int sx, int sy, int dx, int dy,
int w, int h)
{
- synchronized (D3DContext.LOCK) {
- long pCtx = D3DBlitLoops.getContext(src, dst, clip, comp, at);
- D3DBlitLoops.doTransform(src.getNativeOps(), dst.getNativeOps(),
- pCtx, hint,
- sx, sy, sx+w, sy+h,
- (float)dx, (float)dy,
- (float)(dx+w), (float)(dy+h));
- }
+ D3DBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, at, hint,
+ sx, sy, sx+w, sy+h,
+ dx, dy, dx+w, dy+h,
+ false);
}
}
-class D3DTextureToSurfaceScale extends ScaledBlit {
+class D3DRTTSurfaceToSurfaceBlit extends Blit {
- D3DTextureToSurfaceScale(SurfaceType dstType) {
- super(D3DTexture, CompositeType.AnyAlpha, dstType);
+ D3DRTTSurfaceToSurfaceBlit() {
+ super(D3DSurfaceData.D3DSurfaceRTT,
+ CompositeType.AnyAlpha,
+ D3DSurfaceData.D3DSurface);
+ }
+
+ public void Blit(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ int sx, int sy, int dx, int dy, int w, int h)
+ {
+ D3DBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, null,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
+ sx, sy, sx+w, sy+h,
+ dx, dy, dx+w, dy+h,
+ true);
+ }
+}
+
+class D3DRTTSurfaceToSurfaceScale extends ScaledBlit {
+
+ D3DRTTSurfaceToSurfaceScale() {
+ super(D3DSurfaceData.D3DSurfaceRTT,
+ CompositeType.AnyAlpha,
+ D3DSurfaceData.D3DSurface);
}
- @Override
public void Scale(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx1, int sy1,
@@ -161,65 +453,381 @@ class D3DTextureToSurfaceScale extends ScaledBlit {
double dx1, double dy1,
double dx2, double dy2)
{
- synchronized (D3DContext.LOCK) {
- long pCtx = D3DBlitLoops.getContext(src, dst, clip, comp, null);
- D3DBlitLoops.doTransform(src.getNativeOps(), dst.getNativeOps(),
- pCtx,
- AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
- sx1, sy1, sx2, sy2,
- (float)dx1, (float)dy1,
- (float)dx2, (float)dy2);
+ D3DBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, null,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2,
+ true);
+ }
+}
+
+class D3DRTTSurfaceToSurfaceTransform extends TransformBlit {
+
+ D3DRTTSurfaceToSurfaceTransform() {
+ super(D3DSurfaceData.D3DSurfaceRTT,
+ CompositeType.AnyAlpha,
+ D3DSurfaceData.D3DSurface);
+ }
+
+ public void Transform(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ AffineTransform at, int hint,
+ int sx, int sy, int dx, int dy, int w, int h)
+ {
+ D3DBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, at, hint,
+ sx, sy, sx+w, sy+h,
+ dx, dy, dx+w, dy+h,
+ true);
+ }
+}
+
+class D3DSurfaceToSwBlit extends Blit {
+
+ private int typeval;
+
+ // REMIND: destination will actually be opaque/premultiplied...
+ D3DSurfaceToSwBlit(SurfaceType dstType, int typeval) {
+ super(D3DSurfaceData.D3DSurface,
+ CompositeType.SrcNoEa,
+ dstType);
+ this.typeval = typeval;
+ }
+
+ public void Blit(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ int sx, int sy, int dx, int dy,
+ int w, int h)
+ {
+ D3DRenderQueue rq = D3DRenderQueue.getInstance();
+ rq.lock();
+ try {
+ // make sure the RenderQueue keeps a hard reference to the
+ // destination (sysmem) SurfaceData to prevent it from being
+ // disposed while the operation is processed on the QFT
+ rq.addReference(dst);
+
+ RenderBuffer buf = rq.getBuffer();
+ D3DContext.setScratchSurface(((D3DSurfaceData)src).getContext());
+
+ rq.ensureCapacityAndAlignment(48, 32);
+ buf.putInt(SURFACE_TO_SW_BLIT);
+ buf.putInt(sx).putInt(sy);
+ buf.putInt(dx).putInt(dy);
+ buf.putInt(w).putInt(h);
+ buf.putInt(typeval);
+ buf.putLong(src.getNativeOps());
+ buf.putLong(dst.getNativeOps());
+
+ // always flush immediately
+ rq.flushNow();
+ } finally {
+ rq.unlock();
}
}
}
-class DelegateSwToTextureLoop extends Blit {
+class D3DSwToSurfaceBlit extends Blit {
+
+ private int typeval;
- DelegateSwToTextureLoop() {
- super(SurfaceType.Any, CompositeType.SrcNoEa, D3DTexture);
+ D3DSwToSurfaceBlit(SurfaceType srcType, int typeval) {
+ super(srcType,
+ CompositeType.AnyAlpha,
+ D3DSurfaceData.D3DSurface);
+ this.typeval = typeval;
}
- @Override
public void Blit(SurfaceData src, SurfaceData dst,
Composite comp, Region clip,
int sx, int sy, int dx, int dy, int w, int h)
{
- Blit realBlit = null;
- int pf = ((D3DSurfaceData)dst).getPixelFormat();
- switch (pf) {
- case PF_INT_ARGB:
- realBlit = Blit.getFromCache(src.getSurfaceType(),
- CompositeType.SrcNoEa,
- SurfaceType.IntArgbPre);
- break;
- case PF_INT_RGB:
- realBlit = Blit.getFromCache(src.getSurfaceType(),
- CompositeType.SrcNoEa,
- SurfaceType.IntRgb);
- break;
- case PF_USHORT_565_RGB:
- realBlit = Blit.getFromCache(src.getSurfaceType(),
- CompositeType.SrcNoEa,
- SurfaceType.Ushort565Rgb);
- break;
- case PF_USHORT_555_RGB:
- realBlit = Blit.getFromCache(src.getSurfaceType(),
- CompositeType.SrcNoEa,
- SurfaceType.Ushort555Rgb);
- break;
- case PF_USHORT_4444_ARGB:
- // REMIND: this should really be premultiplied!
- realBlit = Blit.getFromCache(src.getSurfaceType(),
- CompositeType.SrcNoEa,
- SurfaceType.Ushort4444Argb);
- break;
- default:
- throw
- new InternalError("Can't yet handle dest pixel format: "+pf);
+ D3DBlitLoops.Blit(src, dst,
+ comp, clip, null,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
+ sx, sy, sx+w, sy+h,
+ dx, dy, dx+w, dy+h,
+ typeval, false);
+ }
+}
+
+class D3DSwToSurfaceScale extends ScaledBlit {
+
+ private int typeval;
+
+ D3DSwToSurfaceScale(SurfaceType srcType, int typeval) {
+ super(srcType,
+ CompositeType.AnyAlpha,
+ D3DSurfaceData.D3DSurface);
+ this.typeval = typeval;
+ }
+
+ 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)
+ {
+ D3DBlitLoops.Blit(src, dst,
+ comp, clip, null,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2,
+ typeval, false);
+ }
+}
+
+class D3DSwToSurfaceTransform extends TransformBlit {
+
+ private int typeval;
+
+ D3DSwToSurfaceTransform(SurfaceType srcType, int typeval) {
+ super(srcType,
+ CompositeType.AnyAlpha,
+ D3DSurfaceData.D3DSurface);
+ this.typeval = typeval;
+ }
+
+ public void Transform(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ AffineTransform at, int hint,
+ int sx, int sy, int dx, int dy, int w, int h)
+ {
+ D3DBlitLoops.Blit(src, dst,
+ comp, clip, at, hint,
+ sx, sy, sx+w, sy+h,
+ dx, dy, dx+w, dy+h,
+ typeval, false);
+ }
+}
+
+class D3DSwToTextureBlit extends Blit {
+
+ private int typeval;
+
+ D3DSwToTextureBlit(SurfaceType srcType, int typeval) {
+ super(srcType,
+ CompositeType.SrcNoEa,
+ D3DSurfaceData.D3DTexture);
+ this.typeval = typeval;
+ }
+
+ public void Blit(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ int sx, int sy, int dx, int dy, int w, int h)
+ {
+ D3DBlitLoops.Blit(src, dst,
+ comp, clip, null,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
+ sx, sy, sx+w, sy+h,
+ dx, dy, dx+w, dy+h,
+ typeval, true);
+ }
+}
+
+class D3DTextureToSurfaceBlit extends Blit {
+
+ D3DTextureToSurfaceBlit() {
+ super(D3DSurfaceData.D3DTexture,
+ CompositeType.AnyAlpha,
+ D3DSurfaceData.D3DSurface);
+ }
+
+ public void Blit(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ int sx, int sy, int dx, int dy, int w, int h)
+ {
+ D3DBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, null,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
+ sx, sy, sx+w, sy+h,
+ dx, dy, dx+w, dy+h,
+ true);
+ }
+}
+
+class D3DTextureToSurfaceScale extends ScaledBlit {
+
+ D3DTextureToSurfaceScale() {
+ super(D3DSurfaceData.D3DTexture,
+ CompositeType.AnyAlpha,
+ D3DSurfaceData.D3DSurface);
+ }
+
+ 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)
+ {
+ D3DBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, null,
+ AffineTransformOp.TYPE_NEAREST_NEIGHBOR,
+ sx1, sy1, sx2, sy2,
+ dx1, dy1, dx2, dy2,
+ true);
+ }
+}
+
+class D3DTextureToSurfaceTransform extends TransformBlit {
+
+ D3DTextureToSurfaceTransform() {
+ super(D3DSurfaceData.D3DTexture,
+ CompositeType.AnyAlpha,
+ D3DSurfaceData.D3DSurface);
+ }
+
+ public void Transform(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ AffineTransform at, int hint,
+ int sx, int sy, int dx, int dy,
+ int w, int h)
+ {
+ D3DBlitLoops.IsoBlit(src, dst,
+ null, null,
+ comp, clip, at, hint,
+ sx, sy, sx+w, sy+h,
+ dx, dy, dx+w, dy+h,
+ true);
+ }
+}
+
+/**
+ * This general Blit implemenation converts any source surface to an
+ * intermediate IntArgbPre surface, and then uses the more specific
+ * IntArgbPre->D3DSurface/Texture loop to get the intermediate
+ * (premultiplied) surface down to D3D.
+ */
+class D3DGeneralBlit extends Blit {
+
+ private Blit performop;
+ private WeakReference srcTmp;
+
+ D3DGeneralBlit(SurfaceType dstType,
+ CompositeType compType,
+ Blit performop)
+ {
+ super(SurfaceType.Any, compType, dstType);
+ this.performop = performop;
+ }
+
+ public synchronized void Blit(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ int sx, int sy, int dx, int dy,
+ int w, int h)
+ {
+ Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
+ CompositeType.SrcNoEa,
+ SurfaceType.IntArgbPre);
+
+ SurfaceData cachedSrc = null;
+ if (srcTmp != null) {
+ // use cached intermediate surface, if available
+ cachedSrc = (SurfaceData)srcTmp.get();
}
- if (realBlit != null) {
- realBlit.Blit(src, dst, comp, clip, sx, sy, dx, dy, w, h);
+ // convert source to IntArgbPre
+ src = convertFrom(convertsrc, src, sx, sy, w, h,
+ cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE);
+
+ // copy IntArgbPre intermediate surface to D3D surface
+ performop.Blit(src, dst, comp, clip,
+ 0, 0, dx, dy, w, h);
+
+ if (src != cachedSrc) {
+ // cache the intermediate surface
+ srcTmp = new WeakReference(src);
}
}
}
+
+/*
+ * The following classes prohibit copying D3DSurfaces to the screen
+ * (the D3D->sysmem->GDI path is known to be very very slow).
+ *
+ * Note: we used to disable hw acceleration for the surafce manager associated
+ * with the source surface in these loops but it proved to be too cautious.
+ *
+ * In most cases d3d->screen copy happens only during some transitional
+ * period where the accelerated destination surface is being recreated or
+ * restored (for example, when Swing's backbuffer VI is copied to the screen
+ * but the D3DScreenSurfaceManager couldn't restore its surface).
+ *
+ * An exception is if for some reason we could not enable accelerated on-screen
+ * rendering for this window for some permanent reason (like window being too
+ * small, or a present BufferStrategy).
+ *
+ * This meant that we'd disable hw acceleration after the first failure
+ * completely (at least until the src image is recreated which in case of
+ * Swing back-buffer happens only after resize).
+ *
+ * Now we delegate to the VISM to figure out if the acceleration needs to
+ * be disabled or if we can wait for a while until the onscreen accelerated
+ * can resume (by marking the source surface lost and making sure the
+ * VISM has a chance to use the backup surface).
+ *
+ */
+
+class D3DSurfaceToGDIWindowSurfaceBlit extends Blit {
+
+ D3DSurfaceToGDIWindowSurfaceBlit() {
+ super(D3DSurfaceData.D3DSurface,
+ CompositeType.AnyAlpha,
+ GDIWindowSurfaceData.AnyGdi);
+ }
+ @Override
+ public void Blit(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ int sx, int sy, int dx, int dy, int w, int h)
+ {
+ // see comment above
+ D3DVolatileSurfaceManager.handleVItoScreenOp(src, dst);
+ }
+
+}
+
+class D3DSurfaceToGDIWindowSurfaceScale extends ScaledBlit {
+
+ D3DSurfaceToGDIWindowSurfaceScale() {
+ super(D3DSurfaceData.D3DSurface,
+ CompositeType.AnyAlpha,
+ GDIWindowSurfaceData.AnyGdi);
+ }
+ @Override
+ 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)
+ {
+ // see comment above
+ D3DVolatileSurfaceManager.handleVItoScreenOp(src, dst);
+ }
+}
+
+class D3DSurfaceToGDIWindowSurfaceTransform extends TransformBlit {
+
+ D3DSurfaceToGDIWindowSurfaceTransform() {
+ super(D3DSurfaceData.D3DSurface,
+ CompositeType.AnyAlpha,
+ GDIWindowSurfaceData.AnyGdi);
+ }
+ @Override
+ public void Transform(SurfaceData src, SurfaceData dst,
+ Composite comp, Region clip,
+ AffineTransform at, int hint,
+ int sx, int sy, int dx, int dy,
+ int w, int h)
+ {
+ // see comment above
+ D3DVolatileSurfaceManager.handleVItoScreenOp(src, dst);
+ }
+}