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