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