Home | History | Annotate | Download | only in include
      1 /*
      2     Copyright 2011 Google Inc.
      3 
      4     Licensed under the Apache License, Version 2.0 (the "License");
      5     you may not use this file except in compliance with the License.
      6     You may obtain a copy of the License at
      7 
      8          http://www.apache.org/licenses/LICENSE-2.0
      9 
     10     Unless required by applicable law or agreed to in writing, software
     11     distributed under the License is distributed on an "AS IS" BASIS,
     12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13     See the License for the specific language governing permissions and
     14     limitations under the License.
     15  */
     16 
     17 #ifndef GrGpu_DEFINED
     18 #define GrGpu_DEFINED
     19 
     20 #include "GrDrawTarget.h"
     21 #include "GrPathRenderer.h"
     22 #include "GrRect.h"
     23 #include "GrRefCnt.h"
     24 #include "GrTexture.h"
     25 
     26 class GrContext;
     27 class GrIndexBufferAllocPool;
     28 class GrResource;
     29 class GrVertexBufferAllocPool;
     30 
     31 /**
     32  * Gpu usage statistics.
     33  */
     34 struct GrGpuStats {
     35     uint32_t fVertexCnt;  //<! Number of vertices drawn
     36     uint32_t fIndexCnt;   //<! Number of indices drawn
     37     uint32_t fDrawCnt;    //<! Number of draws
     38 
     39     uint32_t fProgChngCnt;//<! Number of program changes (N/A for fixed)
     40 
     41     /*
     42         *  Number of times the texture is set in 3D API
     43         */
     44     uint32_t fTextureChngCnt;
     45     /*
     46         *  Number of times the render target is set in 3D API
     47         */
     48     uint32_t fRenderTargetChngCnt;
     49     /*
     50         *  Number of textures created (includes textures that are rendertargets).
     51         */
     52     uint32_t fTextureCreateCnt;
     53     /*
     54         *  Number of rendertargets created.
     55         */
     56     uint32_t fRenderTargetCreateCnt;
     57 };
     58 
     59 class GrGpu : public GrDrawTarget {
     60 
     61 public:
     62     /**
     63      * Additional blend coeffecients for dual source blending, not exposed
     64      * through GrPaint/GrContext.
     65      */
     66     enum ExtendedBlendCoeffs {
     67         // source 2 refers to second output color when
     68         // using dual source blending.
     69         kS2C_BlendCoeff = kPublicBlendCoeffCount,
     70         kIS2C_BlendCoeff,
     71         kS2A_BlendCoeff,
     72         kIS2A_BlendCoeff,
     73 
     74         kTotalBlendCoeffCount
     75     };
     76 
     77     /**
     78      *  Create an instance of GrGpu that matches the specified Engine backend.
     79      *  If the requested engine is not supported (at compile-time or run-time)
     80      *  this returns NULL.
     81      */
     82     static GrGpu* Create(GrEngine, GrPlatform3DContext context3D);
     83 
     84     ////////////////////////////////////////////////////////////////////////////
     85 
     86     GrGpu();
     87     virtual ~GrGpu();
     88 
     89     // The GrContext sets itself as the owner of this Gpu object
     90     void setContext(GrContext* context) {
     91         GrAssert(NULL == fContext);
     92         fContext = context;
     93     }
     94     GrContext* getContext() { return fContext; }
     95     const GrContext* getContext() const { return fContext; }
     96 
     97     /**
     98      * The GrGpu object normally assumes that no outsider is setting state
     99      * within the underlying 3D API's context/device/whatever. This call informs
    100      * the GrGpu that the state was modified and it shouldn't make assumptions
    101      * about the state.
    102      */
    103     void markContextDirty() { fContextIsDirty = true; }
    104 
    105     void unimpl(const char[]);
    106 
    107     /**
    108      * Creates a texture object. If desc width or height is not a power of
    109      * two but underlying API requires a power of two texture then srcData
    110      * will be embedded in a power of two texture. The extra width and height
    111      * is filled as though srcData were rendered clamped into the texture.
    112      *
    113      * If kRenderTarget_TextureFlag is specified the GrRenderTarget is
    114      * accessible via GrTexture::asRenderTarget(). The texture will hold a ref
    115      * on the render target until its releaseRenderTarget() is called or it is
    116      * destroyed.
    117      *
    118      * @param desc        describes the texture to be created.
    119      * @param srcData     texel data to load texture. Begins with full-size
    120      *                    palette data for paletted textures. Contains width*
    121      *                    height texels. If NULL texture data is uninitialized.
    122      *
    123      * @return    The texture object if successful, otherwise NULL.
    124      */
    125     GrTexture* createTexture(const GrTextureDesc& desc,
    126                              const void* srcData, size_t rowBytes);
    127 
    128     GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc);
    129 
    130     /**
    131      * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
    132      * viewport state from the underlying 3D API and wraps it in a
    133      * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
    134      * underlying object in its destructor and it is up to caller to guarantee
    135      * that it remains valid while the GrRenderTarget is used.
    136      *
    137      * @return the newly created GrRenderTarget
    138      */
    139     GrRenderTarget* createRenderTargetFrom3DApiState();
    140 
    141     /**
    142      * Creates a vertex buffer.
    143      *
    144      * @param size    size in bytes of the vertex buffer
    145      * @param dynamic hints whether the data will be frequently changed
    146      *                by either GrVertexBuffer::lock or
    147      *                GrVertexBuffer::updateData.
    148      *
    149      * @return    The vertex buffer if successful, otherwise NULL.
    150      */
    151     GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);
    152 
    153     /**
    154      * Creates an index buffer.
    155      *
    156      * @param size    size in bytes of the index buffer
    157      * @param dynamic hints whether the data will be frequently changed
    158      *                by either GrIndexBuffer::lock or
    159      *                GrIndexBuffer::updateData.
    160      *
    161      * @return The index buffer if successful, otherwise NULL.
    162      */
    163     GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
    164 
    165     /**
    166      * Are 8 bit paletted textures supported.
    167      *
    168      * @return    true if 8bit palette textures are supported, false otherwise
    169      */
    170     bool supports8BitPalette() const { return f8bitPaletteSupport; }
    171 
    172     /**
    173      * returns true if two sided stenciling is supported. If false then only
    174      * the front face values of the GrStencilSettings
    175      * @return    true if only a single stencil pass is needed.
    176      */
    177     bool supportsTwoSidedStencil() const
    178                                         { return fTwoSidedStencilSupport; }
    179 
    180     /**
    181      * returns true if stencil wrap is supported. If false then
    182      * kIncWrap_StencilOp and kDecWrap_StencilOp are treated as
    183      * kIncClamp_StencilOp and kDecClamp_StencilOp, respectively.
    184      * @return    true if stencil wrap ops are supported.
    185      */
    186     bool supportsStencilWrapOps() const
    187                                         { return fStencilWrapOpsSupport; }
    188 
    189     /**
    190      * Checks whether locking vertex and index buffers is supported.
    191      *
    192      * @return true if locking is supported.
    193      */
    194     bool supportsBufferLocking() const { return fBufferLockSupport; }
    195 
    196     /**
    197      * Does the 3D API support anti-aliased lines. If so then line primitive
    198      * types will use this functionality when the AA state flag is set.
    199      */
    200     bool supportsAALines() const { return fAALineSupport; }
    201 
    202     /**
    203      * Does the subclass support GrSamplerState::k4x4Downsample_Filter
    204      */
    205     bool supports4x4DownsampleFilter() const { return f4X4DownsampleFilterSupport; }
    206 
    207     /**
    208      * Does this instance support dual-source blending? Required for proper
    209      * blending with partial coverage with certain blend modes (dst coeff is
    210      * not 1, ISA, or ISC)
    211      */
    212     bool supportsDualSourceBlending() const {
    213         return fDualSourceBlendingSupport;
    214     }
    215 
    216     /**
    217      * Gets the minimum width of a render target. If a texture/rt is created
    218      * with a width less than this size the GrGpu object will clamp it to this
    219      * value.
    220      */
    221     int minRenderTargetWidth() const { return fMinRenderTargetWidth; }
    222 
    223     /**
    224      * Gets the minimum width of a render target. If a texture/rt is created
    225      * with a height less than this size the GrGpu object will clamp it to this
    226      * value.
    227      */
    228     int minRenderTargetHeight() const  { return fMinRenderTargetHeight; }
    229 
    230     /**
    231      * Reports whether full scene anti-aliasing is supported.
    232      */
    233     bool supportsFullsceneAA() const { return fFSAASupport; }
    234 
    235     /**
    236      * Returns true if NPOT textures can be created
    237      *
    238      * @return    true if NPOT textures can be created
    239      */
    240     bool npotTextureSupport() const { return fNPOTTextureSupport; }
    241 
    242     /**
    243      * Returns true if NPOT textures can be repeat/mirror tiled.
    244      *
    245      * @return    true if NPOT textures can be tiled
    246      */
    247     bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
    248 
    249     /**
    250      * Returns true if a NPOT texture can be a rendertarget
    251      *
    252      * @return    the true if NPOT texture/rendertarget can be created.
    253      */
    254     bool npotRenderTargetSupport() const { return fNPOTRenderTargetSupport; }
    255 
    256     int maxTextureDimension() const { return fMaxTextureDimension; }
    257 
    258     // GrDrawTarget overrides
    259     virtual void drawIndexed(GrPrimitiveType type,
    260                              int startVertex,
    261                              int startIndex,
    262                              int vertexCount,
    263                              int indexCount);
    264 
    265     virtual void drawNonIndexed(GrPrimitiveType type,
    266                                 int startVertex,
    267                                 int vertexCount);
    268     virtual void clear(const GrIRect* rect, GrColor color);
    269 
    270     /**
    271      * Installs a path renderer that will be used to draw paths that are
    272      * part of the clip.
    273      */
    274     void setClipPathRenderer(GrPathRenderer* pathRenderer) {
    275         GrSafeAssign(fClientPathRenderer, pathRenderer);
    276     }
    277 
    278     /**
    279      * Returns an index buffer that can be used to render quads.
    280      * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
    281      * The max number of quads can be queried using GrIndexBuffer::maxQuads().
    282      * Draw with kTriangles_PrimitiveType
    283      * @ return the quad index buffer
    284      */
    285     const GrIndexBuffer* getQuadIndexBuffer() const;
    286 
    287     /**
    288      * Returns a vertex buffer with four position-only vertices [(0,0), (1,0),
    289      * (1,1), (0,1)].
    290      * @ return unit square vertex buffer
    291      */
    292     const GrVertexBuffer* getUnitSquareVertexBuffer() const;
    293 
    294     /**
    295      * Ensures that the current render target is actually set in the
    296      * underlying 3D API. Used when client wants to use 3D API to directly
    297      * render to the RT.
    298      */
    299     void forceRenderTargetFlush();
    300 
    301     /**
    302      * Reads a rectangle of pixels from a render target.
    303      * @param renderTarget  the render target to read from. NULL means the
    304      *                      current render target.
    305      * @param left          left edge of the rectangle to read (inclusive)
    306      * @param top           top edge of the rectangle to read (inclusive)
    307      * @param width         width of rectangle to read in pixels.
    308      * @param height        height of rectangle to read in pixels.
    309      * @param config        the pixel config of the destination buffer
    310      * @param buffer        memory to read the rectangle into.
    311      *
    312      * @return true if the read succeeded, false if not. The read can fail
    313      *              because of a unsupported pixel config or because no render
    314      *              target is currently set.
    315      */
    316     bool readPixels(GrRenderTarget* renderTarget,
    317                     int left, int top, int width, int height,
    318                     GrPixelConfig config, void* buffer);
    319 
    320     const GrGpuStats& getStats() const;
    321     void resetStats();
    322     void printStats() const;
    323 
    324     /**
    325      * Called to tell Gpu object that all GrResources have been lost and should
    326      * be abandoned.
    327      */
    328     virtual void abandonResources();
    329 
    330     /**
    331      * Called to tell Gpu object to release all GrResources.
    332      */
    333     void releaseResources();
    334 
    335     /**
    336      * Add resource to list of resources. Should only be called by GrResource.
    337      * @param resource  the resource to add.
    338      */
    339     void insertResource(GrResource* resource);
    340 
    341     /**
    342      * Remove resource from list of resources. Should only be called by
    343      * GrResource.
    344      * @param resource  the resource to remove.
    345      */
    346     void removeResource(GrResource* resource);
    347 
    348 protected:
    349     enum PrivateStateBits {
    350         kFirstBit = (kLastPublicStateBit << 1),
    351 
    352         kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
    353                                                  // stencil bits used for
    354                                                  // clipping.
    355     };
    356 
    357     /**
    358      * Extensions to GrDrawTarget::StateBits to implement stencil clipping
    359      */
    360     struct ClipState {
    361         bool            fClipInStencil;
    362         bool            fClipIsDirty;
    363     } fClipState;
    364 
    365     // GrDrawTarget override
    366     virtual void clipWillBeSet(const GrClip& newClip);
    367 
    368     // prepares clip flushes gpu state before a draw
    369     bool setupClipAndFlushState(GrPrimitiveType type);
    370 
    371     // Functions used to map clip-respecting stencil tests into normal
    372     // stencil funcs supported by GPUs.
    373     static GrStencilFunc ConvertStencilFunc(bool stencilInClip,
    374                                             GrStencilFunc func);
    375     static void ConvertStencilFuncAndMask(GrStencilFunc func,
    376                                           bool clipInStencil,
    377                                           unsigned int clipBit,
    378                                           unsigned int userBits,
    379                                           unsigned int* ref,
    380                                           unsigned int* mask);
    381 
    382     // stencil settings to clip drawing when stencil clipping is in effect
    383     // and the client isn't using the stencil test.
    384     static const GrStencilSettings gClipStencilSettings;
    385 
    386     // defaults to false, subclass can set true to support palleted textures
    387     bool f8bitPaletteSupport;
    388 
    389     // set by subclass
    390     bool fNPOTTextureSupport;
    391     bool fNPOTTextureTileSupport;
    392     bool fNPOTRenderTargetSupport;
    393     bool fTwoSidedStencilSupport;
    394     bool fStencilWrapOpsSupport;
    395     bool fAALineSupport;
    396     bool fFSAASupport;
    397     bool f4X4DownsampleFilterSupport; // supports GrSamplerState::k4x4Downsample_Filter
    398     bool fDualSourceBlendingSupport;
    399 
    400     // set by subclass to true if index and vertex buffers can be locked, false
    401     // otherwise.
    402     bool fBufferLockSupport;
    403 
    404     // set by subclass
    405     int fMinRenderTargetWidth;
    406     int fMinRenderTargetHeight;
    407     int fMaxTextureDimension;
    408 
    409     GrGpuStats fStats;
    410 
    411     const GrVertexBuffer*           fCurrPoolVertexBuffer;
    412     int                             fCurrPoolStartVertex;
    413 
    414     const GrIndexBuffer*            fCurrPoolIndexBuffer;
    415     int                             fCurrPoolStartIndex;
    416 
    417     // GrDrawTarget overrides
    418     virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
    419                                    void**         vertices,
    420                                    void**         indices);
    421     virtual void onReleaseGeometry();
    422 
    423     virtual void onSetVertexSourceToArray(const void* vertexArray,
    424                                           int vertexCount);
    425 
    426     virtual void onSetIndexSourceToArray(const void* indexArray,
    427                                          int indexCount);
    428     // Helpers for setting up geometry state
    429     void finalizeReservedVertices();
    430     void finalizeReservedIndices();
    431 
    432     // overridden by API-specific derived class to handle re-emitting 3D API
    433     // preample and dirtying state cache.
    434     virtual void resetContext() = 0;
    435 
    436     // overridden by API-specific derived class to create objects.
    437     virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
    438                                        const void* srcData,
    439                                        size_t rowBytes) = 0;
    440     virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) = 0;
    441     virtual GrRenderTarget* onCreateRenderTargetFrom3DApiState() = 0;
    442     virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size,
    443                                                  bool dynamic) = 0;
    444     virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
    445                                                bool dynamic) = 0;
    446 
    447     // overridden by API-specific derivated class to perform the clear and
    448     // clearRect. NULL rect means clear whole target.
    449     virtual void onClear(const GrIRect* rect, GrColor color) = 0;
    450 
    451     // overridden by API-specific derived class to perform the draw call.
    452     virtual void onDrawIndexed(GrPrimitiveType type,
    453                                uint32_t startVertex,
    454                                uint32_t startIndex,
    455                                uint32_t vertexCount,
    456                                uint32_t indexCount) = 0;
    457 
    458     virtual void onDrawNonIndexed(GrPrimitiveType type,
    459                                   uint32_t vertexCount,
    460                                   uint32_t numVertices) = 0;
    461 
    462     // overridden by API-specific derived class to perform flush
    463     virtual void onForceRenderTargetFlush() = 0;
    464 
    465     // overridden by API-specific derived class to perform the read pixels.
    466     virtual bool onReadPixels(GrRenderTarget* target,
    467                               int left, int top, int width, int height,
    468                               GrPixelConfig, void* buffer) = 0;
    469 
    470     // called to program the vertex data, indexCount will be 0 if drawing non-
    471     // indexed geometry. The subclass may adjust the startVertex and/or
    472     // startIndex since it may have already accounted for these in the setup.
    473     virtual void setupGeometry(int* startVertex,
    474                                int* startIndex,
    475                                int vertexCount,
    476                                int indexCount) = 0;
    477 
    478 
    479     // The GrGpu typically records the clients requested state and then flushes
    480     // deltas from previous state at draw time. This function does the
    481     // API-specific flush of the state
    482     // returns false if current state is unsupported.
    483     virtual bool flushGraphicsState(GrPrimitiveType type) = 0;
    484 
    485     // Sets the scissor rect, or disables if rect is NULL.
    486     virtual void flushScissor(const GrIRect* rect) = 0;
    487 
    488     // GrGpu subclass removes the clip from the stencil buffer
    489     virtual void clearStencilClip(const GrIRect& rect) = 0;
    490 
    491 private:
    492     GrContext*                  fContext; // not reffed (context refs gpu)
    493 
    494     GrVertexBufferAllocPool*    fVertexPool;
    495 
    496     GrIndexBufferAllocPool*     fIndexPool;
    497 
    498     mutable GrIndexBuffer*      fQuadIndexBuffer; // mutable so it can be
    499                                                   // created on-demand
    500 
    501     mutable GrVertexBuffer*     fUnitSquareVertexBuffer; // mutable so it can be
    502                                                          // created on-demand
    503 
    504     GrDefaultPathRenderer*      fDefaultPathRenderer;
    505     GrPathRenderer*             fClientPathRenderer;
    506 
    507     bool                        fContextIsDirty;
    508 
    509     // when in an internal draw these indicate whether the pools are in use
    510     // by one of the outer draws. If false then it is safe to reset the
    511     // pool.
    512     bool                        fVertexPoolInUse;
    513     bool                        fIndexPoolInUse;
    514 
    515     GrResource*                 fResourceHead;
    516 
    517     // readies the pools to provide vertex/index data.
    518     void prepareVertexPool();
    519     void prepareIndexPool();
    520 
    521     // determines the path renderer used to draw a clip path element.
    522     GrPathRenderer* getClipPathRenderer(const SkPath& path, GrPathFill fill);
    523 
    524     void handleDirtyContext() {
    525         if (fContextIsDirty) {
    526             this->resetContext();
    527             fContextIsDirty = false;
    528         }
    529     }
    530 
    531     // used to save and restore state when the GrGpu needs
    532     // to make its geometry pools available internally
    533     class AutoInternalDrawGeomRestore {
    534     public:
    535         AutoInternalDrawGeomRestore(GrGpu* gpu) : fAgsr(gpu) {
    536             fGpu = gpu;
    537 
    538             fVertexPoolWasInUse = gpu->fVertexPoolInUse;
    539             fIndexPoolWasInUse  = gpu->fIndexPoolInUse;
    540 
    541             gpu->fVertexPoolInUse = fVertexPoolWasInUse ||
    542                                    (kBuffer_GeometrySrcType !=
    543                                     gpu->fGeometrySrc.fVertexSrc);
    544             gpu->fIndexPoolInUse  = fIndexPoolWasInUse ||
    545                                    (kBuffer_GeometrySrcType !=
    546                                     gpu->fGeometrySrc.fIndexSrc);;
    547 
    548             fSavedPoolVertexBuffer = gpu->fCurrPoolVertexBuffer;
    549             fSavedPoolStartVertex  = gpu->fCurrPoolStartVertex;
    550             fSavedPoolIndexBuffer  = gpu->fCurrPoolIndexBuffer;
    551             fSavedPoolStartIndex   = gpu->fCurrPoolStartIndex;
    552 
    553             fSavedReservedGeometry = gpu->fReservedGeometry;
    554             gpu->fReservedGeometry.fLocked = false;
    555         }
    556         ~AutoInternalDrawGeomRestore() {
    557             fGpu->fCurrPoolVertexBuffer = fSavedPoolVertexBuffer;
    558             fGpu->fCurrPoolStartVertex  = fSavedPoolStartVertex;
    559             fGpu->fCurrPoolIndexBuffer  = fSavedPoolIndexBuffer;
    560             fGpu->fCurrPoolStartIndex   = fSavedPoolStartIndex;
    561             fGpu->fVertexPoolInUse = fVertexPoolWasInUse;
    562             fGpu->fIndexPoolInUse  = fIndexPoolWasInUse;
    563             fGpu->fReservedGeometry = fSavedReservedGeometry;
    564         }
    565     private:
    566         AutoGeometrySrcRestore  fAgsr;
    567         GrGpu*                  fGpu;
    568         const GrVertexBuffer*   fSavedPoolVertexBuffer;
    569         int                     fSavedPoolStartVertex;
    570         const GrIndexBuffer*    fSavedPoolIndexBuffer;
    571         int                     fSavedPoolStartIndex;
    572         bool                    fVertexPoolWasInUse;
    573         bool                    fIndexPoolWasInUse;
    574         ReservedGeometry        fSavedReservedGeometry;
    575     };
    576 
    577     typedef GrDrawTarget INHERITED;
    578 };
    579 
    580 #endif
    581