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