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
Родитель 4a28778f52
Коммит 0d6f7f1c2b
3 изменённых файлов: 92 добавлений и 8 удалений

Просмотреть файл

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

Просмотреть файл

@ -2158,39 +2158,72 @@ void GLContext::fCopyTexImage2D(GLenum target, GLint level,
AfterGLReadCall(); 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) { switch (pname) {
case LOCAL_GL_MAX_TEXTURE_SIZE: case LOCAL_GL_MAX_TEXTURE_SIZE:
MOZ_ASSERT(mMaxTextureSize > 0); MOZ_ASSERT(mMaxTextureSize > 0);
*params = mMaxTextureSize; *params = mMaxTextureSize;
break; return;
case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE: case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
MOZ_ASSERT(mMaxCubeMapTextureSize > 0); MOZ_ASSERT(mMaxCubeMapTextureSize > 0);
*params = mMaxCubeMapTextureSize; *params = mMaxCubeMapTextureSize;
break; return;
case LOCAL_GL_MAX_RENDERBUFFER_SIZE: case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
MOZ_ASSERT(mMaxRenderbufferSize > 0); MOZ_ASSERT(mMaxRenderbufferSize > 0);
*params = mMaxRenderbufferSize; *params = mMaxRenderbufferSize;
break; return;
case LOCAL_GL_VIEWPORT: case LOCAL_GL_VIEWPORT:
for (size_t i = 0; i < 4; i++) { for (size_t i = 0; i < 4; i++) {
params[i] = mViewportRect[i]; params[i] = mViewportRect[i];
} }
break; return;
case LOCAL_GL_SCISSOR_BOX: case LOCAL_GL_SCISSOR_BOX:
for (size_t i = 0; i < 4; i++) { for (size_t i = 0; i < 4; i++) {
params[i] = mScissorRect[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; break;
default: default:
raw_fGetIntegerv(pname, params);
break; break;
} }
raw_fGetIntegerv(pname, params);
} }
void GLContext::fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, void GLContext::fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,

Просмотреть файл

@ -27,6 +27,7 @@
# define MOZ_GL_DEBUG 1 # define MOZ_GL_DEBUG 1
#endif #endif
#include "mozilla/IntegerRange.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "mozilla/ThreadLocal.h" #include "mozilla/ThreadLocal.h"
@ -2019,10 +2020,49 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
AFTER_GL_CALL; 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; BEFORE_GL_CALL;
mSymbols.fBindFramebuffer(target, framebuffer); mSymbols.fBindFramebuffer(target, fb);
AFTER_GL_CALL; 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) { void fBindRenderbuffer(GLenum target, GLuint renderbuffer) {
@ -2286,6 +2326,16 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
BEFORE_GL_CALL; BEFORE_GL_CALL;
mSymbols.fDeleteFramebuffers(n, names); mSymbols.fDeleteFramebuffers(n, names);
AFTER_GL_CALL; 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) { void raw_fDeleteRenderbuffers(GLsizei n, const GLuint* names) {