Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp (270252 => 270253)
--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp 2020-11-30 19:08:40 UTC (rev 270252)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp 2020-11-30 19:20:52 UTC (rev 270253)
@@ -1340,7 +1340,7 @@
return;
if (!validateTexture3DBinding("copyTexSubImage3D", target))
return;
- clearIfComposited();
+ clearIfComposited(ClearCallerOther);
m_context->copyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
}
@@ -3566,7 +3566,7 @@
// taint the origin using the WebGL API.
ASSERT(canvasBase().originClean());
- clearIfComposited();
+ clearIfComposited(ClearCallerOther);
GCGLsizei length, columns, rows;
m_context->getExtensions().readnPixelsRobustANGLE(x, y, width, height, format, type, 0, &length, &columns, &rows, reinterpret_cast<uint8_t*>(offset), true);
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (270252 => 270253)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2020-11-30 19:08:40 UTC (rev 270252)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2020-11-30 19:20:52 UTC (rev 270253)
@@ -461,6 +461,27 @@
bool m_enabled;
};
+class ScopedDisableRasterizerDiscard {
+public:
+ explicit ScopedDisableRasterizerDiscard(WebGLRenderingContextBase* context, bool wasEnabled)
+ : m_context(context)
+ , m_wasEnabled(wasEnabled)
+ {
+ if (m_wasEnabled)
+ m_context->disable(GraphicsContextGL::RASTERIZER_DISCARD);
+ }
+
+ ~ScopedDisableRasterizerDiscard()
+ {
+ if (m_wasEnabled)
+ m_context->enable(GraphicsContextGL::RASTERIZER_DISCARD);
+ }
+
+private:
+ WebGLRenderingContextBase* m_context;
+ bool m_wasEnabled;
+};
+
#define ADD_VALUES_TO_SET(set, arr) \
set.add(arr, arr + WTF_ARRAY_LENGTH(arr))
@@ -865,7 +886,9 @@
m_stencilFuncMaskBack = 0xFFFFFFFF;
m_layerCleared = false;
m_numGLErrorsToConsoleAllowed = maxGLErrorsAllowedToConsole;
-
+
+ m_rasterizerDiscardEnabled = false;
+
m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0;
m_scissorEnabled = false;
m_clearDepth = 1;
@@ -1097,7 +1120,7 @@
canvas->notifyObserversCanvasChanged(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
}
-bool WebGLRenderingContextBase::clearIfComposited(GCGLbitfield mask)
+bool WebGLRenderingContextBase::clearIfComposited(WebGLRenderingContextBase::ClearCaller caller, GCGLbitfield mask)
{
if (isContextLostOrPending())
return false;
@@ -1107,7 +1130,7 @@
GCGLbitfield buffersNeedingClearing = m_context->getBuffersToAutoClear();
- if (!buffersNeedingClearing || (mask && m_framebufferBinding))
+ if (!buffersNeedingClearing || (mask && m_framebufferBinding) || (m_rasterizerDiscardEnabled && caller == ClearCallerDrawOrClear))
return false;
// Use the underlying GraphicsContext3D's attributes to take into
@@ -1145,10 +1168,13 @@
GCGLenum bindingPoint = isWebGL2() ? GraphicsContextGL::DRAW_FRAMEBUFFER : GraphicsContextGL::FRAMEBUFFER;
if (m_framebufferBinding)
m_context->bindFramebuffer(bindingPoint, 0);
- // If the WebGL 2.0 clearBuffer APIs already have been used to
- // selectively clear some of the buffers, don't destroy those
- // results.
- m_context->clear(clearMask & buffersNeedingClearing);
+ {
+ ScopedDisableRasterizerDiscard disable(this, m_rasterizerDiscardEnabled);
+ // If the WebGL 2.0 clearBuffer APIs already have been used to
+ // selectively clear some of the buffers, don't destroy those
+ // results.
+ m_context->clear(clearMask & buffersNeedingClearing);
+ }
m_context->setBuffersToAutoClear(0);
restoreStateAfterClear();
@@ -1200,7 +1226,7 @@
canvas->clearPresentationCopy();
}
- clearIfComposited();
+ clearIfComposited(ClearCallerOther);
if (!m_markedCanvasDirty && !m_layerCleared)
return;
@@ -1217,7 +1243,7 @@
{
if (isContextLostOrPending())
return nullptr;
- clearIfComposited();
+ clearIfComposited(ClearCallerOther);
return m_context->paintRenderingResultsToImageData();
}
@@ -1680,7 +1706,7 @@
return;
}
#endif
- if (!clearIfComposited(mask))
+ if (!clearIfComposited(ClearCallerDrawOrClear, mask))
m_context->clear(mask);
markContextChangedAndNotifyCanvasObserver();
}
@@ -1857,7 +1883,7 @@
#if USE(ANGLE)
if (!validateTexture2DBinding("copyTexSubImage2D", target))
return;
- clearIfComposited();
+ clearIfComposited(ClearCallerOther);
m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
#else
if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
@@ -1888,7 +1914,7 @@
synthesizeGLError(GraphicsContextGL::INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
return;
}
- clearIfComposited();
+ clearIfComposited(ClearCallerOther);
GCGLint clippedX, clippedY;
GCGLsizei clippedWidth, clippedHeight;
@@ -2169,6 +2195,8 @@
}
if (cap == GraphicsContextGL::SCISSOR_TEST)
m_scissorEnabled = false;
+ if (cap == GraphicsContextGL::RASTERIZER_DISCARD)
+ m_rasterizerDiscardEnabled = false;
m_context->disable(cap);
}
@@ -2536,7 +2564,7 @@
if (m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*this, *m_currentProgram))
return;
- clearIfComposited();
+ clearIfComposited(ClearCallerDrawOrClear);
#if !USE(ANGLE)
bool vertexAttrib0Simulated = false;
@@ -2599,7 +2627,7 @@
if (m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*this, *m_currentProgram))
return;
- clearIfComposited();
+ clearIfComposited(ClearCallerDrawOrClear);
#if !USE(ANGLE)
bool vertexAttrib0Simulated = false;
@@ -2650,6 +2678,8 @@
}
if (cap == GraphicsContextGL::SCISSOR_TEST)
m_scissorEnabled = true;
+ if (cap == GraphicsContextGL::RASTERIZER_DISCARD)
+ m_rasterizerDiscardEnabled = true;
m_context->enable(cap);
}
@@ -4334,7 +4364,7 @@
}
#endif // USE(ANGLE)
- clearIfComposited();
+ clearIfComposited(ClearCallerOther);
void* data = ""
#if USE(ANGLE)
@@ -5593,7 +5623,7 @@
if (!tex)
return;
#if USE(ANGLE)
- clearIfComposited();
+ clearIfComposited(ClearCallerOther);
m_context->copyTexImage2D(target, level, internalFormat, x, y, width, height, border);
#else
if (!isTexInternalFormatColorBufferCombinationValid(internalFormat, getBoundReadFramebufferColorFormat())) {
@@ -5609,7 +5639,7 @@
synthesizeGLError(GraphicsContextGL::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
return;
}
- clearIfComposited();
+ clearIfComposited(ClearCallerOther);
GCGLint clippedX, clippedY;
GCGLsizei clippedWidth, clippedHeight;
@@ -7685,7 +7715,7 @@
return;
#endif // !USE(ANGLE)
- clearIfComposited();
+ clearIfComposited(ClearCallerDrawOrClear);
#if !USE(ANGLE)
bool vertexAttrib0Simulated = false;
@@ -7731,7 +7761,7 @@
return;
#endif // !USE(ANGLE)
- clearIfComposited();
+ clearIfComposited(ClearCallerDrawOrClear);
#if !USE(ANGLE)
bool vertexAttrib0Simulated = false;
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (270252 => 270253)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2020-11-30 19:08:40 UTC (rev 270252)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2020-11-30 19:20:52 UTC (rev 270253)
@@ -647,6 +647,8 @@
GCGLint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
GCGLuint m_stencilFuncMask, m_stencilFuncMaskBack;
+ bool m_rasterizerDiscardEnabled { false };
+
bool m_isGLES2Compliant;
bool m_isGLES2NPOTStrict;
bool m_isDepthStencilSupported;
@@ -718,10 +720,17 @@
RefPtr<Float32Array> getWebGLFloatArrayParameter(GCGLenum);
RefPtr<Int32Array> getWebGLIntArrayParameter(GCGLenum);
+ enum ClearCaller {
+ // Caller of ClearIfComposited is a user-level draw or clear call.
+ ClearCallerDrawOrClear,
+ // Caller of ClearIfComposited is anything else, including
+ // readbacks or copies.
+ ClearCallerOther,
+ };
// Clear the backbuffer if it was composited since the last operation.
// clearMask is set to the bitfield of any clear that would happen anyway at this time
// and the function returns true if that clear is now unnecessary.
- bool clearIfComposited(GCGLbitfield clearMask = 0);
+ bool clearIfComposited(ClearCaller, GCGLbitfield clearMask = 0);
// Helper to restore state that clearing the framebuffer may destroy.
void restoreStateAfterClear();