Fix computation of texture size for approximately-fit deferred proxies
For approximate-fit deferred proxies asserts were firing when the instantiated size was larger than the pre-computed exact-fit size.
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4972
Change-Id: I879e16b86ab4d9ef9834163c24ccd6507fe4b94a
Reviewed-on: https://skia-review.googlesource.com/4972
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index 3f91a2f..46b9986 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -129,8 +129,9 @@
void setLastOpList(GrOpList* opList);
GrOpList* getLastOpList() { return fLastOpList; }
- static size_t WorstCaseSize(const GrSurfaceDesc& desc);
- static size_t ComputeSize(const GrSurfaceDesc& desc, int colorSamplesPerPixel, bool hasMIPMaps);
+ static size_t WorstCaseSize(const GrSurfaceDesc& desc, bool useNextPow2 = false);
+ static size_t ComputeSize(const GrSurfaceDesc& desc, int colorSamplesPerPixel,
+ bool hasMIPMaps, bool useNextPow2 = false);
protected:
// Methods made available via GrSurfacePriv
diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp
index 8eb335d..cb9b97a 100644
--- a/src/gpu/GrRenderTargetProxy.cpp
+++ b/src/gpu/GrRenderTargetProxy.cpp
@@ -71,6 +71,6 @@
}
// TODO: do we have enough information to improve this worst case estimate?
- return GrSurface::ComputeSize(fDesc, fDesc.fSampleCnt+1, false);
+ return GrSurface::ComputeSize(fDesc, fDesc.fSampleCnt+1, false, SkBackingFit::kApprox == fFit);
}
diff --git a/src/gpu/GrSurface.cpp b/src/gpu/GrSurface.cpp
index 7f571b8..f67bfd4 100644
--- a/src/gpu/GrSurface.cpp
+++ b/src/gpu/GrSurface.cpp
@@ -13,6 +13,7 @@
#include "SkBitmap.h"
#include "SkGrPriv.h"
#include "SkImageEncoder.h"
+#include "SkMathPriv.h"
#include <stdio.h>
GrSurface::~GrSurface() {
@@ -25,9 +26,12 @@
SkASSERT(NULL == fReleaseProc);
}
-size_t GrSurface::WorstCaseSize(const GrSurfaceDesc& desc) {
+size_t GrSurface::WorstCaseSize(const GrSurfaceDesc& desc, bool useNextPow2) {
size_t size;
+ int width = useNextPow2 ? GrNextPow2(desc.fWidth) : desc.fWidth;
+ int height = useNextPow2 ? GrNextPow2(desc.fHeight) : desc.fHeight;
+
bool isRenderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
if (isRenderTarget) {
// We own one color value for each MSAA sample.
@@ -38,7 +42,7 @@
}
SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig));
- size_t colorBytes = (size_t) desc.fWidth * desc.fHeight * GrBytesPerPixel(desc.fConfig);
+ size_t colorBytes = (size_t) width * height * GrBytesPerPixel(desc.fConfig);
// This would be a nice assert to have (i.e., we aren't creating 0 width/height surfaces).
// Unfortunately Chromium seems to want to do this.
@@ -48,9 +52,9 @@
size += colorBytes/3; // in case we have to mipmap
} else {
if (GrPixelConfigIsCompressed(desc.fConfig)) {
- size = GrCompressedFormatDataSize(desc.fConfig, desc.fWidth, desc.fHeight);
+ size = GrCompressedFormatDataSize(desc.fConfig, width, height);
} else {
- size = (size_t) desc.fWidth * desc.fHeight * GrBytesPerPixel(desc.fConfig);
+ size = (size_t) width * height * GrBytesPerPixel(desc.fConfig);
}
size += size/3; // in case we have to mipmap
@@ -61,14 +65,18 @@
size_t GrSurface::ComputeSize(const GrSurfaceDesc& desc,
int colorSamplesPerPixel,
- bool hasMIPMaps) {
+ bool hasMIPMaps,
+ bool useNextPow2) {
size_t colorSize;
+ int width = useNextPow2 ? GrNextPow2(desc.fWidth) : desc.fWidth;
+ int height = useNextPow2 ? GrNextPow2(desc.fHeight) : desc.fHeight;
+
SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
if (GrPixelConfigIsCompressed(desc.fConfig)) {
- colorSize = GrCompressedFormatDataSize(desc.fConfig, desc.fWidth, desc.fHeight);
+ colorSize = GrCompressedFormatDataSize(desc.fConfig, width, height);
} else {
- colorSize = (size_t) desc.fWidth * desc.fHeight * GrBytesPerPixel(desc.fConfig);
+ colorSize = (size_t) width * height * GrBytesPerPixel(desc.fConfig);
}
SkASSERT(colorSize > 0);
@@ -80,7 +88,7 @@
finalSize += colorSize/3;
}
- SkASSERT(finalSize <= WorstCaseSize(desc));
+ SkASSERT(finalSize <= WorstCaseSize(desc, useNextPow2));
return finalSize;
}
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
index 9798747..77a8402 100644
--- a/src/gpu/GrTextureProxy.cpp
+++ b/src/gpu/GrTextureProxy.cpp
@@ -35,5 +35,5 @@
static const bool kHasMipMaps = true;
// TODO: add tracking of mipmap state to improve the estimate
- return GrSurface::ComputeSize(fDesc, 1, kHasMipMaps);
+ return GrSurface::ComputeSize(fDesc, 1, kHasMipMaps, SkBackingFit::kApprox == fFit);
}
diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp
index 95451e9..212ea0a 100644
--- a/src/gpu/GrTextureRenderTargetProxy.cpp
+++ b/src/gpu/GrTextureRenderTargetProxy.cpp
@@ -36,6 +36,6 @@
}
// TODO: do we have enough information to improve this worst case estimate?
- return GrSurface::ComputeSize(fDesc, fDesc.fSampleCnt+1, true);
+ return GrSurface::ComputeSize(fDesc, fDesc.fSampleCnt+1, true, SkBackingFit::kApprox == fFit);
}
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
index 8d59cae..a228e16 100644
--- a/tests/ProxyTest.cpp
+++ b/tests/ProxyTest.cpp
@@ -136,6 +136,13 @@
sk_sp<GrSurfaceProxy> sProxy(GrSurfaceProxy::MakeDeferred(
caps, desc,
fit, budgeted));
+ // This forces the proxy to compute and cache its pre-instantiation
+ // size guess. Later, when it is actually instantiated, it checks
+ // that the instantiated size is <= to the pre-computation.
+ // If the proxy never computed its pre-instantiation size then the
+ // check is skipped.
+ sProxy->gpuMemorySize();
+
check_surface(reporter, sProxy.get(), origin,
widthHeight, widthHeight, config,
kInvalidResourceID, budgeted);
@@ -151,6 +158,13 @@
desc,
fit,
budgeted));
+ // This forces the proxy to compute and cache its pre-instantiation
+ // size guess. Later, when it is actually instantiated, it checks
+ // that the instantiated size is <= to the pre-computation.
+ // If the proxy never computed its pre-instantiation size then the
+ // check is skipped.
+ sProxy->gpuMemorySize();
+
check_surface(reporter, sProxy.get(), origin,
widthHeight, widthHeight, config,
kInvalidResourceID, budgeted);