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