jdk/src/windows/native/sun/java2d/d3d/D3DContext.h
changeset 2 90ce3da70b43
child 887 0aab8d3fa11a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/windows/native/sun/java2d/d3d/D3DContext.h	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,446 @@
+/*
+ * Copyright 2005-2006 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.
+ */
+
+#ifndef D3DCONTEXT_H
+#define D3DCONTEXT_H
+
+#include "java_awt_Transparency.h"
+#include "sun_java2d_d3d_D3DContext.h"
+#include "ddrawObject.h"
+extern "C" {
+#include "glyphblitting.h"
+#include "AccelGlyphCache.h"
+}
+#include "j2d_md.h"
+
+
+// - State switching optimizations -----------------------------------
+
+/**
+ * The goal is to reduce device state switching as much as possible.
+ * This means: don't reset the texture if not needed, don't change
+ * the texture stage states unless necessary.
+ * For this we need to track the current device state. So each operation
+ * supplies its own operation type to BeginScene, which updates the state
+ * as necessary.
+ *
+ * Another optimization is to use a single vertex format for
+ * all primitives.
+ *
+ * See D3DContext::UpdateState() and D3DContext::BeginScene() for
+ * more information.
+ */
+
+// The state is undefined, assume that complete initialization is
+// needed.
+#define STATE_UNDEFINED          (0 << 0)
+// Current state uses texture mapping
+#define STATE_TEXTURE            (1 << 0)
+// Texture stage state which is used when mask is involved
+// (text rendering, maskfill)
+#define STATE_TEXTURE_STAGE_MASK (1 << 1)
+// Texture stage state which is used when doing texture
+// mapping in blits
+#define STATE_TEXTURE_STAGE_BLIT (1 << 2)
+// Texture stage state which is used when not doing
+// texture mapping, only use diffuse color
+#define STATE_TEXTURE_STAGE_POLY (1 << 3)
+// Texture mapping operation which involves mask texture
+#define STATE_MASKOP             (STATE_TEXTURE|STATE_TEXTURE_STAGE_MASK)
+// Texture mapping operation which involves image texture
+#define STATE_BLITOP             (STATE_TEXTURE|STATE_TEXTURE_STAGE_BLIT)
+// Rendering operation which doesn't use texture mapping
+#define STATE_RENDEROP           (STATE_TEXTURE_STAGE_POLY)
+
+// The max. stage number we currently use (could not be
+// larger than 7)
+#define MAX_USED_TEXTURE_STAGE 0
+
+// - Texture pixel format table  -------------------------------------
+#define TR_OPAQUE      java_awt_Transparency_OPAQUE
+#define TR_BITMASK     java_awt_Transparency_BITMASK
+#define TR_TRANSLUCENT java_awt_Transparency_TRANSLUCENT
+
+// depth indices for the D3DTextureTable type
+#define DEPTH16_IDX 0
+#define DEPTH24_IDX 1
+#define DEPTH32_IDX 2
+#define DEPTH_MAX_IDX 3
+
+// corresponding transparency indices for the D3DTextureTable type
+#define TR_OPAQUE_IDX 0
+#define TR_BITMASK_IDX 1
+#define TR_TRANSLUCENT_IDX 2
+#define TR_MAX_IDX 3
+
+typedef struct
+{
+    DDPIXELFORMAT pddpf;
+    jint  pfType;
+} D3DTextureTableCell;
+
+// texture table:
+// [transparency={OPAQUE,BITMASK,TRANCLUCENT},depth={16,24,32}]
+typedef D3DTextureTableCell D3DTextureTable[TR_MAX_IDX][DEPTH_MAX_IDX];
+
+// - D3DContext class  -----------------------------------------------
+
+/**
+ * This class provides the following functionality:
+ *  - holds the state of D3DContext java class (current pixel color,
+ *    alpha compositing mode, extra alpha)
+ *  - provides access to IDirect3DDevice7 interface (creation,
+ *    disposal, exclusive access)
+ *  - handles state changes of the direct3d device (transform,
+ *    compositing mode, current texture)
+ *  - provides means of creating textures, plain surfaces
+ *  - holds a glyph cache texture for the associated device
+ *  - implements primitives batching mechanism
+ */
+class D3DContext {
+public:
+    /**
+     * Creates and returns D3DContext instance. If created context was
+     * unable to initialize d3d device or if the device tests failed,
+     * returns NULL.
+     */
+    static D3DContext* CreateD3DContext(DDraw *ddObject, DXObject* dxObject);
+    /**
+     * Releases the old device (if there was one) and all associated
+     * resources, re-creates, initializes and tests the new device.
+     *
+     * If the device doesn't pass the test, it's released.
+     *
+     * Used when the context is first created, and then after a
+     * display change event.
+     *
+     * Note that this method also does the necessary registry checks,
+     * and if the registry shows that we've crashed when attempting
+     * to initialize and test the device last time, it doesn't attempt
+     * to create/init/test the device.
+     */
+    void    CreateD3DDevice();
+    void    Release3DDevice();
+    virtual ~D3DContext();
+
+    /**
+     * Stores a weak reference of passed D3DContext object.
+     * This method is called from _getNativeDeviceCaps method, and does the
+     * association of the native D3DContext with the corresponding java object.
+     * We need a reference to the java object so it can be notified when
+     * the native context is released or recreated.
+     *
+     * See jobject jD3DContext field
+     */
+    void SetJavaContext(JNIEnv *env, jobject jd3dc);
+
+    /**
+     * Methods to get/release exclusive access to the direct3d device
+     * interface. Note that some methods of this class assume that the
+     * lock is already taken. They're marked with 'NOLOCK' comment.
+     * Those methods not dealing with the d3d device interface are not
+     * required to obtain the lock (and not marked with NOLOCK)
+     */
+    void GetExclusiveAccess() { CRITICAL_SECTION_ENTER(deviceLock);}
+    void ReleaseExclusiveAccess() { CRITICAL_SECTION_LEAVE(deviceLock);}
+
+    // methods replicating java-level D3DContext objext
+    void SetColor(jint eargb, jint flags);
+    void SetAlphaComposite(jint rule, jfloat extraAlpha, jint flags);
+    void ResetComposite();
+
+    // Glyph cache-related methods
+    HRESULT /*NOLOCK*/ InitGlyphCache();
+    HRESULT /*NOLOCK*/ GlyphCacheAdd(JNIEnv *env, GlyphInfo *glyph);
+    HRESULT /*NOLOCK*/ UploadImageToTexture(DXSurface *texture, jubyte *pixels,
+                                            jint dstx, jint dsty,
+                                            jint srcx, jint srcy,
+                                            jint srcWidth, jint srcHeight,
+                                            jint srcStride);
+    DXSurface /*NOLOCK*/ *GetGlyphCacheTexture() { return lpGlyphCacheTexture; }
+    DXSurface /*NOLOCK*/ *GetMaskTexture();
+    GlyphCacheInfo *GetGlyphCache() { return glyphCache; }
+
+    HRESULT CreateSurface(JNIEnv *env,
+                          jint width, jint height, jint depth,
+                          jint transparency, jint d3dSurfaceType,
+                          DXSurface** dxSurface, jint* pType);
+
+    /**
+     * Attaches a depth buffer to the specified dxSurface.
+     * If depthBufferFormat is not initialized (depthBufferFormat.dwSize == 0),
+     * it will be initialized at the time of the call.
+     *
+     * If the buffer for this surface already exists, a "lost" status of the
+     * depth buffer is returned.
+     */
+    HRESULT AttachDepthBuffer(DXSurface *dxSurface);
+
+    // methods for dealing with device capabilities as determined by
+    // methods in D3DRuntimeTest
+    int GetDeviceCaps() { return deviceCaps; }
+    void SetDeviceCaps(int caps) { deviceCaps = caps; }
+
+    // Returns the texture pixel format table
+    D3DTextureTable &GetTextureTable() { return textureTable; }
+
+    DDrawSurface *GetTargetSurface() { return ddTargetSurface; }
+    IDirect3DDevice7 *Get3DDevice() { return d3dDevice; }
+
+    // IDirect3DDevice7-delegation methods
+
+    /**
+     * This method only sets the texture if it's not already set.
+     */
+    HRESULT /*NOLOCK*/ SetTexture(DXSurface *dxSurface, DWORD dwStage = 0);
+    HRESULT SetRenderTarget(DDrawSurface *lpSurface);
+    HRESULT SetTransform(jobject xform,
+                         jdouble m00, jdouble m10,
+                         jdouble m01, jdouble m11,
+                         jdouble m02, jdouble m12);
+    HRESULT SetClip(JNIEnv *env, jobject clip,
+                    jboolean isRect,
+                    int x1, int y1, int x2, int y2);
+
+    DWORD GetMinTextureWidth() { return d3dDevDesc.dwMinTextureWidth; }
+    DWORD GetMinTextureHeight() { return d3dDevDesc.dwMinTextureHeight; }
+    DWORD GetMaxTextureWidth() { return d3dDevDesc.dwMaxTextureWidth; }
+    DWORD GetMaxTextureHeight() { return d3dDevDesc.dwMaxTextureHeight; }
+    DWORD GetMaxTextureAspectRatio()
+        { return d3dDevDesc.dwMaxTextureAspectRatio; };
+    BOOL IsPow2TexturesOnly()
+        { return d3dDevDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2; };
+    BOOL IsSquareTexturesOnly()
+        { return d3dDevDesc.dpcTriCaps.dwTextureCaps &
+              D3DPTEXTURECAPS_SQUAREONLY; }
+
+    /**
+     * This method invalidates the java-level D3DContext object if
+     * the passed DDrawSurface is the current render target.
+     * The invalidation needs to be done so that the D3DContext object
+     * resets itself in case the native d3d device has been recreated, or
+     * the target surface has been lost (in which case this method is called
+     * from D3DSD_RestoreSurface function, see D3DSD_RestoreSurface for
+     * more info).
+     */
+    void InvalidateIfTarget(JNIEnv *env, DDrawSurface *lpSurface);
+
+    // primitives batching-related methods
+    /**
+     * Calls devices's BeginScene if there weren't one already pending,
+     * sets the pending flag.
+     */
+    HRESULT /*NOLOCK*/ BeginScene(jbyte newState);
+    /**
+     * Only calls device's EndScene if ddResult is an error.
+     */
+    HRESULT /*NOLOCK*/ EndScene(HRESULT ddResult);
+    /**
+     * forces the end of batching by calling EndScene if
+     * there was BeginScene pending.
+     */
+    HRESULT /*NOLOCK*/ ForceEndScene();
+    /**
+     * flushes the queue if the argument is this device's render target
+     */
+    void    FlushD3DQueueForTarget(DDrawSurface *ddSurface);
+
+    // fields replicating D3DContext class' fields
+    jint       compState;
+    jfloat     extraAlpha;
+    jint       colorPixel;
+
+    // pixel for vertices used in blits via texture mapping,
+    // set in SetAlphaComposite()
+    jint       blitPolygonPixel;
+
+    /**
+     * Current operation state.
+     * See STATE_* macros above.
+     */
+    jbyte      opState;
+
+private:
+    D3DContext(DDraw *ddObject, DXObject* dxObject);
+    HRESULT InitD3DDevice(IDirect3DDevice7 *d3dDevice);
+    /**
+     * This method releases an old device, creates a new one,
+     * runs d3d caps tests on it and sets the device caps according
+     * to the results.
+     */
+    HRESULT /*NOLOCK*/ CreateAndTestD3DDevice(DxCapabilities *dxCaps);
+    HRESULT /*NOLOCK*/ InitMaskTileTexture();
+    void    /*NOLOCK*/ UpdateState(jbyte newState);
+
+    IDirect3DDevice7        *d3dDevice;
+    IDirect3D7              *d3dObject;
+    DDraw                   *ddObject;
+    DXObject                *dxObject;
+    const GUID              *pDeviceGUID;
+    DDrawSurface            *ddTargetSurface;
+    DXSurface               *lpMaskTexture;
+    DXSurface               *lpGlyphCacheTexture;
+    D3DTextureTable         textureTable;
+    DDPIXELFORMAT           depthBufferFormat;
+    DDPIXELFORMAT           maskTileTexFormat;
+    GlyphCacheInfo          *glyphCache;
+    BOOL                    glyphCacheAvailable;
+    // array of the textures currently set to the device
+    IDirectDrawSurface7     *lastTexture[MAX_USED_TEXTURE_STAGE+1];
+
+    /**
+     * A weak reference to the java-level D3DContext object.
+     * Used to invalidate the java D3DContext object if the device has been
+     * recreated.
+     * See SetJavaContext() method.
+     */
+    jobject jD3DContext;
+
+    D3DDEVICEDESC7 d3dDevDesc;
+    int deviceCaps;
+    BOOL bIsHWRasterizer;
+
+    /**
+     * Used to implement simple primitive batching.
+     * See BeginScene/EndScene/ForceEndScene.
+     */
+    BOOL    bBeginScenePending;
+#ifdef DEBUG
+    int endSceneQueueDepth;
+#endif /* DEBUG */
+
+    CriticalSection deviceLock;
+};
+
+// - Various vertex formats -------------------------------------------
+
+#define D3DFVF_J2DLVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
+typedef struct _J2DLVERTEX {
+    float x, y, z;
+    DWORD color;
+    float tu, tv;
+} J2DLVERTEX;
+
+/**
+ * We're still debating whether to use a single vertex format
+ * for all primitives or specific per-primitive formats.
+ * Using different vertex formats reduces the amount of
+ * data being sent to the video board, and this shows
+ * benetits when running Java2D benchmarks.
+ *
+ * However, in a typical Swing application the number
+ * of primitives of the same type rendered in a row is
+ * relatively small, which means that the driver has
+ * to spend more time state switching to account for different
+ * vertex formats (and according to MSDN, switching vertex format
+ * is a very expensive operation). So for this kind of application
+ * it's better to stick with a single vertex format.
+ */
+#define USE_SINGLE_VERTEX_FORMAT
+
+#ifndef USE_SINGLE_VERTEX_FORMAT
+
+#define D3DFVF_J2D_XY_C (D3DFVF_XYZ | D3DFVF_DIFFUSE)
+#define D3DFVF_XY_VERTEX D3DFVF_XYZ
+
+typedef struct _J2D_XY_C_VERTEX {
+    float x, y, z;
+    DWORD color;
+} J2D_XY_C_VERTEX;
+typedef struct _J2D_XY_VERTEX {
+    float x, y, z;
+} J2D_XY_VERTEX;
+
+#else // USE_SINGLE_VERTEX_FORMAT
+
+// When using a single vertex format, define
+// every format as J2DLVERTEX
+
+#define D3DFVF_J2D_XY_C D3DFVF_J2DLVERTEX
+#define D3DFVF_XY_VERTEX D3DFVF_J2DLVERTEX
+typedef J2DLVERTEX J2D_XY_C_VERTEX;
+typedef J2DLVERTEX J2D_XY_VERTEX;
+
+#endif // USE_SINGLE_VERTEX_FORMAT
+
+typedef J2DLVERTEX      J2DLV_QUAD[4];
+typedef J2DLVERTEX      J2DLV_HEXA[6];
+typedef J2D_XY_C_VERTEX J2DXYC_HEXA[6];
+typedef J2D_XY_VERTEX   J2DXY_HEXA[6];
+#define MAX_CACHED_SPAN_VX_NUM 100
+
+// - Helper Macros ---------------------------------------------------
+
+#define D3D_DEPTH_IDX(DEPTH) \
+  (((DEPTH) <= 16) ? DEPTH16_IDX : \
+    (((DEPTH) <= 24) ? DEPTH24_IDX : DEPTH32_IDX))
+
+#define D3D_TR_IDX(TRAN) ((TRAN) - 1)
+
+#define D3DSD_MASK_TILE_SIZE 32
+#define D3D_GCACHE_WIDTH 512
+#define D3D_GCACHE_HEIGHT 512
+#define D3D_GCACHE_CELL_WIDTH 16
+#define D3D_GCACHE_CELL_HEIGHT 16
+
+#define D3DC_NO_CONTEXT_FLAGS \
+    sun_java2d_d3d_D3DContext_NO_CONTEXT_FLAGS
+#define D3DC_SRC_IS_OPAQUE    \
+    sun_java2d_d3d_D3DContext_SRC_IS_OPAQUE
+
+#define J2D_D3D_FAILURE \
+    sun_java2d_d3d_D3DContext_J2D_D3D_FAILURE
+#define J2D_D3D_PLAIN_SURFACE_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_PLAIN_SURFACE_OK
+#define J2D_D3D_OP_TEXTURE_SURFACE_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_OP_TEXTURE_SURFACE_OK
+#define J2D_D3D_BM_TEXTURE_SURFACE_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_BM_TEXTURE_SURFACE_OK
+#define J2D_D3D_TR_TEXTURE_SURFACE_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_TR_TEXTURE_SURFACE_OK
+#define J2D_D3D_DEPTH_SURFACE_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_DEPTH_SURFACE_OK
+#define J2D_D3D_OP_RTT_SURFACE_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_OP_RTT_SURFACE_OK
+#define J2D_D3D_LINES_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_LINES_OK
+#define J2D_D3D_TEXTURE_BLIT_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_TEXTURE_BLIT_OK
+#define J2D_D3D_TEXTURE_TRANSFORM_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_TEXTURE_TRANSFORM_OK
+#define J2D_D3D_LINE_CLIPPING_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_LINE_CLIPPING_OK
+#define J2D_D3D_DEVICE_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_DEVICE_OK
+#define J2D_D3D_PIXEL_FORMATS_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_PIXEL_FORMATS_OK
+#define J2D_D3D_SET_TRANSFORM_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_SET_TRANSFORM_OK
+#define J2D_D3D_HW_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_HW_OK
+#define J2D_D3D_ENABLED_OK \
+    sun_java2d_d3d_D3DContext_J2D_D3D_ENABLED_OK
+
+#endif D3DCONTEXT_H