您的位置:首页 > 移动开发 > Android开发

chromium for android v34 2dCanvas硬件绘制实现分析

2014-10-08 10:59 1811 查看
HTMLCanvasElement对应h5的canvas元素。

解析网页遇到canvas元素会创建HTMLCanvasElement实例。

Canvas可以支持2d和3d图形的绘制。

HTMLCanvasElement提供了getContext()接口,返回图形绘制的上下文对象,

对于2d图形返回的是CanvasRenderingContext2D。

CanvasRenderingContext2D提供了网页可调用的所有绘制动作。

CanvasRenderingContext2D的所有绘制命令都转接给了

HTMLCanvasElement::drawingContext()提供的绘制上下文。

HTMLCanvasElement是整个Canvas实现的入口。

我们从这里入手理出2dCanvas的硬件绘制及硬件渲染架构。

一.硬件绘制的实现结构

硬件绘制是指,网页调用的绘制动作,通过HTMLCanvasElement

转给skia库,skia库通过调用GPU命令完成实际的绘制操作。

软件绘制是指skia库在cpu上完成绘制操作。

完成硬件绘制需要:

1.建立HTMLCanvasElement与skia库的GrContext(skia硬件绘制上下文)之间的联系。

2.建立skia库GrContext与GPU之间的联系。

3.创建保存硬件绘制结果的Texture.

完成这3件事,网页调用HTMLCanvasElement的绘制命令经由Skia库调用

实际的GPU操作绘制到保存绘制结果的Texture上。

1.建立HTMLCanvasElement与skia库的GrContext(硬件绘制上下文)之间的联系。

Skia的GrContext封装在webkit::gpu:: GrContextForWebGraphicsContext3D类中。

创建过程如下图:



GrContext是在Canvas2DLayerBridge::create中被创建并保存在SkGpuDevice中。

GrContext创建过程涉及的类图:



GrContext是在Canvas2DLayerBridge::create中被创建并保存在SkGpuDevice中。

GrContext创建过程涉及的类图grcontextwrap.jpg。

CanvasRenderingContext2D的绘制动作转接给刚刚创建的GrContext的过程

(以CanvasRenderingContext2D的fillRect()为例),可以分为三步(A,B,C):

A.CanvasRenderingContext2D::fillRect()--->Canvas2DLayerBridge::create()

中创建的SkDeferredCanvas::drawRect()。



CanvasRenderingContext2D的fillRect()通过HTMLCanvasElement::drawingContext()

传给了ImageBuffer中创建的GraphicsContext,GraphicContext又进一步调用

它包含的SkCanvas::drawRect().GraphicContext包含的SkCanvas是

Canvas2DLayerBridge中创建的SkDeferredCanvas。

这个过程中涉及到的类图:



B.SkDeferredCanvas::drawRect()--->DeferredDevice:: fImmediateCanvas::drawRect()

SkDeferredCanvas::drawRect()调用的是SkDefferdCanvas创建的DeferredDevice中

包含的成员变量SkCanvas* fImmediateCanvas的drawRect().我们看这个fImmediateCanvas的来源.



SkDefferdCanvas创建时传入了SkSurface_Gpu实例作为参数。

SkDeferredCanvas::Create()中以SkSurface_Gpu为参数创建了DeferredDevice。

并将这个DeferredDevice传递给了SkCanvas.可以通过SkCanvas的getDevice()

接口得到DeferredDevice实例。所以DeferredDevice成员变量SkCanvas* fImmediateCanvas是

在SkSurface_Gpu::onNewCanvas()中创建的SkCanvas,并传入了SkGpuDevice作为参数。

这个过程涉及的类图:



C.DeferredDevice:: fImmediateCanvas::drawRect()--->SkCanvas::drawRect().

接下来看以SkGpuDevice为参数创建的SkCanvas的drawRect()的执行流程。



到这,终于看到,CanvasRenderingContext2D的绘制动作转给了GrContext。

2.建立skia库GrContext与GPU之间的联系。

由GrContext的创建过程我们知道GrContetxt被封装在GrContextForWebGraphicsContext3D实例中。

GrContextForWebGraphicsContext3D的构造函数中传入了

WebGraphicsContext3DCommandBufferImpl实例。

chromium for android GPU进程结构分析我们知道,

WebGraphicsContext3DCommandBufferImpl是与GPU进程(线程)通信的入口。

GrContextForWebGraphicsContext3D的构造函数中

GrContext与WebGraphicsContext3DCommandBufferImpl的关联是通过GrGLInterface建立的。

GrGLInterface包含与opengl es对应的接口。

WebGraphicsContext3DCommandBufferImpl::createGrGLInterface()调用

skia_bindings::CreateCommandBufferSkiaGLBinding()生成GrGLInterface,

并将GrGLInterface包含的接口绑定到WebGraphicsContext3DCommandBufferImpl对应的接口上。

GrGlInterface被传给了GrContext.这样在GrContext中通过GrGlInterface调用的操作

实际调用的是WebGraphicsContext3DCommandBufferImpl的gl操作,

并由WebGraphicsContext3DCommandBufferImpl通过CommandBuffer结构调用到

实际的GPU进程(线程中)中提给的真正gl操作。参见chromium for android GPU进程结构分析。

下图是GrContext::drawRect()调用到WebGraphicsContext3DCommandBufferImpl的gl操作的过程:



3.创建保存硬件绘制结果的Texture.

以下是具体创建过程:



这个texture由GrGpuGL::onCreateTexture()调用WebGraphicsContext3DCommandBufferImpl

接口GenTextures()生成,并保存在GrGLTexture实例中。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: