feat: Per-Boundary GPU Textures + 0% GPU Idle (v0.1.19)#95
Merged
Conversation
- gg v0.44.1 → v0.46.4 (LCD ClearType, TagText scene text, atlas zoom resilience, deferred ortho projection, blit scissor groups) - gogpu v0.31.0 → v0.34.0 (ClearType, SubpixelLayout, D2 render loop) - gpucontext v0.16.0 → v0.18.0 (SubpixelLayout, AdapterInfo)
Retained-mode compositor with per-boundary GPU textures: - compositor/ package: Layer Tree types (OffsetLayer, PictureLayer, ClipRectLayer, OpacityLayer, Compositor) — implemented, tested, not yet connected to production pipeline (future optimization) - PaintBoundaryLayers: re-records dirty boundaries (Flutter flushPaint) - renderBoundaryTextures: per-boundary offscreen MSAA textures - compositeTextures: blit all textures via non-MSAA path - DrawChild skip (Flutter paintChild): child boundaries SKIPPED during parent recording, composed as separate textures - Compositor scissor clipping for ScrollView viewport - RepaintBoundary as WidgetBase property (ADR-024) - Spinner auto-boundary (indeterminate progress) - AnimationScheduler (Flutter scheduleFrame pattern) - Scrollbar Qt6 timing (500ms initial, 50ms repeat) - Upward dirty propagation to nearest boundary (O(depth))
- SVG icons in SceneCanvas via SVGRenderer + SVGFiller interfaces - CPU rasterization via RasterizerAnalytic (bypasses GPU queueing) - 2-level LRU IconCache: L1 parsed svg.Document, L2 rasterized scene.Image by (ptr, w, h, color) with 256-entry eviction. 7.5ms → <1µs per frame. - DPI-aware: render at ceil(logicalSize × deviceScale) physical pixels - DeviceScaler interface propagates scale to SceneCanvas - Qt6/Chromium/IntelliJ enterprise pattern
- CrossAxisAlignment for VBox/HBox: Center, Start, End, Stretch - Collapsible: header as internal widget for dirty tracking - Collapsible: TitleSignal + TitleReadonlySignal for reactive headers - TextField/Slider/LineChart: fill MaxWidth from constraints (was hardcoded) - Per-item InvalidateRect in ListView (not full bounds) - Leaf-dirty pattern in dirty collector - ScreenOriginBase on Canvas for screen-space dirty tracking
Six professional test suites: 1. MultiFrameSpinnerLifecycle — 5-frame simulation, per-frame invariants 2. DataTickerDoesNotTriggerOffscreenSpinnerRecording — isolation verified 3. BoundaryRecordingOrder_RootBeforeChildren — depth-first order 4. ScreenBoundsAccuracyAfterRecording — screen-space damage coords 5. CleanStateEarlyReturn — zero Draw calls on clean pass 6. VisibilityMatrix — 14 table-driven subtests (all positions) Plus: hover E2E, spinner E2E, DrawChild skip, compositor clip, boundary recording, screen origin, dirty overlay, first frame tests
- CHANGELOG: per-boundary GPU textures, 0% GPU idle, offscreen culling, SVG icons, DPI rendering, CrossAxisAlignment, 34 integration tests, damage rect fixes, pumper isolation, scrollbar Qt6 timing - ARCHITECTURE: production pipeline with frame skip + culling - ROADMAP: performance targets (0% idle achieved), new widget plans, optimization roadmap (LoadOpLoad P0, parent chain P1, Vello P3) - Test adaptations for new boundary/compositor infrastructure
Mark unused code with nolint:unused and task references: - compositor/ layer asContainer overrides (TASK-UI-OPT-005) - replayLayerTree in desktop.go (TASK-UI-OPT-005) - dirty collector debug field (enterprise logging) - testSceneRecorderForOriginTests (future test variants)
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
- desktop.go: nolint:gocyclo,nestif on render loop (pipeline orchestration) - desktop.go: ifElseChain → switch in compositeTextures - desktop.go: nolint:gocognit,nestif on renderBoundaryTexturesRecursive - listview: nolint:nestif on cache/widget (type assertion chains) - collector.go: nolint:nestif on viewport dirty collection - collapsible_test.go: preallocate texts slice - progress_test.go: remove empty if block - collector_test.go: remove unused x parameter - .golangci.yml: exclude tmp/ from analysis Result: golangci-lint v2.12.2 reports 0 issues.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
desktop.drawwhen nothing dirty. Offscreen boundary culling stops animation pumper. Verified on all 6 examples.GPU Performance (Intel Iris Xe)
Test plan
go build ./...— passgo test ./...— 56 packages, 0 FAILgolangci-lint run— 0 new issuesgo vet ./...— cleango mod verify— all modules verified