2312skia,14示例及一些介绍

本文介绍了Skia库的SkPDF后端限制以及SkiaViewer的功能,包括渲染性能测试、不同渲染方法、资源加载和SkSL与运行时特效的使用。同时涵盖了iOS和Android平台的兼容与构建指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pdf示例.

SkDocumentSkCanvasAPISkiaPDF后端(SkPDF)的示例,[这里](https://fiddle.skia.org/c/@PDF docs/examples/PDF.cpp).

SkPDF限制

Skia的公共API有几个角落是SkPDF目前无法处理的,因为或没有已知的客户使用该功能,或没有简单的PDF式方法来处理它.

本文档中:

1,drop表示什么都不画.
2,忽略表明不带特效的绘画
3,expand表明按非PDF方式实现.表明
栅格化向量图形,扩展带路径特效的路径至多个单独路径,或转换文本为路径.

特效文本其他
SkMaskFilterdropignoreignore
SkPathEffectignoren/aexpand
SkColorFilterignoreexpandignore
SkImageFilterexpandexpandexpand
不支持SkXferModesignoreignoreignore
非渐进SkShaderexpandn/aexpand

注意:
1,SkImageFilter:展开SkImageFilter时,文本作为文本丢失.
2,SkXferMode:PDF自身不支持以下传输模式:
DstOver,SrcIn,DstIn,SrcOut,DstOut,SrcATop,DstATopModulate.

SkiaViewer

SkiaViewer显示一系列展示了Skia包括SkiaGM允许交互的编程示例指定功能幻灯片.此外,查看器还用来调试和理解Skia系统的不同部分.

1,观察渲染性能,按统计信息模式看查看器可显示平均帧时间
2,试不同的渲染方法,可在三个渲染方法之间循环:(在支持的平台上)光栅(raster),OpenGLVulkan.
可与统计信息模式一起使用此功能,以查看不同渲染方法绘图性能的影响.
3,显示和操作你自己的图片.

某些幻灯片需要在程序外部存储的资源.在<skia-path>/resources目录中存储这些资源.

Linux,MacintoshWindows

可用普通的GN构建进程构建查看器,如

bin/gn gen out/Release --args='is_debug=false'     ninja -C out/Release viewer

要在桌面查看器中加载资源,用--resourcePath选项:

<skia-path>/out/Release/viewer --resourcePath <skia-path>/resources

同样,--skps <skp-file-path>加载该目录中的.skp文件,以便在查看器中显示.

其他有用的命令行选项:使用--match <pattern>加载仅与该名匹配的skp或幻灯片;使用--slide<name>在该幻灯片上启动;

你可用--backend,即--backend sw,--backend gl,--backend vk--backend mtl来启动特定渲染方法.

键盘鼠标控制桌面查看器:左和右箭头在幻灯片移动;上下箭头来放大和缩小;点击和拖动将平移.
可在工具UI中找到其他显示选项幻灯片选取器,可通过按空格键切换.
d更改渲染操作.s显示渲染时间和图.空格切换显示.

安卓

要为安卓应用构建Viewer,请先按安卓构建说明设置AndroidNDKninja out目录.此外,还需要安装AndroidSDK并设置ANDROID_HOME环境变量.

    mkdir ~/android-sdk
    ( cd ~/android-sdk; unzip ~/Downloads/sdk-tools-*.zip )
    yes | ~/android-sdk/tools/bin/sdkmanager --licenses
    export ANDROID_HOME=~/android-sdk  
# 安装Android SDK的目录.

如果你不用AndroidSDK附带的NDK(在本例中为~/android-sdk/ndk-bundle),则需要设置环境变量为ANDROID_NDK_HOME,如:

    export ANDROID_NDK_HOME=/tmp/ndk

必须由gradle构建查看器APK,可在命令行上调用以下脚本:

platform_tools/android/bin/android_build_app -C <out_dir> viewer

<out_dir>是创建的ninja out目录(如out/arm64).完成脚本后,可在<out_dir>/viewer.apk找到APK.用adb install安装.

如何使用应用

大多数应用功能(触摸手势和箭头按钮除外)都放在左侧抽屉中.点击左上角的汉堡包按钮以打开该抽屉.

切换幻灯片

右上角,有两个箭头:下一张,上一张幻灯片.
左侧抽屉中,可直接从列表(微调器)中选择幻灯片.在该微调器上方,有一个应用至幻灯片列表的文本过滤器.有数百张幻灯片,如果知道幻灯片名,可用该过滤器快速找到并显示它.

缩放/翻译

支持幻灯片上的触摸手势,因此可拖动和捏合以缩放.

更改后端

左侧抽屉中,可从OpenGL,VulkanRaster列表中选择后端.

软键/统计

左边抽屉里,有一个软键列表.对应桌面查看器应用键盘命令.如,可切换颜色模式统计信息窗口.可像幻灯片一样过滤它们.
动画幻灯片,还显示FPS(每帧秒数),以毫秒为单位的帧刷新率.

加载资源或skps

TODO(https://issues.skia.org/295805469):这曾经可通过以下说明实现,但它们不再适合最新版本的Android.

要在安卓查看器中加载资源,请在/data/local/tmp/resources中放置它们;要加载SKP,在/data/local/tmp/skps中放置它们.

iOS系统

用普通GN进程构建iOS上的查看器,如

    bin/gn gen out/Release --args='target_os="ios" is_debug=false'
    ninja -C out/Release viewer

与其他iOS应用一样,可用ios-deploy这里等来部署,也可通过在Xcode构建,并启动IDE来部署.

在顶级Skia目录中Viewer自动绑定资源目录,如果也在Skia目录中放置skps目录,则会绑定skps目录.
iOS上,查看器提供基本触摸功能:可查看幻灯片,在幻灯片之间轻扫,捏合缩放以缩放及通过平移翻译.尚不支持显示选项或从幻灯片列表中选择.

sksl与运行时特效

概述

SkSLSkia的着色语言.SkRuntimeEffect是一个Skia的可用来创建行为由SkSL代码控制的SkShader,SkColorFilterSkBlender对象的C++对象.

你可在https://shaders.skia.org/试用SkSL.语法与GLSL类似.在Skia应用中使用SkSL特效时,需要记住一些(与GLSL)重要的差异.

差异大多源于:使用GPU着色语言,你正在对GPU管道的一个阶段编程.使用SkSL,你正在对Skia管道的一个阶段编程.
即,GLSL片段着色器控制GPU光栅化器和混合硬件之间的整个行为.该着色器负责计算颜色,再把生成的颜色填充到管道固定函数混合阶段的颜色.
SkSL特效作为更大的Skia管道的一部分存在.当发出画布绘画操作时,Skia(一般)会组装单个GPU片段着色器来完成工作.

此着色器一般包含多个部分.如,它可能包括:
1,求值像素是落在所绘画形状内部还是外部(或在边框上,它可能会应用抗锯齿).
2,求值像素是落在剪切区域内还是外(同样,边界像素可能有抗锯齿逻辑).
3,SkPaintSkShader的逻辑.(由于SkShaders::Blend和下面描述的其他特征)SkShader可以是对象树.
4,SkColorFilter的类似逻辑(由于SkColorFilters::Compose,SkColorFilters::Blend及下面描述的特征,也可以是).
5,混合代码(对某些SkBlendModes,或用SkPaint::setBlender指定的自定义混合).
6,转换颜色空间代码,作为Skia管理颜色的一部分.

SkShader,SkColorFilterSkBlender字段中,即使SkPaint复杂的对象树,也只有一个GPU片段着色器.
该树中的每个节点都会创建一个函数.裁剪和几何代码各自创建一个函数.混合代码可能会创建一个函数.然后,整个片段着色器调用所有这些函数(这些函数可能会调用其他函数,如在SkShader树时).

SkSL特效为GPU的片段着色器贡献了一个函数.

求值(采样)其他SkShader

GLSL中,片段着色器可采样纹理.使用运行时特效时,(用C++)绑定的对象是一个由SkSL中的着色器表示的SkShader.

为表明,你正在操作发出自己的着色器代码的对象,请不要使用sample.相反,着色器对象有.eval()方法.
Skia有从SkImage创建SkShader的简单方法,因此在运行时特效中使用图像很容易.
因为绑定和计算的对象是SkShader,因此可直接用Skia着色器,而不必先转换图像(纹理).如,可计算线性梯度.

此例中,没有创建纹理来保持渐变.Skia生成一个片段着色器,来计算渐变颜色,再从图像的纹理中采样,然后再两者相乘.
当然,甚至可调用另一个运行时特效,从而可动态组合着色器片段.

坐标空间

要了解坐标在SkSL中的工作原理,你首先需要了解它们在Skia中的工作原理.如果你对Skia的坐标空间感到满意,则记住,提供给main()的坐标是本地坐标.

它们相对于SkShader坐标空间.匹配画布的本地空间和localMatrix转换.此外,如果另一个着色器调用着色器,则该父着色器可任意修改它们.

此外,从SkImage生成的SkShader(如GLSL中的纹理)不使用归一化坐标.它在左上角使用(0,0),在右下角使用(w,h).
一般,这正是你想要的.如果要使用基于传递给你的坐标来求值SkImageShader,则该比例是正确的.但是,如果要调整这些坐标(重新映射图像),请记住,把坐标放大图像尺寸.

颜色空间

一般由颜色管理管理使用Skia的应用.表面(目标)颜色空间决定了绘画工作颜色空间.(如包括SkImageShader着色器)源内容也有颜色空间.
默认,把SkSL着色器的输入转换为工作颜色空间.但是,某些输入需要特别小心才能获得(或抑制)此行为.

首先,看看Skia管理颜色的实际应用.在此,绘画了两次山魈图像的一部分.
第一次,正常绘画,尊重在文件中存储的(恰好是sRGB)颜色空间.
第二次,为图像赋值Rec.2020颜色空间.这仅告诉Skia按好像为该颜色空间来存储图像.然后,Skia将这些值从Rec.2020转换为目标表面(sRGB)颜色空间.

因此,所有颜色都更加生动.更重要的是,如果图像确实在其他颜色空间中,或目标表面在其他颜色空间中,则该自动转换是值得的,因为它可确保在用户的屏幕上内容总是正确.

统一

SkiaSkSL不知道你的统一变量是否包含颜色,因此它不会自动转换应用颜色.下例中,声明了两个统一:
colornot_a_color.SkSL只是水平淡入两个统一"颜色"中的一个,为着色器上半下半部分选择不同的统一.该代码传递相同的值给两个统一,{1,0,0,1}四个浮点值表示"红色".

为了真正看到自动统一转换的特效,在Rec.2020颜色空间中的屏幕外表面绘画小提琴.Rec.2020非常宽的色域,即可表示比常见的默认sRGB颜色空间更鲜艳的颜色.
特别是,与Rec.2020中的纯红色相比,sRGB中最纯的红色相当暗淡.

为了理解它,解释两种不同情况下的步骤.对上半部分,使用not_a_color.SkiaSkSL不知道你打算将它用作颜色,因此直接把提供的原始浮点值传递给SkSL着色器.

即,当SkSL执行时,不论表面颜色空间,not_a_color包含{1,0,0,1}.这会在目的颜色空间中产生最鲜艳的红色(此时,最终像非常鲜艳的红色).

对下半部分,用特殊的layout(color)语法声明了统一颜色.告诉SkSL该变量将用作颜色.只能在vec3(即RGB)或vec4(即RGBA)的统一值上用layout(color).

总之,提供统一数据时,提供的颜色都应是未预乘的sRGB颜色.如果提供广色域颜色,它们可包含[0,1]区间外的值.

SkiaSkPaint接受和存储颜色的方式相同.当SkSL执行时,Skia会把统一值转换为工作颜色空间.此时,即把(开始时为sRGB红色)颜色转换为表示Rec.2020颜色空间中相同颜色的值.

总体特效是使正确标记统一更加暗淡,但这是在使用统一颜色时想要的.这样标记统一颜色,不论目标表面颜色空间,(放在统一中的颜色)源颜色表示相同且一致的颜色.

原始图像着色器

尽管大多数图像都包含应管理颜色颜色,但某些图像包含的数据不是颜色.这包括存储法线,材料属性(如粗糙度),高度图或恰好存储在图像中的其他纯数学数据的图像.

SkSL中使用这类图像时,想用用SkImage::makeRawShader创建的原始图像着色器.它们(包括过滤和平铺)的工作方式与普通图像着色器类似,但有一些主要区别:从未转换颜色空间(忽略图像的颜色空间).
不会自动预乘alpha类型为kUnpremul的图像.不支持双三次过滤.调用makeRawShader时,请求双三次过滤,会返回nullptr.

在此,创建包含球面法线贴图的图像.然后,用浅着色器显示渲染到不同颜色空间时的情况.如果使用普通图像着色器,会把法线颜色转换为工作颜色空间.
这会错误地改变法线.最后绘画中,使用忽略工作颜色空间并返回原始法线原始图像着色器.

在已知颜色空间中工作

SkSL着色器中,你不知道工作颜色空间.对许多特效,这没事.求值图像着色器,简单颜色数学运算,一般正确(如,如果知道应用工作颜色空间总是是sRGB).
但是,对某些特效,在固定已知颜色空间中搞一些数学运算可能很重要.最常见示例是照明,为了获得物理上准确的照明,应该在线性颜色空间中完成数学运算.

为此,SkSL提供了两个内部函数:

vec3 toLinearSrgb(vec3 color);
vec3 fromLinearSrgb(vec3 color);

它们在工作和线性sRGB颜色空间之间转换颜色.该空间使用sRGB原色(色域)和线性传递函数.它使用扩展区间值(低于0.0和高于1.0)表示sRGB色域之外的值.

如,这对应安卓LINEAR_EXTENDED_SRGBAppleextendedLinearSRGB这里这里.
如可在(sRGB)默认工作空间中完成照明数学运算,并在线性空间中再次数学运算.

预乘Alpha

处理透明颜色时,有两个(常见的)可能的表示.Skia称为非预乘和预乘.在Skia管道中,每个SkShader都会返回预乘的颜色.

如果熟悉OpenGL混合,则可当作混合等式.对常见的alpha混合(叫source-over),一般配置混合函数(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA).
Skia混合源过度定义为(GL_ONE,GL_ONE_MINUS_SRC_ALPHA)混合函数.
Skia使用预乘alpha表明:
1,如果从未预乘的SkImage(如PNG)开始,请转换其为SkImageShader,并计算该着色器,生成颜色将是[R*A,G*A,B*A,A],而不是[R,G,B,A].
2,如果SkSL返回透明颜色,则必须确保用A乘以RGB.
3,对更复杂着色器,必须了解哪种颜色预乘与未预乘.如果混合两个颜色在一起,许多操作就没有意义.
可随着alpha的减少,正确预乘颜色会产生平滑渐变.未预乘的颜色会导致错误显示渐变,变得太亮,并随alpha变化而改变色调.

减小SkSL

Skia包含一个压缩器工具,可自动减小RuntimeEffectSkMesh代码的大小.它消除了空格和注释,缩短了函数和变量名,并删除未引用代码.

启用此工具,请添加skia_compile_modules=truegn参数列表中.(在命令行中,键入gn args out/yourbuild以访问参数,或直接编辑out/yourbuild/args.gn文件.
使用ninja再次编译Skia,现在输出目录中将有叫sksl-minify的新工具.

缩小网格程序时,必须提供与SkMeshSpecification对应的struct Varyingsstruct Attributes.为了方便,会从缩小程序中删除这些结构.

sksl-minify带以下命令行参数:
1,输出路径,如MyShader.minified.sksl
2,输入路径,如MyShader.sksl
3,(可选)传递--stringify以在带引号的C++串中包装缩小的SkSL文本.默认,输出文件包含普通SkSL.上面示例代码中缩小的着色器串是使用--stringify创建的.
4,(可选)传递--shader,--colorfilter,--blender,--meshfrag--meshvert来设置程序类型.默认值为--shader.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值