Home | History | Annotate | Download | only in gpu
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef GrGpu_DEFINED
     11 #define GrGpu_DEFINED
     12 
     13 #include "GrDrawTarget.h"
     14 #include "GrRect.h"
     15 #include "GrRefCnt.h"
     16 #include "GrTexture.h"
     17 
     18 class GrContext;
     19 class GrIndexBufferAllocPool;
     20 class GrPathRenderer;
     21 class GrPathRendererChain;
     22 class GrResource;
     23 class GrStencilBuffer;
     24 class GrVertexBufferAllocPool;
     25 
     26 /**
     27  * Gpu usage statistics.
     28  */
     29 struct GrGpuStats {
     30     uint32_t fVertexCnt;  //<! Number of vertices drawn
     31     uint32_t fIndexCnt;   //<! Number of indices drawn
     32     uint32_t fDrawCnt;    //<! Number of draws
     33 
     34     uint32_t fProgChngCnt;//<! Number of program changes
     35 
     36     /**
     37      *  Number of times the texture is set in 3D API
     38      */
     39     uint32_t fTextureChngCnt;
     40     /**
     41      *  Number of times the render target is set in 3D API
     42      */
     43     uint32_t fRenderTargetChngCnt;
     44     /**
     45      *  Number of textures created (includes textures that are rendertargets).
     46      */
     47     uint32_t fTextureCreateCnt;
     48     /**
     49      *  Number of rendertargets created.
     50      */
     51     uint32_t fRenderTargetCreateCnt;
     52 };
     53 
     54 class GrGpu : public GrDrawTarget {
     55 
     56 public:
     57 
     58     /**
     59      * Additional blend coeffecients for dual source blending, not exposed
     60      * through GrPaint/GrContext.
     61      */
     62     enum ExtendedBlendCoeffs {
     63         // source 2 refers to second output color when
     64         // using dual source blending.
     65         kS2C_BlendCoeff = kPublicBlendCoeffCount,
     66         kIS2C_BlendCoeff,
     67         kS2A_BlendCoeff,
     68         kIS2A_BlendCoeff,
     69 
     70         kTotalBlendCoeffCount
     71     };
     72 
     73     /**
     74      *  Create an instance of GrGpu that matches the specified Engine backend.
     75      *  If the requested engine is not supported (at compile-time or run-time)
     76      *  this returns NULL.
     77      */
     78     static GrGpu* Create(GrEngine, GrPlatform3DContext context3D);
     79 
     80     ////////////////////////////////////////////////////////////////////////////
     81 
     82     GrGpu();
     83     virtual ~GrGpu();
     84 
     85     // The GrContext sets itself as the owner of this Gpu object
     86     void setContext(GrContext* context) {
     87         GrAssert(NULL == fContext);
     88         fContext = context;
     89     }
     90     GrContext* getContext() { return fContext; }
     91     const GrContext* getContext() const { return fContext; }
     92 
     93     /**
     94      * The GrGpu object normally assumes that no outsider is setting state
     95      * within the underlying 3D API's context/device/whatever. This call informs
     96      * the GrGpu that the state was modified and it shouldn't make assumptions
     97      * about the state.
     98      */
     99     void markContextDirty() { fContextIsDirty = true; }
    100 
    101     void unimpl(const char[]);
    102 
    103     /**
    104      * Creates a texture object. If desc width or height is not a power of
    105      * two but underlying API requires a power of two texture then srcData
    106      * will be embedded in a power of two texture. The extra width and height
    107      * is filled as though srcData were rendered clamped into the texture.
    108      *
    109      * If kRenderTarget_TextureFlag is specified the GrRenderTarget is
    110      * accessible via GrTexture::asRenderTarget(). The texture will hold a ref
    111      * on the render target until its releaseRenderTarget() is called or it is
    112      * destroyed.
    113      *
    114      * @param desc        describes the texture to be created.
    115      * @param srcData     texel data to load texture. Begins with full-size
    116      *                    palette data for paletted textures. Contains width*
    117      *                    height texels. If NULL texture data is uninitialized.
    118      *
    119      * @return    The texture object if successful, otherwise NULL.
    120      */
    121     GrTexture* createTexture(const GrTextureDesc& desc,
    122                              const void* srcData, size_t rowBytes);
    123 
    124     /**
    125      * Implements GrContext::createPlatformTexture
    126      */
    127     GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc);
    128 
    129     /**
    130      * Implements GrContext::createPlatformTexture
    131      */
    132     GrRenderTarget* createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc);
    133 
    134     /**
    135      * Creates a vertex buffer.
    136      *
    137      * @param size    size in bytes of the vertex buffer
    138      * @param dynamic hints whether the data will be frequently changed
    139      *                by either GrVertexBuffer::lock or
    140      *                GrVertexBuffer::updateData.
    141      *
    142      * @return    The vertex buffer if successful, otherwise NULL.
    143      */
    144     GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);
    145 
    146     /**
    147      * Creates an index buffer.
    148      *
    149      * @param size    size in bytes of the index buffer
    150      * @param dynamic hints whether the data will be frequently changed
    151      *                by either GrIndexBuffer::lock or
    152      *                GrIndexBuffer::updateData.
    153      *
    154      * @return The index buffer if successful, otherwise NULL.
    155      */
    156     GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
    157 
    158     /**
    159      * Returns an index buffer that can be used to render quads.
    160      * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
    161      * The max number of quads can be queried using GrIndexBuffer::maxQuads().
    162      * Draw with kTriangles_PrimitiveType
    163      * @ return the quad index buffer
    164      */
    165     const GrIndexBuffer* getQuadIndexBuffer() const;
    166 
    167     /**
    168      * Returns a vertex buffer with four position-only vertices [(0,0), (1,0),
    169      * (1,1), (0,1)].
    170      * @ return unit square vertex buffer
    171      */
    172     const GrVertexBuffer* getUnitSquareVertexBuffer() const;
    173 
    174     /**
    175      * Resolves MSAA.
    176      */
    177     void resolveRenderTarget(GrRenderTarget* target);
    178 
    179     /**
    180      * Ensures that the current render target is actually set in the
    181      * underlying 3D API. Used when client wants to use 3D API to directly
    182      * render to the RT.
    183      */
    184     void forceRenderTargetFlush();
    185 
    186     /**
    187      * If this returns true then a sequence that reads unpremultiplied pixels
    188      * from a surface, writes back the same values, and reads them again will
    189      * give the same pixel values back in both reads.
    190      */
    191     virtual bool canPreserveReadWriteUnpremulPixels() = 0;
    192 
    193     /**
    194      * readPixels with some configs may be slow. Given a desired config this
    195      * function returns a fast-path config. The returned config must have the
    196      * same components, component sizes, and not require conversion between
    197      * pre- and unpremultiplied alpha. The caller is free to ignore the result
    198      * and call readPixels with the original config.
    199      */
    200     virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig config)
    201                                                                         const {
    202         return config;
    203     }
    204 
    205     /**
    206      * Same as above but applies to writeTexturePixels
    207      */
    208     virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig config)
    209                                                                         const {
    210         return config;
    211     }
    212 
    213     /**
    214      * OpenGL's readPixels returns the result bottom-to-top while the skia
    215      * API is top-to-bottom. Thus we have to do a y-axis flip. The obvious
    216      * solution is to have the subclass do the flip using either the CPU or GPU.
    217      * However, the caller (GrContext) may have transformations to apply and can
    218      * simply fold in the y-flip for free. On the other hand, the subclass may
    219      * be able to do it for free itself. For example, the subclass may have to
    220      * do memcpys to handle rowBytes that aren't tight. It could do the y-flip
    221      * concurrently.
    222      *
    223      * This function returns true if a y-flip is required to put the pixels in
    224      * top-to-bottom order and the subclass cannot do it for free.
    225      *
    226      * See read pixels for the params
    227      * @return true if calling readPixels with the same set of params will
    228      *              produce bottom-to-top data
    229      */
    230      virtual bool readPixelsWillPayForYFlip(GrRenderTarget* renderTarget,
    231                                             int left, int top,
    232                                             int width, int height,
    233                                             GrPixelConfig config,
    234                                             size_t rowBytes) const = 0;
    235      /**
    236       * This should return true if reading a NxM rectangle of pixels from a
    237       * render target is faster if the target has dimensons N and M and the read
    238       * rectangle has its top-left at 0,0.
    239       */
    240      virtual bool fullReadPixelsIsFasterThanPartial() const { return false; };
    241 
    242     /**
    243      * Reads a rectangle of pixels from a render target. Fails if read requires
    244      * conversion between premultiplied and unpremultiplied configs. The caller
    245      * should do the conversion by rendering to a target with the desire config
    246      * first.
    247      *
    248      * @param renderTarget  the render target to read from. NULL means the
    249      *                      current render target.
    250      * @param left          left edge of the rectangle to read (inclusive)
    251      * @param top           top edge of the rectangle to read (inclusive)
    252      * @param width         width of rectangle to read in pixels.
    253      * @param height        height of rectangle to read in pixels.
    254      * @param config        the pixel config of the destination buffer
    255      * @param buffer        memory to read the rectangle into.
    256      * @param rowBytes      the number of bytes between consecutive rows. Zero
    257      *                      means rows are tightly packed.
    258      * @param invertY       buffer should be populated bottom-to-top as opposed
    259      *                      to top-to-bottom (skia's usual order)
    260      *
    261      * @return true if the read succeeded, false if not. The read can fail
    262      *              because of a unsupported pixel config or because no render
    263      *              target is currently set.
    264      */
    265     bool readPixels(GrRenderTarget* renderTarget,
    266                     int left, int top, int width, int height,
    267                     GrPixelConfig config, void* buffer, size_t rowBytes,
    268                     bool invertY);
    269 
    270     /**
    271      * Updates the pixels in a rectangle of a texture.
    272      *
    273      * @param left          left edge of the rectangle to write (inclusive)
    274      * @param top           top edge of the rectangle to write (inclusive)
    275      * @param width         width of rectangle to write in pixels.
    276      * @param height        height of rectangle to write in pixels.
    277      * @param config        the pixel config of the source buffer
    278      * @param buffer        memory to read pixels from
    279      * @param rowBytes      number of bytes bewtween consecutive rows. Zero
    280      *                      means rows are tightly packed.
    281      */
    282     void writeTexturePixels(GrTexture* texture,
    283                             int left, int top, int width, int height,
    284                             GrPixelConfig config, const void* buffer,
    285                             size_t rowBytes);
    286 
    287     const GrGpuStats& getStats() const;
    288     void resetStats();
    289     void printStats() const;
    290 
    291     /**
    292      * Called to tell Gpu object that all GrResources have been lost and should
    293      * be abandoned. Overrides must call INHERITED::abandonResources().
    294      */
    295     virtual void abandonResources();
    296 
    297     /**
    298      * Called to tell Gpu object to release all GrResources. Overrides must call
    299      * INHERITED::releaseResources().
    300      */
    301     void releaseResources();
    302 
    303     /**
    304      * Add resource to list of resources. Should only be called by GrResource.
    305      * @param resource  the resource to add.
    306      */
    307     void insertResource(GrResource* resource);
    308 
    309     /**
    310      * Remove resource from list of resources. Should only be called by
    311      * GrResource.
    312      * @param resource  the resource to remove.
    313      */
    314     void removeResource(GrResource* resource);
    315 
    316     // GrDrawTarget overrides
    317     virtual void clear(const GrIRect* rect, GrColor color);
    318 
    319     // After the client interacts directly with the 3D context state the GrGpu
    320     // must resync its internal state and assumptions about 3D context state.
    321     // Each time this occurs the GrGpu bumps a timestamp.
    322     // state of the 3D context
    323     // At 10 resets / frame and 60fps a 64bit timestamp will overflow in about
    324     // a billion years.
    325     typedef uint64_t ResetTimestamp;
    326 
    327     // This timestamp is always older than the current timestamp
    328     static const ResetTimestamp kExpiredTimestamp = 0;
    329     // Returns a timestamp based on the number of times the context was reset.
    330     // This timestamp can be used to lazily detect when cached 3D context state
    331     // is dirty.
    332     ResetTimestamp getResetTimestamp() const {
    333         return fResetTimestamp;
    334     }
    335 
    336 protected:
    337     enum PrivateDrawStateStateBits {
    338         kFirstBit = (GrDrawState::kLastPublicStateBit << 1),
    339 
    340         kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
    341                                                  // stencil bits used for
    342                                                  // clipping.
    343     };
    344 
    345     // keep track of whether we are using stencil clipping (as opposed to
    346     // scissor).
    347     bool    fClipInStencil;
    348 
    349     // prepares clip flushes gpu state before a draw
    350     bool setupClipAndFlushState(GrPrimitiveType type);
    351 
    352     // Functions used to map clip-respecting stencil tests into normal
    353     // stencil funcs supported by GPUs.
    354     static GrStencilFunc ConvertStencilFunc(bool stencilInClip,
    355                                             GrStencilFunc func);
    356     static void ConvertStencilFuncAndMask(GrStencilFunc func,
    357                                           bool clipInStencil,
    358                                           unsigned int clipBit,
    359                                           unsigned int userBits,
    360                                           unsigned int* ref,
    361                                           unsigned int* mask);
    362 
    363     // stencil settings to clip drawing when stencil clipping is in effect
    364     // and the client isn't using the stencil test.
    365     static const GrStencilSettings* GetClipStencilSettings();
    366 
    367     GrGpuStats fStats;
    368 
    369     struct GeometryPoolState {
    370         const GrVertexBuffer* fPoolVertexBuffer;
    371         int                   fPoolStartVertex;
    372 
    373         const GrIndexBuffer*  fPoolIndexBuffer;
    374         int                   fPoolStartIndex;
    375     };
    376     const GeometryPoolState& getGeomPoolState() {
    377         return fGeomPoolStateStack.back();
    378     }
    379 
    380     // GrDrawTarget overrides
    381     virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout,
    382                                       int vertexCount,
    383                                       void** vertices);
    384     virtual bool onReserveIndexSpace(int indexCount, void** indices);
    385     virtual void releaseReservedVertexSpace();
    386     virtual void releaseReservedIndexSpace();
    387     virtual void onSetVertexSourceToArray(const void* vertexArray,
    388                                           int vertexCount);
    389     virtual void onSetIndexSourceToArray(const void* indexArray,
    390                                          int indexCount);
    391     virtual void releaseVertexArray();
    392     virtual void releaseIndexArray();
    393     virtual void geometrySourceWillPush();
    394     virtual void geometrySourceWillPop(const GeometrySrcState& restoredState);
    395 
    396     // Helpers for setting up geometry state
    397     void finalizeReservedVertices();
    398     void finalizeReservedIndices();
    399 
    400     // called when the 3D context state is unknown. Subclass should emit any
    401     // assumed 3D context state and dirty any state cache
    402     virtual void onResetContext() = 0;
    403 
    404 
    405     // overridden by API-specific derived class to create objects.
    406     virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
    407                                        const void* srcData,
    408                                        size_t rowBytes) = 0;
    409     virtual GrTexture* onCreatePlatformTexture(const GrPlatformTextureDesc& desc) = 0;
    410     virtual GrRenderTarget* onCreatePlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) = 0;
    411     virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size,
    412                                                  bool dynamic) = 0;
    413     virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
    414                                                bool dynamic) = 0;
    415 
    416     // overridden by API-specific derivated class to perform the clear and
    417     // clearRect. NULL rect means clear whole target.
    418     virtual void onClear(const GrIRect* rect, GrColor color) = 0;
    419 
    420     // overridden by API-specific derived class to perform the draw call.
    421     virtual void onGpuDrawIndexed(GrPrimitiveType type,
    422                                   uint32_t startVertex,
    423                                   uint32_t startIndex,
    424                                   uint32_t vertexCount,
    425                                   uint32_t indexCount) = 0;
    426 
    427     virtual void onGpuDrawNonIndexed(GrPrimitiveType type,
    428                                      uint32_t vertexCount,
    429                                      uint32_t numVertices) = 0;
    430 
    431     // overridden by API-specific derived class to perform flush
    432     virtual void onForceRenderTargetFlush() = 0;
    433 
    434     // overridden by API-specific derived class to perform the read pixels.
    435     virtual bool onReadPixels(GrRenderTarget* target,
    436                               int left, int top, int width, int height,
    437                               GrPixelConfig,
    438                               void* buffer,
    439                               size_t rowBytes,
    440                               bool invertY) = 0;
    441 
    442     // overridden by API-specific derived class to perform the texture update
    443     virtual void onWriteTexturePixels(GrTexture* texture,
    444                                       int left, int top, int width, int height,
    445                                       GrPixelConfig config, const void* buffer,
    446                                       size_t rowBytes) = 0;
    447 
    448     // overridden by API-specific derived class to perform the resolve
    449     virtual void onResolveRenderTarget(GrRenderTarget* target) = 0;
    450 
    451     // called to program the vertex data, indexCount will be 0 if drawing non-
    452     // indexed geometry. The subclass may adjust the startVertex and/or
    453     // startIndex since it may have already accounted for these in the setup.
    454     virtual void setupGeometry(int* startVertex,
    455                                int* startIndex,
    456                                int vertexCount,
    457                                int indexCount) = 0;
    458 
    459     // width and height may be larger than rt (if underlying API allows it).
    460     // Should attach the SB to the RT. Returns false if compatible sb could
    461     // not be created.
    462     virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt,
    463                                                     int width,
    464                                                     int height) = 0;
    465 
    466     // attaches an existing SB to an existing RT.
    467     virtual bool attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
    468                                                    GrRenderTarget* rt) = 0;
    469 
    470     // The GrGpu typically records the clients requested state and then flushes
    471     // deltas from previous state at draw time. This function does the
    472     // API-specific flush of the state
    473     // returns false if current state is unsupported.
    474     virtual bool flushGraphicsState(GrPrimitiveType type) = 0;
    475 
    476     // Sets the scissor rect, or disables if rect is NULL.
    477     virtual void flushScissor(const GrIRect* rect) = 0;
    478 
    479     // GrGpu subclass sets clip bit in the stencil buffer. The subclass is
    480     // free to clear the remaining bits to zero if masked clears are more
    481     // expensive than clearing all bits.
    482     virtual void clearStencilClip(const GrIRect& rect, bool insideClip) = 0;
    483 
    484     // clears the entire stencil buffer to 0
    485     virtual void clearStencil() = 0;
    486 
    487 private:
    488     GrContext*                  fContext; // not reffed (context refs gpu)
    489 
    490     ResetTimestamp              fResetTimestamp;
    491 
    492     GrVertexBufferAllocPool*    fVertexPool;
    493 
    494     GrIndexBufferAllocPool*     fIndexPool;
    495 
    496     // counts number of uses of vertex/index pool in the geometry stack
    497     int                         fVertexPoolUseCnt;
    498     int                         fIndexPoolUseCnt;
    499 
    500     enum {
    501         kPreallocGeomPoolStateStackCnt = 4,
    502     };
    503     SkSTArray<kPreallocGeomPoolStateStackCnt,
    504               GeometryPoolState, true>              fGeomPoolStateStack;
    505 
    506     mutable GrIndexBuffer*      fQuadIndexBuffer; // mutable so it can be
    507                                                   // created on-demand
    508 
    509     mutable GrVertexBuffer*     fUnitSquareVertexBuffer; // mutable so it can be
    510                                                          // created on-demand
    511 
    512     // must be instantiated after GrGpu object has been given its owning
    513     // GrContext ptr. (GrGpu is constructed first then handed off to GrContext).
    514     GrPathRendererChain*        fPathRendererChain;
    515 
    516     bool                        fContextIsDirty;
    517 
    518     GrResource*                 fResourceHead;
    519 
    520     // Given a rt, find or create a stencil buffer and attach it
    521     bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
    522 
    523     // GrDrawTarget overrides
    524     virtual void onDrawIndexed(GrPrimitiveType type,
    525                                int startVertex,
    526                                int startIndex,
    527                                int vertexCount,
    528                                int indexCount);
    529     virtual void onDrawNonIndexed(GrPrimitiveType type,
    530                                   int startVertex,
    531                                   int vertexCount);
    532 
    533     // readies the pools to provide vertex/index data.
    534     void prepareVertexPool();
    535     void prepareIndexPool();
    536 
    537     // determines the path renderer used to draw a clip path element.
    538     GrPathRenderer* getClipPathRenderer(const SkPath& path, GrPathFill fill);
    539 
    540     void resetContext() {
    541         this->onResetContext();
    542         ++fResetTimestamp;
    543     }
    544 
    545     void handleDirtyContext() {
    546         if (fContextIsDirty) {
    547             this->resetContext();
    548             fContextIsDirty = false;
    549         }
    550     }
    551 
    552     typedef GrDrawTarget INHERITED;
    553 };
    554 
    555 #endif
    556