Skip to content

Introduce snapshot concept of canvas#36119

Merged
sagudev merged 8 commits intoservo:mainfrom
sagudev:canvas-snapshot
Apr 23, 2025
Merged

Introduce snapshot concept of canvas#36119
sagudev merged 8 commits intoservo:mainfrom
sagudev:canvas-snapshot

Conversation

@sagudev
Copy link
Copy Markdown
Member

@sagudev sagudev commented Mar 24, 2025

Each canvas context returns snapshot instead of just raw bytes. This allows as to hold off conversions (BGRA <-> RGBA, (un)premultiply) to when/if they are actually needed. For example when loading snapshot into webgl we can load both RGBA and BGRA so no conversion is really needed.

Currently whole thing is designed to be able to be extend on servo/ipc-channel#356, to make less copies. Hence some commented out code.

Fixes #35759
There are tests for these changes in WPT

@sagudev sagudev added A-gfx/uncategorized A-content/webgl 3d canvas API A-content/canvas 2d canvas API A-content/webgpu The WebGPU implementation. labels Mar 24, 2025
@github-project-automation github-project-automation bot moved this to In progress in WebGPU Mar 24, 2025
@sagudev sagudev changed the title Introduce snapshot concept of ImageBitmap of canvas Introduce snapshot concept of canvas Mar 24, 2025
@sagudev sagudev force-pushed the canvas-snapshot branch 2 times, most recently from 441e7c8 to c8f619e Compare April 9, 2025 07:21
@sagudev
Copy link
Copy Markdown
Member Author

sagudev commented Apr 9, 2025

I analyzed all stable unexpected failures https://github.com/sagudev/servo/actions/runs/14377247275/attempts/1#summary-40315242040:

New PASSes are because we now properly handle RGBA<->BGRA and pre/un multiplying when uploading/downloading pixels.

New FAILures were actually just false positives, this can be verified with "near" tests that also fail.

@sagudev sagudev force-pushed the canvas-snapshot branch 4 times, most recently from 8a126f5 to 99418a4 Compare April 11, 2025 04:28
@sagudev
Copy link
Copy Markdown
Member Author

sagudev commented Apr 11, 2025

I also experimented with typing inner alphamode and pixelformat, but decides it was not worth it as we must use untyped version most of the time anyway: sagudev@61d20f3

@sagudev sagudev marked this pull request as ready for review April 11, 2025 04:33
@sagudev sagudev requested a review from gterzian as a code owner April 11, 2025 04:33
Copy link
Copy Markdown
Member

@gterzian gterzian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM overall, although I know very little about image formats so this may warrant the involvement of another reviewer?

Do I understand it correctly that the snapshot does not introduce any kind of concurrent logic, and is only used to delay running the conversion logic(on data that does not change or lose validity at some point) at the point of use?

I'm asking because to me the name "snapshot" seems to imply some sort of concurrent logic around the snapshot becoming out of date at some point in time, but that seems to be a wrong assumption on my part and the logic seems straight forward.

@sagudev
Copy link
Copy Markdown
Member Author

sagudev commented Apr 18, 2025

LGTM overall, although I know very little about image formats so this may warrant the involvement of another reviewer?

Hm, @jdm?

Do I understand it correctly that the snapshot does not introduce any kind of concurrent logic, and is only used to delay running the conversion logic(on data that does not change or lose validity at some point) at the point of use?

Yes, mayor goal is to actually avoid running conversion os much as possible.

I'm asking because to me the name "snapshot" seems to imply some sort of concurrent logic around the snapshot becoming out of date at some point in time, but that seems to be a wrong assumption on my part and the logic seems straight forward.

I took the name from webgpu spec: https://gpuweb.github.io/gpuweb/#abstract-opdef-get-a-copy-of-the-image-contents-of-a-context and it represents snapshot of canvas image bitmap. I will write more docs.

Signed-off-by: sagudev <[email protected]>
Copy link
Copy Markdown
Member

@jdm jdm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sensible! Just a couple questions.

})
Snapshot::new(
canvas_size,
snapshot::PixelFormat::BGRA,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit weird to see the bgra8 format here when we call a function named rgba8_get_rect just above this.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rgba8_get_rect just extracts subimage (pixels) of image regardless of pixel inner structure (pixel just needs to be 4B), if input image is BGRA it's result will also be BGRA and that's whats happening here.

Signed-off-by: sagudev <[email protected]>
Signed-off-by: sagudev <[email protected]>
@sagudev sagudev enabled auto-merge April 23, 2025 06:47
@sagudev sagudev added this pull request to the merge queue Apr 23, 2025
Merged via the queue into servo:main with commit 73b778e Apr 23, 2025
21 checks passed
@sagudev sagudev deleted the canvas-snapshot branch April 23, 2025 08:05
@github-project-automation github-project-automation bot moved this from In progress to Done in WebGPU Apr 23, 2025
github-merge-queue bot pushed a commit that referenced this pull request Jul 3, 2025
I introduced snapshot in #36119 to pack raw bytes and metadata together,
now we take the next step and require for user to always specify what
kind of byte data they want when calling `as_bytes` or `to_vec`
(basically joining transform and data). There are also valid usages when
one might require just one property of bytes (textures can generally
handle both RGBA and BGRA). There are also valid usages of using just
raw bytes (when cropping). This PR tries to make such usages more
obvious.

This will make it easier to fix stuff around 2d canvas (we do not want
to assume any bytes properties in abstraction).

Testing: Code is covered by WPT tests.

---------

Signed-off-by: sagudev <[email protected]>
Co-authored-by: Martin Robinson <[email protected]>
@sagudev sagudev self-assigned this Aug 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-content/canvas 2d canvas API A-content/webgl 3d canvas API A-content/webgpu The WebGPU implementation. A-gfx/uncategorized

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

get_image_data(_shared_memory) is a mess

3 participants