package sun.java2d.d3d;
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.ScaledBlit;
import sun.java2d.loops.SurfaceType;
import sun.java2d.loops.TransformBlit;
import sun.java2d.pipe.Region;
import sun.java2d.pipe.RenderBuffer;
import sun.java2d.pipe.RenderQueue;
import static sun.java2d.pipe.BufferedOpCodes.*;
import sun.java2d.windows.GDIWindowSurfaceData;
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);
GraphicsPrimitive[] primitives = {
new D3DSurfaceToGDIWindowSurfaceBlit(),
new D3DSurfaceToGDIWindowSurfaceScale(),
new D3DSurfaceToGDIWindowSurfaceTransform(),
new D3DSurfaceToSurfaceBlit(),
new D3DSurfaceToSurfaceScale(),
new D3DSurfaceToSurfaceTransform(),
new D3DRTTSurfaceToSurfaceBlit(),
new D3DRTTSurfaceToSurfaceScale(),
new D3DRTTSurfaceToSurfaceTransform(),
new D3DSurfaceToSwBlit(SurfaceType.IntArgb,
D3DSurfaceData.ST_INT_ARGB),
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),
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),
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),
new D3DTextureToSurfaceBlit(),
new D3DTextureToSurfaceScale(),
new D3DTextureToSurfaceTransform(),
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),
new D3DGeneralBlit(D3DSurfaceData.D3DTexture,
CompositeType.SrcNoEa,
blitIntArgbPreToTexture),
};
GraphicsPrimitiveMgr.register(primitives);
}
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;
private static int createPackedParams(boolean isoblit, boolean texture,
boolean rtt, boolean xform,
int hint, int srctype)
{
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));
}
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)
{
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());
}
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 {
rq.addReference(srcData);
if (texture) {
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);
rq.flushNow();
} finally {
rq.unlock();
}
if (d3dDst.getType() == D3DSurfaceData.WINDOW) {
D3DScreenUpdateManager mgr =
(D3DScreenUpdateManager)ScreenUpdateManager.getInstance();
mgr.runUpdateNow();
}
}
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 {
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 );
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)) {
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)
{
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 D3DSurfaceToSurfaceScale extends ScaledBlit {
D3DSurfaceToSurfaceScale() {
super(D3DSurfaceData.D3DSurface,
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,
false);
}
}
class D3DSurfaceToSurfaceTransform extends TransformBlit {
D3DSurfaceToSurfaceTransform() {
super(D3DSurfaceData.D3DSurface,
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,
false);
}
}
class D3DRTTSurfaceToSurfaceBlit extends Blit {
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);
}
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 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;
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 {
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());
rq.flushNow();
} finally {
rq.unlock();
}
}
}
class D3DSwToSurfaceBlit extends Blit {
private int typeval;
D3DSwToSurfaceBlit(SurfaceType srcType, int typeval) {
super(srcType,
CompositeType.AnyAlpha,
D3DSurfaceData.D3DSurface);
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, 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);
}
}
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) {
cachedSrc = (SurfaceData)srcTmp.get();
}
src = convertFrom(convertsrc, src, sx, sy, w, h,
cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE);
performop.Blit(src, dst, comp, clip,
0, 0, dx, dy, w, h);
if (src != cachedSrc) {
srcTmp = new WeakReference(src);
}
}
}
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)
{
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)
{
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)
{
D3DVolatileSurfaceManager.handleVItoScreenOp(src, dst);
}
}