diff options
author | Brian Salomon <bsalomon@google.com> | 2017-05-17 13:49:59 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-05-17 18:17:50 +0000 |
commit | bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14 (patch) | |
tree | e743c265e75a1dad32c1425bf3b9ed88abad2c52 | |
parent | 9f1c403362d8de6038328c7238b6ac56be552324 (diff) |
Remove GrSurfaceDesc member from GrSurfaceProxy.
Stores the config, origin, and dimensions in GrSurfaceProxy, sample count in GrRenderTargetProxy, and "was constructed with mip maps" in GrTextureProxy.
Change-Id: Iee058674dce49107a991cca9d083cd33e3572809
Reviewed-on: https://skia-review.googlesource.com/17209
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
30 files changed, 215 insertions, 158 deletions
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h index dd37c18008..668838b2d5 100644 --- a/include/gpu/GrSurface.h +++ b/include/gpu/GrSurface.h @@ -71,7 +71,7 @@ public: inline const GrSurfacePriv surfacePriv() const; static size_t WorstCaseSize(const GrSurfaceDesc& desc, bool useNextPow2 = false); - static size_t ComputeSize(const GrSurfaceDesc& desc, int colorSamplesPerPixel, + static size_t ComputeSize(GrPixelConfig config, int width, int height, int colorSamplesPerPixel, bool hasMIPMaps, bool useNextPow2 = false); protected: diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h index dd28b0f86d..6d8b000d7c 100644 --- a/include/private/GrRenderTargetProxy.h +++ b/include/private/GrRenderTargetProxy.h @@ -24,15 +24,16 @@ public: const GrRenderTargetProxy* asRenderTargetProxy() const override { return this; } // Actually instantiate the backing rendertarget, if necessary. - GrRenderTarget* instantiate(GrResourceProvider* resourceProvider); - - /** - * Returns the number of samples/pixel in the stencil buffer (Zero if non-MSAA). - */ - int numStencilSamples() const { return fDesc.fSampleCnt; } + GrSurface* instantiate(GrResourceProvider* resourceProvider) override; + GrRenderTarget* instantiateRenderTarget(GrResourceProvider* resourceProvider) { + if (auto surf = this->instantiate(resourceProvider)) { + return surf->asRenderTarget(); + } + return nullptr; + } GrFSAAType fsaaType() const { - if (!fDesc.fSampleCnt) { + if (!fSampleCnt) { SkASSERT(!(fRenderTargetFlags & GrRenderTarget::Flags::kMixedSampled)); return GrFSAAType::kNone; } @@ -40,13 +41,23 @@ public: ? GrFSAAType::kMixedSamples : GrFSAAType::kUnifiedMSAA; } + + /** + * Returns the number of samples/pixel in the stencil buffer (Zero if non-MSAA). + */ + int numStencilSamples() const { return fSampleCnt; } + /** * Returns the number of samples/pixel in the color buffer (Zero if non-MSAA or mixed sampled). */ int numColorSamples() const { - return GrFSAAType::kMixedSamples == this->fsaaType() ? 0 : fDesc.fSampleCnt; + return GrFSAAType::kMixedSamples == this->fsaaType() ? 0 : fSampleCnt; } + int worstCaseWidth() const; + + int worstCaseHeight() const; + int maxWindowRectangles(const GrCaps& caps) const; GrRenderTarget::Flags testingOnly_getFlags() const; @@ -65,8 +76,9 @@ protected: GrRenderTargetProxy(sk_sp<GrSurface>); private: - size_t onGpuMemorySize() const override; + size_t onUninstantiatedGpuMemorySize() const override; + int fSampleCnt; // For wrapped render targets the actual GrRenderTarget is stored in the GrIORefProxy class. // For deferred proxies that pointer is filled in when we need to instantiate the // deferred resource. diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h index 8b3779c4e9..bf668fcb2d 100644 --- a/include/private/GrSurfaceProxy.h +++ b/include/private/GrSurfaceProxy.h @@ -189,14 +189,12 @@ public: static sk_sp<GrTextureProxy> MakeWrappedBackend(GrContext*, GrBackendTexture&, GrSurfaceOrigin); GrSurfaceOrigin origin() const { - SkASSERT(kTopLeft_GrSurfaceOrigin == fDesc.fOrigin || - kBottomLeft_GrSurfaceOrigin == fDesc.fOrigin); - return fDesc.fOrigin; + SkASSERT(kTopLeft_GrSurfaceOrigin == fOrigin || kBottomLeft_GrSurfaceOrigin == fOrigin); + return fOrigin; } - int width() const { return fDesc.fWidth; } - int height() const { return fDesc.fHeight; } - GrPixelConfig config() const { return fDesc.fConfig; } - bool isMipMapped() const { return fDesc.fIsMipMapped; } + int width() const { return fWidth; } + int height() const { return fHeight; } + GrPixelConfig config() const { return fConfig; } class UniqueID { public: @@ -244,16 +242,13 @@ public: */ UniqueID uniqueID() const { return fUniqueID; } - GrSurface* instantiate(GrResourceProvider* resourceProvider); + virtual GrSurface* instantiate(GrResourceProvider* resourceProvider) = 0; /** * Helper that gets the width and height of the surface as a bounding rectangle. */ SkRect getBoundsRect() const { return SkRect::MakeIWH(this->width(), this->height()); } - int worstCaseWidth(const GrCaps& caps) const; - int worstCaseHeight(const GrCaps& caps) const; - /** * @return the texture proxy associated with the surface proxy, may be NULL. */ @@ -285,8 +280,11 @@ public: * @return the amount of GPU memory used in bytes */ size_t gpuMemorySize() const { + if (fTarget) { + return fTarget->gpuMemorySize(); + } if (kInvalidGpuMemorySize == fGpuMemorySize) { - fGpuMemorySize = this->onGpuMemorySize(); + fGpuMemorySize = this->onUninstantiatedGpuMemorySize(); SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize); } return fGpuMemorySize; @@ -318,14 +316,17 @@ public: protected: // Deferred version GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted, uint32_t flags) - : fDesc(desc) - , fFit(fit) - , fBudgeted(budgeted) - , fFlags(flags) - // fMipColorMode is only valid for texturable proxies - , fMipColorMode(SkDestinationSurfaceColorMode::kLegacy) - , fGpuMemorySize(kInvalidGpuMemorySize) - , fLastOpList(nullptr) { + : fConfig(desc.fConfig) + , fWidth(desc.fWidth) + , fHeight(desc.fHeight) + , fOrigin(desc.fOrigin) + , fFit(fit) + , fBudgeted(budgeted) + , fFlags(flags) + // fMipColorMode is only valid for texturable proxies + , fMipColorMode(SkDestinationSurfaceColorMode::kLegacy) + , fGpuMemorySize(kInvalidGpuMemorySize) + , fLastOpList(nullptr) { // Note: this ctor pulls a new uniqueID from the same pool at the GrGpuResources } @@ -345,8 +346,15 @@ protected: return this->internalHasPendingWrite(); } - // For wrapped resources, 'fDesc' will always be filled in from the wrapped resource. - GrSurfaceDesc fDesc; + GrSurface* instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt, + GrSurfaceFlags flags, bool isMipMapped); + + // For wrapped resources, 'fConfig', 'fWidth', 'fHeight', and 'fOrigin; will always be filled in + // from the wrapped resource. + GrPixelConfig fConfig; + int fWidth; + int fHeight; + GrSurfaceOrigin fOrigin; SkBackingFit fFit; // always exact for wrapped resources mutable SkBudgeted fBudgeted; // set from the backing resource for wrapped resources // mutable bc of SkSurface/SkImage wishy-washiness @@ -360,7 +368,7 @@ protected: SkDEBUGCODE(size_t getRawGpuMemorySize_debugOnly() const { return fGpuMemorySize; }) private: - virtual size_t onGpuMemorySize() const = 0; + virtual size_t onUninstantiatedGpuMemorySize() const = 0; // This entry is lazily evaluated so, when the proxy wraps a resource, the resource // will be called but, when the proxy is deferred, it will compute the answer itself. diff --git a/include/private/GrTextureProxy.h b/include/private/GrTextureProxy.h index e14e285d87..342e920682 100644 --- a/include/private/GrTextureProxy.h +++ b/include/private/GrTextureProxy.h @@ -22,7 +22,13 @@ public: const GrTextureProxy* asTextureProxy() const override { return this; } // Actually instantiate the backing texture, if necessary - GrTexture* instantiate(GrResourceProvider*); + GrSurface* instantiate(GrResourceProvider*) override; + GrTexture* instantiateTexture(GrResourceProvider* resourceProvider) { + if (auto surf = this->instantiate(resourceProvider)) { + return surf->asTexture(); + } + return nullptr; + } void setMipColorMode(SkDestinationSurfaceColorMode colorMode); @@ -36,6 +42,8 @@ public: } } + bool isMipMapped() const { return fIsMipMapped; } + protected: friend class GrSurfaceProxy; // for ctors @@ -46,7 +54,9 @@ protected: GrTextureProxy(sk_sp<GrSurface>); private: - size_t onGpuMemorySize() const override; + bool fIsMipMapped; + + size_t onUninstantiatedGpuMemorySize() const override; // For wrapped proxies the GrTexture pointer is stored in GrIORefProxy. // For deferred proxies that pointer will be filled in when we need to instantiate diff --git a/src/core/SkGpuBlurUtils.cpp b/src/core/SkGpuBlurUtils.cpp index e832c879a1..359cbea4ae 100644 --- a/src/core/SkGpuBlurUtils.cpp +++ b/src/core/SkGpuBlurUtils.cpp @@ -201,7 +201,7 @@ sk_sp<GrRenderTargetContext> GaussianBlur(GrContext* context, // Chrome is crashing with proxies when they need to be instantiated. // Force an instantiation here (where, in olden days, we used to require a GrTexture) // to see if the input is already un-instantiable. - GrTexture* temp = srcProxy->instantiate(context->resourceProvider()); + GrTexture* temp = srcProxy->instantiateTexture(context->resourceProvider()); if (!temp) { return nullptr; } diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 7862a8223c..1455800cbd 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -380,7 +380,7 @@ bool GrContextPriv::writeSurfacePixels(GrSurfaceContext* dst, if (tempProxy->priv().hasPendingIO()) { this->flush(tempProxy.get()); } - GrTexture* texture = tempProxy->instantiate(fContext->resourceProvider()); + GrTexture* texture = tempProxy->instantiateTexture(fContext->resourceProvider()); if (!texture) { return false; } diff --git a/src/gpu/GrCoordTransform.cpp b/src/gpu/GrCoordTransform.cpp index 79d9e98b76..4767e53d69 100644 --- a/src/gpu/GrCoordTransform.cpp +++ b/src/gpu/GrCoordTransform.cpp @@ -18,7 +18,7 @@ void GrCoordTransform::reset(GrResourceProvider* resourceProvider, const SkMatri // MDB TODO: just GrCaps is needed for this method // MDB TODO: once all the coord transforms take a proxy just store it here and // instantiate later - fTexture = proxy->instantiate(resourceProvider); + fTexture = proxy->instantiateTexture(resourceProvider); fNormalize = normalize; fReverseY = kBottomLeft_GrSurfaceOrigin == proxy->origin(); } diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp index f1f29dc9ef..0e8de3c578 100644 --- a/src/gpu/GrDrawOpAtlas.cpp +++ b/src/gpu/GrDrawOpAtlas.cpp @@ -210,7 +210,7 @@ inline bool GrDrawOpAtlas::updatePlot(GrDrawOp::Target* target, AtlasID* id, Plo // MDB TODO: this is currently fine since the atlas' proxy is always pre-instantiated. // Once it is deferred more care must be taken upon instantiation failure. - GrTexture* texture = fProxy->instantiate(fContext->resourceProvider()); + GrTexture* texture = fProxy->instantiateTexture(fContext->resourceProvider()); if (!texture) { return false; } @@ -289,7 +289,7 @@ bool GrDrawOpAtlas::addToAtlas(AtlasID* id, GrDrawOp::Target* target, int width, sk_sp<Plot> plotsp(SkRef(newPlot.get())); // MDB TODO: this is currently fine since the atlas' proxy is always pre-instantiated. // Once it is deferred more care must be taken upon instantiation failure. - GrTexture* texture = fProxy->instantiate(fContext->resourceProvider()); + GrTexture* texture = fProxy->instantiateTexture(fContext->resourceProvider()); if (!texture) { return false; } diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index 0c2485b544..b177a43003 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -308,7 +308,8 @@ sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext( if (useDIF && fContext->caps()->shaderCaps()->pathRenderingSupport() && GrFSAAType::kNone != rtp->fsaaType()) { // TODO: defer stencil buffer attachment for PathRenderingDrawContext - sk_sp<GrRenderTarget> rt(sk_ref_sp(rtp->instantiate(fContext->resourceProvider()))); + sk_sp<GrRenderTarget> rt( + sk_ref_sp(rtp->instantiateRenderTarget(fContext->resourceProvider()))); if (!rt) { return nullptr; } diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp index 1533257bad..c20ebabfb5 100644 --- a/src/gpu/GrProcessor.cpp +++ b/src/gpu/GrProcessor.cpp @@ -250,7 +250,7 @@ void GrResourceIOProcessor::TextureSampler::reset(GrResourceProvider* resourcePr // For now, end the deferral at this time. Once all the TextureSamplers are swapped over // to taking a GrSurfaceProxy just use the IORefs on the proxy - GrTexture* texture = proxy->instantiate(resourceProvider); + GrTexture* texture = proxy->instantiateTexture(resourceProvider); if (texture) { fTexture.set(SkRef(texture), kRead_GrIOType); SkASSERT(texture->texturePriv().highestFilterMode() == proxy->highestFilterMode()); @@ -267,7 +267,7 @@ void GrResourceIOProcessor::TextureSampler::reset(GrResourceProvider* resourcePr GrShaderFlags visibility) { // For now, end the deferral at this time. Once all the TextureSamplers are swapped over // to taking a GrSurfaceProxy just use the IORefs on the proxy - GrTexture* texture = proxy->instantiate(resourceProvider); + GrTexture* texture = proxy->instantiateTexture(resourceProvider); if (texture) { fTexture.set(SkRef(texture), kRead_GrIOType); SkASSERT(texture->texturePriv().highestFilterMode() == proxy->highestFilterMode()); diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 0076812845..e58b4bb06e 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -226,10 +226,8 @@ void GrRenderTargetContextPriv::absClear(const SkIRect* clearRect, const GrColor AutoCheckFlush acf(fRenderTargetContext->drawingManager()); - SkIRect rtRect = SkIRect::MakeWH(fRenderTargetContext->fRenderTargetProxy->worstCaseWidth( - *fRenderTargetContext->caps()), - fRenderTargetContext->fRenderTargetProxy->worstCaseHeight( - *fRenderTargetContext->caps())); + SkIRect rtRect = SkIRect::MakeWH(fRenderTargetContext->fRenderTargetProxy->worstCaseWidth(), + fRenderTargetContext->fRenderTargetProxy->worstCaseHeight()); if (clearRect) { if (clearRect->contains(rtRect)) { @@ -1677,7 +1675,8 @@ bool GrRenderTargetContext::setupDstTexture(GrRenderTargetProxy* rtProxy, const if (this->caps()->textureBarrierSupport()) { if (GrTextureProxy* texProxy = rtProxy->asTextureProxy()) { // MDB TODO: remove this instantiation. Blocked on making DstTexture be proxy-based - sk_sp<GrTexture> tex(sk_ref_sp(texProxy->instantiate(fContext->resourceProvider()))); + sk_sp<GrTexture> tex( + sk_ref_sp(texProxy->instantiateTexture(fContext->resourceProvider()))); if (!tex) { SkDebugf("setupDstTexture: instantiation of src texture failed.\n"); return false; // We have bigger problems now @@ -1754,7 +1753,7 @@ bool GrRenderTargetContext::setupDstTexture(GrRenderTargetProxy* rtProxy, const GrTextureProxy* copyProxy = sContext->asTextureProxy(); // MDB TODO: remove this instantiation once DstTexture is proxy-backed - sk_sp<GrTexture> copy(sk_ref_sp(copyProxy->instantiate(fContext->resourceProvider()))); + sk_sp<GrTexture> copy(sk_ref_sp(copyProxy->instantiateTexture(fContext->resourceProvider()))); if (!copy) { SkDebugf("setupDstTexture: instantiation of copied texture failed.\n"); return false; diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h index a749046d24..0f9e530b83 100644 --- a/src/gpu/GrRenderTargetContext.h +++ b/src/gpu/GrRenderTargetContext.h @@ -361,7 +361,7 @@ public: GrRenderTarget* accessRenderTarget() { // TODO: usage of this entry point needs to be reduced and potentially eliminated // since it ends the deferral of the GrRenderTarget's allocation - return fRenderTargetProxy->instantiate(fContext->resourceProvider()); + return fRenderTargetProxy->instantiateRenderTarget(fContext->resourceProvider()); } GrSurfaceProxy* asSurfaceProxy() override { return fRenderTargetProxy.get(); } diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp index 44f23d484b..099f7e5f8d 100644 --- a/src/gpu/GrRenderTargetProxy.cpp +++ b/src/gpu/GrRenderTargetProxy.cpp @@ -13,17 +13,19 @@ #include "GrRenderTargetPriv.h" #include "GrResourceProvider.h" #include "GrTextureRenderTargetProxy.h" +#include "SkMathPriv.h" // Deferred version // TODO: we can probably munge the 'desc' in both the wrapped and deferred // cases to make the sampleConfig/numSamples stuff more rational. GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted, uint32_t flags) - : INHERITED(desc, fit, budgeted, flags) - , fRenderTargetFlags(GrRenderTarget::Flags::kNone) { + : INHERITED(desc, fit, budgeted, flags) + , fSampleCnt(desc.fSampleCnt) + , fRenderTargetFlags(GrRenderTarget::Flags::kNone) { // Since we know the newly created render target will be internal, we are able to precompute // what the flags will ultimately end up being. - if (caps.usesMixedSamples() && fDesc.fSampleCnt > 0) { + if (caps.usesMixedSamples() && fSampleCnt > 0) { fRenderTargetFlags |= GrRenderTarget::Flags::kMixedSampled; } if (caps.maxWindowRectangles() > 0) { @@ -33,9 +35,9 @@ GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc // Wrapped version GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface> surf) - : INHERITED(std::move(surf), SkBackingFit::kExact) - , fRenderTargetFlags(fTarget->asRenderTarget()->renderTargetPriv().flags()) { -} + : INHERITED(std::move(surf), SkBackingFit::kExact) + , fSampleCnt(fTarget->asRenderTarget()->numStencilSamples()) + , fRenderTargetFlags(fTarget->asRenderTarget()->renderTargetPriv().flags()) {} int GrRenderTargetProxy::maxWindowRectangles(const GrCaps& caps) const { return (fRenderTargetFlags & GrRenderTarget::Flags::kWindowRectsSupport) @@ -43,27 +45,48 @@ int GrRenderTargetProxy::maxWindowRectangles(const GrCaps& caps) const { : 0; } -GrRenderTarget* GrRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) { - SkASSERT(fDesc.fFlags & GrSurfaceFlags::kRenderTarget_GrSurfaceFlag); +GrSurface* GrRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) { + static constexpr GrSurfaceFlags kFlags = kRenderTarget_GrSurfaceFlag; - GrSurface* surf = INHERITED::instantiate(resourceProvider); - if (!surf || !surf->asRenderTarget()) { + GrSurface* surf = this->instantiateImpl(resourceProvider, fSampleCnt, kFlags, + /* isMipped = */ false); + if (!surf) { return nullptr; } - + SkASSERT(surf->asRenderTarget()); // Check that our a priori computation matched the ultimate reality SkASSERT(fRenderTargetFlags == surf->asRenderTarget()->renderTargetPriv().flags()); - return surf->asRenderTarget(); + return surf; } -size_t GrRenderTargetProxy::onGpuMemorySize() const { +int GrRenderTargetProxy::worstCaseWidth() const { if (fTarget) { - return fTarget->gpuMemorySize(); + return fTarget->width(); + } + + if (SkBackingFit::kExact == fFit) { + return fWidth; } + return SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(fWidth)); +} + +int GrRenderTargetProxy::worstCaseHeight() const { + if (fTarget) { + return fTarget->height(); + } + + if (SkBackingFit::kExact == fFit) { + return fHeight; + } + return SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(fHeight)); +} +size_t GrRenderTargetProxy::onUninstantiatedGpuMemorySize() const { + int colorSamplesPerPixel = this->numColorSamples() + 1; // TODO: do we have enough information to improve this worst case estimate? - return GrSurface::ComputeSize(fDesc, fDesc.fSampleCnt+1, false, SkBackingFit::kApprox == fFit); + return GrSurface::ComputeSize(fConfig, fWidth, fHeight, colorSamplesPerPixel, false, + SkBackingFit::kApprox == fFit); } bool GrRenderTargetProxy::refsWrappedObjects() const { diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp index ad92abfb77..a46ecb63dd 100644 --- a/src/gpu/GrResourceProvider.cpp +++ b/src/gpu/GrResourceProvider.cpp @@ -293,7 +293,7 @@ void GrResourceProvider::assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextur return; } - GrTexture* texture = proxy->instantiate(this); + GrTexture* texture = proxy->instantiateTexture(this); if (!texture) { return; } diff --git a/src/gpu/GrSurface.cpp b/src/gpu/GrSurface.cpp index aae3f23362..26584285b8 100644 --- a/src/gpu/GrSurface.cpp +++ b/src/gpu/GrSurface.cpp @@ -51,20 +51,22 @@ size_t GrSurface::WorstCaseSize(const GrSurfaceDesc& desc, bool useNextPow2) { return size; } -size_t GrSurface::ComputeSize(const GrSurfaceDesc& desc, +size_t GrSurface::ComputeSize(GrPixelConfig config, + int width, + int height, int colorSamplesPerPixel, bool hasMIPMaps, bool useNextPow2) { size_t colorSize; - int width = useNextPow2 ? GrNextPow2(desc.fWidth) : desc.fWidth; - int height = useNextPow2 ? GrNextPow2(desc.fHeight) : desc.fHeight; + width = useNextPow2 ? GrNextPow2(width) : width; + height = useNextPow2 ? GrNextPow2(height) : height; - SkASSERT(kUnknown_GrPixelConfig != desc.fConfig); - if (GrPixelConfigIsCompressed(desc.fConfig)) { - colorSize = GrCompressedFormatDataSize(desc.fConfig, width, height); + SkASSERT(kUnknown_GrPixelConfig != config); + if (GrPixelConfigIsCompressed(config)) { + colorSize = GrCompressedFormatDataSize(config, width, height); } else { - colorSize = (size_t) width * height * GrBytesPerPixel(desc.fConfig); + colorSize = (size_t)width * height * GrBytesPerPixel(config); } SkASSERT(colorSize > 0); @@ -75,8 +77,6 @@ size_t GrSurface::ComputeSize(const GrSurfaceDesc& desc, // we'd expect because we never change fDesc.fWidth/fHeight. finalSize += colorSize/3; } - - SkASSERT(finalSize <= WorstCaseSize(desc, useNextPow2)); return finalSize; } diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index 43a650fb4e..a9abb16ea9 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -21,15 +21,17 @@ #include "SkMathPriv.h" GrSurfaceProxy::GrSurfaceProxy(sk_sp<GrSurface> surface, SkBackingFit fit) - : INHERITED(std::move(surface)) - , fDesc(fTarget->desc()) - , fFit(fit) - , fBudgeted(fTarget->resourcePriv().isBudgeted()) - , fFlags(0) - , fUniqueID(fTarget->uniqueID()) // Note: converting from unique resource ID to a proxy ID! - , fGpuMemorySize(kInvalidGpuMemorySize) - , fLastOpList(nullptr) { -} + : INHERITED(std::move(surface)) + , fConfig(fTarget->config()) + , fWidth(fTarget->width()) + , fHeight(fTarget->height()) + , fOrigin(fTarget->origin()) + , fFit(fit) + , fBudgeted(fTarget->resourcePriv().isBudgeted()) + , fFlags(0) + , fUniqueID(fTarget->uniqueID()) // Note: converting from unique resource ID to a proxy ID! + , fGpuMemorySize(kInvalidGpuMemorySize) + , fLastOpList(nullptr) {} GrSurfaceProxy::~GrSurfaceProxy() { // For this to be deleted the opList that held a ref on it (if there was one) must have been @@ -37,15 +39,24 @@ GrSurfaceProxy::~GrSurfaceProxy() { SkASSERT(!fLastOpList); } -GrSurface* GrSurfaceProxy::instantiate(GrResourceProvider* resourceProvider) { +GrSurface* GrSurfaceProxy::instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt, + GrSurfaceFlags flags, bool isMipMapped) { if (fTarget) { return fTarget; } + GrSurfaceDesc desc; + desc.fConfig = fConfig; + desc.fWidth = fWidth; + desc.fHeight = fHeight; + desc.fOrigin = fOrigin; + desc.fSampleCnt = sampleCnt; + desc.fIsMipMapped = isMipMapped; + desc.fFlags = flags; if (SkBackingFit::kApprox == fFit) { - fTarget = resourceProvider->createApproxTexture(fDesc, fFlags); + fTarget = resourceProvider->createApproxTexture(desc, fFlags); } else { - fTarget = resourceProvider->createTexture(fDesc, fBudgeted, fFlags).release(); + fTarget = resourceProvider->createTexture(desc, fBudgeted, fFlags).release(); } if (!fTarget) { return nullptr; @@ -63,38 +74,6 @@ GrSurface* GrSurfaceProxy::instantiate(GrResourceProvider* resourceProvider) { return fTarget; } -int GrSurfaceProxy::worstCaseWidth(const GrCaps& caps) const { - if (fTarget) { - return fTarget->width(); - } - - if (SkBackingFit::kExact == fFit) { - return fDesc.fWidth; - } - - if (caps.reuseScratchTextures() || fDesc.fFlags & kRenderTarget_GrSurfaceFlag) { - return SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(fDesc.fWidth)); - } - - return fDesc.fWidth; -} - -int GrSurfaceProxy::worstCaseHeight(const GrCaps& caps) const { - if (fTarget) { - return fTarget->height(); - } - - if (SkBackingFit::kExact == fFit) { - return fDesc.fHeight; - } - - if (caps.reuseScratchTextures() || fDesc.fFlags & kRenderTarget_GrSurfaceFlag) { - return SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(fDesc.fHeight)); - } - - return fDesc.fHeight; -} - void GrSurfaceProxy::setLastOpList(GrOpList* opList) { #ifdef SK_DEBUG if (fLastOpList) { @@ -303,8 +282,8 @@ void GrSurfaceProxyPriv::exactify() { // obliterating the area of interest information. This call (exactify) only used // when converting an SkSpecialImage to an SkImage so the proxy shouldn't be // used for additional draws. - fProxy->fDesc.fWidth = fProxy->fTarget->width(); - fProxy->fDesc.fHeight = fProxy->fTarget->height(); + fProxy->fWidth = fProxy->fTarget->width(); + fProxy->fHeight = fProxy->fTarget->height(); return; } diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp index 6609fa61e3..0aa1ac07a6 100644 --- a/src/gpu/GrTexture.cpp +++ b/src/gpu/GrTexture.cpp @@ -36,7 +36,8 @@ void GrTexture::dirtyMipMaps(bool mipMapsDirty) { } size_t GrTexture::onGpuMemorySize() const { - return GrSurface::ComputeSize(fDesc, 1, this->texturePriv().hasMipMaps()); + return GrSurface::ComputeSize(this->config(), this->width(), this->height(), 1, + this->texturePriv().hasMipMaps(), false); } void GrTexture::validateDesc() const { diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp index 7557712c12..7ecd50bee8 100644 --- a/src/gpu/GrTextureProxy.cpp +++ b/src/gpu/GrTextureProxy.cpp @@ -12,21 +12,23 @@ GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, SkBackingFit fit, SkBudgeted budgeted, const void* srcData, size_t /*rowBytes*/, uint32_t flags) - : INHERITED(srcDesc, fit, budgeted, flags) { - SkASSERT(!srcData); // currently handled in Make() + : INHERITED(srcDesc, fit, budgeted, flags) + , fIsMipMapped(srcDesc.fIsMipMapped) { + SkASSERT(!srcData); // currently handled in Make() } GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf) - : INHERITED(std::move(surf), SkBackingFit::kExact) { -} + : INHERITED(std::move(surf), SkBackingFit::kExact) + , fIsMipMapped(fTarget->asTexture()->texturePriv().hasMipMaps()) {} -GrTexture* GrTextureProxy::instantiate(GrResourceProvider* resourceProvider) { - GrSurface* surf = this->INHERITED::instantiate(resourceProvider); +GrSurface* GrTextureProxy::instantiate(GrResourceProvider* resourceProvider) { + GrSurface* surf = + this->instantiateImpl(resourceProvider, 0, kNone_GrSurfaceFlags, fIsMipMapped); if (!surf) { return nullptr; } - - return fTarget->asTexture(); + SkASSERT(surf->asTexture()); + return surf; } void GrTextureProxy::setMipColorMode(SkDestinationSurfaceColorMode colorMode) { @@ -56,12 +58,10 @@ GrSamplerParams::FilterMode GrTextureProxy::highestFilterMode() const { return GrSamplerParams::kMipMap_FilterMode; } -size_t GrTextureProxy::onGpuMemorySize() const { - if (fTarget) { - return fTarget->gpuMemorySize(); - } - +size_t GrTextureProxy::onUninstantiatedGpuMemorySize() const { static const bool kHasMipMaps = true; - // TODO: add tracking of mipmap state to improve the estimate - return GrSurface::ComputeSize(fDesc, 1, kHasMipMaps, SkBackingFit::kApprox == fFit); + // TODO: add tracking of mipmap state to improve the estimate. We track whether we are created + // with mip maps but not whether a texture read from the proxy will lazily generate mip maps. + return GrSurface::ComputeSize(fConfig, fWidth, fHeight, 1, kHasMipMaps, + SkBackingFit::kApprox == fFit); } diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp index 432d00854f..4f1c420830 100644 --- a/src/gpu/GrTextureRenderTargetProxy.cpp +++ b/src/gpu/GrTextureRenderTargetProxy.cpp @@ -32,12 +32,28 @@ GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(sk_sp<GrSurface> surf) SkASSERT(surf->asRenderTarget()); } -size_t GrTextureRenderTargetProxy::onGpuMemorySize() const { - if (fTarget) { - return fTarget->gpuMemorySize(); - } +size_t GrTextureRenderTargetProxy::onUninstantiatedGpuMemorySize() const { + int colorSamplesPerPixel = this->numColorSamples() + 1; + + static const bool kHasMipMaps = true; + // TODO: add tracking of mipmap state to improve the estimate. We track whether we are created + // with mip maps but not whether a texture read from the proxy will lazily generate mip maps. // TODO: do we have enough information to improve this worst case estimate? - return GrSurface::ComputeSize(fDesc, fDesc.fSampleCnt+1, true, SkBackingFit::kApprox == fFit); + return GrSurface::ComputeSize(fConfig, fWidth, fHeight, colorSamplesPerPixel, kHasMipMaps, + SkBackingFit::kApprox == fFit); } +GrSurface* GrTextureRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) { + static constexpr GrSurfaceFlags kFlags = kRenderTarget_GrSurfaceFlag; + + GrSurface* surf = this->instantiateImpl(resourceProvider, this->numStencilSamples(), kFlags, + this->isMipMapped()); + if (!surf) { + return nullptr; + } + SkASSERT(surf->asRenderTarget()); + SkASSERT(surf->asTexture()); + + return surf; +} diff --git a/src/gpu/GrTextureRenderTargetProxy.h b/src/gpu/GrTextureRenderTargetProxy.h index 09aef756e1..992e319770 100644 --- a/src/gpu/GrTextureRenderTargetProxy.h +++ b/src/gpu/GrTextureRenderTargetProxy.h @@ -32,7 +32,9 @@ private: // Wrapped version GrTextureRenderTargetProxy(sk_sp<GrSurface>); - size_t onGpuMemorySize() const override; + GrSurface* instantiate(GrResourceProvider*) override; + + size_t onUninstantiatedGpuMemorySize() const override; }; #ifdef SK_BUILD_FOR_WIN diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h index 7d5232c3e0..8e0e4b0fb1 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.h +++ b/src/gpu/effects/GrSimpleTextureEffect.h @@ -28,7 +28,7 @@ public: // MDB TODO: remove this instantiation once instantiation is pushed past the // TextureSamplers. Instantiation failure in the TextureSampler is difficult to // recover from. - GrTexture* temp = proxy->instantiate(resourceProvider); + GrTexture* temp = proxy->instantiateTexture(resourceProvider); if (!temp) { return nullptr; } @@ -48,7 +48,7 @@ public: // MDB TODO: remove this instantiation once instantiation is pushed past the // TextureSamplers. Instantiation failure in the TextureSampler is difficult to // recover from. - GrTexture* temp = proxy->instantiate(resourceProvider); + GrTexture* temp = proxy->instantiateTexture(resourceProvider); if (!temp) { return nullptr; } @@ -67,7 +67,7 @@ public: // MDB TODO: remove this instantiation once instantiation is pushed past the // TextureSamplers. Instantiation failure in the TextureSampler is difficult to // recover from. - GrTexture* temp = proxy->instantiate(resourceProvider); + GrTexture* temp = proxy->instantiateTexture(resourceProvider); if (!temp) { return nullptr; } diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp index 09c2851d56..7d45ceb619 100644 --- a/src/gpu/gl/GrGLRenderTarget.cpp +++ b/src/gpu/gl/GrGLRenderTarget.cpp @@ -83,7 +83,8 @@ sk_sp<GrGLRenderTarget> GrGLRenderTarget::MakeWrapped(GrGLGpu* gpu, } size_t GrGLRenderTarget::onGpuMemorySize() const { - return GrSurface::ComputeSize(fDesc, fNumSamplesOwnedPerPixel, false); + return GrSurface::ComputeSize(this->config(), this->width(), this->height(), + fNumSamplesOwnedPerPixel, false); } bool GrGLRenderTarget::completeStencilAttachment() { @@ -188,7 +189,8 @@ void GrGLRenderTarget::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) // Log any renderbuffer's contribution to memory. We only do this if we own the renderbuffer // (have a fMSColorRenderbufferID). if (fMSColorRenderbufferID) { - size_t size = GrSurface::ComputeSize(fDesc, this->msaaSamples(), false); + size_t size = GrSurface::ComputeSize(this->config(), this->width(), this->height(), + this->msaaSamples(), false); // Due to this resource having both a texture and a renderbuffer component, dump as // skia/gpu_resources/resource_#/renderbuffer diff --git a/src/gpu/gl/GrGLTextureRenderTarget.h b/src/gpu/gl/GrGLTextureRenderTarget.h index 7ff8d490e0..0d3b19daed 100644 --- a/src/gpu/gl/GrGLTextureRenderTarget.h +++ b/src/gpu/gl/GrGLTextureRenderTarget.h @@ -70,7 +70,7 @@ private: } size_t onGpuMemorySize() const override { - return GrSurface::ComputeSize(fDesc, + return GrSurface::ComputeSize(this->config(), this->width(), this->height(), this->numSamplesOwnedPerPixel(), this->texturePriv().hasMipMaps()); } diff --git a/src/gpu/vk/GrVkRenderTarget.h b/src/gpu/vk/GrVkRenderTarget.h index cf425fb0a2..272998e317 100644 --- a/src/gpu/vk/GrVkRenderTarget.h +++ b/src/gpu/vk/GrVkRenderTarget.h @@ -100,7 +100,9 @@ protected: size_t onGpuMemorySize() const override { // The plus 1 is to account for the resolve texture. // TODO: is this still correct? - return GrSurface::ComputeSize(fDesc, fDesc.fSampleCnt+1, false); + int numColorSamples = this->numColorSamples() + 1; + return GrSurface::ComputeSize(this->config(), this->width(), this->height(), + numColorSamples, false); } void createFramebuffer(GrVkGpu* gpu); diff --git a/src/gpu/vk/GrVkTextureRenderTarget.h b/src/gpu/vk/GrVkTextureRenderTarget.h index 2877a36265..03f9fdbbb1 100644 --- a/src/gpu/vk/GrVkTextureRenderTarget.h +++ b/src/gpu/vk/GrVkTextureRenderTarget.h @@ -115,7 +115,9 @@ private: // GrGLRenderTarget accounts for the texture's memory and any MSAA renderbuffer's memory. size_t onGpuMemorySize() const override { // The plus 1 is to account for the resolve texture. - return GrSurface::ComputeSize(fDesc, fDesc.fSampleCnt+1, // TODO: this still correct? + int numColorSamples = this->numColorSamples() + 1; + return GrSurface::ComputeSize(this->config(), this->width(), this->height(), + numColorSamples, // TODO: this still correct? this->texturePriv().hasMipMaps()); } }; diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 5327e5ebd4..efdd2d7468 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -171,7 +171,7 @@ GrTexture* SkImage_Gpu::onGetTexture() const { return nullptr; } - return proxy->instantiate(fContext->resourceProvider()); + return proxy->instantiateTexture(fContext->resourceProvider()); } bool SkImage_Gpu::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB, @@ -486,7 +486,7 @@ sk_sp<SkImage> SkImage::MakeCrossContextFromEncoded(GrContext* context, sk_sp<Sk return codecImage; } - sk_sp<GrTexture> texture(sk_ref_sp(proxy->instantiate(context->resourceProvider()))); + sk_sp<GrTexture> texture(sk_ref_sp(proxy->instantiateTexture(context->resourceProvider()))); if (!texture) { return codecImage; } diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h index 5c3ed5a1fd..273f93e5c5 100644 --- a/src/image/SkImage_Gpu.h +++ b/src/image/SkImage_Gpu.h @@ -36,7 +36,7 @@ public: return fProxy.get(); } GrTexture* peekTexture() const override { - return fProxy->instantiate(fContext->resourceProvider()); + return fProxy->instantiateTexture(fContext->resourceProvider()); } sk_sp<GrTextureProxy> asTextureProxyRef() const override { return fProxy; diff --git a/tests/ClipStackTest.cpp b/tests/ClipStackTest.cpp index 31dffcb6c2..ba80933009 100644 --- a/tests/ClipStackTest.cpp +++ b/tests/ClipStackTest.cpp @@ -1442,7 +1442,7 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ClipMaskCache, reporter, ctxInfo) { stack.save(); stack.clipPath(path, m, SkClipOp::kIntersect, true); sk_sp<GrTextureProxy> mask = GrClipStackClip(&stack).testingOnly_createClipMask(context); - GrTexture* tex = mask->instantiate(context->resourceProvider()); + GrTexture* tex = mask->instantiateTexture(context->resourceProvider()); REPORTER_ASSERT(reporter, 0 == strcmp(tex->getUniqueKey().tag(), kTag)); // Make sure mask isn't pinned in cache. mask.reset(nullptr); diff --git a/tests/ImageFilterCacheTest.cpp b/tests/ImageFilterCacheTest.cpp index 0dda42e3a8..a8b8f87981 100644 --- a/tests/ImageFilterCacheTest.cpp +++ b/tests/ImageFilterCacheTest.cpp @@ -206,7 +206,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageFilterCache_ImageBackedGPU, reporter, ct return; } - GrTexture* tex = srcProxy->instantiate(context->resourceProvider()); + GrTexture* tex = srcProxy->instantiateTexture(context->resourceProvider()); if (!tex) { return; } diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp index 7b3600f800..0bd8537b6b 100644 --- a/tests/ProxyTest.cpp +++ b/tests/ProxyTest.cpp @@ -49,7 +49,7 @@ static void check_rendertarget(skiatest::Reporter* reporter, REPORTER_ASSERT(reporter, rtProxy->numStencilSamples() == numSamples); GrSurfaceProxy::UniqueID idBefore = rtProxy->uniqueID(); - GrRenderTarget* rt = rtProxy->instantiate(provider); + GrRenderTarget* rt = rtProxy->instantiateRenderTarget(provider); REPORTER_ASSERT(reporter, rt); REPORTER_ASSERT(reporter, rtProxy->uniqueID() == idBefore); @@ -83,7 +83,7 @@ static void check_texture(skiatest::Reporter* reporter, SkBackingFit fit, bool wasWrapped) { GrSurfaceProxy::UniqueID idBefore = texProxy->uniqueID(); - GrTexture* tex = texProxy->instantiate(provider); + GrTexture* tex = texProxy->instantiateTexture(provider); REPORTER_ASSERT(reporter, tex); REPORTER_ASSERT(reporter, texProxy->uniqueID() == idBefore); |