Bug 1726863 - Cache/elide GLContext::BindFramebuffer calls. r=lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D123275
This commit is contained in:
Jeff Gilbert 2021-08-23 23:59:26 +00:00
parent 4a28778f52
commit 0d6f7f1c2b
3 changed files with 92 additions and 8 deletions

View File

@ -635,6 +635,7 @@ void WebGLContext::FinishInit() {
// Initial setup.
gl->mImplicitMakeCurrent = true;
gl->mElideDuplicateBindFramebuffers = true;
const auto& size = mDefaultFB->mSize;

View File

@ -2158,39 +2158,72 @@ void GLContext::fCopyTexImage2D(GLenum target, GLint level,
AfterGLReadCall();
}
void GLContext::fGetIntegerv(GLenum pname, GLint* params) const {
void GLContext::fGetIntegerv(const GLenum pname, GLint* const params) const {
const auto AssertBinding = [&](const char* const name, const GLenum binding,
const GLuint expected) {
if (MOZ_LIKELY(!mDebugFlags)) return;
GLuint actual = 0;
raw_fGetIntegerv(binding, (GLint*)&actual);
if (actual != expected) {
gfxCriticalError() << "Misprediction: " << name << " expected "
<< expected << ", was " << actual;
}
};
switch (pname) {
case LOCAL_GL_MAX_TEXTURE_SIZE:
MOZ_ASSERT(mMaxTextureSize > 0);
*params = mMaxTextureSize;
break;
return;
case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
MOZ_ASSERT(mMaxCubeMapTextureSize > 0);
*params = mMaxCubeMapTextureSize;
break;
return;
case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
MOZ_ASSERT(mMaxRenderbufferSize > 0);
*params = mMaxRenderbufferSize;
break;
return;
case LOCAL_GL_VIEWPORT:
for (size_t i = 0; i < 4; i++) {
params[i] = mViewportRect[i];
}
break;
return;
case LOCAL_GL_SCISSOR_BOX:
for (size_t i = 0; i < 4; i++) {
params[i] = mScissorRect[i];
}
return;
case LOCAL_GL_DRAW_FRAMEBUFFER_BINDING:
if (mElideDuplicateBindFramebuffers) {
static_assert(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING ==
LOCAL_GL_FRAMEBUFFER_BINDING);
AssertBinding("GL_DRAW_FRAMEBUFFER_BINDING",
LOCAL_GL_DRAW_FRAMEBUFFER_BINDING, mCachedDrawFb);
*params = static_cast<GLint>(mCachedDrawFb);
return;
}
break;
case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
if (mElideDuplicateBindFramebuffers) {
if (IsSupported(GLFeature::framebuffer_blit)) {
AssertBinding("GL_READ_FRAMEBUFFER_BINDING",
LOCAL_GL_READ_FRAMEBUFFER_BINDING, mCachedReadFb);
}
*params = static_cast<GLint>(mCachedReadFb);
return;
}
break;
default:
raw_fGetIntegerv(pname, params);
break;
}
raw_fGetIntegerv(pname, params);
}
void GLContext::fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,

View File

@ -27,6 +27,7 @@
# define MOZ_GL_DEBUG 1
#endif
#include "mozilla/IntegerRange.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/ThreadLocal.h"
@ -2019,10 +2020,49 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
AFTER_GL_CALL;
}
void fBindFramebuffer(GLenum target, GLuint framebuffer) {
private:
mutable GLuint mCachedDrawFb = 0;
mutable GLuint mCachedReadFb = 0;
public:
bool mElideDuplicateBindFramebuffers = false;
void fBindFramebuffer(const GLenum target, const GLuint fb) const {
if (mElideDuplicateBindFramebuffers) {
MOZ_ASSERT(mCachedDrawFb ==
GetIntAs<GLuint>(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING));
MOZ_ASSERT(mCachedReadFb ==
GetIntAs<GLuint>(LOCAL_GL_READ_FRAMEBUFFER_BINDING));
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
if (mCachedDrawFb == fb && mCachedReadFb == fb) return;
break;
case LOCAL_GL_DRAW_FRAMEBUFFER:
if (mCachedDrawFb == fb) return;
break;
case LOCAL_GL_READ_FRAMEBUFFER:
if (mCachedReadFb == fb) return;
break;
}
}
BEFORE_GL_CALL;
mSymbols.fBindFramebuffer(target, framebuffer);
mSymbols.fBindFramebuffer(target, fb);
AFTER_GL_CALL;
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
mCachedDrawFb = fb;
mCachedReadFb = fb;
break;
case LOCAL_GL_DRAW_FRAMEBUFFER:
mCachedDrawFb = fb;
break;
case LOCAL_GL_READ_FRAMEBUFFER:
mCachedReadFb = fb;
break;
}
}
void fBindRenderbuffer(GLenum target, GLuint renderbuffer) {
@ -2286,6 +2326,16 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
BEFORE_GL_CALL;
mSymbols.fDeleteFramebuffers(n, names);
AFTER_GL_CALL;
for (const auto i : IntegerRange(n)) {
const auto fb = names[i];
if (mCachedDrawFb == fb) {
mCachedDrawFb = 0;
}
if (mCachedReadFb == fb) {
mCachedReadFb = 0;
}
}
}
void raw_fDeleteRenderbuffers(GLsizei n, const GLuint* names) {