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