| /* |
| * 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 |