




已阅读5页,还剩25页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
小妞的傻大熊博客园 首页 社区 新随笔 联系 订阅 管理 随笔-14 评论-34 文章-0 trackbacks-0 android双屏显示的一些修改与尝试转载时请注明出处和作者文章出处:/xl19862005作者:Xandy用的是android2.3的代码这些天来一直在看android display相关的代码和资料并作了一些尝试,现在将这些天来的工作记录如下,有错误的地方希望广大同行指正,谢谢!经过阅读代码和查到的相关一些资料,对android双屏的支持总体思路如下图所示:由于目前跟踪代码只跟到了surfaceflinger这一层,下面先从surfaceflinger说起:在frameworksbaseservicessurfaceflingersurfaceflinger.cpp这个文件中有如下代码片断:status_t SurfaceFlinger:readyToRun() LOGI(SurfaceFlingers main thread ready to run. Initializing graphics H/W.n); / we only support one display currently int dpy = 0; / initialize the main display GraphicPlane& plane(graphicPlane(dpy); DisplayHardware* const hw = new DisplayHardware(this, dpy); DisplayHardware* const hw1 = new DisplayHardware(this, 1); /这个是我加入测试HAL层用的,下面将介绍到 plane.setDisplayHardware(hw); / create the shared control-block mServerHeap = new MemoryHeapBase(4096,MemoryHeapBase:READ_ONLY, SurfaceFlinger read-only heap); LOGE_IF(mServerHeap=0, cant create shared memory dealer); mServerCblk = static_cast(mServerHeap-getBase(); LOGE_IF(mServerCblk=0, cant get to shared control blocks address); new(mServerCblk) surface_flinger_cblk_t; / initialize primary screen / (other display should be initialized in the same manner, but / asynchronously, as they could come and go. None of this is supported / yet). 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(); hw.makeCurrent(); / initialize the shared control block mServerCblk-connected |= 1displays + dpy; memset(dcblk, 0, sizeof(display_cblk_t); dcblk-w = plane.getWidth(); dcblk-h = plane.getHeight(); dcblk-format = f; dcblk-orientation = ISurfaceComposer:eOrientationDefault; dcblk-xdpi = hw.getDpiX(); dcblk-ydpi = hw.getDpiY(); dcblk-fps = hw.getRefreshRate(); dcblk-density = hw.getDensity(); / Initialize OpenGL|ES glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ALIGNMENT, 4); glEnableClientState(GL_VERTEX_ARRAY); glEnable(GL_SCISSOR_TEST); glShadeModel(GL_FLAT); glDisable(GL_DITHER); glDisable(GL_CULL_FACE); const uint16_t g0 = pack565(0x0F,0x1F,0x0F); const uint16_t g1 = pack565(0x17,0x2f,0x17); const uint16_t textureData4 = g0, g1, g1, g0 ; glGenTextures(1, &mWormholeTexName); glBindTexture(GL_TEXTURE_2D, mWormholeTexName); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData); glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrthof(0, w, h, 0, 0, 1); LayerDim:initDimmer(this, w, h); mReadyToRunBarrier.open(); /* * Were now ready to accept clients. */ / start boot animation property_set(ctl.start, bootanim); return NO_ERROR;重点看上面用黄色标出的那两行,其中DisplayHardware* const hw1 = new DisplayHardware(this, 1);是我加入用来测试HAL层的buffer分配用的,DisplayHardware这个是在frameworksbaseservicessurfaceflingerDisplayHardwareDisplayHardware.cpp这个文件中定义的,如以下代码片断:/* * Initialize the display to the specified values. * */DisplayHardware:DisplayHardware(const sp& flinger,uint32_t dpy) : DisplayHardwareBase(flinger, dpy),mFlags(0) init(dpy);而在同文件中有如下代码片断:void DisplayHardware:init(uint32_t dpy) mNativeWindow = new FramebufferNativeWindow(dpy); framebuffer_device_t const * fbDev = mNativeWindow-getDevice(); mDpiX = mNativeWindow-xdpi; mDpiY = mNativeWindow-ydpi; mRefreshRate = fbDev-fps; mOverlayEngine = NULL; hw_module_t const* module; if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) = 0) overlay_control_open(module, &mOverlayEngine); EGLint w, h, dummy; EGLint numConfigs=0; EGLSurface surface; EGLContext context; / initialize EGL EGLint attribs = EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE, 0, EGL_NONE ; / debug: disable h/w rendering char propertyPROPERTY_VALUE_MAX; if (property_get(debug.sf.hw, property, NULL) 0) if (atoi(property) = 0) LOGW(H/W composition disabled); attribs2 = EGL_CONFIG_CAVEAT; attribs3 = EGL_SLOW_CONFIG; / TODO: all the extensions below should be queried through / eglGetProcAddress(). / set to EGL wrapper to load SW OpenGLES only if (property_get(debug.sf.enable_hgl, property, 1) 0) if (atoi(property) = 0) eglSetImplementationAndroid(EGL_TRUE); /*下面这些都是和egl相关的,目前正在研究中,由于代码量太大,一起不好发上来,这里简单介绍一下,frameworksbaseopengllibagl目录下是agl相关的一些代码,这些代码会生成libGLES_android.so 这个动态库,这点可以从此目录下的Android.mk文件里看出:LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/eglLOCAL_MODULE:= libGLES_android 在frameworksbaseopengllibs目录下是egl相关的一些代码,这些代码主要把agl这个库作了个封装,并向外提供相关接口*/ EGLDisplay display = eglGetDisplay(NativeDisplayType)dpy);/(EGL_DEFAULT_DISPLAY); LOGI(*DisplayHardware.cpp display:%d*n,(int)display); eglInitialize(display, NULL, NULL); eglGetConfigs(display, NULL, 0, &numConfigs); EGLConfig config; status_t err = EGLUtils:selectConfigForNativeWindow(display, attribs, mNativeWindow.get(), &config); LOGE_IF(err, couldnt find an EGLConfig matching the screen format); EGLint r,g,b,a; eglGetConfigAttrib(display, config, EGL_RED_SIZE, &r); eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g); eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &b); eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a); if (mNativeWindow-isUpdateOnDemand() mFlags |= PARTIAL_UPDATES; if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) = EGL_TRUE) if (dummy = EGL_SLOW_CONFIG) mFlags |= SLOW_CONFIG; /* * Create our main surface */ surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL); eglQuerySurface(display, surface, EGL_WIDTH, &mWidth); eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight); if (mFlags & PARTIAL_UPDATES) / if we have partial updates, we definitely dont need to / preserve the backbuffer, which may be costly. eglSurfaceAttrib(display, surface,EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) = EGL_TRUE) if (dummy = EGL_BUFFER_PRESERVED) mFlags |= BUFFER_PRESERVED; /* Read density from build-specific ro.sf.lcd_density property * except if it is overridden by qemu.sf.lcd_density. */ if (property_get(qemu.sf.lcd_density, property, NULL) = 0) if (property_get(ro.sf.lcd_density, property, NULL) format; mPageFlipCount = 0; /* * Gather OpenGL ES extensions */ eglMakeCurrent(display, surface, surface, context); GLExtensions& extensions(GLExtensions:getInstance(); extensions.initWithGLStrings(glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION), glGetString(GL_EXTENSIONS), eglQueryString(display, EGL_VENDOR), eglQueryString(display, EGL_VERSION), eglQueryString(display, EGL_EXTENSIONS); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &mMaxViewportDims);#ifdef EGL_ANDROID_swap_rectangle if (extensions.hasExtension(EGL_ANDROID_swap_rectangle) if (eglSetSwapRectangleANDROID(display, surface,0, 0, mWidth, mHeight) = EGL_TRUE) / This could fail if this extension is not supported by this / specific surface (of config) mFlags |= SWAP_RECTANGLE; / when we have the choice between PARTIAL_UPDATES and SWAP_RECTANGLE / choose PARTIAL_UPDATES, which should be more efficient#ifdef FSL_EPDC_FB#else if (mFlags & PARTIAL_UPDATES) mFlags &= SWAP_RECTANGLE;#endif#endif LOGI(EGL informations:); LOGI(# of configs : %d, numConfigs); LOGI(vendor : %s, extensions.getEglVendor(); LOGI(version : %s, extensions.getEglVersion(); LOGI(extensions: %s, extensions.getEglExtension(); LOGI(Client API: %s, eglQueryString(display, EGL_CLIENT_APIS)?:Not Supported); LOGI(EGLSurface: %d-%d-%d-%d, config=%p, r, g, b, a, config); LOGI(OpenGL informations:); LOGI(vendor : %s, extensions.getVendor(); LOGI(renderer : %s, extensions.getRenderer(); LOGI(version : %s, extensions.getVersion(); LOGI(extensions: %s, extensions.getExtension(); LOGI(GL_MAX_TEXTURE_SIZE = %d, mMaxTextureSize); LOGI(GL_MAX_VIEWPORT_DIMS = %d, mMaxViewportDims); LOGI(flags = %08x, mFlags); / Unbind the context from this thread eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);上面代码黄色标出的将会new一个framebufferNativeWindow,其实就是通过HAL层的Gralloc这个库映射到kernel层中的framebuffer在frameworksbaselibsuiFramebufferNativeWindow.cpp这个文件中有如下代码片断:FramebufferNativeWindow:FramebufferNativeWindow(uint32_t dpy) : BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false) hw_module_t const* module; char GRALLOC_MODE10; char GRALLOC_FB10; char GRALLOC_GPU10; if(dpy = DISPLAY0) strcpy(GRALLOC_MODE,GRALLOC_HARDWARE_MODULE_ID0); strcpy(GRALLOC_FB,GRALLOC_HARDWARE_FB0); strcpy(GRALLOC_GPU,GRALLOC_HARDWARE_GPU0); else if(dpy = DISPLAY1) strcpy(GRALLOC_MODE,GRALLOC_HARDWARE_MODULE_ID1); strcpy(GRALLOC_FB,GRALLOC_HARDWARE_FB1); strcpy(GRALLOC_GPU,GRALLOC_HARDWARE_GPU1); else strcpy(GRALLOC_MODE,GRALLOC_HARDWARE_MODULE_ID0); strcpy(GRALLOC_FB,GRALLOC_HARDWARE_FB0); strcpy(GRALLOC_GPU,GRALLOC_HARDWARE_GPU0); /*这个函数的原型是没有传入参数的,为了增加对second display的支持自行加入的,上面这些代码也是后来加入的,为的是根据传入的dpy(display 0/1)打开相应的Gralloc和GPU的库文件*/ if (hw_get_module(GRALLOC_MODE, &module) = 0) int stride; int err; int i; err = framebuffer_open(module,GRALLOC_FB, &fbDev); LOGE_IF(err, couldnt open framebuffer HAL (%s), strerror(-err); err = gralloc_open(module,GRALLOC_GPU, &grDev); LOGE_IF(err, couldnt open gralloc HAL (%s), strerror(-err); / bail out if we cant initialize the modules if (!fbDev | !grDev) return; mUpdateOnDemand = (fbDev-setUpdateRect != 0); / initialize the buffer FIFO mNumBuffers = fbDev-reserved0; if (mNumBuffers != 3 & mNumBuffers != 2) LOGE(The framebuffer number got from HAL is not supported(%d), mNumBuffers); return; mNumFreeBuffers = mNumBuffers; mBufferHead = mNumBuffers-1; for (i = 0; i width, fbDev-height, fbDev-format, GRALLOC_USAGE_HW_FB); for (i = 0; i alloc(grDev,fbDev-width, fbDev-height, fbDev-format,GRALLOC_USAGE_HW_FB, &buffersi-handle, &buffersi-stride); LOGE_IF(err, fb buffer %d allocation failed w=%d, h=%d, err=%s,i, fbDev-width, fbDev-height, strerror(-err); const_cast(ANativeWindow:flags) = fbDev-flags; const_cast(ANativeWindow:xdpi) = fbDev-xdpi; const_cast(ANativeWindow:ydpi) = fbDev-ydpi; const_cast(ANativeWindow:minSwapInterval) = fbDev-minSwapInterval; const_cast(ANativeWindow:maxSwapInterval) = fbDev-maxSwapInterval; else LOGE(Couldnt get gralloc module); ANativeWindow:setSwapInterval = setSwapInterval; ANativeWindow:dequeueBuffer = dequeueBuffer; ANativeWindow:lockBuffer = lockBuffer; ANativeWindow:queueBuffer = queueBuffer; ANativeWindow:query = query; ANativeWindow:perform = perform;重点在上面用黄色标出的这几行代码,hw_get_module会根据传入的dpy选择打开gralloc0还是gralloc1,framebuffer_open会根据传入的dpy选择打开fb0还是fb1,gralloc_open会根据传入的dpy选择打开gpu0还是gpu1;接下来的几行代码都是和buffer相关,mNumBuffers在这里等于3,先new NativeBuffer得到相应的buffersi(i=0/1/2),grDev-alloc将会为这些buffers分配内存。在hardwarelibhardwareincludehardwareGralloc.h文件中有如下定义,为了加入second display我这里作了一些修改/* * The id of this module */#define GRALLOC_HARDWARE_MODULE_ID0 gralloc0#define GRALLOC_HARDWARE_MODULE_ID1 gralloc1/* * Name of the graphics device to open */#define GRALLOC_HARDWARE_FB0 fb0#define GRALLOC_HARDWARE_FB1 fb1#define GRALLOC_HARDWARE_GPU0 gpu0#define GRALLOC_HARDWARE_GPU1 gpu1./* convenience API for opening and closing a supported device 下面这些封装都是在得到了module这个结构体之后得到相应的函数入口*/static inline int gralloc_open(const struct hw_module_t* module, const char * name,struct alloc_device_t* device) return module-methods-open(module, name, (struct hw_device_t*)device);static inline int gralloc_close(struct alloc_device_t* device) return device-common.close(&device-common);static inline int framebuffer_open(const struct hw_module_t* module,const char * name, struct framebuffer_device_t* device) return module-methods-open(module,name, (struct hw_device_t*)device);static inline int framebuffer_close(struct framebuffer_device_t* device) return device-common.close(&device-common);上面这些代码就是通过打开不同的gralloc模块,得到不同的函数入口地址,这里我对gralloc分别新建了两个,一个映射到fb0,一个映射到fb1,如下文件列表:其中libgralloc_sec_display是我后来加入的,先看libgralloc里面的内容:在gralloc.cpp这个文件里有如下代码片断:/*这里的open就是打开gralloc这个模块之后与在gralloc.h中module-methods-open相对应了*/static struct hw_module_methods_t gralloc_module_methods = open: gralloc_device_open;struct private_module_t HAL_MODULE_INFO_SYM = base: common: tag: HARDWARE_MODULE_TAG, version_major: 1, version_minor: 0, id: GRALLOC_HARDWARE_MODULE_ID0, name: Graphics Memory Allocator Module, author: The Android Open Source Project, methods: &gralloc_module_methods , registerBuffer: gralloc_register_buffer, unregisterBuffer: gralloc_unregister_buffer, lock: gralloc_lock, unlock: gralloc_unlock, , framebuffer: 0, flags: 0, numBuffers: 0, bufferMask: 0, lock: PTHREAD_MUTEX_INITIALIZER, currentBuffer: 0, pmem_master: -1, pmem_master_base: 0, master_phys: 0;open的实现代码如下:int gralloc_device_open(const hw_module_t* module, const char* name,hw_device_t* device) int status = -EINVAL; /name = GRALLOC_HARDWARE_FB0 or GRALLOC_HARDWARE_GPU0 GRALLLOGI0(*gralloc_devide_open : name = %s*n,name); if (!strcmp(name, GRALLOC_HARDWARE_GPU0) gralloc_context_t *dev; dev = (gralloc_context_t*)malloc(sizeof(*dev); /* initialize our state here */ memset(dev, 0, sizeof(*dev); /* initialize the procs */ mon.tag = HARDWARE_DEVICE_TAG; mon.version = 0; mon.module
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 工业设计与制造技术创新
- 工业领域的能源管理培训教程
- 工作中的目标管理与实现路径
- 工作生活的平衡技巧探讨与应用实例
- 工业领域新能源技术的推广
- 工作与生活平衡的技巧
- 工程流体力学中的数学模型与数值模拟方法研究
- 工作汇报的快速制作技巧
- 工程索道设计与施工技术管理
- 工程机械的冷却系统设计与研究
- 后罗拉过桥摇臂-课程设计说明书
- 《Python少儿编程》PPT课件(共11章)第二章 Python 编程基础
- 配对样本t检验表格
- GB/T 91-2000开口销
- 青花瓷中国风ppt
- 2021年汽车吊载人吊篮作业安全专项措施
- 质量管理之CAPA教学课件
- 泌尿外科健康教育2膀胱冲洗健康宣教
- 焊接件通用技术要求
- 星子港件杂货港区总平面布置与码头结构设计
- 水墨印刷机操作规程
评论
0/150
提交评论