Skip to content
Permalink
Browse files
composited canvas element should update the layer configuration after…
… creating a WebGL context

https://bugs.webkit.org/show_bug.cgi?id=243629

Reviewed by Simon Fraser.

Because WebGL is GPU accelerated, creating a WebGL context makes the
canvas element have a compositing layer. However, if a canvas element
had a compositing layer before creating a WebGL context, it didn't
update the content layer.

When canvas.getContext('webgl') creates a WebGL context,
HTMLCanvasElement::createContextWebGL calls
invalidateStyleAndLayerComposition to create a new compositing layer
for the canvas element and set the WebGL layer as the content layer of
the layer. However, if the canvas element already had a compositing
layer, the content layer wasn't set as expected.

* LayoutTests/compositing/webgl/update-composited-canvas-layer-expected.html: Added.
* LayoutTests/compositing/webgl/update-composited-canvas-layer.html: Added.
* Source/WebCore/html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::createContextWebGL):
Call RenderBoxModelObject::contentChanged to ensure the content layer
updated if it already has a renderer.

Canonical link: https://commits.webkit.org/253231@main
  • Loading branch information
fujii committed Aug 8, 2022
1 parent 809ad82 commit a91690f4cb06906a50bc9606bbe089d7ac6e8a93
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<style>
canvas {
width: 100px;
height: 100px;
background: red;
}
</style>
<script>
if (window.testRunner)
testRunner.waitUntilDone();

onload = async () => {
await new Promise(resolve => requestAnimationFrame(resolve));
await new Promise(resolve => requestAnimationFrame(resolve));

let canvas = document.getElementById('canvas');
let gl = canvas.getContext('webgl');
gl.clearColor(0, 0.5, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);

if (window.testRunner)
testRunner.notifyDone();
}
</script>
</head>
<body>
<p>You should see a green box.</p>
<canvas id="canvas"></canvas>
</body>
</html>
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<style>
canvas {
width: 100px;
height: 100px;
background: red;
will-change: transform;
}
</style>
<script>
if (window.testRunner)
testRunner.waitUntilDone();

onload = async () => {
await new Promise(resolve => requestAnimationFrame(resolve));
await new Promise(resolve => requestAnimationFrame(resolve));

let canvas = document.getElementById('canvas');
let gl = canvas.getContext('webgl');
gl.clearColor(0, 0.5, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);

if (window.testRunner)
testRunner.notifyDone();
}
</script>
</head>
<body>
<p>You should see a green box.</p>
<canvas id="canvas"></canvas>
</body>
</html>
@@ -482,6 +482,8 @@ WebGLRenderingContextBase* HTMLCanvasElement::createContextWebGL(WebGLVersion ty

// Need to make sure a RenderLayer and compositing layer get created for the Canvas.
invalidateStyleAndLayerComposition();
if (renderBox())
renderBox()->contentChanged(CanvasChanged);
#if ENABLE(WEBXR)
ASSERT(!attrs.xrCompatible || downcast<WebGLRenderingContextBase>(m_context.get())->isXRCompatible());
#endif

0 comments on commit a91690f

Please sign in to comment.