Chinaunix首页 | 论坛 | 博客
  • 博客访问: 86668
  • 博文数量: 20
  • 博客积分: 553
  • 博客等级: 中士
  • 技术积分: 220
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-09 15:01
文章分类
文章存档

2010年(20)

分类:

2010-03-16 11:47:10

Android 中的图形系统采用 Client/Server 架构。Server (即SurfaceFlinger) 主要由 C++ 代码编写而成。Client 端代码分为两部分,一部分是由 Java 提供 的供应用程序使用的 API,令一部分则是用 C++ 写成的底层实现。下图概要介 绍了 Android 图形系统的架构以及使用的主要组件。

SurfaceFlinger

SurfaceFlinger 在整个图形系统中担任 server 角色,它负责将各个 surface 根据 Z order 合成 (composer) 起来。

Surface

Android 图形系统中一个重要的概念和线索是surface。View及其子类(如 TextView Button)要画在surface上。每个surface创建一个Canvas对象 (但 属性时常改变),用来管理view在surface上的绘图操作,如画点画线。每个 canvas对象对应一个bitmap,存储画在surface上的内容。

每个Surface通常对应两个buffer,一个front buffer 一个back buffer。其中, back buffer就是canvas绘图时对应的bitmap (研究 android_view_Surface.cpp::lockCanvas)。因此,绘画总是在back buffer上, 需要更新时,则将back buffer和front buffer互换。

The window is tied to a Surface and the ViewRoot asks the Surface for a Canvas that is then used by the Views to draw onto. After View draw its data to canvas ViewRoot will call surface.unlockCanvasAndPost(canvas) to schedule surfaceFlinger::composeSurfaces() which do the actually display to display panel. SurfaceFlinger handles to transfers drawn data in canvas to surface front buffer or backbuffer.

Except for SurfaceViews different views within the same ViewRoot share the same surface.

layer

每个surface又对应一个layer SurfaceFlinger负责将各个layer的front buffer合成(composite)绘制到屏幕上。

A layer is something that can be composited by SurfaceFlinger (should have been called layerFlinger). There are several types of layers if you look in the code in particular the regular ones (layer.cpp) they are backed by a Surface and the layerBuffer (very badly chosen name) which don't have a backing store but receive one from their client. . Note that the GGLSurface type should have been called GGLBuffer.

Multiple layers are just composited to the final buffer in their Z order.

创建一个 Surface 的过程

Android 创建一个 Surface 的过程如下面的序列图所示:

研究一个surface如何创建的关键路径如下:

1. frameworks/base/core/java/android/view/Surface.java — Surface::Surface ()。

2. frameworks/base/core/jni/android_view_Surface.cpp — Surface_init ()。

在这个函数中SurfaceComposerClient 对象被创建。

3. frameworks/base/libs/ui/SurfaceComposerClient.cpp — SurfaceComposerClient::SurfaceComposerClient ().

这 个函数非常重要,在这里建立了client和server之间的桥梁。通过函数_get_surface_manager()获得了一个指向 server的IBinder 对象(具有ISurfaceComposer接口),之后通过这个IBinder就可以跨进程访问Server的功能。接着调用 ISurfaceComposer::createConnection()创建并返回了一个ISurfaceFlingerClient的 IBinder。

4. frameworks/base/libs/ui/SurfaceComposerClient.cpp — SurfaceComposerClient::createSurface().

这个函数中,利用前面获得的ISurfaceFlingerClient的IBinder调用其createSurface接口。

5.frameworks/base/libs/surfaceflinger/SurfaceFlinger.cpp — BClient::createSurface ()。

BClient由ISurfaceFlingerClient派生而来。

6.frameworks/base/libs/surfaceflinger/SurfaceFlinger.cpp — SurfaceFlinger:: createSurface()。

这个函数为Surface创建一个对应的layer。

上述关键路径中,1,2,3,4运行于client进程中,而5,6运行与server进程中。server作为一个service提供给client访问。

与图形相关的代码分析

与图形相关的代码主要位于下列目录:

1. frameworks/base/graphics/java/android/graphics

2.frameworks/base/core/java/android/view

3.frameworks/base/core/java/android/widget

4.frameworks/base/opengl/

5.frameworks/base/libs/ui

6.frameworks/base/libs/surfaceflinger

7.frameworks/base/core/jni/android/graphics

8.frameworks/base/core/jni/android/opengl

9.frameworks/base/core/jni/android/android_view_*.cpp

10.external/skia

android.graphics android.view和android.widget

1.frameworks/base/graphics/java/android/graphics

2.frameworks/base/core/java/android/view

3.frameworks/base/core/java/android/widget

android.graphics android.view和android.widget 功能和其他类似的图形库如 Qt/Gtk+差不多,分别提供基本的图形原语(如画点画线,设置图形上下文等), 事件机制,以及开发图形用户界面的控件等。canvas 用于开发2D图形, Surface 代表一个可供图形系统绘制的surface。可在其上绘制2D活3D图形。

frameworks/base/opengl/

这个目录包含opengel的接口以及软件实现。在

http://developer.android.com/guide/topics/graphics/opengl.html

有详细介绍如何使用android.opengl开发3d graphics。

external/skia

skia与cairo功能相当,封装底 层的图形硬件,为上面的图形库提供最基础的操 作图形硬件的原语。关于 skia 可参考《淺談 Google Skia 圖形處理引擎》2和 《Android 的图形引擎 Skia》3两篇文章。

frameworks/base/libs/ui 和 frameworks/base/libs/surfaceflinger

ISurface 定义了基础的Surface接口,供图形系统客户端 (应用)和server端 (即surfaceflinger)交互。

BpSurface是ISurface的派生类,提供接口供server 调用客户端功能;

BnSurface 是ISurface的另一个派生类,提供接口供客户端调用server功能。当 server 收到来自客户端 (通过BnSurace)的调用请求后,如registerBuffers postBuffer等,BnSurface::onTransact被触发。

Surface (layerbaseClient的私有类)是BnSurface的派生类。

SurfaceBuffer (SurfaceBuffer的私有类)是Surface的派生类。

ISurfaceComposer 定义了基础的接口,供客户端和server端交互。

BpSurfaceComposer是一个派生类,提供接口供server调用客户端功能;

BnSurfaceComposer是另一派生类,提供接口供客户端调用server功能。类 SurfaceFlinger 由BnSurfaceComposer派生而来。

SurfaceComposerClient直接供客户端使用,调用ISurface (BnSurface)和 ISurfaceComposer (BnSurfaceComposer)以及 ISurfaceFlingerClient 接口与server交互。

BClient 派生自ISurfaceFlingerClient (BnSurfaceFlingerClient),调用server的createSurface,真正创建一个surface。每个surface对应一个layer.

egl_native_window_t 定义了一个本地window类 。这个类提供了对本地window 的所有描述以及用于egl (opengl 与本地图形系统的接口)操作本地windwo的所 有方法。

EGLNativeSurface是egl_native_window_t的一个派生类。

EGLDisplaySurface是EGLNativeSurface的派生类。 EGLDisplaySurface 是一个 非常重要的类,在这个类里,真正打开framebuffer设备(/dev/graphics/fb0 或 者/dev/fb0),并将这个设备封装成EGLDisplaySurface的形式供server使用。函 数mapframeBuffer打开framebuffer 创建两个缓冲区,(一个是on screen front 缓冲区, 另一个back buffer 可能位于offscreen framebuffer也可能 位于系统内存)。 函数swapBuffers将back buffer内容拷贝到front buffer中。

DisplayHardware 类中初始化了egl系统,并为本地窗口对象EGLDisplaySurface 创建了对应的EGLSurface 对象。surfaceflinger 使用DisplayHardware去和本地窗口打交道。

jni

7.frameworks/base/core/jni/android/graphics

8.frameworks/base/core/jni/android/opengl

9.frameworks/base/core/jni/android/android_view_*.cpp

这些目录下的代码在Java层的graphics 组件和native (c++)组件之间衔接,将java层的功能调用转换到对应的本地调用。

hardware/libhardware实现了HAL(Hardware Abstraction Layer)层,copybit device是其中一个模块。

android中,与图形相关的上层java package包括:
android.graphics,
android.view,
android.widget
android.opengl

android.graphics, android.view和android.widget功能和其他类似的图形库如Qt/Gtk+差不多,分别提供基本的图形原语(如画点画线,设置图形 上下文等),事件机制,以及开发图形用户界面的控件等。canvas 用于开发2D图形,而android.opengl用于开发3d graphics,在http://developer.android.com/guide/topics/graphics/opengl.html 有详细介绍如何使用。

本文重点放在研究android.graphics之下的和图形硬件设备交互的层。

Canvas: the Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing). Via the Canvas, your drawing is actually performed upon an underlying Bitmap, which is placed into the window

The window is tied to a Surface and the ViewRoot asks the Surface for a
Canvas that is then used by the Views to draw onto. After View draw its data to canvas, ViewRoot
will call surface.unlockCanvasAndPost(canvas) to schedule surfaceFlinger::composeSurfaces() which do the actually display to display panel. SurfaceFlinger handles to transfers drawn data in canvas to surface front buffer or backbuffer

Except for SurfaceViews, different views within the same ViewRoot share the same surface.


frameworks/base/graphics/java/android/graphics/Canvas.java 提供基础的绘制图形原语。
frameworks/base/core/jni/android/graphics/Canvas.cpp 提供native的绘制图形原语。Canvas.java中的函数通过JNI调用Canvas.cpp中的函数。但Canvas.cpp中的函数并不是最 终实现,仅仅是一个中间函数。
external/skia/src/core/SkCanvas.cpp提供最终函数实现。Canvas可以画在一个bitmap上,之后传给surface。

Java API 包括Surface.java 以及 SurfaceSession.java,由客户端应用使用;对应的c++代码创建SurfaceComposerClient。而 SurfaceComposerClient建立与surfaceflinger server的连接。

Surface的概念:
每个surface有一个front buffer和一个back buffer。每个window有一个对应的surface. window内容绘制在view的bitmap后传给surface。surface作为一个service提供给系统使用,由service manager(frameworks/base/services/java/com/android/server/SystemSever.java, frameworks/base/cmds/system_server/library/system_init.cpp)初始化。surface server的代码位于frameworks/base/libs/surfaceflinger下。



frameworks/base/libs/ui下提供:
EGLDisplaySurface.cpp 中函数真正和图形设备framebuffer打交道。函数mapFrameBuffer打开图形设备framebuffer(/dev/graphics /fb0或者/dev/fb0),然后定义framebuffer的frontbuffer和backbuffer。backbuffer可能位于 framebuffer上,也可能是一块system memory(由malloc分配),然后函数swapBuffers将back buffer内容拷贝到front buffer中。如果copybit device实现的话,拷贝可以使用硬件加速。

hardware/libhardware实现了HAL(Hardware Abstraction Layer)层,copybit device是其中一个模块。

frameworks/base/libs/surfaceflinger中提供:
DisplayHardware/DisplayHardware.cpp调用EGLDisplaySurface.cpp中的函数,初始化egl library,创建EGLSurface

阅读(4633) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~