Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2015 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 GrResourceProvider_DEFINED
      9 #define GrResourceProvider_DEFINED
     10 
     11 #include "GrBatchAtlas.h"
     12 #include "GrIndexBuffer.h"
     13 #include "GrTextureProvider.h"
     14 #include "GrPathRange.h"
     15 
     16 class GrBatchAtlas;
     17 class GrIndexBuffer;
     18 class GrPath;
     19 class GrRenderTarget;
     20 class GrSingleOwner;
     21 class GrStencilAttachment;
     22 class GrStrokeInfo;
     23 class GrVertexBuffer;
     24 class SkDescriptor;
     25 class SkPath;
     26 class SkTypeface;
     27 
     28 /**
     29  * An extension of the texture provider for arbitrary resource types. This class is intended for
     30  * use within the Gr code base, not by clients or extensions (e.g. third party GrProcessor
     31  * derivatives).
     32  *
     33  * This currently inherits from GrTextureProvider non-publically to force callers to provider
     34  * make a flags (pendingIO) decision and not use the GrTP methods that don't take flags. This
     35  * can be relaxed once https://bug.skia.org/4156 is fixed.
     36  */
     37 class GrResourceProvider : protected GrTextureProvider {
     38 public:
     39     GrResourceProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* owner);
     40 
     41     template <typename T> T* findAndRefTByUniqueKey(const GrUniqueKey& key) {
     42         return static_cast<T*>(this->findAndRefResourceByUniqueKey(key));
     43     }
     44 
     45     /**
     46      * Either finds and refs, or creates an index buffer for instanced drawing with a specific
     47      * pattern if the index buffer is not found. If the return is non-null, the caller owns
     48      * a ref on the returned GrIndexBuffer.
     49      *
     50      * @param pattern     the pattern of indices to repeat
     51      * @param patternSize size in bytes of the pattern
     52      * @param reps        number of times to repeat the pattern
     53      * @param vertCount   number of vertices the pattern references
     54      * @param key         Key to be assigned to the index buffer.
     55      *
     56      * @return The index buffer if successful, otherwise nullptr.
     57      */
     58     const GrIndexBuffer* findOrCreateInstancedIndexBuffer(const uint16_t* pattern,
     59                                                           int patternSize,
     60                                                           int reps,
     61                                                           int vertCount,
     62                                                           const GrUniqueKey& key) {
     63         if (GrIndexBuffer* buffer = this->findAndRefTByUniqueKey<GrIndexBuffer>(key)) {
     64             return buffer;
     65         }
     66         return this->createInstancedIndexBuffer(pattern, patternSize, reps, vertCount, key);
     67     }
     68 
     69     /**
     70      * Returns an index buffer that can be used to render quads.
     71      * Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
     72      * The max number of quads can be queried using GrIndexBuffer::maxQuads().
     73      * Draw with kTriangles_GrPrimitiveType
     74      * @ return the quad index buffer
     75      */
     76     const GrIndexBuffer* refQuadIndexBuffer() {
     77         if (GrIndexBuffer* buffer =
     78             this->findAndRefTByUniqueKey<GrIndexBuffer>(fQuadIndexBufferKey)) {
     79             return buffer;
     80         }
     81         return this->createQuadIndexBuffer();
     82     }
     83 
     84     /**
     85      * Factories for GrPath and GrPathRange objects. It's an error to call these if path rendering
     86      * is not supported.
     87      */
     88     GrPath* createPath(const SkPath&, const GrStrokeInfo&);
     89     GrPathRange* createPathRange(GrPathRange::PathGenerator*, const GrStrokeInfo&);
     90     GrPathRange* createGlyphs(const SkTypeface*, const SkDescriptor*, const GrStrokeInfo&);
     91 
     92     using GrTextureProvider::assignUniqueKeyToResource;
     93     using GrTextureProvider::findAndRefResourceByUniqueKey;
     94     using GrTextureProvider::findAndRefTextureByUniqueKey;
     95     using GrTextureProvider::abandon;
     96 
     97     enum Flags {
     98         /** If the caller intends to do direct reads/writes to/from the CPU then this flag must be
     99          *  set when accessing resources during a GrDrawTarget flush. This includes the execution of
    100          *  GrBatch objects. The reason is that these memory operations are done immediately and
    101          *  will occur out of order WRT the operations being flushed.
    102          *  Make this automatic: https://bug.skia.org/4156
    103          */
    104         kNoPendingIO_Flag = kNoPendingIO_ScratchTextureFlag,
    105     };
    106 
    107     enum BufferUsage {
    108         /** Caller intends to specify the buffer data rarely with respect to the number of draws
    109             that read the data. */
    110         kStatic_BufferUsage,
    111         /** Caller intends to respecify the buffer data frequently between draws. */
    112         kDynamic_BufferUsage,
    113     };
    114     GrIndexBuffer* createIndexBuffer(size_t size, BufferUsage, uint32_t flags);
    115     GrVertexBuffer* createVertexBuffer(size_t size, BufferUsage, uint32_t flags);
    116     GrTransferBuffer* createTransferBuffer(size_t size, TransferType, uint32_t flags);
    117 
    118     GrTexture* createApproxTexture(const GrSurfaceDesc& desc, uint32_t flags) {
    119         SkASSERT(0 == flags || kNoPendingIO_Flag == flags);
    120         return this->internalCreateApproxTexture(desc, flags);
    121     }
    122 
    123     /**  Returns a GrBatchAtlas. This function can be called anywhere, but the returned atlas should
    124      *   only be used inside of GrBatch::generateGeometry
    125      *   @param GrPixelConfig    The pixel config which this atlas will store
    126      *   @param width            width in pixels of the atlas
    127      *   @param height           height in pixels of the atlas
    128      *   @param numPlotsX        The number of plots the atlas should be broken up into in the X
    129      *                           direction
    130      *   @param numPlotsY        The number of plots the atlas should be broken up into in the Y
    131      *                           direction
    132      *   @param func             An eviction function which will be called whenever the atlas has to
    133      *                           evict data
    134      *   @param data             User supplied data which will be passed into func whenver an
    135      *                           eviction occurs
    136      *
    137      *   @return                 An initialized GrBatchAtlas, or nullptr if creation fails
    138      */
    139     GrBatchAtlas* createAtlas(GrPixelConfig, int width, int height, int numPlotsX, int numPlotsY,
    140                               GrBatchAtlas::EvictionFunc func, void* data);
    141 
    142     /**
    143      * If passed in render target already has a stencil buffer, return it. Otherwise attempt to
    144      * attach one.
    145      */
    146     GrStencilAttachment* attachStencilAttachment(GrRenderTarget* rt);
    147 
    148     const GrCaps* caps() { return this->gpu()->caps(); }
    149 
    150      /**
    151       * Wraps an existing texture with a GrRenderTarget object. This is useful when the provided
    152       * texture has a format that cannot be textured from by Skia, but we want to raster to it.
    153       *
    154       * @return GrRenderTarget object or NULL on failure.
    155       */
    156      GrRenderTarget* wrapBackendTextureAsRenderTarget(const GrBackendTextureDesc& desc,
    157                                                       GrWrapOwnership = kBorrow_GrWrapOwnership);
    158 
    159 private:
    160     const GrIndexBuffer* createInstancedIndexBuffer(const uint16_t* pattern,
    161                                                     int patternSize,
    162                                                     int reps,
    163                                                     int vertCount,
    164                                                     const GrUniqueKey& key);
    165 
    166     const GrIndexBuffer* createQuadIndexBuffer();
    167 
    168     GrUniqueKey fQuadIndexBufferKey;
    169 
    170     typedef GrTextureProvider INHERITED;
    171 };
    172 
    173 #endif
    174