尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Skia CanvasKit 构建与测试实战:从 emscripten 编译、本地调试到 Karma 测试与 WASM 性能验证

发布时间:2026/9/25 5:41:19

资讯中心
01
ARTICLE

Skia CanvasKit 构建与测试实战:从 emscripten 编译、本地调试到 Karma 测试与 WASM 性能验证

Skia CanvasKit 构建与测试实战:从 emscripten 编译、本地调试到 Karma 测试与 WASM 性能验证
图形学图像处理【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images.项目地址https://gitcode.com/gh_mirrors/skia1/skia点击查看免费下载本篇指南基于仓库中 modules/canvaskit/README.md 展开系统讲解 CanvasKitSkia 的 WebAssembly/WebGL 移植的完整工程流程如何使用 GN emscripten 编译出.js/.wasm产物、如何编译并运行本地示例、如何组合编译开关裁剪体积、如何用 Karma 跑单元测试与覆盖率、如何用 Puppeteer 做性能测量、如何用wasm2wat检查 SIMD 指令以及 CIGerrit/Docker侧的测试与基础设施运维套路。读完本文你可以独立完成 CanvasKit 的任意构建变体并复现其在浏览器端的全部测试与验证手段。前置条件与工具链运行 CanvasKit 测试需要Node v14 及以上并使用 npmNode Package Manager安装测试依赖较新的 Node 发行版已自带 npm。README 明确说明CanvasKit 没有其它外部源码依赖其余能力均由 Skia 仓库内部提供。编译侧则依赖 Skia 的 GN 构建体系与 emscripten 工具链需要按照 Skia 官方的下载说明获取 Skia 源码树及其依赖DEPS 体系。必须下载并激活 emscripten。仓库提供了 bin/activate-emsdk 脚本//tools/git-sync-deps也会调用它激活后相关文件位于 third_party/externals/emsdkGN 构建脚本默认使用该路径。若想使用自己版本的 emscripten可设置 GN 参数skia_emsdk_dir。从源码结构看该参数在 gn/toolchain/wasm.gni 中声明默认值正是仓库内的 emsdk 目录同文件还定义了skia_wasm_lib模板它会把 wasm 库目标拆成xxx_js可执行目标与聚合 group这是 CanvasKit 目标canvaskit的构建基础。modules/canvaskit/compile.sh 自动化了默认的 GN 配置用户可以自行设置参数其余可用参数见 modules/canvaskit/BUILD.gn 与 modules/canvaskit/canvaskit.gni。macOS 特别提示来自 README 的踩坑记录确保安装了 Python3否则下载 emscripten 工具链时可能因 SSL 证书问题失败。Python3 使用错误证书的情况可参考 emscripten 社区 issue 中给出的解决方案。使用 GN 编译compile.sh 的开关体系modules/canvaskit/compile.sh 是默认构建入口。它先pushd到仓库根目录并执行./bin/fetch-gn然后根据命令行关键字解析出一组内部布尔变量最终拼出一长串./bin/gn gen ${BUILD_DIR} --args...并调用 ninja 编译canvaskit.js目标。从脚本源码可以确认其完整的开关体系如下构建类型与后端选择命令行关键字内部变量 / GN 参数输出目录默认ENABLE_WEBGLtrueskia_enable_ganeshtrueout/canvaskit_wasmcpu_only/cpu关闭 GaneshGPU纯 CPU 后端-sUSE_WEBGL20out/canvaskit_wasmuse_webgpu/webgpuskia_use_dawntrue、skia_enable_graphitetrue、关闭 Ganesh启用 WebGPU 绑定out/canvaskit_wasmdebug_buildis_debugtrue、is_official_buildfalseout/canvaskit_wasm_debugprofilingskia_canvaskit_profile_buildtrueBUILD.gn 断言其必须搭配is_debugfalseout/canvaskit_wasm_profileforce_tracing未出现该关键字时skia_canvaskit_force_tracingtrue即 release/profiling 默认关闭 tracingdebug 默认开启—功能裁剪开关以下开关均通过--args中的skia_canvaskit_*参数生效对应的 GN 参数默认值可查 modules/canvaskit/canvaskit.gnideclare_args段命令行关键字作用对应 GN 参数 / 备注no_skp_serialization禁用 SKP 序列化脚本注释称约省 20KB 压缩体积skia_canvaskit_enable_skp_serializationfalseno_effects_deserialization禁用效果反序列化约省 60KB 压缩体积skia_canvaskit_enable_effects_deserializationfalseno_skottie省略 Lottie 动画支持Skottieskia_enable_skottiefalseviewer内嵌 SKP/SVG 查看器同时启用 expatskia_canvaskit_include_viewertrue、skia_use_expattrueno_pathops省略 PathOps约省 2KB 压缩体积skia_canvaskit_enable_pathopsfalseno_matrix省略矩阵辅助代码同时会连带关闭 HTML Canvas 绑定绑定依赖矩阵助手skia_canvaskit_enable_matrix_helperfalse隐含no_canvasno_canvas省略 HTML Canvas API 绑定skia_canvaskit_enable_canvas_bindingsfalseno_font省略内置字体、字体管理器及全部字体相关代码skia_canvaskit_enable_fontfalse且skia_canvaskit_enable_embedded_fontfalseno_embedded_font仅省略内置字体保留字体管理器skia_canvaskit_enable_embedded_fontfalseno_woff2关闭 woff2 支持skia_use_freetype_woff2falseno_alias_font关闭字体别名查找skia_canvaskit_enable_alias_fontfalselegacy_draw_vertices恢复旧版drawVertices无 shader 时的 blend 行为对应 Flutter issue 98531skia_canvaskit_legacy_draw_vertices_blend_modetrueno_paragraph隐含于primitive_shaper/no_font省略 SkParagraph前提是有字体且非 primitive shaperskia_canvaskit_enable_paragraphfalseprimitive_shaper用原始终端 shaper 替代 HarfBuzz/ICU 组合同时关闭 paragraphskia_use_icufalse skia_use_harfbuzzfalseclient_unicode使用客户端提供的 skunicode 数据与 harfbuzzskia_use_client_icutrueno_codecs关闭全部图片解码并顺带关闭 png/jpeg/webp 编码skia_use_libjpeg_turbo_decodefalse等全部置 falseno_encode_png/no_encode_jpeg/no_encode_webp分别关闭对应格式的编码skia_use_lib*_encodefalse及skia_use_no_*_encodetrueenable_debugger构建带调试器绑定的版本skia_canvaskit_enable_debuggertrue默认文本栈为skia_use_icutrue skia_use_harfbuzztrue均非 system 版本默认开启skia_canvaskit_enable_rt_shadertrue运行时着色器。这些参数如何落到最终产物可以直接在 modules/canvaskit/BUILD.gn 的skia_wasm_lib(canvaskit)目标中看到对应关系release 模式-Oz --closure1 --pre-js release.jsclosure 编译器使用 modules/canvaskit/externs.js 作为 externs这正是 README 提醒“release 测试能暴露 closure 编译与漏写 externs 问题”的底层原因。debug 模式-O0 -sASSERTIONS1 -sGL_ASSERTIONS1 -g3 --pre-js debug.js并启用 DEMANGLE_SUPPORT。WebGL 路径-lGL、-sUSE_WEBGL21、-sMAX_WEBGL_VERSION2并预注入 modules/canvaskit/cpu.js 与 modules/canvaskit/webgl.js。WebGPU 路径-sUSE_WEBGPU1、-sASYNCIFY、导出WebGPU,JsValStore运行时方法且因 closure 与 ASYNCIFY 不兼容而强制--closure0。公共链接参数--bindembind 生成 JS 绑定、-sMODULARIZE、-sEXPORT_NAMECanvasKitInit模块初始化入口、-sINITIAL_MEMORY128MB、-sALLOW_MEMORY_GROWTH、-sWASM、-sSTRICT1等。各功能开关同时控制--pre-js的注入文件如font.js、pathops.js、skp.js、rt_shader.js、paragraph.js以及开启 Canvas 绑定时的 modules/canvaskit/htmlcanvas/ 全套 HTMLCanvas API 胶水代码canvas2dcontext.js、htmlcanvas.js、path2d.js等。条件编译宏也在此映射CK_EMBED_FONT、CK_INCLUDE_PARAGRAPH、CK_SERIALIZE_SKP、CK_INCLUDE_PATHOPS、CK_INCLUDE_RUNTIME_EFFECT、CK_NO_FONTS、CK_NO_ALIAS_FONT等内置字体 modules/canvaskit/fonts/NotoMono-Regular.ttf 会通过embed_resources.py生成为 C 数组参与编译。此外gn/toolchain/wasm.gni 还会向所有 wasm 目标统一注入SKNX_NO_SIMD、SK_FORCE_8_BYTE_ALIGNMENT等宏定义并在关闭效果反序列化或 SKP 序列化时追加SK_DISABLE_EFFECT_DESERIALIZATION。编译并运行本地示例README 给出的标准操作流程是# 安装全部 npm 依赖仅在首次设置或依赖变更时需要很少发生 npm ci make release # make debug 更快且报错信息更友好 make local-example其中make local-example的定义见 modules/canvaskit/Makefile它打印提示并启动python3 ../../tools/serve_wasm.py即 tools/serve_wasm.py随后在浏览器打开http://localhost:8000/npm_build/example.html即可。你可以修改 modules/canvaskit/npm_build/example.html 来实验 CanvasKit API 并刷新页面针对一些更实验性的 API还有 modules/canvaskit/npm_build/extra.html 可用。npm_build目录下另有多用途示例页面multicanvas.html多画布、paragraphs.html、shaping.html 以及 Node 端示例 node.example.js对应make node-example以--expose-wasm模式运行。Makefile 中的构建目标全览modules/canvaskit/Makefile 暴露的目标可分为几类常规构建release、release_cpu、release_webgpu、release_viewer、debug、debug_cpu、debug_webgpu、debug_viewer、profile。每个目标都是“调用compile.sh 对应参数 把out/canvaskit_wasm*/canvaskit.{js,wasm}拷入本地build/目录”注释明确说明会尽可能增量构建。npm 发布make npm会先打 full 版本./compile.sh release再构建一个为通用场景裁剪过体积的版本关闭 skottie、sksl trace、alias font、效果反序列化、jpeg/webp 编码、内嵌字体并启用 legacy draw vertices最后构建 profiling 版本三类产物分别放入npm_build/bin/full、npm_build/bin、npm_build/bin/profiling。GM 测试构建gm_tests与gm_tests_debug调用compile_gm.sh见下文。服务与测试local-example、single-gm、test-continuous、test-continuous-headless、node-example。基础设施docker-compile使用gcr.io/skia-public/canvaskit-emsdk:2.0.0_v1镜像挂载仓库执行infra/canvaskit/build_canvaskit.sh、typecheck进入npm_build运行npm run dtslint做 TS 类型检查。Bazel 构建bazel_canvaskit_debug/bazel_canvaskit_releasebazelisk build :canvaskit --configck_full_webgl2_debug|release与bazel_test_canvaskit产物来自bazel-bin/modules/canvaskit/canvaskit/。调试器/着色器专用with_debugger、with_debugger_release、for_shaders除构建外还会把产物同步到infra/debugger-app/wasm_libs/local_build/或infra/shaders/wasm_libs/local_build/。裁剪版构建构建一个不带文本支持、也不含任何 extras 的精简 CanvasKit例如./compile.sh no_skottie no_fontREADME 指出这样的精简版体积约为默认 release 构建的一半。结合前文开关表还可以进一步叠加no_skp_serialization、no_effects_deserialization、no_codecs等以继续压缩体积——make npm发布目标就是这一思路的工程化落地。构建失败排查README 给出两条经验若 CanvasKit 构建失败且编译错误看起来不像 Skia 代码问题可能需要全新安装 npm 模块找到报错信息中提到的.d.ts文件删除后重新执行npm ci。若模块版本正确且使用了受支持的最新 TypeScript 仍失败则可能需要更新 modules/canvaskit/package.json 中列出的模块版本。单元测试、覆盖率与持续测试在 debug GPU 构建上运行单元测试并计算覆盖率make debug make test-continuous从 Makefile 看test-continuous实际执行npx karma start ./karma.conf.js --no-single-run --watch-pollheadless 版本见test-continuous-headless。行为特征README 原文归纳读取 modules/canvaskit/karma.conf.js打开 Chrome 浏览器开始运行tests/目录下的全部测试检测到该目录下的测试文件变化时自动重跑并且会自动重新构建并重新加载 CanvasKit关闭 Chrome 窗口只会让它重新打开要停止持续监听需要杀掉 karma 进程。测试运行的是你最后一次构建的 CanvasKit 版本。README 强调必须同时在release、debug_cpu、release_cpu上测试——release 构建会暴露 closure 编译问题与通常被忘记的 externs与 BUILD.gn 中 release 分支强制--closure1并注入externs.js的实现相呼应。覆盖率本地运行test-continuous时覆盖率会自动计算且只有在 debug 构建下结果才有意义。打开coverage/浏览器版本/index.html可查看汇总与逐行详情。测试的组织方式与 gm 快照tests/中的测试按主题分组为文件从目录可以看到具体分组canvas_test.js、path_test.js、font_test.js、matrix_test.js、skottie_test.js、paragraph_test.js、rtshader_test.js、canvas2d_test.js、core_test.js 等测试资产字体、图片、SKP、Lottie JSON位于 modules/canvaskit/tests/assets/。每个文件内用 Jasmine 的describe块进一步组织describe内是测试具体行为的it()函数。两者都可临时重命名为fdescribe/fit让 Jasmine 只运行被聚焦的用例。除此之外还定义了gm方法用于定义把某些内容画到 canvas、截图并上报 gold.skia.org 的测试可与 head 版本的快照进行对比即 CanvasKit 也接入了 Skia 的图像回归比对基础设施。性能测量性能数据由 Puppeteer 驱动 Chrome 以一致的方式采集实现位于 tools/perf-canvaskit-puppeteer/。该目录自带 README其中描述的三类基准均值得了解基础性能测试基准代码片段追加到canvas_perf.jsharness 为canvas_perf.htmlbenchmark.js运行make perf_js后会对 test() 代码段跑多帧采集数据并上报 90/95/99 分位帧时间、平均帧时间、中位数与标准差。三种度量分别是without_flush_ms仅 test() 调用、with_flush_mstest() flush()、total_frame_ms帧到帧时间包含 GPU 在 CanvasKit flush 之后仍需完成的工作。Skottie 帧性能循环渲染 600 帧 Lottie 动画并采集指标前 5 帧时间、平均帧时间、90/95/99 分位。SKP 性能反复播放 SKP 并测量各类指标。CI 中这些结果统一上报到 perf.skia.org。从 Gerrit 发起测试在 Gerrit 提交 CL 时点击 choose tryjobs 并输入 CanvasKit 过滤全部选中撰写时为 4 个任务覆盖 perf/test × gpu/cpu 的组合。性能结果上报 perf.skia.org正确性结果上报 gold.skia.org以这种方式运行测试时不测量覆盖率。检查输出 WASM 中的 SIMD 指令WebAssembly Binary Toolkit 提供的wasm2wat工具可以把.wasm文件转成人类可读的文本形式。README 对版本有硬性要求wasm2wat --version的输出应为1.0.13 (1.0.17)。该版本经过验证可与 modules/canvaskit/wasm_tools/SIMD/ 中的工具配合工作。这套工具会程序化地检查 CanvasKit 构建产出的.wasm以检测其中是否存在 wasm SIMD 操作。该目录包含 build_simd_test.sh、simd_test.sh、能力探测源码 simd_float_capabilities.cpp 与 simd_int_capabilities.cpp。值得注意的是gn/toolchain/wasm.gni 默认给 wasm 目标注入SKNX_NO_SIMD也就是说 CanvasKit 主构建路径默认禁用 Skia 自身的 NEON 式 SIMD 优化路径上述检查正是为了在引入 SIMD 时确认工具链行为是否符合预期。基础设施手册Docker、Emscripten 升级与 GM/单元测试验证CanvasKit / PathKit 的 Docker 化在 Skia 的 bots 上处理 CanvasKit或 PathKit时使用 Docker。构建/测试镜像的构建与编辑说明见 infra/wasm-common/docker/README.md。该目录实际包含emsdk-base、karma-chrome-tests、gold-karma-chrome-tests、perf-karma-chrome-tests等镜像定义及 Makefile。本地也可以直接用make docker-compile复现该流程。更新构建/测试所用的 Emscripten 版本前提你已在本地把 emscripten 升级到目标版本并验证/修复了由此产生的构建问题。然后编辑 bin/activate-emsdk安装并激活期望的 Emscripten 版本上传包含全部变更的 CL运行全部 Test.CanvasKit、Perf.Puppeteer、Test.PathKit、Perf.PathKit 任务确认新构建通过所有测试且不搞崩性能 harness发出 CL 评审可以把评审人引到上述步骤说明。在 wasmWebGL 上运行 Skia 的 GM 与单元测试通用技巧README 原文归纳利用 tools/run-wasm-gm-tests/run-wasm-gm-tests.html 中的 skip list 与起始索引聚焦定位有问题的测试看到Uncaught (in promise) RuntimeError: function signature mismatch通常意味着某处解引用了 null可加SkASSERT验证。单个 GM/单元测试的快速调试为了缩短周期建议只编译特定 GM 而非全部。做法是修改 modules/canvaskit/compile_gm.sh但不要把该修改提交入库脚本中把GMS_TO_BUILD/TESTS_TO_BUILD设为最小文件集配合其中的if false; then段注释掉false即可启用。随后在本目录执行make gm_tests或make gm_tests_debug会在未入库的build子目录生成.js与.wasm。再执行make single-gm并访问http://localhost:8000/wasm_tools/gms.html——该服务由 tools/serve_wasm.py 提供modules/canvaskit/wasm_tools/gms.html 会加载新构建的wasm_gm_tests二进制并运行编译进去的那一个 GM/单元测试你可以按需修改该 HTML 来运行关心的测试。从 compile_gm.sh 源码还能看到更完整的上下文它要求设置EMSDK环境变量并 sourceemsdk_env.shGM 侧默认编译gm/*.cpp、测试侧默认编译tests/*.cpp并用GLOBIGNORE显式排除了若干无法在 wasm 下编译或链接的 GM如compressed_textures、animated_gif、fiddle、fontations、video_decoder与单元测试如CodecTest、ImageTest、FCITest等以及一个会崩溃的GrThreadSafeCacheTest。最终链接参数与主构建同源风格--bind、-sMODULARIZE1、-sEXPORT_NAMEInitWasmGMTests、-sINITIAL_MEMORY256MB、-sFILESYSTEM1等且注释特意说明 Emscripten 希望.a库排在链接顺序最后否则可能误删符号。全量 GM/单元测试以当前 GN 构建全部编译与重编译耗时相当可观README 备注“即将到来的 Bazel 构建应能缓解这一点”——对应 Makefile 中的bazel_*目标。流程与单测一致先make gm_tests/make gm_tests_debug产出build/下的.js.wasm然后进入 tools/run-wasm-gm-tests 目录执行make run_local所有 GM 产出的 PNG 会写入/tmp/wasm-gmtests并同时运行全部单元测试。该目录的 run-wasm-gm-tests.js 与 HTML 页面即上文提到的 skip list / 起始索引功能所在。小结CanvasKit 的构建体系可以概括为一条主线compile.sh功能开关 → GN 参数→BUILD.gn的skia_wasm_lib目标embind pre-js 胶水 closure/优化配置→canvaskit.{js,wasm}产物测试与验证则由四层组成——Karma 持续单元测试含覆盖率、gold 图像比对gm测试、Puppeteer 性能 harnesswithout_flush_ms/with_flush_ms/total_frame_ms三类指标、wasm2watSIMD 检查最终由 Docker 化的 CI 镜像与 Gerrit tryjobs 闭环。所有脚本与配置都可直接在仓库内查阅入口 modules/canvaskit/README.md、构建 modules/canvaskit/compile.sh 与 modules/canvaskit/BUILD.gn、参数默认值 modules/canvaskit/canvaskit.gni、目标汇总 modules/canvaskit/Makefile、GM 测试 modules/canvaskit/compile_gm.sh 与 tools/run-wasm-gm-tests、性能 tools/perf-canvaskit-puppeteer、基础设施 infra/wasm-common/docker/README.md。赞分享图形学图像处理【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images.项目地址https://gitcode.com/gh_mirrors/skia1/skia点击查看免费下载相关推荐CanvasKit 构建与测试完全指南从 Emscripten 编译到 WASM 调试Skia 官方实践CanvasKit 构建与测试完全指南从 Emscripten 编译到 WASM 调试Skia 官方实践 本指南以 Skia 仓库中 modules/ca图形学PDBRipper GUI使用教程图形界面下的PDB分析完全指南PDBRipper GUI使用教程图形界面下的PDB分析完全指南 PDBRipper是一款专业的 PDB文件分析工具 专为开发者和逆向工程师设计能够从PD逆向工程开发工具Skia wasm-common Docker用四张 Docker 镜像构建与测试 PathKit/CanvasKit WASM 的完整指南Skia wasm common Docker用四张 Docker 镜像构建与测试 PathKit/CanvasKit WASM 的完整指南 本文基于 Ski图形学图像处理上一篇MXNet Gluon MNIST 图像分类实战从数据加载到模型训练与推理下一篇nRFMicro硬件详解为什么它是Pro Micro的完美升级替代品创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。