Skip to content

Add PAGXOptimizer for PAGX structure simplification#3393

Open
OnionsYu wants to merge 29 commits intoTencent:mainfrom
OnionsYu:feature/onionsyu_pagx_verify2
Open

Add PAGXOptimizer for PAGX structure simplification#3393
OnionsYu wants to merge 29 commits intoTencent:mainfrom
OnionsYu:feature/onionsyu_pagx_verify2

Conversation

@OnionsYu
Copy link
Copy Markdown
Contributor

@OnionsYu OnionsYu commented Apr 17, 2026

新增 PAGXOptimizer 模块,用于自动简化 PAGX 文件结构(解包冗余 Group、合并可合并节点等)。

主要变更:

  • 新增 PAGXOptimizer 类及其公开 API,支持多种结构简化选项
  • 提取共享的 verify 工具函数到 VerifyUtils
  • 改进 SVG 导入保真度,跳过影响渲染结果的优化并保留小数精度
  • 新增 PAGXOptimizer 相关测试用例

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 17, 2026

Codecov Report

❌ Patch coverage is 87.40741% with 221 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.85%. Comparing base (96a6e0a) to head (362517f).

Files with missing lines Patch % Lines
src/pagx/PAGXOptimizer.cpp 76.56% 86 Missing and 109 partials ⚠️
test/src/PAGXOptimizerTest.cpp 98.09% 6 Missing and 9 partials ⚠️
src/pagx/utils/StringParser.cpp 76.47% 1 Missing and 3 partials ⚠️
src/cli/CommandImport.cpp 25.00% 2 Missing and 1 partial ⚠️
src/cli/CommandResolve.cpp 25.00% 2 Missing and 1 partial ⚠️
src/cli/CommandVerify.cpp 92.85% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3393      +/-   ##
==========================================
+ Coverage   78.41%   78.85%   +0.43%     
==========================================
  Files         532      540       +8     
  Lines       41448    43109    +1661     
  Branches    12486    12860     +374     
==========================================
+ Hits        32502    33993    +1491     
- Misses       6391     6454      +63     
- Partials     2555     2662     +107     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@OnionsYu OnionsYu force-pushed the feature/onionsyu_pagx_verify2 branch from 55a1c0d to 8df6c42 Compare April 17, 2026 12:36
@OnionsYu OnionsYu force-pushed the feature/onionsyu_pagx_verify2 branch from d04ef06 to 7055b85 Compare April 20, 2026 02:06
@OnionsYu OnionsYu force-pushed the feature/onionsyu_pagx_verify2 branch from 702f412 to 66de2e5 Compare April 20, 2026 02:52
@OnionsYu OnionsYu changed the title Add PAGXOptimizer and optimize CLI subcommand for PAGX structure simplification Add PAGXOptimizer for PAGX structure simplification Apr 20, 2026
Copy link
Copy Markdown
Collaborator

@shlzxjp shlzxjp left a comment

Choose a reason for hiding this comment

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

初次评审反馈:新增 PAGXOptimizer 模块整体思路清晰,保守性原则和幂等保证都到位。以下是按严重度梳理的 Blocker / Major 问题行级评论,建议合入前优先处理。Minor/Nit 级别的问题后续单独提。

Comment thread src/pagx/svg/SVGImporter.cpp Outdated
Comment thread src/pagx/PAGXOptimizer.cpp Outdated
Comment thread include/pagx/PAGXOptimizer.h Outdated
Comment thread include/pagx/PAGXOptimizer.h Outdated
Comment thread src/cli/CliUtils.h
Comment thread test/src/PAGXOptimizerTest.cpp
Comment thread src/cli/CommandResolve.cpp Outdated
Comment thread src/pagx/PAGXOptimizer.cpp Outdated
…sk canonicalization, and expand option coverage tests.
…_verify2

# Conflicts:
#	src/cli/CliUtils.cpp   resolved by feature/onionsyu_pagx_verify2 version
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread include/pagx/PAGXOptimizer.h Outdated
Comment thread src/pagx/PAGXOptimizer.cpp Outdated
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread src/pagx/utils/VerifyUtils.h
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread test/src/PAGXOptimizerTest.cpp
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread src/cli/CommandVerify.cpp
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread test/src/PAGXOptimizerTest.cpp
@shlzxjp
Copy link
Copy Markdown
Collaborator

shlzxjp commented Apr 24, 2026

[Nit] 新 N4 — test/baseline/version.json 的 8 条 baseline 更新建议拆 commit

commit 1dfc758066de2e53test/baseline/version.json 里同时更新了 8 条 baseline key,混合了两类原因:

  1. FloatToString 精度修复(由 commit 5e975393 引起的 SVG 精度保真)
  2. PAGXOptimizer 接入 SVGToPAGXAll 后的结构变化(由 commit 189ecde0 / b7b8b60 引起)

两类变更的回归风险不同(前者是数值精度级别、后者是结构级别),混在一个 version bump 里 bisect 或回滚都不便。

建议(下次类似变更时): 把"精度修复"与"结构优化"的 baseline 更新拆成独立 commit,方便未来 git bisect

Comment thread test/src/PAGXOptimizerTest.cpp
@OnionsYu OnionsYu force-pushed the feature/onionsyu_pagx_verify2 branch 3 times, most recently from 578e89f to 52effa1 Compare April 27, 2026 04:44
Comment thread include/pagx/PAGXOptimizer.h Outdated
Comment thread include/pagx/PAGXOptimizer.h Outdated
Comment thread src/pagx/PAGXOptimizer.cpp Outdated
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread src/cli/CommandImport.cpp Outdated
Comment thread src/cli/CommandResolve.cpp Outdated
Comment thread src/pagx/utils/StringParser.cpp
Comment thread src/pagx/utils/VerifyUtils.cpp Outdated
Comment thread src/pagx/PAGXOptimizer.cpp Outdated
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread src/pagx/PAGXOptimizer.cpp
Comment thread src/pagx/PAGXOptimizer.cpp Outdated
return false;
}

bool LayoutNodeHasConstraints(const LayoutNode* node) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LayoutNodeHasConstraints 遗漏了 percentWidth/percentHeight 检查。Path 和 Rectangle 都继承自 LayoutNode,该基类含 float percentWidth = NANfloat percentHeight = NAN 字段。当一个 Path 设了 percentWidth=50 但 6 个约束字段都是 NaN 时,此函数返回 false,导致 TryCanonicalizePath 将其错误改写为固定尺寸 Rectangle,丢失 percent 布局语义。同理影响 TryConvertRectMaskToScrollRect

LayoutNode 自身已有 hasConstraints() 方法(src/pagx/LayoutNode.cpp:35-38)正确包含了 percent 检查,建议直接复用 node->hasConstraints() 替代此手写版本。

if (group->skewAxis != 0) {
return false;
}
if (!std::isnan(group->width) || !std::isnan(group->height)) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

IsDefaultTransformGroup 同样遗漏了 percentWidth/percentHeight 检查。Group 继承自 LayoutNode,如果 Group 设了 percentWidth=50width 为 NAN,此函数会误判为 default-transform group,导致 UnwrapRedundantFirstGroupMergeAdjacentGroups 错误处理(展开或合并携带 percent 布局语义的 Group)。

建议补充:

if (!std::isnan(group->percentWidth) || !std::isnan(group->percentHeight)) return false;

if (layer->mask != nullptr) {
return true;
}
if (layer->maskType != MaskType::Alpha) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

maskType 检查未绑定 mask 指针存在性。当 mask == nullptr && maskType != Alpha 时(可能由构造器默认值异常或未来代码路径解除 mask 后残留),此条件仍返回 true,永久阻止该 Layer 被识别为 shell。

建议改为:

if (layer->mask != nullptr && layer->maskType != MaskType::Alpha) return true;

即把 maskType 的语义绑定到 mask != nullptr 时才生效。


// ============================================================================
// Local helpers. `HasLayerOnlyFeatures`, `IsLayerShell`, `IsPainter`, and
// `HasPainter` are the shared definitions from pagx/utils/VerifyUtils.h
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

注释表达方向有误。当前措辞像是 optimizer 是 VerifyUtils 的使用方、verify/resolve 是"源头"。实际这些谓词是共享定义,optimizer 也是定义方之一。

建议改为:// Shared layer/element classification predicates — single source-of-truth in pagx/utils/VerifyUtils.h, used by verify, resolve, and optimizer.

// Layer -> Group conversion
// ----------------------------------------------------------------------------

// Wraps a downgradable shell Layer's contents in a new Group, transferring customData. The
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

注释 "caller is responsible for releasing the old Layer reference" 不准确。doc->nodes 仍通过 unique_ptr 持有该 Layer,调用方不能也不应该释放它。实际语义是调用方须将 Layer 从拥有它的 layers/children 向量中移除。

建议改为:// Wraps a downgradable shell Layer's contents in a new Group, transferring customData. Caller must have verified the layer is downgradable and is responsible for removing it from the owning list.

* Number of rule iterations actually executed (both on the root layer list and on each
* Composition's layer list). Useful as a monotonic signal for regression / telemetry.
*/
int iterationsUsed = 0;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

iterationsUsed 是所有 layer list(root + 每个 Composition)的累加值,但 maxIterations 是每段独立上限。建议注释中明确此为累加值,不可直接与单段阈值比较:

// Cumulative iteration count across all layer lists (root + each Composition).
// Not directly comparable to any single-segment cap; use `converged` for the
// convergence signal instead.

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