《Android图形显示.doc》由会员分享,可在线阅读,更多相关《Android图形显示.doc(11页珍藏版)》请在三一文库上搜索。
1、工作总结Android 图形显示在使用Marvell PXA310平台开发android过程中, 一直碰到图形显示相关问题。一直也没下定决心理一理图形显示相关流程,一方面是因为这块技术涉及到一些图形算法,看起来比较费劲,另一方面原因可以归结为自己的浮躁。直到如今,仍然碰到图形显示相关的问题,而仍是跟几个月前一样束手无策,才决定写下这篇文档。不求完全厘清图形显示相关代码,只要能够由此而引入门即功德圆满。1、 Overview Android中的图形系统采用Client/Server架构。Server (即SurfaceFlinger)主要由c+代码编写而成。Client端代码分为两部分,一部分是
2、由Java提供的供应用使用的api,另一部分则是由c+写成的底层实现。下图概要介绍了android图形系统的架构以及使用到的主要组件。2、 Surface概念 Android图形系统中一个重要的概念和线索是surface。View及其子类(如TextView, Button)要画在surface上。每个surface创建一个Canvas对象(但属性时常改变),用来管理view在surface上的绘图操作,如画点画线。每个canvas对象对应一个bitmap,存储画在surface上的内容。每个surface有一个front buffer和一个back buffer。每个window有一个对应的
3、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下。3、 有几个对象与Surface概念紧密相关1. Java
4、 Surface (frameworks/base/core/java/android/view/Surface.java)。该对象被应用间接调用(通过SurfaceView, ViewRoot等), 应用需要创建surface,(并同时创建canvas), 将图形绘制到这个对象上并最终投递到屏幕上。2. C+ Surface (frameworks/base/libs/ui/Surface.cpp。 这个对象被Java Surface通过Jni 调用,实现Java Surface 的功能3. ISurface (以及其派生类BnSurface)。这个对象是应用和server之间的接口。C+
5、Surface创建这个ISurface (BnSurface)并发送命令,如更新surface内容到屏幕上。Server端接受这个命令并执行相应操作。4、 研究一个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/li
6、bs/ui/SurfaceComposerClient.cpp SurfaceComposerClient:SurfaceComposerClient (). 这个函数非常重要,在这里建立了client和server之间的桥梁。通过函数_get_surface_manager()获得了一个指向server的IBinder 对象(具有ISurfaceComposer接口),之后通过这个IBinder就可以跨进程访问Server的功能。接着调用ISurfaceComposer:createConnection()创建并返回了一个ISurfaceFlingerClient的IBinder。4.fra
7、meworks/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/surfacefl
8、inger/SurfaceFlinger.cpp - SurfaceFlinger: createSurface()。这个函数为Surface创建一个对应的Layer。上述关键路径中,1,2,3,4运行于client进程中,而5,6运行与server进程中。server作为一个service提供给client访问。与图形相关的代码主要位于下列目录:1、frameworks/base/graphics/java/android/graphics2、frameworks/base/core/java/android/view3、frameworks/base/core/java/android/w
9、idget4、frameworks/base/opengl/5、frameworks/base/libs/ui6、frameworks/base/libs/surfaceflinger7、frameworks/base/core/jni/android/graphics8、frameworks/base/core/jni/android/opengl9、frameworks/base/core/jni/android/android_view_*.cpp10、external/skia5、 OverLay2 Marvell显示驱动除了base frame buffer设备fb0外,加入了fb1
10、(overlay1)、fb2(overlay2)、fb3(cursor fb)。在此仅讨论fb2,主要有2个应用: 1、camera record时候,负责把数据刷新到LCD上; 2、Opencore中output2overlay /*这里display_config主要完成pDisplayCfg-overlay映射到fb2设备驱动文件*/问题:Fb2驱动文件收到数据后,如何与fb0合并, 刷新到LCD?6、 M2D最下层是Graphics Controller,这就是CPU提供的硬件加速单元,提供画直线,填充和各种blit功能。这个在Monahans_L_LV_Processor_Dev_M
11、an_Vol_III.pdf里有详细描述。再上层是驱动程序,它对Graphics Controller的寄存器进行包装,为应用程序提供设备文件/dev/m2d。m2d_append 函数负责向命令队列中写入要执行的命令:static int m2d_append(struct m2d_device *dev, void *usrbuf, size_t len) volatile gcu_regs_t *gr = dev-gcu_regs; unsigned int tail_room, head_room; unsigned long exhead = gr-gcrbexhr; unsigne
12、d long tail = dev-ring_tail_dma; unsigned long base = dev-ring_addr_dma; unsigned long size = dev-ring_size; unsigned char *ring_addr = (unsigned char *)dev-ring_addr; if (tail = exhead) tail_room = size - (tail - base); head_room = exhead - base; else tail_room = exhead - tail; head_room = 0; if (t
13、ail_room = len) if (copy_from_user(ring_addr + (tail - base), usrbuf, len) return -EFAULT; tail += len;#ifdef FILL_NOP else if (head_room = len) m2d_fill_nop(ring_addr + (tail - base), tail_room);#else else if (head_room + tail_room = len) if (copy_from_user(ring_addr + (tail - base), usrbuf, tail_r
14、oom) return -EFAULT; usrbuf += tail_room; len -= tail_room;#endif if (copy_from_user(ring_addr, usrbuf, len) return -EFAULT; tail = dev-ring_addr_dma + len; else return -ENOSPC; if (tail - base = size) tail = base; switch_m2d_clk(1); dev-ring_tail_dma = tail; gr-gcrbtr = tail; return 0;执行完成后,GCU会通过中
15、断通知CPU:static int m2d_gcu_irq(int irq, void *dev_id) struct m2d_device *dev = (struct m2d_device *)dev_id; volatile gcu_regs_t *gr = dev-gcu_regs; unsigned long status = gr-gciscr & gr-gciecr; if (irq != IRQ_GRPHICS) return IRQ_NONE; /* FIXME: what if this interrupt occurs with no current context *
16、in execution */ if (status & (GCISCR_PF_INTST | GCISCR_IIN_INTST | GCISCR_IOP_INTST) m2d_interrupt_err(dev, gr); if (status & GCISCR_EEOB_INTST) m2d_interrupt_eeob(dev, gr); return IRQ_HANDLED;再上层是函数库,它对Graphics Controller提供的基本功能进行包装,然后通过/dev/m2d的ioctrl把命令发给Graphics Controller。这里的大部分函数的功能只是将数据打包,然后通
17、过ioctrl把命令传递给驱动程序,如:int m2d_color_fill( struct m2d_context *ctx, struct m2d_op_region *opr) int len = 0; fprintf(stdout, %s:%dn, _func_, _LINE_); if (ctx = NULL) return -1; CHECK_BOUNDARY( opr-dx0, opr-dy0, opr-width, opr-height, ctx-dstbuf); SETUP_CFILL_IMM(ctx-cmdbuf.cb_ptr, len, opr-dx0, opr-dy0,
18、 opr-width, opr-height, ctx-fill_color_format, ctx-fill_color_value); UPDATE_CMDBUF(ctx, len); fprintf(stdout, %s:%dn, _func_, _LINE_); return len;打包数据:#define SETUP_CFILL_IMM(buf, len, x, y, w, h, pf, c) do fprintf(stdout, SETUP_CFILL_IMM: x=%d y=%d w=%d h=%dn,x, y, w, h); uint32_t f = GCU_PXLFMT_F
19、ORMAT(pf); if (f) 0x0a) buf0 = GC_CFILL_IMM | (f) 8) | 0x04; len = 5; buf4 = (uint32_t)(c); else if (f) = 0x0B) buf0 = GC_CFILL_IMM | (f) 32); buf5 = (uint32_t)(c); else len = -ERR_IPF; break; buf1 = (x); buf2 = (y); buf3 = (h) cmdbuf.cb_ptr, (len); (context)-cmdbuf.cb_ptr += (len); (context)-cmdbuf.cb_len += (len) cmdbuf.cb_len + CMDBUF_SAFE_ROOM CMDBUF_SIZE) _m2d_submit(context), 0); while (0)再上层包括两个部分,gcu对m2d_lib进一步包装,给视频播放器调用的。copybit插件是给OpenGL调用的。7、 Copybit11
链接地址:https://www.31doc.com/p-2736358.html