Title: [264733] trunk
Revision
264733
Author
[email protected]
Date
2020-07-22 16:38:57 -0700 (Wed, 22 Jul 2020)

Log Message

[WebGL2] Implement multiple render target entry points
https://bugs.webkit.org/show_bug.cgi?id=211156

Patch by Kenneth Russell <[email protected]> on 2020-07-22
Reviewed by Dean Jackson.

Source/WebCore:

Implement the drawBuffers and clearBuffer entry points.

Integrate the clearBuffer APIs with preserveDrawingBuffer:false's
auto-clearing. Move some auto-clearing state from
WebGLRenderingContextBase to GraphicsContextGL and
GraphicsContextGLOpenGL.

Rename setPreserveDrawingBuffer to enablePreserveDrawingBuffer to
make it clear that arbitrary changes of preserveDrawingBuffer are
not supported. setPreserveDrawingBuffer was previously added for
capture of preserveDrawingBuffer:false WebGL canvases.

Covered by existing WebGL conformance tests and canvas capture
layout tests.

* Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp:
(WebCore::CanvasCaptureMediaStreamTrack::Source::canvasChanged):
* html/canvas/WebGL2RenderingContext.cpp:
(WebCore::WebGL2RenderingContext::drawBuffers):
(WebCore::WebGL2RenderingContext::clearBufferiv):
(WebCore::WebGL2RenderingContext::clearBufferuiv):
(WebCore::WebGL2RenderingContext::clearBufferfv):
(WebCore::WebGL2RenderingContext::clearBufferfi):
(WebCore::WebGL2RenderingContext::validateClearBuffer):
(WebCore::WebGL2RenderingContext::updateBuffersToAutoClear):
* html/canvas/WebGL2RenderingContext.h:
* html/canvas/WebGLFramebuffer.cpp:
(WebCore::WebGLFramebuffer::drawBuffersIfNecessary):
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::clearIfComposited):
(WebCore::WebGLRenderingContextBase::enablePreserveDrawingBuffer):
* html/canvas/WebGLRenderingContextBase.h:
(WebCore::WebGLRenderingContextBase::setPreserveDrawingBuffer): Deleted.
* platform/graphics/GraphicsContextGL.cpp:
(WebCore::GraphicsContextGL::enablePreserveDrawingBuffer):
* platform/graphics/GraphicsContextGL.h:
* platform/graphics/angle/GraphicsContextGLANGLE.cpp:
(WebCore::GraphicsContextGLOpenGL::markLayerComposited):
(WebCore::GraphicsContextGLOpenGL::drawBuffers):
(WebCore::GraphicsContextGLOpenGL::clearBufferiv):
(WebCore::GraphicsContextGLOpenGL::clearBufferuiv):
(WebCore::GraphicsContextGLOpenGL::clearBufferfv):
(WebCore::GraphicsContextGLOpenGL::clearBufferfi):
* platform/graphics/opengl/GraphicsContextGLOpenGL.cpp:
(WebCore::GraphicsContextGLOpenGL::resetBuffersToAutoClear):
(WebCore::GraphicsContextGLOpenGL::setBuffersToAutoClear):
(WebCore::GraphicsContextGLOpenGL::getBuffersToAutoClear const):
(WebCore::GraphicsContextGLOpenGL::enablePreserveDrawingBuffer):
* platform/graphics/opengl/GraphicsContextGLOpenGL.h:
* platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp:
(WebCore::GraphicsContextGLOpenGL::markLayerComposited):
(WebCore::GraphicsContextGLOpenGL::drawBuffers):

LayoutTests:

Rebaseline one layout test which is now fully passing, and another
which now properly detects errors.

* fast/canvas/webgl/webgl2/sequences-expected.txt:
* webgl/2.0.0/conformance2/reading/read-pixels-from-fbo-test-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (264732 => 264733)


--- trunk/LayoutTests/ChangeLog	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/LayoutTests/ChangeLog	2020-07-22 23:38:57 UTC (rev 264733)
@@ -1,3 +1,16 @@
+2020-07-22  Kenneth Russell  <[email protected]>
+
+        [WebGL2] Implement multiple render target entry points
+        https://bugs.webkit.org/show_bug.cgi?id=211156
+
+        Reviewed by Dean Jackson.
+
+        Rebaseline one layout test which is now fully passing, and another
+        which now properly detects errors.
+
+        * fast/canvas/webgl/webgl2/sequences-expected.txt:
+        * webgl/2.0.0/conformance2/reading/read-pixels-from-fbo-test-expected.txt:
+
 2020-07-22  Karl Rackler  <[email protected]>
 
         [ macOS debug wk2 ] Set expectation for imported/w3c/web-platform-tests/webrtc/RTCSctpTransport-events.html is a flaky crash.

Modified: trunk/LayoutTests/fast/canvas/webgl/webgl2/sequences-expected.txt (264732 => 264733)


--- trunk/LayoutTests/fast/canvas/webgl/webgl2/sequences-expected.txt	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/LayoutTests/fast/canvas/webgl/webgl2/sequences-expected.txt	2020-07-22 23:38:57 UTC (rev 264733)
@@ -2,6 +2,12 @@
 CONSOLE MESSAGE: WebGL: INVALID_VALUE: vertexAttribI4iv: array too small
 CONSOLE MESSAGE: WebGL: INVALID_VALUE: vertexAttribI4uiv: array too small
 CONSOLE MESSAGE: WebGL: INVALID_VALUE: vertexAttribI4uiv: array too small
+CONSOLE MESSAGE: WebGL: INVALID_VALUE: clearBufferiv: invalid array size / srcOffset
+CONSOLE MESSAGE: WebGL: INVALID_VALUE: clearBufferiv: invalid array size / srcOffset
+CONSOLE MESSAGE: WebGL: INVALID_VALUE: clearBufferuiv: invalid array size / srcOffset
+CONSOLE MESSAGE: WebGL: INVALID_VALUE: clearBufferuiv: invalid array size / srcOffset
+CONSOLE MESSAGE: WebGL: INVALID_VALUE: clearBufferfv: invalid array size / srcOffset
+CONSOLE MESSAGE: WebGL: INVALID_VALUE: clearBufferfv: invalid array size / srcOffset
 
 PASS uniform1uiv data with typed array of type ui 
 PASS uniform1uiv data with sequence of type ui 

Modified: trunk/LayoutTests/webgl/2.0.0/conformance2/reading/read-pixels-from-fbo-test-expected.txt (264732 => 264733)


--- trunk/LayoutTests/webgl/2.0.0/conformance2/reading/read-pixels-from-fbo-test-expected.txt	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/LayoutTests/webgl/2.0.0/conformance2/reading/read-pixels-from-fbo-test-expected.txt	2020-07-22 23:38:57 UTC (rev 264733)
@@ -1,200 +1,5 @@
 This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.
 
 Test: ../../resources/webgl_test_files/conformance2/reading/read-pixels-from-fbo-test.html
-[ 1: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 2: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 3: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 4: PASS ] Color read back as expected
-[ 5: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 6: PASS ] Color read back as expected
-[ 7: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 8: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 9: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 10: FAIL ] Expected color = 250,0,0,0, was = 0,0,0,1
-[ 11: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 12: FAIL ] Expected color = 250,0,0,0, was = 0
-[ 13: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 14: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 15: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 16: FAIL ] Expected color = -126,0,0,0, was = 0,0,0,1
-[ 17: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 18: FAIL ] Expected color = -126,0,0,0, was = 0
-[ 19: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 20: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 21: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 22: FAIL ] Expected color = 30001,0,0,0, was = 0,0,0,1
-[ 23: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 24: FAIL ] Expected color = 30001,0,0,0, was = 0
-[ 25: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 26: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 27: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 28: FAIL ] Expected color = -14189,0,0,0, was = 0,0,0,1
-[ 29: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 30: FAIL ] Expected color = -14189,0,0,0, was = 0
-[ 31: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 32: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 33: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 34: FAIL ] Expected color = 126726,0,0,0, was = 0,0,0,1
-[ 35: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 36: FAIL ] Expected color = 126726,0,0,0, was = 0
-[ 37: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 38: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 39: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 40: FAIL ] Expected color = -126726,0,0,0, was = 0,0,0,1
-[ 41: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 42: FAIL ] Expected color = -126726,0,0,0, was = 0
-[ 43: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 44: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 45: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 46: PASS ] Color read back as expected
-[ 47: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 48: PASS ] Color read back as expected
-[ 49: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 50: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 51: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 52: PASS ] Color read back as expected
-[ 53: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 54: PASS ] Color read back as expected
-[ 55: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 56: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 57: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 58: PASS ] Color read back as expected
-[ 59: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 60: PASS ] Color read back as expected
-[ 61: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 62: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 63: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 64: PASS ] Color read back as expected
-[ 65: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 66: PASS ] Color read back as expected
-[ 67: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 68: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 69: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 70: PASS ] Color read back as expected
-[ 71: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 72: PASS ] Color read back as expected
-[ 73: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 74: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 75: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 76: PASS ] Color read back as expected
-[ 77: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 78: PASS ] Color read back as expected
-[ 79: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 80: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 81: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 82: PASS ] Color read back as expected
-[ 83: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 84: PASS ] Color read back as expected
-[ 85: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 86: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 87: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 88: PASS ] Color read back as expected
-[ 89: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 90: PASS ] Color read back as expected
-[ 91: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 92: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 93: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 94: PASS ] Color read back as expected
-[ 95: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 96: PASS ] Color read back as expected
-[ 97: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 98: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 99: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 100: PASS ] Color read back as expected
-[ 101: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 102: PASS ] Color read back as expected
-[ 103: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 104: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 105: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 106: PASS ] Color read back as expected
-[ 107: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 108: PASS ] Color read back as expected
-[ 109: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 110: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 111: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 112: PASS ] Color read back as expected
-[ 113: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 114: PASS ] Color read back as expected
-[ 115: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 116: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 117: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 118: PASS ] Color read back as expected
-[ 119: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 120: PASS ] Color read back as expected
-[ 121: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 122: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 123: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 124: PASS ] Color read back as expected
-[ 125: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 126: PASS ] Color read back as expected
-[ 127: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 128: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 129: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 130: PASS ] Color read back as expected
-[ 131: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 132: PASS ] Color read back as expected
-[ 133: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 134: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 135: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 136: PASS ] Color read back as expected
-[ 137: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 138: PASS ] Color read back as expected
-[ 139: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 140: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 141: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 142: PASS ] Color read back as expected
-[ 143: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 144: PASS ] Color read back as expected
-[ 145: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 146: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 147: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 148: FAIL ] Expected color = 127,0,255,178, was = 0,0,0,0
-[ 149: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 150: FAIL ] Expected color = 127,0,255,178, was = 0,0,0,0
-[ 151: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 152: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 153: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 154: FAIL ] Expected color = -55,56,80,127, was = 0,0,0,0
-[ 155: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 156: FAIL ] Expected color = -55,56,80,127, was = 0,0,0,0
-[ 157: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 158: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 159: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 160: FAIL ] Expected color = 178,0,127,3, was = 0,0,0,0
-[ 161: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 162: FAIL ] Expected color = 178,0,127,3, was = 0,0,0,0
-[ 163: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 164: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 165: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 166: FAIL ] Expected color = 14189,6735,0,19, was = 0,0,0,0
-[ 167: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 168: FAIL ] Expected color = 14189,6735,0,19, was = 0,0,0,0
-[ 169: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 170: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 171: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 172: FAIL ] Expected color = 14189,-6735,0,19, was = 0,0,0,0
-[ 173: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 174: FAIL ] Expected color = 14189,-6735,0,19, was = 0,0,0,0
-[ 175: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 176: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 177: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 178: FAIL ] Expected color = 126726,6726,98765,2015, was = 0,0,0,0
-[ 179: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 180: FAIL ] Expected color = 126726,6726,98765,2015, was = 0,0,0,0
-[ 181: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 182: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 183: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 184: FAIL ] Expected color = 126726,-6726,-98765,2015, was = 0,0,0,0
-[ 185: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 186: FAIL ] Expected color = 126726,-6726,-98765,2015, was = 0,0,0,0
-[ 187: PASS ] getError was expected value: NO_ERROR : Setting up fbo should generate no error
-[ 188: PASS ] getError was expected value: NO_ERROR : Clear color should generate no error
-[ 189: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 190: PASS ] Color read back as expected
-[ 191: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 192: PASS ] Color read back as expected
-[ 193: PASS ] getError was expected value: NO_ERROR : readPixels should generate no error
-[ 194: PASS ] Color read back as expected
-[ 195: PASS ] successfullyParsed is true
-[ FAIL ] 26 failures reported
+[ PASS ] All tests passed
 

Modified: trunk/Source/WebCore/ChangeLog (264732 => 264733)


--- trunk/Source/WebCore/ChangeLog	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/Source/WebCore/ChangeLog	2020-07-22 23:38:57 UTC (rev 264733)
@@ -1,3 +1,63 @@
+2020-07-22  Kenneth Russell  <[email protected]>
+
+        [WebGL2] Implement multiple render target entry points
+        https://bugs.webkit.org/show_bug.cgi?id=211156
+
+        Reviewed by Dean Jackson.
+
+        Implement the drawBuffers and clearBuffer entry points.
+
+        Integrate the clearBuffer APIs with preserveDrawingBuffer:false's
+        auto-clearing. Move some auto-clearing state from
+        WebGLRenderingContextBase to GraphicsContextGL and
+        GraphicsContextGLOpenGL.
+
+        Rename setPreserveDrawingBuffer to enablePreserveDrawingBuffer to
+        make it clear that arbitrary changes of preserveDrawingBuffer are
+        not supported. setPreserveDrawingBuffer was previously added for
+        capture of preserveDrawingBuffer:false WebGL canvases.
+
+        Covered by existing WebGL conformance tests and canvas capture
+        layout tests.
+
+        * Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp:
+        (WebCore::CanvasCaptureMediaStreamTrack::Source::canvasChanged):
+        * html/canvas/WebGL2RenderingContext.cpp:
+        (WebCore::WebGL2RenderingContext::drawBuffers):
+        (WebCore::WebGL2RenderingContext::clearBufferiv):
+        (WebCore::WebGL2RenderingContext::clearBufferuiv):
+        (WebCore::WebGL2RenderingContext::clearBufferfv):
+        (WebCore::WebGL2RenderingContext::clearBufferfi):
+        (WebCore::WebGL2RenderingContext::validateClearBuffer):
+        (WebCore::WebGL2RenderingContext::updateBuffersToAutoClear):
+        * html/canvas/WebGL2RenderingContext.h:
+        * html/canvas/WebGLFramebuffer.cpp:
+        (WebCore::WebGLFramebuffer::drawBuffersIfNecessary):
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::clearIfComposited):
+        (WebCore::WebGLRenderingContextBase::enablePreserveDrawingBuffer):
+        * html/canvas/WebGLRenderingContextBase.h:
+        (WebCore::WebGLRenderingContextBase::setPreserveDrawingBuffer): Deleted.
+        * platform/graphics/GraphicsContextGL.cpp:
+        (WebCore::GraphicsContextGL::enablePreserveDrawingBuffer):
+        * platform/graphics/GraphicsContextGL.h:
+        * platform/graphics/angle/GraphicsContextGLANGLE.cpp:
+        (WebCore::GraphicsContextGLOpenGL::markLayerComposited):
+        (WebCore::GraphicsContextGLOpenGL::drawBuffers):
+        (WebCore::GraphicsContextGLOpenGL::clearBufferiv):
+        (WebCore::GraphicsContextGLOpenGL::clearBufferuiv):
+        (WebCore::GraphicsContextGLOpenGL::clearBufferfv):
+        (WebCore::GraphicsContextGLOpenGL::clearBufferfi):
+        * platform/graphics/opengl/GraphicsContextGLOpenGL.cpp:
+        (WebCore::GraphicsContextGLOpenGL::resetBuffersToAutoClear):
+        (WebCore::GraphicsContextGLOpenGL::setBuffersToAutoClear):
+        (WebCore::GraphicsContextGLOpenGL::getBuffersToAutoClear const):
+        (WebCore::GraphicsContextGLOpenGL::enablePreserveDrawingBuffer):
+        * platform/graphics/opengl/GraphicsContextGLOpenGL.h:
+        * platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp:
+        (WebCore::GraphicsContextGLOpenGL::markLayerComposited):
+        (WebCore::GraphicsContextGLOpenGL::drawBuffers):
+
 2020-07-22  Wenson Hsieh  <[email protected]>
 
         Article headlines are split across multiple lines after translating tagesschau.de

Modified: trunk/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp (264732 => 264733)


--- trunk/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp	2020-07-22 23:38:57 UTC (rev 264733)
@@ -161,7 +161,7 @@
         auto& context = downcast<WebGLRenderingContextBase>(*canvas.renderingContext());
         if (!context.isPreservingDrawingBuffer()) {
             canvas.scriptExecutionContext()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, "Turning drawing buffer preservation for the WebGL canvas being captured"_s);
-            context.setPreserveDrawingBuffer(true);
+            context.enablePreserveDrawingBuffer();
         }
     }
 #endif

Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp (264732 => 264733)


--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp	2020-07-22 23:38:57 UTC (rev 264733)
@@ -1759,7 +1759,7 @@
         }
         // Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0.
         GCGLenum value = (bufs[0] == GraphicsContextGL::BACK) ? GraphicsContextGL::COLOR_ATTACHMENT0 : GraphicsContextGL::NONE;
-        graphicsContextGL()->getExtensions().drawBuffersEXT(1, &value);
+        m_context->drawBuffers(1, &value);
         setBackDrawBuffer(bufs[0]);
     } else {
         if (n > getMaxDrawBuffers()) {
@@ -1776,92 +1776,48 @@
     }
 }
 
-void WebGL2RenderingContext::clearBufferiv(GCGLenum buffer, GCGLint drawbuffer, Int32List&&, GCGLuint)
+void WebGL2RenderingContext::clearBufferiv(GCGLenum buffer, GCGLint drawbuffer, Int32List&& values, GCGLuint srcOffset)
 {
-    switch (buffer) {
-    case GraphicsContextGL::COLOR:
-        if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
-            synthesizeGLError(GraphicsContextGL::INVALID_VALUE, "clearBufferiv", "buffer index out of range");
-            return;
-        }
-        // TODO: Call clearBufferiv, requires gl3.h and ES3/gl.h
-        break;
-    case GraphicsContextGL::STENCIL:
-        if (drawbuffer) {
-            synthesizeGLError(GraphicsContextGL::INVALID_VALUE, "clearBufferiv", "buffer index must be 0");
-            return;
-        }
-        // TODO: Call clearBufferiv, requires gl3.h and ES3/gl.h
-        break;
-    case GraphicsContextGL::DEPTH:
-    case GraphicsContextGL::DEPTH_STENCIL:
-    default:
-        synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, "clearBufferiv", "buffer argument must be COLOR or STENCIL");
-        break;
-    }
+    if (isContextLostOrPending() || !validateClearBuffer("clearBufferiv", buffer, values.length(), srcOffset))
+        return;
+
+    m_context->clearBufferiv(buffer, drawbuffer, values.data(), srcOffset);
+    updateBuffersToAutoClear(ClearBufferCaller::ClearBufferiv, buffer, drawbuffer);
 }
 
-void WebGL2RenderingContext::clearBufferuiv(GCGLenum buffer, GCGLint drawbuffer, Uint32List&&, GCGLuint)
+void WebGL2RenderingContext::clearBufferuiv(GCGLenum buffer, GCGLint drawbuffer, Uint32List&& values, GCGLuint srcOffset)
 {
-    switch (buffer) {
-    case GraphicsContextGL::COLOR:
-        if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
-            synthesizeGLError(GraphicsContextGL::INVALID_VALUE, "clearBufferuiv", "buffer index out of range");
-            return;
-        }
-        // TODO: Call clearBufferuiv, requires gl3.h and ES3/gl.h
-        break;
-    case GraphicsContextGL::DEPTH:
-    case GraphicsContextGL::STENCIL:
-    case GraphicsContextGL::DEPTH_STENCIL:
-    default:
-        synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, "clearBufferuiv", "buffer argument must be COLOR");
-        break;
-    }
+    if (isContextLostOrPending() || !validateClearBuffer("clearBufferuiv", buffer, values.length(), srcOffset))
+        return;
+
+    m_context->clearBufferuiv(buffer, drawbuffer, values.data(), srcOffset);
+    updateBuffersToAutoClear(ClearBufferCaller::ClearBufferuiv, buffer, drawbuffer);
 }
 
-void WebGL2RenderingContext::clearBufferfv(GCGLenum buffer, GCGLint drawbuffer, Float32List&&, GCGLuint)
+void WebGL2RenderingContext::clearBufferfv(GCGLenum buffer, GCGLint drawbuffer, Float32List&& values, GCGLuint srcOffset)
 {
-    switch (buffer) {
-    case GraphicsContextGL::COLOR:
-        if (drawbuffer < 0 || drawbuffer >= getMaxDrawBuffers()) {
-            synthesizeGLError(GraphicsContextGL::INVALID_VALUE, "clearBufferfv", "buffer index out of range");
-            return;
-        }
-        // TODO: Call clearBufferfv, requires gl3.h and ES3/gl.h
-        break;
-    case GraphicsContextGL::DEPTH:
-        if (drawbuffer) {
-            synthesizeGLError(GraphicsContextGL::INVALID_VALUE, "clearBufferfv", "buffer index must be 0");
-            return;
-        }
-        // TODO: Call clearBufferfv, requires gl3.h and ES3/gl.h
-        break;
-    case GraphicsContextGL::STENCIL:
-    case GraphicsContextGL::DEPTH_STENCIL:
-    default:
-        synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, "clearBufferfv", "buffer argument must be COLOR OR DEPTH");
-        break;
-    }
+    if (isContextLostOrPending() || !validateClearBuffer("clearBufferfv", buffer, values.length(), srcOffset))
+        return;
+
+    m_context->clearBufferfv(buffer, drawbuffer, values.data(), srcOffset);
+    // clearBufferiv and clearBufferuiv will currently generate an error
+    // if they're called against the default back buffer. If support for
+    // extended canvas color spaces is added, this call might need to be
+    // added to the other versions.
+    markContextChanged();
+    updateBuffersToAutoClear(ClearBufferCaller::ClearBufferfv, buffer, drawbuffer);
 }
 
-void WebGL2RenderingContext::clearBufferfi(GCGLenum buffer, GCGLint drawbuffer, GCGLfloat, GCGLint)
+void WebGL2RenderingContext::clearBufferfi(GCGLenum buffer, GCGLint drawbuffer, GCGLfloat depth, GCGLint stencil)
 {
-    switch (buffer) {
-    case GraphicsContextGL::DEPTH_STENCIL:
-        if (drawbuffer) {
-            synthesizeGLError(GraphicsContextGL::INVALID_VALUE, "clearBufferfv", "buffer index must be 0");
-            return;
-        }
-        // TODO: Call clearBufferfi, requires gl3.h and ES3/gl.h
-        break;
-    case GraphicsContextGL::COLOR:
-    case GraphicsContextGL::DEPTH:
-    case GraphicsContextGL::STENCIL:
-    default:
-        synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, "clearBufferfv", "buffer argument must be DEPTH_STENCIL");
-        break;
-    }
+    if (isContextLostOrPending())
+        return;
+
+    m_context->clearBufferfi(buffer, drawbuffer, depth, stencil);
+    // This might have been used to clear the depth and stencil buffers
+    // of the default back buffer.
+    markContextChanged();
+    updateBuffersToAutoClear(ClearBufferCaller::ClearBufferfi, buffer, drawbuffer);
 }
 
 RefPtr<WebGLQuery> WebGL2RenderingContext::createQuery()
@@ -3307,6 +3263,35 @@
     }
 }
 
+bool WebGL2RenderingContext::validateClearBuffer(const char* functionName, GCGLenum buffer, size_t size, GCGLuint srcOffset)
+{
+    Checked<GLsizei, RecordOverflow> checkedSize(size);
+    checkedSize -= srcOffset;
+    if (checkedSize.hasOverflowed()) {
+        synthesizeGLError(GraphicsContextGL::INVALID_VALUE, functionName, "invalid array size / srcOffset");
+        return false;
+    }
+    switch (buffer) {
+    case GraphicsContextGL::COLOR:
+        if (checkedSize.unsafeGet() < 4) {
+            synthesizeGLError(GraphicsContextGL::INVALID_VALUE, functionName, "invalid array size / srcOffset");
+            return false;
+        }
+        break;
+    case GraphicsContextGL::DEPTH:
+    case GraphicsContextGL::STENCIL:
+        if (checkedSize.unsafeGet() < 1) {
+            synthesizeGLError(GraphicsContextGL::INVALID_VALUE, functionName, "invalid array size / srcOffset");
+            return false;
+        }
+        break;
+    default:
+        synthesizeGLError(GraphicsContextGL::INVALID_ENUM, functionName, "invalid buffer");
+        return false;
+    }
+    return true;
+}
+
 void WebGL2RenderingContext::uniform1fv(WebGLUniformLocation* location, Float32List data, GLuint srcOffset, GLuint srcLength)
 {
     if (isContextLostOrPending() || !validateUniformParameters("uniform1fv", location, data, 1, srcOffset, srcLength))
@@ -3464,6 +3449,74 @@
 
 #undef REMOVE_BUFFER_FROM_BINDING
 
+void WebGL2RenderingContext::updateBuffersToAutoClear(ClearBufferCaller caller, GCGLenum buffer, GCGLint drawbuffer)
+{
+    // This method makes sure that we don't auto-clear any buffers which the
+    // user has manually cleared using the new ES 3.0 clearBuffer* APIs.
+
+    // If the user has a framebuffer bound, don't update the auto-clear
+    // state of the built-in back buffer.
+    if (m_framebufferBinding)
+        return;
+
+    // If the scissor test is on, assume that we can't short-circuit
+    // these clears.
+    if (m_scissorEnabled)
+        return;
+
+    // The default back buffer only has one color attachment.
+    if (drawbuffer)
+        return;
+
+    // If the call to the driver generated an error, don't claim that
+    // we've auto-cleared these buffers. The early returns below are for
+    // cases where errors will be produced.
+
+    // The default back buffer is currently always RGB(A)8, which
+    // restricts the variants which can legally be used to clear the
+    // color buffer. TODO(crbug.com/829632): this needs to be
+    // generalized.
+    switch (caller) {
+    case ClearBufferCaller::ClearBufferiv:
+        if (buffer != GraphicsContextGL::STENCIL)
+            return;
+        break;
+    case ClearBufferCaller::ClearBufferfv:
+        if (buffer != GraphicsContextGL::COLOR && buffer != GraphicsContextGL::DEPTH)
+            return;
+        break;
+    case ClearBufferCaller::ClearBufferuiv:
+        return;
+    case ClearBufferCaller::ClearBufferfi:
+        if (buffer != GraphicsContextGL::DEPTH_STENCIL)
+            return;
+        break;
+    }
+
+    GCGLbitfield buffersToClear = 0;
+
+    // Turn it into a bitfield and mask it off.
+    switch (buffer) {
+    case GraphicsContextGL::COLOR:
+        buffersToClear = GraphicsContextGL::COLOR_BUFFER_BIT;
+        break;
+    case GraphicsContextGL::DEPTH:
+        buffersToClear = GraphicsContextGL::DEPTH_BUFFER_BIT;
+        break;
+    case GraphicsContextGL::STENCIL:
+        buffersToClear = GraphicsContextGL::STENCIL_BUFFER_BIT;
+        break;
+    case GraphicsContextGL::DEPTH_STENCIL:
+        buffersToClear = GraphicsContextGL::DEPTH_BUFFER_BIT | GraphicsContextGL::STENCIL_BUFFER_BIT;
+        break;
+    default:
+        // Illegal value.
+        return;
+    }
+
+    m_context->setBuffersToAutoClear(m_context->getBuffersToAutoClear() & (~buffersToClear));
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEBGL)

Modified: trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h (264732 => 264733)


--- trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h	2020-07-22 23:38:57 UTC (rev 264733)
@@ -291,6 +291,7 @@
     bool validateIndexArrayConservative(GCGLenum type, unsigned& numElementsRequired) final;
     bool validateBlendEquation(const char* functionName, GCGLenum mode) final;
     bool validateCapability(const char* functionName, GCGLenum cap) final;
+    bool validateClearBuffer(const char* functionName, GCGLenum buffer, size_t, GCGLuint srcOffset);
     bool validateFramebufferTarget(GCGLenum target) final;
     WebGLFramebuffer* getFramebufferBinding(GCGLenum target) final;
     WebGLFramebuffer* getReadFramebufferBinding() final;
@@ -317,6 +318,14 @@
 
     void uncacheDeletedBuffer(WebGLBuffer*) final;
 
+    enum class ClearBufferCaller : uint8_t {
+        ClearBufferiv,
+        ClearBufferuiv,
+        ClearBufferfv,
+        ClearBufferfi
+    };
+    void updateBuffersToAutoClear(ClearBufferCaller, GCGLenum buffer, GCGLint drawbuffer);
+
     RefPtr<WebGLFramebuffer> m_readFramebufferBinding;
     RefPtr<WebGLTransformFeedback> m_boundTransformFeedback;
     RefPtr<WebGLTransformFeedback> m_defaultTransformFeedback;

Modified: trunk/Source/WebCore/html/canvas/WebGLFramebuffer.cpp (264732 => 264733)


--- trunk/Source/WebCore/html/canvas/WebGLFramebuffer.cpp	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/Source/WebCore/html/canvas/WebGLFramebuffer.cpp	2020-07-22 23:38:57 UTC (rev 264733)
@@ -621,32 +621,32 @@
 
 void WebGLFramebuffer::drawBuffersIfNecessary(bool force)
 {
-#if ENABLE(WEBGL2)
-    // FIXME: The logic here seems wrong. If we don't have WebGL 2 enabled at all, then
-    // we skip the m_webglDrawBuffers check. But if we do have WebGL 2 enabled, then we
-    // perform this check, for WebGL 1 contexts only.
-    if (!context()->m_webglDrawBuffers && !context()->isWebGL2())
-        return;
-#endif
-    bool reset = force;
-    // This filtering works around graphics driver bugs on Mac OS X.
-    for (size_t i = 0; i < m_drawBuffers.size(); ++i) {
-        if (m_drawBuffers[i] != GraphicsContextGL::NONE && getAttachment(m_drawBuffers[i])) {
-            if (m_filteredDrawBuffers[i] != m_drawBuffers[i]) {
-                m_filteredDrawBuffers[i] = m_drawBuffers[i];
-                reset = true;
+    if (context()->isWebGL2() || context()->m_webglDrawBuffers) {
+        bool reset = force;
+        // This filtering works around graphics driver bugs on macOS.
+        for (size_t i = 0; i < m_drawBuffers.size(); ++i) {
+            if (m_drawBuffers[i] != GraphicsContextGL::NONE && getAttachment(m_drawBuffers[i])) {
+                if (m_filteredDrawBuffers[i] != m_drawBuffers[i]) {
+                    m_filteredDrawBuffers[i] = m_drawBuffers[i];
+                    reset = true;
+                }
+            } else {
+                if (m_filteredDrawBuffers[i] != GraphicsContextGL::NONE) {
+                    m_filteredDrawBuffers[i] = GraphicsContextGL::NONE;
+                    reset = true;
+                }
             }
-        } else {
-            if (m_filteredDrawBuffers[i] != GraphicsContextGL::NONE) {
-                m_filteredDrawBuffers[i] = GraphicsContextGL::NONE;
-                reset = true;
+        }
+        if (reset) {
+            if (context()->isWebGL2()) {
+                context()->graphicsContextGL()->drawBuffers(
+                    m_filteredDrawBuffers.size(), m_filteredDrawBuffers.data());
+            } else {
+                context()->graphicsContextGL()->getExtensions().drawBuffersEXT(
+                    m_filteredDrawBuffers.size(), m_filteredDrawBuffers.data());
             }
         }
     }
-    if (reset) {
-        context()->graphicsContextGL()->getExtensions().drawBuffersEXT(
-            m_filteredDrawBuffers.size(), m_filteredDrawBuffers.data());
-    }
 }
 
 GCGLenum WebGLFramebuffer::getDrawBuffer(GCGLenum drawBuffer)

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (264732 => 264733)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2020-07-22 23:38:57 UTC (rev 264733)
@@ -1100,14 +1100,18 @@
     if (isContextLostOrPending())
         return false;
 
-    if (!m_context->layerComposited() || m_layerCleared
-        || m_attributes.preserveDrawingBuffer || (mask && m_framebufferBinding)
-        || m_preventBufferClearForInspector)
+    if (!m_context->layerComposited() || m_layerCleared || m_preventBufferClearForInspector)
         return false;
 
-    auto contextAttributes = getContextAttributes();
-    ASSERT(contextAttributes);
+    GCGLbitfield buffersNeedingClearing = m_context->getBuffersToAutoClear();
 
+    if (!buffersNeedingClearing || (mask && m_framebufferBinding))
+        return false;
+
+    // Use the underlying GraphicsContext3D's attributes to take into
+    // account (for example) packed depth/stencil buffers.
+    auto contextAttributes = m_context->contextAttributes();
+
     // Determine if it's possible to combine the clear the user asked for and this clear.
     bool combinedClear = mask && !m_scissorEnabled;
 
@@ -1121,13 +1125,13 @@
         m_context->clearColor(0, 0, 0, 0);
     m_context->colorMask(true, true, true, true);
     GCGLbitfield clearMask = GraphicsContextGL::COLOR_BUFFER_BIT;
-    if (contextAttributes->depth) {
+    if (contextAttributes.depth) {
         if (!combinedClear || !m_depthMask || !(mask & GraphicsContextGL::DEPTH_BUFFER_BIT))
             m_context->clearDepth(1.0f);
         clearMask |= GraphicsContextGL::DEPTH_BUFFER_BIT;
         m_context->depthMask(true);
     }
-    if (contextAttributes->stencil) {
+    if (contextAttributes.stencil) {
         if (combinedClear && (mask & GraphicsContextGL::STENCIL_BUFFER_BIT))
             m_context->clearStencil(m_clearStencil & m_stencilMask);
         else
@@ -1135,11 +1139,15 @@
         clearMask |= GraphicsContextGL::STENCIL_BUFFER_BIT;
         m_context->stencilMaskSeparate(GraphicsContextGL::FRONT, 0xFFFFFFFF);
     }
-    
+
     GCGLenum bindingPoint = isWebGL2() ? GraphicsContextGL::DRAW_FRAMEBUFFER : GraphicsContextGL::FRAMEBUFFER;
     if (m_framebufferBinding)
         m_context->bindFramebuffer(bindingPoint, 0);
-    m_context->clear(clearMask);
+    // 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();
     if (m_framebufferBinding)
@@ -3688,6 +3696,14 @@
     return false;
 }
 
+void WebGLRenderingContextBase::enablePreserveDrawingBuffer()
+{
+    ASSERT(!m_attributes.preserveDrawingBuffer);
+    m_attributes.preserveDrawingBuffer = true;
+    // Must send this notification down to the GraphicsContextGL as well.
+    m_context->enablePreserveDrawingBuffer();
+}
+
 GCGLboolean WebGLRenderingContextBase::isBuffer(WebGLBuffer* buffer)
 {
     if (!buffer || isContextLostOrPending())

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (264732 => 264733)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2020-07-22 23:38:57 UTC (rev 264733)
@@ -215,7 +215,10 @@
     bool extensionIsEnabled(const String&);
 
     bool isPreservingDrawingBuffer() const { return m_attributes.preserveDrawingBuffer; }
-    void setPreserveDrawingBuffer(bool value) { m_attributes.preserveDrawingBuffer = value; }
+    // Concession to canvas capture API, which must dynamically enable
+    // preserveDrawingBuffer. This can only be called once, when
+    // isPreservingDrawingBuffer() returns false.
+    void enablePreserveDrawingBuffer();
 
     bool preventBufferClearForInspector() const { return m_preventBufferClearForInspector; }
     void setPreventBufferClearForInspector(bool value) { m_preventBufferClearForInspector = value; }

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContextGL.cpp (264732 => 264733)


--- trunk/Source/WebCore/platform/graphics/GraphicsContextGL.cpp	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContextGL.cpp	2020-07-22 23:38:57 UTC (rev 264733)
@@ -40,6 +40,13 @@
 {
 }
 
+void GraphicsContextGL::enablePreserveDrawingBuffer()
+{
+    // Canvas capture should not call this unless necessary.
+    ASSERT(!m_attrs.preserveDrawingBuffer);
+    m_attrs.preserveDrawingBuffer = true;
+}
+
 unsigned GraphicsContextGL::getClearBitsByAttachmentType(GCGLenum attachment)
 {
     switch (attachment) {

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContextGL.h (264732 => 264733)


--- trunk/Source/WebCore/platform/graphics/GraphicsContextGL.h	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContextGL.h	2020-07-22 23:38:57 UTC (rev 264733)
@@ -1116,6 +1116,10 @@
 
     GraphicsContextGLAttributes contextAttributes() const { return m_attrs; }
     void setContextAttributes(const GraphicsContextGLAttributes& attrs) { m_attrs = attrs; }
+    // Concession to Canvas captureStream, which needs to dynamically set
+    // preserveDrawingBuffer to true in order to avoid implicit clears.
+    // Implementations generally do not support toggling this bit arbitrarily.
+    virtual void enablePreserveDrawingBuffer();
 
     // VertexArrayOject calls
     virtual PlatformGLObject createVertexArray() = 0;
@@ -1186,7 +1190,7 @@
 
     virtual void drawRangeElements(GCGLenum mode, GCGLuint start, GCGLuint end, GCGLsizei count, GCGLenum type, GCGLintptr offset) = 0;
 
-    virtual void drawBuffers(const Vector<GCGLenum>& buffers) = 0;
+    virtual void drawBuffers(GCGLsizei n, const GCGLenum* bufs) = 0;
     virtual void clearBufferiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLint* values, GCGLuint srcOffset) = 0;
     virtual void clearBufferuiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLuint* values, GCGLuint srcOffset) = 0;
     virtual void clearBufferfv(GCGLenum buffer, GCGLint drawbuffer, const GCGLfloat* values, GCGLuint srcOffset) = 0;

Modified: trunk/Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp (264732 => 264733)


--- trunk/Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp	2020-07-22 23:38:57 UTC (rev 264733)
@@ -1899,6 +1899,7 @@
 void GraphicsContextGLOpenGL::markLayerComposited()
 {
     m_layerComposited = true;
+    resetBuffersToAutoClear();
 
     for (auto* client : copyToVector(m_clients))
         client->didComposite();
@@ -2307,41 +2308,29 @@
     gl::DrawRangeElements(mode, start, end, count, type, reinterpret_cast<void*>(offset));
 }
 
-void GraphicsContextGLOpenGL::drawBuffers(const Vector<GCGLenum>& buffers)
+void GraphicsContextGLOpenGL::drawBuffers(GCGLsizei n, const GCGLenum* bufs)
 {
-    UNUSED_PARAM(buffers);
+    gl::DrawBuffers(n, bufs);
 }
 
 void GraphicsContextGLOpenGL::clearBufferiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLint* values, GCGLuint srcOffset)
 {
-    UNUSED_PARAM(buffer);
-    UNUSED_PARAM(drawbuffer);
-    UNUSED_PARAM(values);
-    UNUSED_PARAM(srcOffset);
+    gl::ClearBufferiv(buffer, drawbuffer, values + srcOffset);
 }
 
 void GraphicsContextGLOpenGL::clearBufferuiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLuint* values, GCGLuint srcOffset)
 {
-    UNUSED_PARAM(buffer);
-    UNUSED_PARAM(drawbuffer);
-    UNUSED_PARAM(values);
-    UNUSED_PARAM(srcOffset);
+    gl::ClearBufferuiv(buffer, drawbuffer, values + srcOffset);
 }
 
 void GraphicsContextGLOpenGL::clearBufferfv(GCGLenum buffer, GCGLint drawbuffer, const GCGLfloat* values, GCGLuint srcOffset)
 {
-    UNUSED_PARAM(buffer);
-    UNUSED_PARAM(drawbuffer);
-    UNUSED_PARAM(values);
-    UNUSED_PARAM(srcOffset);
+    gl::ClearBufferfv(buffer, drawbuffer, values + srcOffset);
 }
 
 void GraphicsContextGLOpenGL::clearBufferfi(GCGLenum buffer, GCGLint drawbuffer, GCGLfloat depth, GCGLint stencil)
 {
-    UNUSED_PARAM(buffer);
-    UNUSED_PARAM(drawbuffer);
-    UNUSED_PARAM(depth);
-    UNUSED_PARAM(stencil);
+    gl::ClearBufferfi(buffer, drawbuffer, depth, stencil);
 }
 
 void GraphicsContextGLOpenGL::deleteQuery(PlatformGLObject query)

Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.cpp (264732 => 264733)


--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.cpp	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.cpp	2020-07-22 23:38:57 UTC (rev 264733)
@@ -271,6 +271,42 @@
 
 } // anonymous namespace
 
+void GraphicsContextGLOpenGL::resetBuffersToAutoClear()
+{
+    GCGLuint buffers = GraphicsContextGL::COLOR_BUFFER_BIT;
+    // The GraphicsContextGL's attributes (as opposed to
+    // WebGLRenderingContext's) indicate whether there is an
+    // implicitly-allocated stencil buffer, for example.
+    auto attrs = contextAttributes();
+    if (attrs.depth)
+        buffers |= GraphicsContextGL::DEPTH_BUFFER_BIT;
+    if (attrs.stencil)
+        buffers |= GraphicsContextGL::STENCIL_BUFFER_BIT;
+    setBuffersToAutoClear(buffers);
+}
+
+void GraphicsContextGLOpenGL::setBuffersToAutoClear(GCGLbitfield buffers)
+{
+    auto attrs = contextAttributes();
+    if (!attrs.preserveDrawingBuffer)
+        m_buffersToAutoClear = buffers;
+    else
+        ASSERT(!m_buffersToAutoClear);
+}
+
+GCGLbitfield GraphicsContextGLOpenGL::getBuffersToAutoClear() const
+{
+    return m_buffersToAutoClear;
+}
+
+void GraphicsContextGLOpenGL::enablePreserveDrawingBuffer()
+{
+    GraphicsContextGL::enablePreserveDrawingBuffer();
+    // After dynamically transitioning to preserveDrawingBuffer:true
+    // for canvas capture, clear out any buffer auto-clearing state.
+    m_buffersToAutoClear = 0;
+}
+
 bool GraphicsContextGLOpenGL::texImage2DResourceSafe(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, GCGLenum format, GCGLenum type, GCGLint unpackAlignment)
 {
     ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8);

Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h (264732 => 264733)


--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h	2020-07-22 23:38:57 UTC (rev 264733)
@@ -433,7 +433,7 @@
 
     void drawRangeElements(GCGLenum mode, GCGLuint start, GCGLuint end, GCGLsizei count, GCGLenum type, GCGLintptr offset) final;
 
-    void drawBuffers(const Vector<GCGLenum>& buffers) final;
+    void drawBuffers(GCGLsizei n, const GCGLenum* bufs) final;
     void clearBufferiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLint* values, GCGLuint srcOffset) final;
     void clearBufferuiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLuint* values, GCGLuint srcOffset) final;
     void clearBufferfv(GCGLenum buffer, GCGLint drawbuffer, const GCGLfloat* values, GCGLuint srcOffset) final;
@@ -523,6 +523,14 @@
     void forceContextLost();
     void recycleContext();
 
+    // Maintenance of auto-clearing of color/depth/stencil buffers. The
+    // reset method is present to keep calling code simpler, so it
+    // doesn't have to know which buffers were allocated.
+    void resetBuffersToAutoClear();
+    void setBuffersToAutoClear(GCGLbitfield);
+    GCGLbitfield getBuffersToAutoClear() const;
+    void enablePreserveDrawingBuffer() override;
+
     void dispatchContextChangedNotification();
     void simulateContextChanged();
 
@@ -864,6 +872,11 @@
     GCGLuint m_preserveDrawingBufferFBO { 0 };
 #endif
 
+    // A bitmask of GL buffer bits (GL_COLOR_BUFFER_BIT,
+    // GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT) which need to be
+    // auto-cleared.
+    GCGLbitfield m_buffersToAutoClear { 0 };
+
     // Errors raised by synthesizeGLError().
     ListHashSet<GCGLenum> m_syntheticErrors;
 

Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp (264732 => 264733)


--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp	2020-07-22 23:36:22 UTC (rev 264732)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp	2020-07-22 23:38:57 UTC (rev 264733)
@@ -2019,6 +2019,7 @@
 void GraphicsContextGLOpenGL::markLayerComposited()
 {
     m_layerComposited = true;
+    resetBuffersToAutoClear();
 
     for (auto* client : copyToVector(m_clients))
         client->didComposite();
@@ -2424,9 +2425,10 @@
     UNUSED_PARAM(offset);
 }
 
-void GraphicsContextGLOpenGL::drawBuffers(const Vector<GCGLenum>& buffers)
+void GraphicsContextGLOpenGL::drawBuffers(GCGLsizei n, const GCGLenum* bufs)
 {
-    UNUSED_PARAM(buffers);
+    UNUSED_PARAM(n);
+    UNUSED_PARAM(bufs);
 }
 
 void GraphicsContextGLOpenGL::clearBufferiv(GCGLenum buffer, GCGLint drawbuffer, const GCGLint* values, GCGLuint srcOffset)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to