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 findAndRefTByUniqueKey(const GrUniqueKey & key)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 */ findOrCreateInstancedIndexBuffer(const uint16_t * pattern,int patternSize,int reps,int vertCount,const GrUniqueKey & key)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 */ refQuadIndexBuffer()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 createApproxTexture(const GrSurfaceDesc & desc,uint32_t flags)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 caps()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