Title: [295490] trunk
Revision
295490
Author
[email protected]
Date
2022-06-13 09:11:21 -0700 (Mon, 13 Jun 2022)

Log Message

WebGL: Fix implicit clears with rasterizer discard enabled
https://bugs.webkit.org/show_bug.cgi?id=223351

Patch by Alexey Knyazev <[email protected]> on 2022-06-13
Reviewed by Kimmo Kinnunen.

* Do not mark context as changed after draw or clear ops with
enabled rasterizer discard.
* Rename ClearCaller enum to CallerType.

* LayoutTests/TestExpectations:
* Source/WebCore/html/canvas/WebGL2RenderingContext.cpp:
(WebCore::WebGL2RenderingContext::blitFramebuffer):
(WebCore::WebGL2RenderingContext::copyTexSubImage3D):
(WebCore::WebGL2RenderingContext::drawRangeElements):
(WebCore::WebGL2RenderingContext::readPixels):
* Source/WebCore/html/canvas/WebGLMultiDraw.cpp:
(WebCore::WebGLMultiDraw::multiDrawArraysWEBGL):
(WebCore::WebGLMultiDraw::multiDrawArraysInstancedWEBGL):
(WebCore::WebGLMultiDraw::multiDrawElementsWEBGL):
(WebCore::WebGLMultiDraw::multiDrawElementsInstancedWEBGL):
* Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::markContextChangedAndNotifyCanvasObserver):
(WebCore::WebGLRenderingContextBase::clearIfComposited):
(WebCore::WebGLRenderingContextBase::paintRenderingResultsToCanvas):
(WebCore::WebGLRenderingContextBase::paintRenderingResultsToPixelBuffer):
(WebCore::WebGLRenderingContextBase::clear):
(WebCore::WebGLRenderingContextBase::copyTexSubImage2D):
(WebCore::WebGLRenderingContextBase::drawArrays):
(WebCore::WebGLRenderingContextBase::drawElements):
(WebCore::WebGLRenderingContextBase::readPixels):
(WebCore::WebGLRenderingContextBase::copyTexImage2D):
(WebCore::WebGLRenderingContextBase::drawArraysInstanced):
(WebCore::WebGLRenderingContextBase::drawElementsInstanced):
* Source/WebCore/html/canvas/WebGLRenderingContextBase.h:

Canonical link: https://commits.webkit.org/251494@main

Modified Paths

Diff

Modified: trunk/LayoutTests/TestExpectations (295489 => 295490)


--- trunk/LayoutTests/TestExpectations	2022-06-13 16:10:45 UTC (rev 295489)
+++ trunk/LayoutTests/TestExpectations	2022-06-13 16:11:21 UTC (rev 295490)
@@ -3782,6 +3782,7 @@
 webgl/2.0.y/conformance2/extensions/ext-texture-norm16.html [ Pass ]
 webgl/2.0.y/conformance2/extensions/oes-draw-buffers-indexed.html [ Pass ]
 webgl/2.0.y/conformance2/extensions/promoted-extensions-in-shaders.html [ Pass ]
+webgl/2.0.y/conformance2/rendering/rasterizer-discard-and-implicit-clear.html [ Pass ]
 
 # WebGL 1.0.3 and 2.0.0 tests where behavior is obsolete and WebKit contains implementation
 # and tests for the new behavior. Should be removed once 1.0.3 and 2.0.0 are retired.

Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp (295489 => 295490)


--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp	2022-06-13 16:10:45 UTC (rev 295489)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp	2022-06-13 16:11:21 UTC (rev 295490)
@@ -703,7 +703,7 @@
     if (isContextLostOrPending())
         return;
     m_context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
-    markContextChangedAndNotifyCanvasObserver();
+    markContextChangedAndNotifyCanvasObserver(CallerTypeOther);
 }
 
 void WebGL2RenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
@@ -1144,7 +1144,7 @@
         return;
     if (!validateTexture3DBinding("copyTexSubImage3D", target))
         return;
-    clearIfComposited(ClearCallerOther);
+    clearIfComposited(CallerTypeOther);
     m_context->copyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
 }
 
@@ -1612,7 +1612,7 @@
     if (m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*this, *m_currentProgram))
         return;
 
-    clearIfComposited(ClearCallerDrawOrClear);
+    clearIfComposited(CallerTypeDrawOrClear);
 
     {
         InspectorScopedShaderProgramHighlight scopedHighlight(*this, m_currentProgram.get());
@@ -3392,7 +3392,7 @@
     // taint the origin using the WebGL API.
     ASSERT(canvasBase().originClean());
 
-    clearIfComposited(ClearCallerOther);
+    clearIfComposited(CallerTypeOther);
 
     m_context->readnPixels(x, y, width, height, format, type, offset);
 }

Modified: trunk/Source/WebCore/html/canvas/WebGLMultiDraw.cpp (295489 => 295490)


--- trunk/Source/WebCore/html/canvas/WebGLMultiDraw.cpp	2022-06-13 16:10:45 UTC (rev 295489)
+++ trunk/Source/WebCore/html/canvas/WebGLMultiDraw.cpp	2022-06-13 16:11:21 UTC (rev 295490)
@@ -73,7 +73,7 @@
     if (m_context->m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*m_context, *m_context->m_currentProgram))
         return;
 
-    m_context->clearIfComposited(WebGLRenderingContextBase::ClearCallerDrawOrClear);
+    m_context->clearIfComposited(WebGLRenderingContextBase::CallerTypeDrawOrClear);
 
     {
         InspectorScopedShaderProgramHighlight scopedHighlight(*m_context, m_context->m_currentProgram.get());
@@ -102,7 +102,7 @@
     if (m_context->m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*m_context, *m_context->m_currentProgram))
         return;
 
-    m_context->clearIfComposited(WebGLRenderingContextBase::ClearCallerDrawOrClear);
+    m_context->clearIfComposited(WebGLRenderingContextBase::CallerTypeDrawOrClear);
 
     {
         InspectorScopedShaderProgramHighlight scopedHighlight(*m_context, m_context->m_currentProgram.get());
@@ -130,7 +130,7 @@
     if (m_context->m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*m_context, *m_context->m_currentProgram))
         return;
 
-    m_context->clearIfComposited(WebGLRenderingContextBase::ClearCallerDrawOrClear);
+    m_context->clearIfComposited(WebGLRenderingContextBase::CallerTypeDrawOrClear);
 
     {
         InspectorScopedShaderProgramHighlight scopedHighlight(*m_context, m_context->m_currentProgram.get());
@@ -159,7 +159,7 @@
     if (m_context->m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*m_context, *m_context->m_currentProgram))
         return;
 
-    m_context->clearIfComposited(WebGLRenderingContextBase::ClearCallerDrawOrClear);
+    m_context->clearIfComposited(WebGLRenderingContextBase::CallerTypeDrawOrClear);
 
     {
         InspectorScopedShaderProgramHighlight scopedHighlight(*m_context, m_context->m_currentProgram.get());

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (295489 => 295490)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2022-06-13 16:10:45 UTC (rev 295489)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2022-06-13 16:11:21 UTC (rev 295490)
@@ -1294,8 +1294,12 @@
     }
 }
 
-void WebGLRenderingContextBase::markContextChangedAndNotifyCanvasObserver()
+void WebGLRenderingContextBase::markContextChangedAndNotifyCanvasObserver(WebGLRenderingContextBase::CallerType caller)
 {
+    // Draw and clear ops with rasterizer discard enabled do not change the canvas.
+    if (caller == CallerTypeDrawOrClear && m_rasterizerDiscardEnabled)
+        return;
+
     // If we're not touching the default framebuffer, nothing visible has changed.
     if (m_framebufferBinding)
         return;
@@ -1311,7 +1315,7 @@
     canvas->notifyObserversCanvasChanged(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
 }
 
-bool WebGLRenderingContextBase::clearIfComposited(WebGLRenderingContextBase::ClearCaller caller, GCGLbitfield mask)
+bool WebGLRenderingContextBase::clearIfComposited(WebGLRenderingContextBase::CallerType caller, GCGLbitfield mask)
 {
     if (isContextLostOrPending())
         return false;
@@ -1324,7 +1328,7 @@
 
     GCGLbitfield buffersNeedingClearing = m_context->getBuffersToAutoClear();
 
-    if (!buffersNeedingClearing || (mask && m_framebufferBinding) || (m_rasterizerDiscardEnabled && caller == ClearCallerDrawOrClear))
+    if (!buffersNeedingClearing || (mask && m_framebufferBinding) || (m_rasterizerDiscardEnabled && caller == CallerTypeDrawOrClear))
         return false;
 
     // Use the underlying GraphicsContext3D's attributes to take into
@@ -1429,7 +1433,7 @@
         return;
     }
 
-    clearIfComposited(ClearCallerOther);
+    clearIfComposited(CallerTypeOther);
 
     if (!m_markedCanvasDirty && !m_layerCleared)
         return;
@@ -1451,7 +1455,7 @@
 {
     if (isContextLostOrPending())
         return nullptr;
-    clearIfComposited(ClearCallerOther);
+    clearIfComposited(CallerTypeOther);
     return m_context->paintRenderingResultsToPixelBuffer();
 }
 
@@ -1917,7 +1921,7 @@
         return;
     }
 #endif
-    if (!clearIfComposited(ClearCallerDrawOrClear, mask))
+    if (!clearIfComposited(CallerTypeDrawOrClear, mask))
         m_context->clear(mask);
     markContextChangedAndNotifyCanvasObserver();
 }
@@ -2094,7 +2098,7 @@
 #if USE(ANGLE)
     if (!validateTexture2DBinding("copyTexSubImage2D", target))
         return;
-    clearIfComposited(ClearCallerOther);
+    clearIfComposited(CallerTypeOther);
     m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
 #else
     if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
@@ -2125,7 +2129,7 @@
         synthesizeGLError(GraphicsContextGL::INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
         return;
     }
-    clearIfComposited(ClearCallerOther);
+    clearIfComposited(CallerTypeOther);
 
     GCGLint clippedX, clippedY;
     GCGLsizei clippedWidth, clippedHeight;
@@ -2801,7 +2805,7 @@
     if (m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*this, *m_currentProgram))
         return;
 
-    clearIfComposited(ClearCallerDrawOrClear);
+    clearIfComposited(CallerTypeDrawOrClear);
 
 #if !USE(ANGLE)
     bool vertexAttrib0Simulated = false;
@@ -2850,7 +2854,7 @@
     if (m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*this, *m_currentProgram))
         return;
 
-    clearIfComposited(ClearCallerDrawOrClear);
+    clearIfComposited(CallerTypeDrawOrClear);
 
 #if !USE(ANGLE)
     bool vertexAttrib0Simulated = false;
@@ -4644,7 +4648,7 @@
     }
 #endif // USE(ANGLE)
 
-    clearIfComposited(ClearCallerOther);
+    clearIfComposited(CallerTypeOther);
     void* data = ""
 
 #if USE(ANGLE)
@@ -5902,7 +5906,7 @@
     if (!tex)
         return;
 #if USE(ANGLE)
-    clearIfComposited(ClearCallerOther);
+    clearIfComposited(CallerTypeOther);
     m_context->copyTexImage2D(target, level, internalFormat, x, y, width, height, border);
 #else
     if (!isTexInternalFormatColorBufferCombinationValid(internalFormat, getBoundReadFramebufferColorFormat())) {
@@ -5918,7 +5922,7 @@
         synthesizeGLError(GraphicsContextGL::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
         return;
     }
-    clearIfComposited(ClearCallerOther);
+    clearIfComposited(CallerTypeOther);
 
     GCGLint clippedX, clippedY;
     GCGLsizei clippedWidth, clippedHeight;
@@ -7994,7 +7998,7 @@
     if (m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*this, *m_currentProgram))
         return;
 
-    clearIfComposited(ClearCallerDrawOrClear);
+    clearIfComposited(CallerTypeDrawOrClear);
 
 #if !USE(ANGLE)
     bool vertexAttrib0Simulated = false;
@@ -8042,7 +8046,7 @@
     if (m_currentProgram && InspectorInstrumentation::isWebGLProgramDisabled(*this, *m_currentProgram))
         return;
 
-    clearIfComposited(ClearCallerDrawOrClear);
+    clearIfComposited(CallerTypeDrawOrClear);
 
 #if !USE(ANGLE)
     bool vertexAttrib0Simulated = false;

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (295489 => 295490)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2022-06-13 16:10:45 UTC (rev 295489)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2022-06-13 16:11:21 UTC (rev 295490)
@@ -519,8 +519,16 @@
 
     void setGraphicsContextGL(Ref<GraphicsContextGL>&&);
     void destroyGraphicsContextGL();
+
+    enum CallerType {
+        // Caller is a user-level draw or clear call.
+        CallerTypeDrawOrClear,
+        // Caller is anything else, including blits, readbacks or copies.
+        CallerTypeOther,
+    };
+
     void markContextChanged();
-    void markContextChangedAndNotifyCanvasObserver();
+    void markContextChangedAndNotifyCanvasObserver(CallerType = CallerTypeDrawOrClear);
 
     void addActivityStateChangeObserverIfNecessary();
     void removeActivityStateChangeObserver();
@@ -797,17 +805,10 @@
     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(ClearCaller, GCGLbitfield clearMask = 0);
+    bool clearIfComposited(CallerType, GCGLbitfield clearMask = 0);
 
     // Helper to restore state that clearing the framebuffer may destroy.
     void restoreStateAfterClear();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to