Skia 与 Chromium 协同落地:Blink 布局测试重基线(Rebaseline)操作指南
图形学图像处理【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images.项目地址https://gitcode.com/gh_mirrors/skia1/skia点击查看免费下载本篇指南基于 Skia 官方开发者文档系统讲解“如何让一个会改变 Blink 布局测试结果的 Skia 变更安全落地”。读完本文你将掌握两条落地路径——小范围测试改动少于约 20 个用例的免协调重基线流程以及大范围渲染改动所依赖的SK_IGNORE_xxx_FIX代码抑制code suppression机制并理解 Skia 自动滚入rollChromium 这一底层协作模型的来龙去脉。背景Skia 变更为什么会“炸”到 Blink 布局测试Skia 是 Chromium 的 2D 渲染引擎二者通过自动滚动roll机制保持同步Skia 仓库的提交会由Auto Roll Bot即skia-deps-roller每天多次自动滚入 Chromium 的DEPS也可以手动触发。因此 Skia 侧的每一个像素级渲染差异最终都会在 Chromium 侧的 Blink 布局测试third_party/blink/web_tests/TestExpectations所管理的那套 WebKit 布局测试上体现出来布局测试的核心产物是截图比对只要 Skia 的绘制行为变化抗锯齿、抖动、光栅化策略等大量布局测试的期望图像就会失配Chromium.WebKit树随之变红文档给出的关键决策阈值是约 20 个测试用例影响更少可以自行重基线影响更多则必须引入代码抑制并通知 Blink gardener。这一阈值划分是整个流程的骨架下面分别展开。相关上游文档见 Skia 变更如何同步到 Chromium 与 Skia 在 Chrome 中的分支与滚动。路径 A影响少于约 20 个布局测试——免协调重基线原文档明确指出影响少于约 20 个布局测试结果的变更无需与 Blink gardener 特别协调按以下五步操作即可准备 Skia 变更并记录哪些布局测试会转红。Skia 本地可通过自身的 GM 测试与 SkiaGold 比对预判Chromium 侧的布局测试运行细节属于 Blink 仓库范畴文档在此只给出“先预判红名单”这一要求。把代码提交到 Skia 仓库。在包含该变更的 Skia 自动 roll 之前手动向 Blink 的LayoutTests/TestExpectations文件推送一个变更把因你的改动而预期失败的测试标记出来。标记语法为foo/bar/test-name.html [ Failure Pass ] # Needs rebaseline这条期望行的含义是该测试当前会失败Failure在重基线完成后应当通过Pass尾部注释说明这是“待重基线”条目。等待 Skia roll 成功落地。此时 Blink 树不会因你的变更而变红因为期望文件已经声明了这些失败是预期内的。再提交一个 BlinkTestExpectations变更移除你在第 3 步添加的所有跳过的测试期望并运行git cl rebaseline该命令会触发自动重基线机器人由它自动把新的期望图像 check in完成图像基线更新。整条路径的精髓在于时序控制TestExpectations 的声明必须先于或恰好在Skia roll 落地前生效让 roll 通过 CQ 时布局测试不会大面积变红roll 落地后再撤销期望并交给 rebase bot 自动更新图像。路径 B影响超过约 20 个测试——代码抑制 重基线 清理三段式当“大范围”指超过约 20 个测试时直接改图会导致Chromium.WebKit树在较长时间内大面积变红必须走更严谨的三段式流程Setup设置代码抑制→ Rebaseline重基线→ Cleanup清理。基本概念代码抑制code suppression即一个编译开关build flag又称 define用来在 Chromium 侧暂时屏蔽新渲染路径、保留旧行为命名规范抑制开关必须命名为SK_IGNORE_xxx_FIX形式FIX后缀提示该开关是临时性的重基线后必须移除roll 的含义更新 Chromium 中 Skia 版本的动作称为 roll由 Auto Roll Bot 每天自动执行多次也可手动执行对应skia-deps-roller的 DEPS 变更。代码抑制在 Skia 源码中的真实形态文档要求“把变更放在代码抑制后面”即新代码路径用#ifdef / #ifndef包裹Chromium 侧不定义该宏时行为与旧版本完全一致。当前 Skia 仓库中就有多个这样的存量开关可作为写代码时的直接参照src/core/SkBitmapDevice.cpp 中SK_IGNORE_BLURRED_RRECT_OPT包裹了drawRRect的优化路径——定义该宏则回退到通用的drawPath分支void SkBitmapDevice::drawRRect(const SkRRect rrect, const SkPaint paint) { #ifdef SK_IGNORE_BLURRED_RRECT_OPT // call the VIRTUAL version, so any subclasses who do handle drawPath arent // required to override drawRRect. this-drawPath(SkPath::RRect(rrect), paint, true); #else LOOP_TILER( drawRRect(rrect, paint), Bounder(rrect.getBounds(), paint)) #endif }src/gpu/DitherUtils.h 用#ifndef SK_IGNORE_GPU_DITHER把 GPU 抖动相关的整组声明DitherRangeForConfig、MakeDitherLUT包裹起来对应的实现侧 src/gpu/DitherUtils.cpp、src/gpu/ganesh/SkGr.cpp 以及 Graphite 侧的 src/gpu/graphite/PaintParams.cpp、src/gpu/graphite/precompile/PaintOption.cpp 也以同样的#ifndef对称包裹。这种“头文件与实现同时用相同宏包裹”的写法保证了Chromium 定义SK_IGNORE_GPU_DITHER后新路径的声明与实现一起消失旧版 Chromium 代码不会因链接缺失或符号冲突而出错。编写自己的SK_IGNORE_xxx_FIX时应对齐这一模式。Setup三种情形下的初始化步骤情形一抑制尚不存在——直接法Direct method在 Skia 中做出会改变大量 Blink 布局测试的变更将该变更放在代码抑制SK_IGNORE_xxx_FIX之后把变更 check in 到 Skia 仓库手动 roll Skia或给 autoroll 追加代码抑制——即把它写进 Chromium 的skia/chromium_skia_defines.gypi。情形二抑制尚不存在——替代法Alternate method先在 Chromium 的skia/chromium_skia_defines.gypi中加上代码抑制再动 Skia 代码在 Skia 中做出会改变大量布局测试的变更把变更放在代码抑制后面把变更 check in 到 Skia 仓库等待 Skia roll 进 Chromium。两种写法的差异只在时序直接法让 Skia 先落地、roll 时带上 define替代法让 define 先落地roll 到 Chromium 后新代码自然被抑制。两者终态相同。情形三抑制已存在于头文件中从 Chromium 的头文件中移除该代码抑制同时把它加入skia/chromium_skia_defines.gypi原文档特别警告代码抑制不能同时存在于头文件和 gyp 文件的 define 中否则会产生“多重定义”警告而在 Chromium 构建中这类警告会被当作错误直接打断整个 Chromium 构建。这一约束与 Skia 与 Chromium 的 API 同步策略 中关于“code suppression cannot exist in both the header file and the gyp file, it should only reside in one location”的描述完全一致说明 define 的存放位置是全局唯一归属问题而非简单便利问题。Rebaseline重基线窗口期的操作选择 Blink 树安静的时段操作尤其避开 PST 下午改动越大这一点越重要。无论如何都要确认当值 Blink gardener 是谁并事先通知——你会让Chromium.WebKit树变红一段时间gardener 需要知道这不是他要修的故障。提交一个同时做两件事的 CL从 Chromium 的skia/chromium_skia_defines.gypi中移除代码抑制同时向 Blink 的LayoutTests/TestExpectations添加[ NeedsRebaseline ]期望行。之后自动重基线机器人会负责把新图像 check in。原文档给出的规模指引是大约600 张以内需要重基线的图像走这套自动化流程是普遍可接受的超过 600 张时仍可用[ NeedsRebaseline ]但最好与 gardener 协调。该 CL 应当能干净地通过 CQ。小心本来就失败或不稳定flaky的测试它们是否需要重基线是不确定的而 flaky 测试无论如何都不应从 TestExpectations 中移除。遇到这类情况在提交前先回退revert你对 TestExpectations 的改动。如果清理步骤不由你负责请按以下模板开一个 Skia Issue 交给负责人标题Remove code suppression SK_IGNORE_xxx_FIX.描述Code suppression SK_IGNORE_xxx_FIX rebaselined with Blink revision 123456.并 assign 给负责清理的那个人。Cleanup清理从 Skia 中删除已经不再使用的旧代码以及当初为抑制新代码而引入的所有 define把清理变更 check in 到 Skia 仓库等待 Skia roll 进 Chromium。至此SK_IGNORE_xxx_FIX从“临时脚手架”完成它的生命周期。可以推断正是这个“Issue 跟踪 最终移除”的闭环使得仓库里存活的SK_IGNORE_*宏数量有限且都可追溯到具体变更如上文SK_IGNORE_BLURRED_RRECT_OPT、SK_IGNORE_GPU_DITHER即为其产物。配套能力在 trybot 上联调 Skia Chromium/Blink 改动上述流程的前提是“能在提交前验证 Skia 变更在 Chromium 中的表现”。多仓库 Chromium trybot 指南 提供了配套的验证手段只有 Skia 改动Skia 补丁已在 Gerrit 上时直接跑 Chromium trybot 即可机器人会应用该 Skia 补丁Skia Chromium 改动在 Chromium CL 的chromium/src/DEPS的hooks数组中加fetch_custom_patchapply_custom_patch两个钩子从 Gerrit 的refs/changes/XX/YYYY/ZZfetch 并 cherry-pick Skia 补丁让 trybot 在 Skia 补丁之上跑测试本地验证时运行gclient runhooks拉取 Skia 源码若third_party/skia工作区不干净已打过补丁需先在该目录执行git reset --hard再运行gclient runhooks上传 Chromium CL 时用常规git cl upload但要在 issue 描述中加COMMITfalse避免误提交。对于无法走 DEPS 钩子的任意文件改动文档还给出了把文件拷入chromium/src/patch/并按 Chromium 目录结构覆盖的兜底方案。出问题时roll 失败、回滚与树管理重基线流程发生在 Skia roll 与 Chromium 树的交汇处失败时的处置方式在 Skia 文档体系中有明确对应Skia 在 Chrome 的分支与滚动 说明roll 出问题时应到 autoroll 页面暂停新 roll、revert 有问题的 DEPS roll找不到 owner 时指派给 Skia Gardener列于 status.skia.org 的 gardeners 组件中Skia 日常维护gardening文档 明确指出DEPS roll 落地失败的常见原因就是布局测试——检查 DEPS roll 的 commit 哈希区间找到肇事的 Skia CL 并 revert或联系作者如果 Skia CL 改变了布局测试但新图像看起来正确则测试需要重基线并给出了两条操作路径编辑 Chromium 侧的skia/skia_test_expectations.txt较快、但文档标注为不推荐或提交单独的 Blink 补丁编辑LayoutTests/TestExpectations推荐但更慢。此外还给出了创建 “Skia image rebaseline” Chromium bug 的完整模板标签需包含OS-All与Cr-Blink-LayoutTests滤镜相关改动需 cc 特定同学。注意这两条路径与本文主线文档的关系gardening 文档面向“roll 已经红了、需要灭火”的场景而blink.md面向“我要主动发起一个已知会改变渲染的变更”的场景——后者通过代码抑制和[ NeedsRebaseline ]预期行本质上就是为了避免进入前者的救火状态。决策速查变更规模是否需要通知 gardener核心机制关键动作少于约 20 个布局测试否TestExpectations期望行roll 前加foo/bar/test.html [ Failure Pass ] # Needs rebaselineroll 后移除并git cl rebaseline超过约 20 个布局测试是SK_IGNORE_xxx_FIX代码抑制Setupdefine 写入skia/chromium_skia_defines.gypi且不得与头文件重复→ Rebaseline移除 define 加[ NeedsRebaseline ]约 600 张以内自动化可接受→ Cleanup删旧码与 define开 Skia Issue 跟踪无论哪条路径时序纪律都是成败关键期望声明要跑在 roll 变红之前define 的增删要成对出现清理必须闭环。按这套流程操作一个像素级的 Skia 变更就能在 Chromium 庞大的布局测试体系下平稳落地。赞分享图形学图像处理【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images.项目地址https://gitcode.com/gh_mirrors/skia1/skia点击查看免费下载相关推荐miniblink49 中 Skia 变更与 Blink 布局测试Layout Tests的提交协作指南miniblink49 中 Skia 变更与 Blink 布局测试Layout Tests的提交协作指南 导读 本文以 third_party/skia/s前端桌面应用Skia 与 Chromium 代码同步指南API 变更的构建宏抑制策略与 Blink 测试协作流程Skia 与 Chromium 代码同步指南API 变更的构建宏抑制策略与 Blink 测试协作流程 导读 当你的 Skia 改动修改了公共 API 时往往图形学Skia 变更如何优雅落地 Blink Layout Tests从 Rebaseline 到 Staging Define 全流程指南Skia 变更如何优雅落地 Blink Layout Tests从 Rebaseline 到 Staging Define 全流程指南 导读 Skia 是 C图形学上一篇猫抓插件实战上手网页视频音频一网打尽的零门槛攻略下一篇MobileIMSDK即时通讯场景扩展从单聊到群聊的完整实现指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考