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等缓存管理机制
由于OpenGL编程本身很复杂,东西也很多,这里只是介绍一下用法和流程框架,有兴趣研究的可按上述问题细看。

二、用法

/*获取OpenGL上下文*/
GrContextFactory contextFactory;
GrContext* context = contextFactory.get(GrContextFactory::kNative_GLContextType);
/*创建指定大小格式Surface,并由Surface中取出Canvas*/
const SkImageInfo info = SkImageInfo::MakeN32Premul(720,1080);
SkSurface* surface = SkSurface::NewRenderTarget(context, info);//实际上是创建一个纹理,并创建相应的fbo与之绑定,以作为渲染目标
//或者用 NewScratchRenderTarget,这个会用缓存过的目标纹理
SkCanvas* canvas = surface->getCanvas();
/*执行绘制*/
/*canvas->drawColor(0x0);*/
/*..........*/
/*..........*/
/*..........*/
/*绘制完成,取出像素*/
SkBitmap output;
output.setInfo(info);
canvas->readPixels(&output);
/*又或者读到GraphicBuffer上*/
/*输入 ANativeWindow_Buffer outBuffer*/
canvas->readPixels(info, outputBuffer.bits, outputBuffer.stride*4/*ARGB*/, 0, 0);

Skia创建GPU上下文时,其Surface并不关联Android里面的显示系统,因此是无法直接渲染上屏的,在绘制完成之后需要额外的一次readPixels,也即内存拷贝,这使其不适合做实时渲染。只是在做比较复杂的效果,如Bicubic插值、光照、模糊时,可以用一用。
关于 Skia的特效,可以看 include/effects 和 src/effects 目录下面的代码,这里面是CPU方式实现的。由于很少见用到,之前并没有介绍。
对应的gpu特效实现见 include/gpu 和 src/gpu/effects目录下的代码。

三、流程与框架

SkGpu的一次绘制基本流程如下:

Created with Raphaël 2.1.2SkCanvasSkGpuDeviceGrContextGrDrawTargetGrGpuGrGLInterface

SkCanvas:如之前章节所述,下发命令,保留Layer
SkGpuDevice:处理退化情况,将SkPaint转化为GrPaint
GrContext:构建形(顶点Vertex)且处理抗锯齿,描述色(GrDrawState)
GrDrawTarget:描述绘图目标,起接口作用,将材料打包为Drawinfo,由子类执行 onDraw方法。
GrGpu:设定Shader、设定顶点,调用OpenGL接口渲染
GrGLInterFace:由于各个厂商支持的OpenGL标准版本有所不同,且一些厂商会增加一些接口,这一层做一个API适配,这样平台相关的代码就集中在此层级。

时间: 2024-10-02 04:55:41

Skia深入分析8——Skia的GPU绘图的相关文章

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

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

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

前言:         断断续续跟Android的skia库打了两年交道,如今交接掉了,便写写关于skia的一些知识,也算了结一段职业生涯. 找了找网上关于skia的文章,基本上都过时了,讲得也不怎么深入.虽然Skia只是一个2D引擎,但其深度优化的算法.完善的渲染体系和精炼的代码框架,还是很值得借鉴的.         PS:文章所依据的代码为目前最新的Android 5.0.2. 基本章节规划如下: 1.Skia的上下文(即本章) 2.Skia基本渲染流程与框架 3.Skia图像绘制分析 4

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深入分析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深入分析9——延迟渲染和显示列表

概念 Android的硬件加速,是先将绘制命令存储起来,然后回放,作为软件绘制的引擎Skia中同样有这样的机制.在Android 4.4的版本中又加入了延迟渲染的Canvas,它相当于默认使用显示列表的Canvas. 先得到显示列表,再进行渲染,便有机会基于绘制API的整体情况做优化调度.比如使用GPU加速,裁剪过度绘制等.从原理上看,很可能在这一层级做比较大的效率提升,不过,由于Android既定的渲染框架限制,尽管Google在这方面做的东西很多,生效场景很少,收益也很有限. 显示列表--S