Closed Bug 1344524 Opened 8 years ago Closed 3 years ago

canvas.captureStream: doesn't capture frames in a background tab

Categories

(Core :: WebRTC: Audio/Video, defect, P2)

51 Branch
defect

Tracking

()

RESOLVED FIXED
98 Branch
Tracking Status
firefox98 --- fixed

People

(Reporter: tristan.fraipont, Assigned: pehrsons)

References

(Regressed 1 open bug, )

Details

Attachments

(7 files)

MediaRecorder drops frames when the main window looses focus (e.g when we switch to an other tab). This looks like it has the same limitations as requestAnimationFrame about this. In the attached example, the canvas animation is ticked to an audioContext based timer (which is not limited by this focus issue). When we loose focus, the Recorder drops the frames, even when stream.requestFrame is manually called. However, if we call canvas.toBlob(), we can see that all the frames are presented and rendered on the canvas, but somehow they're not passed to the recorder. Note : - Since chrome has fixed this bug (https://bugs.chromium.org/p/chromium/issues/detail?id=653548) it does work for them. - I am pretty sure it did work on beta channel around november of 2016, however I was unable to find a working release with moz-regression... A minimal version can be found here : https://jsfiddle.net/qnzz47pw/
Attached video Output video
Note, only the fiddle in comment 0 reproduces for me (OSX). The attachment is always silky smooth, no framedrops! Furthermore, the fiddle problem seems e10s related. If I open a new non-e10s window then it works fine. I tried as far back as 2016-07-12 (which is as far as mozregression successfully run builds for me for some reason), which puts it at 51, and with e10s it's broken, and with non-e10s it works. This might explain why you saw it working in a beta, but couldn't find a regression range. The Chrome bug you reference seems different, not producing any frames at all.
Has STR: --- → yes
Rank: 15
Flags: needinfo?(tristan.fraipont)
Keywords: regression
Priority: -- → P1
Summary: (canvas.captureStream) Dropped frames in recording when the window is blurred → [e10s](canvas.captureStream) Dropped frames in recording when the window is blurred
Version: 54 Branch → 51 Branch
Flags: needinfo?(tristan.fraipont)
Status: UNCONFIRMED → NEW
Ever confirmed: true
Yes e10s seems to be the trouble-maker. I disabled it and the number of dropped frames considerably lowered. (I still have some though) Also if I pointed to the not directly related chrome bug, it's because in their current stable version, this bug makes it impossible to test, while in canary, with shipped fix, we can see it works smoothly.
This is a P1 bug without an assignee. P1 are bugs which are being worked on for the current release cycle/iteration/sprint. If the bug is not assigned by Monday, 28 August, the bug's priority will be reset to '--'.
Keywords: stale-bug
Mass change P1->P2 to align with new Mozilla triage process
Priority: P1 → P2
Moving to p3 because no activity for at least 1 year(s). See https://github.com/mozilla/bug-handling/blob/master/policy/triage-bugzilla.md#how-do-you-triage for more information
Priority: P2 → P3

This doesn't seem to be exclusive to the MediaRecorder btw, it also effects active (canvas based) MediaStreams.

A bit more information:

I can reproduce the behaviour on both Windows and macOS with Firefox 66.0.5.
I've also re-tried the requestFrame invocation Kaiido mentioned.

  • captureStream without requestFrame
  • requestFrame with captureStream(0)
  • both

Here is a recording

https://youtu.be/OKlv9MMKZFk

showing FF (left) and Chrome (74 on the right) and the behaviour
of a MediaStream acquired via captureStream vs getUserMedia in the two browsers
when the tab becomes inactive (covered by a different window).

Note:

Might be worth noting that the fiddle still works, but you need to run it pressing the "run" button
because the AudioContext requires a user gesture to start in Chrome.

Any updates on this? I feel like this should be a higher priority than it is.

For many apps (recording, live streaming, etc), dropping frames like this when the window is blurred is a nasty user experience. Unfortunately, for many of these types of apps, Firefox isn't usable because of this bug.

Would love to see it fixed soon!

Just ran into this ourselves. This is prevent our app from supporting Firefox. Anything that can be done to help move this along???

We are also running into this issue, and it is very problematic for our app's experience when using FF vs Chrome.

A totally experimental/naive patch that resolves the issue when capturing from a Canvas, if it is helpful at all.

Also ran into this. Doesn't anyone of the team want to incorporate the diff? We need to recommend Chrome to our customers cause of this.

this issue is really an issue for our web application as well. please apply the provided fix!

Flags: needinfo?(padenot)

Lee, what would it take for <canvas> to continue drawing when not in foreground when it's being recorded via captureStream ? This is a clear webcompat problem and we need to fix it. What do you think of the patch attached here?

Flags: needinfo?(padenot) → needinfo?(lsalzman)

Andreas Pehrson wrote the code that the patch in question modifies, so he would be the better person to answer that question.

Flags: needinfo?(lsalzman) → needinfo?(apehrson)

I don't think the patch would work as it seems to be creating a new refresh driver and hooking it up to be driven by a timer.

We are deliberate about the refresh driver we use. It has to be in sync with webgl rendering, or else the front buffer may be empty when a capture happens.

We should be able to avoid the throttling while a canvas has a pending capture. But I'm not sure where that is managed, or who would be the right person to ask. Lee, would you know this?

Flags: needinfo?(apehrson) → needinfo?(lsalzman)

I think this boils down to animation frame callbacks not being called when hidden. If there are no animation frame callbacks, and no useful timers (because they're throttled), how would one be able to draw to the canvas, even if it is able to capture frames while in the background?

This to me seems to require spec work, even if comment 17 was fixed. How does it work in Chrome?

Right, you run the drawing with a ScriptProcessorNode instead of requestAnimationFrame.

That will work ok until ScriptProcessorNode is removed (we have AudioWorklet as a way better alternative now) but then we're stuck in comment 18 anyway.

The activeness of a tab is generally managed by the front-end code, fwiw. See BrowsingContext::IsActive and related code.

Mike, how do we solve this for Picture In Picture? Do we do something fancy with tab activeness in the front-end for it?

Alternatively, we could keep track of whether there's any ongoing capture and tweak this code to consider the PresShell active anyways.

Flags: needinfo?(mconley)

(In reply to Emilio Cobos Álvarez (:emilio) from comment #21)

Mike, how do we solve this for Picture In Picture? Do we do something fancy with tab activeness in the front-end for it?

Alternatively, we could keep track of whether there's any ongoing capture and tweak this code to consider the PresShell active anyways.

PiP actually suffers from the same issue. Some videos will pause or degrade in quality when in a background tab. We track this in bug 1598654, where I tried a hacky PiP-centric solution, but it didn't stick.

Flags: needinfo?(mconley)

(In reply to Andreas Pehrson [:pehrsons] from comment #17)

I don't think the patch would work as it seems to be creating a new refresh driver and hooking it up to be driven by a timer.

We are deliberate about the refresh driver we use. It has to be in sync with webgl rendering, or else the front buffer may be empty when a capture happens.

We should be able to avoid the throttling while a canvas has a pending capture. But I'm not sure where that is managed, or who would be the right person to ask. Lee, would you know this?

Maybe Matt or Nical might have some input.

Flags: needinfo?(lsalzman)

(In reply to Andreas Pehrson [:pehrsons] from comment #19)

Right, you run the drawing with a ScriptProcessorNode instead of requestAnimationFrame.

That will work ok until ScriptProcessorNode is removed (we have AudioWorklet as a way better alternative now) but then we're stuck in comment 18 anyway.

No I run the drawing with an AudioScheduledSourceNode which is not scheduled to be deprecated anytime soon no, and there are many other ways to not get throttled in a background tab.

(from comment #18)

I think this boils down to animation frame callbacks not being called when hidden. If there are no animation frame callbacks, and no useful timers (because they're throttled), how would one be able to draw to the canvas, even if it is able to capture frames while in the background?

This to me seems to require spec work, even if comment 17 was fixed. How does it work in Chrome?

Once again we fall here.
Why should this be tied to rAF callbacks?
I don't have any telemetry info at hand, but from what I saw in the wild most uses of a canvas stream + MediaRecorder are to apply some filters or recognition results over an other source (e.g a video or a webcam stream).
In this more than common case, and in many others, one doesn't want to record at the screen refresh rate (120Hz on new mobile phones, anything between 50 to 240Hz on desktops), they generally want a more conventional frame-rate between 25FPS and 30FPS, maybe even 60FPS, because that's the source's rate anyway, or to avoid recording 4 times more frames than most readers are able to cope with or just to avoid having 4 times bigger files than necessary.
And for this task rAF is the worst* timer you can find (*right after requestIdleCallback):
There is no way to tell at which frequency it will fire, every user will produce different results only because the refresh-rate of their monitor is different. This refresh-rate can even change during the recording if the user moves the browser's tab to a second monitor. And as demonstrated here, it gets throttled when the document is blurred.

Don't get me wrong, rAF is great at what it does: offer a mean to hook to the presentation time so that animations that makes it to the monitor are in sync with the monitor.
But here we just don't have to take the monitor into consideration at all.

So yes, we fall back in this poor design decision of tying this API to the undefined "paint" time of the canvas, which you read as being the next "painting frame", while as also demonstrated here, at least the 2D API has means to force these paints synchronously: ctx.getImageData, ctx.drawImage(canvas,x,y), canvas.toDataURL(), and even if not really required, in the facts even canvas.toBlob() does this.

So why not simply make CanvasCaptureMediaStreamTrack.requestFrame() do the same?

I'd absolutely agree with @Kaiido's points here. Additionally, something to consider is a frame event or callback request on a video or canvas element. That way, we could "genlock" paints to the target canvas to frames from a source video. But, I'd happily settle for a frame callback on the captured media stream if that's all we can get.

requestAnimationFrame() was a hack in this context... we were only using it because it's all we had, aside from the even hackier callbacks with the Web Audio API ScriptProcessorNode. If we had some frame clock that would allow us to paint to the canvas at a predictable framerate, that would be a better resolution to this problem.

Please do however keep in mind that other throttling, such as for setTimeout()/setInterval() and perhaps requestAnimationFrame() still likely needs to be disabled to avoid side effects. The scripts painting to the canvas may require other code to run that uses these timers.

(In reply to Andreas Pehrson [:pehrsons] from comment #19)

Right, you run the drawing with a ScriptProcessorNode instead of requestAnimationFrame.

To nuance this: A running AudioContext will disable timer throttling, so if timers are used for scheduling one doesn't need a ScriptProcessorNode.


Canvas.captureStream was not designed as a tool to transform every frame in a video track, so of course some pain points will arise when used as such.

I do have sympathy for the use case, since it's the only tool available for transforming video right now. A better tool would be what insertable streams claims to do for raw media, though that hasn't properly materialized yet.

To be pragmatic, I think we could possibly do something like comment 18 suggests to keep this working while in the background.

If you argue for changing behavior of requestFrame() you should do so on the spec.

Same or a very similar problem appears in a WebRTC stream transformation use case and there seems to be no workaround.
Even if you use an alternative timer source, such as a timer worker or an audio oscillator, the canvas stream appears throttled to 1 fps when the tab is in the background leading to an obviously unpleasant call experience if one of the peers decides to multitask.

We are also forced to nudge users to Google Chrome because of that.

Keywords: stale-bug
Blocks: gfx-triage
Summary: [e10s](canvas.captureStream) Dropped frames in recording when the window is blurred → Dropped frames in recording with canvas use

Jib, any chance you could give us some clarity on what the standards involved here mandate we do?

Flags: needinfo?(jib)

This is a complicated. At its core, canvas.captureStream() creates a sink for a canvas other than the (visible) page, which breaks the assumption that canvas paints can be throttled in background tabs without visible consequences.

I see at least 3 questions:

  1. When is a canvas painted? From bug 1613602 comment 1: the spec says:

    • "A new frame is requested from the canvas when [[frameCaptureRequested]] is true and the canvas is painted.", but when a canvas is painted is not properly defined (#29). A bit of digging suggests "canvas paint cycle" / "paint mechanisms" is distinct from "user agent rendering algorithm" / "rasterization". cc @annevk can you help clarify?
  2. Should requestFrame() trigger "paint" or something like it? Kaiido makes a case in comment 24 (which should be raised in issue #28):

    So yes, we fall back in this poor design decision of tying this API to the undefined "paint" time of the canvas, which you read as being the next "painting frame", while as also demonstrated here, at least the 2D API has means to force these paints synchronously: ctx.getImageData, ctx.drawImage(canvas,x,y), canvas.toDataURL(), and even if not really required, in the facts even canvas.toBlob() does this.

    So why not simply make CanvasCaptureMediaStreamTrack.requestFrame() do the same?

  3. Rendering opportunities in background tabs are subject to "user agent throttling for performance reasons". But is rendering == canvas paint?

Developers have shown clever uses of non-rendering timers to drive canvas actions, which begs the question why Firefox's MediaRecorder cannot keep up, when Chrome's apparently can. Since years have passed, we should probably look at web compat over specs at this point.

Though curiously, as a test, when I compared this direct camera record fiddle with one that goes an extra step through canvas using requestAnimationFrame, I got some surprising results with the latter:

  • Navigating to a different tab in Firefox predictably causes <1 fps, but in Chrome the video stalls entirely.

So from this test, I'd say comment 18 doesn't sound like the right solution.

Flags: needinfo?(jib) → needinfo?(annevk)

(In reply to Jan-Ivar Bruaroey [:jib] (needinfo? me) from comment #30)

Though curiously, as a test, when I compared this direct camera record fiddle with one that goes an extra step through canvas using requestAnimationFrame, I got some surprising results with the latter:

  • Navigating to a different tab in Firefox predictably causes <1 fps, but in Chrome the video stalls entirely.

So from this test, I'd say comment 18 doesn't sound like the right solution.

I don't follow this reasoning. How does keeping rAF running in these background tabs not solve the stalling problem?

I should add that we internally run the frame-capturing of canvases off the refresh driver, which also drives rAF callbacks, in order to capture a webgl buffer before it is swapped away. The order of events there is important and chrome got it wrong in the past (so tried to update the spec to deal with it for them), not sure how they fare now.

Flags: needinfo?(jib)

I suspect what Jan-Ivar is saying is that might not necessarily result in interop with Chrome?

I had forgotten https://github.com/w3c/mediacapture-fromelement existed. It seems to me it should be integrated with the HTML Standard directly. It's indeed not clear to me what a canvas paint might be. Per the HTML Standard the canvas is always up-to-date and there is no explicit paint step. "Update the rendering" is when style/layout happens and various related events fire, typically/ideally at 60pfs.

Perhaps one thing that might help to look at is to make requestFrame() use logic similar to getImageData()/toBlob() and friends as those reportedly do the right thing. I would also love it if someone could explain the security story for requestFrame(). Is it basically so that the resulting MediaStream is opaque once the canvas is tainted in some way? Do we have tests for that? Not propagating tainting is a frequent source of bugs...

Another thing to look out for here is that this cannot be used to circumvent throttling of background pages.

Hope that helps a bit.

Flags: needinfo?(annevk)

(In reply to Anne (:annevk) from comment #32)

I suspect what Jan-Ivar is saying is that might not necessarily result in interop with Chrome?

I had forgotten https://github.com/w3c/mediacapture-fromelement existed. It seems to me it should be integrated with the HTML Standard directly. It's indeed not clear to me what a canvas paint might be. Per the HTML Standard the canvas is always up-to-date and there is no explicit paint step. "Update the rendering" is when style/layout happens and various related events fire, typically/ideally at 60pfs.

Perhaps one thing that might help to look at is to make requestFrame() use logic similar to getImageData()/toBlob() and friends as those reportedly do the right thing. I would also love it if someone could explain the security story for requestFrame(). Is it basically so that the resulting MediaStream is opaque once the canvas is tainted in some way? Do we have tests for that? Not propagating tainting is a frequent source of bugs...

Test for capturing a tainted canvas. Test for tainting a captured canvas.

Another thing to look out for here is that this cannot be used to circumvent throttling of background pages.

Well, Google Meet in Chrome is drawing to the canvas, and capturing from it in the background somehow. I suspect their capturing is decoupled from drawing (related: comment 31 - ours is not) and the drawing in Meet is driven by something else than requestAnimationFrame. Maybe requestVideoFrameCallback? For instance on whereby.com blurred video stalls in the background in Chrome.

Hope that helps a bit.

(In reply to Andreas Pehrson [:pehrsons] from comment #33)

(In reply to Anne (:annevk) from comment #32)

I suspect what Jan-Ivar is saying is that might not necessarily result in interop with Chrome?

I had forgotten https://github.com/w3c/mediacapture-fromelement existed. It seems to me it should be integrated with the HTML Standard directly. It's indeed not clear to me what a canvas paint might be. Per the HTML Standard the canvas is always up-to-date and there is no explicit paint step. "Update the rendering" is when style/layout happens and various related events fire, typically/ideally at 60pfs.

Perhaps one thing that might help to look at is to make requestFrame() use logic similar to getImageData()/toBlob() and friends as those reportedly do the right thing. I would also love it if someone could explain the security story for requestFrame(). Is it basically so that the resulting MediaStream is opaque once the canvas is tainted in some way? Do we have tests for that? Not propagating tainting is a frequent source of bugs...

Test for capturing a tainted canvas. Test for tainting a captured canvas.

Another thing to look out for here is that this cannot be used to circumvent throttling of background pages.

Well, Google Meet in Chrome is drawing to the canvas, and capturing from it in the background somehow. I suspect their capturing is decoupled from drawing (related: comment 31 - ours is not) and the drawing in Meet is driven by something else than requestAnimationFrame. Maybe requestVideoFrameCallback? For instance on whereby.com blurred video stalls in the background in Chrome.

Hope that helps a bit.

In our app (Bash Video) we used a worker to post messages at a set rate to the Window which would then call requestFrame to prevent background stalling in Chrome.

(In reply to Anne (:annevk) from comment #32)

I suspect what Jan-Ivar is saying is that might not necessarily result in interop with Chrome?

Unthrottling rAF in Firefox may solve it, but at the cost of undoing a potentially significant background optimization (I have 100s of open tabs, likely with fewer ads than most).

So we'd probably only be able to turn this on if we see captureStream in use, but then we've created an escape hatch from throttling that pages may use maliciously, and it would only hurt Firefox users. That seems unwise.

This would widen the behavior gap with Chrome, who has solved this differently somehow. Since it's not tightly spec'ed, I suppose browsers' throttling stories don't technically need to match. But from a web developer pov, it'd probably be easier if they did. I wish we knew more about what Chrome does here.

(In reply to Andreas Pehrson [:pehrsons] from comment #33)

Well, Google Meet in Chrome is drawing to the canvas, and capturing from it in the background somehow. I suspect their capturing is decoupled from drawing (related: comment 31 - ours is not) and the drawing in Meet is driven by something else than requestAnimationFrame. Maybe requestVideoFrameCallback?

A version of the through-canvas fiddle using requestVideoFrameCallback also stalls when in the background in Chrome FWIW.

Flags: needinfo?(jib)

(In reply to Jan-Ivar Bruaroey [:jib] (needinfo? me) from comment #35)

(In reply to Andreas Pehrson [:pehrsons] from comment #33)

Well, Google Meet in Chrome is drawing to the canvas, and capturing from it in the background somehow. I suspect their capturing is decoupled from drawing (related: comment 31 - ours is not) and the drawing in Meet is driven by something else than requestAnimationFrame. Maybe requestVideoFrameCallback?

A version of the through-canvas fiddle using requestVideoFrameCallback also stalls when in the background in Chrome FWIW.

So I did some debugging in Chrome 95 today. They have MediaStreamTrackProcessor present in code but it's not in use. Instead there are two canvases on which captureStream(0) is used. There is a "timer worker" that sends messages to main thread to trigger requestFrame(). So basically comment 34.

If this approach is viable in Firefox (and from talking to :farre I think it is) we could for instance simulate the refresh driver ticks to allow a canvas-captureStream to capture frames from a canvas when the refresh driver (and rAF callbacks) is throttled. Anne, jib, does this sound like a decent short-term fix to you? The long-term fix I imagine is whatever comes out of mediacapture-transform.

Flags: needinfo?(jib)
Flags: needinfo?(annevk)
No longer blocks: gfx-triage

WFM.

Flags: needinfo?(jib)

I filed https://github.com/w3c/mediacapture-fromelement/issues/94 on better HTML integration.

It seems that allowing a worker with postMessage() to bypass throttling in that matter will become problematic. Why would that not be abused in the same way timers have been in the past? It's also still not clear to me why toBlob() already works, but requestFrame() does not. Can the latter not pull directly from the canvas and instead the canvas has to actively push frames into the MediaStream?

Flags: needinfo?(annevk)

(In reply to Anne (:annevk) from comment #38)

I filed https://github.com/w3c/mediacapture-fromelement/issues/94 on better HTML integration.

It seems that allowing a worker with postMessage() to bypass throttling in that matter will become problematic. Why would that not be abused in the same way timers have been in the past? It's also still not clear to me why toBlob() already works, but requestFrame() does not. Can the latter not pull directly from the canvas and instead the canvas has to actively push frames into the MediaStream?

My interpretation of the spec is that requestFrame() (and the term "request a frame to be captured") sets the internal slot [[frameCaptureRequested]] to true. The capturing then happens with the same timing as for the other captureStream() modes.

Also, issue #28.

(In reply to Jan-Ivar Bruaroey [:jib] (needinfo? me) from comment #35)

(In reply to Anne (:annevk) from comment #32)

I suspect what Jan-Ivar is saying is that might not necessarily result in interop with Chrome?

Unthrottling rAF in Firefox may solve it, but at the cost of undoing a potentially significant background optimization (I have 100s of open tabs, likely with fewer ads than most).

So we'd probably only be able to turn this on if we see captureStream in use, but then we've created an escape hatch from throttling that pages may use maliciously, and it would only hurt Firefox users. That seems unwise.

Please weigh these concerns against the fact that software is broken in Firefox today, due to this throttling. This also hurts Firefox users.

I think the solution of disabling throttling when captureStream is used is correct, in lieu of a frame timer specific to the drawing context of the Canvas/CanvasCaptureMediaStream. That would be a better solution, solving for the issue documented here, and others. It also avoids the hack of worker postMessage.

Please, don't make rAF even more broken, and for something that is unrelated to rAF to begin with.
The problem is that Firefox's MediaRecorder is hooked to rAF with no good reasons, that's what needs to be fixed. Use a monotonic timer that doesn't get throttled like Chrome is apparently doing.
Yes it's unfortunate that we have to use hacks to workaround throttling, but breaking rAF which does promise exactly that it's battery friendly and throttles nicely when the page is hidden is the-wrong-direction™. Hopefully there will be better solutions than these hacks (maybe from the scheduler API?), but that we need hacks is not a reason to break existing APIs.

(In reply to Kaiido from comment #41)

The problem is that Firefox's MediaRecorder is hooked to rAF with no good reasons, that's what needs to be fixed. Use a monotonic timer that doesn't get throttled like Chrome is apparently doing.

Let's be clear here. MediaRecorder is irrelevant. Canvas captureStreams are tied to rAF, for the reason mentioned in comment 31.

(In reply to Andreas Pehrson [:pehrsons] from comment #42)

Let's be clear here. MediaRecorder is irrelevant. Canvas captureStreams are tied to rAF, for the reason mentioned in comment 31.

Yes sorry, replace "MediaRecorder" with "CanvasCaptureMediaStream[not yet Track...]" in my previous comment.

But I don't see why the argument in comment 31 is any compelling, rAF is still the worst place to capture frames, there is obviously an issue with captureStream(0) which ought to work like drawImage, and there is still no good reason to break rAF for this.
If you really need to, then break the perfs of the only webgl context that is being captured like Chrome does, but don't break everything for this API. From my point of view you are proposing to break everything to maintain a workaround.

No longer blocks: webrtc-triage
Assignee: nobody → apehrson
Severity: normal → S3
Status: NEW → ASSIGNED
Rank: 15
Component: Audio/Video: Recording → WebRTC: Audio/Video
Keywords: regression
OS: macOS → All
Priority: P3 → P2
Hardware: x86 → All
Summary: Dropped frames in recording with canvas use → canvas.captureStream: doesn't capture frames in a background tab

This allows the canvas element to be notified when a draw that would trigger
a captureStream-frame to be captured.

Note that this is only triggered if the application is able to draw to the
canvas while the refresh driver is throttled.

Attachment #9259111 - Attachment description: Bug 1344524 - Change ContextCleanForFrameCapture flag to a Watchable FrameCaptureState. r?jgilbert! → Bug 1344524 - Change ContextCleanForFrameCapture flag to a Watchable FrameCaptureState. r?jgilbert!, r?kvark!
Attachment #9259111 - Attachment description: Bug 1344524 - Change ContextCleanForFrameCapture flag to a Watchable FrameCaptureState. r?jgilbert!, r?kvark! → Bug 1344524 - Change ContextCleanForFrameCapture flag to a Watchable FrameCaptureState. r?jgilbert!
Pushed by pehrsons@gmail.com: https://hg.mozilla.org/integration/autoland/rev/d930203c9295 Modernize test_capture.html for 2d context. r=jgilbert https://hg.mozilla.org/integration/autoland/rev/7eb441eeec30 Add mochitest. r=jgilbert https://hg.mozilla.org/integration/autoland/rev/4cb7ff5d0a69 Change ContextCleanForFrameCapture flag to a Watchable FrameCaptureState. r=jgilbert https://hg.mozilla.org/integration/autoland/rev/25c186bc96eb Capture frames from a canvas while its refresh driver is throttled. r=jgilbert
Regressions: 1752351
No longer regressions: 1753275
See Also: → 1752902
Blocks: 1703668
Regressions: 1752902
See Also: 1752902
Regressions: 1777094
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: