Android GUI系统之SurfaceFlinger(01)显示系统框架

该系列文章总纲链接:Android GUI系统之SurfaceFlinger 系列文章目录


本章关键点总结 & 说明:

Android GUI系统之SurfaceFlinger(01)显示系统框架_第1张图片

本章节思维导图如上。主要讲述了显示系统的基础,了解FrameBuffer与Android的关系,给出SurfaceFlinger的整体框架以及一个核心的demo测试程序。接下来的章节 将以该demo为核心进行阐述和分析。


1 frameBuffer与Android

当我们的程序 想要 在屏幕上显示内容时,我们的机制是直接向FrameBuffer(后面简称FB)写入内容来实现。接下来谈谈Android 实用FB的策略:

如果只有一个FB,当APP写入速度>LCD显示速度时没问题;当APP写入速度 <=LCD显示速度时,会卡顿和闪烁,为了解决这个问题,一般采用2个以上FB。以2个FB为例,APP写入FB0,LCD此时渲染FB1,FB0写入结束后,LCD渲染FB0,此时APP写入FB1,之后不断循环即可。

对于Android系统来说,有很多个APP,如果这些APP同时向FB写入内容那显示的内容就乱了,因此 需要一个大管家来管理,这个大管家就是 SurfaceFlinger。

2 SurfaceFlinger整体框架简图说明(因为是简图,主要为了方便学习和理解,所以并不完善)

Android GUI系统之SurfaceFlinger(01)显示系统框架_第2张图片

SurfaceFlinger(后 简称SF)主要可以做以下几件事情:

  1. 给app提供buffer: 通过gralloc模块向ashmen申请内存得到文件句柄fd,将fd通过binder机制传递给对应的app,app再执行mmap操作即可获得 对应的buffer。
  2. 将app发来的buffer(界面数据)进行合成:根据各个界面的layer(就是Z值,由WindowManagerService来确定),把这些排序后的整体buffer传递给HardwareComposer(后简称HWC)
  3. 当HWC不能处理(无HWC硬件、超出HWC层数)buffer时,使用图形库GL来处理。
  4. SF也好,APP也好,都可以直接调用EGL层接口来实现 渲染功能。

3 最简单的 Surface测试程序

为了更好的了解SurfaceFlinger的显示流程我们先用最简单的例子感知下最小显示系统。同时 后面的章节也会以此来分析 SF的内部机制。程序代码如下:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace android;

int main(int argc, char** argv)
{
    // 启动binder 和 它的线程池
    sp proc(ProcessState::self());
    ProcessState::self()->startThreadPool();

    // 创建surfaceflinger的客户端
    sp client = new SurfaceComposerClient();
    
    //获取surface
    sp surfaceControl = client->createSurface(String8("resize"),
            160, 240, PIXEL_FORMAT_RGB_565, 0);
    sp surface = surfaceControl->getSurface();

    //设置layer,layer值越大,显示层越靠前
    SurfaceComposerClient::openGlobalTransaction();
    surfaceControl->setLayer(100000);
    SurfaceComposerClient::closeGlobalTransaction();

    //获取buffer->锁定buffer->写入buffer->解锁并提交buffer
    ANativeWindow_Buffer outBuffer;
    surface->lock(&outBuffer, NULL);
    ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
    android_memset16((uint16_t*)outBuffer.bits, 0xF800, bpr*outBuffer.height);
    surface->unlockAndPost();
    sleep(3);

    //同上
    surface->lock(&outBuffer, NULL);
    android_memset16((uint16_t*)outBuffer.bits, 0x07E0, bpr*outBuffer.height);
    surface->unlockAndPost();
    sleep(3);
    
    IPCThreadState::self()->joinThreadPool();
    
    return 0;
}

对应的Android.mk文件如下:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
	SurfaceTest.cpp

LOCAL_SHARED_LIBRARIES := \
	libcutils \
	libutils \
    libui \
    libgui \
    libbinder

LOCAL_MODULE:= SurfaceTest

LOCAL_MODULE_TAGS := tests

include $(BUILD_EXECUTABLE)

程序的显示效果如下(即在界面上显示一个色块 )

Android GUI系统之SurfaceFlinger(01)显示系统框架_第3张图片

整个流程总结如下:

获取SurfaceFlinger->获取Surface->设置Layer->获取Buffer->锁定buffer->写入buffer->解锁并提交buffer

你可能感兴趣的:(android,显示子系统)