Make use of the buffer data null hint a GrContextOption

TBR=bsalomon@google.com
Change-Id: I5a3fd18479ca8c95e1bc8c087c28346264049eb0
Reviewed-on: https://skia-review.googlesource.com/111604
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Robert Phillips 2018-03-01 16:51:25 -05:00 committed by Skia Commit-Bot
parent f184bdf507
commit f2ec024c44
5 changed files with 46 additions and 21 deletions

View File

@ -131,6 +131,19 @@ struct GrContextOptions {
*/
bool fAvoidStencilBuffers = false;
/**
* When specifing new data for a vertex/index buffer that replaces old data Ganesh can give
* a hint to the driver that the previous data will not be used in future draws like this:
* glBufferData(GL_..._BUFFER, size, NULL, usage); //<--hint, NULL means
* glBufferSubData(GL_..._BUFFER, 0, lessThanSize, data) // old data can't be
* // used again.
* However, this can be an unoptimization on some platforms, esp. Chrome.
* Chrome's cmd buffer will create a new allocation and memset the whole thing
* to zero (for security reasons).
* Defaults to the value of GR_GL_USE_BUFFER_DATA_NULL_HINT #define (which is, by default, 1).
*/
Enable fUseGLBufferDataNullHint = Enable::kDefault;
/**
* If true, texture fetches from mip-mapped textures will be biased to read larger MIP levels.
* This has the effect of sharpening those textures, at the cost of some aliasing, and possible

View File

@ -172,6 +172,7 @@ void GrCaps::dumpJSON(SkJSONWriter* writer) const {
writer->appendBool("Blacklist Coverage Counting Path Renderer [workaround]",
fBlacklistCoverageCounting);
writer->appendBool("Prefer VRAM Use over flushes [workaround]", fPreferVRAMUseOverFlushes);
writer->appendBool("Avoid stencil buffers [workaround]", fAvoidStencilBuffers);
if (this->advancedBlendEquationSupport()) {
writer->appendHexU32("Advanced Blend Equation Blacklist", fAdvBlendEqBlacklist);

View File

@ -175,7 +175,7 @@ void GrGLBuffer::onMap() {
case GrGLCaps::kMapBuffer_MapBufferType: {
GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
// Let driver know it can discard the old data
if (GR_GL_USE_BUFFER_DATA_NULL_HINT || fGLSizeInBytes != this->sizeInBytes()) {
if (this->glCaps().useBufferDataNullHint() || fGLSizeInBytes != this->sizeInBytes()) {
GL_CALL(BufferData(target, this->sizeInBytes(), nullptr, fUsage));
}
GL_CALL_RET(fMapPtr, MapBuffer(target, readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY));
@ -257,7 +257,7 @@ bool GrGLBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) {
// bindbuffer handles dirty context
GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
#if GR_GL_USE_BUFFER_DATA_NULL_HINT
if (this->glCaps().useBufferDataNullHint()) {
if (this->sizeInBytes() == srcSizeInBytes) {
GL_CALL(BufferData(target, (GrGLsizeiptr) srcSizeInBytes, src, fUsage));
} else {
@ -272,13 +272,13 @@ bool GrGLBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) {
GL_CALL(BufferSubData(target, 0, (GrGLsizeiptr) srcSizeInBytes, src));
}
fGLSizeInBytes = this->sizeInBytes();
#else
} else {
// Note that we're cheating on the size here. Currently no methods
// allow a partial update that preserves contents of non-updated
// portions of the buffer (map() does a glBufferData(..size, nullptr..))
GL_CALL(BufferData(target, srcSizeInBytes, src, fUsage));
fGLSizeInBytes = srcSizeInBytes;
#endif
}
VALIDATE();
return true;
}

View File

@ -48,6 +48,7 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
fPartialFBOReadIsSlow = false;
fMipMapLevelAndLodControlSupport = false;
fRGBAToBGRAReadbackConversionsAreSlow = false;
fUseBufferDataNullHint = SkToBool(GR_GL_USE_BUFFER_DATA_NULL_HINT);
fDoManualMipmapping = false;
fSRGBDecodeDisableAffectsMipmaps = false;
fClearToBoundaryValuesIsBroken = false;
@ -260,6 +261,12 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
// vis-versa.
fRGBAToBGRAReadbackConversionsAreSlow = isMESA || isMAC;
if (GrContextOptions::Enable::kNo == contextOptions.fUseGLBufferDataNullHint) {
fUseBufferDataNullHint = false;
} else if (GrContextOptions::Enable::kYes == contextOptions.fUseGLBufferDataNullHint) {
fUseBufferDataNullHint = true;
}
if (kGL_GrGLStandard == standard) {
if (version >= GR_GL_VER(4,4) || ctxInfo.hasExtension("GL_ARB_clear_texture")) {
fClearTextureSupport = true;
@ -1145,6 +1152,7 @@ void GrGLCaps::onDumpJSON(SkJSONWriter* writer) const {
writer->appendBool("Texture swizzle support", fTextureSwizzleSupport);
writer->appendBool("BGRA to RGBA readback conversions are slow",
fRGBAToBGRAReadbackConversionsAreSlow);
writer->appendBool("Use buffer data null hint", fUseBufferDataNullHint);
writer->appendBool("Draw To clear color", fUseDrawToClearColor);
writer->appendBool("Draw To clear stencil clip", fUseDrawToClearStencilClip);
writer->appendBool("Intermediate texture for partial updates of unorm textures ever bound to FBOs",

View File

@ -351,6 +351,8 @@ public:
return fRGBAToBGRAReadbackConversionsAreSlow;
}
bool useBufferDataNullHint() const { return fUseBufferDataNullHint; }
// Certain Intel GPUs on Mac fail to clear if the glClearColor is made up of only 1s and 0s.
bool clearToBoundaryValuesIsBroken() const { return fClearToBoundaryValuesIsBroken; }
@ -480,6 +482,7 @@ private:
bool fTextureSwizzleSupport : 1;
bool fMipMapLevelAndLodControlSupport : 1;
bool fRGBAToBGRAReadbackConversionsAreSlow : 1;
bool fUseBufferDataNullHint : 1;
bool fClearTextureSupport : 1;
bool fProgramBinarySupport : 1;