Skip to content

Do not create GPU rendering work for caret-only host frames #114

Description

@wieslawsoltes

Problem

A focused native text control keeps WebScene demand bit 2 (4) active for caret blinking. When WebGPU is installed, v8_dom_runtime::signal_animation_frame() currently turns every admitted caret frame into a GPU rendering opportunity even when there is no JavaScript RAF, GPU canvas, or current texture.

That makes has_pending_animation_frame_task() report work. The worker then marks the frame changed and publishes an unchanged scene. AppScene's publication callback requests the next display tick, and the still-focused caret admits it again. In Code OSS this can close a 120 Hz redraw loop after the hidden editor input receives focus.

Observed packaged impact at 1440x940 on macOS arm64:

  • about 120 completed presentations/second while visibly idle;
  • RSS high-water reached about 775 MiB in the failing run;
  • the same package can appear idle when the editor input does not retain native focus, making the regression intermittent.

CSS animation demand was already zero during the sustained loop. Trace edges stayed at demand 4, with only brief 4 -> 5 -> 4 JavaScript RAF bursts.

Proposed fix

Create a GPU rendering opportunity only when the frame can contain GPU work:

  1. a waiting JavaScript RAF may acquire a canvas current texture; or
  2. a GPU canvas already has a current texture that must be retired.

WebGPU availability alone must not create frame work.

The focused local change is on branch fix/idle-webgpu-rendering-opportunity at commit 00e5e90c and is merged only into the local consolidation branch. It is not pushed or merged to the repository default branch.

Acceptance gates

  • Native graphics regression: install WebGPU, focus an <input>, queue no RAF/CSS/GPU canvas work, verify caret demand is 4, call signal_animation_frame(), and verify no pending animation-frame task is created.
  • Preserve existing RAF-acquired texture, current-texture retirement, GPU canvas lifetime, resize, and caret blink tests.
  • Hosted macOS and Windows native graphics lanes pass.
  • Three packaged Code OSS performance runs pass:
    • visible idle presentations <= 5/s;
    • hidden idle presentations <= 2/s;
    • existing CPU, RSS, input, render, CSS, layout, scene, publication, and panel budgets remain green.
  • Existing native caret visual regression still observes both visible and hidden blink phases.

This internal host scheduling behavior is not observable through web-platform tests. The meaningful regression coverage is the native graphics contract plus the packaged performance gate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions