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