mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 22:32:51 +00:00
Bug 1312865 - ClearBuffer and similar funcs should mirror Clear's behavior. - r=daoshengmu
MozReview-Commit-ID: 4Gm5aNZ1PXX
This commit is contained in:
parent
3587cf5c07
commit
6091cfeb6e
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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++;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user