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 "GrBuffer.h" 12 #include "GrGpu.h" 13 #include "GrPathRange.h" 14 15 class GrPath; 16 class GrRenderTarget; 17 class GrSingleOwner; 18 class GrStencilAttachment; 19 class GrStyle; 20 class SkDescriptor; 21 class SkPath; 22 class SkTypeface; 23 24 /** 25 * A factory for arbitrary resource types. This class is intended for use within the Gr code base. 26 * 27 * Some members force callers to make a flags (pendingIO) decision. This can be relaxed once 28 * https://bug.skia.org/4156 is fixed. 29 */ 30 class GrResourceProvider { 31 public: 32 GrResourceProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* owner); 33 findAndRefTByUniqueKey(const GrUniqueKey & key)34 template <typename T> T* findAndRefTByUniqueKey(const GrUniqueKey& key) { 35 return static_cast<T*>(this->findAndRefResourceByUniqueKey(key)); 36 } 37 38 /////////////////////////////////////////////////////////////////////////// 39 // Textures 40 41 /** 42 * Creates a new texture in the resource cache and returns it. The caller owns a 43 * ref on the returned texture which must be balanced by a call to unref. 44 * 45 * @param desc Description of the texture properties. 46 * @param budgeted Does the texture count against the resource cache budget? 47 * @param texels A contiguous array of mipmap levels 48 * @param mipLevelCount The amount of elements in the texels array 49 */ 50 GrTexture* createMipMappedTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, 51 const GrMipLevel* texels, int mipLevelCount, 52 uint32_t flags = 0, 53 SkDestinationSurfaceColorMode mipColorMode = 54 SkDestinationSurfaceColorMode::kLegacy); 55 56 /** 57 * This function is a shim which creates a SkTArray<GrMipLevel> of size 1. 58 * It then calls createTexture with that SkTArray. 59 * 60 * @param srcData Pointer to the pixel values (optional). 61 * @param rowBytes The number of bytes between rows of the texture. Zero 62 * implies tightly packed rows. For compressed pixel configs, this 63 * field is ignored. 64 */ 65 GrTexture* createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, const void* srcData, 66 size_t rowBytes, uint32_t flags = 0); 67 68 /** Shortcut for creating a texture with no initial data to upload. */ 69 GrTexture* createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, uint32_t flags = 0) { 70 return this->createTexture(desc, budgeted, nullptr, 0, flags); 71 } 72 73 /** Assigns a unique key to the texture. The texture will be findable via this key using 74 findTextureByUniqueKey(). If an existing texture has this key, it's key will be removed. */ 75 void assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy*); 76 77 /** Finds a texture by unique key. If the texture is found it is ref'ed and returned. */ 78 sk_sp<GrTextureProxy> findProxyByUniqueKey(const GrUniqueKey& key); 79 80 /** 81 * Finds a texture that approximately matches the descriptor. Will be at least as large in width 82 * and height as desc specifies. If desc specifies that the texture should be a render target 83 * then result will be a render target. Format and sample count will always match the request. 84 * The contents of the texture are undefined. The caller owns a ref on the returned texture and 85 * must balance with a call to unref. 86 */ 87 GrTexture* createApproxTexture(const GrSurfaceDesc&, uint32_t flags); 88 89 /////////////////////////////////////////////////////////////////////////// 90 // Wrapped Backend Surfaces 91 92 /** 93 * Wraps an existing texture with a GrTexture object. 94 * 95 * OpenGL: if the object is a texture Gr may change its GL texture params 96 * when it is drawn. 97 * 98 * @return GrTexture object or NULL on failure. 99 */ 100 sk_sp<GrTexture> wrapBackendTexture(const GrBackendTextureDesc& desc, 101 GrWrapOwnership = kBorrow_GrWrapOwnership); 102 103 /** 104 * Wraps an existing render target with a GrRenderTarget object. It is 105 * similar to wrapBackendTexture but can be used to draw into surfaces 106 * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that 107 * the client will resolve to a texture). Currently wrapped render targets 108 * always use the kBorrow_GrWrapOwnership semantics. 109 * 110 * @return GrRenderTarget object or NULL on failure. 111 */ 112 sk_sp<GrRenderTarget> wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc); 113 114 static const int kMinScratchTextureSize; 115 116 /** 117 * Either finds and refs, or creates an index buffer for instanced drawing with a specific 118 * pattern if the index buffer is not found. If the return is non-null, the caller owns 119 * a ref on the returned GrBuffer. 120 * 121 * @param pattern the pattern of indices to repeat 122 * @param patternSize size in bytes of the pattern 123 * @param reps number of times to repeat the pattern 124 * @param vertCount number of vertices the pattern references 125 * @param key Key to be assigned to the index buffer. 126 * 127 * @return The index buffer if successful, otherwise nullptr. 128 */ findOrCreateInstancedIndexBuffer(const uint16_t * pattern,int patternSize,int reps,int vertCount,const GrUniqueKey & key)129 const GrBuffer* findOrCreateInstancedIndexBuffer(const uint16_t* pattern, 130 int patternSize, 131 int reps, 132 int vertCount, 133 const GrUniqueKey& key) { 134 if (GrBuffer* buffer = this->findAndRefTByUniqueKey<GrBuffer>(key)) { 135 return buffer; 136 } 137 return this->createInstancedIndexBuffer(pattern, patternSize, reps, vertCount, key); 138 } 139 140 /** 141 * Returns an index buffer that can be used to render quads. 142 * Six indices per quad: 0, 1, 2, 0, 2, 3, etc. 143 * The max number of quads is the buffer's index capacity divided by 6. 144 * Draw with kTriangles_GrPrimitiveType 145 * @ return the quad index buffer 146 */ refQuadIndexBuffer()147 const GrBuffer* refQuadIndexBuffer() { 148 if (GrBuffer* buffer = 149 this->findAndRefTByUniqueKey<GrBuffer>(fQuadIndexBufferKey)) { 150 return buffer; 151 } 152 return this->createQuadIndexBuffer(); 153 } 154 155 /** 156 * Factories for GrPath and GrPathRange objects. It's an error to call these if path rendering 157 * is not supported. 158 */ 159 GrPath* createPath(const SkPath&, const GrStyle&); 160 GrPathRange* createPathRange(GrPathRange::PathGenerator*, const GrStyle&); 161 GrPathRange* createGlyphs(const SkTypeface*, const SkScalerContextEffects&, 162 const SkDescriptor*, const GrStyle&); 163 164 /** These flags govern which scratch resources we are allowed to return */ 165 enum Flags { 166 kExact_Flag = 0x1, 167 168 /** If the caller intends to do direct reads/writes to/from the CPU then this flag must be 169 * set when accessing resources during a GrOpList flush. This includes the execution of 170 * GrOp objects. The reason is that these memory operations are done immediately and 171 * will occur out of order WRT the operations being flushed. 172 * Make this automatic: https://bug.skia.org/4156 173 */ 174 kNoPendingIO_Flag = 0x2, 175 176 kNoCreate_Flag = 0x4, 177 178 /** Normally the caps may indicate a preference for client-side buffers. Set this flag when 179 * creating a buffer to guarantee it resides in GPU memory. 180 */ 181 kRequireGpuMemory_Flag = 0x8, 182 }; 183 184 /** 185 * Returns a buffer. 186 * 187 * @param size minimum size of buffer to return. 188 * @param intendedType hint to the graphics subsystem about what the buffer will be used for. 189 * @param GrAccessPattern hint to the graphics subsystem about how the data will be accessed. 190 * @param flags see Flags enum. 191 * @param data optional data with which to initialize the buffer. 192 * 193 * @return the buffer if successful, otherwise nullptr. 194 */ 195 GrBuffer* createBuffer(size_t size, GrBufferType intendedType, GrAccessPattern, uint32_t flags, 196 const void* data = nullptr); 197 198 199 /** 200 * If passed in render target already has a stencil buffer, return it. Otherwise attempt to 201 * attach one. 202 */ 203 GrStencilAttachment* attachStencilAttachment(GrRenderTarget* rt); 204 205 /** 206 * Wraps an existing texture with a GrRenderTarget object. This is useful when the provided 207 * texture has a format that cannot be textured from by Skia, but we want to raster to it. 208 * 209 * The texture is wrapped as borrowed. The texture object will not be freed once the 210 * render target is destroyed. 211 * 212 * @return GrRenderTarget object or NULL on failure. 213 */ 214 sk_sp<GrRenderTarget> wrapBackendTextureAsRenderTarget(const GrBackendTextureDesc& desc); 215 216 /** 217 * Assigns a unique key to a resource. If the key is associated with another resource that 218 * association is removed and replaced by this resource. 219 */ 220 void assignUniqueKeyToResource(const GrUniqueKey&, GrGpuResource*); 221 222 /** 223 * Finds a resource in the cache, based on the specified key. This is intended for use in 224 * conjunction with addResourceToCache(). The return value will be NULL if not found. The 225 * caller must balance with a call to unref(). 226 */ 227 GrGpuResource* findAndRefResourceByUniqueKey(const GrUniqueKey&); 228 229 sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(); 230 231 // Takes the GrSemaphore and sets the ownership of the semaphore to the GrGpu object used by 232 // this class. This call is only used when passing a GrSemaphore from one context to another. 233 void takeOwnershipOfSemaphore(sk_sp<GrSemaphore>); 234 // Takes the GrSemaphore and resets the ownership of the semaphore so that it is not owned by 235 // any GrGpu. A follow up call to takeOwnershipofSemaphore must be made so that the underlying 236 // semaphore can be deleted. This call is only used when passing a GrSemaphore from one context 237 // to another. 238 void releaseOwnershipOfSemaphore(sk_sp<GrSemaphore>); 239 abandon()240 void abandon() { 241 fCache = nullptr; 242 fGpu = nullptr; 243 } 244 245 // 'Proxy' is about to be used as a texture src. This query can be used to determine if 246 // it is going to need a texture domain. 247 static bool IsFunctionallyExact(GrTextureProxy* proxy); 248 caps()249 const GrCaps* caps() const { return fCaps.get(); } 250 251 private: 252 GrTexture* internalCreateApproxTexture(const GrSurfaceDesc& desc, uint32_t scratchTextureFlags); 253 254 GrTexture* findAndRefTextureByUniqueKey(const GrUniqueKey& key); assignUniqueKeyToTexture(const GrUniqueKey & key,GrTexture * texture)255 void assignUniqueKeyToTexture(const GrUniqueKey& key, GrTexture* texture) { 256 SkASSERT(key.isValid()); 257 this->assignUniqueKeyToResource(key, texture); 258 } 259 260 GrTexture* refScratchTexture(const GrSurfaceDesc&, uint32_t scratchTextureFlags); 261 cache()262 GrResourceCache* cache() { return fCache; } cache()263 const GrResourceCache* cache() const { return fCache; } 264 gpu()265 GrGpu* gpu() { return fGpu; } gpu()266 const GrGpu* gpu() const { return fGpu; } 267 isAbandoned()268 bool isAbandoned() const { 269 SkASSERT(SkToBool(fGpu) == SkToBool(fCache)); 270 return !SkToBool(fCache); 271 } 272 273 const GrBuffer* createInstancedIndexBuffer(const uint16_t* pattern, 274 int patternSize, 275 int reps, 276 int vertCount, 277 const GrUniqueKey& key); 278 279 const GrBuffer* createQuadIndexBuffer(); 280 281 GrResourceCache* fCache; 282 GrGpu* fGpu; 283 sk_sp<const GrCaps> fCaps; 284 GrUniqueKey fQuadIndexBufferKey; 285 286 // In debug builds we guard against improper thread handling 287 SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;) 288 }; 289 290 #endif 291