| 1 | /* | 
|---|
| 2 | * Copyright 2016 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 GrSurfaceProxy_DEFINED | 
|---|
| 9 | #define GrSurfaceProxy_DEFINED | 
|---|
| 10 |  | 
|---|
| 11 | #include "include/core/SkRect.h" | 
|---|
| 12 | #include "include/gpu/GrBackendSurface.h" | 
|---|
| 13 | #include "include/private/SkNoncopyable.h" | 
|---|
| 14 | #include "src/gpu/GrGpuResource.h" | 
|---|
| 15 | #include "src/gpu/GrNonAtomicRef.h" | 
|---|
| 16 | #include "src/gpu/GrSurface.h" | 
|---|
| 17 | #include "src/gpu/GrTexture.h" | 
|---|
| 18 |  | 
|---|
| 19 | class GrCaps; | 
|---|
| 20 | class GrContext_Base; | 
|---|
| 21 | class GrOpsTask; | 
|---|
| 22 | class GrRecordingContext; | 
|---|
| 23 | class GrRenderTargetProxy; | 
|---|
| 24 | class GrRenderTask; | 
|---|
| 25 | class GrResourceProvider; | 
|---|
| 26 | class GrSurfaceContext; | 
|---|
| 27 | class GrSurfaceProxyPriv; | 
|---|
| 28 | class GrSurfaceProxyView; | 
|---|
| 29 | class GrTextureProxy; | 
|---|
| 30 |  | 
|---|
| 31 | class GrSurfaceProxy : public SkNVRefCnt<GrSurfaceProxy> { | 
|---|
| 32 | public: | 
|---|
| 33 | virtual ~GrSurfaceProxy(); | 
|---|
| 34 |  | 
|---|
| 35 | /** | 
|---|
| 36 | * Indicates "resolutions" that need to be done on a surface before its pixels can be accessed. | 
|---|
| 37 | * If both types of resolve are requested, the MSAA resolve will happen first. | 
|---|
| 38 | */ | 
|---|
| 39 | enum class ResolveFlags { | 
|---|
| 40 | kNone = 0, | 
|---|
| 41 | kMSAA = 1 << 0,  // Blit and resolve an internal MSAA render buffer into the texture. | 
|---|
| 42 | kMipMaps = 1 << 1,  // Regenerate all mipmap levels. | 
|---|
| 43 | }; | 
|---|
| 44 |  | 
|---|
| 45 | /** | 
|---|
| 46 | * Some lazy proxy callbacks want to set their own (or no key) on the GrSurfaces they return. | 
|---|
| 47 | * Others want the GrSurface's key to be kept in sync with the proxy's key. This enum controls | 
|---|
| 48 | * the key relationship between proxies and their targets. | 
|---|
| 49 | */ | 
|---|
| 50 | enum class LazyInstantiationKeyMode { | 
|---|
| 51 | /** | 
|---|
| 52 | * Don't key the GrSurface with the proxy's key. The lazy instantiation callback is free to | 
|---|
| 53 | * return a GrSurface that already has a unique key unrelated to the proxy's key. | 
|---|
| 54 | */ | 
|---|
| 55 | kUnsynced, | 
|---|
| 56 | /** | 
|---|
| 57 | * Keep the GrSurface's unique key in sync with the proxy's unique key. The GrSurface | 
|---|
| 58 | * returned from the lazy instantiation callback must not have a unique key or have the same | 
|---|
| 59 | * same unique key as the proxy. If the proxy is later assigned a key it is in turn assigned | 
|---|
| 60 | * to the GrSurface. | 
|---|
| 61 | */ | 
|---|
| 62 | kSynced | 
|---|
| 63 | }; | 
|---|
| 64 |  | 
|---|
| 65 | struct LazyCallbackResult { | 
|---|
| 66 | LazyCallbackResult() = default; | 
|---|
| 67 | LazyCallbackResult(const LazyCallbackResult&) = default; | 
|---|
| 68 | LazyCallbackResult(LazyCallbackResult&& that) = default; | 
|---|
| 69 | LazyCallbackResult(sk_sp<GrSurface> surf, | 
|---|
| 70 | bool releaseCallback = true, | 
|---|
| 71 | LazyInstantiationKeyMode mode = LazyInstantiationKeyMode::kSynced) | 
|---|
| 72 | : fSurface(std::move(surf)), fKeyMode(mode), fReleaseCallback(releaseCallback) {} | 
|---|
| 73 | LazyCallbackResult(sk_sp<GrTexture> tex) | 
|---|
| 74 | : LazyCallbackResult(sk_sp<GrSurface>(std::move(tex))) {} | 
|---|
| 75 |  | 
|---|
| 76 | LazyCallbackResult& operator=(const LazyCallbackResult&) = default; | 
|---|
| 77 | LazyCallbackResult& operator=(LazyCallbackResult&&) = default; | 
|---|
| 78 |  | 
|---|
| 79 | sk_sp<GrSurface> fSurface; | 
|---|
| 80 | LazyInstantiationKeyMode fKeyMode = LazyInstantiationKeyMode::kSynced; | 
|---|
| 81 | /** | 
|---|
| 82 | * Should the callback be disposed of after it has returned or preserved until the proxy | 
|---|
| 83 | * is freed. Only honored if fSurface is not-null. If it is null the callback is preserved. | 
|---|
| 84 | */ | 
|---|
| 85 | bool fReleaseCallback = true; | 
|---|
| 86 | }; | 
|---|
| 87 |  | 
|---|
| 88 | using LazyInstantiateCallback = std::function<LazyCallbackResult(GrResourceProvider*)>; | 
|---|
| 89 |  | 
|---|
| 90 | enum class UseAllocator { | 
|---|
| 91 | /** | 
|---|
| 92 | * This proxy will be instantiated outside the allocator (e.g. for proxies that are | 
|---|
| 93 | * instantiated in on-flush callbacks). | 
|---|
| 94 | */ | 
|---|
| 95 | kNo = false, | 
|---|
| 96 | /** | 
|---|
| 97 | * GrResourceAllocator should instantiate this proxy. | 
|---|
| 98 | */ | 
|---|
| 99 | kYes = true, | 
|---|
| 100 | }; | 
|---|
| 101 |  | 
|---|
| 102 | bool isLazy() const { return !this->isInstantiated() && SkToBool(fLazyInstantiateCallback); } | 
|---|
| 103 |  | 
|---|
| 104 | bool isFullyLazy() const { | 
|---|
| 105 | bool result = fDimensions.width() < 0; | 
|---|
| 106 | SkASSERT(result == (fDimensions.height() < 0)); | 
|---|
| 107 | SkASSERT(!result || this->isLazy()); | 
|---|
| 108 | return result; | 
|---|
| 109 | } | 
|---|
| 110 |  | 
|---|
| 111 | SkISize dimensions() const { | 
|---|
| 112 | SkASSERT(!this->isFullyLazy()); | 
|---|
| 113 | return fDimensions; | 
|---|
| 114 | } | 
|---|
| 115 | int width() const { return this->dimensions().width(); } | 
|---|
| 116 | int height() const { return this->dimensions().height(); } | 
|---|
| 117 |  | 
|---|
| 118 | SkISize backingStoreDimensions() const; | 
|---|
| 119 |  | 
|---|
| 120 | /** | 
|---|
| 121 | * Helper that gets the width and height of the proxy as a bounding rectangle. | 
|---|
| 122 | */ | 
|---|
| 123 | SkRect getBoundsRect() const { return SkRect::Make(this->dimensions()); } | 
|---|
| 124 |  | 
|---|
| 125 | /* A perhaps faster check for this->dimensions() == this->backingStoreDimensions(). */ | 
|---|
| 126 | bool isFunctionallyExact() const; | 
|---|
| 127 |  | 
|---|
| 128 | /** | 
|---|
| 129 | * Helper that gets the dimensions the backing GrSurface will have as a bounding rectangle. | 
|---|
| 130 | */ | 
|---|
| 131 | SkRect backingStoreBoundsRect() const { | 
|---|
| 132 | return SkRect::Make(this->backingStoreDimensions()); | 
|---|
| 133 | } | 
|---|
| 134 |  | 
|---|
| 135 | const GrBackendFormat& backendFormat() const { return fFormat; } | 
|---|
| 136 |  | 
|---|
| 137 | bool isFormatCompressed(const GrCaps*) const; | 
|---|
| 138 |  | 
|---|
| 139 | class UniqueID { | 
|---|
| 140 | public: | 
|---|
| 141 | static UniqueID InvalidID() { | 
|---|
| 142 | return UniqueID(uint32_t(SK_InvalidUniqueID)); | 
|---|
| 143 | } | 
|---|
| 144 |  | 
|---|
| 145 | // wrapped | 
|---|
| 146 | explicit UniqueID(const GrGpuResource::UniqueID& id) : fID(id.asUInt()) { } | 
|---|
| 147 | // deferred and lazy-callback | 
|---|
| 148 | UniqueID() : fID(GrGpuResource::CreateUniqueID()) { } | 
|---|
| 149 |  | 
|---|
| 150 | uint32_t asUInt() const { return fID; } | 
|---|
| 151 |  | 
|---|
| 152 | bool operator==(const UniqueID& other) const { | 
|---|
| 153 | return fID == other.fID; | 
|---|
| 154 | } | 
|---|
| 155 | bool operator!=(const UniqueID& other) const { | 
|---|
| 156 | return !(*this == other); | 
|---|
| 157 | } | 
|---|
| 158 |  | 
|---|
| 159 | void makeInvalid() { fID = SK_InvalidUniqueID; } | 
|---|
| 160 | bool isInvalid() const { return SK_InvalidUniqueID == fID; } | 
|---|
| 161 |  | 
|---|
| 162 | private: | 
|---|
| 163 | explicit UniqueID(uint32_t id) : fID(id) {} | 
|---|
| 164 |  | 
|---|
| 165 | uint32_t fID; | 
|---|
| 166 | }; | 
|---|
| 167 |  | 
|---|
| 168 | /* | 
|---|
| 169 | * The contract for the uniqueID is: | 
|---|
| 170 | *   for wrapped resources: | 
|---|
| 171 | *      the uniqueID will match that of the wrapped resource | 
|---|
| 172 | * | 
|---|
| 173 | *   for deferred resources: | 
|---|
| 174 | *      the uniqueID will be different from the real resource, when it is allocated | 
|---|
| 175 | *      the proxy's uniqueID will not change across the instantiate call | 
|---|
| 176 | * | 
|---|
| 177 | *    the uniqueIDs of the proxies and the resources draw from the same pool | 
|---|
| 178 | * | 
|---|
| 179 | * What this boils down to is that the uniqueID of a proxy can be used to consistently | 
|---|
| 180 | * track/identify a proxy but should never be used to distinguish between | 
|---|
| 181 | * resources and proxies - beware! | 
|---|
| 182 | */ | 
|---|
| 183 | UniqueID uniqueID() const { return fUniqueID; } | 
|---|
| 184 |  | 
|---|
| 185 | UniqueID underlyingUniqueID() const { | 
|---|
| 186 | if (fTarget) { | 
|---|
| 187 | return UniqueID(fTarget->uniqueID()); | 
|---|
| 188 | } | 
|---|
| 189 |  | 
|---|
| 190 | return fUniqueID; | 
|---|
| 191 | } | 
|---|
| 192 |  | 
|---|
| 193 | virtual bool instantiate(GrResourceProvider*) = 0; | 
|---|
| 194 |  | 
|---|
| 195 | void deinstantiate(); | 
|---|
| 196 |  | 
|---|
| 197 | /** | 
|---|
| 198 | * Proxies that are already instantiated and whose backing surface cannot be recycled to | 
|---|
| 199 | * instantiate other proxies do not need to be considered by GrResourceAllocator. | 
|---|
| 200 | */ | 
|---|
| 201 | bool canSkipResourceAllocator() const; | 
|---|
| 202 |  | 
|---|
| 203 | /** | 
|---|
| 204 | * @return the texture proxy associated with the surface proxy, may be NULL. | 
|---|
| 205 | */ | 
|---|
| 206 | virtual GrTextureProxy* asTextureProxy() { return nullptr; } | 
|---|
| 207 | virtual const GrTextureProxy* asTextureProxy() const { return nullptr; } | 
|---|
| 208 |  | 
|---|
| 209 | /** | 
|---|
| 210 | * @return the render target proxy associated with the surface proxy, may be NULL. | 
|---|
| 211 | */ | 
|---|
| 212 | virtual GrRenderTargetProxy* asRenderTargetProxy() { return nullptr; } | 
|---|
| 213 | virtual const GrRenderTargetProxy* asRenderTargetProxy() const { return nullptr; } | 
|---|
| 214 |  | 
|---|
| 215 | bool isInstantiated() const { return SkToBool(fTarget); } | 
|---|
| 216 |  | 
|---|
| 217 | // If the proxy is already instantiated, return its backing GrTexture; if not, return null. | 
|---|
| 218 | GrSurface* peekSurface() const { return fTarget.get(); } | 
|---|
| 219 |  | 
|---|
| 220 | // If this is a texture proxy and the proxy is already instantiated, return its backing | 
|---|
| 221 | // GrTexture; if not, return null. | 
|---|
| 222 | GrTexture* peekTexture() const { return fTarget ? fTarget->asTexture() : nullptr; } | 
|---|
| 223 |  | 
|---|
| 224 | // If this is a render target proxy and the proxy is already instantiated, return its backing | 
|---|
| 225 | // GrRenderTarget; if not, return null. | 
|---|
| 226 | GrRenderTarget* peekRenderTarget() const { | 
|---|
| 227 | return fTarget ? fTarget->asRenderTarget() : nullptr; | 
|---|
| 228 | } | 
|---|
| 229 |  | 
|---|
| 230 | /** | 
|---|
| 231 | * Does the resource count against the resource budget? | 
|---|
| 232 | */ | 
|---|
| 233 | SkBudgeted isBudgeted() const { return fBudgeted; } | 
|---|
| 234 |  | 
|---|
| 235 | /** | 
|---|
| 236 | * The pixel values of this proxy's surface cannot be modified (e.g. doesn't support write | 
|---|
| 237 | * pixels or MIP map level regen). Read-only proxies also bypass interval tracking and | 
|---|
| 238 | * assignment in GrResourceAllocator. | 
|---|
| 239 | */ | 
|---|
| 240 | bool readOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kReadOnly; } | 
|---|
| 241 | bool framebufferOnly() const { | 
|---|
| 242 | return fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly; | 
|---|
| 243 | } | 
|---|
| 244 |  | 
|---|
| 245 | /** | 
|---|
| 246 | * This means surface is a multisampled render target, and internally holds a non-msaa texture | 
|---|
| 247 | * for resolving into. The render target resolves itself by blitting into this internal texture. | 
|---|
| 248 | * (asTexture() might or might not return the internal texture, but if it does, we always | 
|---|
| 249 | * resolve the render target before accessing this texture's data.) | 
|---|
| 250 | */ | 
|---|
| 251 | bool requiresManualMSAAResolve() const { | 
|---|
| 252 | return fSurfaceFlags & GrInternalSurfaceFlags::kRequiresManualMSAAResolve; | 
|---|
| 253 | } | 
|---|
| 254 |  | 
|---|
| 255 | void setLastRenderTask(GrRenderTask*); | 
|---|
| 256 | GrRenderTask* getLastRenderTask() { return fLastRenderTask; } | 
|---|
| 257 |  | 
|---|
| 258 | GrOpsTask* getLastOpsTask(); | 
|---|
| 259 |  | 
|---|
| 260 | /** | 
|---|
| 261 | * Retrieves the amount of GPU memory that will be or currently is used by this resource | 
|---|
| 262 | * in bytes. It is approximate since we aren't aware of additional padding or copies made | 
|---|
| 263 | * by the driver. | 
|---|
| 264 | * | 
|---|
| 265 | * @return the amount of GPU memory used in bytes | 
|---|
| 266 | */ | 
|---|
| 267 | size_t gpuMemorySize(const GrCaps& caps) const { | 
|---|
| 268 | SkASSERT(!this->isFullyLazy()); | 
|---|
| 269 | if (fTarget) { | 
|---|
| 270 | return fTarget->gpuMemorySize(); | 
|---|
| 271 | } | 
|---|
| 272 | if (kInvalidGpuMemorySize == fGpuMemorySize) { | 
|---|
| 273 | fGpuMemorySize = this->onUninstantiatedGpuMemorySize(caps); | 
|---|
| 274 | SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize); | 
|---|
| 275 | } | 
|---|
| 276 | return fGpuMemorySize; | 
|---|
| 277 | } | 
|---|
| 278 |  | 
|---|
| 279 | enum class RectsMustMatch : bool { | 
|---|
| 280 | kNo = false, | 
|---|
| 281 | kYes = true | 
|---|
| 282 | }; | 
|---|
| 283 |  | 
|---|
| 284 | // Helper function that creates a temporary SurfaceContext to perform the copy | 
|---|
| 285 | // The copy is is not a render target and not multisampled. | 
|---|
| 286 | // | 
|---|
| 287 | // The intended use of this copy call is simply to copy exact pixel values from one proxy to a | 
|---|
| 288 | // new one. Thus, there isn't a need for a swizzle when doing the copy. The format of the copy | 
|---|
| 289 | // will be the same as the src. Therefore, the copy can be used in a view with the same swizzle | 
|---|
| 290 | // as the original for use with a given color type. | 
|---|
| 291 | static sk_sp<GrSurfaceProxy> Copy(GrRecordingContext*, | 
|---|
| 292 | GrSurfaceProxy* src, | 
|---|
| 293 | GrSurfaceOrigin, | 
|---|
| 294 | GrMipMapped, | 
|---|
| 295 | SkIRect srcRect, | 
|---|
| 296 | SkBackingFit, | 
|---|
| 297 | SkBudgeted, | 
|---|
| 298 | RectsMustMatch = RectsMustMatch::kNo); | 
|---|
| 299 |  | 
|---|
| 300 | // Same as above Copy but copies the entire 'src' | 
|---|
| 301 | static sk_sp<GrSurfaceProxy> Copy(GrRecordingContext*, | 
|---|
| 302 | GrSurfaceProxy* src, | 
|---|
| 303 | GrSurfaceOrigin, | 
|---|
| 304 | GrMipMapped, | 
|---|
| 305 | SkBackingFit, | 
|---|
| 306 | SkBudgeted); | 
|---|
| 307 |  | 
|---|
| 308 | #if GR_TEST_UTILS | 
|---|
| 309 | int32_t testingOnly_getBackingRefCnt() const; | 
|---|
| 310 | GrInternalSurfaceFlags testingOnly_getFlags() const; | 
|---|
| 311 | #endif | 
|---|
| 312 |  | 
|---|
| 313 | SkDEBUGCODE(void validate(GrContext_Base*) const;) | 
|---|
| 314 |  | 
|---|
| 315 | // Provides access to functions that aren't part of the public API. | 
|---|
| 316 | inline GrSurfaceProxyPriv priv(); | 
|---|
| 317 | inline const GrSurfaceProxyPriv priv() const; | 
|---|
| 318 |  | 
|---|
| 319 | GrProtected isProtected() const { return fIsProtected; } | 
|---|
| 320 |  | 
|---|
| 321 | protected: | 
|---|
| 322 | // Deferred version - takes a new UniqueID from the shared resource/proxy pool. | 
|---|
| 323 | GrSurfaceProxy(const GrBackendFormat&, | 
|---|
| 324 | SkISize, | 
|---|
| 325 | SkBackingFit, | 
|---|
| 326 | SkBudgeted, | 
|---|
| 327 | GrProtected, | 
|---|
| 328 | GrInternalSurfaceFlags, | 
|---|
| 329 | UseAllocator); | 
|---|
| 330 | // Lazy-callback version - takes a new UniqueID from the shared resource/proxy pool. | 
|---|
| 331 | GrSurfaceProxy(LazyInstantiateCallback&&, | 
|---|
| 332 | const GrBackendFormat&, | 
|---|
| 333 | SkISize, | 
|---|
| 334 | SkBackingFit, | 
|---|
| 335 | SkBudgeted, | 
|---|
| 336 | GrProtected, | 
|---|
| 337 | GrInternalSurfaceFlags, | 
|---|
| 338 | UseAllocator); | 
|---|
| 339 |  | 
|---|
| 340 | // Wrapped version - shares the UniqueID of the passed surface. | 
|---|
| 341 | // Takes UseAllocator because even though this is already instantiated it still can participate | 
|---|
| 342 | // in allocation by having its backing resource recycled to other uninstantiated proxies or | 
|---|
| 343 | // not depending on UseAllocator. | 
|---|
| 344 | GrSurfaceProxy(sk_sp<GrSurface>, | 
|---|
| 345 | SkBackingFit, | 
|---|
| 346 | UseAllocator); | 
|---|
| 347 |  | 
|---|
| 348 | friend class GrSurfaceProxyPriv; | 
|---|
| 349 |  | 
|---|
| 350 | // Methods made available via GrSurfaceProxyPriv | 
|---|
| 351 | bool ignoredByResourceAllocator() const { return fIgnoredByResourceAllocator; } | 
|---|
| 352 | void setIgnoredByResourceAllocator() { fIgnoredByResourceAllocator = true; } | 
|---|
| 353 |  | 
|---|
| 354 | void computeScratchKey(const GrCaps&, GrScratchKey*) const; | 
|---|
| 355 |  | 
|---|
| 356 | virtual sk_sp<GrSurface> createSurface(GrResourceProvider*) const = 0; | 
|---|
| 357 | void assign(sk_sp<GrSurface> surface); | 
|---|
| 358 |  | 
|---|
| 359 | sk_sp<GrSurface> createSurfaceImpl(GrResourceProvider*, int sampleCnt, GrRenderable, | 
|---|
| 360 | GrMipMapped) const; | 
|---|
| 361 |  | 
|---|
| 362 | // Once the dimensions of a fully-lazy proxy are decided, and before it gets instantiated, the | 
|---|
| 363 | // client can use this optional method to specify the proxy's dimensions. (A proxy's dimensions | 
|---|
| 364 | // can be less than the GPU surface that backs it. e.g., SkBackingFit::kApprox.) Otherwise, | 
|---|
| 365 | // the proxy's dimensions will be set to match the underlying GPU surface upon instantiation. | 
|---|
| 366 | void setLazyDimensions(SkISize dimensions) { | 
|---|
| 367 | SkASSERT(this->isFullyLazy()); | 
|---|
| 368 | SkASSERT(!dimensions.isEmpty()); | 
|---|
| 369 | fDimensions = dimensions; | 
|---|
| 370 | } | 
|---|
| 371 |  | 
|---|
| 372 | bool instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt, GrRenderable, | 
|---|
| 373 | GrMipMapped, const GrUniqueKey*); | 
|---|
| 374 |  | 
|---|
| 375 | // For deferred proxies this will be null until the proxy is instantiated. | 
|---|
| 376 | // For wrapped proxies it will point to the wrapped resource. | 
|---|
| 377 | sk_sp<GrSurface>       fTarget; | 
|---|
| 378 |  | 
|---|
| 379 | // In many cases these flags aren't actually known until the proxy has been instantiated. | 
|---|
| 380 | // However, Ganesh frequently needs to change its behavior based on these settings. For | 
|---|
| 381 | // internally create proxies we will know these properties ahead of time. For wrapped | 
|---|
| 382 | // proxies we will copy the properties off of the GrSurface. For lazy proxies we force the | 
|---|
| 383 | // call sites to provide the required information ahead of time. At instantiation time | 
|---|
| 384 | // we verify that the assumed properties match the actual properties. | 
|---|
| 385 | GrInternalSurfaceFlags fSurfaceFlags; | 
|---|
| 386 |  | 
|---|
| 387 | private: | 
|---|
| 388 | // For wrapped resources, 'fFormat', 'fWidth', and 'fHeight'; will always be filled in from the | 
|---|
| 389 | // wrapped resource. | 
|---|
| 390 | const GrBackendFormat  fFormat; | 
|---|
| 391 | SkISize                fDimensions; | 
|---|
| 392 |  | 
|---|
| 393 | SkBackingFit           fFit;      // always kApprox for lazy-callback resources | 
|---|
| 394 | // always kExact for wrapped resources | 
|---|
| 395 | mutable SkBudgeted     fBudgeted; // always kYes for lazy-callback resources | 
|---|
| 396 | // set from the backing resource for wrapped resources | 
|---|
| 397 | // mutable bc of SkSurface/SkImage wishy-washiness | 
|---|
| 398 | // Only meaningful if fLazyInstantiateCallback is non-null. | 
|---|
| 399 | UseAllocator           fUseAllocator; | 
|---|
| 400 |  | 
|---|
| 401 | const UniqueID         fUniqueID; // set from the backing resource for wrapped resources | 
|---|
| 402 |  | 
|---|
| 403 | LazyInstantiateCallback fLazyInstantiateCallback; | 
|---|
| 404 |  | 
|---|
| 405 | SkDEBUGCODE(void validateSurface(const GrSurface*);) | 
|---|
| 406 | SkDEBUGCODE(virtual void onValidateSurface(const GrSurface*) = 0;) | 
|---|
| 407 |  | 
|---|
| 408 | static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0); | 
|---|
| 409 | SkDEBUGCODE(size_t getRawGpuMemorySize_debugOnly() const { return fGpuMemorySize; }) | 
|---|
| 410 |  | 
|---|
| 411 | virtual size_t onUninstantiatedGpuMemorySize(const GrCaps&) const = 0; | 
|---|
| 412 |  | 
|---|
| 413 | bool                   fIgnoredByResourceAllocator = false; | 
|---|
| 414 | GrProtected            fIsProtected; | 
|---|
| 415 |  | 
|---|
| 416 | // This entry is lazily evaluated so, when the proxy wraps a resource, the resource | 
|---|
| 417 | // will be called but, when the proxy is deferred, it will compute the answer itself. | 
|---|
| 418 | // If the proxy computes its own answer that answer is checked (in debug mode) in | 
|---|
| 419 | // the instantiation method. | 
|---|
| 420 | mutable size_t         fGpuMemorySize; | 
|---|
| 421 |  | 
|---|
| 422 | // The last GrRenderTask that wrote to or is currently going to write to this surface | 
|---|
| 423 | // The GrRenderTask can be closed (e.g., no surface context is currently bound | 
|---|
| 424 | // to this proxy). | 
|---|
| 425 | // This back-pointer is required so that we can add a dependancy between | 
|---|
| 426 | // the GrRenderTask used to create the current contents of this surface | 
|---|
| 427 | // and the GrRenderTask of a destination surface to which this one is being drawn or copied. | 
|---|
| 428 | // This pointer is unreffed. GrRenderTasks own a ref on their surface proxies. | 
|---|
| 429 | GrRenderTask*          fLastRenderTask = nullptr; | 
|---|
| 430 | }; | 
|---|
| 431 |  | 
|---|
| 432 | GR_MAKE_BITFIELD_CLASS_OPS(GrSurfaceProxy::ResolveFlags) | 
|---|
| 433 |  | 
|---|
| 434 | #endif | 
|---|
| 435 |  | 
|---|