Bug 217339 - [GPU Process] Support CanvasRenderingContext2D.drawImage() with HTMLVideoElement
Summary: [GPU Process] Support CanvasRenderingContext2D.drawImage() with HTMLVideoElement
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Canvas (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Wenson Hsieh
URL:
Keywords: InRadar
Depends on: 217397
Blocks:
  Show dependency treegraph
 
Reported: 2020-10-05 14:41 PDT by Wenson Hsieh
Modified: 2021-02-17 16:35 PST (History)
21 users (show)

See Also:


Attachments
Work in progress (77.55 KB, patch)
2020-10-05 15:27 PDT, Wenson Hsieh
no flags Details | Formatted Diff | Diff
Work in progress (78.33 KB, patch)
2020-10-06 08:22 PDT, Wenson Hsieh
no flags Details | Formatted Diff | Diff
Patch (81.67 KB, patch)
2020-10-06 10:37 PDT, Wenson Hsieh
no flags Details | Formatted Diff | Diff
Patch (34.12 KB, patch)
2020-10-06 13:46 PDT, Wenson Hsieh
no flags Details | Formatted Diff | Diff
For EWS (33.50 KB, patch)
2020-10-07 10:27 PDT, Wenson Hsieh
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Wenson Hsieh 2020-10-05 14:41:46 PDT
Support CanvasRenderingContext2D.drawImage() with HTMLVideoElement

Covered by existing layout tests in fast/canvas and canvas.
Comment 1 Wenson Hsieh 2020-10-05 15:27:14 PDT Comment hidden (obsolete)
Comment 2 Wenson Hsieh 2020-10-06 08:22:25 PDT Comment hidden (obsolete)
Comment 3 Wenson Hsieh 2020-10-06 10:37:36 PDT Comment hidden (obsolete)
Comment 4 Wenson Hsieh 2020-10-06 13:46:33 PDT
Created attachment 410690 [details]
Patch
Comment 5 Wenson Hsieh 2020-10-06 14:39:21 PDT
<rdar://problem/69409029>
Comment 6 Peng Liu 2020-10-06 17:22:32 PDT
Comment on attachment 410690 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=410690&action=review

> Source/WebCore/ChangeLog:9
> +        details.

I guess we can enable some tests in this patch?
Comment 7 Wenson Hsieh 2020-10-06 17:57:30 PDT
(In reply to Peng Liu from comment #6)
> Comment on attachment 410690 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=410690&action=review
> 
> > Source/WebCore/ChangeLog:9
> > +        details.
> 
> I guess we can enable some tests in this patch?

The entirety of fast/canvas, canvas, imported/w3c/canvas and imported/w3c/web-platform-tests/html/canvas are skipped at the moment. This code should be covered by the following tests once we enable those directories:

• imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/canvas-createImageBitmap-video-resize.html
• fast/canvas/canvas-createPattern-video-loading.html
• fast/canvas/canvas-createPattern-video-modify.html
• imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-drawImage.html
• imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY.html
Comment 8 Darin Adler 2020-10-07 09:08:16 PDT
Comment on attachment 410690 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=410690&action=review

> Source/WebCore/platform/graphics/GraphicsContext.cpp:1263
> +    player.setVisible(true);

Surprised that this:

1) is needed.
2) is needed every time.
3) is harmless from a side effect point of view

> Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp:1937
> +void GraphicsContext::paintFrameForMedia(MediaPlayer& player, const FloatRect& destination)

Annoying that this repeats the code from the non-CG version. Is there a better way to factor this?

> Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp:1947
> +    player.setVisible(true);

Ditto.

> Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp:1242
> +    // Should be handled by the delegate.

Ugly but OK.

> Source/WebCore/platform/graphics/displaylists/DisplayListItems.h:2589
> +    static Ref<PaintFrameForMedia> create(MediaPlayer& player, const FloatRect& destination)

Should not inline this kind of function. The constructor can get inclined instead. Better for efficiency and for class definition brevity.

> Source/WebCore/platform/graphics/displaylists/DisplayListItems.h:2603
> +    static Ref<PaintFrameForMedia> create(MediaPlayerIdentifier identifier, const FloatRect& destination)

Ditto.
Comment 9 Wenson Hsieh 2020-10-07 10:19:55 PDT
Comment on attachment 410690 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=410690&action=review

>> Source/WebCore/platform/graphics/GraphicsContext.cpp:1263
>> +    player.setVisible(true);
> 
> Surprised that this:
> 
> 1) is needed.
> 2) is needed every time.
> 3) is harmless from a side effect point of view

Good catch! After taking a closer look, it shouldn’t be necessary at all — I removed this line.

My intent had been to preserve the logic in `HTMLVideoElement::paintCurrentFrameInContext` when playing the drawing item back in the GPUP. However, since `MediaPlayerPrivateRemote::setVisible` will make the remote-side MediaPlayer visible anyways, doing this in GraphicsContext is redundant.

>> Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp:1937
>> +void GraphicsContext::paintFrameForMedia(MediaPlayer& player, const FloatRect& destination)
> 
> Annoying that this repeats the code from the non-CG version. Is there a better way to factor this?

I had done it this way to avoid changing behavior when using the Nicosia-specific `CairoOperationRecorder` as the `GraphicsContextImpl` — I’ve changed this to avoid duplicating the logic in CoreGraphics platform code by instead doing it like this:
• Add a `GraphicsContextImpl::canPaintFrameForMedia` method that returns `true` for the display list recorder, and false in other GraphicsContextImpl subclasses where it’s not implemented.
• Move `GraphicsContext::paintFrameForMedia` into the common `GraphicsContext.cpp` file, and consult `canPaintFrameForMedia` before delegating the call to `m_impl`.

(This way, we can avoid code duplication, and also keep Nicosia working).

>> Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp:1947
>> +    player.setVisible(true);
> 
> Ditto.

Removed!

>> Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp:1242
>> +    // Should be handled by the delegate.
> 
> Ugly but OK.

Indeed. I hatched a plan (with @thorton) to fix this:

We’re thinking of a design where we push logic for applying the display list item out of the delegate (in this case, RemoteImageBufferProxy) and into `PaintFrameForMedia::apply` and `PutImageData::apply`. Instead of a `DisplayList::Replayer::Delegate::apply`, we would then have a `DisplayList::Replayer::Delegate::willApply` method that will prepare the Display List item for playback. In the case of PaintFrameForMedia, we could set a pointer to the `MediaPlayer`, and in the case of `PutImageData`, it could be something like telling the display list item about the `ImageBuffer`.

I’m planning to explore this in a followup.

>> Source/WebCore/platform/graphics/displaylists/DisplayListItems.h:2589
>> +    static Ref<PaintFrameForMedia> create(MediaPlayer& player, const FloatRect& destination)
> 
> Should not inline this kind of function. The constructor can get inclined instead. Better for efficiency and for class definition brevity.

Sounds good — made this out of line. That said, the other static `create` methods in this file are also currently inline; I’ll put together a followup patch to mass move these too.

>> Source/WebCore/platform/graphics/displaylists/DisplayListItems.h:2603
>> +    static Ref<PaintFrameForMedia> create(MediaPlayerIdentifier identifier, const FloatRect& destination)
> 
> Ditto.

👍🏻
Comment 10 Wenson Hsieh 2020-10-07 10:27:28 PDT
Created attachment 410758 [details]
For EWS
Comment 11 EWS 2020-10-07 13:13:29 PDT
Committed r268145: <https://trac.webkit.org/changeset/268145>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 410758 [details].