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 GrRenderTargetContext::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 * Creates a texture proxy that will be instantiated by a user-supplied callback during flush. 155 * The width and height must either both be greater than 0 or both less than or equal to zero. A 156 * non-positive value is a signal that the width height are currently unknown. The texture will 157 * not be renderable. 158 * 159 * When called, the callback must be able to cleanup any resources that it captured at creation. 160 * It also must support being passed in a null GrResourceProvider. When this happens, the 161 * callback should cleanup any resources it captured and return an empty sk_sp<GrTextureProxy>. 162 */ 163 sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, 164 const GrBackendFormat&, 165 SkISize dimensions, 166 GrMipmapped, 167 GrMipmapStatus, 168 GrInternalSurfaceFlags, 169 SkBackingFit, 170 SkBudgeted, 171 GrProtected, 172 UseAllocator); 173 174 /** A null TextureInfo indicates a non-textureable render target. */ 175 sk_sp<GrRenderTargetProxy> createLazyRenderTargetProxy(LazyInstantiateCallback&&, 176 const GrBackendFormat&, 177 SkISize dimensions, 178 int renderTargetSampleCnt, 179 GrInternalSurfaceFlags, 180 const TextureInfo*, 181 GrMipmapStatus, 182 SkBackingFit, 183 SkBudgeted, 184 GrProtected, 185 bool wrapsVkSecondaryCB, 186 UseAllocator useAllocator); 187 188 /** 189 * Fully lazy proxies have unspecified width and height. Methods that rely on those values 190 * (e.g., width, height, getBoundsRect) should be avoided. 191 */ 192 static sk_sp<GrTextureProxy> MakeFullyLazyProxy(LazyInstantiateCallback&&, 193 const GrBackendFormat&, 194 GrRenderable, 195 int renderTargetSampleCnt, 196 GrProtected, 197 const GrCaps&, 198 UseAllocator); 199 200 enum class InvalidateGPUResource : bool { kNo = false, kYes = true }; 201 202 /* 203 * This method ensures that, if a proxy w/ the supplied unique key exists, it is removed from 204 * the proxy provider's map and its unique key is removed. If 'invalidateSurface' is true, it 205 * will independently ensure that the unique key is removed from any GrGpuResources that may 206 * have it. 207 * 208 * If 'proxy' is provided (as an optimization to stop re-looking it up), its unique key must be 209 * valid and match the provided unique key. 210 * 211 * This method is called if either the proxy attached to the unique key is being deleted 212 * (in which case we don't want it cluttering up the hash table) or the client has indicated 213 * that it will never refer to the unique key again. 214 */ 215 void processInvalidUniqueKey(const GrUniqueKey&, GrTextureProxy*, InvalidateGPUResource); 216 217 GrDDLProvider isDDLProvider() const; 218 219 // TODO: remove these entry points - it is a bit sloppy to be getting context info from here 220 uint32_t contextID() const; 221 const GrCaps* caps() const; 222 sk_sp<const GrCaps> refCaps() const; 223 224 int numUniqueKeyProxies_TestOnly() const; 225 226 // This is called on a DDL's proxyprovider when the DDL is finished. The uniquely keyed 227 // proxies need to keep their unique key but cannot hold on to the proxy provider unique 228 // pointer. 229 void orphanAllUniqueKeys(); 230 // This is only used by GrContext::releaseResourcesAndAbandonContext() 231 void removeAllUniqueKeys(); 232 233 /** 234 * Does the proxy provider have access to a GrDirectContext? If so, proxies will be 235 * instantiated immediately. 236 */ 237 bool renderingDirectly() const; 238 239 #if GR_TEST_UTILS 240 /** 241 * Create a texture proxy that is backed by an instantiated GrSurface. 242 */ 243 sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(SkISize dimensions, 244 const GrBackendFormat& format, 245 GrRenderable renderable, 246 int renderTargetSampleCnt, 247 SkBackingFit fit, 248 SkBudgeted budgeted, 249 GrProtected isProtected); 250 251 /** Version of above that picks the default format for the color type. */ 252 sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(SkISize dimensions, 253 GrColorType colorType, 254 GrRenderable renderable, 255 int renderTargetSampleCnt, 256 SkBackingFit fit, 257 SkBudgeted budgeted, 258 GrProtected isProtected); 259 260 sk_sp<GrTextureProxy> testingOnly_createWrapped(sk_sp<GrTexture>); 261 #endif 262 263 private: 264 friend class GrAHardwareBufferImageGenerator; // for createWrapped 265 friend class GrResourceProvider; // for createWrapped 266 267 // processInvalidUniqueKey() with control over removing hash table entries, 268 // which is not safe while iterating with foreach(). 269 enum class RemoveTableEntry { kNo, kYes }; 270 void processInvalidUniqueKeyImpl(const GrUniqueKey&, GrTextureProxy*, 271 InvalidateGPUResource, RemoveTableEntry); 272 273 bool isAbandoned() const; 274 275 /* 276 * Create an un-mipmapped texture proxy for the bitmap. 277 */ 278 sk_sp<GrTextureProxy> createNonMippedProxyFromBitmap(const SkBitmap&, SkBackingFit, SkBudgeted); 279 /* 280 * Create an mipmapped texture proxy for the bitmap. 281 */ 282 sk_sp<GrTextureProxy> createMippedProxyFromBitmap(const SkBitmap&, 283 SkBudgeted); 284 285 sk_sp<GrTextureProxy> createWrapped(sk_sp<GrTexture> tex, UseAllocator useAllocator); 286 287 struct UniquelyKeyedProxyHashTraits { GetKeyUniquelyKeyedProxyHashTraits288 static const GrUniqueKey& GetKey(const GrTextureProxy& p) { return p.getUniqueKey(); } 289 HashUniquelyKeyedProxyHashTraits290 static uint32_t Hash(const GrUniqueKey& key) { return key.hash(); } 291 }; 292 typedef SkTDynamicHash<GrTextureProxy, GrUniqueKey, UniquelyKeyedProxyHashTraits> UniquelyKeyedProxyHash; 293 294 // This holds the texture proxies that have unique keys. The resourceCache does not get a ref 295 // on these proxies but they must send a message to the resourceCache when they are deleted. 296 UniquelyKeyedProxyHash fUniquelyKeyedProxies; 297 298 GrImageContext* fImageContext; 299 }; 300 301 #endif 302