Skip to content

android: A55 — the cursor rides the daemon's cursor plane - #24

Merged
utkarshdalal merged 1 commit into
gamenativefrom
cursor-plane-on-android
Oct 31, 2026
Merged

utkarshdalal merged 1 commit into
gamenativefrom
cursor-plane-on-android

Conversation

@utkarshdalal

@utkarshdalal utkarshdalal commented Oct 31, 2026 •

Copy link
Copy Markdown

android: A55 — the cursor rides the daemon's cursor plane

Branch cursor-plane-on-android (41aea0e), base gamenative (A52 is the last patch there). No longer stacked on #23: A55 applies over 0001-0050 alone. New patch android/patches/gamescope/0051-A55-cursor-plane-on-gamenative-drm.patch; the 0001-0051 train applies cleanly over a fresh export. CI build 41199397730.

Change

  • DRMBackend.cpp init_drm: requests the daemon's GNDRM_CLIENT_CAP_CURSOR_LAYER (0x474E434C, "GNCL"). Accepted -> drm_cursor_plane on, logged drm: cursor: daemon cursor layer on (GNCL accepted, max 256x256), drm_cursor_plane=1. Rejected (old daemon) -> unchanged behaviour, logged once.
  • Direct path (game buffer on the primary plane, the DXVK case): a cursor move commits the same primary framebuffer plus the moved cursor plane, no composite.
  • Composite path (FSR/NIS/SGSR, filters, looks, refused buffers): composites everything except the cursor; a paint caused only by cursor motion re-commits the last composite instead of compositing again (skipped for fade, blur, ReShade, composite debug). If the two-plane commit is refused that frame composites the cursor in as before and that image is not offered to the plane again.
  • steamcompmgr.cpp: a cursor motion is a repaint request like hasRepaint (picked up on the next vblank, painted on every flip type) but recorded as a cursor repaint, a motion serial the paint records, so a motion during a paint stays pending. A paint whose only cause is the cursor is flagged cursor-only and takes the cursor-only path (same primary framebuffer or the last composite, cursor plane moved, no composite). There is no idle gate on gamenative, so no extra wake is needed. wlserver.cpp: wlserver_oncursorevent uses the cursor repaint when the cursor is on the plane, hasRepaint otherwise.

Results (Retroid Pocket 6, 120 Hz, Dave the Diver, cap 60, with gamenative-drm real-cursor-plane; measured on the earlier build stacked on #23)

cursor hidden cursor moving
before (stacked build, A53/A54 only) 46.9 fps (pre shim fix) 70.78 presents/s: a full composite + flip per cursor move
+ A55 + daemon cursor layer 60.00 54.85, scan-out and cursor both DEVICE, picture intact

The remaining ~5 fps drop with the cursor moving is per-motion wineserver work on the game's main thread (not display); separate follow-up.

Needs the daemon PR for the plane to appear; without it (EINVAL) nothing changes.

With GNCL accepted by gamenative-drm, drm_cursor_plane is on: the cursor is
scanned out on the daemon's cursor layer, the composite path composites under
the cursor plane and re-uses that composite for cursor-only paints, and a
cursor motion is a cursor repaint request picked up on the next vblank, so a
paint whose only cause is the cursor takes the cursor-only path. An older
daemon refuses GNCL and nothing changes.
@utkarshdalal
utkarshdalal force-pushed the cursor-plane-on-android branch from 569b7ca to 41aea0e Compare October 31, 2026 12:03
@utkarshdalal
utkarshdalal merged commit 8e4b50c into gamenative Oct 31, 2026
2 checks passed
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