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