Skip to content

feat(馃): name the Android backing view explicitly - #574

Merged
wcandillon merged 1 commit into
mainfrom
android-backing-view
Oct 18, 2026
Merged

wcandillon merged 1 commit into
mainfrom
android-backing-view

Conversation

@wcandillon

Copy link
Copy Markdown
Owner

Why

Mirror of react-native-skia's change, so both canvases take the same Android options. opaque was a shortcut to get a SurfaceView on Android; on native it was consumed nowhere else, and on the web it only painted a white background. It moves under android as a compositing hint, and the backing view gets a name of its own.

The model

<Canvas />                                                     // TextureView, translucent
<Canvas android={{ opaque: true }} />                          // TextureView, no blend
<Canvas android={{ backingView: "SurfaceView" }} />            // compositor fast path, opaque by default
<Canvas android={{ backingView: "SurfaceView", opaque: false, zOrderOnTop: true }} />
<Canvas android={{ backingView: "HardwareBufferView" }} />     // opt-in, always composites with alpha
  • android is a discriminated union. A TextureView takes opaque (false by default). A SurfaceView takes opaque (true by default: a translucent one blends against black below the window), zOrderOnTop and the new zOrderMediaOverlay, which composites it above the other SurfaceViews below the window; both z-orders apply in place on Android 11 and later and are read at mount before that. A HardwareBufferView takes no option, and falls back to a TextureView below Android 10 with a warning in development.
  • Nothing derives the backing view from another prop any more: BackingViewKind holds the pure rules and Canvas.tsx mirrors them for the development warnings.
  • On the web, alphaMode alone decides how the canvas composites, as in a browser; the white background is gone.
  • The docs rewrite the Android rendering options and the transparency sections around this model, and say what a remount through a key costs rather than claiming Android cannot hand a canvas over (fix(馃): keep a canvas on screen while it swaps its backing view in place聽#563 shows it can, at the price of per-release logic).

Migration

The top-level opaque prop is gone (TypeScript flags it) and android.surfaceType is android.backingView. The default moves from an opaque SurfaceView to a translucent TextureView: a full-screen scene that wants the compositor fast path asks for it with android={{ backingView: "SurfaceView" }}. Per the discussion, this lands as a plain feature commit, not a major.

Verification

  • Pixel 8 (Android 17), Android View Props diagnostic: opaque applies in place on both views, the on-top and media overlay z-orders move a mounted SurfaceView without a remount, the hardware buffer view composites with alpha; no warning, error or crash in logcat. Screenshots of each state were checked.
  • yarn tsc and yarn lint in the package, the example and the docs app (the docs app's two pre-existing TS2698 errors in TransparencyDemo.tsx are untouched), the Android build of the example, and the package's Jest suite against the Pixel 8 (44 suites, 222 tests).

Same model as react-native-skia: the `opaque` prop was a shortcut to get
a SurfaceView on Android, consumed nowhere else on native (the web view
only painted a white background from it). It moves under `android` as a
compositing hint, applied in place on whichever view backs the canvas,
and the view itself is named by `android.backingView` (replacing
`surfaceType`), with `TextureView` as the default whatever the opacity.

- `android` is a discriminated union: a TextureView takes `opaque`
  (translucent by default), a SurfaceView takes `opaque` (opaque by
  default), `zOrderOnTop` and the new `zOrderMediaOverlay`, which
  composites it above the other SurfaceViews below the window; both
  z-order options apply in place on Android 11 and later. A
  HardwareBufferView takes no option: it always composites with alpha,
  and falls back to a TextureView below Android 10, with a warning in
  development.
- Nothing derives the backing view from another prop any more, so the
  JS and Java rules collapse to reading `backingView`; the pure rules
  live in BackingViewKind.
- On the web, `alphaMode` alone decides how the canvas composites, as in
  a browser: the white background `opaque` used to paint is gone.
- The docs describe the model, including what a remount through a key
  costs (a frame or two off screen) and that keeping the canvas on screen
  through a swap is possible but needs per-release logic (#563).

Verified on the Pixel 8 (Android 17) with the Android View Props
diagnostic: opaque applies in place on both views, the on-top and media
overlay z-orders move a mounted SurfaceView without a remount, and the
HardwareBufferView composites with alpha; no warning, error or crash in
logcat.
@github-actions

Copy link
Copy Markdown

馃帀 This PR is included in version 0.17.0 馃帀

The release is available on:

Your semantic-release bot 馃摝馃殌

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant