1 /*
   2  * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #ifndef D3DCONTEXT_H
  27 #define D3DCONTEXT_H
  28 
  29 #include "java_awt_Transparency.h"
  30 #include "sun_java2d_pipe_BufferedContext.h"
  31 #include "sun_java2d_d3d_D3DContext_D3DContextCaps.h"
  32 #include "sun_java2d_d3d_D3DSurfaceData.h"
  33 #include "sun_java2d_pipe_hw_AccelDeviceEventNotifier.h"
  34 
  35 #include "ShaderList.h"
  36 #include "D3DPipeline.h"
  37 #include "D3DMaskCache.h"
  38 #include "D3DVertexCacher.h"
  39 #include "D3DResourceManager.h"
  40 
  41 #include "j2d_md.h"
  42 
  43 typedef enum {
  44     TILEFMT_UNKNOWN,
  45     TILEFMT_1BYTE_ALPHA,
  46     TILEFMT_3BYTE_RGB,
  47     TILEFMT_3BYTE_BGR,
  48     TILEFMT_4BYTE_ARGB_PRE,
  49 } TileFormat;
  50 
  51 typedef enum {
  52     CLIP_NONE,
  53     CLIP_RECT,
  54     CLIP_SHAPE,
  55 } ClipType;
  56 
  57 // - State switching optimizations -----------------------------------
  58 
  59 /**
  60  * The goal is to reduce device state switching as much as possible.
  61  * This means: don't reset the texture if not needed, don't change
  62  * the texture stage states unless necessary.
  63  * For this we need to track the current device state. So each operation
  64  * supplies its own operation type to BeginScene, which updates the state
  65  * as necessary.
  66  *
  67  * Another optimization is to use a single vertex format for
  68  * all primitives.
  69  *
  70  * See D3DContext::UpdateState() and D3DContext::BeginScene() for
  71  * more information.
  72  */
  73 #define STATE_CHANGE    (0 << 0)
  74 #define STATE_RENDEROP  (1 << 0)
  75 #define STATE_MASKOP    (1 << 1)
  76 #define STATE_GLYPHOP   (1 << 2)
  77 #define STATE_TEXTUREOP (1 << 3)
  78 #define STATE_AAPGRAMOP (1 << 4)
  79 #define STATE_OTHEROP   (1 << 5)
  80 
  81 // The max. stage number we currently use (could not be
  82 // larger than 7)
  83 #define MAX_USED_TEXTURE_SAMPLER 1
  84 
  85 // - Texture pixel format table  -------------------------------------
  86 #define TR_OPAQUE      java_awt_Transparency_OPAQUE
  87 #define TR_BITMASK     java_awt_Transparency_BITMASK
  88 #define TR_TRANSLUCENT java_awt_Transparency_TRANSLUCENT
  89 
  90 class D3DResource;
  91 class D3DResourceManager;
  92 class D3DMaskCache;
  93 class D3DVertexCacher;
  94 class D3DGlyphCache;
  95 
  96 // - D3DContext class  -----------------------------------------------
  97 
  98 /**
  99  * This class provides the following functionality:
 100  *  - holds the state of D3DContext java class (current pixel color,
 101  *    alpha compositing mode, extra alpha)
 102  *  - provides access to IDirect3DDevice9 interface (creation,
 103  *    disposal, exclusive access)
 104  *  - handles state changes of the direct3d device (transform,
 105  *    compositing mode, current texture)
 106  *  - provides means of creating textures, plain surfaces
 107  *  - holds a glyph cache texture for the associated device
 108  *  - implements primitives batching mechanism
 109  */
 110 class D3DPIPELINE_API D3DContext {
 111 public:
 112     /**
 113      * Releases the old device (if there was one) and all associated
 114      * resources, re-creates, initializes and tests the new device.
 115      *
 116      * If the device doesn't pass the test, it's released.
 117      *
 118      * Used when the context is first created, and then after a
 119      * display change event.
 120      *
 121      * Note that this method also does the necessary registry checks,
 122      * and if the registry shows that we've crashed when attempting
 123      * to initialize and test the device last time, it doesn't attempt
 124      * to create/init/test the device.
 125      */
 126     static
 127     HRESULT CreateInstance(IDirect3D9 *pd3d9, UINT adapter, D3DContext **ppCtx);
 128     // creates a new D3D windowed device with swap copy effect and default
 129     // present interval
 130     HRESULT InitContext();
 131     // creates or resets a D3D device given the parameters
 132     HRESULT ConfigureContext(D3DPRESENT_PARAMETERS *pNewParams);
 133     // resets existing D3D device with the current presentation parameters
 134     HRESULT ResetContext();
 135     HRESULT CheckAndResetDevice();
 136 
 137     // saves the state of the D3D device in a state block, resets
 138     // context's state to STATE_CHANGE
 139     HRESULT SaveState();
 140     // restores the state of the D3D device from existing state block,
 141     // resets context's state to STATE_CHANGE
 142     HRESULT RestoreState();
 143 
 144     void    ReleaseContextResources();
 145     void    ReleaseDefPoolResources();
 146     virtual ~D3DContext();
 147 
 148     // methods replicating java-level D3DContext objext
 149     HRESULT SetAlphaComposite(jint rule, jfloat extraAlpha, jint flags);
 150     HRESULT ResetComposite();
 151 
 152     /**
 153      * Glyph cache-related methods
 154      */
 155     HRESULT InitGrayscaleGlyphCache();
 156     HRESULT InitLCDGlyphCache();
 157     D3DGlyphCache* GetGrayscaleGlyphCache() { return pGrayscaleGlyphCache; }
 158     D3DGlyphCache* GetLCDGlyphCache() { return pLCDGlyphCache; }
 159 
 160     D3DResourceManager *GetResourceManager() { return pResourceMgr; }
 161     D3DMaskCache       *GetMaskCache() { return pMaskCache; }
 162 
 163     HRESULT UploadTileToTexture(D3DResource *pTextureRes, void *pixels,
 164                                 jint dstx, jint dsty,
 165                                 jint srcx, jint srcy,
 166                                 jint srcWidth, jint srcHeight,
 167                                 jint srcStride,
 168                                 TileFormat srcFormat,
 169                                 // out: num of pixels in first and last
 170                                 // columns, only counted for LCD glyph uploads
 171                                 jint *pPixelsTouchedL = NULL,
 172                                 jint *pPixelsTouchedR = NULL);
 173 
 174     // returns capabilities of the Direct3D device
 175     D3DCAPS9 *GetDeviceCaps() { return &devCaps; }
 176     // returns caps in terms of the D3DContext
 177     int GetContextCaps() { return contextCaps; }
 178     D3DPRESENT_PARAMETERS *GetPresentationParams() { return &curParams; }
 179 
 180     IDirect3DDevice9 *Get3DDevice() { return pd3dDevice; }
 181     IDirect3D9 *Get3DObject() { return pd3dObject; }
 182 
 183     /**
 184      * This method only sets the texture if it's not already set.
 185      */
 186     HRESULT SetTexture(IDirect3DTexture9 *pTexture, DWORD dwSampler = 0);
 187 
 188     /**
 189      * This method only updates the texture color state if it hasn't changed.
 190      */
 191     HRESULT UpdateTextureColorState(DWORD dwState, DWORD dwSampler = 0);
 192 
 193     HRESULT SetRenderTarget(IDirect3DSurface9 *pSurface);
 194     HRESULT SetTransform(jdouble m00, jdouble m10,
 195                          jdouble m01, jdouble m11,
 196                          jdouble m02, jdouble m12);
 197     HRESULT ResetTransform();
 198 
 199     // clipping-related methods
 200     HRESULT SetRectClip(int x1, int y1, int x2, int y2);
 201     HRESULT BeginShapeClip();
 202     HRESULT EndShapeClip();
 203     HRESULT ResetClip();
 204     ClipType GetClipType();
 205 
 206     /**
 207      * Shader-related methods
 208      */
 209     HRESULT EnableBasicGradientProgram(jint flags);
 210     HRESULT EnableLinearGradientProgram(jint flags);
 211     HRESULT EnableRadialGradientProgram(jint flags);
 212     HRESULT EnableConvolveProgram(jint flags);
 213     HRESULT EnableRescaleProgram(jint flags);
 214     HRESULT EnableLookupProgram(jint flags);
 215     HRESULT EnableLCDTextProgram();
 216     HRESULT EnableAAParallelogramProgram();
 217     HRESULT DisableAAParallelogramProgram();
 218 
 219     BOOL IsTextureFilteringSupported(D3DTEXTUREFILTERTYPE fType);
 220     BOOL IsStretchRectFilteringSupported(D3DTEXTUREFILTERTYPE fType);
 221     BOOL IsPow2TexturesOnly()
 222         { return devCaps.TextureCaps & D3DPTEXTURECAPS_POW2; };
 223     BOOL IsSquareTexturesOnly()
 224         { return devCaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY; }
 225     BOOL IsHWRasterizer() { return bIsHWRasterizer; }
 226     BOOL IsTextureFormatSupported(D3DFORMAT format, DWORD usage = 0);
 227     BOOL IsDynamicTextureSupported()
 228         { return devCaps.Caps2 & D3DCAPS2_DYNAMICTEXTURES; }
 229 // REMIND: for now for performance testing
 230 //        { return (getenv("J2D_D3D_USE_DYNAMIC_TEX") != NULL); }
 231     BOOL IsImmediateIntervalSupported()
 232         { return devCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE;}
 233     BOOL IsPixelShader20Supported()
 234         { return (devCaps.PixelShaderVersion >= D3DPS_VERSION(2,0)); }
 235     BOOL IsGradientInstructionExtensionSupported()
 236         { return devCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS; }
 237     BOOL IsPixelShader30Supported()
 238         { return (devCaps.PixelShaderVersion >= D3DPS_VERSION(3,0)); }
 239     BOOL IsMultiTexturingSupported()
 240         { return (devCaps.MaxSimultaneousTextures > 1); }
 241     BOOL IsAlphaRTSurfaceSupported();
 242     BOOL IsAlphaRTTSupported();
 243     BOOL IsOpaqueRTTSupported();
 244 
 245     jint GetPaintState() { return paintState; }
 246     void SetPaintState(jint state) { this->paintState = state; }
 247     BOOL IsIdentityTx() { return bIsIdentityTx; }
 248 
 249     HRESULT FlushVertexQueue();
 250     D3DVertexCacher *pVCacher;
 251     HRESULT UpdateState(jbyte newState);
 252 
 253     HRESULT Sync();
 254 
 255     // primitives batching-related methods
 256     /**
 257      * Calls devices's BeginScene if there weren't one already pending,
 258      * sets the pending flag.
 259      */
 260     HRESULT BeginScene(jbyte newState);
 261     /**
 262      * Flushes the vertex queue and does end scene if
 263      * a BeginScene is pending
 264      */
 265     HRESULT EndScene();
 266 
 267     /**
 268      * Fields that track native-specific state.
 269      */
 270     jint       paintState;
 271     jboolean   useMask;
 272     jfloat     extraAlpha;
 273 
 274     /**
 275      * Current operation state.
 276      * See STATE_* macros above.
 277      */
 278     jbyte      opState;
 279 
 280 private:
 281 
 282     /**
 283      * Glyph cache-related methods/fields...
 284      */
 285     D3DGlyphCache *pGrayscaleGlyphCache;
 286     D3DGlyphCache *pLCDGlyphCache;
 287 
 288     /**
 289      * The handle to the LCD text pixel shader program.
 290      */
 291     IDirect3DPixelShader9 *lcdTextProgram;
 292 
 293     /**
 294      * The handle to the AA pixel and vertex shader programs.
 295      */
 296     IDirect3DPixelShader9 *aaPgramProgram;
 297 
 298     IDirect3DPixelShader9 *CreateFragmentProgram(DWORD **shaders,
 299                                                  ShaderList *programs,
 300                                                  jint flags);
 301     HRESULT EnableFragmentProgram(DWORD **shaders,
 302                                   ShaderList *programList,
 303                                   jint flags);
 304 
 305     // finds appropriate to the target surface depth format,
 306     // creates the depth buffer and installs it onto the device
 307     HRESULT InitDepthStencilBuffer(D3DSURFACE_DESC *pTargetDesc);
 308     // returns true if the current depth buffer is compatible
 309     // with the new target, and the dimensions fit, false otherwise
 310     BOOL IsDepthStencilBufferOk(D3DSURFACE_DESC *pTargetDesc);
 311 
 312     D3DContext(IDirect3D9 *pd3dObject, UINT adapter);
 313     HRESULT InitDevice(IDirect3DDevice9 *d3dDevice);
 314     HRESULT InitContextCaps();
 315     // updates the texture transform(s) used for better texel to pixel mapping
 316     // for the passed in sampler;
 317     // if -1 is passed as the sampler, texture transforms for
 318     // samplers [0..MAX_USED_TEXTURE_SAMPLER] are updated
 319     // REMIND: see the comment in the method implementation before enabling.
 320 #undef UPDATE_TX
 321 #ifdef UPDATE_TX
 322     HRESULT UpdateTextureTransforms(DWORD dwSamplerToUpdate);
 323 #endif // UPDATE_TX
 324     IDirect3DDevice9        *pd3dDevice;
 325     IDirect3D9              *pd3dObject;
 326 
 327     D3DResourceManager      *pResourceMgr;
 328     D3DMaskCache            *pMaskCache;
 329 
 330     ShaderList convolvePrograms;
 331     ShaderList rescalePrograms;
 332     ShaderList lookupPrograms;
 333     ShaderList basicGradPrograms;
 334     ShaderList linearGradPrograms;
 335     ShaderList radialGradPrograms;
 336 
 337     // array of the textures currently set to the device
 338     IDirect3DTexture9     *lastTexture[MAX_USED_TEXTURE_SAMPLER+1];
 339 
 340     DWORD lastTextureColorState[MAX_USED_TEXTURE_SAMPLER+1];
 341 
 342     UINT adapterOrdinal;
 343     D3DPRESENT_PARAMETERS   curParams;
 344     D3DCAPS9 devCaps;
 345     int contextCaps;
 346     BOOL bIsHWRasterizer;
 347 
 348     BOOL bIsIdentityTx;
 349 
 350     IDirect3DQuery9* pSyncQuery;
 351     D3DResource* pSyncRTRes;
 352 
 353     IDirect3DStateBlock9* pStateBlock;
 354 
 355     /**
 356      * Used to implement simple primitive batching.
 357      * See BeginScene/EndScene/ForceEndScene.
 358      */
 359     BOOL    bBeginScenePending;
 360 };
 361 
 362 // - Helper Macros ---------------------------------------------------
 363 
 364 #define D3DC_INIT_SHADER_LIST(list, max) \
 365     do { \
 366         (list).head     = NULL; \
 367         (list).maxItems = (max); \
 368         (list).dispose  = D3DContext_DisposeShader; \
 369     } while (0)
 370 
 371 /**
 372  * This constant determines the size of the shared tile texture used
 373  * by a number of image rendering methods.  For example, the blit tile texture
 374  * will have dimensions with width D3DC_BLIT_TILE_SIZE and height
 375  * D3DC_BLIT_TILE_SIZE (the tile will always be square).
 376  */
 377 #define D3DC_BLIT_TILE_SIZE 256
 378 
 379 /**
 380  * See BufferedContext.java for more on these flags...
 381  */
 382 #define D3DC_NO_CONTEXT_FLAGS \
 383     sun_java2d_pipe_BufferedContext_NO_CONTEXT_FLAGS
 384 #define D3DC_SRC_IS_OPAQUE    \
 385     sun_java2d_pipe_BufferedContext_SRC_IS_OPAQUE
 386 #define D3DC_USE_MASK         \
 387     sun_java2d_pipe_BufferedContext_USE_MASK
 388 
 389 #define CAPS_EMPTY          \
 390     sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_EMPTY
 391 #define CAPS_RT_PLAIN_ALPHA \
 392     sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_RT_PLAIN_ALPHA
 393 #define CAPS_RT_TEXTURE_ALPHA      \
 394     sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_RT_TEXTURE_ALPHA
 395 #define CAPS_RT_TEXTURE_OPAQUE     \
 396     sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_RT_TEXTURE_OPAQUE
 397 #define CAPS_MULTITEXTURE   \
 398     sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_MULTITEXTURE
 399 #define CAPS_TEXNONPOW2     \
 400     sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_TEXNONPOW2
 401 #define CAPS_TEXNONSQUARE   \
 402     sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_TEXNONSQUARE
 403 #define CAPS_LCD_SHADER     \
 404     sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_LCD_SHADER
 405 #define CAPS_BIOP_SHADER    \
 406     sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_BIOP_SHADER
 407 #define CAPS_AA_SHADER    \
 408     sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_AA_SHADER
 409 #define CAPS_DEVICE_OK      \
 410     sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_DEVICE_OK
 411 #define CAPS_PS20           \
 412     sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_PS20
 413 #define CAPS_PS30           \
 414     sun_java2d_d3d_D3DContext_D3DContextCaps_CAPS_PS30
 415 
 416 #define DEVICE_RESET    \
 417     sun_java2d_pipe_hw_AccelDeviceEventNotifier_DEVICE_RESET
 418 #define DEVICE_DISPOSED \
 419     sun_java2d_pipe_hw_AccelDeviceEventNotifier_DEVICE_DISPOSED
 420 
 421 #endif // D3DCONTEXT_H