Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef GrGpu_DEFINED
      9 #define GrGpu_DEFINED
     10 
     11 #include "GrDrawTarget.h"
     12 #include "GrRefCnt.h"
     13 #include "GrClipMaskManager.h"
     14 #include "SkPath.h"
     15 
     16 class GrContext;
     17 class GrIndexBufferAllocPool;
     18 class GrPath;
     19 class GrPathRenderer;
     20 class GrPathRendererChain;
     21 class GrResource;
     22 class GrStencilBuffer;
     23 class GrVertexBufferAllocPool;
     24 
     25 class GrGpu : public GrDrawTarget {
     26 public:
     27 
     28     /**
     29      * Additional blend coefficients for dual source blending, not exposed
     30      * through GrPaint/GrContext.
     31      */
     32     enum ExtendedBlendCoeffs {
     33         // source 2 refers to second output color when
     34         // using dual source blending.
     35         kS2C_GrBlendCoeff = kPublicGrBlendCoeffCount,
     36         kIS2C_GrBlendCoeff,
     37         kS2A_GrBlendCoeff,
     38         kIS2A_GrBlendCoeff,
     39 
     40         kTotalGrBlendCoeffCount
     41     };
     42 
     43     /**
     44      * Create an instance of GrGpu that matches the specified backend. If the requested backend is
     45      * not supported (at compile-time or run-time) this returns NULL. The context will not be
     46      * fully constructed and should not be used by GrGpu until after this function returns.
     47      */
     48     static GrGpu* Create(GrBackend, GrBackendContext, GrContext* context);
     49 
     50     ////////////////////////////////////////////////////////////////////////////
     51 
     52     GrGpu(GrContext* context);
     53     virtual ~GrGpu();
     54 
     55     GrContext* getContext() { return this->INHERITED::getContext(); }
     56     const GrContext* getContext() const { return this->INHERITED::getContext(); }
     57 
     58     /**
     59      * The GrGpu object normally assumes that no outsider is setting state
     60      * within the underlying 3D API's context/device/whatever. This call informs
     61      * the GrGpu that the state was modified and it shouldn't make assumptions
     62      * about the state.
     63      */
     64     void markContextDirty(uint32_t state = kAll_GrBackendState) {
     65         fResetBits |= state;
     66     }
     67 
     68     void unimpl(const char[]);
     69 
     70     /**
     71      * Creates a texture object. If desc width or height is not a power of
     72      * two but underlying API requires a power of two texture then srcData
     73      * will be embedded in a power of two texture. The extra width and height
     74      * is filled as though srcData were rendered clamped into the texture.
     75      *
     76      * If kRenderTarget_TextureFlag is specified the GrRenderTarget is
     77      * accessible via GrTexture::asRenderTarget(). The texture will hold a ref
     78      * on the render target until the texture is destroyed.
     79      *
     80      * @param desc        describes the texture to be created.
     81      * @param srcData     texel data to load texture. Begins with full-size
     82      *                    palette data for paletted textures. Contains width*
     83      *                    height texels. If NULL texture data is uninitialized.
     84      *
     85      * @return    The texture object if successful, otherwise NULL.
     86      */
     87     GrTexture* createTexture(const GrTextureDesc& desc,
     88                              const void* srcData, size_t rowBytes);
     89 
     90     /**
     91      * Implements GrContext::wrapBackendTexture
     92      */
     93     GrTexture* wrapBackendTexture(const GrBackendTextureDesc&);
     94 
     95     /**
     96      * Implements GrContext::wrapBackendTexture
     97      */
     98     GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc&);
     99 
    100     /**
    101      * Creates a vertex buffer.
    102      *
    103      * @param size    size in bytes of the vertex buffer
    104      * @param dynamic hints whether the data will be frequently changed
    105      *                by either GrVertexBuffer::lock or
    106      *                GrVertexBuffer::updateData.
    107      *
    108      * @return    The vertex buffer if successful, otherwise NULL.
    109      */
    110     GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);
    111 
    112     /**
    113      * Creates an index buffer.
    114      *
    115      * @param size    size in bytes of the index buffer
    116      * @param dynamic hints whether the data will be frequently changed
    117      *                by either GrIndexBuffer::lock or
    118      *                GrIndexBuffer::updateData.
    119      *
    120      * @return The index buffer if successful, otherwise NULL.
    121      */
    122     GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
    123 
    124     /**
    125      * Creates a path object that can be stenciled using stencilPath(). It is
    126      * only legal to call this if the caps report support for path stenciling.
    127      */
    128     GrPath* createPath(const SkPath& path);
    129 
    130     /**
    131      * Returns an index buffer that can be used to render quads.
    132      * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
    133      * The max number of quads can be queried using GrIndexBuffer::maxQuads().
    134      * Draw with kTriangles_GrPrimitiveType
    135      * @ return the quad index buffer
    136      */
    137     const GrIndexBuffer* getQuadIndexBuffer() const;
    138 
    139     /**
    140      * Resolves MSAA.
    141      */
    142     void resolveRenderTarget(GrRenderTarget* target);
    143 
    144     /**
    145      * Ensures that the current render target is actually set in the
    146      * underlying 3D API. Used when client wants to use 3D API to directly
    147      * render to the RT.
    148      */
    149     void forceRenderTargetFlush();
    150 
    151     /**
    152      * Gets a preferred 8888 config to use for writing/reading pixel data to/from a surface with
    153      * config surfaceConfig. The returned config must have at least as many bits per channel as the
    154      * readConfig or writeConfig param.
    155      */
    156     virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig readConfig,
    157                                                     GrPixelConfig surfaceConfig) const {
    158         return readConfig;
    159     }
    160     virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig,
    161                                                      GrPixelConfig surfaceConfig) const {
    162         return writeConfig;
    163     }
    164 
    165     /**
    166      * Called before uploading writing pixels to a GrTexture when the src pixel config doesn't
    167      * match the texture's config.
    168      */
    169     virtual bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const = 0;
    170 
    171     /**
    172      * OpenGL's readPixels returns the result bottom-to-top while the skia
    173      * API is top-to-bottom. Thus we have to do a y-axis flip. The obvious
    174      * solution is to have the subclass do the flip using either the CPU or GPU.
    175      * However, the caller (GrContext) may have transformations to apply and can
    176      * simply fold in the y-flip for free. On the other hand, the subclass may
    177      * be able to do it for free itself. For example, the subclass may have to
    178      * do memcpys to handle rowBytes that aren't tight. It could do the y-flip
    179      * concurrently.
    180      *
    181      * This function returns true if a y-flip is required to put the pixels in
    182      * top-to-bottom order and the subclass cannot do it for free.
    183      *
    184      * See read pixels for the params
    185      * @return true if calling readPixels with the same set of params will
    186      *              produce bottom-to-top data
    187      */
    188      virtual bool readPixelsWillPayForYFlip(GrRenderTarget* renderTarget,
    189                                             int left, int top,
    190                                             int width, int height,
    191                                             GrPixelConfig config,
    192                                             size_t rowBytes) const = 0;
    193      /**
    194       * This should return true if reading a NxM rectangle of pixels from a
    195       * render target is faster if the target has dimensons N and M and the read
    196       * rectangle has its top-left at 0,0.
    197       */
    198      virtual bool fullReadPixelsIsFasterThanPartial() const { return false; };
    199 
    200     /**
    201      * Reads a rectangle of pixels from a render target.
    202      *
    203      * @param renderTarget  the render target to read from. NULL means the
    204      *                      current render target.
    205      * @param left          left edge of the rectangle to read (inclusive)
    206      * @param top           top edge of the rectangle to read (inclusive)
    207      * @param width         width of rectangle to read in pixels.
    208      * @param height        height of rectangle to read in pixels.
    209      * @param config        the pixel config of the destination buffer
    210      * @param buffer        memory to read the rectangle into.
    211      * @param rowBytes      the number of bytes between consecutive rows. Zero
    212      *                      means rows are tightly packed.
    213      * @param invertY       buffer should be populated bottom-to-top as opposed
    214      *                      to top-to-bottom (skia's usual order)
    215      *
    216      * @return true if the read succeeded, false if not. The read can fail
    217      *              because of a unsupported pixel config or because no render
    218      *              target is currently set.
    219      */
    220     bool readPixels(GrRenderTarget* renderTarget,
    221                     int left, int top, int width, int height,
    222                     GrPixelConfig config, void* buffer, size_t rowBytes);
    223 
    224     /**
    225      * Updates the pixels in a rectangle of a texture.
    226      *
    227      * @param left          left edge of the rectangle to write (inclusive)
    228      * @param top           top edge of the rectangle to write (inclusive)
    229      * @param width         width of rectangle to write in pixels.
    230      * @param height        height of rectangle to write in pixels.
    231      * @param config        the pixel config of the source buffer
    232      * @param buffer        memory to read pixels from
    233      * @param rowBytes      number of bytes between consecutive rows. Zero
    234      *                      means rows are tightly packed.
    235      */
    236     bool writeTexturePixels(GrTexture* texture,
    237                             int left, int top, int width, int height,
    238                             GrPixelConfig config, const void* buffer,
    239                             size_t rowBytes);
    240 
    241     /**
    242      * Called to tell Gpu object that all GrResources have been lost and should
    243      * be abandoned. Overrides must call INHERITED::abandonResources().
    244      */
    245     virtual void abandonResources();
    246 
    247     /**
    248      * Called to tell Gpu object to release all GrResources. Overrides must call
    249      * INHERITED::releaseResources().
    250      */
    251     void releaseResources();
    252 
    253     /**
    254      * Add resource to list of resources. Should only be called by GrResource.
    255      * @param resource  the resource to add.
    256      */
    257     void insertResource(GrResource* resource);
    258 
    259     /**
    260      * Remove resource from list of resources. Should only be called by
    261      * GrResource.
    262      * @param resource  the resource to remove.
    263      */
    264     void removeResource(GrResource* resource);
    265 
    266     // GrDrawTarget overrides
    267     virtual void clear(const SkIRect* rect,
    268                        GrColor color,
    269                        GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
    270 
    271     virtual void purgeResources() SK_OVERRIDE {
    272         // The clip mask manager can rebuild all its clip masks so just
    273         // get rid of them all.
    274         fClipMaskManager.releaseResources();
    275     }
    276 
    277     // After the client interacts directly with the 3D context state the GrGpu
    278     // must resync its internal state and assumptions about 3D context state.
    279     // Each time this occurs the GrGpu bumps a timestamp.
    280     // state of the 3D context
    281     // At 10 resets / frame and 60fps a 64bit timestamp will overflow in about
    282     // a billion years.
    283     typedef uint64_t ResetTimestamp;
    284 
    285     // This timestamp is always older than the current timestamp
    286     static const ResetTimestamp kExpiredTimestamp = 0;
    287     // Returns a timestamp based on the number of times the context was reset.
    288     // This timestamp can be used to lazily detect when cached 3D context state
    289     // is dirty.
    290     ResetTimestamp getResetTimestamp() const {
    291         return fResetTimestamp;
    292     }
    293 
    294     /**
    295      * Can the provided configuration act as a color render target?
    296      */
    297     bool isConfigRenderable(GrPixelConfig config) const {
    298         GrAssert(kGrPixelConfigCnt > config);
    299         return fConfigRenderSupport[config];
    300     }
    301 
    302     /**
    303      * These methods are called by the clip manager's setupClipping function
    304      * which (called as part of GrGpu's implementation of onDraw and
    305      * onStencilPath member functions.) The GrGpu subclass should flush the
    306      * stencil state to the 3D API in its implementation of flushGraphicsState.
    307      */
    308     void enableScissor(const SkIRect& rect) {
    309         fScissorState.fEnabled = true;
    310         fScissorState.fRect = rect;
    311     }
    312     void disableScissor() { fScissorState.fEnabled = false; }
    313 
    314     /**
    315      * Like the scissor methods above this is called by setupClipping and
    316      * should be flushed by the GrGpu subclass in flushGraphicsState. These
    317      * stencil settings should be used in place of those on the GrDrawState.
    318      * They have been adjusted to account for any interactions between the
    319      * GrDrawState's stencil settings and stencil clipping.
    320      */
    321     void setStencilSettings(const GrStencilSettings& settings) {
    322         fStencilSettings = settings;
    323     }
    324     void disableStencil() { fStencilSettings.setDisabled(); }
    325 
    326     // GrGpu subclass sets clip bit in the stencil buffer. The subclass is
    327     // free to clear the remaining bits to zero if masked clears are more
    328     // expensive than clearing all bits.
    329     virtual void clearStencilClip(const SkIRect& rect, bool insideClip) = 0;
    330 
    331     enum PrivateDrawStateStateBits {
    332         kFirstBit = (GrDrawState::kLastPublicStateBit << 1),
    333 
    334         kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
    335                                                  // stencil bits used for
    336                                                  // clipping.
    337     };
    338 
    339 protected:
    340     enum DrawType {
    341         kDrawPoints_DrawType,
    342         kDrawLines_DrawType,
    343         kDrawTriangles_DrawType,
    344         kStencilPath_DrawType,
    345     };
    346 
    347     DrawType PrimTypeToDrawType(GrPrimitiveType type) {
    348         switch (type) {
    349             case kTriangles_GrPrimitiveType:
    350             case kTriangleStrip_GrPrimitiveType:
    351             case kTriangleFan_GrPrimitiveType:
    352                 return kDrawTriangles_DrawType;
    353             case kPoints_GrPrimitiveType:
    354                 return kDrawPoints_DrawType;
    355             case kLines_GrPrimitiveType:
    356             case kLineStrip_GrPrimitiveType:
    357                 return kDrawLines_DrawType;
    358             default:
    359                 GrCrash("Unexpected primitive type");
    360                 return kDrawTriangles_DrawType;
    361         }
    362     }
    363 
    364     // prepares clip flushes gpu state before a draw
    365     bool setupClipAndFlushState(DrawType,
    366                                 const GrDeviceCoordTexture* dstCopy,
    367                                 GrDrawState::AutoRestoreEffects* are);
    368 
    369     // Functions used to map clip-respecting stencil tests into normal
    370     // stencil funcs supported by GPUs.
    371     static GrStencilFunc ConvertStencilFunc(bool stencilInClip,
    372                                             GrStencilFunc func);
    373     static void ConvertStencilFuncAndMask(GrStencilFunc func,
    374                                           bool clipInStencil,
    375                                           unsigned int clipBit,
    376                                           unsigned int userBits,
    377                                           unsigned int* ref,
    378                                           unsigned int* mask);
    379 
    380     GrClipMaskManager           fClipMaskManager;
    381 
    382     struct GeometryPoolState {
    383         const GrVertexBuffer* fPoolVertexBuffer;
    384         int                   fPoolStartVertex;
    385 
    386         const GrIndexBuffer*  fPoolIndexBuffer;
    387         int                   fPoolStartIndex;
    388     };
    389     const GeometryPoolState& getGeomPoolState() {
    390         return fGeomPoolStateStack.back();
    391     }
    392 
    393     // The state of the scissor is controlled by the clip manager
    394     struct ScissorState {
    395         bool    fEnabled;
    396         SkIRect fRect;
    397     } fScissorState;
    398 
    399     // The final stencil settings to use as determined by the clip manager.
    400     GrStencilSettings fStencilSettings;
    401 
    402     // Derived classes need access to this so they can fill it out in their
    403     // constructors
    404     bool    fConfigRenderSupport[kGrPixelConfigCnt];
    405 
    406     // Helpers for setting up geometry state
    407     void finalizeReservedVertices();
    408     void finalizeReservedIndices();
    409 
    410 private:
    411     // GrDrawTarget overrides
    412     virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) SK_OVERRIDE;
    413     virtual bool onReserveIndexSpace(int indexCount, void** indices) SK_OVERRIDE;
    414     virtual void releaseReservedVertexSpace() SK_OVERRIDE;
    415     virtual void releaseReservedIndexSpace() SK_OVERRIDE;
    416     virtual void onSetVertexSourceToArray(const void* vertexArray, int vertexCount) SK_OVERRIDE;
    417     virtual void onSetIndexSourceToArray(const void* indexArray, int indexCount) SK_OVERRIDE;
    418     virtual void releaseVertexArray() SK_OVERRIDE;
    419     virtual void releaseIndexArray() SK_OVERRIDE;
    420     virtual void geometrySourceWillPush() SK_OVERRIDE;
    421     virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE;
    422 
    423 
    424     // called when the 3D context state is unknown. Subclass should emit any
    425     // assumed 3D context state and dirty any state cache.
    426     virtual void onResetContext(uint32_t resetBits) = 0;
    427 
    428     // overridden by backend-specific derived class to create objects.
    429     virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
    430                                        const void* srcData,
    431                                        size_t rowBytes) = 0;
    432     virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) = 0;
    433     virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) = 0;
    434     virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size, bool dynamic) = 0;
    435     virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size, bool dynamic) = 0;
    436     virtual GrPath* onCreatePath(const SkPath& path) = 0;
    437 
    438     // overridden by backend-specific derived class to perform the clear and
    439     // clearRect. NULL rect means clear whole target.
    440     virtual void onClear(const SkIRect* rect, GrColor color) = 0;
    441 
    442     // overridden by backend-specific derived class to perform the draw call.
    443     virtual void onGpuDraw(const DrawInfo&) = 0;
    444     // when GrDrawTarget::stencilPath is called the draw state's current stencil
    445     // settings are ignored. Instead the GrGpu decides the stencil rules
    446     // necessary to stencil the path. These are still subject to filtering by
    447     // the clip mask manager.
    448     virtual void setStencilPathSettings(const GrPath&,
    449                                         SkPath::FillType,
    450                                         GrStencilSettings* settings) = 0;
    451     // overridden by backend-specific derived class to perform the path stenciling.
    452     virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) = 0;
    453 
    454     // overridden by backend-specific derived class to perform flush
    455     virtual void onForceRenderTargetFlush() = 0;
    456 
    457     // overridden by backend-specific derived class to perform the read pixels.
    458     virtual bool onReadPixels(GrRenderTarget* target,
    459                               int left, int top, int width, int height,
    460                               GrPixelConfig,
    461                               void* buffer,
    462                               size_t rowBytes) = 0;
    463 
    464     // overridden by backend-specific derived class to perform the texture update
    465     virtual bool onWriteTexturePixels(GrTexture* texture,
    466                                       int left, int top, int width, int height,
    467                                       GrPixelConfig config, const void* buffer,
    468                                       size_t rowBytes) = 0;
    469 
    470     // overridden by backend-specific derived class to perform the resolve
    471     virtual void onResolveRenderTarget(GrRenderTarget* target) = 0;
    472 
    473     // width and height may be larger than rt (if underlying API allows it).
    474     // Should attach the SB to the RT. Returns false if compatible sb could
    475     // not be created.
    476     virtual bool createStencilBufferForRenderTarget(GrRenderTarget*, int width, int height) = 0;
    477 
    478     // attaches an existing SB to an existing RT.
    479     virtual bool attachStencilBufferToRenderTarget(GrStencilBuffer*, GrRenderTarget*) = 0;
    480 
    481     // The GrGpu typically records the clients requested state and then flushes
    482     // deltas from previous state at draw time. This function does the
    483     // backend-specific flush of the state.
    484     // returns false if current state is unsupported.
    485     virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) = 0;
    486 
    487     // clears the entire stencil buffer to 0
    488     virtual void clearStencil() = 0;
    489 
    490     // Given a rt, find or create a stencil buffer and attach it
    491     bool attachStencilBufferToRenderTarget(GrRenderTarget* target);
    492 
    493     // GrDrawTarget overrides
    494     virtual void onDraw(const DrawInfo&) SK_OVERRIDE;
    495     virtual void onStencilPath(const GrPath* path, const SkStrokeRec& stroke,
    496                                SkPath::FillType) SK_OVERRIDE;
    497 
    498     // readies the pools to provide vertex/index data.
    499     void prepareVertexPool();
    500     void prepareIndexPool();
    501 
    502     void resetContext() {
    503         // We call this because the client may have messed with the
    504         // stencil buffer. Perhaps we should detect whether it is a
    505         // internally created stencil buffer and if so skip the invalidate.
    506         fClipMaskManager.invalidateStencilMask();
    507         this->onResetContext(fResetBits);
    508         fResetBits = 0;
    509         ++fResetTimestamp;
    510     }
    511 
    512     void handleDirtyContext() {
    513         if (fResetBits) {
    514             this->resetContext();
    515         }
    516     }
    517 
    518     enum {
    519         kPreallocGeomPoolStateStackCnt = 4,
    520     };
    521     typedef SkTInternalLList<GrResource> ResourceList;
    522     SkSTArray<kPreallocGeomPoolStateStackCnt, GeometryPoolState, true>  fGeomPoolStateStack;
    523     ResetTimestamp                                                      fResetTimestamp;
    524     uint32_t                                                            fResetBits;
    525     GrVertexBufferAllocPool*                                            fVertexPool;
    526     GrIndexBufferAllocPool*                                             fIndexPool;
    527     // counts number of uses of vertex/index pool in the geometry stack
    528     int                                                                 fVertexPoolUseCnt;
    529     int                                                                 fIndexPoolUseCnt;
    530     // these are mutable so they can be created on-demand
    531     mutable GrIndexBuffer*                                              fQuadIndexBuffer;
    532     // Used to abandon/release all resources created by this GrGpu. TODO: Move this
    533     // functionality to GrResourceCache.
    534     ResourceList                                                        fResourceList;
    535 
    536     typedef GrDrawTarget INHERITED;
    537 };
    538 
    539 #endif
    540