Alter approximate scratch texture binning after 1024
As the powers-of-2 get larger the coarse binning can burn a lot of VRAM.
Granted it isn't the best metric but, with this CL, the number of textures created and scratch textures reused remains unchanged when running the GMs.
Change-Id: I84abbbae0ed01aabb387671b5ee0e4fcdb82b671
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/226226
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index 0e171a8..db9ead2 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -209,6 +209,32 @@
return fGpu->createTexture(desc, budgeted);
}
+// Map 'value' to a larger multiple of 2. Values <= 'kMagicTol' will pop up to
+// the next power of 2. Those above 'kMagicTol' will only go up half the floor power of 2.
+uint32_t GrResourceProvider::MakeApprox(uint32_t value) {
+ static const int kMagicTol = 1024;
+
+ value = SkTMax(kMinScratchTextureSize, value);
+
+ if (SkIsPow2(value)) {
+ return value;
+ }
+
+ uint32_t ceilPow2 = GrNextPow2(value);
+ if (value <= kMagicTol) {
+ return ceilPow2;
+ }
+
+ uint32_t floorPow2 = ceilPow2 >> 1;
+ uint32_t mid = floorPow2 + (floorPow2 >> 1);
+
+ if (value <= mid) {
+ return mid;
+ }
+
+ return ceilPow2;
+}
+
sk_sp<GrTexture> GrResourceProvider::createApproxTexture(const GrSurfaceDesc& desc,
Flags flags) {
ASSERT_SINGLE_OWNER
@@ -233,12 +259,12 @@
SkTCopyOnFirstWrite<GrSurfaceDesc> copyDesc(desc);
- // bin by pow2 with a reasonable min
+ // bin by some multiple or power of 2 with a reasonable min
if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
(fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) {
GrSurfaceDesc* wdesc = copyDesc.writable();
- wdesc->fWidth = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fWidth));
- wdesc->fHeight = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fHeight));
+ wdesc->fWidth = MakeApprox(wdesc->fWidth);
+ wdesc->fHeight = MakeApprox(wdesc->fHeight);
}
if (auto tex = this->refScratchTexture(*copyDesc, flags)) {
@@ -273,6 +299,7 @@
GrSurface::WorstCaseSize(desc),
scratchFlags);
if (resource) {
+ fGpu->stats()->incNumScratchTexturesReused();
GrSurface* surface = static_cast<GrSurface*>(resource);
return sk_sp<GrTexture>(surface->asTexture());
}