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 "include/gpu/GrContextOptions.h" 12 #include "include/private/SkImageInfoPriv.h" 13 #include "src/core/SkScalerContext.h" 14 #include "src/gpu/GrGpuBuffer.h" 15 #include "src/gpu/GrResourceCache.h" 16 17 class GrBackendRenderTarget; 18 class GrBackendSemaphore; 19 class GrBackendTexture; 20 class GrGpu; 21 class GrPath; 22 class GrRenderTarget; 23 class GrResourceProviderPriv; 24 class GrSemaphore; 25 class GrSingleOwner; 26 class GrStencilAttachment; 27 class GrTexture; 28 struct GrVkDrawableInfo; 29 30 class GrStyle; 31 class SkDescriptor; 32 class SkPath; 33 class SkTypeface; 34 35 /** 36 * A factory for arbitrary resource types. 37 */ 38 class GrResourceProvider { 39 public: 40 GrResourceProvider(GrGpu*, GrResourceCache*, GrSingleOwner*); 41 42 /** 43 * Finds a resource in the cache, based on the specified key. Prior to calling this, the caller 44 * must be sure that if a resource of exists in the cache with the given unique key then it is 45 * of type T. 46 */ 47 template <typename T = GrGpuResource> 48 typename std::enable_if<std::is_base_of<GrGpuResource, T>::value, sk_sp<T>>::type findByUniqueKey(const GrUniqueKey & key)49 findByUniqueKey(const GrUniqueKey& key) { 50 return sk_sp<T>(static_cast<T*>(this->findResourceByUniqueKey(key).release())); 51 } 52 53 /////////////////////////////////////////////////////////////////////////// 54 // Textures 55 56 /** 57 * Finds a texture that approximately matches the descriptor. Will be at least as large in width 58 * and height as desc specifies. If renderable is kYes then the GrTexture will also be a 59 * GrRenderTarget. The texture's format and sample count will always match the request. 60 * The contents of the texture are undefined. 61 */ 62 sk_sp<GrTexture> createApproxTexture(const GrSurfaceDesc& desc, 63 const GrBackendFormat& format, 64 GrRenderable renderable, 65 int renderTargetSampleCnt, 66 GrProtected isProtected); 67 68 /** Create an exact fit texture with no initial data to upload. */ 69 sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, 70 const GrBackendFormat& format, 71 GrRenderable renderable, 72 int renderTargetSampleCnt, 73 GrMipMapped mipMapped, 74 SkBudgeted budgeted, 75 GrProtected isProtected); 76 77 /** 78 * Create an exact fit texture with initial data to upload. The color type must be valid 79 * for the format and also describe the texel data. This will ensure any conversions that 80 * need to get applied to the data before upload are applied. 81 */ 82 sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, 83 const GrBackendFormat& format, 84 GrColorType colorType, 85 GrRenderable renderable, 86 int renderTargetSampleCnt, 87 SkBudgeted budgeted, 88 GrProtected isProtected, 89 const GrMipLevel texels[], 90 int mipLevelCount); 91 92 /** 93 * Create a potentially loose fit texture with the provided data. The color type must be valid 94 * for the format and also describe the texel data. This will ensure any conversions that 95 * need to get applied to the data before upload are applied. 96 */ 97 sk_sp<GrTexture> createTexture(const GrSurfaceDesc& desc, 98 const GrBackendFormat& format, 99 GrColorType srcColorType, 100 GrRenderable renderable, 101 int renderTargetSampleCnt, 102 SkBudgeted budgeted, 103 SkBackingFit fit, 104 GrProtected isProtected, 105 const GrMipLevel& mipLevel); 106 107 /** 108 * Creates a compressed texture. The GrGpu must support the SkImageImage::Compression type. 109 * This does not currently support MIP maps. It will not be renderable. 110 */ 111 sk_sp<GrTexture> createCompressedTexture(int width, int height, const GrBackendFormat&, 112 SkImage::CompressionType, SkBudgeted, SkData* data); 113 114 /////////////////////////////////////////////////////////////////////////// 115 // Wrapped Backend Surfaces 116 117 /** 118 * Wraps an existing texture with a GrTexture object. 119 * 120 * GrIOType must either be kRead or kRW. kRead blocks any operations that would modify the 121 * pixels (e.g. dst for a copy, regenerating MIP levels, write pixels). 122 * 123 * OpenGL: if the object is a texture Gr may change its GL texture params 124 * when it is drawn. 125 * 126 * @return GrTexture object or NULL on failure. 127 */ 128 sk_sp<GrTexture> wrapBackendTexture(const GrBackendTexture& tex, GrColorType, GrWrapOwnership, 129 GrWrapCacheable, GrIOType); 130 131 /** 132 * This makes the backend texture be renderable. If sampleCnt is > 1 and the underlying API 133 * uses separate MSAA render buffers then a MSAA render buffer is created that resolves 134 * to the texture. 135 */ 136 sk_sp<GrTexture> wrapRenderableBackendTexture(const GrBackendTexture& tex, 137 int sampleCnt, 138 GrColorType, 139 GrWrapOwnership, 140 GrWrapCacheable); 141 142 /** 143 * Wraps an existing render target with a GrRenderTarget object. It is 144 * similar to wrapBackendTexture but can be used to draw into surfaces 145 * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that 146 * the client will resolve to a texture). Currently wrapped render targets 147 * always use the kBorrow_GrWrapOwnership and GrWrapCacheable::kNo semantics. 148 * 149 * @return GrRenderTarget object or NULL on failure. 150 */ 151 sk_sp<GrRenderTarget> wrapBackendRenderTarget(const GrBackendRenderTarget&, 152 GrColorType colorType); 153 154 sk_sp<GrRenderTarget> wrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&, 155 const GrVkDrawableInfo&); 156 157 static const uint32_t kMinScratchTextureSize; 158 159 /** 160 * Either finds and refs, or creates a static buffer with the given parameters and contents. 161 * 162 * @param intendedType hint to the graphics subsystem about what the buffer will be used for. 163 * @param size minimum size of buffer to return. 164 * @param data optional data with which to initialize the buffer. 165 * @param key Key to be assigned to the buffer. 166 * 167 * @return The buffer if successful, otherwise nullptr. 168 */ 169 sk_sp<const GrGpuBuffer> findOrMakeStaticBuffer(GrGpuBufferType intendedType, size_t size, 170 const void* data, const GrUniqueKey& key); 171 172 /** 173 * Either finds and refs, or creates an index buffer with a repeating pattern for drawing 174 * contiguous vertices of a repeated mesh. If the return is non-null, the caller owns a ref on 175 * the returned GrBuffer. 176 * 177 * @param pattern the pattern of indices to repeat 178 * @param patternSize size in bytes of the pattern 179 * @param reps number of times to repeat the pattern 180 * @param vertCount number of vertices the pattern references 181 * @param key Key to be assigned to the index buffer. 182 * 183 * @return The index buffer if successful, otherwise nullptr. 184 */ findOrCreatePatternedIndexBuffer(const uint16_t * pattern,int patternSize,int reps,int vertCount,const GrUniqueKey & key)185 sk_sp<const GrGpuBuffer> findOrCreatePatternedIndexBuffer(const uint16_t* pattern, 186 int patternSize, 187 int reps, 188 int vertCount, 189 const GrUniqueKey& key) { 190 if (auto buffer = this->findByUniqueKey<const GrGpuBuffer>(key)) { 191 return buffer; 192 } 193 return this->createPatternedIndexBuffer(pattern, patternSize, reps, vertCount, &key); 194 } 195 196 /** 197 * Returns an index buffer that can be used to render quads. 198 * Six indices per quad: 0, 1, 2, 2, 1, 3, etc. 199 * The max number of quads is the buffer's index capacity divided by 6. 200 * Draw with GrPrimitiveType::kTriangles 201 * @ return the quad index buffer 202 */ refQuadIndexBuffer()203 sk_sp<const GrGpuBuffer> refQuadIndexBuffer() { 204 if (!fQuadIndexBuffer) { 205 fQuadIndexBuffer = this->createQuadIndexBuffer(); 206 } 207 return fQuadIndexBuffer; 208 } 209 210 static int QuadCountOfQuadBuffer(); 211 212 /** 213 * Factories for GrPath objects. It's an error to call these if path rendering 214 * is not supported. 215 */ 216 sk_sp<GrPath> createPath(const SkPath&, const GrStyle&); 217 218 /** 219 * Returns a buffer. 220 * 221 * @param size minimum size of buffer to return. 222 * @param intendedType hint to the graphics subsystem about what the buffer will be used for. 223 * @param GrAccessPattern hint to the graphics subsystem about how the data will be accessed. 224 * @param flags see Flags enum. 225 * @param data optional data with which to initialize the buffer. 226 * 227 * @return the buffer if successful, otherwise nullptr. 228 */ 229 sk_sp<GrGpuBuffer> createBuffer(size_t size, GrGpuBufferType intendedType, GrAccessPattern, 230 const void* data = nullptr); 231 232 /** 233 * If passed in render target already has a stencil buffer with at least "numSamples" samples, 234 * return true. Otherwise attempt to attach one and return true on success. 235 */ 236 bool attachStencilAttachment(GrRenderTarget* rt, int numStencilSamples); 237 238 /** 239 * Wraps an existing texture with a GrRenderTarget object. This is useful when the provided 240 * texture has a format that cannot be textured from by Skia, but we want to raster to it. 241 * 242 * The texture is wrapped as borrowed. The texture object will not be freed once the 243 * render target is destroyed. 244 * 245 * @return GrRenderTarget object or NULL on failure. 246 */ 247 sk_sp<GrRenderTarget> wrapBackendTextureAsRenderTarget(const GrBackendTexture&, 248 int sampleCnt, 249 GrColorType); 250 251 /** 252 * Assigns a unique key to a resource. If the key is associated with another resource that 253 * association is removed and replaced by this resource. 254 */ 255 void assignUniqueKeyToResource(const GrUniqueKey&, GrGpuResource*); 256 257 sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned = true); 258 259 enum class SemaphoreWrapType { 260 kWillSignal, 261 kWillWait, 262 }; 263 264 sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore&, 265 SemaphoreWrapType wrapType, 266 GrWrapOwnership = kBorrow_GrWrapOwnership); 267 abandon()268 void abandon() { 269 fCache = nullptr; 270 fGpu = nullptr; 271 } 272 contextUniqueID()273 uint32_t contextUniqueID() const { return fCache->contextUniqueID(); } caps()274 const GrCaps* caps() const { return fCaps.get(); } overBudget()275 bool overBudget() const { return fCache->overBudget(); } 276 277 static uint32_t MakeApprox(uint32_t value); 278 279 inline GrResourceProviderPriv priv(); 280 inline const GrResourceProviderPriv priv() const; 281 282 private: 283 sk_sp<GrGpuResource> findResourceByUniqueKey(const GrUniqueKey&); 284 285 // Attempts to find a resource in the cache that exactly matches the GrSurfaceDesc. Failing that 286 // it returns null. If non-null, the resulting texture is always budgeted. 287 sk_sp<GrTexture> refScratchTexture(const GrSurfaceDesc&, 288 const GrBackendFormat&, 289 GrRenderable, 290 int renderTargetSampleCnt, 291 GrMipMapped, 292 GrProtected); 293 294 /* 295 * Try to find an existing scratch texture that exactly matches 'desc'. If successful 296 * update the budgeting accordingly. 297 */ 298 sk_sp<GrTexture> getExactScratch(const GrSurfaceDesc&, 299 const GrBackendFormat&, 300 GrRenderable, 301 int renderTargetSampleCnt, 302 SkBudgeted, 303 GrMipMapped, 304 GrProtected); 305 306 // Used to perform any conversions necessary to texel data before creating a texture with 307 // existing data or uploading to a scratch texture. 308 using TempLevels = SkAutoSTMalloc<14, GrMipLevel>; 309 using TempLevelDatas = SkAutoSTArray<14, std::unique_ptr<char[]>>; 310 GrColorType prepareLevels(const GrBackendFormat& format, 311 GrColorType, 312 const SkISize& baseSize, 313 const GrMipLevel texels[], 314 int mipLevelCount, 315 TempLevels*, 316 TempLevelDatas*) const; 317 318 // GrResourceProvider may be asked to "create" a new texture with initial pixel data to populate 319 // it. In implementation it may pull an existing texture from GrResourceCache and then write the 320 // pixel data to the texture. It takes a width/height for the base level because we may be 321 // using an approximate-sized scratch texture. On success the texture is returned and nullptr 322 // on failure. 323 sk_sp<GrTexture> writePixels(sk_sp<GrTexture> texture, 324 GrColorType colorType, 325 const SkISize& baseSize, 326 const GrMipLevel texels[], 327 int mipLevelCount) const; 328 cache()329 GrResourceCache* cache() { return fCache; } cache()330 const GrResourceCache* cache() const { return fCache; } 331 332 friend class GrResourceProviderPriv; 333 334 // Method made available via GrResourceProviderPriv gpu()335 GrGpu* gpu() { return fGpu; } gpu()336 const GrGpu* gpu() const { return fGpu; } 337 isAbandoned()338 bool isAbandoned() const { 339 SkASSERT(SkToBool(fGpu) == SkToBool(fCache)); 340 return !SkToBool(fCache); 341 } 342 343 sk_sp<const GrGpuBuffer> createPatternedIndexBuffer(const uint16_t* pattern, 344 int patternSize, 345 int reps, 346 int vertCount, 347 const GrUniqueKey* key); 348 349 sk_sp<const GrGpuBuffer> createQuadIndexBuffer(); 350 351 GrResourceCache* fCache; 352 GrGpu* fGpu; 353 sk_sp<const GrCaps> fCaps; 354 sk_sp<const GrGpuBuffer> fQuadIndexBuffer; 355 356 // In debug builds we guard against improper thread handling 357 SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;) 358 }; 359 360 #endif 361