• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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 GrProxyProvider_DEFINED
9 #define GrProxyProvider_DEFINED
10 
11 #include "include/gpu/GrTypes.h"
12 #include "src/core/SkTDynamicHash.h"
13 #include "src/gpu/ResourceKey.h"
14 #include "src/gpu/ganesh/GrTextureProxy.h"
15 
16 class GrBackendRenderTarget;
17 class GrContextThreadSafeProxy;
18 class GrImageContext;
19 class GrSurfaceProxyView;
20 class SkBitmap;
21 class SkImage;
22 enum class SkTextureCompressionType;
23 struct GrVkDrawableInfo;
24 
25 /*
26  * A factory for creating GrSurfaceProxy-derived objects.
27  */
28 class GrProxyProvider {
29 public:
30     using UseAllocator = GrSurfaceProxy::UseAllocator;
31 
32     GrProxyProvider(GrImageContext*);
33 
34     ~GrProxyProvider();
35 
36     /*
37      * Assigns a unique key to a proxy. The proxy will be findable via this key using
38      * findProxyByUniqueKey(). It is an error if an existing proxy already has a key.
39      */
40     bool assignUniqueKeyToProxy(const skgpu::UniqueKey&, GrTextureProxy*);
41 
42     /*
43      * Sets the unique key of the provided proxy to the unique key of the surface. The surface must
44      * have a valid unique key.
45      */
46     void adoptUniqueKeyFromSurface(GrTextureProxy* proxy, const GrSurface*);
47 
48     /*
49      * Removes a unique key from a proxy. If the proxy has already been instantiated, it will
50      * also remove the unique key from the target GrSurface.
51      */
52     void removeUniqueKeyFromProxy(GrTextureProxy*);
53 
54     /*
55      * Finds a proxy by unique key.
56      */
57     sk_sp<GrTextureProxy> findProxyByUniqueKey(const skgpu::UniqueKey&);
58 
59     /*
60      * Finds a proxy by unique key or creates a new one that wraps a resource matching the unique
61      * key.
62      */
63     sk_sp<GrTextureProxy> findOrCreateProxyByUniqueKey(const skgpu::UniqueKey&,
64                                                        UseAllocator = UseAllocator::kYes);
65 
66     /**
67      * A helper that uses findOrCreateProxyByUniqueKey() to find a proxy and, if found, creates
68      * a view for the found proxy using the passed in origin and color type. It is assumed that if
69      * the proxy is renderable then it was created via a fallback code path so the fallback
70      * color type will be used to create the view.
71      */
72     GrSurfaceProxyView findCachedProxyWithColorTypeFallback(const skgpu::UniqueKey&,
73                                                             GrSurfaceOrigin,
74                                                             GrColorType,
75                                                             int sampleCnt);
76 
77     /*
78      * Creates a new texture proxy for the bitmap, optionally with mip levels generated by the cpu.
79      * The bitmap is uploaded to the texture proxy assuming a kTopLeft_GrSurfaceOrigin.
80      */
81     sk_sp<GrTextureProxy> createProxyFromBitmap(const SkBitmap&,
82                                                 skgpu::Mipmapped,
83                                                 SkBackingFit,
84                                                 skgpu::Budgeted);
85 
86     /*
87      * Create a GrSurfaceProxy without any data.
88      */
89     sk_sp<GrTextureProxy> createProxy(const GrBackendFormat&,
90                                       SkISize dimensions,
91                                       GrRenderable,
92                                       int renderTargetSampleCnt,
93                                       skgpu::Mipmapped,
94                                       SkBackingFit,
95                                       skgpu::Budgeted,
96                                       GrProtected,
97                                       std::string_view label,
98                                       GrInternalSurfaceFlags = GrInternalSurfaceFlags::kNone,
99                                       UseAllocator useAllocator = UseAllocator::kYes);
100 
101     /*
102      * Create a texture proxy from compressed texture data.
103      */
104     sk_sp<GrTextureProxy> createCompressedTextureProxy(SkISize dimensions,
105                                                        skgpu::Budgeted,
106                                                        skgpu::Mipmapped,
107                                                        GrProtected,
108                                                        SkTextureCompressionType,
109                                                        sk_sp<SkData> data);
110 
111     // These match the definitions in SkImage & GrTexture.h, for whence they came
112     typedef void* ReleaseContext;
113     typedef void (*ReleaseProc)(ReleaseContext);
114 
115     /*
116      * Create a texture proxy that wraps a (non-renderable) backend texture. GrIOType must be
117      * kRead or kRW.
118      */
119     sk_sp<GrTextureProxy> wrapBackendTexture(const GrBackendTexture&,
120                                              GrWrapOwnership,
121                                              GrWrapCacheable,
122                                              GrIOType,
123                                              sk_sp<skgpu::RefCntedCallback> = nullptr);
124 
125     sk_sp<GrTextureProxy> wrapCompressedBackendTexture(const GrBackendTexture&,
126                                                        GrWrapOwnership,
127                                                        GrWrapCacheable,
128                                                        sk_sp<skgpu::RefCntedCallback>);
129 
130     /*
131      * Create a texture proxy that wraps a backend texture and is both texture-able and renderable
132      */
133     sk_sp<GrTextureProxy> wrapRenderableBackendTexture(const GrBackendTexture&,
134                                                        int sampleCnt,
135                                                        GrWrapOwnership,
136                                                        GrWrapCacheable,
137                                                        sk_sp<skgpu::RefCntedCallback> releaseHelper);
138 
139     /*
140      * Create a render target proxy that wraps a backend render target
141      */
142     sk_sp<GrSurfaceProxy> wrapBackendRenderTarget(const GrBackendRenderTarget&,
143                                                   sk_sp<skgpu::RefCntedCallback> releaseHelper);
144 
145     using LazyInstantiationKeyMode = GrSurfaceProxy::LazyInstantiationKeyMode;
146     using LazySurfaceDesc = GrSurfaceProxy::LazySurfaceDesc;
147     using LazyCallbackResult = GrSurfaceProxy::LazyCallbackResult;
148     using LazyInstantiateCallback = GrSurfaceProxy::LazyInstantiateCallback;
149 
150     struct TextureInfo {
151         skgpu::Mipmapped fMipmapped;
152         GrTextureType fTextureType;
153     };
154 
155     /**
156      * Similar to createLazyProxy below, except narrowed to the use case of shared promise images
157      * i.e. static so it doesn't have access to mutable state. Used by MakePromiseImageLazyProxy().
158      */
159     static sk_sp<GrTextureProxy> CreatePromiseProxy(GrContextThreadSafeProxy*,
160                                                     LazyInstantiateCallback&&,
161                                                     const GrBackendFormat&,
162                                                     SkISize dimensions,
163                                                     skgpu::Mipmapped);
164 
165     /**
166      * Creates a texture proxy that will be instantiated by a user-supplied callback during flush.
167      * The width and height must either both be greater than 0 or both less than or equal to zero. A
168      * non-positive value is a signal that the width height are currently unknown. The texture will
169      * not be renderable.
170      *
171      * When called, the callback must be able to cleanup any resources that it captured at creation.
172      * It also must support being passed in a null GrResourceProvider. When this happens, the
173      * callback should cleanup any resources it captured and return an empty sk_sp<GrTextureProxy>.
174      */
175     sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&,
176                                           const GrBackendFormat&,
177                                           SkISize dimensions,
178                                           skgpu::Mipmapped,
179                                           GrMipmapStatus,
180                                           GrInternalSurfaceFlags,
181                                           SkBackingFit,
182                                           skgpu::Budgeted,
183                                           GrProtected,
184                                           UseAllocator,
185                                           std::string_view label);
186 
187     /** A null TextureInfo indicates a non-textureable render target. */
188     sk_sp<GrRenderTargetProxy> createLazyRenderTargetProxy(LazyInstantiateCallback&&,
189                                                            const GrBackendFormat&,
190                                                            SkISize dimensions,
191                                                            int renderTargetSampleCnt,
192                                                            GrInternalSurfaceFlags,
193                                                            const TextureInfo*,
194                                                            GrMipmapStatus,
195                                                            SkBackingFit,
196                                                            skgpu::Budgeted,
197                                                            GrProtected,
198                                                            bool wrapsVkSecondaryCB,
199                                                            UseAllocator useAllocator);
200 
201     /**
202      * Fully lazy proxies have unspecified width and height. Methods that rely on those values
203      * (e.g., width, height, getBoundsRect) should be avoided.
204      */
205     static sk_sp<GrTextureProxy> MakeFullyLazyProxy(LazyInstantiateCallback&&,
206                                                     const GrBackendFormat&,
207                                                     GrRenderable,
208                                                     int renderTargetSampleCnt,
209                                                     GrProtected,
210                                                     const GrCaps&,
211                                                     UseAllocator);
212 
213     enum class InvalidateGPUResource : bool { kNo = false, kYes = true };
214 
215     /*
216      * This method ensures that, if a proxy w/ the supplied unique key exists, it is removed from
217      * the proxy provider's map and its unique key is removed. If 'invalidateSurface' is true, it
218      * will independently ensure that the unique key is removed from any GrGpuResources that may
219      * have it.
220      *
221      * If 'proxy' is provided (as an optimization to stop re-looking it up), its unique key must be
222      * valid and match the provided unique key.
223      *
224      * This method is called if either the proxy attached to the unique key is being deleted
225      * (in which case we don't want it cluttering up the hash table) or the client has indicated
226      * that it will never refer to the unique key again.
227      */
228     void processInvalidUniqueKey(const skgpu::UniqueKey&, GrTextureProxy*, InvalidateGPUResource);
229 
230     GrDDLProvider isDDLProvider() const;
231 
232     // TODO: remove these entry points - it is a bit sloppy to be getting context info from here
233     uint32_t contextID() const;
234     const GrCaps* caps() const;
235     sk_sp<const GrCaps> refCaps() const;
236 
237     GrResourceProvider* resourceProvider() const;
238 
239     int numUniqueKeyProxies_TestOnly() const;
240 
241     // This is called on a DDL's proxyprovider when the DDL is finished. The uniquely keyed
242     // proxies need to keep their unique key but cannot hold on to the proxy provider unique
243     // pointer.
244     void orphanAllUniqueKeys();
245     // This is only used by GrContext::releaseResourcesAndAbandonContext()
246     void removeAllUniqueKeys();
247 
248     /**
249      * Does the proxy provider have access to a GrDirectContext? If so, proxies will be
250      * instantiated immediately.
251      */
252     bool renderingDirectly() const;
253     bool isAbandoned() const;
254 
255 #if defined(GR_TEST_UTILS)
256     /**
257      * Create a texture proxy that is backed by an instantiated GrSurface.
258      */
259     sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(SkISize dimensions,
260                                                               const GrBackendFormat& format,
261                                                               GrRenderable renderable,
262                                                               int renderTargetSampleCnt,
263                                                               SkBackingFit fit,
264                                                               skgpu::Budgeted budgeted,
265                                                               GrProtected isProtected);
266 
267     /** Version of above that picks the default format for the color type. */
268     sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(SkISize dimensions,
269                                                               GrColorType colorType,
270                                                               GrRenderable renderable,
271                                                               int renderTargetSampleCnt,
272                                                               SkBackingFit fit,
273                                                               skgpu::Budgeted budgeted,
274                                                               GrProtected isProtected);
275 
276     sk_sp<GrTextureProxy> testingOnly_createWrapped(sk_sp<GrTexture>);
277 #endif
278 
279 private:
280     friend class GrAHardwareBufferImageGenerator; // for createWrapped
281     friend class GrResourceProvider; // for createWrapped
282 
283     // processInvalidUniqueKey() with control over removing hash table entries,
284     // which is not safe while iterating with foreach().
285     enum class RemoveTableEntry { kNo, kYes };
286     void processInvalidUniqueKeyImpl(const skgpu::UniqueKey&, GrTextureProxy*,
287                                      InvalidateGPUResource, RemoveTableEntry);
288 
289     /*
290      * Create an un-mipmapped texture proxy for the bitmap.
291      */
292     sk_sp<GrTextureProxy> createNonMippedProxyFromBitmap(const SkBitmap&,
293                                                          SkBackingFit,
294                                                          skgpu::Budgeted);
295     /*
296      * Create an mipmapped texture proxy for the bitmap.
297      */
298     sk_sp<GrTextureProxy> createMippedProxyFromBitmap(const SkBitmap&, skgpu::Budgeted);
299 
300     sk_sp<GrTextureProxy> createWrapped(sk_sp<GrTexture> tex, UseAllocator useAllocator);
301 
302     struct UniquelyKeyedProxyHashTraits {
GetKeyUniquelyKeyedProxyHashTraits303         static const skgpu::UniqueKey& GetKey(const GrTextureProxy& p) { return p.getUniqueKey(); }
304 
HashUniquelyKeyedProxyHashTraits305         static uint32_t Hash(const skgpu::UniqueKey& key) { return key.hash(); }
306     };
307     typedef SkTDynamicHash<GrTextureProxy, skgpu::UniqueKey, UniquelyKeyedProxyHashTraits> UniquelyKeyedProxyHash;
308 
309     // This holds the texture proxies that have unique keys. The resourceCache does not get a ref
310     // on these proxies but they must send a message to the resourceCache when they are deleted.
311     UniquelyKeyedProxyHash fUniquelyKeyedProxies;
312 
313     GrImageContext*        fImageContext;
314 };
315 
316 #endif
317