Bug 1325733 - Mark read/draw calls better. - r=daoshengmu
MozReview-Commit-ID: A6spAvpKvd7
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -186,18 +186,16 @@ WebGLContext::WebGLContext()
GenerateWarning("webgl.max-warnings-per-context size is too large (seems like a negative value wrapped)");
mMaxWarnings = 0;
}
mLastUseIndex = 0;
InvalidateBufferFetching();
- mBackbufferNeedsClear = true;
-
mDisableFragHighP = false;
mDrawCallsSinceLastFlush = 0;
}
WebGLContext::~WebGLContext()
{
RemovePostRefreshObserver();
@@ -1117,24 +1115,16 @@ WebGLContext::SetDimensions(int32_t sign
}
void
WebGLContext::ClearBackbufferIfNeeded()
{
if (!mBackbufferNeedsClear)
return;
-#ifdef DEBUG
- gl->MakeCurrent();
-
- GLuint fb = 0;
- gl->GetUIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &fb);
- MOZ_ASSERT(fb == 0);
-#endif
-
ClearScreen();
mBackbufferNeedsClear = false;
}
void
WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
{
@@ -2075,16 +2065,26 @@ WebGLContext::ScopedDrawCallWrapper::~Sc
/*static*/ bool
WebGLContext::ScopedDrawCallWrapper::HasDepthButNoStencil(const WebGLFramebuffer* fb)
{
const auto& depth = fb->DepthAttachment();
const auto& stencil = fb->StencilAttachment();
return depth.IsDefined() && !stencil.IsDefined();
}
+////
+
+void
+WebGLContext::OnBeforeReadCall()
+{
+ if (!mBoundReadFramebuffer) {
+ ClearBackbufferIfNeeded();
+ }
+}
+
////////////////////////////////////////
IndexedBufferBinding::IndexedBufferBinding()
: mRangeStart(0)
, mRangeSize(0)
{ }
uint64_t
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1999,21 +1999,24 @@ protected:
HasDepthButNoStencil(webgl.mBoundDrawFramebuffer))
{
return true;
}
return false;
}
+ ////
+
explicit ScopedDrawCallWrapper(WebGLContext& webgl);
-
~ScopedDrawCallWrapper();
};
+ void OnBeforeReadCall();
+
void LoseOldestWebGLContextIfLimitExceeded();
void UpdateLastUseIndex();
template <typename WebGLObjectType>
JS::Value WebGLObjectAsJSValue(JSContext* cx, const WebGLObjectType*,
ErrorResult& rv) const;
template <typename WebGLObjectType>
JSObject* WebGLObjectAsJSObject(JSContext* cx, const WebGLObjectType*,
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -1542,16 +1542,18 @@ WebGLContext::ReadPixelsImpl(GLint x, GL
if (bytesNeeded > dataLen) {
ErrorInvalidOperation("readPixels: buffer too small");
return;
}
////////////////
// Now that the errors are out of the way, on to actually reading!
+ OnBeforeReadCall();
+
uint32_t readX, readY;
uint32_t writeX, writeY;
uint32_t rwWidth, rwHeight;
Intersect(srcWidth, x, width, &readX, &writeX, &rwWidth);
Intersect(srcHeight, y, height, &readY, &writeY, &rwHeight);
if (rwWidth == uint32_t(width) && rwHeight == uint32_t(height)) {
DoReadPixelsAndConvert(srcFormat->format, x, y, width, height, packFormat,
--- a/dom/canvas/WebGLFramebuffer.cpp
+++ b/dom/canvas/WebGLFramebuffer.cpp
@@ -1863,16 +1863,17 @@ WebGLFramebuffer::BlitFramebuffer(WebGLC
} else if (!srcFB && !dstFB) {
webgl->ErrorInvalidOperation("%s: Feedback with default framebuffer.", funcName);
return;
}
////
gl->MakeCurrent();
+ webgl->OnBeforeReadCall();
WebGLContext::ScopedDrawCallWrapper wrapper(*webgl);
gl->fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1,
mask, filter);
}
////////////////////////////////////////////////////////////////////////////////
// Goop.
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -1982,18 +1982,17 @@ DoCopyTexOrSubImage(WebGLContext* webgl,
const WebGLTexture* tex, TexImageTarget target, GLint level,
GLint xWithinSrc, GLint yWithinSrc,
uint32_t srcTotalWidth, uint32_t srcTotalHeight,
const webgl::FormatUsageInfo* srcUsage,
GLint xOffset, GLint yOffset, GLint zOffset,
uint32_t dstWidth, uint32_t dstHeight,
const webgl::FormatUsageInfo* dstUsage)
{
- gl::GLContext* gl = webgl->gl;
- gl->MakeCurrent();
+ const auto& gl = webgl->gl;
////
uint32_t readX, readY;
uint32_t writeX, writeY;
uint32_t rwWidth, rwHeight;
Intersect(srcTotalWidth, xWithinSrc, dstWidth, &readX, &writeX, &rwWidth);
Intersect(srcTotalHeight, yWithinSrc, dstHeight, &readY, &writeY, &rwHeight);
@@ -2122,16 +2121,19 @@ WebGLTexture::CopyTexImage2D(TexImageTar
}
if (!ValidateCopyTexImageFormats(mContext, funcName, srcFormat, dstFormat))
return;
////////////////////////////////////
// Do the thing!
+ mContext->gl->MakeCurrent();
+ mContext->OnBeforeReadCall();
+
const bool isSubImage = false;
if (!DoCopyTexOrSubImage(mContext, funcName, isSubImage, this, target, level, x, y,
srcTotalWidth, srcTotalHeight, srcUsage, 0, 0, 0, width,
height, dstUsage))
{
return;
}
@@ -2197,16 +2199,19 @@ WebGLTexture::CopyTexSubImage(const char
auto srcFormat = srcUsage->format;
if (!ValidateCopyTexImageFormats(mContext, funcName, srcFormat, dstFormat))
return;
////////////////////////////////////
// Do the thing!
+ mContext->gl->MakeCurrent();
+ mContext->OnBeforeReadCall();
+
bool uploadWillInitialize;
if (!EnsureImageDataInitializedForUpload(this, funcName, target, level, xOffset,
yOffset, zOffset, width, height, depth,
imageInfo, &uploadWillInitialize))
{
return;
}
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -882,27 +882,31 @@ public:
BEFORE_GL_CALL;
mSymbols.fBindBuffer(target, buffer);
AFTER_GL_CALL;
}
void fBindFramebuffer(GLenum target, GLuint framebuffer);
void fInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) {
+ BeforeGLDrawCall();
BEFORE_GL_CALL;
ASSERT_SYMBOL_PRESENT(fInvalidateFramebuffer);
mSymbols.fInvalidateFramebuffer(target, numAttachments, attachments);
AFTER_GL_CALL;
+ AfterGLDrawCall();
}
void fInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) {
+ BeforeGLDrawCall();
BEFORE_GL_CALL;
ASSERT_SYMBOL_PRESENT(fInvalidateSubFramebuffer);
mSymbols.fInvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height);
AFTER_GL_CALL;
+ AfterGLDrawCall();
}
void fBindTexture(GLenum target, GLuint texture) {
BEFORE_GL_CALL;
mSymbols.fBindTexture(target, texture);
AFTER_GL_CALL;
}
@@ -3135,21 +3139,23 @@ public:
pixels);
AFTER_GL_CALL;
}
void fCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset,
GLint yoffset, GLint zoffset, GLint x,
GLint y, GLsizei width, GLsizei height)
{
+ BeforeGLReadCall();
BEFORE_GL_CALL;
ASSERT_SYMBOL_PRESENT(fCopyTexSubImage3D);
mSymbols.fCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset,
x, y, width, height);
AFTER_GL_CALL;
+ AfterGLReadCall();
}
void fCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLsizei imageSize, const GLvoid* data)
{
BEFORE_GL_CALL;
ASSERT_SYMBOL_PRESENT(fCompressedTexImage3D);