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