Skia深入分析1——skia上下文

前言:

        断断续续跟Android的skia库打了两年交道,如今交接掉了,便写写关于skia的一些知识,也算了结一段职业生涯。
找了找网上关于skia的文章,基本上都过时了,讲得也不怎么深入。虽然Skia只是一个2D引擎,但其深度优化的算法、完善的渲染体系和精炼的代码框架,还是很值得借鉴的。

        PS:文章所依据的代码为目前最新的Android 5.0.2。

基本章节规划如下:
1、Skia的上下文(即本章)
2、Skia基本渲染流程与框架
3、Skia图像绘制分析
4、Skia路径绘制分析
5、Skia文本绘制分析
6、Skia编解码架构分析

7、区域解码分析
8、Skia-gpu简介
9、Skia的性能瓶颈分析
10、延迟渲染机制


一、Skia在Android中的地位

1、规定2D绘制API
2、规定图像数据结构
3、承担编解码调度和软件渲染职责

二、Android系统中主要使用Skia的场景

Skia调用关系简图

1、界面绘制(lockCanvas——draw——unlockCanvas流程)
(1)UI控件,未开启硬件加速。由performTravelsals——drawSoftware调入。
Android显示系统是最复杂的Android最复杂的子系统,没有之一,这里只说明软件绘制时的一个基本过程:
a、计算布局,看是否需要更新View。
b、计算所有需要更新的View的区域,计算其最小外包矩形,即dirtyRect
c、由Surface去Lock一个Canvas,Lock时指定dirtyRect,这里涉及gui的buffer轮换机制,会去获取一块未在显示的Buffer,由于换了buffer,在gui模块会去拷贝上一帧非dirtyRect的部分。
d、执行根View的draw方法,递归调用所有子View的onDraw方法。由于Canvas对应的是软件绘制的canvas,所有绘制操作经过Canvas——SkiaCanvas——SkCanvas的流程,由skia引擎执行。(AndroidL上在jni(libandroid_runtime)处作了一层SkiaCanvas的封装,4.4及以前是Canvas——SkCanvas)
e、完成绘制,让Surface去unlockCanvas,将绘制好的Buffer送显。
(2)SurfaceView,这个是由应用显式实现lockCanvas——draw——unlockCanvas流程。
2、图像处理
这种情况下,开发者自行基于目标Bitmap创建Canvas,调用Canvas的API绘制图像,一般是作图像的缩放、旋转处理,也可以加入渐变特效。(不是 lockCanvas 或 继承 onDraw 方法中传入的Canvas,就别想拿去上屏了)
3、图像编解码
Skia对各种类型的图片作了适配,提供统一的接口,开发者调用BitmapFactory,BitmapFactory进一步调用jni——skia。
(1)关于图像全解,这部分调用逻辑看上去简单,实际上对于输入输出流的处理还是比较复杂的,涉及Java的流——Skia规定的流——对应解码库的流两重转换。
(2)关于区域解码,这部分是google为平衡内存——性能——显示速度而设计的方案,一些Android机器上的图库打开照片时有一块一块渐渐清晰的过程,就是区域解码然后局部刷新的结果。
区域解码分成两步:
a、创建tileIndex,以便查找某个区域所对应的码流位置。
b、解码:输入指定区域,按照tileIndex查找对应码流,将对应区域的图片解出来,这个过程一般会调用多次。

4、番外:webview软件渲染
由于libchromeview将libskia以静态方法集成进去,便跟系统的skia库没什么关系了。对Android系统而言是统一的webview显示框架。

三、skia相关的库简介

Skia相关模块

1、调用skia的库
libandroid_runtime:framework.jar的jni实现,链接framework和lib库的桥梁
hwui:2D硬件加速库,使用skia的数据格式
libchromeview:浏览器引擎,webview相关

2、Skia使用的库

(1)图片编解码库
libjpeg
libpng
libgif
webp
(2)字体解析
freetype
具体内容会在后续章节中讲述。

时间: 2024-08-03 03:39:07

Skia深入分析1——skia上下文的相关文章

Skia深入分析8——Skia的GPU绘图

Skia的GPU绘图 一.Skia-GPU概述 在Android4.2到Android5.0的过程中,skia中开发较频繁的部分莫过于GPU加速部分和延迟渲染机制,尽管目前来看几乎没有用到,但后续很可能会在Frameworks层引入. 在Android上面,只可能使用OpenGL,因此作为使用OpenGL的绘图引擎,关注如下要点即可: 1.OpenGL上下文如何建立(关系到如何显示绘制结果) 2.顶点如何生成 3.着色器如何管理,特效怎么设置 4.纹理.vbo.字体cache等缓存管理机制 由于

Skia深入分析5——skia文字绘制的实现

文字绘制主要包括编码转换(主要是中文).字形解析(点线或image)和实际渲染三个步骤.在这个过程中,字形解析和实际渲染均是耗时步骤.Skia对文字解析的结果做了一套缓存机制.在中文字较多,使用多种字体,绘制的样式(粗/斜体)有变化时,这个缓存会变得很大,因此Skia文字缓存做了内存上的限制. 1.SkPaint 文字绘制与SkPaint的属性相关很大,先回头看下SkPaint相关的属性 class SkPaint { private SkTypeface* fTypeface;//字体 SkP

Skia深入分析6——skia中图像编解码代码概述

1.API和自注册机制 Skia中编码解码图片都只需要一行代码: SkBitmap bitmap; SkImageDecoder::DecodeFile("test.xxx", &bitmap);//由文件名解码,自动推断图片类型 //或者由流解码 SkFILEStream stream("test.xxx"); SkImageDecoder::DecodeStream(stream, &bitmap);//由输入流解码,自动推断图片类型 //编码

Skia深入分析4——skia路径绘制的实现

Skia路径绘制代码分析 路径绘制尽管使用频率相对于图像绘制.文本绘制低,但却是非常重要的一个基本特性.所有不规则图形(椭圆.圆角矩形.三角形.简单的文字),最后都避不开路径绘制. 而且,若自己实现一个2D引擎,这块内容是很具有参考意义的,用OpenGL的话,图像采样等都很少关注了,对对坐标就好.但菱角.圆弧.曲线等如何绘制仍然是一个难题,这时就可以参考Skia中drawPath的实现. 由于涉及较多的图形学知识,本章就不讲相关公式了,只讲讲基本的流程.一.SkPath类 在之前的图像绘制并没有

Skia深入分析3——skia图片绘制的实现(2)

此篇讲图像采样一.采样流程在上一节里的流程图有写到,图像绘制的实际渲染发生在某个blitter的blitRect函数中,我们先看一个具体的blitRect实现. void SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) { SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() && y

Skia深入分析10——Skia库的性能与优化潜力

Skia库性能与优化潜力 图形/渲染 算法/架构 作为图形渲染引擎,性能上是非常重要的,按通常Android手机60帧的刷新率,绘制一帧的总时间只有16ms,可谓是毫厘必争.提升性能到最后,就必然跟不同CPU的特性打交道,毕竟一个SIMD下去,好做的提升5.6倍,不那么好做的也达到2.3倍,收益极其可观. SIMD,在intel上是SSE,在arm上是neon,在mips上则是其dsp功能.使用SIMD,需要代码架构是满足内存连续性要求的,否则需要重构,Skia作为正常的图形渲染引擎,采用行渲染

Skia深入分析3——skia图片绘制的实现(1)

此篇讲Skia绘制图片的流程,在下一篇讲图像采样原理.混合和抖动技术1.API用法(1)drawBitmapvoid drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, const SkPaint* paint = NULL);将bitmap画到x,y的位置(这本身是一个平移,需要和SkCanvas中的矩阵状态叠加).(2)drawBitmapRect 和 drawBitmapRectToRectvoid drawBit

Skia深入分析2——skia渲染架构

一.渲染层级从渲染流程上分,Skia可分为如下三个层级: 1.指令层:SkPicture.SkDeferredCanvas->SkCanvas 这一层决定需要执行哪些绘图操作,绘图操作的预变换矩阵,当前裁剪区域,绘图操作产生在哪些layer上,Layer的生成与合并. 2.解析层:SkBitmapDevice->SkDraw->SkScan.SkDraw1Glyph::Proc 这一层决定绘制方式,完成坐标变换,解析出需要绘制的形体(点/线/规整矩形)并做好抗锯齿处理,进行相关资源解析并

Skia深入分析7——区域解码

Skia深入分析7--区域解码 1.概述 -当图片很大时,解码速度缓慢,占用内存很高,并且,当图片超过一定尺寸时,无法做纹理上传和显示(这跟GPU能力有关,一般的GPU是8192*8192).这时只好做下采样,但会牺牲图片显示的质量. -对于图库等需要清晰浏览图片的应用,不可能设置一个下采样率去解决这一问题,因此,Google加入了区域解码这个功能,使我们可以从原始的图片文件中,解出一部分区域完整的图片内容. -区域解码的难点主要在于定位像素区域所对应的文件位置,这个需要图像编码时有一定的连续性