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 GrProxyProvider(GrImageContext*); 27 28 ~GrProxyProvider(); 29 30 /* 31 * Assigns a unique key to a proxy. The proxy will be findable via this key using 32 * findProxyByUniqueKey(). It is an error if an existing proxy already has a key. 33 */ 34 bool assignUniqueKeyToProxy(const GrUniqueKey&, GrTextureProxy*); 35 36 /* 37 * Sets the unique key of the provided proxy to the unique key of the surface. The surface must 38 * have a valid unique key. 39 */ 40 void adoptUniqueKeyFromSurface(GrTextureProxy* proxy, const GrSurface*); 41 42 /* 43 * Removes a unique key from a proxy. If the proxy has already been instantiated, it will 44 * also remove the unique key from the target GrSurface. 45 */ 46 void removeUniqueKeyFromProxy(GrTextureProxy*); 47 48 /* 49 * Finds a proxy by unique key. 50 */ 51 sk_sp<GrTextureProxy> findProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin); 52 53 /* 54 * Finds a proxy by unique key or creates a new one that wraps a resource matching the unique 55 * key. GrColorType is required to set the proxy's texture swizzle on creation. For any key, 56 * each call that might result in a cache hit must provide the same colorType as the call that 57 * caused a cache miss and created the proxy. 58 */ 59 sk_sp<GrTextureProxy> findOrCreateProxyByUniqueKey(const GrUniqueKey&, GrColorType colorType, 60 GrSurfaceOrigin); 61 62 /* 63 * Create an un-mipmapped texture proxy with data. The SkImage must be a raster backend image. 64 * Since the SkImage is ref counted, we simply take a ref on it to keep the data alive until we 65 * actually upload the data to the gpu. 66 */ 67 sk_sp<GrTextureProxy> createTextureProxy( 68 sk_sp<SkImage> srcImage, int sampleCnt, SkBudgeted, SkBackingFit, 69 GrInternalSurfaceFlags = GrInternalSurfaceFlags::kNone); 70 71 /* 72 * Create a mipmapped texture proxy without any data. 73 * 74 * Like the call above but there are no texels to upload. A texture proxy is returned that 75 * simply has space allocated for the mips. We will allocated the full amount of mip levels 76 * based on the width and height in the GrSurfaceDesc. 77 */ 78 sk_sp<GrTextureProxy> createMipMapProxy(const GrBackendFormat&, const GrSurfaceDesc&, 79 GrRenderable, int renderTargetSampleCnt, 80 GrSurfaceOrigin, SkBudgeted, GrProtected); 81 82 /* 83 * Creates a new texture proxy for the bitmap, optionally with mip levels generated by the cpu. 84 */ 85 sk_sp<GrTextureProxy> createProxyFromBitmap(const SkBitmap& bitmap, GrMipMapped); 86 87 /* 88 * Create a GrSurfaceProxy without any data. 89 */ 90 sk_sp<GrTextureProxy> createProxy(const GrBackendFormat&, const GrSurfaceDesc&, GrRenderable, 91 int renderTargetSampleCnt, GrSurfaceOrigin, GrMipMapped, 92 SkBackingFit, SkBudgeted, GrProtected, 93 GrInternalSurfaceFlags); 94 95 sk_sp<GrTextureProxy> createProxy( 96 const GrBackendFormat& format, const GrSurfaceDesc& desc, GrRenderable renderable, 97 int renderTargetSampleCnt, GrSurfaceOrigin origin, SkBackingFit fit, 98 SkBudgeted budgeted, GrProtected isProtected, 99 GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone) { 100 return this->createProxy(format, desc, renderable, renderTargetSampleCnt, origin, 101 GrMipMapped::kNo, fit, budgeted, isProtected, surfaceFlags); 102 } 103 104 /* 105 * Create a texture proxy from compressed texture data. 106 */ 107 sk_sp<GrTextureProxy> createCompressedTextureProxy(int width, int height, SkBudgeted budgeted, 108 SkImage::CompressionType compressionType, 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&, GrColorType, GrSurfaceOrigin, 120 GrWrapOwnership, GrWrapCacheable, GrIOType, 121 ReleaseProc = nullptr, ReleaseContext = nullptr); 122 123 /* 124 * Create a texture proxy that wraps a backend texture and is both texture-able and renderable 125 */ 126 sk_sp<GrTextureProxy> wrapRenderableBackendTexture(const GrBackendTexture&, GrSurfaceOrigin, 127 int sampleCnt, GrColorType, 128 GrWrapOwnership, GrWrapCacheable, 129 ReleaseProc = nullptr, 130 ReleaseContext = nullptr); 131 132 /* 133 * Create a render target proxy that wraps a backend render target 134 */ 135 sk_sp<GrSurfaceProxy> wrapBackendRenderTarget(const GrBackendRenderTarget&, GrColorType, 136 GrSurfaceOrigin, 137 ReleaseProc = nullptr, ReleaseContext = nullptr); 138 139 /* 140 * Create a render target proxy that wraps a backend texture 141 */ 142 sk_sp<GrSurfaceProxy> wrapBackendTextureAsRenderTarget(const GrBackendTexture&, 143 GrColorType, 144 GrSurfaceOrigin, 145 int sampleCnt); 146 147 sk_sp<GrRenderTargetProxy> wrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&, 148 const GrVkDrawableInfo&); 149 150 using LazyInstantiationKeyMode = GrSurfaceProxy::LazyInstantiationKeyMode; 151 using LazyInstantiationResult = GrSurfaceProxy::LazyInstantiationResult; 152 using LazyInstantiateCallback = GrSurfaceProxy::LazyInstantiateCallback; 153 154 struct TextureInfo { 155 GrMipMapped fMipMapped; 156 GrTextureType fTextureType; 157 }; 158 159 using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType; 160 /** 161 * Creates a texture proxy that will be instantiated by a user-supplied callback during flush. 162 * (Stencil is not supported by this method.) The width and height must either both be greater 163 * than 0 or both less than or equal to zero. A non-positive value is a signal that the width 164 * and height are currently unknown. 165 * 166 * When called, the callback must be able to cleanup any resources that it captured at creation. 167 * It also must support being passed in a null GrResourceProvider. When this happens, the 168 * callback should cleanup any resources it captured and return an empty sk_sp<GrTextureProxy>. 169 */ 170 sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&, 171 const GrSurfaceDesc&, GrRenderable, 172 int renderTargetSampleCnt, GrSurfaceOrigin, 173 GrMipMapped, GrMipMapsStatus, GrInternalSurfaceFlags, 174 SkBackingFit, SkBudgeted, GrProtected, 175 LazyInstantiationType); 176 177 sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&, 178 const GrSurfaceDesc&, GrRenderable, 179 int renderTargetSampleCnt, GrSurfaceOrigin, GrMipMapped, 180 GrMipMapsStatus, GrInternalSurfaceFlags, SkBackingFit, 181 SkBudgeted, GrProtected); 182 183 sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&, 184 const GrSurfaceDesc&, GrRenderable, 185 int renderTargetSampleCnt, GrSurfaceOrigin, GrMipMapped, 186 GrMipMapsStatus, SkBackingFit, SkBudgeted, GrProtected); 187 188 /** A null TextureInfo indicates a non-textureable render target. */ 189 sk_sp<GrRenderTargetProxy> createLazyRenderTargetProxy(LazyInstantiateCallback&&, 190 const GrBackendFormat&, 191 const GrSurfaceDesc&, 192 int renderTargetSampleCnt, 193 GrSurfaceOrigin origin, 194 GrInternalSurfaceFlags, 195 const TextureInfo*, GrMipMapsStatus, 196 SkBackingFit, SkBudgeted, GrProtected, 197 bool wrapsVkSecondaryCB); 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&, GrRenderable, 205 int renderTargetSampleCnt, GrProtected, 206 GrSurfaceOrigin, GrPixelConfig, const GrCaps&); 207 208 // 'proxy' is about to be used as a texture src or drawn to. This query can be used to 209 // determine if it is going to need a texture domain or a full clear. 210 static bool IsFunctionallyExact(GrSurfaceProxy* proxy); 211 212 enum class InvalidateGPUResource : bool { kNo = false, kYes = true }; 213 214 /* 215 * This method ensures that, if a proxy w/ the supplied unique key exists, it is removed from 216 * the proxy provider's map and its unique key is removed. If 'invalidateSurface' is true, it 217 * will independently ensure that the unique key is removed from any GrGpuResources that may 218 * have it. 219 * 220 * If 'proxy' is provided (as an optimization to stop re-looking it up), its unique key must be 221 * valid and match the provided unique key. 222 * 223 * This method is called if either the proxy attached to the unique key is being deleted 224 * (in which case we don't want it cluttering up the hash table) or the client has indicated 225 * that it will never refer to the unique key again. 226 */ 227 void processInvalidUniqueKey(const GrUniqueKey&, GrTextureProxy*, InvalidateGPUResource); 228 229 // TODO: remove these entry points - it is a bit sloppy to be getting context info from here 230 uint32_t contextID() const; 231 const GrCaps* caps() const; 232 sk_sp<const GrCaps> refCaps() const; 233 234 int numUniqueKeyProxies_TestOnly() const; 235 236 // This is called on a DDL's proxyprovider when the DDL is finished. The uniquely keyed 237 // proxies need to keep their unique key but cannot hold on to the proxy provider unique 238 // pointer. 239 void orphanAllUniqueKeys(); 240 // This is only used by GrContext::releaseResourcesAndAbandonContext() 241 void removeAllUniqueKeys(); 242 243 /** 244 * Does the proxy provider have access to a GrDirectContext? If so, proxies will be 245 * instantiated immediately. 246 */ 247 bool renderingDirectly() const; 248 249 #if GR_TEST_UTILS 250 /* 251 * Create a texture proxy that is backed by an instantiated GrSurface. 252 * TODO: Remove GrColorType. Currently used to infer a GrPixelConfig. 253 */ 254 sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(const SkISize& size, 255 GrColorType colorType, 256 const GrBackendFormat& format, 257 GrRenderable renderable, 258 int renderTargetSampleCnt, 259 GrSurfaceOrigin origin, 260 SkBackingFit fit, 261 SkBudgeted budgeted, 262 GrProtected isProtected); 263 264 /** Version of above that picks the default format for the color type. */ 265 sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(const SkISize& size, 266 GrColorType colorType, 267 GrRenderable renderable, 268 int renderTargetSampleCnt, 269 GrSurfaceOrigin origin, 270 SkBackingFit fit, 271 SkBudgeted budgeted, 272 GrProtected isProtected); 273 274 sk_sp<GrTextureProxy> testingOnly_createWrapped(sk_sp<GrTexture>, GrColorType, GrSurfaceOrigin); 275 #endif 276 277 private: 278 friend class GrAHardwareBufferImageGenerator; // for createWrapped 279 friend class GrResourceProvider; // for createWrapped 280 281 bool isAbandoned() const; 282 283 // GrColorType is used to determine the proxy's texture swizzle. 284 sk_sp<GrTextureProxy> createWrapped(sk_sp<GrTexture> tex, GrColorType, GrSurfaceOrigin origin); 285 286 struct UniquelyKeyedProxyHashTraits { GetKeyUniquelyKeyedProxyHashTraits287 static const GrUniqueKey& GetKey(const GrTextureProxy& p) { return p.getUniqueKey(); } 288 HashUniquelyKeyedProxyHashTraits289 static uint32_t Hash(const GrUniqueKey& key) { return key.hash(); } 290 }; 291 typedef SkTDynamicHash<GrTextureProxy, GrUniqueKey, UniquelyKeyedProxyHashTraits> UniquelyKeyedProxyHash; 292 293 // This holds the texture proxies that have unique keys. The resourceCache does not get a ref 294 // on these proxies but they must send a message to the resourceCache when they are deleted. 295 UniquelyKeyedProxyHash fUniquelyKeyedProxies; 296 297 GrImageContext* fImageContext; 298 }; 299 300 #endif 301