pdf示例.
SkDocument
和SkCanvasAPI
用Skia
的PDF
后端(SkPDF)
的示例,[这里](https://fiddle.skia.org/c/@PDF docs/examples/PDF.cpp).
SkPDF
限制
Skia
的公共API
有几个角落是SkPDF
目前无法处理的,因为或没有已知的客户使用该功能
,或没有简单的PDF
式方法来处理它.
本文档中:
1,drop
表示什么都不画.
2,忽略
表明不带特效
的绘画
3,expand
表明按非PDF
方式实现.表明
栅格化
向量图形,扩展带路径特效
的路径至多个
单独路径,或转换
文本为路径
.
特效 | 文本 | 图 | 其他 |
---|---|---|---|
SkMaskFilter | drop | ignore | ignore |
SkPathEffect | ignore | n/a | expand |
SkColorFilter | ignore | expand | ignore |
SkImageFilter | expand | expand | expand |
不支持SkXferModes | ignore | ignore | ignore |
非渐进SkShader | expand | n/a | expand |
注意:
1,SkImageFilter
:展开SkImageFilter
时,文本作为文本
丢失.
2,SkXferMode
:PDF
自身不支持以下传输模式
:
DstOver,SrcIn,DstIn,SrcOut,DstOut,SrcATop,DstATop
和Modulate
.
SkiaViewer
SkiaViewer
显示一系列展示了Skia
包括SkiaGM
和允许交互
的编程示例指定功能
的幻灯片
.此外,查看器还用来调试和理解Skia
系统的不同部分.
1,观察渲染性能,按统计信息
模式看查看器
可显示平均帧时间
2,试不同的渲染
方法,可在三个
渲染方法之间循环:(在支持的平台上)光栅(raster),OpenGL
和Vulkan
.
可与统计信息
模式一起使用此功能,以查看不同渲染方法
对绘图性能
的影响.
3,显示和操作
你自己的图片.
某些幻灯片需要在程序外部存储
的资源.在<skia-path>/resources
目录中存储
这些资源.
Linux,Macintosh
和Windows
可用普通的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
,请先按安卓
构建说明设置AndroidNDK
和ninja out
目录.此外,还需要安装AndroidSDK
并设置ANDROID_HOME
环境变量.
mkdir ~/android-sdk( cd ~/android-sdk; unzip ~/Downloads/sdk-tools-*.zip )yes | ~/android-sdk/tools/bin/sdkmanager --licensesexport 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,Vulkan
和Raster
列表中选择
后端.
软键/统计
在左边
抽屉里,有一个软键列表
.对应桌面查看器应用
的键盘
命令.如,可切换颜色模式
或统计信息
窗口.可像幻灯片一样过滤它们
.
对动画
幻灯片,还显示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与运行时特效
概述
SkSL
是Skia
的着色语言.SkRuntimeEffect
是一个Skia
的可用来创建行为由SkSL
代码控制的SkShader,SkColorFilter
和SkBlender
对象的C++
对象.
你可在https://shaders.skia.org/
试用SkSL
.语法与GLSL
类似.在Skia
应用中使用SkSL
特效时,需要记住一些(与GLSL
)重要的差异.
差异大多
源于:使用GPU
着色语言,你正在对GPU
管道的一个阶段编程
.使用SkSL
,你正在对Skia
管道的一个阶段编程
.
即,GLSL
片段着色器控制GPU
在光栅化器和混合硬件
之间的整个行为.该着色器
负责计算颜色
,再把生成的颜色填充到管道
的固定函数混合
阶段的颜色.
SkSL
特效作为更大的Skia
管道的一部分存在.当发出画布
绘画操作时,Skia
(一般)会组装单个GPU
的片段着色器
来完成工作.
此着色器
一般包含多个部分
.如,它可能包括:
1,求值
像素是落在所绘画形状
的内部还是外部
(或在边框
上,它可能会应用抗锯齿
).
2,求值
像素是落在剪切区域
内还是外(同样,边界
像素可能有抗锯齿
逻辑).
3,SkPaint
上SkShader
的逻辑.(由于SkShaders::Blend
和下面描述的其他特征)SkShader
可以是对象树
.
4,SkColorFilter
的类似逻辑(由于SkColorFilters::Compose,SkColorFilters::Blend
及下面描述的特征
,也可以是树
).
5,混合
代码(对某些SkBlendModes
,或用SkPaint::setBlender
指定的自定义混合
).
6,转换颜色空间
代码,作为Skia
管理颜色的一部分.
在SkShader,SkColorFilter
或SkBlender
字段中,即使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)
颜色空间.
因此,所有颜色
都更加生动.更重要的是,如果图像
确实在其他颜色空间中,或目标表面
在其他颜色空间中,则该自动转换
是值得的,因为它可确保在用户的屏幕上内容
总是正确.
统一
Skia
和SkSL
不知道你的统一变量
是否包含颜色,因此它不会自动转换
应用颜色.下例中,声明了两个统一:
color
和not_a_color
.SkSL
只是水平淡入
两个统一"颜色"
中的一个,为着色器
的上半
和下半
部分选择不同的统一
.该代码传递
相同的值给两个
统一,{1,0,0,1}
四个浮点值表示"红色"
.
为了真正看到自动统一转换
的特效,在Rec.2020
颜色空间中的屏幕外表面
绘画小提琴.Rec.2020
有非常宽
的色域,即可表示比常见的默认sRGB
颜色空间更鲜艳
的颜色.
特别是,与Rec.2020
中的纯红色相比,sRGB
中最纯的红色
相当暗淡.
为了理解
它,解释两种不同情况下的步骤.对上半
部分,使用not_a_color
.Skia
和SkSL
不知道你打算将它用作颜色
,因此直接把提供的原始浮点值
传递给SkSL
着色器.
即,当SkSL
执行时,不论表面
的颜色空间
,not_a_color
包含{1,0,0,1}
.这会在目的
颜色空间中产生最鲜艳的红色
(此时,最终像非常鲜艳
的红色).
对下半部分,用特殊的layout(color)
语法声明了统一
颜色.告诉SkSL
该变量将用作颜色
.只能在vec3
(即RGB
)或vec4
(即RGBA
)的统一值上用layout(color)
.
总之,提供统一
数据时,提供的颜色都应是未预乘的sRGB
颜色.如果提供广色域
颜色,它们可包含[0,1]
区间外的值.
与Skia
在SkPaint
上接受和存储
颜色的方式相同.当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_SRGB
或Apple
的extendedLinearSRGB
这里和这里.
如可在(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
包含一个压缩器工具
,可自动减小RuntimeEffect
或SkMesh
代码的大小.它消除了空格和注释
,缩短了函数和变量名
,并删除
了未引用代码
.
要启用
此工具,请添加skia_compile_modules=true
到gn
参数列表中.(在命令行中,键入gn args out/yourbuild
以访问参数,或直接编辑out/yourbuild/args.gn
文件.
使用ninja
再次编译Skia
,现在输出
目录中将有叫sksl-minify
的新工具.
在缩小网格
程序时,必须提供与SkMeshSpecification
对应的struct Varyings
和struct Attributes
.为了方便,会从缩小程序中删除这些结构.
sksl-minify
带以下命令行参数:
1,输出
路径,如MyShader.minified.sksl
2,输入
路径,如MyShader.sksl
3,(可选)传递--stringify
以在带引号的C++
串中包装
缩小的SkSL
文本.默认,输出文件
包含普通SkSL
.上面示例
代码中缩小的着色器串
是使用--stringify
创建的.
4,(可选)传递--shader,--colorfilter,--blender,--meshfrag
或--meshvert
来设置程序类型
.默认值为--shader
.