Title: [290356] trunk
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()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to