Skip to content

Commit

Permalink
Google meet video effects have a low frame rate
Browse files Browse the repository at this point in the history
rdar://121257960
https://bugs.webkit.org/show_bug.cgi?id=268455

Reviewed by Dan Glastonbury and Kimmo Kinnunen.

Document::canvasChanged is only triggering a PrepareCanvasesForDisplay update if it is not given a rect.
WebGLRenderingContextBase::markContextChangedAndNotifyCanvasObserver was passing the whole canvas rect.
We change it to passing std::nullopt instead.

* LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-canvas-webgl-expected.txt: Added.
* LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-canvas-webgl.html: Added.
* Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::markContextChangedAndNotifyCanvasObserver):

Canonical link: https://commits.webkit.org/273897@main
  • Loading branch information
youennf committed Feb 1, 2024
1 parent 3b6c9da commit 52bbfea
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@


PASS check frame of capture canvas is sufficient

Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Capture canvas to video track framerate</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../../webrtc/routines.js"></script>
</head>
<body>
<video id="video" muted autoplay playsInline controls width="200px"></video>
<script>
function drawCanvasTestPatternWebGL(canvas, patternNumber)
{
patternNumber = patternNumber || 0;
const gl = canvas.getContext("webgl", { depth: false, stencil: false, antialias: false });
gl.enable(gl.SCISSOR_TEST);
const boxSize = [ canvas.width, canvas.height ];
const boxes = [
[0.0, 0.5, 0.5, 1.0],
[0.5, 0.5, 1.0, 1.0],
[0.5, 0.0, 1.0, 0.5],
[0.0, 0.0, 0.5, 0.5],
];
const boxColors = Object.values(testColors);
for (let n = 0; n < 4; ++n) {
const i = (n + patternNumber) % boxes.length;
const color = boxColors[i];
const box = boxes[n];
gl.scissor(box[0] * boxSize[0], box[1] * boxSize[1], box[2] * boxSize[0], box[3] * boxSize[1]);
gl.clearColor(color[0] / 255., color[1] / 255, color[2] / 255., color[3] / 255.);
gl.clear(gl.COLOR_BUFFER_BIT);
}
}

promise_test(async (t) => {
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 200;

let frames = 0;
const loop = () => {
frames += 1;
drawCanvasTestPatternWebGL(canvas, frames);
setTimeout(loop, 1000/30);
}

loop();

const stream = canvas.captureStream();
video.srcObject = stream;
video.play();

const frameRate = await computeFrameRate(stream, video);

// If the test was unable to generate any frames then nothing meaningful can be determined. Our test only makes sense if we have sufficient fps.
if (frames <= 10)
return;

// Check that the difference in expected and observed frame rates is < 25%
const percentDiff = Math.abs(frameRate - frames) / frames * 100;
assert_less_than(percentDiff, 25, `frame rate difference between ${frames} & ${frameRate} is below 25%`);
}, "check frame of capture canvas is sufficient");
</script>
</body>
</html>
2 changes: 2 additions & 0 deletions LayoutTests/platform/glib/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,8 @@ http/wpt/webcodecs/encoder-task-failing.html [ Pass ]
# expected to pass again once we update to GStreamer 1.24.
fast/mediastream/play-newly-added-audio-track.html [ Pass Crash ]

fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-canvas-webgl.html [ Pass Failure ]

webkit.org/b/264665 http/wpt/webcodecs/videoFrame-webglCanvasImageSource.html [ Failure ]

webkit.org/b/264666 imported/w3c/web-platform-tests/encrypted-media/clearkey-generate-request-disallowed-input.https.html [ Failure ]
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ void WebGLRenderingContextBase::markContextChangedAndNotifyCanvasObserver(WebGLR

if (auto* canvas = htmlCanvas()) {
if (isAccelerated()) {
canvas->notifyObserversCanvasChanged(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
canvas->notifyObserversCanvasChanged({ });
RenderBox* renderBox = canvas->renderBox();
if (renderBox && renderBox->hasAcceleratedCompositing()) {
m_canvasBufferContents = std::nullopt;
Expand Down

0 comments on commit 52bbfea

Please sign in to comment.