Skip to content

fix(📲): unconfigure a canvas surface only while it is configured - #551

Draft
YevheniiKotyrlo wants to merge 4 commits into
wcandillon:mainfrom
YevheniiKotyrlo:fix/unconfigure-configured-surface
Draft

YevheniiKotyrlo wants to merge 4 commits into
wcandillon:mainfrom
YevheniiKotyrlo:fix/unconfigure-configured-surface

Conversation

@YevheniiKotyrlo

@YevheniiKotyrlo YevheniiKotyrlo commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #550; the diff of its own is the last commit.

Problem

context.unconfigure() calls Surface::Unconfigure() whenever a surface is attached, and Dawn rejects that on a surface that is not configured (Surface::Unconfigure: "is not configured"). GPUCanvasContext.unconfigure() is valid in each of these cases, and each one reaches Dawn as a validation error:

  • a second unconfigure();
  • an unconfigure() on a context that was never configured while its view's surface is attached;
  • on Android, an unconfigure() after device.destroy(), which recreates the canvas's surface unconfigured.

Solution

SurfaceInfo tracks whether its surface is configured: set when it configures the surface, cleared when it unconfigures it, adopts or recreates a surface, or detaches one. unconfigure() calls Surface::Unconfigure() only while it is.

Tests

Three cases in tests/cpp/SurfaceInfoTest.cpp: unconfigure twice, unconfigure a context that was never configured, and configure again after unconfigure and present. Without the change the first two fail with the fake's record of Dawn's rejection (Surface.Unconfigure on a surface that is not configured); with it all 29 C++ tests pass.

Verification

yarn test:cpp on Ubuntu 24.04 (g++ 13.3): 29 passed. The Android library's native build (:react-native-webgpu:externalNativeBuildDebug, x86_64) compiles the change, and so does the example's iOS build for the simulator SDK. clang-format and the package's cpplint command leave the two files unchanged. CI's Android e2e step (debug build, Metro with CI=true) on an Android 15 emulator: 219 of 221, as on main; the two failures, the YUV cases of ExternalTextureColorSpace and NativeBufferWrapper, fail on main there too. On devices the whole suite passes, 221 of 221: on a Galaxy S23 (Android 14), and on an iPad Pro 12.9-inch (4th generation, iOS 27.0.1) built and run as CI's iOS job does on a simulator (Debug build, Metro with CI=true). main passes 221 of 221 on both.

@YevheniiKotyrlo

YevheniiKotyrlo commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor Author

The three new tests against #550's SurfaceRegistry.h (ctest -R Unconfigure):

1/3 Test #20: SurfaceInfoTest.UnconfiguresTwice .........................................***Failed    0.00 sec
    Which is: { "Surface.Unconfigure on a surface that is not configured" }
2/3 Test #21: SurfaceInfoTest.UnconfiguresAContextThatWasNeverConfigured ................***Failed    0.00 sec
    Which is: { "Surface.Unconfigure on a surface that is not configured" }
3/3 Test #22: SurfaceInfoTest.PresentsOnTheSurfaceAgainOnceConfiguredAfterUnconfigure ...   Passed    0.00 sec
33% tests passed, 2 tests failed out of 3

With the change, the whole C++ suite:

100% tests passed, 0 tests failed out of 29

…dence on the host

SurfaceRegistry.h and AnimationReporter had no unit tests: CI built them
and the e2e suite on a device was the only check. tests/cpp compiles the
registry for the host against FakeWebGPU.cpp, a stand-in for the WebGPU C
functions it calls that records every call Dawn would reject, and
`yarn test:cpp` builds and runs it with CMake and GoogleTest.
AnimationReporter's timing rule moves unchanged into AnimationCadence,
which takes the time as an argument, so the same tests drive it. The
Android CI job runs them before the Gradle build.
context.unconfigure() called Surface::Unconfigure() whenever a surface was
attached, and Dawn rejects that on a surface that is not configured: a
second unconfigure(), one on a context that was never configured while its
view's surface is attached, or one after device.destroy() recreated the
surface on Android. GPUCanvasContext.unconfigure() is valid in each case.
SurfaceInfo now tracks whether its surface is configured.
@YevheniiKotyrlo
YevheniiKotyrlo force-pushed the fix/unconfigure-configured-surface branch from 0d6ba19 to 11920e6 Compare October 16, 2026 14:05

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant