Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reftests: Canvas display after device lost/destroyed #3251

Open
2 of 5 tasks
kainino0x opened this issue Jan 9, 2024 · 6 comments
Open
2 of 5 tasks

reftests: Canvas display after device lost/destroyed #3251

kainino0x opened this issue Jan 9, 2024 · 6 comments

Comments

@kainino0x
Copy link
Collaborator

kainino0x commented Jan 9, 2024

I believe that according to the WebGPU spec, canvas display should interact with device loss (and destroy()) as follows:

Rough test cases:

@kainino0x
Copy link
Collaborator Author

@perryuwang
The general instructions for CTS contributions are here:
https://github.com/gpuweb/cts/blob/main/docs/intro/README.md

The reftests live in this directory:
https://github.com/gpuweb/cts/tree/main/src/webgpu/web_platform/reftests

A good example to look at is the simplest one. Here is the test:
https://github.com/gpuweb/cts/blob/main/src/webgpu/web_platform/reftests/canvas_clear.https.html
Note its script is canvas_clear.html.js which is actually canvas_clear.html.ts in the repository.

Also note it points to it's match reference rendering ./ref/canvas_clear-ref.html. A reftest compares the rendering of the page with the rendering of the match reference. Usually our reftests compare WebGPU rendering to 2D canvas rendering, which make it easy to render a solid color like that:
https://github.com/gpuweb/cts/blob/main/src/webgpu/web_platform/reftests/ref/canvas_clear-ref.html

For this test, I think a solid color canvas (one opaque and one transparent), similar to the canvas_clear test, is sufficient, except you will probably want to set the background color of the element or the page in order to test the transparency rendering.

Usually I recommend just visually comparing the rendering of the test and the reference. In order to run the pages locally, follow the setup instructions here:
https://github.com/gpuweb/cts/blob/main/docs/intro/developing.md
and see here for how to open the page on localhost:
https://github.com/gpuweb/cts/blob/main/docs/intro/developing.md#web-platform-tests-wpt---ref-tests
There are also instructions for actually running the reftest (with automatic comparison) in that documentation section, but since this test just needs to show a solid color it probably won't be necessary.

@perryuwang
Copy link
Contributor

I believe that according to the WebGPU spec, canvas display should interact with device loss (and destroy()) as follows:

  • After the device is lost but before calling getCurrentTexture, it should keep returning the last displayed frame

  • After the device is lost and after calling getCurrentTexture, it should return:

    • a solid black image, if configure()d as opaque
    • a blank transparent image, if configure()d as transparent

Rough test cases:

  • Render something, destroy the device, then wait a few frames before the screenshot is taken
  • Render something, destroy the device, wait a few frames, call getCurrentTexture

@kainino0x
I test on Firefox and Safari, and they always return the last displayed frame after the device is lost.
I think this may be more reasonable, but I'm not sure if it violates the spec.

@kainino0x
Copy link
Collaborator Author

According to the spec as written, getCurrentTexture() is always supposed to create a new drawing buffer (unless there is already one for the current frame). That drawing buffer is then supposed to get displayed on the next frame. All of this is independent of anything that's going on with the GPUDevice - there's no special casing for lost devices in the canvas-related algorithms.

There's a good reason for this, actually - device loss occurs in the device timeline (GPU process), while all canvas state stuff is done in the content timeline (renderer process). Of course, all display is going through the GPU process anyway, so technically the spec could try to define some parts of the canvas algorithms as occurring in the device timeline, but this would be difficult to match up with the HTML spec on canvas, which defines no concept of a device timeline.

  • After the device is lost but before calling getCurrentTexture, it should keep returning the last displayed frame

Giving this a bit more thought - we can't really guarantee this for all device loss. For device destroy, we can. But if something catastrophic happens like the GPU process crashes (about:gpucrash in chrome), I think the canvas contents will be entirely lost and there's nothing we can do about that.

The spec makes no carveout for this. It technically should, but this is such an exceptional case that I don't think it's worth the significant effort to figure out what that carveout should look like.

@perryuwang
Copy link
Contributor

Got it. Thanks very much.

@kainino0x
Copy link
Collaborator Author

With gpuweb/gpuweb#4859 it seems we'll end up allowing multiple behaviors. Fortunately WPT supports this! https://web-platform-tests.org/writing-tests/reftests.html#multiple-references

@kainino0x
Copy link
Collaborator Author

Possibly useful reference for test cases: https://codepen.io/kainino0x/pen/dyxoNRd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Open (no TODO)
Development

No branches or pull requests

2 participants