商城网站做推广wordpress woo
news/
2025/9/28 19:34:33/
文章来源:
商城网站做推广,wordpress woo,推广文章,wordpress评论通知代码6这篇文章非常好#xff0c;必须转载。目录(?)[-] Kernel Space Display架构介绍函数和数据结构介绍函数和数据结构介绍函数和数据结构介绍数据流分析初始化过程分析User Space display接口Kernel display接口典型应用flow分析介绍 Surface manager#xff08;surface flinge… 这篇文章非常好必须转载。 目录(?)[-] Kernel Space Display架构介绍函数和数据结构介绍函数和数据结构介绍函数和数据结构介绍数据流分析初始化过程分析User Space display接口Kernel display接口典型应用flow分析介绍 Surface managersurface flinger简介架构分析流程分析根据前面的介绍surfaceflinger作为一个server process上层的应用程序作为client通过Binder方式与其进行通信。Surfaceflinger作为一个thread这里把它分为3个部分如下开发的经验分享 Display Driver的工作内容开发过程 配置Power和IOPorting LCD初始化序列LCD初始化过程的调试LCD的调整其他 Android display架构分析一 http://hi.baidu.com/leowenj/blog/item/429c2dd6ac1480c851da4b95.html 高通7系列硬件架构分析 如上图高通7系列 Display的硬件部分主要由下面几个部分组成 A、MDP 高通MSM7200A内部模块主要负责显示数据的转换和部分图像处理功能理如YUV转RGB放大缩小、旋转等。MDP内部的MDP DMA负责数据从DDR到MDDI Host的传输可以完成RGB之间的转换如RGB565转成RGB666这个转换工能载目前的code 中没有使用。 B、MDDI 一种采用差分信号的高速的串行数据传输总线只负责数据传输无其它功能其中的MDDI Hosat提供并行数据和串行数据之间的转换和缓冲功能。由于外面是VGA的屏幕数据量较大为了减少对EBI2总线的影响传输总线使用MDDI而非之前的EBI2。 C、MDDI Bridge 由于现在采用的外接LCD并不支持MDDI接口故需要外加MDDI转换器即MDDI bridge来把MDDI数据转换成RGB接口数据。这里采用的EPSON MDDIBridge还有LCD Controller功能可以完成其它一些数据处理的功能如数据格式转换、支持TV-OUT、PIP等并且还可以提供一定数量的GPIO。目前我们主要用它把HOST端MDDI传递过来的显示数据和控制数据初始化配置等转换成并行的数据传递给LCD。 D、LCD module 主要是LCD Driver IC 和TFT Panel负责把MDDI Bridge传来的显存中的图像示在自己的 Panel上。 Android display架构分析二 http://hi.baidu.com/leowenj/blog/item/3fe59f740a6fee17b051b991.html Android display SW架构分析 下面简单介绍一下上图中的各个Layer *蓝色部分用户空间应用程序 应用程序层其中包括Android应用程序以及框架和系统运行库和底层相关的是系统运行库而其中和显示相关的就是Android的Surface Manager, 它负责对显示子系统的管理并且为多个应用程序提 供了2D和3D图层的无缝融合。 *黑色部分HAL层在2.2.1部分会有介绍 *红色部分Linux kernel层 Linux kernel其中和显示部分相关的就是Linux的FrameBuffer它是Linux系统中的显示部分驱动程序接口。Linux工作在保护模式下User空间的应用程序无法直接调用显卡的驱动程序来直接画屏FrameBuffer机制模仿显卡的功能将显卡硬件结构抽象掉可以通过 Framebuffer的读写直接对显存进行操作。用户可以将Framebuffer看成是显示内存的一个映像将其映射到进程地址空间之后就可以直接进行读写操作而写操作可以立即反应在屏幕上。这种操作是抽象的统一的。用户不必关心物理显存的位置、换页机制等等具体细节。这些都是由 Framebuffer设备驱动来完成的。 *绿色部分HW驱动层 该部分可以看作高通显卡的驱动程序和高通显示部分硬件相关以及外围LCD相关的驱动都被定义在这边比如上述的显卡的一些特性都是在这边被初始化的同样MDP和MDDI相关的驱动也都定义在这里 User Space Display功能介绍 这里的User Space就是与应用程序相关的上层部分参考上图中的蓝色部分其中与Kernel空间交互的部分称之为HALHW Abstraction Layer。 HAL其实就是用户空间的驱动程序。如果想要将 Android 在某硬件平台上执行基本上完成这些驱动程序就行了。其内定义了 Android 对各硬件装置例如显示芯片、声音、数字相机、GPS、GSM 等等的需求。 HAL存在的几个原因 1、 并不是所有的硬件设备都有标准的linux kernel的接口。 2、 Kernel driver涉及到GPL的版权。某些设备制造商并不原因公开硬件驱动所以才去HAL方式绕过GPL。 3、 针对某些硬件Android有一些特殊的需求。 在display部分HAL的实现code在copybit.c中应用程序直接操作这些接口即可具体的接口如下 [cpp] view plaincopyprint? struct copybit_context_t *ctx malloc(sizeof(struct copybit_context_t)); memset(ctx, 0, sizeof(*ctx)); ctx-device.common.tag HARDWARE_DEVICE_TAG; ctx-device.common.version 0; ctx-device.common.module module; ctx-device.common.close close_copybit; ctx-device.set_parameter set_parameter_copybit;//设置参数 ctx-device.get get; ctx-device.blit blit_copybit;//传送显示数据 ctx-device.stretch stretch_copybit; ctx-mAlpha MDP_ALPHA_NOP; ctx-mFlags 0; ctx-mFD open(/dev/graphics/fb0, O_RDWR, 0);//打开设备 Kernel Space Display功能介绍 这里的Kernel空间与Display相关是Linux平台下的FB设备参考上图中的红色部分。下面介绍一下FB设备。 Fb即FrameBuffer的简称。framebuffer 是一种能够提取图形的硬件设备是用户进入图形界面很好的接口。有了framebuffer用户的应用程序不需要对底层驱动有深入了解就能够做出很好的图形。对于用户而言它和/dev 下面的其他设备没有什么区别用户可以把 framebuffer 看成一块内存既可以向这块内存中写入数据也可以从这块内存中读取数据。它允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。这种操作是抽象的统一的。用户不必关心物理显存的位置、换页机制等等具体细节。这些都是由Framebuffer设备驱动来完成的。 从用户的角度看帧缓冲设备和其他位于/dev下面的设备类似它是一个字符设备通常主设备号是29次设备号定义帧缓冲的个数。 在LINUX系统中设备被当作文件来处理所有的文件包括设备文件Linux都提供了统一的操作函数接口。上面的结构体就是Linux为FB设备提供的操作函数接口。 1、读写read/write接口即读写屏幕缓冲区应用程序不一定会调用该接口 2、映射map操作用户空间不能直接访问显存物理空间需map成虚拟地址后才可以 由于Linux工作在保护模式每个应用程序都有自己的虚拟地址空间在应用程序中是不能直接访问物理缓冲区地址的。为此Linux在文件操作 file_operations结构中提供了mmap函数可将文件的内容映射到用户空间。对于帧缓冲设备则可通过映射操作可将屏幕缓冲区的物理地址映射到用户空间的一段虚拟地址中之后用户就可以通过读写这段虚拟地址访问屏幕缓冲区在屏幕上绘图了。实际上使用帧缓冲设备的应用程序都是通过映射操作来显示图形的。由于映射操作都是由内核来完成下面我们将看到帧缓冲驱动留给开发人员的工作并不多 3、I/O控制对于帧缓冲设备对设备文件的ioctl操作可读取/设置显示设备及屏幕的参数如分辨率显示颜色数屏幕大小等等。ioctl的操作是由底层的驱动程序来完成 Note上述部分请参考文件fbmem.c。 Android display架构分析三 http://hi.baidu.com/leowenj/blog/item/76411bf6237dc429bc31099f.html Kernel Space Display架构介绍 如上图所示除了上层的图形应用程序外和Kernel空间有关的包括Linux FB设备层以及和具体HW相关的驱动层对应的源文件分别是fb_mem.c、msm_fb.c、mddi_toshiba.c。下面会一一介绍。 函数和数据结构介绍 这个文件包含了Linux Fb设备的所有接口主要函数接口和数据结构如下 A、Fb设备的文件操作接口 B、3个重要的数据结构 FrameBuffer中有3个重要的结构体fb.h中定义如下 1 、frame_var_screeninfo 该结构体定义了显卡的一些可变的特性这些特性在程序运行期间可以由应用程序动态改变比较典型的如xrex和yres表示在显示屏上显示的真实分辨率、显示的bit数等该结构体user space可以访问。 2 、frame_fix_screeninfo 该结构体定义了显卡的一些固定的特性这些特性在硬件初始化时就被定义了以后不可以更改。其中最重要的成员就是smem_len和smem_start前者指示显存的大小目前程序中定义的显存大小为整屏数据RGB565大小的2倍,后者给出了显存的物理地址。该结构体user space可以访问。 Notesmem_start是显存的物理地址应用程序是不可以直接访问的必须通过fb_ops中的mmp函数映射成虚拟地址后应用程序方可访问。 3 、fb_info FrameBuffer中最重要的结构体它只能在内核空间内访问。内部定义了fb_ops结构体包含一系列FrameBuffer的操作函数Open/read/write、地址映射等. C、其他 1、一个重要的全局变量 struct fb_info *registered_fb[FB_MAX]; 这变量记录了所有fb_info 结构的实例fb_info 结构描述显卡的当前状态所有设备对应的fb_info 结构都保存在这个数组中当一个FrameBuffer设备驱动向系统注册自己时其对应的fb_info 结构就会添加到这个结构中同时num_registered_fb 为自动加1。 2、注册framebuffer函数 register_framebuffer(struct fb_info *fb_info); unregister_framebuffer(struct fb_info *fb_info); 这两个是提供给下层FrameBuffer设备驱动的接口设备驱动通过这两函数向系统注册或注销自己。几乎底层设备驱动所要做的所有事情就是填充fb_info结构然后向系统注册或注销它 Android display架构分析四 http://hi.baidu.com/leowenj/blog/item/37e1a8521e35522842a75b99.html 函数和数据结构介绍 该文件为高通显卡的驱动文件比较重要的函数接口和数据结构如下 A、高通msm fb设备的文件操作函数接口 [cpp] view plaincopyprint? static struct fb_ops msm_fb_ops { .owner THIS_MODULE, .fb_open msm_fb_open, .fb_release msm_fb_release, .fb_read NULL, .fb_write NULL, .fb_cursor NULL, .fb_check_var msm_fb_check_var, /* 参数检查 */ .fb_set_par msm_fb_set_par, /* 设置显示相关参数 */ .fb_setcolreg NULL, /* set color register */ .fb_blank NULL, /* blank display */ .fb_pan_display msm_fb_pan_display, /* 显示 */ .fb_fillrect msm_fb_fillrect, /* Draws a rectangle */ .fb_copyarea msm_fb_copyarea, /* Copy data from area to another */ .fb_imageblit msm_fb_imageblit, /* Draws a image to the display */ .fb_cursor NULL, .fb_rotate NULL, .fb_sync NULL, /* wait for blit idle, optional */ .fb_ioctl msm_fb_ioctl, /* perform fb specific ioctl (optional) */ .fb_mmap NULL, }; B、高通msm fb的driver接口 [cpp] view plaincopyprint? static struct platform_driver msm_fb_driver { .probe msm_fb_probe,//驱动探测函数 .remove msm_fb_remove, #ifndef CONFIG_ANDROID_POWER .suspend msm_fb_suspend, .suspend_late NULL, .resume_early NULL, .resume msm_fb_resume, #endif .shutdown NULL, .driver { /* Driver name must match the device name added in platform.c. */ .name msm_fb, }, }; C、msm_fb_init 向系统注册msm fb的driver初始化时会调用 D、msm_fb_add_device 向系统中添加新的lcd设备在mddi_toshiba.c中会被调用 函数和数据结构介绍 该文件包含了所有和具体LCDToshiba相关的信息和驱动重点的数据结构和函数结构如下 A、LCD设备相关信息 [cpp] view plaincopyprint? static struct platform_device this_device_0 {p .name mddi_toshiba_vga, .id TOSHIBA_VGA_PRIM, .dev { .platform_data toshiba_panel_data0, } }; 其中toshiba_panel_data0包含了硬件LCD的控制函数如开关、初始化等等 B、LCD driver接口 [cpp] view plaincopyprint? static struct platform_driver this_driver { .probe mddi_toshiba_lcd_probe, .driver { .name mddi_toshiba_vga, }, }; 其中mddi_toshiba_lcd_probe中会调用msm_fb_add_device接口把具体LCD添加到系统中去。 C、mddi_toshiba_lcd_init 注册LCD设备及driver到系统中去同时也把LCD的固有信息大小、格式、位率等一并注册到系统中去。 D、LCD相关控制函数 toshiba_common_initial_setup初始化MDDI bridge toshiba_prim_start初始化LCD 数据流分析 本部分来看一下应用层以下显示数据的流程是怎样的。 先来分析一下传统的Linux平台下FB设备是如果调用的如下图所示 上层调用FB API主要是fb_ioctl()fb_ioctl()会调用具体显卡的驱动这里是高通的显卡驱动其实就是MDP DMA的驱动通过MDP DMA把显示数据经MDDI接口送到外围LCD组件。 Note这里的MDP DMA并不对数据进行任何处理可以完成简单的格式转换如RGB565-RGB666。 接下来再分析一下Android平台下显示数据是如何处理的如下图所示 同样上层也是调用FB API不过这里其实把FB bypass了相当于直接调用的是高通MDP PPP的驱动然后数据经PPP处理后再经MDDI接口送出到外围LCD组件。 Note这里的MDP PPP可以完成很多显示数据处理功能如YUV-RGB、Scale、Rotate、Blending等。 初始化过程分析 Kernel部分display的初始化包含下面几个步骤 1、在linux fb设备初始化时会向系统中注册msm_fb_driver。Name为msm_fb。 msm_fb_init msm_fb_register_driver- platform_driver_register(msm_fb_driver) 其中的probe函数会对msm fb进行初始化分配显存等见msm_fb_probe函数。 2、在LCD模块初始化时会先向系统中注册驱动在mddi_toshiba_lcd_init函数中 platform_driver_register(this_driver);名字为mddi_toshiba_vga this_driver的probe函数为mddi_toshiba_lcd_probe其内部会调用msm_fb_add_device向系统中添加MSM fb设备。 3、调用platform_device_register(this_device_0)向系统中注册设备名字为mddi_toshiba_vga其中this_device_0包含了一些操作LCD的接口如on/off。 Note:设备和driver的name需要一致才可以绑定另外如果某些设备不需要让platform的总线来管理那么只需要注册驱动即可而无须向系统中注册device如msm_touch。 Android display架构分析五 http://hi.baidu.com/leowenj/blog/item/7a12ecb77067737f8ad4b266.html Display接口介绍 、User Space display接口 在Android平台下应用程序面对的显示部分的接口就是HAL参考copybit.c具体接口如下介绍 [cpp] view plaincopyprint? open_copybit 初始化相关变量并调用open(/dev/graphics/fb0, O_RDWR, 0);打开fb设备。 [cpp] view plaincopyprint? set_parameter_copybit 设置各种操作参数如rotate、alpha、dither等。 [cpp] view plaincopyprint? stretch_copybit Copy一块数据Rectangle到显存然后并命令msm_fb进行显示。 [cpp] view plaincopyprint? close_copybit 调用close(ctx-mFD);关闭fb设备。 Note另外应用程序在使用上面接口之前需要调用mapFrameBuffer接口EGLDisplaySurface.cpp其功能如下 1、 初始化显示相关参数并设置到底层。 2、 映射出显存的虚拟地址。 、Kernel display接口 Kernel部分显示的接口全部都在fbmem.c中这里详细介绍一下 fb_open 打开Linux下fb设备。 fb_read/fb_write 读写显存中的数据 fb_ioctl 对显示设备的命令操作。如get或set一些显示参数、通知底层进行刷屏等。 在典型应用中画屏的一般步骤如下 1 打开/dev/fb设备文件。 2 用ioctrl操作取得当前显示屏幕的参数如屏幕分辨率每个像素点的比特数。根据屏幕参数可计算屏幕缓冲区的大小。 3 将屏幕缓冲区映射到用户空间。 4 映射后就可以直接读写屏幕缓冲区进行绘图和图片显示了。 典型程序段如下 [cpp] view plaincopyprint? #include int main() { int fbfd 0; struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; long int screensize 0; [cpp] view plaincopyprint? /*打开设备文件*/ fbfd open(/dev/fb0, O_RDWR); [cpp] view plaincopyprint? /*取得屏幕相关参数*/ ioctl(fbfd, FBIOGET_FSCREENINFO, finfo); ioctl(fbfd, FBIOGET_VSCREENINFO, vinfo); [cpp] view plaincopyprint? /*计算屏幕缓冲区大小*/ screensize vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; [cpp] view plaincopyprint? /*映射屏幕缓冲区到用户地址空间*/ fbp(char*)mmap(0,screensize,PROT_READ|PROT_WRITE,MAP_SHARED, fbfd, 0); [cpp] view plaincopyprint? /*下面可通过fbp指针读写缓冲区*/ ... } 典型应用flow分析 在不同应用程序中上层的调用会有所不同比如Andriod下会选择应用程序跳过Linux fb操作层直接操作显卡驱动层称之为BLT accelerator。 下面看一下Android平台下画屏的操作流程。 1、 通过mapFrameBuffer直接把用户空间的数据映射到显存中。 2、 调用HAL中的stretch函数直接命令MSM设备提取显存数据然后送入MDP PPP进行处理并经MDDI接口送到外围LCD组件。 具体的函数调用流程如下 copybit_open//打开BlitEngine同时也打开fb设备 mapFrameBuffer();//设置显示参数同时得到显存虚拟地址 copybit-stretch(copybit, dst, src, sdrect, sdrect, it);//通知底层去刷屏 接下的流程是 stretch_copybit- msm_copybit- fb_ioctl()-msm_fb_ioctl(MSMFB_BLIT)- msmfb_blit- mdp_blit- mdp_ppp_blit-mdp_start_ppp-MDPMDDI HW operation Android display架构分析六 http://hi.baidu.com/leowenj/blog/item/78c068dc443c961f48540361.html 介绍 Note 本部分介绍的完全是用户空间显示部分的架构与kernel并没有直接的联系主要是JNI以下到HAL以上的部分。 、Surface managersurface flinger简介 Surface manager是用户空间中framework下libraries中负责显示相关的一个模块。如下 当系统同时执行多个应用程序时Surface Manager会负责管理显示与存取操作间的互动另外也负责将2D绘图与3D绘图进行显示上的合成。 surface manager 可以准备一块 surface可以看作一个layer把 surface 的 fd (一块内存) 传给一个 app让 app 可以在上面作画。典型应用如下 2、架构分析 Android中的图形系统采用Client/Server架构如下 Client端应用程序相关部分。代码分为两部分一部分是由Java提供的供应用使用的api,另一部分则是由c写成的底层实现。 Server端即SurfaceFlinger负责合成并送入buffer显示。其主要由c代码编写而成。 Client和Server之前通过Binder的IPC方式进行通信总体结构图如下 如上图所示Surface的client部分其实是提供给各应用程序进行画图操作的一个桥梁该桥梁通过binder通向server端的SurfaceflingerSurfaceflinger负责合成各个surface然后把buffer传送到framebuffer端进行底层显示。其中每个surface对应2个buffer一个front buffer, 一个back buffer更新时数据更新在back buffer上需要显示时则将back buffer和front buffer互换。 下一部分我们重点研究一下Surfaceflinger。 Android display架构分析七-1 http://hi.baidu.com/leowenj/blog/item/7abbe33a309367ff3b87ce6f.html 流程分析 根据前面的介绍surfaceflinger作为一个server process上层的应用程序作为client通过Binder方式与其进行通信。Surfaceflinger作为一个thread这里把它分为3个部分如下 1、 Thread本身处理部分包括初始化以及thread loop。 2、 Binder部分负责接收上层应用的各个设置和命令并反馈状态标志给上层。 3、 与底层的交互负责调用底层接口HAL。 结构图如下 注释 a、 Binder接收到应用程序的命令如创建surface、设置参数等传递给flinger。 b、 Flinger完成对应命令后将相关结果状态反馈给上层。 c、 在处理上层命令过程中根据需要设置event主要和显示有关通知Thread Loop进行处理。 d、 Flinger根据上层命令通知底层进行处理主要是设置一些参数Layer、position等 e、 Thread Loop中进行surface的合成并通知底层进行显示Post buffer。 f、 DisplayHardware层根据flinger命令调用HAL进行HW的操作。 下面来具体分析一些SurfaceFlinger中重要的处理函数以及surface、Layer的属性 1、readToRun SurfaceFlinger thread的初始化函数主要任务是分配内存和设置底层接口(EGLHAL)。 [cpp] view plaincopyprint? status_t SurfaceFlinger::readyToRun() … … mServerHeap new MemoryDealer(4096, MemoryDealer::READ_ONLY);//为IPC分配共享内存 … mSurfaceHeapManager new SurfaceHeapManager(this, 8 20);//为flinger分配heap大小为8M存放具体的显示数据 { // initialize the main display GraphicPlane plane(graphicPlane(dpy)); DisplayHardware* const hw new DisplayHardware(this, dpy); plane.setDisplayHardware(hw);//保存显示接口 } //获取显示相关参数 const GraphicPlane plane(graphicPlane(dpy)); const DisplayHardware hw plane.displayHardware(); const uint32_t w hw.getWidth(); const uint32_t h hw.getHeight(); const uint32_t f hw.getFormat(); … … // Initialize OpenGL|ES glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); … … 2、ThreadLoop Surfaceflinger的loop函数主要是等待其他接口发送的event进行显示数据的合成以及显示。 [cpp] view plaincopyprint? bool SurfaceFlinger::threadLoop() { waitForEvent();//等待其他接口的signal event … … // post surfaces (if needed) handlePageFlip();//处理翻页机制 const DisplayHardware hw(graphicPlane(0).displayHardware()); if (LIKELY(hw.canDraw())) { // repaint the framebuffer (if needed) handleRepaint();//合并所有layer并填充到buffer中去 … … postFramebuffer();//互换front buffer和back buffer调用EGL接口进行显示 } … … } 3、createSurface 提供给应用程序的主要接口该接口可以创建一个surface底层会根据参数创建layer以及分配内存surface相关参数会反馈给上层 [cpp] view plaincopyprint? sp SurfaceFlinger::createSurface(ClientID clientId, int pid, ISurfaceFlingerClient::surface_data_t* params, DisplayID d, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) … … int32_t id c-generateId(pid); if (uint32_t(id) NUM_LAYERS_MAX) //NUM_LAYERS_MAX31 { LOGE(createSurface() failed, generateId %d, id); return } … layer createNormalSurfaceLocked(c, d, id, w, h, format, flags);//创建layer根据参数宽高格式分配内存共2个bufferfront/back buffer if (layer) { setTransactionFlags(eTransactionNeeded); surfaceHandle layer-getSurface();//创建surface if (surfaceHandle ! 0) surfaceHandle-getSurfaceData(params);//创建的surface参数反馈给应用层 } 待续。。。 Android display架构分析七2 http://hi.baidu.com/leowenj/blog/item/ba4c5d6378a5da48eaf8f86a.html 、setClientState 处理上层的各个命令并根据flag设置event通知Threadloop进行处理 [cpp] view plaincopyprint? status_t SurfaceFlinger::setClientState( ClientID cid, int32_t count, const layer_state_t* states) { Mutex::Autolock _l(mStateLock); uint32_t flags 0; cid 16; for (int i0 ; i { const layer_state_t s states[i]; LayerBaseClient* layer getLayerUser_l(s.surface | cid); if (layer) { const uint32_t what s.what; // 检测应用层是否设置各个标志如果有则通知底层完成对应操作并通知ThreadLoop做对应的处理 if (what eDestroyed) //删除该层Layer { if (removeLayer_l(layer) NO_ERROR) { flags | eTransactionNeeded; continue; } } if (what ePositionChanged) //显示位置变化 { if (layer-setPosition(s.x, s.y)) flags | eTraversalNeeded; } if (what eLayerChanged) //Layer改变 { if (layer-setLayer(s.z)) { mCurrentState.layersSortedByZ.reorder( layer, Layer::compareCurrentStateZ); flags | eTransactionNeeded|eTraversalNeeded; } } if (what eSizeChanged) { if (layer-setSize(s.w, s.h))//设置宽高变化 flags | eTraversalNeeded; } if (what eAlphaChanged) {//设置Alpha效果 if (layer-setAlpha(uint8_t(255.0f*s.alpha0.5f))) flags | eTraversalNeeded; } if (what eMatrixChanged) {//矩阵参数变化 if (layer-setMatrix(s.matrix)) flags | eTraversalNeeded; } if (what eTransparentRegionChanged) {//显示区域变化 if (layer-setTransparentRegionHint(s.transparentRegion)) flags | eTraversalNeeded; } if (what eVisibilityChanged) {//是否显示 if (layer-setFlags(s.flags, s.mask)) flags | eTraversalNeeded; } } } if (flags) { setTransactionFlags(flags);//通过signal通知ThreadLoop } return NO_ERROR; } 5、composeSurfaces 该接口在Threadloop中被调用负责将所有存在的surface进行合并OpenGl模块负责这个部分。 6、postFramebuffer 该接口在Threadloop中被调用负责将合成好的数据存于back buffer中推入在front buffer中然后调用HAL接口命令底层显示。 7、从3中可知上层每创建一个surface的时候底层都会同时创建一个layer下面看一下surface及layer的相关属性。 Notecode中相关结构体太大就不全部罗列出来了 A、Surface相关属性详细参考文件surface.h a1SurfaceID根据此ID把相关surface和layer对应起来 a2SurfaceInfo 包括宽高格式等信息 a32个buffer指针、buffer索引等信息 B、Layer相关属性详细参考文件layer.h/layerbase.h/layerbitmap.h 包括Layer的ID、宽高、位置、layer、alpha指、前后buffer地址及索引、layer的状态信息如eFlipRequested、eBusy、eLocked等 Android display架构分析八 http://hi.baidu.com/leowenj/blog/item/03aae36137acb8d1e6113a75.html 开发的经验分享 1Display Driver的工作内容 参考上面linux下fb设备的软件架构可以知道要加入一个新的MDDI 接口的LCMDriver的工作就是要提供自己的mddi_xxxx.c在这次porting的过程中为了节省时间我们直接修改了mddi_toshiba.c并且完成和这个lcd相关的HWr的初始化。主要的工作包括 A、初始化和LCD / LCD背光相关的IO以及电源 B、编写初始化函数 。主要是初始化LCD控制器这个一般LCD厂商会提供然后分配显存这个高通release过来的code已经包含这个动作了最后是初始化一个fb_info的结构体在这里主要是把LCD的一些信息登记进来。 C、把LCD的设备以及驱动注册到系统中去。这里因为是替换现有的驱动所以相关修改的部分不多。 上述B、C部分代码请参考kernel/drivers/video/msm/mddi_toshiba.c。 开发过程 1.2.1配置Power和IO 更改一些GPIO的配置以及一些电源的电平配置然后通过实际测量确保一下信号正常 A、供给LCD以及MDDI Bridge的电源 B、MDDI Bridge以及LCD reset信号 C、控制背光IC的GPIO工作正常背光不打开无法调试LCD。 1.2.2Porting LCD初始化序列 LCD init的code以及外围MDDI Bridge的初始化code都可以之前Boston Windows Mobile系统的code base中获得把这部分code移植到mddi_Toshiba.c中并更改相应的图像格式、分辨率等配置编译通过。LCD初始化部分就算基本完成。 1.2.3LCD初始化过程的调试 由于硬件在之前Boston load是可以工作的可以认为硬件连接等没有问题所以只需关注软件部分就行。 Display部分软件调试过程如下 A、 开机后量一下GPIO是否为code中配置预期的状态可确保code中的 GPIO接口工作正常 B、 量一下各个电源是否都处于Code中定义的电平值。这些都OK后背光 是会亮的背光的控制比较简单一个GPIO即可 C、 这个时候如果LCD以及MDDI Bridge有被正常初始化的话屏幕上是会 看出来的。反之如果屏幕没有显示需要用JTAG跟一下mddi_Toshiba.c中的初始化函数是否在开机的时候有被调用过。 目前版本中是根据外围MDDI Bridge中读到的的厂商号来决定加载哪个驱动模块的。在本次调试中bootloader中可以正确读到厂商号所以bootloader中对于LCD的初始化是有做的所以屏幕看到的状态就是LCD初始化后的样子花屏。 但Kernel起来后并没有其他显示用JTAG跟了后发现Kernel中MODULE INIT中读不到正确的厂商号所以说后面的driver没有被加载。接着发现如果在bootloader中如果不做MDDI Bridge的初始化的话后面的MODULE INIT就可正常运行该问题目前还没有澄清现在暂时先把bootloader中的init disable掉。 1.2.4LCD的调整 初始化正常后屏幕会显示UI的相关画面但明显颜色、位置都不对。 这个可能是数据类型配置不对导致的即MDP输出的类型、MDDI配置的类型以、LCD接收的类型不匹配导致也有可能是RGB的顺序不对导致可配置成BGR。经过调试后把MDP端输出的格式配置成RGB565,同时外围MDDI Bridge以及LCD的input格式也配置成RGB565这时显示色彩正常了。 如果位置或者方向不对比如说上下或是左右颠倒可以更改LCD的配置中的扫描方向即可。 1.2.5其他 后续发现一个问题播放video的时候颜色都是黑白的。 这个问题很容易让人误解按照正常的理解video decode出来的数据为YCbCrY为亮度信号CbCr为色差信号如果只有Y信号的话颜色应该就是黑白的。所以有2个怀疑点一个是decode出来的数据有误另一个是MDDI Bridge误把输入的YcbCr信号当作RGB信号进行出来这个也是有可能的。但很快第二个怀疑点被排除了因为单更改MDDI input格式后还是不能解决问题。 后来又详细的看了显示部分的代码并用JTAG追踪video播放的时候用的显示接口发现目前所有的显示接口输出的格式都是RGB格式也就是说在通过MDP之前YcbCr已经被转化过而MDP里的转换功能并没有使用MDP只是被当作一个DMA完成数据的直接传输文档中叫做Bypasse。 YcbCr到RGB的转换是由Android的lib来完成。发了个SR给高通高通的回复也确认了在6.3.50中Android上层缺少这个libcopybit.default.so6.3.60之后的版本经解决了这个问题。 高通Android平台下关于display部分的几个关键问题 http://hi.baidu.com/leowenj/blog/item/06f8c0000763b37a3812bb03.html 显示部分的几个问题这几天通过实际测试澄清了一下主要是下图中各个模块的使用状况以及HAL层几个模块的调用流程。以问题的方式描述如下 1、 Ap是怎么进行显示的 Surfaceflinger负责所有上层的显示处理对于AP2D或是3D的应用程序而言只要到surfaceflinger中创建surface设置好参数接下来都是统一交给surfaceflinger进行处理 2、 Surface是怎么管理多个surface的 不管有多少个surface最终送到显示部分的只能是屏幕大小数据surfaceflinger中利用MDP或是GPU进行多个surface的合成处理普通的合成MDP就可完成但如果是复杂的比如3D的应用等就必须使用GPU最终合成的好数据会被送到framebuffer中。 3、 Framebuffer是什么 Framebuffer是Linux中为显示数据分配的一块显存fb设备中通常大小是一整个屏幕数据的两倍对于上层AP而言只需要将要显示的数据丢到framebuffer中就OK了但此时显示数据并未真正的被送到LCD上而是暂存在framebuffer中而已。 4、 上层是通过什么方式将显示内容送到framebuffer的 有2个方式二选一不会同时在运行 A、 普通的显示使用copybitMDP未使用GPU Surfaceflinger通过copybit将要显示的数据送到framebuffer。 Notecopybit可以看做是MDP PPP的接口它提供了MDP的功能如多个layer合成scale、rotate等。 其接口在android/hardware/msm7k/libcopybit/copybit.cpp B、 使用GPU即使用图中的Graphics driver 当进行复杂的显示处理时比如3D的应用GPU把处理好的数据直接丢到framebuffer中和MDP没有任何关系 5、 Framebuffer中的数据是如何被送到LCD显示的 图中的Gralloc完成的。 Gralloc有2个功能 一个是和copybit相同的里面有MDP PPP的接口目前没有使用 另一个则是刷屏整屏刷的接口即将framebuffer中的数据送到lcd上调用的是MDP DMA的接口 这部分的code在android/hardware/msm7k/libgralloc-qsd8k目录下之前没有留意以为没有使用。现在可以看出开机初始化后就创建了disp_loop thread里面的操作就是调用系统接口 ioctl(m-framebuffer-fd, FBIOPUT_VSCREENINFO, m-info) 将数据送到lcd Note送数据的时候是2个buffer切换的 另外上层surfaceflinger也是通过Gralloc中的接口获知屏幕的大小调用接口为 ioctl(fd, FBIOGET_VSCREENINFO, info)info中的屏幕宽高对应的就是底层driver设置的宽高值 6、 OpenGL是什么 它是一个图像处理引擎当需要一些复杂的显示2D/3D操作时会用到它。它分为SW方案和HW方案软件方案就是图中的libagl.so,对应到目前项目中是libGLES_android.so它可以完成简单的2D文字icon等处理通过trace看目前大部分显示操作都是它来完成的。 Note它是软件方案处理好的数据是通过copybit送到framebuffer的而不是GPU。 其接口部分参考android/frameworks/base/opengl/libagl HW方案就是图中的Graphics driver它通过使用GPU硬件来完成图像处理处理后的数据直接送到framebuffer中。其接口部分参考android/frameworks/base/opengl/libs有几个版本 7、 OpenGL在项目中是如何配置的 在android/vendor/qcom/msm7627_ffa目录下有一个egl.cfg文件里面指定了当前版本中的OpenGL信息目前如下 0 0 android 0 1 adreno200 第一行代表该codebase支持SW 方案的OpenGL是android default的 第二行代表该codebase也支持HW方案的OpenGL是高通的adreno引擎 如果该cfg文件为空则只支持default的SW方案。 如果2个方案都在上层将根据实际应用自行选择使用其一。 该部分请参考android/frameworks/base/opengl/libs/EGL/loader.cpp 转载于:https://www.cnblogs.com/yuzaipiaofei/archive/2012/10/25/4124154.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/921045.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!