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