Skip to content

feat: vendor QSGBatchRenderer as WSGBatchRenderer - #1275

Open
zccrs wants to merge 2 commits into
linuxdeepin:masterfrom
zccrs:wsg-batch-renderer
Open

feat: vendor QSGBatchRenderer as WSGBatchRenderer#1275
zccrs wants to merge 2 commits into
linuxdeepin:masterfrom
zccrs:wsg-batch-renderer

Conversation

@zccrs

@zccrs zccrs commented Aug 13, 2026

Copy link
Copy Markdown
Member

Summary

  • Vendor Qt Quick's QSGBatchRenderer (qtdeclarative v6.11.1) into waylib as WSGBatchRenderer, with version gates so one copy builds against Qt 6.8.0, 6.11.x and 6.12.x.
  • Install WSGContext on QQuickRenderControlPrivate::sg before any QQuickRenderControl is constructed, so the RHI window renderer and extra sources come from the fork via createRenderer().
  • Leave the software backend on Qt's own scene graph adaptation. This PR does not add damage tracking and does not strip opaque/alpha/depth.

Test plan

  • CI configure/build on the default Qt preset and clang/ci presets if they run
  • tinywl-qtquick on the default RHI backend: windows, titlebar, lockscreen, overview, Blur/Glass
  • QT_QUICK_BACKEND=software: software path unchanged, no crash on RenderControl creation
  • Creating a QQuickRenderControl before WOutputRenderWindow fatals (WSGContext must be installed first)

Benchmark

glmark2-es2-wayland, 800×600 windowed, 2s per scene (not the official 10s run). Same GLES client against compositor WLR_RENDERER=gles2|vulkan. WLR_SCENE_DISABLE_DIRECT_SCANOUT=1. Intel Arc Pro (ARL), Mesa 24.3. Isolated builds under ~/tmp/glmark-bench/, no system install.

Overall score (higher is better):

Compositor GLES Vulkan
tinywl (wlroots C) 4658 4570
WSG treeland (this PR) 4203 4449
Qt-native treeland (pre-WSG) 3574 3987
  • WSG vs tinywl: GLES 90%, Vulkan 97%
  • WSG vs Qt-native: GLES +18%, Vulkan +12%

Per scene (FPS)

Scene tinywl GLES tinywl VK WSG GLES WSG VK Qt-native GLES Qt-native VK
build use-vbo=false 4152 4111 3761 3463 3479 3358
build use-vbo=true 4669 4652 3592 4115 3679 3858
texture nearest 4401 4448 3735 4398 3313 4171
texture linear 4432 4252 3456 4237 3479 4162
texture mipmap 4287 4255 3686 4356 3448 4191
shading gouraud 3956 4044 3606 3966 3192 3622
shading blinn-phong-inf 3759 4000 3480 3770 3252 3430
shading phong 4084 3950 3419 3714 3110 3511
shading cel 3954 3956 3489 3984 3148 3456
bump high-poly 3539 4015 3298 3788 2950 3256
bump normals 7017 7268 6991 7550 4733 6545
bump height 6042 6566 5782 6257 3762 5653
effect2d laplacian 5487 5577 4098 4353 3169 4299
effect2d box 3935 4412 3613 3908 2865 3805
pulsar 7046 6933 6392 7186 4395 6502
desktop blur (4 windows) 2935 2851 2779 2767 2515 2659
desktop shadow (4 windows) 3447 4725 4008 4618 2972 3558
buffer map update 938 1149 1033 1124 895 829
ideas 2991 2704 3156 2800 3037 2738
jellyfish 3340 3331 3258 3072 2977 3034
terrain 672 655 641 582 641 577
shadow 5116 5078 5458 3737 3620 3720
refract 1857 1770 1809 1694 1778 1722
conditionals fs=0 vs=0 6876 6500 5927 6817 5686 6663
conditionals fs=5 vs=0 6686 6496 5433 6715 5803 6595
conditionals fs=0 vs=5 6895 5763 6690 6744 6097 6365
function low 6516 5950 5828 6554 6576 4745
function medium 5925 5621 5460 5608 5182 4534
loop no-frag-loop 6693 5564 5387 5792 4055 4338
loop uniform=false 6341 5213 5532 5538 3757 3956
loop uniform=true 6456 5900 5534 4768 3280 3793
glmark2 Score 4658 4570 4203 4449 3574 3987

tinywl GLES logged Atomic commit failed: Device or resource busy mid-run; all 31 scenes still recorded.

Summary by Sourcery

Vendor and integrate a Waylib scene-graph renderer with end-to-end partial-damage tracking, preserved-buffer rendering, and runtime diagnostics while retaining Qt's software path.

New Features:

  • Vendor a Waylib-specific Qt Quick batch renderer with compatibility across supported Qt 6 versions.
  • Add runtime damage-debug modes with highlighting, logging, forced rerendering, and a damage visualization playground.
  • Expose damage-aware rendering for Wayland surface content, cursors, effects, popups, and recycled output buffers.

Bug Fixes:

  • Prevent Qt's default scene graph context from being created before Waylib installs its renderer factory.
  • Preserve software rendering on Qt's native adaptation while avoiding crashes during render-control creation.
  • Avoid stale pixels and unnecessary full-output redraws when rendering partial damage into preserved buffers.

Enhancements:

  • Track scene-graph damage across item changes, transforms, effects, surface commits, and output coordinate transforms.
  • Use renderer-reported flush regions to drive wlroots output damage and GPU scissoring.
  • Provide explicit image-node damage propagation for Wayland surface updates.

Build:

  • Add the vendored scene-graph renderer, damage components, examples, and unit-test targets to the build.

Documentation:

  • Document the vendored renderer source, Qt version gates, local adaptations, damage behavior, upgrade process, and test procedures.

Tests:

  • Add unit, scene-level, visual, cursor, effect, compositor-idle, and client-commit damage coverage across supported RHI and wlroots backends.

Chores:

  • Add Qt-compatible DRM image format handling and minor source metadata updates.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @zccrs, your pull request is larger than the review limit of 150000 diff characters

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: zccrs

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai

sourcery-ai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Reviewer's Guide

Vendors Qt Quick’s QSGBatchRenderer into waylib as WSGBatchRenderer, wires it through a custom scene graph context (WSGContext) so QQuickRenderControl and window renderers use the fork, and updates the existing buffer/render paths to depend on WSGBatchRenderer while preserving the software backend and adding version/ABI guards.

Sequence diagram for installing WSGContext before QQuickRenderControl creation

sequenceDiagram
    actor App
    participant WOutputRenderWindow
    participant WSGContext
    participant QQuickRenderControlPrivate
    participant WSGRenderContext
    participant WSGBatchRenderer_Renderer

    App->>WOutputRenderWindow: constructor
    WOutputRenderWindow->>WSGContext: ensureInstalled()
    WSGContext->>QQuickRenderControlPrivate: check sg
    alt sg is null or QSGDefaultContext
        WSGContext->>QQuickRenderControlPrivate: sg = new WSGDefaultContext
    else sg is nondefault
        WSGContext-->>QQuickRenderControlPrivate: keep existing sg
    end
    WOutputRenderWindow->>WOutputRenderWindow: createOutputRenderControl()
    WOutputRenderWindow->>QQuickRenderControlPrivate: new RenderControl()
    QQuickRenderControlPrivate->>WSGRenderContext: createRenderContext()
    WSGRenderContext->>WSGBatchRenderer_Renderer: createRenderer(RenderMode2D)
    WSGBatchRenderer_Renderer-->>WSGRenderContext: Renderer instance
Loading

File-Level Changes

Change Details Files
Vendor QSGBatchRenderer into waylib as WSGBatchRenderer with RHI visualizer and version-gated compatibility helpers.
  • Add WSGBatchRenderer::Renderer implementation and supporting types, copied from Qt’s QSGBatchRenderer and adapted to a new namespace and headers.
  • Introduce wsgrhivisualizer as the visualizer backend for WSGBatchRenderer, mirroring Qt’s RHI visualization helpers.
  • Provide local implementations for non-exported helpers (sampler description compare/hash, env int, mutability group access) and remove Qt-only export macros while keeping ABI compatibility across Qt 6.8/6.11/6.12.
waylib/src/server/qtquick/scenegraph/wsgbatchrenderer.cpp
waylib/src/server/qtquick/scenegraph/wsgbatchrenderer_p.h
waylib/src/server/qtquick/scenegraph/wsgrhivisualizer.cpp
waylib/src/server/qtquick/scenegraph/wsgrhivisualizer_p.h
waylib/src/server/qtquick/scenegraph/README.md
Install WSGContext as the global scene graph context so QQuickRenderControl uses WSGBatchRenderer-based renderers on the RHI backend.
  • Implement WSGContext with a custom QSGDefaultContext/QSGDefaultRenderContext subclass that overrides createRenderer() to return WSGBatchRenderer::Renderer.
  • Hook WSGContext::ensureInstalled() into WOutputRenderWindow construction via a factory for QQuickRenderControl, and into WRenderHelper::getGraphicsApi() to ensure the temporary render control uses the forked scene graph.
  • Guard installation so non-QSGDefaultContext adaptations (e.g. software backend) continue to use Qt’s own scene graph implementation and add fatal logging when WSGContext is installed too late.
waylib/src/server/qtquick/scenegraph/wsgcontext.cpp
waylib/src/server/qtquick/scenegraph/wsgcontext_p.h
waylib/src/server/qtquick/woutputrenderwindow.cpp
waylib/src/server/qtquick/wrenderhelper.cpp
Switch existing buffer rendering paths from QSGBatchRenderer to WSGBatchRenderer and simplify private member access.
  • Replace includes of qsgbatchrenderer_p.h with wsgbatchrenderer_p.h in buffer/render paths and adjust type names from QSGBatchRenderer::Renderer to WSGBatchRenderer::Renderer.
  • Update rendererShaderManager and rendererUseDepthBuffer helpers to use WSGBatchRenderer’s public API instead of template-based private member access hacks.
  • Update WBufferRenderer state and APIs to track WSGBatchRenderer::Renderer and change dynamic_casts in render flows and RhiManager to expect WSGBatchRenderer.
  • Adjust batch detection and depth-test logic to rely on WSGBatchRenderer::Renderer while preserving existing behavior for non-batch renderers.
waylib/src/server/qtquick/private/wrenderbuffernode.cpp
waylib/src/server/qtquick/private/wbufferrenderer.cpp
waylib/src/server/qtquick/private/wbufferrenderer_p.h
Wire the new scenegraph sources and headers into the build and include paths.
  • Add wsgbatchrenderer, wsgrhivisualizer, and wsgcontext source files to the server target’s SOURCES list.
  • Add corresponding private headers to PRIVATE_HEADERS and extend target_include_directories to include the qtquick/scenegraph directory.
  • Ensure the waylib server build sees the new scenegraph code alongside existing Qt private includes.
waylib/src/server/CMakeLists.txt

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@zccrs
zccrs force-pushed the wsg-batch-renderer branch from 1e310ab to b53de02 Compare August 14, 2026 06:48
@deepin-bot

deepin-bot Bot commented Aug 14, 2026

Copy link
Copy Markdown

TAG Bot

New tag: 0.8.18
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1286

@zccrs
zccrs force-pushed the wsg-batch-renderer branch 3 times, most recently from 2815e84 to f91d626 Compare August 14, 2026 09:04
@LFRon

LFRon commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

大佬今天能合入嘛(
看着是大佬说的QML画布局部更新的实现诶

@zccrs

zccrs commented Aug 14, 2026

Copy link
Copy Markdown
Member Author

大佬今天能合入嘛( 看着是大佬说的QML画布局部更新的实现诶

今天肯定不行,本月能合入就不错了。

Comment thread waylib/src/server/qtquick/private/wbufferrenderer.cpp Outdated
Comment thread waylib/src/server/qtquick/private/wbufferrenderer.cpp Outdated
Comment thread waylib/src/server/qtquick/wrenderhelper.cpp Outdated
Comment thread waylib/src/server/utils/wbufferdumper.cpp
@zccrs
zccrs force-pushed the wsg-batch-renderer branch 3 times, most recently from 7c799c8 to 76f4495 Compare August 17, 2026 05:24
@LFRon

LFRon commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

大佬, 这个跑分

glmark2-es2-wayland, 800×600 windowed, 2s per scene (not the official 10s run). Same GLES client against compositor WLR_RENDERER=gles2|vulkan. WLR_SCENE_DISABLE_DIRECT_SCANOUT=1. Intel Arc Pro (ARL), Mesa 24.3. Isolated builds under ~/tmp/glmark-bench/, no system install.

个人认为体现的作用不大, 因为它超出了实际显示器的极限帧率太多, 以至于性能瓶颈几乎不在GPU上, 这边建议跑毒蘑菇这样榨干显卡的, 预设设置为高即可: https://www.volumeshader.dev/zh-CN/gpu-test

@zccrs
zccrs force-pushed the wsg-batch-renderer branch from 76f4495 to 1c30c5a Compare August 17, 2026 09:19
1. Vendor qtdeclarative v6.11.1 QSGBatchRenderer/QSGRhiVisualizer
   into waylib as WSGBatchRenderer, version-gated for Qt 6.8-6.12.
2. Install WSGContext as QQuickRenderControlPrivate::sg before any
   QQuickRenderControl so RHI createRenderer() returns the fork.
3. Route extra sources and WRenderBufferNode through createRenderer();
   keep the software backend on Qt's own scene graph adaptation.

Log: RHI path uses a vendored Scene Graph batch renderer. No
user-facing changes yet; damage tracking is not in this step.

Influence:
1. Launch tinywl-qtquick on the default RHI backend and verify
   windows, titlebar, lockscreen, overview, Blur/Glass still render.
2. Run with QT_QUICK_BACKEND=software and confirm the software path
   is unchanged and RenderControl creation does not crash.
3. Confirm that creating a QQuickRenderControl before
   WOutputRenderWindow fatals with the WSGContext install error.

feat: 将 Qt BatchRenderer 以 WSGBatchRenderer 接入 RHI

1. 从 qtdeclarative v6.11.1 引入 QSGBatchRenderer/QSGRhiVisualizer,
   命名空间改为 WSGBatchRenderer,并用版本宏兼容 Qt 6.8-6.12。
2. 在任何 QQuickRenderControl 构造前安装 WSGContext 覆盖 sg,
   使 RHI 路径的 createRenderer() 直接创建 fork。
3. extra source 与 WRenderBufferNode 改为走 createRenderer();
   software 仍使用 Qt 自己的 scene graph adaptation。

Log: RHI 路径改用自带的 Scene Graph batch renderer。暂无用户可见
变化,本步未做 damage tracking。

Influence:
1. 用默认 RHI 启动 tinywl-qtquick,检查窗口、标题栏、锁屏、多任务、
   Blur/Glass 绘制是否正常。
2. 设置 QT_QUICK_BACKEND=software,确认 software 路径不变、不崩溃。
3. 若在 WOutputRenderWindow 之前创建 QQuickRenderControl,应 qFatal。
@zccrs
zccrs force-pushed the wsg-batch-renderer branch from 1c30c5a to 553a89f Compare August 18, 2026 01:40
1. Add WSGDamageTracker that unions dirty node AABBs into flushRegion,
   and WSGDamageNode so surface content damage is not the full quad.
2. Resolve DontCare to Preserve (wlroots LOAD). GLES and Vulkan both
   redraw ring-stale pixels under per-rect GPU scissors, with no blit.
3. Highlight overlay is red for this frame and shifts to green for
   older frames; WAYLIB_DEBUG_DAMAGE and the debug menu switch modes.
4. Add tracker, QML scene, and visual overlay tests for GLES and Vulkan.

Log: Partial redraw follows Scene Graph damage. Debug highlight can
show refresh regions (red current, green older) via WAYLIB_DEBUG_DAMAGE.

Influence:
1. Run test_wsgdamage and test_wsgdamage_visual (gles2 and vulkan).
2. Set WAYLIB_DEBUG_DAMAGE=highlight, move a window: this frame is red,
   fading older rects shift toward green and disappear after 250ms.
3. Use the debug menu Damage entry (Off/Highlight/Log/Rerender) and
   confirm leftover overlay is erased after switching Off.
4. After a highlight, idle frames should not full-screen flicker.

feat: 跟踪场景图 damage 并按区域裁剪 GPU 重绘

1. 新增 WSGDamageTracker,将脏节点 AABB 合并进 flushRegion;
   WSGDamageNode 让 surface 内容损坏不再整块四边形刷新。
2. DontCare 默认 Preserve(对齐 wlroots LOAD)。GLES 与 Vulkan 都在
   按矩形 GPU scissor 下重画 ring 过期像素,不再 copy 上一帧。
3. Highlight 本帧为红、更旧帧过渡到绿;WAYLIB_DEBUG_DAMAGE 与
   调试菜单可切换 none/highlight/log/rerender。
4. 增加 tracker、QML 场景和 overlay 像素测试(gles2/vulkan)。

Log: 局部重绘跟随场景图 damage。可通过 WAYLIB_DEBUG_DAMAGE 用
红(本帧)到绿(旧帧)高亮刷新区域。

Influence:
1. 运行 test_wsgdamage 与 test_wsgdamage_visual(gles2 和 vulkan)。
2. 设置 WAYLIB_DEBUG_DAMAGE=highlight,移动窗口:本帧红色,
   旧区域变绿并在 250ms 后消失。
3. 用调试菜单 Damage(Off/Highlight/Log/Rerender),确认 Off 后
   残留 overlay 被擦掉。
4. highlight 之后的空闲帧不应整屏闪烁。
@zccrs
zccrs force-pushed the wsg-batch-renderer branch from 553a89f to 7f6b59f Compare August 18, 2026 03:13
@LFRon

LFRon commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

我弄了个review, 希望对大佬有帮助(08/19跑的):
review1.md

08/20跑的:
review2.md

@deepin-bot

deepin-bot Bot commented Aug 21, 2026

Copy link
Copy Markdown

TAG Bot

New tag: 0.9.0
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1312

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.

3 participants