1.Android 形显示系统(九) Android形显示子系统概述
2.你真的源码懂VirtualDisplay虚拟屏幕的Mirror模式吗?
3.å¦ä½å¨Androidä¸å®ç°FrameBufferåOverlayçblend
Android 形显示系统(九) Android形显示子系统概述
Android图形显示系统是Android核心架构中的重要组成部分,它负责处理图形渲染、源码显示以及与硬件的源码交互。系统大致可以分为两大部分:图形系统和显示系统。源码
图形系统包括用于2D和3D图形绘制的源码API(如Skia、OpenGLES、源码帮助文档生成源码RenderScript、源码OpenCV、源码Vulkan),源码解码库(如JPEG、源码PNG、源码GIF)以及相关驱动支持。源码在实际应用中,源码股票竹节线公式源码Android为开发者提供了丰富的源码界面组件(如widget和view),使得开发者无需直接调用底层API,源码即可轻松创建交互式界面。为了提升性能,Android还引入了硬件加速机制,将2D图形转换为3D绘图,并采用部分更新方式,仅重绘有变化的部分,显著提高了界面渲染速度。
显示系统则负责将图形绘制结果呈现给用户。每个界面对应一个Surface对象,多个Surface需要合并显示。音频源码输出方案Android使用SurfaceFlinger服务来管理窗口合成和显示,其核心是图层概念(Layer),多个Layer被合并为一个,最终通过Display HAL(硬件抽象层)送到LCD。SurfaceFlinger利用Buffer管理机制,通过Buffer队列(BufferQueue)和生产者-消费者模型,优化了内存使用,提升了显示效率。
Android显示系统架构复杂但设计精妙,包含多个关键组件如SurfaceFlinger、AMS(Activity Manager Service)、WMS(Window Manager Service)等。操盘大师指标公式源码它不仅支持高效的图形渲染和显示,还提供了丰富的接口和工具,使得开发者能够轻松构建高质量的用户界面。
为了帮助开发者更深入地理解Android显示系统,Android官方提供了详细的文档和示例代码。通过结合架构图和源代码分析,开发者可以更直观地掌握系统内部的工作机制,从而优化应用性能和用户体验。
回到整体系统架构,Android基于Linux内核构建,集成了电话、蓝牙、突破颈线公式源码Wi-Fi、音视频播放、摄像头等众多功能,形成一个庞大的生态系统。Android通过HAL层(硬件抽象层)提供了统一的接口,使得开发者可以基于Linux内核开发各类应用或系统,例如FirefoxOS、OS、YunOS等。
Android Framework分为Native Framework和Java Framework,其中Java Framework的引入是为了吸引更多Java开发者,形成生态链。Native Framework提供底层的性能支持,而Java Framework则方便使用Java语言进行应用开发。在显示子系统中,SurfaceFlinger基于HAL HWComposer管理显示流程,而上层服务如WMS、AMS、View等则负责应用层面的界面管理和控制。
对于Android Native应用开发者来说,Android提供了NDK(Native Development Kit),允许开发者直接访问系统底层API,进行性能优化或实现特定功能。通过NDK,开发者可以创建功能强大、性能出色的原生应用,进一步丰富Android平台的生态系统。
总之,Android图形显示系统是一个高度集成、功能丰富且灵活的系统,它为开发者提供了从底层图形渲染到高级界面管理的完整解决方案。通过深入理解其架构和机制,开发者能够构建出高效、美观的用户界面,为用户提供卓越的移动体验。
你真的懂VirtualDisplay虚拟屏幕的Mirror模式吗?
理解VirtualDisplay的Mirror模式关键在于其如何根据屏幕内容的有无自动切换显示模式。当主屏幕无内容时,它会启用镜像模式,将主屏幕内容复制到虚拟屏幕上;而当虚拟屏幕有自定义内容时,它会独立显示,不会镜像主屏幕。
原理研究步骤:
1. 要观察VirtualDisplay的显示行为,首先通过`dumpsys SurfaceFlinger`查看Display的层级数据和图层索引,确定layer能否在Display上显示。
2. 比较镜像模式和独立显示时,layerStack的差异,发现层栈在有内容和无内容时会发生变化。
3. 通过堆栈追踪,发现当Task在虚拟屏幕中移动时,会触发layerStack的修改,这与SurfaceControl相关。
核心源码分析:
- VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR设置下,会检查DisplayContent的mApplySurfaceChangesTransaction,判断是否有内容。
- 当内容变化时,会调用setDisplayLayerStack来调整层栈,确保正确的Display显示。
- 层栈匹配由SurfaceFlinger控制,决定显示哪个Display。
进一步资料:
- 深入研究可参考:[链接](mp.weixin.qq.com/s/LbVL...),以及其他课程资料:[链接](mp.weixin.qq.com/s/Qv8z...)。
- 视频教程可在B站观看:[链接](bilibili.com/video/BV1w...)。
通过以上分析,VirtualDisplay的Mirror模式依赖于内容的存在与否来决定是否镜像主屏幕,以及如何调整层栈以确保正确的显示。
å¦ä½å¨Androidä¸å®ç°FrameBufferåOverlayçblend
1.SurfaceFlingeræ¯ä¸ä¸ªæå¡ï¼ä¸»è¦æ¯è´è´£åæåçªå£çSurfaceï¼ç¶åéè¿OpenGLESæ¾ç¤ºå°FrameBufferä¸ã
2.DisplayHardwareæ¯å¯¹æ¾ç¤ºè®¾å¤çæ½è±¡ï¼å æ¬FrameBufferåOverlayãå è½½FrameBufferåOverlayæ件ï¼å¹¶åå§åOpenGLES:
view plain
mNativeWindow = new FramebufferNativeWindow();
framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
overlay_control_open(module, &mOverlayEngine);
}
surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
eglMakeCurrent(display, surface, surface, context);
3.FramebufferNativeWindow æ¯framebuffer çæ½è±¡ï¼å®è´è´£å è½½libgrallocï¼å¹¶æå¼framebuffer设å¤ãFramebufferNativeWindow并ä¸ç´æ¥ä½¿ç¨ framebufferï¼èæ¯èªå·±å建äºä¸¤ä¸ªBufferï¼
queueBufferè´è´£æ¾ç¤ºä¸ä¸ªBufferå°å±å¹ä¸ï¼å®è°ç¨fb->postå»æ¾ç¤ºã
dequeueBufferè·åä¸ä¸ªç©ºé²çBufferï¼ç¨æ¥å¨åå°ç»å¶ã
è¿ä¸¤ä¸ªå½æ°ç±eglSwapBuffersè°è¿æ¥ï¼è°å°
view plain
egl_window_surface_v2_t::swapBuffersï¼
nativeWindow->queueBuffer(nativeWindow, buffer);
nativeWindow->dequeueBuffer(nativeWindow, &buffer);
4.msm7k/liboverlayæ¯Overlayçå®ç°ï¼ä¸å ¶å®å¹³å°ä¸åçæ¯ï¼é«éå¹³å°ä¸çOverlay并ä¸æ¯æä¾ä¸ä¸ªframebuffer设å¤ï¼èéè¿fb0çioctlæ¥å®ç°çï¼ioctlå为两类æä½ï¼
OverlayControlChannelç¨äºè®¾ç½®åæ°ï¼æ¯å¦è®¾ç½®Overlayçä½ç½®ï¼å®½åº¦åé«åº¦ï¼
view plain
bool OverlayControlChannel::setPosition(int x, int y, uint_t w, uint_t h) {
ov.dst_rect.x = x;
ov.dst_rect.y = y;
ov.dst_rect.w = w;
ov.dst_rect.h = h;
ioctl(mFD, MSMFB_OVERLAY_SET, &ov);
}
OverlayDataChannelç¨äºæ¾ç¤ºOverlayï¼å ¶ä¸æéè¦çå½æ°å°±æ¯queueBuffer:
view plain
bool OverlayDataChannel::queueBuffer(uint_t offset) {
mOvData.data.offset = offset;
ioctl(mFD, MSMFB_OVERLAY_PLAY, odPtr))
}
5.msm7k/libgralloc æ¯æ¾ç¤ºç¼åçæ½è±¡ï¼å æ¬framebufferåæ®éSurfaceçBufferãframebufferåªæ¯/dev/graphic/fb0çå è£ ï¼SurfaceçBufferåæ¯å¯¹/dev/pmemãashmemåGPUå å(msm_hw3dm)çå è£ ï¼å®çç®æ 主è¦æ¯æ¹ä¾¿ç¡¬ä»¶å éï¼å 为 DMAä¼ è¾ä½¿ç¨ç©çå°åï¼è¦æ±å åå¨ç©çå°åä¸è¿ç»ã
6.msm7k/libcopybitè¿æ¯2Då éåºï¼ä¸»è¦è´è´£Surfaceçæ伸ãæ转ååæçæä½ãå®æ两ç§å®ç°æ¹å¼ï¼
copybit.cpp: åºäºfb0çioctl(MSMFB_BLIT)çå®ç°ã
copybit_c2d.cpp: åºäºkgslçå®ç°ï¼åªæ¯å¯¹libC2D2.soçå è£ ï¼libC2D2.soåºè¯¥æ¯ä¸å¼æºçã
7.pmem
misc/pmem.c: 对ç©çå åç管çï¼ç®æ³åç¨æ·ç©ºé´çæ¥å£ã
board-msm7x.cå®ä¹äºç©çå åç缺ç大å°ï¼
view plain
#define MSM_PMEM_MDP_SIZE 0x1B
#define MSM_PMEM_ADSP_SIZE 0xB
#define MSM_PMEM_AUDIO_SIZE 0x5B
#define MSM_FB_SIZE 0x
#define MSM_GPU_PHYS_SIZE SZ_2M
#define PMEM_KERNEL_EBI1_SIZE 0x1C
msm_msm7x2x_allocate_memory_regionsåé å 大åå åç¨äºç»pmemåäºæ¬¡åé ã
8.KGSL
Kernel Graphics System Layer (KGSL)ï¼3Då¾å½¢å é驱å¨ç¨åºï¼æºä»£ç drivers/gpu/msmç®å½ä¸ï¼å®æ¯å¯¹GPUçå è£ ï¼ç»OpenGLES 2.0æä¾æ½è±¡çæ¥å£ã
9.msm_hw3dm
è¿ä¸ªæå¨å æ ¸ä¸æ²¡ææ¾å°ç¸å ³ä»£ç ã
.msm_fb
msm_fb.c: framebuffer, overlayåblitçç¨æ·æ¥å£ã
mdp_dma.c: å¯¹å ·ä½æ¾ç¤ºè®¾å¤çå è£ ï¼æä¾ä¸¤ç§framebufferæ´æ°çæ¹å¼ï¼
mdp_refresh_screenï¼ å®æ¶æ´æ°ã
mdp_dma_pan_update: éè¿pan display主å¨æ´æ°ã
mdp_dma_lcdc.cï¼é对LCDå®ç°çæ¾ç¤ºè®¾å¤ï¼mdp_lcdc_updateç¨æ´æ°framebufferã