Bug 1312865 - ClearBuffer and similar funcs should mirror Clear's behavior. - r=daoshengmu

MozReview-Commit-ID: 4Gm5aNZ1PXX
This commit is contained in:
Jeff Gilbert 2016-12-20 23:31:22 -08:00
parent 3587cf5c07
commit 6091cfeb6e
8 changed files with 62 additions and 38 deletions

View File

@ -56,6 +56,10 @@ WebGL2Context::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY
////
if (!mBoundReadFramebuffer) {
ClearBackbufferIfNeeded();
}
WebGLFramebuffer::BlitFramebuffer(this,
readFB, srcX0, srcY0, srcX1, srcY1,
drawFB, dstX0, dstY0, dstX1, dstY1,
@ -221,6 +225,16 @@ WebGLContext::ValidateInvalidateFramebuffer(const char* funcName, GLenum target,
}
}
////
if (!fb) {
ClearBackbufferIfNeeded();
// Don't do more validation after these.
Invalidate();
mShouldPresent = true;
}
return true;
}
@ -261,6 +275,12 @@ WebGL2Context::InvalidateSubFramebuffer(GLenum target, const dom::Sequence<GLenu
{
const char funcName[] = "invalidateSubFramebuffer";
if (!ValidateNonNegative(funcName, "width", width) ||
!ValidateNonNegative(funcName, "height", height))
{
return;
}
std::vector<GLenum> scopedVector;
GLsizei glNumAttachments;
const GLenum* glAttachments;
@ -270,12 +290,6 @@ WebGL2Context::InvalidateSubFramebuffer(GLenum target, const dom::Sequence<GLenu
return;
}
if (!ValidateNonNegative(funcName, "width", width) ||
!ValidateNonNegative(funcName, "height", height))
{
return;
}
////
// Some drivers (like OSX 10.9 GL) just don't support invalidate_framebuffer.

View File

@ -83,6 +83,8 @@ WebGL2Context::ClearBufferfv(GLenum buffer, GLint drawBuffer, const Float32Arr&
if (!ValidateClearBuffer(funcName, buffer, drawBuffer, src.elemCount, srcElemOffset))
return;
ScopedDrawCallWrapper wrapper(*this);
const auto ptr = src.elemBytes + srcElemOffset;
gl->fClearBufferfv(buffer, drawBuffer, ptr);
}
@ -95,18 +97,22 @@ WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawBuffer, const Int32Arr& sr
if (!ValidateClearBuffer(funcName, buffer, drawBuffer, src.elemCount, srcElemOffset))
return;
ScopedDrawCallWrapper wrapper(*this);
const auto ptr = src.elemBytes + srcElemOffset;
gl->fClearBufferiv(buffer, drawBuffer, ptr);
}
void
WebGL2Context::ClearBufferuiv(GLenum buffer, GLint drawBuffer, const Uint32Arr& src,
GLuint srcElemOffset)
GLuint srcElemOffset)
{
const char funcName[] = "clearBufferuiv";
if (!ValidateClearBuffer(funcName, buffer, drawBuffer, src.elemCount, srcElemOffset))
return;
ScopedDrawCallWrapper wrapper(*this);
const auto ptr = src.elemBytes + srcElemOffset;
gl->fClearBufferuiv(buffer, drawBuffer, ptr);
}
@ -124,6 +130,8 @@ WebGL2Context::ClearBufferfi(GLenum buffer, GLint drawBuffer, GLfloat depth,
if (buffer != LOCAL_GL_DEPTH_STENCIL)
return ErrorInvalidEnumInfo(funcName, buffer);
ScopedDrawCallWrapper wrapper(*this);
gl->fClearBufferfi(buffer, drawBuffer, depth, stencil);
}

View File

@ -2038,12 +2038,16 @@ WebGLContext::ValidateCurFBForRead(const char* funcName,
////////////////////////////////////////////////////////////////////////////////
WebGLContext::ScopedMaskWorkaround::ScopedMaskWorkaround(WebGLContext& webgl)
WebGLContext::ScopedDrawCallWrapper::ScopedDrawCallWrapper(WebGLContext& webgl)
: mWebGL(webgl)
, mFakeNoAlpha(ShouldFakeNoAlpha(webgl))
, mFakeNoDepth(ShouldFakeNoDepth(webgl))
, mFakeNoStencil(ShouldFakeNoStencil(webgl))
{
if (!mWebGL.mBoundDrawFramebuffer) {
mWebGL.ClearBackbufferIfNeeded();
}
if (mFakeNoAlpha) {
mWebGL.gl->fColorMask(mWebGL.mColorWriteMask[0],
mWebGL.mColorWriteMask[1],
@ -2058,7 +2062,7 @@ WebGLContext::ScopedMaskWorkaround::ScopedMaskWorkaround(WebGLContext& webgl)
}
}
WebGLContext::ScopedMaskWorkaround::~ScopedMaskWorkaround()
WebGLContext::ScopedDrawCallWrapper::~ScopedDrawCallWrapper()
{
if (mFakeNoAlpha) {
mWebGL.gl->fColorMask(mWebGL.mColorWriteMask[0],
@ -2073,10 +2077,15 @@ WebGLContext::ScopedMaskWorkaround::~ScopedMaskWorkaround()
MOZ_ASSERT(mWebGL.mStencilTestEnabled);
mWebGL.gl->fEnable(LOCAL_GL_STENCIL_TEST);
}
if (!mWebGL.mBoundDrawFramebuffer) {
mWebGL.Invalidate();
mWebGL.mShouldPresent = true;
}
}
/*static*/ bool
WebGLContext::ScopedMaskWorkaround::HasDepthButNoStencil(const WebGLFramebuffer* fb)
WebGLContext::ScopedDrawCallWrapper::HasDepthButNoStencil(const WebGLFramebuffer* fb)
{
const auto& depth = fb->DepthAttachment();
const auto& stencil = fb->StencilAttachment();

View File

@ -1901,7 +1901,7 @@ protected:
bool Has64BitTimestamps() const;
struct ScopedMaskWorkaround {
struct ScopedDrawCallWrapper final {
WebGLContext& mWebGL;
const bool mFakeNoAlpha;
const bool mFakeNoDepth;
@ -1950,9 +1950,9 @@ protected:
return false;
}
explicit ScopedMaskWorkaround(WebGLContext& webgl);
explicit ScopedDrawCallWrapper(WebGLContext& webgl);
~ScopedMaskWorkaround();
~ScopedDrawCallWrapper();
};
void LoseOldestWebGLContextIfLimitExceeded();

View File

@ -514,7 +514,7 @@ WebGLContext::DrawArrays(GLenum mode, GLint first, GLsizei vertCount)
return;
{
ScopedMaskWorkaround autoMask(*this);
ScopedDrawCallWrapper wrapper(*this);
gl->fDrawArrays(mode, first, vertCount);
}
@ -553,7 +553,7 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount,
return;
{
ScopedMaskWorkaround autoMask(*this);
ScopedDrawCallWrapper wrapper(*this);
gl->fDrawArraysInstanced(mode, first, vertCount, instanceCount);
}
@ -719,7 +719,7 @@ WebGLContext::DrawElements(GLenum mode, GLsizei vertCount, GLenum type,
return;
{
ScopedMaskWorkaround autoMask(*this);
ScopedDrawCallWrapper wrapper(*this);
gl->fDrawElements(mode, vertCount, type,
reinterpret_cast<GLvoid*>(byteOffset));
}
@ -754,7 +754,7 @@ WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei vertCount, GLenum type,
return;
{
ScopedMaskWorkaround autoMask(*this);
ScopedDrawCallWrapper wrapper(*this);
gl->fDrawElementsInstanced(mode, vertCount, type,
reinterpret_cast<GLvoid*>(byteOffset),
instanceCount);
@ -768,12 +768,6 @@ WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei vertCount, GLenum type,
void
WebGLContext::Draw_cleanup(const char* funcName)
{
if (!mBoundDrawFramebuffer) {
Invalidate();
mShouldPresent = true;
MOZ_ASSERT(!mBackbufferNeedsClear);
}
if (gl->WorkAroundDriverBugs()) {
if (gl->Renderer() == gl::GLRenderer::Tegra) {
mDrawCallsSinceLastFlush++;

View File

@ -32,24 +32,14 @@ WebGLContext::Clear(GLbitfield mask)
GenerateWarning("Calling gl.clear() with RASTERIZER_DISCARD enabled has no effects.");
}
if (mBoundDrawFramebuffer) {
if (!mBoundDrawFramebuffer->ValidateAndInitAttachments(funcName))
return;
gl->fClear(mask);
return;
} else {
ClearBackbufferIfNeeded();
}
// Ok, we're clearing the default framebuffer/screen.
if (mBoundDrawFramebuffer &&
!mBoundDrawFramebuffer->ValidateAndInitAttachments(funcName))
{
ScopedMaskWorkaround autoMask(*this);
gl->fClear(mask);
return;
}
Invalidate();
mShouldPresent = true;
ScopedDrawCallWrapper wrapper(*this);
gl->fClear(mask);
}
static GLfloat

View File

@ -1819,6 +1819,7 @@ WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl,
////
gl->MakeCurrent();
WebGLContext::ScopedDrawCallWrapper wrapper(*webgl);
gl->fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1,
mask, filter);

View File

@ -983,27 +983,35 @@ public:
}
void fClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) {
BeforeGLDrawCall();
BEFORE_GL_CALL;
mSymbols.fClearBufferfi(buffer, drawbuffer, depth, stencil);
AFTER_GL_CALL;
AfterGLDrawCall();
}
void fClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) {
BeforeGLDrawCall();
BEFORE_GL_CALL;
mSymbols.fClearBufferfv(buffer, drawbuffer, value);
AFTER_GL_CALL;
AfterGLDrawCall();
}
void fClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) {
BeforeGLDrawCall();
BEFORE_GL_CALL;
mSymbols.fClearBufferiv(buffer, drawbuffer, value);
AFTER_GL_CALL;
AfterGLDrawCall();
}
void fClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) {
BeforeGLDrawCall();
BEFORE_GL_CALL;
mSymbols.fClearBufferuiv(buffer, drawbuffer, value);
AFTER_GL_CALL;
AfterGLDrawCall();
}
void fClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {