--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,457 @@
+/*
+ * Copyright 2005-2007 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.d3d;
+
+import java.awt.AlphaComposite;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Transparency;
+import java.awt.image.ColorModel;
+import java.awt.image.DirectColorModel;
+import sun.awt.SunHints;
+import sun.awt.Win32GraphicsConfig;
+import sun.awt.Win32GraphicsDevice;
+import sun.awt.image.SurfaceManager;
+import sun.java2d.InvalidPipeException;
+import sun.java2d.SunGraphics2D;
+import sun.java2d.SurfaceData;
+import sun.java2d.SurfaceDataProxy;
+import sun.java2d.loops.GraphicsPrimitive;
+import sun.java2d.loops.SurfaceType;
+import sun.java2d.pipe.PixelToShapeConverter;
+import sun.java2d.pipe.TextPipe;
+import sun.java2d.windows.Win32OffScreenSurfaceData;
+import sun.java2d.windows.Win32SurfaceData;
+import sun.java2d.windows.WinVolatileSurfaceManager;
+import sun.java2d.windows.WindowsFlags;
+
+import static sun.java2d.windows.Win32SurfaceData.*;
+
+public class D3DSurfaceData extends Win32OffScreenSurfaceData {
+
+ // properties of a surface
+ /**
+ * This property is used for a back-buffer surface
+ */
+ public static final int D3D_ATTACHED_SURFACE = (1 << 15);
+ /**
+ * A surface with this property can be used as a Direct3D rendering
+ * destination.
+ */
+ public static final int D3D_RENDER_TARGET = (1 << 16);
+
+ public static final int
+ D3D_INVALID_SURFACE = 0;
+ /**
+ * Surface is a Direct3D plain surface (not a texture).
+ * Plain surface can be used as render target.
+ * VolatileImages typically use plain surfaces as their hardware
+ * accelerated surfaces.
+ */
+ public static final int
+ D3D_PLAIN_SURFACE = (1 << 0) | D3D_RENDER_TARGET;
+ /**
+ * Direct3D texture. Mostly used for cached accelerated surfaces.
+ * Surfaces of this type can be copied from using hardware acceleration
+ * by using texture mapping.
+ */
+ public static final int
+ D3D_TEXTURE_SURFACE = (1 << 1);
+ /**
+ * Direct3D Backbuffer surface - an attached surface. Used for
+ * multibuffered BufferStrategies.
+ */
+ public static final int
+ D3D_BACKBUFFER_SURFACE = D3D_PLAIN_SURFACE | D3D_ATTACHED_SURFACE;
+ /**
+ * Render-to-texture. A texture which can also be a render target.
+ * Combines the benefits of textures (fast copies-from) and
+ * backbuffers or plain surfaces (hw-accelerated rendering to the surface)
+ */
+ public static final int
+ D3D_RTT_SURFACE = D3D_TEXTURE_SURFACE | D3D_RENDER_TARGET;
+
+ // supported texture pixel formats
+ public static final int PF_INVALID = 0;
+ public static final int PF_INT_ARGB = 1;
+ public static final int PF_INT_RGB = 2;
+ public static final int PF_INT_RGBX = 3;
+ public static final int PF_INT_BGR = 4;
+ public static final int PF_USHORT_565_RGB = 5;
+ public static final int PF_USHORT_555_RGB = 6;
+ public static final int PF_USHORT_555_RGBX = 7;
+ public static final int PF_INT_ARGB_PRE = 8;
+ public static final int PF_USHORT_4444_ARGB= 9;
+
+ public static final String
+ DESC_INT_ARGB_D3D = "Integer ARGB D3D with translucency";
+ public static final String
+ DESC_USHORT_4444_ARGB_D3D = "UShort 4444 ARGB D3D with translucency";
+
+ /**
+ * Surface type for texture destination. We cannot render textures to
+ * the screen because Direct3D is not clipped by the window's clip list,
+ * so we only enable the texture blit loops for copies to offscreen
+ * accelerated surfaces.
+ */
+ public static final String
+ DESC_DEST_D3D = "D3D render target";
+
+ public static final SurfaceType D3DSurface =
+ SurfaceType.Any.deriveSubType("Direct3D Surface");
+ public static final SurfaceType D3DTexture =
+ D3DSurface.deriveSubType("Direct3D Texture");
+
+ /**
+ * D3D destination surface types (derive from offscreen dd surfaces).
+ * Note that all of these surfaces have the same surface description;
+ * we do not care about the depth of the surface since texture ops
+ * support multiple depths.
+ */
+ public static final SurfaceType IntRgbD3D =
+ IntRgbDD.deriveSubType(DESC_DEST_D3D);
+
+ public static final SurfaceType IntRgbxD3D =
+ IntRgbxDD.deriveSubType(DESC_DEST_D3D);
+
+ public static final SurfaceType Ushort565RgbD3D =
+ Ushort565RgbDD.deriveSubType(DESC_DEST_D3D);
+
+ public static final SurfaceType Ushort555RgbxD3D =
+ Ushort555RgbxDD.deriveSubType(DESC_DEST_D3D);
+
+ public static final SurfaceType Ushort555RgbD3D =
+ Ushort555RgbDD.deriveSubType(DESC_DEST_D3D);
+
+ // REMIND: Is it possible to have d3d accelerated on this type of surface?
+ public static final SurfaceType ThreeByteBgrD3D =
+ ThreeByteBgrDD.deriveSubType(DESC_DEST_D3D);
+
+ public static final SurfaceType IntArgbD3D =
+ SurfaceType.IntArgb.deriveSubType(DESC_INT_ARGB_D3D);
+
+ public static final SurfaceType Ushort4444ArgbD3D =
+ SurfaceType.Ushort4444Argb.deriveSubType(DESC_USHORT_4444_ARGB_D3D);
+
+ // Textures we can render to using d3d
+ public static final SurfaceType IntRgbD3D_RTT =
+ IntRgbD3D.deriveSubType(DESC_DEST_D3D);
+
+ public static final SurfaceType IntRgbxD3D_RTT =
+ IntRgbxD3D.deriveSubType(DESC_DEST_D3D);
+
+ public static final SurfaceType Ushort565RgbD3D_RTT =
+ Ushort565RgbD3D.deriveSubType(DESC_DEST_D3D);
+
+ public static final SurfaceType Ushort555RgbxD3D_RTT =
+ Ushort555RgbxD3D.deriveSubType(DESC_DEST_D3D);
+
+ public static final SurfaceType Ushort555RgbD3D_RTT =
+ Ushort555RgbD3D.deriveSubType(DESC_DEST_D3D);
+
+ public static final SurfaceType Ushort4444ArgbD3D_RTT =
+ Ushort4444ArgbD3D.deriveSubType(DESC_DEST_D3D);
+
+ public static final SurfaceType IntArgbD3D_RTT =
+ IntArgbD3D.deriveSubType(DESC_DEST_D3D);
+
+ public static final SurfaceType ThreeByteBgrD3D_RTT =
+ ThreeByteBgrD3D.deriveSubType(DESC_DEST_D3D);
+
+ // the type of this surface - texture, plain, back-buffer
+ protected int type;
+ protected int pixelFormat;
+
+ private D3DContext d3dContext;
+
+ protected static D3DRenderer d3dPipe;
+ protected static PixelToShapeConverter d3dTxPipe;
+ protected static D3DTextRenderer d3dTextPipe;
+ protected static D3DDrawImage d3dDrawImagePipe;
+
+ private native void initOps(int depth, int transparency);
+
+ static {
+ if (WindowsFlags.isD3DEnabled()) {
+ D3DBlitLoops.register();
+ D3DMaskFill.register();
+ }
+
+ d3dPipe = new D3DRenderer();
+ d3dTxPipe = new PixelToShapeConverter(d3dPipe);
+ d3dTextPipe = new D3DTextRenderer();
+ d3dDrawImagePipe = new D3DDrawImage();
+
+ if (GraphicsPrimitive.tracingEnabled()) {
+ d3dPipe = d3dPipe.traceWrapD3D();
+ d3dTextPipe = d3dTextPipe.traceWrap();
+ }
+ }
+
+ @Override
+ public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
+ //D3D may be eliminated soon so no Proxy was created for it...
+ //return D3DSurfaceDataProxy.createProxy(srcData, graphicsConfig);
+ return SurfaceDataProxy.UNCACHED;
+ }
+
+ /**
+ * Non-public constructor. Use createData() to create an object.
+ *
+ * This constructor is used to house the common construction
+ * code shared between the creation of D3DSurfaceData objects
+ * and subclasses of D3DSurfaceData (such as D3DBackBufferSD).
+ *
+ * It calls the common constructor in the parent, and then
+ * initializes other shared D3D data.
+ */
+ protected D3DSurfaceData(int width, int height,
+ int d3dSurfaceType,
+ SurfaceType sType, ColorModel cm,
+ GraphicsConfiguration gc,
+ Image image, int transparency)
+ {
+ super(width, height, sType, cm, gc, image, transparency);
+ this.type = d3dSurfaceType;
+ }
+
+ /**
+ * Private constructor. Use createData() to create an object.
+ *
+ * This constructor calls the common constructor above and then
+ * performs the specific initialization of the D3DSurface.
+ */
+ private D3DSurfaceData(int width, int height,
+ int d3dSurfaceType,
+ SurfaceType sType, ColorModel cm,
+ GraphicsConfiguration gc,
+ Image image, int transparency,
+ int screen)
+ {
+ this(width, height, d3dSurfaceType, sType, cm, gc, image, transparency);
+ pixelFormat = initSurface(width, height, screen,
+ null /*parent SurfaceData*/);
+ }
+
+ public static D3DSurfaceData createData(int width, int height,
+ int d3dSurfaceType,
+ ColorModel cm,
+ GraphicsConfiguration gc,
+ Image image)
+ {
+ Win32GraphicsDevice gd = (Win32GraphicsDevice)gc.getDevice();
+ // After a display change ddInstance may not be
+ // recreated yet, and in this case isD3DEnabledOnDevice will
+ // return false, until someone attempted to recreate the
+ // primary.
+ if (!gd.isD3DEnabledOnDevice()) {
+ return null;
+ }
+
+ return new D3DSurfaceData(width, height,
+ d3dSurfaceType,
+ getSurfaceType(gc, cm, d3dSurfaceType),
+ cm, gc, image,
+ cm.getTransparency(), gd.getScreen());
+ }
+
+ int getPixelFormat() {
+ return pixelFormat;
+ }
+
+ static SurfaceType getSurfaceType(GraphicsConfiguration gc,
+ ColorModel cm,
+ int d3dSurfaceType)
+ {
+ if (d3dSurfaceType == D3D_TEXTURE_SURFACE) {
+ // for non-rtt textures we have only one surface type
+ return D3DTexture;
+ } else {
+ int pixelSize = cm.getPixelSize();
+ Win32GraphicsDevice gd = (Win32GraphicsDevice)gc.getDevice();
+ int transparency = cm.getTransparency();
+
+ // We'll attempt to use render-to-texture if render target is
+ // requested, but it's not a back-buffer and we support RTT
+ // for this configuration.
+ boolean useRTT =
+ ((d3dSurfaceType & D3D_RENDER_TARGET) != 0) &&
+ ((d3dSurfaceType & D3D_BACKBUFFER_SURFACE) == 0) &&
+ gd.getD3DContext().isRTTSupported();
+
+ // if there's no RTT available, we can't accelerate non-opaque
+ // surfaces, so we return null.
+ if (transparency == Transparency.TRANSLUCENT ||
+ transparency == Transparency.BITMASK)
+ {
+ if (pixelSize == 16) {
+ return useRTT ? Ushort4444ArgbD3D_RTT :
+ null/*Ushort4444ArgbD3D*/;
+ } else {
+ return useRTT ? IntArgbD3D_RTT : null/*IntArgbD3D*/;
+ }
+ } else {
+ // it's an opaque surface, either a VI or a back-buffer
+ switch (pixelSize) {
+ case 32:
+ case 24:
+ if (cm instanceof DirectColorModel) {
+ if (((DirectColorModel)cm).getRedMask() == 0xff0000) {
+ return useRTT ? IntRgbD3D_RTT : IntRgbD3D;
+ } else {
+ return useRTT ? IntRgbxD3D_RTT : IntRgbxD3D;
+ }
+ } else {
+ return useRTT ? ThreeByteBgrD3D_RTT : ThreeByteBgrD3D;
+ }
+ case 15:
+ return useRTT ? Ushort555RgbD3D_RTT : Ushort555RgbD3D;
+ case 16:
+ if ((cm instanceof DirectColorModel) &&
+ (((DirectColorModel)cm).getBlueMask() == 0x3e))
+ {
+ return useRTT ? Ushort555RgbxD3D_RTT : Ushort555RgbxD3D;
+ } else {
+ return useRTT ? Ushort565RgbD3D_RTT : Ushort565RgbD3D;
+ }
+ case 8: // not supported
+ default:
+ throw new sun.java2d.InvalidPipeException("Unsupported bit " +
+ "depth: " +
+ cm.getPixelSize());
+ }
+ }
+ }
+ }
+
+ private native int initOffScreenSurface(long pCtx,
+ long pData, long parentPdata,
+ int width, int height,
+ int type, int screen);
+
+ protected int initSurface(int width, int height, int screen,
+ Win32SurfaceData parentData)
+ {
+ int pFormat = PF_INVALID;
+
+ synchronized (D3DContext.LOCK) {
+ long pData = getNativeOps();
+ long pDataParent = 0L;
+ if (parentData != null) {
+ pDataParent = parentData.getNativeOps();
+ }
+ D3DContext d3dContext = getContext();
+ long pCtx = d3dContext.getNativeContext();
+ // native context could be 0 if the context is currently invalid,
+ // so attempt to revalidate
+ if (pCtx == 0) {
+ d3dContext.reinitNativeContext();
+ pCtx = d3dContext.getNativeContext();
+ }
+ if (pData != 0 && pCtx != 0) {
+ pFormat = initOffScreenSurface(pCtx,
+ pData, pDataParent,
+ width, height, type, screen);
+ } else {
+ // if the context can't be restored, give up for now.
+ throw new InvalidPipeException("D3DSD.initSurface: pData " +
+ "or pCtx is null");
+ }
+ }
+ return pFormat;
+ }
+
+ @Override
+ public void validatePipe(SunGraphics2D sg2d) {
+ // we don't support COMP_XOR yet..
+ if (sg2d.compositeState < sg2d.COMP_XOR) {
+ TextPipe textpipe;
+ boolean validated = false;
+
+ if (((sg2d.compositeState <= sg2d.COMP_ISCOPY &&
+ sg2d.paintState <= sg2d.PAINT_ALPHACOLOR) ||
+ (sg2d.compositeState == sg2d.COMP_ALPHA &&
+ sg2d.paintState <= sg2d.PAINT_ALPHACOLOR &&
+ (((AlphaComposite)sg2d.composite).getRule() ==
+ AlphaComposite.SRC_OVER))) &&
+ sg2d.textAntialiasHint <= SunHints.INTVAL_TEXT_ANTIALIAS_GASP)
+ {
+ // D3DTextRenderer handles both AA and non-AA text, but
+ // only works if composite is SrcNoEa or SrcOver
+ textpipe = d3dTextPipe;
+ } else {
+ // do this to initialize textpipe correctly; we will attempt
+ // to override the non-text pipes below
+ super.validatePipe(sg2d);
+ textpipe = sg2d.textpipe;
+ validated = true;
+ }
+
+ if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON &&
+ sg2d.paintState <= sg2d.PAINT_ALPHACOLOR)
+ {
+ sg2d.drawpipe =
+ sg2d.strokeState == sg2d.STROKE_THIN ? d3dPipe : d3dTxPipe;
+ sg2d.fillpipe = d3dPipe;
+ sg2d.shapepipe = d3dPipe;
+ } else if (!validated) {
+ super.validatePipe(sg2d);
+ }
+ // install the text pipe based on our earlier decision
+ sg2d.textpipe = textpipe;
+ } else {
+ super.validatePipe(sg2d);
+ }
+
+ // always override the image pipe with the specialized D3D pipe
+ sg2d.imagepipe = d3dDrawImagePipe;
+ }
+
+ /**
+ * Disables D3D acceleration on the surface manager of this surfaceData
+ * object. This can happen when we encounter a hard error in rendering a D3D
+ * primitive (for example, if we were unable to set a surface as D3D target
+ * surface).
+ * Upon next validation the SurfaceManager will create a non-D3D surface.
+ */
+ public void disableD3D() {
+ markSurfaceLost();
+ SurfaceManager sMgr = SurfaceManager.getManager(image);
+ if (sMgr instanceof WinVolatileSurfaceManager) {
+ ((WinVolatileSurfaceManager)sMgr).setD3DAccelerationEnabled(false);
+ }
+ }
+
+ @Override
+ public boolean surfacePunted() {
+ // Punting is disabled for D3D surfaces
+ return false;
+ }
+
+ D3DContext getContext() {
+ return ((Win32GraphicsDevice)graphicsConfig.getDevice()).getD3DContext();
+ }
+}