Chromium Code Reviews| Index: third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp |
| diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp |
| index 999af825100a4abb54ef8ccb4109e5fc320d7936..acc0478cc3868e08a5beb9ac814bd13d19921bf3 100644 |
| --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp |
| +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp |
| @@ -100,6 +100,8 @@ |
| #include "wtf/text/StringUTF8Adaptor.h" |
| #include "wtf/typed_arrays/ArrayBufferContents.h" |
| +#include <memory> |
| + |
| namespace blink { |
| namespace { |
| @@ -122,6 +124,24 @@ WebGLRenderingContextBaseMap& forciblyEvictedContexts() |
| return forciblyEvictedContexts; |
| } |
| +class ScopedRGBEmulationColorMask { |
|
Zhenyao Mo
2016/04/29 22:54:15
Does this bug also exist in core profile? If yes,
erikchen
2016/05/03 22:58:07
It does. I've done as you suggested.
|
| +public: |
| + ScopedRGBEmulationColorMask(gpu::gles2::GLES2Interface* contextGL, GLboolean* colorMask) |
| + : m_contextGL(contextGL) |
| + { |
| + memcpy(m_colorMask, colorMask, 4 * sizeof(GLboolean)); |
| + m_contextGL->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], false); |
| + } |
| + ~ScopedRGBEmulationColorMask() |
| + { |
| + m_contextGL->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], m_colorMask[3]); |
| + } |
| + |
| +private: |
| + gpu::gles2::GLES2Interface* m_contextGL; |
| + GLboolean m_colorMask[4]; |
| +}; |
| + |
| } // namespace |
| void WebGLRenderingContextBase::forciblyLoseOldestContext(const String& reason) |
| @@ -1117,7 +1137,7 @@ WebGLRenderingContextBase::HowToClear WebGLRenderingContextBase::clearIfComposit |
| } else { |
| contextGL()->ClearColor(0, 0, 0, 0); |
| } |
| - contextGL()->ColorMask(true, true, true, true); |
| + contextGL()->ColorMask(true, true, true, !drawingBuffer()->requiresRGBEmulation()); |
| GLbitfield clearMask = GL_COLOR_BUFFER_BIT; |
| if (contextAttributes.get().depth()) { |
| if (!combinedClear || !m_depthMask || !(mask & GL_DEPTH_BUFFER_BIT)) |
| @@ -1409,6 +1429,9 @@ void WebGLRenderingContextBase::bindRenderbuffer(ScriptState* scriptState, GLenu |
| m_renderbufferBinding = renderBuffer; |
| contextGL()->BindRenderbuffer(target, objectOrZero(renderBuffer)); |
| preserveObjectWrapper(scriptState, this, "renderbuffer", 0, renderBuffer); |
| + |
| + drawingBuffer()->setRenderbufferBinding(objectOrZero(renderBuffer)); |
| + |
| if (renderBuffer) |
| renderBuffer->setHasEverBeenBound(); |
| } |
| @@ -1647,6 +1670,11 @@ void WebGLRenderingContextBase::clear(GLbitfield mask) |
| synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "clear", reason); |
| return; |
| } |
| + |
| + std::unique_ptr<ScopedRGBEmulationColorMask> scopedColorMask; |
|
Ken Russell (switch to Gerrit)
2016/04/29 09:33:09
I'd suggest changing ScopedRGBEmulationColorMask's
erikchen
2016/05/03 22:58:07
Done.
|
| + if (m_drawingBuffer->requiresRGBEmulation()) |
| + scopedColorMask.reset(new ScopedRGBEmulationColorMask(contextGL(), m_colorMask)); |
| + |
| if (clearIfComposited(mask) != CombinedClear) { |
| // If clearing the default back buffer's depth buffer, also clear the stencil buffer, if one |
| // was allocated implicitly. This avoids performance problems on some GPUs. |
| @@ -1918,8 +1946,10 @@ void WebGLRenderingContextBase::deleteRenderbuffer(WebGLRenderbuffer* renderbuff |
| { |
| if (!deleteObject(renderbuffer)) |
| return; |
| - if (renderbuffer == m_renderbufferBinding) |
| + if (renderbuffer == m_renderbufferBinding) { |
| m_renderbufferBinding = nullptr; |
| + drawingBuffer()->setRenderbufferBinding(0); |
| + } |
| if (m_framebufferBinding) |
| m_framebufferBinding->removeAttachmentFromBoundFramebuffer(GL_FRAMEBUFFER, renderbuffer); |
| if (getFramebufferBinding(GL_READ_FRAMEBUFFER)) |
| @@ -2067,6 +2097,9 @@ void WebGLRenderingContextBase::drawArrays(GLenum mode, GLint first, GLsizei cou |
| if (!validateDrawArrays("drawArrays")) |
| return; |
| + std::unique_ptr<ScopedRGBEmulationColorMask> scopedColorMask; |
| + if (m_drawingBuffer->requiresRGBEmulation()) |
| + scopedColorMask.reset(new ScopedRGBEmulationColorMask(contextGL(), m_colorMask)); |
| clearIfComposited(); |
| contextGL()->DrawArrays(mode, first, count); |
| markContextChanged(CanvasChanged); |
| @@ -2082,6 +2115,9 @@ void WebGLRenderingContextBase::drawElements(GLenum mode, GLsizei count, GLenum |
| return; |
| } |
| + std::unique_ptr<ScopedRGBEmulationColorMask> scopedColorMask; |
| + if (m_drawingBuffer->requiresRGBEmulation()) |
| + scopedColorMask.reset(new ScopedRGBEmulationColorMask(contextGL(), m_colorMask)); |
| clearIfComposited(); |
| contextGL()->DrawElements(mode, count, type, reinterpret_cast<void*>(static_cast<intptr_t>(offset))); |
| markContextChanged(CanvasChanged); |
| @@ -2092,6 +2128,9 @@ void WebGLRenderingContextBase::drawArraysInstancedANGLE(GLenum mode, GLint firs |
| if (!validateDrawArrays("drawArraysInstancedANGLE")) |
| return; |
| + std::unique_ptr<ScopedRGBEmulationColorMask> scopedColorMask; |
| + if (m_drawingBuffer->requiresRGBEmulation()) |
| + scopedColorMask.reset(new ScopedRGBEmulationColorMask(contextGL(), m_colorMask)); |
| clearIfComposited(); |
| contextGL()->DrawArraysInstancedANGLE(mode, first, count, primcount); |
| markContextChanged(CanvasChanged); |
| @@ -2102,6 +2141,9 @@ void WebGLRenderingContextBase::drawElementsInstancedANGLE(GLenum mode, GLsizei |
| if (!validateDrawElements("drawElementsInstancedANGLE", type, offset)) |
| return; |
| + std::unique_ptr<ScopedRGBEmulationColorMask> scopedColorMask; |
| + if (m_drawingBuffer->requiresRGBEmulation()) |
| + scopedColorMask.reset(new ScopedRGBEmulationColorMask(contextGL(), m_colorMask)); |
| clearIfComposited(); |
| contextGL()->DrawElementsInstancedANGLE(mode, count, type, reinterpret_cast<void*>(static_cast<intptr_t>(offset)), primcount); |
| markContextChanged(CanvasChanged); |
| @@ -2533,6 +2575,8 @@ ScriptValue WebGLRenderingContextBase::getParameter(ScriptState* scriptState, GL |
| case GL_ALIASED_POINT_SIZE_RANGE: |
| return getWebGLFloatArrayParameter(scriptState, pname); |
| case GL_ALPHA_BITS: |
| + if (m_drawingBuffer->requiresRGBEmulation()) |
| + return WebGLAny(scriptState, 0); |
| return getIntParameter(scriptState, pname); |
| case GL_ARRAY_BUFFER_BINDING: |
| return WebGLAny(scriptState, m_boundArrayBuffer.get()); |
| @@ -4954,6 +4998,7 @@ void WebGLRenderingContextBase::loseContextImpl(WebGLRenderingContextBase::LostC |
| // Make absolutely sure we do not refer to an already-deleted texture or framebuffer. |
| drawingBuffer()->setTexture2DBinding(0); |
| drawingBuffer()->setFramebufferBinding(GL_FRAMEBUFFER, 0); |
| + drawingBuffer()->setRenderbufferBinding(0); |
| detachAndRemoveAllObjects(); |