Remove GrSurfaceDesc member from GrSurfaceProxy.
authorBrian Salomon <bsalomon@google.com>
Wed, 17 May 2017 17:49:59 +0000 (13:49 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 17 May 2017 18:17:50 +0000 (18:17 +0000)
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:
include/gpu/GrSurface.h
include/private/GrRenderTargetProxy.h
include/private/GrSurfaceProxy.h
include/private/GrTextureProxy.h
src/core/SkGpuBlurUtils.cpp
src/gpu/GrContext.cpp
src/gpu/GrCoordTransform.cpp
src/gpu/GrDrawOpAtlas.cpp
src/gpu/GrDrawingManager.cpp
src/gpu/GrProcessor.cpp
src/gpu/GrRenderTargetContext.cpp
src/gpu/GrRenderTargetContext.h
src/gpu/GrRenderTargetProxy.cpp
src/gpu/GrResourceProvider.cpp
src/gpu/GrSurface.cpp
src/gpu/GrSurfaceProxy.cpp
src/gpu/GrTexture.cpp
src/gpu/GrTextureProxy.cpp
src/gpu/GrTextureRenderTargetProxy.cpp
src/gpu/GrTextureRenderTargetProxy.h
src/gpu/effects/GrSimpleTextureEffect.h
src/gpu/gl/GrGLRenderTarget.cpp
src/gpu/gl/GrGLTextureRenderTarget.h
src/gpu/vk/GrVkRenderTarget.h
src/gpu/vk/GrVkTextureRenderTarget.h
src/image/SkImage_Gpu.cpp
src/image/SkImage_Gpu.h
tests/ClipStackTest.cpp
tests/ImageFilterCacheTest.cpp
tests/ProxyTest.cpp

index dd37c18..668838b 100644 (file)
@@ -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:
index dd28b0f..6d8b000 100644 (file)
@@ -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.
index 8b3779c..bf668fc 100644 (file)
@@ -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.
index e14e285..342e920 100644 (file)
@@ -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
index e832c87..359cbea 100644 (file)
@@ -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;
         }
index 7862a82..1455800 100644 (file)
@@ -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;
         }
index 79d9e98..4767e53 100644 (file)
@@ -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();
 }
index f1f29dc..0e8de3c 100644 (file)
@@ -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;
     }
index 0c2485b..b177a43 100644 (file)
@@ -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;
         }
index 1533257..c20ebab 100644 (file)
@@ -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());
index 0076812..e58b4bb 100644 (file)
@@ -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;
index a749046..0f9e530 100644 (file)
@@ -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(); }
index 44f23d4..099f7e5 100644 (file)
 #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 {
index ad92abf..a46ecb6 100644 (file)
@@ -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;
     }
index aae3f23..2658428 100644 (file)
@@ -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;
 }
 
index 43a650f..a9abb16 100644 (file)
 #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;
     }
 
index 6609fa6..0aa1ac0 100644 (file)
@@ -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 {
index 7557712..7ecd50b 100644 (file)
 
 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);
 }
index 432d008..4f1c420 100644 (file)
@@ -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;
+}
index 09aef75..992e319 100644 (file)
@@ -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
index 7d5232c..8e0e4b0 100644 (file)
@@ -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;
         }
index 09c2851..7d45ceb 100644 (file)
@@ -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
index 7ff8d49..0d3b19d 100644 (file)
@@ -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());
     }
index cf425fb..272998e 100644 (file)
@@ -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);
index 2877a36..03f9fdb 100644 (file)
@@ -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());
     }
 };
index 5327e5e..efdd2d7 100644 (file)
@@ -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;
     }
index 5c3ed5a..273f93e 100644 (file)
@@ -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;
index 31dffcb..ba80933 100644 (file)
@@ -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);
index 0dda42e..a8b8f87 100644 (file)
@@ -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;
     }
index 7b3600f..0bd8537 100644 (file)
@@ -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);