
图形学【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images. See documentation for contribution instructions.项目地址https://gitcode.com/gh_mirrors/ski/skia点击查看免费下载导读本文以 Skia 仓库中的 tools/skottie_ios_app/README.md 为主线完整讲解如何将 SkottieSkia 的 Lottie 动画渲染模块示例应用skottie_example编译为 iOS.app包并分别针对Metal、纯 CPU、OpenGL三种渲染后端给出可直接复制的 GN 参数配置与构建命令。读完本文你将掌握args.gn中各关键开关skia_use_metal、skia_enable_ganesh、skia_enable_pdf、skia_use_expat的实际作用理解示例应用内部的视图/上下文分层结构以及三种后端在源码层面是如何被选择与实现的从而能够根据自己的设备与性能需求快速搭建、定制 Skottie iOS 演示环境。1. Skottie iOS 示例应用是什么skottie_ios_app是 Skia 仓库中一个独立的 iOS 示例工程其唯一产物是名为skottie_example的应用 bundle。它把 modules/skottie 模块包装成 Objective-C 接口在一个可滚动的UIScrollView中依次加载并播放打包进 bundle 的多段 Lottie 动画 JSON见 BUILD.gn 中data_sources列出的resources/skottie/下的动画资源。从源码结构看该示例的核心设计是将渲染后端与动画控制逻辑解耦SkiaContext.h 定义统一接口makeViewWithController:withFrame:负责为某个动画控制器创建对应后端的UIViewgetViewController:用于反向取回控制器SkottieViewController.h 提供loadAnimation:、seek:、togglePaused、currentTime、animationDurationSeconds等 Objective-C 接口把modules/skottie/include/Skottie.h的skottie::Animation封装为可被 UIKit 直接调用的对象具体后端实现在 SkiaMetalContext.mm、SkiaGLContext.mm、SkiaUIContext.mm 三个文件中。在main.mm中应用通过预编译宏选择后端#if defined(SK_GANESH) defined(SK_METAL) [self setSkiaContext:MakeSkiaMetalContext()]; #elif defined(SK_GANESH) defined(SK_GL) [self setSkiaContext:MakeSkiaGLContext()]; #else [self setSkiaContext:MakeSkiaUIContext()]; #endif也就是说args.gn中的配置最终会决定SK_GANESH、SK_METAL、SK_GL这三个宏是否定义进而决定运行时使用哪个渲染后端。这也解释了为什么同一个工程、三份构建配置可以分别产出 Metal、CPU、OpenGL 三种版本。2. 构建前置条件与目录准备三种后端的构建流程完全一致都需要以下前置条件Skia 源码根目录下文用$SKIA_ROOT_DIRECTORY指代即克隆 Skia 仓库后所在的目录GN 与 Ninjabin/gn gen与ninja命令来自 Skia 内置的bin/工具链bin/gn首次使用时tools/git-sync-deps会同步第三方依赖Xcode 与 iOS SDK编译.appbundle 及后续安装到模拟器/真机都需要完整的 Xcode 环境gn/ios.gni中定义了 iOS 应用 bundle 的打包逻辑ios_app_bundle模板。每次构建都需要新建独立的输出目录并写入args.gn。下面按 Metal / CPU / OpenGL 三个后端分别给出完整的构建命令。三组命令均以cd $SKIA_ROOT_DIRECTORY开头因此以下命令均需在仓库根目录下执行。2.1 准备命令速查步骤命令作用进入仓库根目录cd $SKIA_ROOT_DIRECTORY定位源码根创建输出目录mkdir -p out/ios_arm64_mtl隔离各后端产物写入构建参数cat out/ios_arm64_mtl/args.gn EOM ... EOM生成 GN 参数文件同步依赖tools/git-sync-deps拉取/校验第三方依赖生成构建文件bin/gn gen out/ios_arm64_mtl解析 args.gn 生成 ninja 文件编译ninja -C out/ios_arm64_mtl skottie_example构建.appbundle注意bin/gn是 Skia 仓库自带的 GN 二进制不要与系统安装的 GN 混淆tools/git-sync-deps是仓库根目录下的 Python 脚本 tools/git-sync-deps用于同步 DEPS 中声明的依赖。3. 后端一MetalGPU 加速真机推荐Metal 是 Apple 提供的低开销 GPU 图形 API是 iOS 上性能最好的 Skia Ganesh 后端适合在真机上运行。cd $SKIA_ROOT_DIRECTORY mkdir -p out/ios_arm64_mtl cat out/ios_arm64_mtl/args.gn EOM target_osios target_cpuarm64 skia_use_metaltrue skia_use_expatfalse skia_enable_pdffalse EOM tools/git-sync-deps bin/gn gen out/ios_arm64_mtl ninja -C out/ios_arm64_mtl skottie_example构建完成后将out/ios_arm64_mtl/skottie_example.app安装到 iOS 设备即可可通过 Xcode 的 Devices 面板或xcrun simctl安装。3.1 参数解读target_osios目标平台为 iOS触发gn/ios.gni中的 iOS bundle 模板逻辑target_cpuarm6464 位 ARM 架构覆盖现代 iPhone/iPad 与 Apple Silicon 模拟器skia_use_metaltrue启用 Metal 支持编译时定义SK_METALGanesh 使用 Metal 后端skia_use_expatfalse禁用 expatXML 解析库Skottie 不需要它可减小体积与构建时间skia_enable_pdffalse禁用 PDF 相关代码进一步精简产物。注意此配置中未显式关闭 Ganesh即skia_enable_ganesh保持默认开启true。这正是 BUILD.gn 中skia_enable_ganesh skia_use_metal分支生效的条件此时会额外编译SkMetalViewBridge.mm、SkiaMetalContext.mm并链接Metal.framework与MetalKit.framework见 BUILD.gn 第 60-64 行。3.2 源码实现Metal 视图如何工作Metal 后端由 SkiaMetalContext.mm 实现。初始化时创建MTLDeviceMTLCreateSystemDefaultDevice、MTLCommandQueue并用它们构造GrDirectContextGrMtlBackendContext backendContext {}; backendContext.fDevice.reset((__bridge void*)[self metalDevice]); backendContext.fQueue.reset((__bridge void*)[self metalQueue]); fDContext GrDirectContexts::MakeMetal(backendContext, GrContextOptions());渲染视图SkiaMtkView继承自MTKView在drawRect:中通过SkMtkViewToSurface将MTKView的currentDrawable包装为SkSurface调用[viewController draw:... toCanvas:...]完成 Skottie 帧渲染随后fDContext-flushAndSubmit(surface.get()); idMTLCommandBuffer commandBuffer [fQueue commandBuffer]; [commandBuffer presentDrawable:[self currentDrawable]]; [commandBuffer commit];值得注意的细节是帧率控制视图创建时设置setPreferredFramesPerSecond:3030 FPS并且当动画处于暂停状态时通过setEnableSetNeedsDisplay:paused与setPaused:paused让MTKView停止连续绘制实现暂停即省电的效果。4. 后端二CPU无 GPU 依赖模拟器友好CPU 后端不依赖任何图形 API使用 Skia 的 raster 路径把动画逐帧画到内存位图再上屏适合在 iOS 模拟器或无 GPU 环境下运行也便于调试。cd $SKIA_ROOT_DIRECTORY mkdir -p out/ios_arm64_cpu cat out/ios_arm64_cpu/args.gn EOM target_cpuarm64 target_osios skia_enable_ganeshfalse skia_enable_pdffalse skia_use_expatfalse EOM tools/git-sync-deps bin/gn gen out/ios_arm64_cpu ninja -C out/ios_arm64_cpu skottie_example构建完成后将out/ios_arm64_cpu/skottie_example.app安装到设备或模拟器即可。4.1 参数解读skia_enable_ganeshfalse显式关闭 Ganesh GPU 渲染层这是 CPU 后端与 Metal/OpenGL 后端的根本区别。此时SK_GANESH宏不定义main.mm中的#if defined(SK_GANESH) defined(SK_METAL)与#elif defined(SK_GANESH) defined(SK_GL)均不成立最终落入#else分支调用MakeSkiaUIContext()target_cpuarm64/target_osios与 Metal 配置相同skia_enable_pdffalse、skia_use_expatfalse精简依赖与产物。从 BUILD.gn 的源码结构看当skia_enable_ganesh为 false 时两个 GPU 上下文文件都不会参与编译而是仅编译SkiaUIContext.mm并且不会链接任何 Metal/OpenGL 框架。4.2 源码实现CPU 视图如何工作CPU 后端由 SkiaUIContext.mm 实现。SkiaUIView内部维护一块SkBitmap fBackBuffer作为后备缓冲drawRect:中按当前 view 尺寸重新分配位图尺寸变化时才重建构造SkCanvas canvas(fBackBuffer)调用[viewController draw:... toCanvas:canvas ...]让 Skottie 把动画帧画进位图通过SkCGDrawBitmap把位图交给 CoreGraphics 上屏使用NSTimer按kFrameRate 1.0 / 30.030 FPS调度下一次setNeedsDisplay暂停状态下则不调度从而停止重绘。这段实现也印证了 README 中“CPU 后端”命名背后的机制所有渲染都在 CPU 内存中完成不涉及任何 GPU 命令队列。5. 后端三OpenGLGanesh OpenGLESOpenGL 后端使用 Ganesh 的 OpenGL 实现iOS 上即 OpenGLES适合需要在 Ganesh 框架下对比 Metal/GL 渲染差异的场景。cd $SKIA_ROOT_DIRECTORY mkdir -p out/ios_arm64_gl cat out/ios_arm64_gl/args.gn EOM target_cpuarm64 target_osios skia_enable_ganeshtrue skia_use_metalfalse skia_enable_pdffalse skia_use_expatfalse EOM tools/git-sync-deps bin/gn gen out/ios_arm64_gl ninja -C out/ios_arm64_gl skottie_example构建完成后将out/ios_arm64_gl/skottie_example.app安装到设备或模拟器即可。5.1 参数解读skia_enable_ganeshtrue显式启用 Ganesh GPU 渲染层与默认值一致写出来更清晰skia_use_metalfalse显式关闭 Metal避免与 OpenGL 后端同时启用产生歧义由于skia_use_gl默认开启且本配置未修改Ganesh 将采用 OpenGL 后端SK_GL宏被定义skia_enable_pdffalse、skia_use_expatfalse与前面两个配置一致的精简项。对照 BUILD.gn 与第 65-69 行的框架列表此时命中skia_enable_ganesh skia_use_gl分支仅追加编译SkiaGLContext.mm并链接GLKit.framework与OpenGLES.framework。5.2 源码实现OpenGL 视图如何工作OpenGL 后端由 SkiaGLContext.mm 实现。其核心步骤包括初始化时配置GLKView的 drawable 格式GLKViewDrawableColorFormatRGBA8888、24 位深度缓冲、8 位模板缓冲见configure_glkview_for_skia源码第 23-27 行渲染时查询当前绑定帧缓冲glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, fboid)并通过GrBackendRenderTargets::MakeGL把GL_RGBA8帧缓冲包装为SkSurface然后照常调用[viewController draw:... toCanvas:...]渲染 Skottie 帧渲染完成后由 Ganesh 的 OpenGL 后端负责flush到默认帧缓冲GLKView负责上屏。从代码结构可以推断三个后端的差异被严格隔离在“创建SkiaContext/UIView”这一层SkottieViewController的动画加载、seek、暂停/播放逻辑在三种后端间完全复用。6. 三种后端配置对比与选型配置项MetalCPUOpenGLtarget_osiosiosiostarget_cpuarm64arm64arm64skia_enable_ganesh默认 truefalsetrueskia_use_metaltrue不要求falseskia_enable_pdffalsefalsefalseskia_use_expatfalsefalsefalse运行时上下文MakeSkiaMetalContext()MakeSkiaUIContext()MakeSkiaGLContext()额外框架Metal、MetalKit无GLKit、OpenGLES适用场景真机 GPU 渲染模拟器/无 GPUGanesh GL 对比选型建议基于仓库实现事实非性能断言真机验证 Skottie 渲染效果优先 Metal它是 iOS 上 Skia 主推的 GPU 后端模拟器或 CI 无 GPU 环境用 CPU 后端零图形框架依赖构建最轻需要 Ganesh 抽象层下的跨后端对比同时构建 Metal 与 OpenGL 两套观察同一动画在不同 GPU 后端的表现差异。7. 运行示例应用界面与交互skottie_example的运行界面由 main.mm 构建应用启动后AppViewController读取 bundle 内data目录下所有.json动画资源为每个可成功加载的动画创建一个SkottieViewController并按动画原始宽高比计算高度依次垂直排列进UIStackView整体放入UIScrollView以支持滚动浏览多段动画。交互方面main.mm在根视图注册了UITapGestureRecognizerhandleTap:点击屏幕会遍历所有SkiaViewController并调用togglePaused即点击即可暂停/恢复所有动画暂停状态会通过setNeedsDisplay立即反映到界面。SkottieViewController的播放控制能力来自其内部的SkTimeKeeper与SkAnimationDraw见 SkottieViewController.mmSkAnimationDraw负责用skottie::Animation::Builder从 JSON 数据构建动画并在尺寸变化时计算居中缩放矩阵然后fAnimation-render(canvas)渲染当前帧SkTimeKeeper负责时间轴基于SkTime::GetNSecs()的单调时钟计算播放位置支持seek:暂停时直接改播放时刻、运行时重置起点、setStopAtEnd:播到结尾自动暂停以及togglePaused暂停时记录当前时刻恢复时校准时钟偏移。这两个类的实现恰好对应 SkottieViewController.h 中暴露的 Objective-C 接口isPaused、togglePaused、seek:、currentTime、animationDurationSeconds、size等如果你想把该示例改造为自己的播放器直接复用这些接口即可。8. 自定义与扩展建议在保持仓库只读的前提下你可以基于现有结构做如下扩展仅需在本地副本中修改后重新构建更换/增加动画资源参考 BUILD.gn 的data_sources把自己生成的 Lottie JSON 加入列表重启应用即可在滚动列表中看到新动画限制动画列表main.mm中遍历pathsForResourcesOfType:json inDirectory:data可以改为只加载指定文件名调整帧率Metal 视图的setPreferredFramesPerSecond:30与 CPU 视图的kFrameRate 1.0/30.0是两处可调的帧率参数可按需改高或改低改变交互handleTap:目前统一切换所有动画的暂停状态可改为只切换被点击的那个视图对应的控制器getViewController:接口已为此准备好自定义渲染回调SkiaViewController draw:toCanvas:atSize:协议可被任意自定义控制器实现不限于 Skottie可作为在 iOS 上测试任意 Skia 绘制内容的宿主。9. 常见问题排查bin/gn gen报错找不到工具链确认已安装 Xcode 并完成xcode-select -p配置首次构建务必先执行tools/git-sync-deps安装.app失败真机检查设备是否信任开发者证书.app需通过 Xcode 或xcrun devicectl安装并完成签名示例产物默认面向开发调试场景CPU 后端动画不刷新确认skia_enable_ganeshfalse已写入 args.gn若宏选择逻辑生效main.mm会调用MakeSkiaUIContext()其NSTimer调度依赖isPaused状态暂停时不会重绘属于预期行为Metal 后端在模拟器上无画面MTLCreateSystemDefaultDevice在部分模拟器环境可能返回 nilSkiaMetalContext.mm第 87-91 行会打印 Metal is not supported on this device 并返回 nil 上下文main.mm检测到空上下文会abort此时请改用 CPU 后端配置。10. 延伸阅读示例工程构建定义tools/skottie_ios_app/BUILD.gnSkottie 渲染模块modules/skottie/include/Skottie.hskottie::Animation的构建与渲染接口后端上下文接口tools/skottie_ios_app/SkiaContext.h动画控制器封装tools/skottie_ios_app/SkottieViewController.h 与 tools/skottie_ios_app/SkottieViewController.mmiOS 打包模板gn/ios.gniios_app_bundle应用入口与交互逻辑tools/skottie_ios_app/main.mm示例动画资源resources/skottie/BUILD.gndata_sources所列 JSON通过本文给出的三套args.gn与构建命令你可以在同一份 Skia 源码上分别产出 Metal、CPU、OpenGL 三个版本的 Skottie iOS 示例应用并借助源码理解每一份配置背后实际的渲染链路为后续基于 Skottie 的 iOS 动画业务开发打好基础。赞分享图形学【免费下载链接】skiaSkia is a complete 2D graphic library for drawing Text, Geometries, and Images. See documentation for contribution instructions.项目地址https://gitcode.com/gh_mirrors/ski/skia点击查看免费下载相关推荐用 InstantDB 为 AI 编码应用构建实时后端从包选择到完整示例的实战指南用 InstantDB 为 AI 编码应用构建实时后端从包选择到完整示例的实战指南 导读本文基于仓库 client/sandbox/task tracker后端数据库ESP-IDF安全启动终极指南构建固若金汤的物联网设备保护系统ESP IDF安全启动终极指南构建固若金汤的物联网设备保护系统 ESP IDF安全启动流程是保护ESP32系列物联网设备免受恶意固件攻击的关键技术。作为Esp物联网嵌入式Elm单页应用程序示例教程构建现代化前端应用的完整指南Elm单页应用程序示例教程构建现代化前端应用的完整指南 前言为什么选择Elm构建SPA 还在为前端应用的复杂性而头疼吗状态管理、路由跳转、异步请求、错误上一篇3大核心技术突破MouseClick如何重新定义鼠标自动化效率下一篇MouseClick从手动点击到智能自动化的技术演进与实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考