• 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 class SkBitmap;
19 class SkImage;
20 
21 /*
22  * A factory for creating GrSurfaceProxy-derived objects.
23  */
24 class GrProxyProvider {
25 public:
26     GrProxyProvider(GrImageContext*);
27 
28     ~GrProxyProvider();
29 
30     /*
31      * Assigns a unique key to a proxy. The proxy will be findable via this key using
32      * findProxyByUniqueKey(). It is an error if an existing proxy already has a key.
33      */
34     bool assignUniqueKeyToProxy(const GrUniqueKey&, GrTextureProxy*);
35 
36     /*
37      * Sets the unique key of the provided proxy to the unique key of the surface. The surface must
38      * have a valid unique key.
39      */
40     void adoptUniqueKeyFromSurface(GrTextureProxy* proxy, const GrSurface*);
41 
42     /*
43      * Removes a unique key from a proxy. If the proxy has already been instantiated, it will
44      * also remove the unique key from the target GrSurface.
45      */
46     void removeUniqueKeyFromProxy(GrTextureProxy*);
47 
48     /*
49      * Finds a proxy by unique key.
50      */
51     sk_sp<GrTextureProxy> findProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin);
52 
53     /*
54      * Finds a proxy by unique key or creates a new one that wraps a resource matching the unique
55      * key. GrColorType is required to set the proxy's texture swizzle on creation. For any key,
56      * each call that might result in a cache hit must provide the same colorType as the call that
57      * caused a cache miss and created the proxy.
58      */
59     sk_sp<GrTextureProxy> findOrCreateProxyByUniqueKey(const GrUniqueKey&, GrColorType colorType,
60                                                        GrSurfaceOrigin);
61 
62     /*
63      * Create an un-mipmapped texture proxy with data. The SkImage must be a raster backend image.
64      * Since the SkImage is ref counted, we simply take a ref on it to keep the data alive until we
65      * actually upload the data to the gpu.
66      */
67     sk_sp<GrTextureProxy> createTextureProxy(
68             sk_sp<SkImage> srcImage, int sampleCnt, SkBudgeted, SkBackingFit,
69             GrInternalSurfaceFlags = GrInternalSurfaceFlags::kNone);
70 
71     /*
72      * Create a mipmapped texture proxy without any data.
73      *
74      * Like the call above but there are no texels to upload. A texture proxy is returned that
75      * simply has space allocated for the mips. We will allocated the full amount of mip levels
76      * based on the width and height in the GrSurfaceDesc.
77      */
78     sk_sp<GrTextureProxy> createMipMapProxy(const GrBackendFormat&, const GrSurfaceDesc&,
79                                             GrRenderable, int renderTargetSampleCnt,
80                                             GrSurfaceOrigin, SkBudgeted, GrProtected);
81 
82     /*
83      * Creates a new texture proxy for the bitmap, optionally with mip levels generated by the cpu.
84      */
85     sk_sp<GrTextureProxy> createProxyFromBitmap(const SkBitmap& bitmap, GrMipMapped);
86 
87     /*
88      * Create a GrSurfaceProxy without any data.
89      */
90     sk_sp<GrTextureProxy> createProxy(const GrBackendFormat&, const GrSurfaceDesc&, GrRenderable,
91                                       int renderTargetSampleCnt, GrSurfaceOrigin, GrMipMapped,
92                                       SkBackingFit, SkBudgeted, GrProtected,
93                                       GrInternalSurfaceFlags);
94 
95     sk_sp<GrTextureProxy> createProxy(
96             const GrBackendFormat& format, const GrSurfaceDesc& desc, GrRenderable renderable,
97             int renderTargetSampleCnt, GrSurfaceOrigin origin, SkBackingFit fit,
98             SkBudgeted budgeted, GrProtected isProtected,
99             GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone) {
100         return this->createProxy(format, desc, renderable, renderTargetSampleCnt, origin,
101                                  GrMipMapped::kNo, fit, budgeted, isProtected, surfaceFlags);
102     }
103 
104     /*
105      * Create a texture proxy from compressed texture data.
106      */
107     sk_sp<GrTextureProxy> createCompressedTextureProxy(int width, int height, SkBudgeted budgeted,
108                                                        SkImage::CompressionType compressionType,
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&, GrColorType, GrSurfaceOrigin,
120                                              GrWrapOwnership, GrWrapCacheable, GrIOType,
121                                              ReleaseProc = nullptr, ReleaseContext = nullptr);
122 
123     /*
124      * Create a texture proxy that wraps a backend texture and is both texture-able and renderable
125      */
126     sk_sp<GrTextureProxy> wrapRenderableBackendTexture(const GrBackendTexture&, GrSurfaceOrigin,
127                                                        int sampleCnt, GrColorType,
128                                                        GrWrapOwnership, GrWrapCacheable,
129                                                        ReleaseProc = nullptr,
130                                                        ReleaseContext = nullptr);
131 
132     /*
133      * Create a render target proxy that wraps a backend render target
134      */
135     sk_sp<GrSurfaceProxy> wrapBackendRenderTarget(const GrBackendRenderTarget&, GrColorType,
136                                                   GrSurfaceOrigin,
137                                                   ReleaseProc = nullptr, ReleaseContext = nullptr);
138 
139     /*
140      * Create a render target proxy that wraps a backend texture
141      */
142     sk_sp<GrSurfaceProxy> wrapBackendTextureAsRenderTarget(const GrBackendTexture&,
143                                                            GrColorType,
144                                                            GrSurfaceOrigin,
145                                                            int sampleCnt);
146 
147     sk_sp<GrRenderTargetProxy> wrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&,
148                                                                    const GrVkDrawableInfo&);
149 
150     using LazyInstantiationKeyMode = GrSurfaceProxy::LazyInstantiationKeyMode;
151     using LazyInstantiationResult = GrSurfaceProxy::LazyInstantiationResult;
152     using LazyInstantiateCallback = GrSurfaceProxy::LazyInstantiateCallback;
153 
154     struct TextureInfo {
155         GrMipMapped fMipMapped;
156         GrTextureType fTextureType;
157     };
158 
159     using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType;
160     /**
161      * Creates a texture proxy that will be instantiated by a user-supplied callback during flush.
162      * (Stencil is not supported by this method.) The width and height must either both be greater
163      * than 0 or both less than or equal to zero. A non-positive value is a signal that the width
164      * and height are currently unknown.
165      *
166      * When called, the callback must be able to cleanup any resources that it captured at creation.
167      * It also must support being passed in a null GrResourceProvider. When this happens, the
168      * callback should cleanup any resources it captured and return an empty sk_sp<GrTextureProxy>.
169      */
170     sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&,
171                                           const GrSurfaceDesc&, GrRenderable,
172                                           int renderTargetSampleCnt, GrSurfaceOrigin,
173                                           GrMipMapped, GrMipMapsStatus, GrInternalSurfaceFlags,
174                                           SkBackingFit, SkBudgeted, GrProtected,
175                                           LazyInstantiationType);
176 
177     sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&,
178                                           const GrSurfaceDesc&, GrRenderable,
179                                           int renderTargetSampleCnt, GrSurfaceOrigin, GrMipMapped,
180                                           GrMipMapsStatus, GrInternalSurfaceFlags, SkBackingFit,
181                                           SkBudgeted, GrProtected);
182 
183     sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&,
184                                           const GrSurfaceDesc&, GrRenderable,
185                                           int renderTargetSampleCnt, GrSurfaceOrigin, GrMipMapped,
186                                           GrMipMapsStatus, SkBackingFit, SkBudgeted, GrProtected);
187 
188     /** A null TextureInfo indicates a non-textureable render target. */
189     sk_sp<GrRenderTargetProxy> createLazyRenderTargetProxy(LazyInstantiateCallback&&,
190                                                            const GrBackendFormat&,
191                                                            const GrSurfaceDesc&,
192                                                            int renderTargetSampleCnt,
193                                                            GrSurfaceOrigin origin,
194                                                            GrInternalSurfaceFlags,
195                                                            const TextureInfo*, GrMipMapsStatus,
196                                                            SkBackingFit, SkBudgeted, GrProtected,
197                                                            bool wrapsVkSecondaryCB);
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&, GrRenderable,
205                                                     int renderTargetSampleCnt, GrProtected,
206                                                     GrSurfaceOrigin, GrPixelConfig, const GrCaps&);
207 
208     // 'proxy' is about to be used as a texture src or drawn to. This query can be used to
209     // determine if it is going to need a texture domain or a full clear.
210     static bool IsFunctionallyExact(GrSurfaceProxy* proxy);
211 
212     enum class InvalidateGPUResource : bool { kNo = false, kYes = true };
213 
214     /*
215      * This method ensures that, if a proxy w/ the supplied unique key exists, it is removed from
216      * the proxy provider's map and its unique key is removed. If 'invalidateSurface' is true, it
217      * will independently ensure that the unique key is removed from any GrGpuResources that may
218      * have it.
219      *
220      * If 'proxy' is provided (as an optimization to stop re-looking it up), its unique key must be
221      * valid and match the provided unique key.
222      *
223      * This method is called if either the proxy attached to the unique key is being deleted
224      * (in which case we don't want it cluttering up the hash table) or the client has indicated
225      * that it will never refer to the unique key again.
226      */
227     void processInvalidUniqueKey(const GrUniqueKey&, GrTextureProxy*, InvalidateGPUResource);
228 
229     // TODO: remove these entry points - it is a bit sloppy to be getting context info from here
230     uint32_t contextID() const;
231     const GrCaps* caps() const;
232     sk_sp<const GrCaps> refCaps() const;
233 
234     int numUniqueKeyProxies_TestOnly() const;
235 
236     // This is called on a DDL's proxyprovider when the DDL is finished. The uniquely keyed
237     // proxies need to keep their unique key but cannot hold on to the proxy provider unique
238     // pointer.
239     void orphanAllUniqueKeys();
240     // This is only used by GrContext::releaseResourcesAndAbandonContext()
241     void removeAllUniqueKeys();
242 
243     /**
244      * Does the proxy provider have access to a GrDirectContext? If so, proxies will be
245      * instantiated immediately.
246      */
247     bool renderingDirectly() const;
248 
249 #if GR_TEST_UTILS
250     /*
251      * Create a texture proxy that is backed by an instantiated GrSurface.
252      * TODO: Remove GrColorType. Currently used to infer a GrPixelConfig.
253      */
254     sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(const SkISize& size,
255                                                               GrColorType colorType,
256                                                               const GrBackendFormat& format,
257                                                               GrRenderable renderable,
258                                                               int renderTargetSampleCnt,
259                                                               GrSurfaceOrigin origin,
260                                                               SkBackingFit fit,
261                                                               SkBudgeted budgeted,
262                                                               GrProtected isProtected);
263 
264     /** Version of above that picks the default format for the color type. */
265     sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(const SkISize& size,
266                                                               GrColorType colorType,
267                                                               GrRenderable renderable,
268                                                               int renderTargetSampleCnt,
269                                                               GrSurfaceOrigin origin,
270                                                               SkBackingFit fit,
271                                                               SkBudgeted budgeted,
272                                                               GrProtected isProtected);
273 
274     sk_sp<GrTextureProxy> testingOnly_createWrapped(sk_sp<GrTexture>, GrColorType, GrSurfaceOrigin);
275 #endif
276 
277 private:
278     friend class GrAHardwareBufferImageGenerator; // for createWrapped
279     friend class GrResourceProvider; // for createWrapped
280 
281     bool isAbandoned() const;
282 
283     // GrColorType is used to determine the proxy's texture swizzle.
284     sk_sp<GrTextureProxy> createWrapped(sk_sp<GrTexture> tex, GrColorType, GrSurfaceOrigin origin);
285 
286     struct UniquelyKeyedProxyHashTraits {
GetKeyUniquelyKeyedProxyHashTraits287         static const GrUniqueKey& GetKey(const GrTextureProxy& p) { return p.getUniqueKey(); }
288 
HashUniquelyKeyedProxyHashTraits289         static uint32_t Hash(const GrUniqueKey& key) { return key.hash(); }
290     };
291     typedef SkTDynamicHash<GrTextureProxy, GrUniqueKey, UniquelyKeyedProxyHashTraits> UniquelyKeyedProxyHash;
292 
293     // This holds the texture proxies that have unique keys. The resourceCache does not get a ref
294     // on these proxies but they must send a message to the resourceCache when they are deleted.
295     UniquelyKeyedProxyHash fUniquelyKeyedProxies;
296 
297     GrImageContext*        fImageContext;
298 };
299 
300 #endif
301