blob: 8075c41a5bf3105ee5ec8c121f0075c4cd8a756e [file] [log] [blame]
/*
* Copyright (c) 2007, 2008, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef D3DCONTEXT_H
#define D3DCONTEXT_H
#include "java_awt_Transparency.h"
#include "sun_java2d_pipe_BufferedContext.h"
#include "sun_java2d_d3d_D3DContext.h"
#include "sun_java2d_d3d_D3DContext_D3DContextCaps.h"
#include "sun_java2d_d3d_D3DSurfaceData.h"
#include "sun_java2d_pipe_hw_AccelDeviceEventNotifier.h"
#include "ShaderList.h"
#include "D3DPipeline.h"
#include "D3DMaskCache.h"
#include "D3DVertexCacher.h"
#include "D3DResourceManager.h"
#include "j2d_md.h"
typedef enum {
TILEFMT_UNKNOWN,
TILEFMT_1BYTE_ALPHA,
TILEFMT_3BYTE_RGB,
TILEFMT_3BYTE_BGR,
TILEFMT_4BYTE_ARGB_PRE,
} TileFormat;
typedef enum {
CLIP_NONE,
CLIP_RECT,
CLIP_SHAPE,
} ClipType;
// - 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.
*/
#define STATE_CHANGE (0 << 0)
#define STATE_RENDEROP (1 << 0)
#define STATE_MASKOP (1 << 1)
#define STATE_GLYPHOP (1 << 2)
#define STATE_TEXTUREOP (1 << 3)
#define STATE_AAPGRAMOP (1 << 4)
#define STATE_OTHEROP (1 << 5)
// The max. stage number we currently use (could not be
// larger than 7)
#define MAX_USED_TEXTURE_SAMPLER 1
// - 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
class D3DResource;
class D3DResourceManager;
class D3DMaskCache;
class D3DVertexCacher;
class D3DGlyphCache;
// - 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 IDirect3DDevice9 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 D3DPIPELINE_API D3DContext {
public:
/**
* 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.
*/
static
HRESULT CreateInstance(IDirect3D9 *pd3d9, UINT adapter, D3DContext **ppCtx);
// creates a new D3D windowed device with swap copy effect and default
// present interval
HRESULT InitContext();
// creates or resets a D3D device given the parameters
HRESULT ConfigureContext(D3DPRESENT_PARAMETERS *pNewParams);
// resets existing D3D device with the current presentation parameters
HRESULT ResetContext();
HRESULT CheckAndResetDevice();
// saves the state of the D3D device in a state block, resets
// context's state to STATE_CHANGE
HRESULT SaveState();
// restores the state of the D3D device from existing state block,
// resets context's state to STATE_CHANGE
HRESULT RestoreState();
void ReleaseContextResources();
void ReleaseDefPoolResources();
virtual ~D3DContext();
// methods replicating java-level D3DContext objext
HRESULT SetAlphaComposite(jint rule, jfloat extraAlpha, jint flags);
HRESULT ResetComposite();
/**
* Glyph cache-related methods
*/
HRESULT InitGrayscaleGlyphCache();
HRESULT InitLCDGlyphCache();
D3DGlyphCache* GetGrayscaleGlyphCache() { return pGrayscaleGlyphCache; }
D3DGlyphCache* GetLCDGlyphCache() { return pLCDGlyphCache; }
D3DResourceManager *GetResourceManager() { return pResourceMgr; }
D3DMaskCache *GetMaskCache() { return pMaskCache; }
HRESULT UploadTileToTexture(D3DResource *pTextureRes, void *pixels,
jint dstx, jint dsty,
jint srcx, jint srcy,
jint srcWidth, jint srcHeight,
jint srcStride,
TileFormat srcFormat,
// out: num of pixels in first and last
// columns, only counted for LCD glyph uploads
jint *pPixelsTouchedL = NULL,
jint *pPixelsTouchedR = NULL);
// returns capabilities of the Direct3D device
D3DCAPS9 *GetDeviceCaps() { return &devCaps; }
// returns caps in terms of the D3DContext
int GetContextCaps() { return contextCaps; }
D3DPRESENT_PARAMETERS *GetPresentationParams() { return &curParams; }
IDirect3DDevice9 *Get3DDevice() { return pd3dDevice; }
IDirect3D9 *Get3DObject() { return pd3dObject; }
/**
* This method only sets the texture if it's not already set.
*/
HRESULT SetTexture(IDirect3DTexture9 *pTexture, DWORD dwSampler = 0);
/**
* This method only updates the texture color state if it hasn't changed.
*/
HRESULT UpdateTextureColorState(DWORD dwState, DWORD dwSampler = 0);
HRESULT SetRenderTarget(IDirect3DSurface9 *pSurface);
HRESULT SetTransform(jdouble m00, jdouble m10,
jdouble m01, jdouble m11,
jdouble m02, jdouble m12);
HRESULT ResetTransform();
// clipping-related methods
HRESULT SetRectClip(int x1, int y1, int x2, int y2);
HRESULT BeginShapeClip();
HRESULT EndShapeClip();
HRESULT ResetClip();
ClipType GetClipType();
/**
* Shader-related methods
*/
HRESULT EnableBasicGradientProgram(jint flags);
HRESULT EnableLinearGradientProgram(jint flags);
HRESULT EnableRadialGradientProgram(jint flags);
HRESULT EnableConvolveProgram(jint flags);
HRESULT EnableRescaleProgram(jint flags);
HRESULT EnableLookupProgram(jint flags);
HRESULT EnableLCDTextProgram();
HRESULT EnableAAParallelogramProgram();
HRESULT DisableAAParallelogramProgram();
BOOL IsTextureFilteringSupported(D3DTEXTUREFILTERTYPE fType);
BOOL IsStretchRectFilteringSupported(D3DTEXTUREFILTERTYPE fType);
BOOL IsPow2TexturesOnly()
{ return devCaps.TextureCaps & D3DPTEXTURECAPS_POW2; };
BOOL IsSquareTexturesOnly()
{ return devCaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY; }
BOOL IsHWRasterizer() { return bIsHWRasterizer; }
BOOL IsTextureFormatSupported(D3DFORMAT format, DWORD usage = 0);
BOOL IsDynamicTextureSupported()
{ return devCaps.Caps2 & D3DCAPS2_DYNAMICTEXTURES; }
// REMIND: for now for performance testing
// { return (getenv("J2D_D3D_USE_DYNAMIC_TEX") != NULL); }
BOOL IsImmediateIntervalSupported()
{ return devCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE;}
BOOL IsPixelShader20Supported()
{ return (devCaps.PixelShaderVersion >= D3DPS_VERSION(2,0)); }
BOOL IsGradientInstructionExtensionSupported()
{ return devCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS; }
BOOL IsPixelShader30Supported()
{ return (devCaps.PixelShaderVersion >= D3DPS_VERSION(3,0)); }
BOOL IsMultiTexturingSupported()
{ return (devCaps.MaxSimultaneousTextures > 1); }
BOOL IsAlphaRTSurfaceSupported();
BOOL IsAlphaRTTSupported();
BOOL IsOpaqueRTTSupported();
jint GetPaintState() { return paintState; }
void SetPaintState(jint state) { this->paintState = state; }
BOOL IsIdentityTx() { return bIsIdentityTx; }
HRESULT FlushVertexQueue();
D3DVertexCacher *pVCacher;
HRESULT UpdateState(jbyte newState);
HRESULT Sync();
// primitives batching-related methods
/**
* Calls devices's BeginScene if there weren't one already pending,
* sets the pending flag.
*/
HRESULT BeginScene(jbyte newState);
/**
* Flushes the vertex queue and does end scene if
* a BeginScene is pending
*/
HRESULT EndScene();
/**
* Fields that track native-specific state.
*/
jint paintState;
jboolean useMask;
jfloat extraAlpha;
/**
* Current operation state.
* See STATE_* macros above.
*/
jbyte opState;
private:
/**
* Glyph cache-related methods/fields...
*/
D3DGlyphCache *pGrayscaleGlyphCache;
D3DGlyphCache *pLCDGlyphCache;
/**
* The handle to the LCD text pixel shader program.
*/
IDirect3DPixelShader9 *lcdTextProgram;
/**
* The handle to the AA pixel and vertex shader programs.
*/
IDirect3DPixelShader9 *aaPgramProgram;
IDirect3DPixelShader9 *CreateFragmentProgram(DWORD **shaders,
ShaderList *programs,
jint flags);
HRESULT EnableFragmentProgram(DWORD **shaders,
ShaderList *programList,
jint flags);
// finds appropriate to the target surface depth format,
// creates the depth buffer and installs it onto the device
HRESULT InitDepthStencilBuffer(D3DSURFACE_DESC *pTargetDesc);
// returns true if the current depth buffer is compatible
// with the new target, and the dimensions fit, false otherwise
BOOL IsDepthStencilBufferOk(D3DSURFACE_DESC *pTargetDesc);
D3DContext(IDirect3D9 *pd3dObject, UINT adapter);
HRESULT InitDevice(IDirect3DDevice9 *d3dDevice);
HRESULT InitContextCaps();
// updates the texture transform(s) used for better texel to pixel mapping
// for the passed in sampler;
// if -1 is passed as the sampler, texture transforms for
// samplers [0..MAX_USED_TEXTURE_SAMPLER] are updated
// REMIND: see the comment in the method implementation before enabling.
#undef UPDATE_TX
#ifdef UPDATE_TX
HRESULT UpdateTextureTransforms(DWORD dwSamplerToUpdate);
#endif // UPDATE_TX
IDirect3DDevice9 *pd3dDevice;
IDirect3D9 *pd3dObject;
D3DResourceManager *pResourceMgr;
D3DMaskCache *pMaskCache;
ShaderList convolvePrograms;
ShaderList rescalePrograms;
ShaderList lookupPrograms;
ShaderList basicGradPrograms;
ShaderList linearGradPrograms;
ShaderList radialGradPrograms;
// array of the textures currently set to the device
IDirect3DTexture9 *lastTexture[MAX_USED_TEXTURE_SAMPLER+1];
DWORD lastTextureColorState[MAX_USED_TEXTURE_SAMPLER+1];
UINT adapterOrdinal;
D3DPRESENT_PARAMETERS curParams;
D3DCAPS9 devCaps;
int contextCaps;
BOOL bIsHWRasterizer;
BOOL bIsIdentityTx;
IDirect3DQuery9* pSyncQuery;
D3DResource* pSyncRTRes;
IDirect3DStateBlock9* pStateBlock;
/**
* Used to implement simple primitive batching.
* See BeginScene/EndScene/ForceEndScene.
*/
BOOL bBeginScenePending;
};
// - Helper Macros ---------------------------------------------------
#define D3DC_INIT_SHADER_LIST(list, max) \
do { \
(list).head = NULL; \
(list).maxItems = (max); \
(list).dispose = D3DContext_DisposeShader; \
} while (0)
/**
* This constant determines the size of the shared tile texture used
* by a number of image rendering methods. For example, the blit tile texture
* will have dimensions with width D3DC_BLIT_TILE_SIZE and height
* D3DC_BLIT_TILE_SIZE (the tile will always be square).
*/
#define D3DC_BLIT_TILE_SIZE 256
/**
* See BufferedContext.java for more on these flags...
*/
#define D3DC_NO_CONTEXT_FLAGS \
sun_java2d_pipe_BufferedContext_NO_CONTEXT_FLAGS
#define D3DC_SRC_IS_OPAQUE \
sun_java2d_pipe_BufferedContext_SRC_IS_OPAQUE
#define D3DC_USE_MASK \
sun_java2d_pipe_BufferedContext_USE_MASK
#define CAPS_EMPTY \
sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_EMPTY
#define CAPS_RT_PLAIN_ALPHA \
sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_RT_PLAIN_ALPHA
#define CAPS_RT_TEXTURE_ALPHA \
sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_RT_TEXTURE_ALPHA
#define CAPS_RT_TEXTURE_OPAQUE \
sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_RT_TEXTURE_OPAQUE
#define CAPS_MULTITEXTURE \
sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_MULTITEXTURE
#define CAPS_TEXNONPOW2 \
sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_TEXNONPOW2
#define CAPS_TEXNONSQUARE \
sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_TEXNONSQUARE
#define CAPS_LCD_SHADER \
sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_LCD_SHADER
#define CAPS_BIOP_SHADER \
sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_BIOP_SHADER
#define CAPS_AA_SHADER \
sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_AA_SHADER
#define CAPS_DEVICE_OK \
sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_DEVICE_OK
#define CAPS_PS20 \
sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_PS20
#define CAPS_PS30 \
sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_PS30
#define DEVICE_RESET \
sun_java2d_pipe_hw_AccelDeviceEventNotifier_DEVICE_RESET
#define DEVICE_DISPOSED \
sun_java2d_pipe_hw_AccelDeviceEventNotifier_DEVICE_DISPOSED
#endif // D3DCONTEXT_H