Add ANGLE workaround to prefer flushes over VRAM usage

On the whole, https://codereview.chromium.org/1286203002/ (Defer flushes if kPreferNoIO is specified) improved performance but it did cause a performance regression on ANGLE. This CL disables the deferral of flushes on ANGLE until we can add a separate incremental flushing mechanism.

TBR=bsalomon@google.com

BUG=skia:4201
BUG=521529

Review URL: https://codereview.chromium.org/1287193008
This commit is contained in:
robertphillips 2015-08-20 09:39:02 -07:00 committed by Commit bot
parent 12d8472d31
commit 63926683c5
6 changed files with 29 additions and 8 deletions

View File

@ -133,6 +133,8 @@ public:
return fUseDrawInsteadOfPartialRenderTargetWrite; return fUseDrawInsteadOfPartialRenderTargetWrite;
} }
bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; }
/** /**
* Indicates the capabilities of the fixed function blend unit. * Indicates the capabilities of the fixed function blend unit.
*/ */
@ -249,6 +251,9 @@ protected:
bool fUseDrawInsteadOfClear : 1; bool fUseDrawInsteadOfClear : 1;
bool fUseDrawInsteadOfPartialRenderTargetWrite : 1; bool fUseDrawInsteadOfPartialRenderTargetWrite : 1;
// ANGLE workaround
bool fPreferVRAMUseOverFlushes : 1;
BlendEquationSupport fBlendEquationSupport; BlendEquationSupport fBlendEquationSupport;
uint32_t fAdvBlendEqBlacklist; uint32_t fAdvBlendEqBlacklist;
GR_STATIC_ASSERT(kLast_GrBlendEquation < 32); GR_STATIC_ASSERT(kLast_GrBlendEquation < 32);

View File

@ -114,6 +114,8 @@ GrCaps::GrCaps(const GrContextOptions& options) {
fDrawPathMasksToCompressedTextureSupport = options.fDrawPathToCompressedTexture; fDrawPathMasksToCompressedTextureSupport = options.fDrawPathToCompressedTexture;
fGeometryBufferMapThreshold = options.fGeometryBufferMapThreshold; fGeometryBufferMapThreshold = options.fGeometryBufferMapThreshold;
fUseDrawInsteadOfPartialRenderTargetWrite = options.fUseDrawInsteadOfPartialRenderTargetWrite; fUseDrawInsteadOfPartialRenderTargetWrite = options.fUseDrawInsteadOfPartialRenderTargetWrite;
fPreferVRAMUseOverFlushes = true;
} }
void GrCaps::applyOptionsOverrides(const GrContextOptions& options) { void GrCaps::applyOptionsOverrides(const GrContextOptions& options) {
@ -161,6 +163,8 @@ SkString GrCaps::dump() const {
r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]); r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]);
r.appendf("Draw Instead of TexSubImage [workaround] : %s\n", r.appendf("Draw Instead of TexSubImage [workaround] : %s\n",
gNY[fUseDrawInsteadOfPartialRenderTargetWrite]); gNY[fUseDrawInsteadOfPartialRenderTargetWrite]);
r.appendf("Prefer VRAM Use over flushes [workaround] : %s\n", gNY[fPreferVRAMUseOverFlushes]);
if (this->advancedBlendEquationSupport()) { if (this->advancedBlendEquationSupport()) {
r.appendf("Advanced Blend Equation Blacklist : 0x%x\n", fAdvBlendEqBlacklist); r.appendf("Advanced Blend Equation Blacklist : 0x%x\n", fAdvBlendEqBlacklist);
} }

View File

@ -182,7 +182,7 @@ bool GrContext::init(GrBackend backend, GrBackendContext backendContext,
void GrContext::initCommon() { void GrContext::initCommon() {
fCaps = SkRef(fGpu->caps()); fCaps = SkRef(fGpu->caps());
fResourceCache = SkNEW(GrResourceCache); fResourceCache = SkNEW_ARGS(GrResourceCache, (fCaps));
fResourceCache->setOverBudgetCallback(OverBudgetCB, this); fResourceCache->setOverBudgetCallback(OverBudgetCB, this);
fResourceProvider = SkNEW_ARGS(GrResourceProvider, (fGpu, fResourceCache)); fResourceProvider = SkNEW_ARGS(GrResourceProvider, (fGpu, fResourceCache));

View File

@ -58,7 +58,7 @@ private:
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
GrResourceCache::GrResourceCache() GrResourceCache::GrResourceCache(const GrCaps* caps)
: fTimestamp(0) : fTimestamp(0)
, fMaxCount(kDefaultMaxCount) , fMaxCount(kDefaultMaxCount)
, fMaxBytes(kDefaultMaxSize) , fMaxBytes(kDefaultMaxSize)
@ -75,7 +75,8 @@ GrResourceCache::GrResourceCache()
, fOverBudgetCB(NULL) , fOverBudgetCB(NULL)
, fOverBudgetData(NULL) , fOverBudgetData(NULL)
, fFlushTimestamps(NULL) , fFlushTimestamps(NULL)
, fLastFlushTimestampIndex(0){ , fLastFlushTimestampIndex(0)
, fPreferVRAMUseOverFlushes(caps->preferVRAMUseOverFlushes()) {
SkDEBUGCODE(fCount = 0;) SkDEBUGCODE(fCount = 0;)
SkDEBUGCODE(fNewlyPurgeableResourceForValidation = NULL;) SkDEBUGCODE(fNewlyPurgeableResourceForValidation = NULL;)
this->resetFlushTimestamps(); this->resetFlushTimestamps();
@ -260,9 +261,12 @@ GrGpuResource* GrResourceCache::findAndRefScratchResource(const GrScratchKey& sc
} else if (flags & kRequireNoPendingIO_ScratchFlag) { } else if (flags & kRequireNoPendingIO_ScratchFlag) {
return NULL; return NULL;
} }
if (this->wouldFit(resourceSize)) { // We would prefer to consume more available VRAM rather than flushing
// immediately, but on ANGLE this can lead to starving of the GPU.
if (fPreferVRAMUseOverFlushes && this->wouldFit(resourceSize)) {
// kPrefer is specified, we didn't find a resource without pending io, // kPrefer is specified, we didn't find a resource without pending io,
// but there is still space in our budget for the resource. // but there is still space in our budget for the resource so force
// the caller to allocate a new resource.
return NULL; return NULL;
} }
} }

View File

@ -20,6 +20,7 @@
#include "SkTInternalLList.h" #include "SkTInternalLList.h"
#include "SkTMultiMap.h" #include "SkTMultiMap.h"
class GrCaps;
class SkString; class SkString;
/** /**
@ -47,7 +48,7 @@ class SkString;
*/ */
class GrResourceCache { class GrResourceCache {
public: public:
GrResourceCache(); GrResourceCache(const GrCaps* caps);
~GrResourceCache(); ~GrResourceCache();
// Default maximum number of budgeted resources in the cache. // Default maximum number of budgeted resources in the cache.
@ -298,6 +299,8 @@ private:
// This resource is allowed to be in the nonpurgeable array for the sake of validate() because // This resource is allowed to be in the nonpurgeable array for the sake of validate() because
// we're in the midst of converting it to purgeable status. // we're in the midst of converting it to purgeable status.
SkDEBUGCODE(GrGpuResource* fNewlyPurgeableResourceForValidation;) SkDEBUGCODE(GrGpuResource* fNewlyPurgeableResourceForValidation;)
bool fPreferVRAMUseOverFlushes;
}; };
class GrResourceCache::ResourceAccess { class GrResourceCache::ResourceAccess {

View File

@ -471,6 +471,11 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
fUseDrawInsteadOfPartialRenderTargetWrite = true; fUseDrawInsteadOfPartialRenderTargetWrite = true;
} }
#ifdef SK_BUILD_FOR_WIN
// On ANGLE deferring flushes can lead to GPU starvation
fPreferVRAMUseOverFlushes = !isANGLE;
#endif
if (kChromium_GrGLDriver == ctxInfo.driver()) { if (kChromium_GrGLDriver == ctxInfo.driver()) {
fMustClearUploadedBufferData = true; fMustClearUploadedBufferData = true;
} }
@ -1147,8 +1152,8 @@ SkString GrGLCaps::dump() const {
r.appendf("Use non-VBO for dynamic data: %s\n", r.appendf("Use non-VBO for dynamic data: %s\n",
(fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO")); (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
r.appendf("SRGB write contol: %s\n", (fSRGBWriteControl ? "YES" : "NO")); r.appendf("SRGB write contol: %s\n", (fSRGBWriteControl ? "YES" : "NO"));
r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow? "YES" : "NO")); r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO"));
r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow? "YES" : "NO")); r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO"));
return r; return r;
} }