- Revision
- 290356
- Author
- [email protected]
- Date
- 2022-02-23 00:23:37 -0800 (Wed, 23 Feb 2022)
Log Message
Crash when calling WEBGL_lose_context.loseContext() after the context has been lost
https://bugs.webkit.org/show_bug.cgi?id=236966
Patch by Kimmo Kinnunen <[email protected]> on 2022-02-23
Reviewed by Dean Jackson.
Source/WebCore:
WebGLRenderingContextBase::forceLostContext() would
try to synthesize a GL error to the underlying
m_context. However, m_context is cleared when a real
context loss happens. This happens for example when we
simulate a GPU status failure or when we create too
many contexts. The m_context is not currently cleared
when the page simulates context lost via WEBGL_lose_contexts.loseContext().
Test: webgl/lose-context-after-context-lost.html
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::synthesizeGLError):
LayoutTests:
* webgl/lose-context-after-context-lost-expected.txt: Added.
* webgl/lose-context-after-context-lost.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (290355 => 290356)
--- trunk/LayoutTests/ChangeLog 2022-02-23 08:16:29 UTC (rev 290355)
+++ trunk/LayoutTests/ChangeLog 2022-02-23 08:23:37 UTC (rev 290356)
@@ -1,3 +1,13 @@
+2022-02-23 Kimmo Kinnunen <[email protected]>
+
+ Crash when calling WEBGL_lose_context.loseContext() after the context has been lost
+ https://bugs.webkit.org/show_bug.cgi?id=236966
+
+ Reviewed by Dean Jackson.
+
+ * webgl/lose-context-after-context-lost-expected.txt: Added.
+ * webgl/lose-context-after-context-lost.html: Added.
+
2022-02-23 Youenn Fablet <[email protected]>
Enable WebRTCRemoteVideoFrameEnabled by default in WebKitTestRunner
Modified: trunk/LayoutTests/platform/glib/TestExpectations (290355 => 290356)
--- trunk/LayoutTests/platform/glib/TestExpectations 2022-02-23 08:16:29 UTC (rev 290355)
+++ trunk/LayoutTests/platform/glib/TestExpectations 2022-02-23 08:23:37 UTC (rev 290356)
@@ -1395,6 +1395,7 @@
webkit.org/b/219251 fast/canvas/webgl/getIndexedParameter-crash.html [ Failure ]
webkit.org/b/172812 fast/canvas/webgl/lose-context-on-status-failure.html [ Skip ]
+webkit.org/b/172812 webgl/lose-context-after-context-lost.html [ Failure ]
webkit.org/b/223624 webgl/conformance/extensions/khr-parallel-shader-compile.html [ Skip ]
Added: trunk/LayoutTests/webgl/lose-context-after-context-lost-expected.txt (0 => 290356)
--- trunk/LayoutTests/webgl/lose-context-after-context-lost-expected.txt (rev 0)
+++ trunk/LayoutTests/webgl/lose-context-after-context-lost-expected.txt 2022-02-23 08:23:37 UTC (rev 290356)
@@ -0,0 +1,46 @@
+Test that WEBGL_lose_context functions do not crash after context has been lost.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+TEST COMPLETE: 29 PASS, 2 FAIL
+
+Running test: loseMethod: loseContext, testedMethod: loseContext
+PASS gl.isContextLost() is true
+PASS gl.getError() is gl.CONTEXT_LOST_WEBGL
+PASS gl.getError() is gl.NO_ERROR
+PASS Got webglcontextlost.
+PASS Did not crash on tested method loseContext.
+Running test: loseMethod: loseContext, testedMethod: restoreContext
+PASS gl.isContextLost() is true
+PASS gl.getError() is gl.CONTEXT_LOST_WEBGL
+PASS gl.getError() is gl.NO_ERROR
+PASS Got webglcontextlost.
+PASS Did not crash on tested method restoreContext.
+Running test: loseMethod: manyContexts, testedMethod: loseContext
+PASS gl.isContextLost() is true
+FAIL gl.getError() should be 37442. Was 0.
+PASS gl.getError() is gl.NO_ERROR
+PASS Got webglcontextlost.
+PASS Did not crash on tested method loseContext.
+Running test: loseMethod: manyContexts, testedMethod: restoreContext
+PASS gl.isContextLost() is true
+FAIL gl.getError() should be 37442. Was 0.
+PASS gl.getError() is gl.NO_ERROR
+PASS Got webglcontextlost.
+PASS Did not crash on tested method restoreContext.
+Running test: loseMethod: gpuStatusFailure, testedMethod: loseContext
+PASS gl.isContextLost() is true
+PASS gl.getError() is gl.CONTEXT_LOST_WEBGL
+PASS gl.getError() is gl.NO_ERROR
+PASS Got webglcontextlost.
+PASS Did not crash on tested method loseContext.
+Running test: loseMethod: gpuStatusFailure, testedMethod: restoreContext
+PASS gl.isContextLost() is true
+PASS gl.getError() is gl.CONTEXT_LOST_WEBGL
+PASS gl.getError() is gl.NO_ERROR
+PASS Got webglcontextlost.
+PASS Did not crash on tested method restoreContext.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/webgl/lose-context-after-context-lost.html (0 => 290356)
--- trunk/LayoutTests/webgl/lose-context-after-context-lost.html (rev 0)
+++ trunk/LayoutTests/webgl/lose-context-after-context-lost.html 2022-02-23 08:23:37 UTC (rev 290356)
@@ -0,0 +1,94 @@
+<!DOCTYPE html><!-- webkit-test-runner [ UseGPUProcessForWebGLEnabled=false ] -->
+<!-- Should be removed when https://bugs.webkit.org/show_bug.cgi?id=236964 is fixed. -->
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="stylesheet" href=""
+<script src=""
+<script src=""
+</head>
+<body _onload_="test()">
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Test that WEBGL_lose_context functions do not crash after context has been lost.");
+
+var wtu = WebGLTestUtils;
+var gl;
+
+async function waitForWebGLContextLost(canvas)
+{
+ return new Promise((resolve, reject) => {
+ setTimeout(reject, 2000);
+ canvas.addEventListener("webglcontextlost", resolve, { once: true });
+ });
+}
+
+function testDescription(subcase) {
+ return Object.keys(subcase).map((k) => `${k}: ${typeof subcase[k] === "function" ? subcase[k].name : subcase[k]}`).join(", ");
+}
+
+async function runTest(subcase)
+{
+ debug(`Running test: ${testDescription(subcase)}`);
+ const canvas = document.createElement("canvas");
+ canvas.width = 1;
+ canvas.height = 1;
+ gl = wtu.create3DContext(canvas);
+ const WEBGL_lose_context = wtu.getExtensionWithKnownPrefixes(gl, "WEBGL_lose_context");
+ if (!WEBGL_lose_context) {
+ debug("Could not find WEBGL_lose_context extension");
+ return false;
+ }
+
+ const webglcontextlost = waitForWebGLContextLost(canvas);
+
+ if (subcase.loseMethod == "loseContext")
+ WEBGL_lose_context.loseContext();
+ else if (subcase.loseMethod == "gpuStatusFailure") {
+ internals.simulateEventForWebGLContext("GPUStatusFailure", gl);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ } else if (subcase.loseMethod == "manyContexts") {
+ // This causes the older contexts to be lost, including the first one we created
+ // for testing.
+ for (let i = 0; i < 50; ++i)
+ document.createElement("canvas").getContext("webgl");
+ }
+
+ shouldBeTrue("gl.isContextLost()");
+ shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
+ shouldBe("gl.getError()", "gl.NO_ERROR");
+ try {
+ await webglcontextlost;
+ testPassed("Got webglcontextlost.");
+ } catch (e) {
+ testFailed("Timed out waiting webglcontextlost.");
+ }
+
+ if (subcase.testedMethod == "loseContext")
+ WEBGL_lose_context.loseContext();
+ else if (subcase.testedMethod == "restoreContext")
+ WEBGL_lose_context.restoreContext();
+ testPassed(`Did not crash on tested method ${subcase.testedMethod}.`);
+}
+
+const loseMethods = ["loseContext", "manyContexts"];
+if (window.internals)
+ loseMethods.push("gpuStatusFailure");
+const testedMethods = ["loseContext", "restoreContext"];
+
+const subcases = [];
+for (const loseMethod of loseMethods)
+ for (const testedMethod of testedMethods)
+ subcases.push({loseMethod, testedMethod});
+
+async function test()
+{
+ for (let subcase of subcases)
+ await runTest(subcase);
+ finishTest();
+}
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (290355 => 290356)
--- trunk/Source/WebCore/ChangeLog 2022-02-23 08:16:29 UTC (rev 290355)
+++ trunk/Source/WebCore/ChangeLog 2022-02-23 08:23:37 UTC (rev 290356)
@@ -1,3 +1,23 @@
+2022-02-23 Kimmo Kinnunen <[email protected]>
+
+ Crash when calling WEBGL_lose_context.loseContext() after the context has been lost
+ https://bugs.webkit.org/show_bug.cgi?id=236966
+
+ Reviewed by Dean Jackson.
+
+ WebGLRenderingContextBase::forceLostContext() would
+ try to synthesize a GL error to the underlying
+ m_context. However, m_context is cleared when a real
+ context loss happens. This happens for example when we
+ simulate a GPU status failure or when we create too
+ many contexts. The m_context is not currently cleared
+ when the page simulates context lost via WEBGL_lose_contexts.loseContext().
+
+ Test: webgl/lose-context-after-context-lost.html
+
+ * html/canvas/WebGLRenderingContextBase.cpp:
+ (WebCore::WebGLRenderingContextBase::synthesizeGLError):
+
2022-02-23 Youenn Fablet <[email protected]>
Optimize RemoteVideoFrame handling in WebProcess WebRTC pipeline
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (290355 => 290356)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2022-02-23 08:16:29 UTC (rev 290355)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2022-02-23 08:23:37 UTC (rev 290356)
@@ -7852,7 +7852,8 @@
String str = "WebGL: " + GetErrorString(error) + ": " + String(functionName) + ": " + String(description);
printToConsole(MessageLevel::Error, str);
}
- m_context->synthesizeGLError(error);
+ if (m_context)
+ m_context->synthesizeGLError(error);
}
void WebGLRenderingContextBase::applyStencilTest()