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 "GrResourceKey.h" 12 #include "GrTextureProxy.h" 13 #include "GrTypes.h" 14 #include "SkTDynamicHash.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. 56 */ 57 sk_sp<GrTextureProxy> findOrCreateProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin); 58 59 /* 60 * Create an un-mipmapped texture proxy with data. The SkImage must be a raster backend image. 61 * Since the SkImage is ref counted, we simply take a ref on it to keep the data alive until we 62 * actually upload the data to the gpu. 63 */ 64 sk_sp<GrTextureProxy> createTextureProxy( 65 sk_sp<SkImage> srcImage, GrSurfaceDescFlags, int sampleCnt, SkBudgeted, SkBackingFit, 66 GrInternalSurfaceFlags = GrInternalSurfaceFlags::kNone); 67 68 /* 69 * Create a mipmapped texture proxy without any data. 70 * 71 * Like the call above but there are no texels to upload. A texture proxy is returned that 72 * simply has space allocated for the mips. We will allocated the full amount of mip levels 73 * based on the width and height in the GrSurfaceDesc. 74 */ 75 sk_sp<GrTextureProxy> createMipMapProxy(const GrBackendFormat&, const GrSurfaceDesc&, 76 GrSurfaceOrigin, SkBudgeted); 77 78 /* 79 * Creates a new mipmapped texture proxy for the bitmap with mip levels generated by the cpu. 80 */ 81 sk_sp<GrTextureProxy> createMipMapProxyFromBitmap(const SkBitmap& bitmap); 82 83 /* 84 * Create a GrSurfaceProxy without any data. 85 */ 86 sk_sp<GrTextureProxy> createProxy(const GrBackendFormat&, const GrSurfaceDesc&, GrSurfaceOrigin, 87 GrMipMapped, SkBackingFit, SkBudgeted, 88 GrInternalSurfaceFlags); 89 90 sk_sp<GrTextureProxy> createProxy( 91 const GrBackendFormat& format, const GrSurfaceDesc& desc, 92 GrSurfaceOrigin origin, SkBackingFit fit, SkBudgeted budgeted, 93 GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone) { 94 return this->createProxy(format, desc, origin, GrMipMapped::kNo, fit, budgeted, 95 surfaceFlags); 96 } 97 98 /* 99 * Create a texture proxy with data. It's assumed that the data is packed tightly. 100 */ 101 sk_sp<GrTextureProxy> createProxy(sk_sp<SkData>, const GrSurfaceDesc& desc); 102 103 // These match the definitions in SkImage & GrTexture.h, for whence they came 104 typedef void* ReleaseContext; 105 typedef void (*ReleaseProc)(ReleaseContext); 106 107 /* 108 * Create a texture proxy that wraps a (non-renderable) backend texture. GrIOType must be 109 * kRead or kRW. 110 */ 111 sk_sp<GrTextureProxy> wrapBackendTexture(const GrBackendTexture&, GrSurfaceOrigin, 112 GrWrapOwnership, GrWrapCacheable, GrIOType, 113 ReleaseProc = nullptr, ReleaseContext = nullptr); 114 115 /* 116 * Create a texture proxy that wraps a backend texture and is both texture-able and renderable 117 */ 118 sk_sp<GrTextureProxy> wrapRenderableBackendTexture(const GrBackendTexture&, GrSurfaceOrigin, 119 int sampleCnt, GrWrapOwnership, 120 GrWrapCacheable, ReleaseProc, 121 ReleaseContext); 122 123 /* 124 * Create a render target proxy that wraps a backend render target 125 */ 126 sk_sp<GrSurfaceProxy> wrapBackendRenderTarget(const GrBackendRenderTarget&, GrSurfaceOrigin, 127 ReleaseProc, ReleaseContext); 128 129 /* 130 * Create a render target proxy that wraps a backend texture 131 */ 132 sk_sp<GrSurfaceProxy> wrapBackendTextureAsRenderTarget(const GrBackendTexture& backendTex, 133 GrSurfaceOrigin origin, 134 int sampleCnt); 135 136 sk_sp<GrRenderTargetProxy> wrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&, 137 const GrVkDrawableInfo&); 138 139 using LazyInstantiateCallback = std::function<sk_sp<GrSurface>(GrResourceProvider*)>; 140 141 enum class Renderable : bool { 142 kNo = false, 143 kYes = true 144 }; 145 146 struct TextureInfo { 147 GrMipMapped fMipMapped; 148 GrTextureType fTextureType; 149 }; 150 151 using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType; 152 /** 153 * Creates a texture proxy that will be instantiated by a user-supplied callback during flush. 154 * (Stencil is not supported by this method.) The width and height must either both be greater 155 * than 0 or both less than or equal to zero. A non-positive value is a signal that the width 156 * and height are currently unknown. 157 * 158 * When called, the callback must be able to cleanup any resources that it captured at creation. 159 * It also must support being passed in a null GrResourceProvider. When this happens, the 160 * callback should cleanup any resources it captured and return an empty sk_sp<GrTextureProxy>. 161 */ 162 sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&, 163 const GrSurfaceDesc&, GrSurfaceOrigin, GrMipMapped, 164 GrInternalSurfaceFlags, SkBackingFit, SkBudgeted, 165 LazyInstantiationType); 166 167 sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&, 168 const GrSurfaceDesc&, GrSurfaceOrigin, GrMipMapped, 169 GrInternalSurfaceFlags, SkBackingFit, SkBudgeted); 170 171 sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrBackendFormat&, 172 const GrSurfaceDesc&, GrSurfaceOrigin, GrMipMapped, 173 SkBackingFit, SkBudgeted); 174 175 /** A null TextureInfo indicates a non-textureable render target. */ 176 sk_sp<GrRenderTargetProxy> createLazyRenderTargetProxy(LazyInstantiateCallback&&, 177 const GrBackendFormat&, 178 const GrSurfaceDesc&, 179 GrSurfaceOrigin origin, 180 GrInternalSurfaceFlags, 181 const TextureInfo*, 182 SkBackingFit, 183 SkBudgeted, 184 bool wrapsVkSecondaryCB); 185 186 /** 187 * Fully lazy proxies have unspecified width and height. Methods that rely on those values 188 * (e.g., width, height, getBoundsRect) should be avoided. 189 */ 190 static sk_sp<GrTextureProxy> MakeFullyLazyProxy(LazyInstantiateCallback&&, 191 const GrBackendFormat&, Renderable, 192 GrSurfaceOrigin, GrPixelConfig, const GrCaps&); 193 194 // 'proxy' is about to be used as a texture src or drawn to. This query can be used to 195 // determine if it is going to need a texture domain or a full clear. 196 static bool IsFunctionallyExact(GrSurfaceProxy* proxy); 197 198 enum class InvalidateGPUResource : bool { kNo = false, kYes = true }; 199 200 /* 201 * This method ensures that, if a proxy w/ the supplied unique key exists, it is removed from 202 * the proxy provider's map and its unique key is removed. If 'invalidateSurface' is true, it 203 * will independently ensure that the unique key is removed from any GrGpuResources that may 204 * have it. 205 * 206 * If 'proxy' is provided (as an optimization to stop re-looking it up), its unique key must be 207 * valid and match the provided unique key. 208 * 209 * This method is called if either the proxy attached to the unique key is being deleted 210 * (in which case we don't want it cluttering up the hash table) or the client has indicated 211 * that it will never refer to the unique key again. 212 */ 213 void processInvalidUniqueKey(const GrUniqueKey&, GrTextureProxy*, InvalidateGPUResource); 214 215 // TODO: remove these entry points - it is a bit sloppy to be getting context info from here 216 uint32_t contextID() const; 217 const GrCaps* caps() const; 218 sk_sp<const GrCaps> refCaps() const; 219 220 int numUniqueKeyProxies_TestOnly() const; 221 222 // This is called on a DDL's proxyprovider when the DDL is finished. The uniquely keyed 223 // proxies need to keep their unique key but cannot hold on to the proxy provider unique 224 // pointer. 225 void orphanAllUniqueKeys(); 226 // This is only used by GrContext::releaseResourcesAndAbandonContext() 227 void removeAllUniqueKeys(); 228 229 /** 230 * Does the proxy provider have access to a GrDirectContext? If so, proxies will be 231 * instantiated immediately. 232 */ 233 bool renderingDirectly() const; 234 235 #if GR_TEST_UTILS 236 /* 237 * Create a texture proxy that is backed by an instantiated GrSurface. 238 */ 239 sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(const GrSurfaceDesc&, GrSurfaceOrigin, 240 SkBackingFit, SkBudgeted); 241 sk_sp<GrTextureProxy> testingOnly_createWrapped(sk_sp<GrTexture>, GrSurfaceOrigin); 242 #endif 243 244 private: 245 friend class GrAHardwareBufferImageGenerator; // for createWrapped 246 friend class GrResourceProvider; // for createWrapped 247 248 bool isAbandoned() const; 249 250 sk_sp<GrTextureProxy> createWrapped(sk_sp<GrTexture> tex, GrSurfaceOrigin origin); 251 252 struct UniquelyKeyedProxyHashTraits { GetKeyUniquelyKeyedProxyHashTraits253 static const GrUniqueKey& GetKey(const GrTextureProxy& p) { return p.getUniqueKey(); } 254 HashUniquelyKeyedProxyHashTraits255 static uint32_t Hash(const GrUniqueKey& key) { return key.hash(); } 256 }; 257 typedef SkTDynamicHash<GrTextureProxy, GrUniqueKey, UniquelyKeyedProxyHashTraits> UniquelyKeyedProxyHash; 258 259 // This holds the texture proxies that have unique keys. The resourceCache does not get a ref 260 // on these proxies but they must send a message to the resourceCache when they are deleted. 261 UniquelyKeyedProxyHash fUniquelyKeyedProxies; 262 263 GrImageContext* fImageContext; 264 }; 265 266 #endif 267