文章目录

    • 1. Android Window
    • 2. Window的添加流程
      • 1. Native Surface的面貌
    • 3. BufferQueue
            • BufferQueue的消费者模型大概的通信流程:
    • 4. Surface 和 Layer
      • 1. Surface绘图过程
      • 2. 整体绘制过程概述:
    • 5. 总结

本文基于Android N;

1. Android Window

Android中的Window是一个抽象概念,并不是真正的window,而是一个用于对真正的图形显示组件(Surface)做管理的 “虚拟窗口概念”。

我们在开发过程中的意识上可以认为Window就是一个屏幕窗口,这也是Android提出Window概念的目的所在,可以更好的面向开发者理解。

实质上的Window其实是一块 图形缓冲区 ,这块图形缓冲区的承载者就是我们在自定义View的时候所见的Canvas,而对Canvas也有其缓冲区管理者,叫做Surface。

Surface的作用是向SurfaceFlinger获取App界面创建时候的 GraphicBuffer(IGraphicBufferProducer),并向Buffer中默认填充一个Bitmap数据格式,并设置到Canvas中,这整个流程在接下来都会有讲到。


2. Window的添加流程

Window的添加流程从WindowManager的addView开始,这个接口是所有客户端对窗口的新建的统一接口,并且调用之后,会直接显示在界面上(系统Window的使用会有权限问题)

如上图所示,addWindow的流程其实就是向WindowManagerService注册Window的格式/类型/尺寸等大小,然后向SurfaceFlinger申请图形缓存Layer,Layer中会有创建好的GraphicBuffer,和用于提交图形的producer对象,消费图形数据的consumer对象。

  • 图中重要的几点:
  1. ViewRootImpl创建的时候,会创建一个Surface,此时这个Surface对象是空的;
  2. Surface的对象填充是在requestLayout之后,底层会返回Native Surface的地址,并通过1中创建的Surface对象中;

1. Native Surface的面貌

  • 看一下Native的Surface是什么样子的?
//frameworks/native/libs/gui/Surface.cppSurface::Surface(        const sp<IGraphicBufferProducer>& bufferProducer,        bool controlledByApp)    : mGraphicBufferProducer(bufferProducer),      mCrop(Rect::EMPTY_RECT),      mGenerationNumber(0),      mSharedBufferMode(false),      mAutoRefresh(false),      mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),      mSharedBufferHasBeenQueued(false){

对IGraphicBufferProducer的一个封装。

  • bufferProducer对象是怎么来的?
//frameworks/native/libs/gui/SurfaceControl.cppSurfaceControl::SurfaceControl(        const sp<SurfaceComposerClient>& client,        const sp<IBinder>& handle,        const sp<IGraphicBufferProducer>& gbp)    : mClient(client), mHandle(handle),    mGraphicBufferProducer(gbp) //来自构造函数;{}    ......sp<Surface> SurfaceControl::getSurface() const{    Mutex::Autolock _l(mLock);    if (mSurfaceData == 0) {        // This surface is always consumed by SurfaceFlinger, so the        // producerControlledByApp value doesn't matter; using false.        //Native Surface创建        mSurfaceData = new Surface(mGraphicBufferProducer, false);    }    return mSurfaceData;}

SurfaceControl创建的时候会传递gbp对象并赋给mGraphicBufferProducer。

  • gbp怎么来的?
//frameworks/native/libs/gui/SurfaceComposerClient.cppsp<SurfaceControl> SurfaceComposerClient::createSurface(        const String8& name,        uint32_t w,        uint32_t h,        PixelFormat format,        uint32_t flags){    sp<SurfaceControl> sur;    if (mStatus == NO_ERROR) {        sp<IBinder> handle;        sp<IGraphicBufferProducer> gbp;        status_t err = mClient->createSurface(name, w, h, format, flags,                &handle, &gbp);        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));        if (err == NO_ERROR) {            sur = new SurfaceControl(this, handle, gbp);        }    }    return sur;}

在requestLayout的时候,调用createSurface创建的,并通过SurfaceControl包装的(构造时候传递进去的)。

还是没有说到gbp怎么来的,继续跟:

//frameworks/native/services/surfaceflinger/SurfaceFlinger_hwc1.cppstatus_t SurfaceFlinger::createLayer(        const String8& name,        const sp<Client>& client,        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp){   ...    sp<Layer> layer;    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {        case ISurfaceComposerClient::eFXSurfaceNormal:            result = createNormalLayer(client,                    name, w, h, flags, format,                    handle, gbp, &layer);            break;        case ISurfaceComposerClient::eFXSurfaceDim:            ...            break;        default:            ...    }...}status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer){    ...    *outLayer = new Layer(this, client, name, w, h, flags);    status_t err = (*outLayer)->setBuffers(w, h, format, flags);    if (err == NO_ERROR) {        *handle = (*outLayer)->getHandle();        *gbp = (*outLayer)->getProducer(); //**gbp来自于这里    }...}

继续跟

void Layer::onFirstRef() {    sp<IGraphicBufferProducer> producer;    sp<IGraphicBufferConsumer> consumer;    BufferQueue::createBufferQueue(&producer, &consumer); //创建producer和consumer    mProducer = new MonitoredProducer(producer, mFlinger); //包装producer    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName); //包装consumer    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));    mSurfaceFlingerConsumer->setContentsChangedListener(this); //设置consumer的FrameAvailable监听器,                                                              //会在producer queueBuffer之后,通知consumer有可用的帧数据需要合成;    mSurfaceFlingerConsumer->setName(mName);}sp<IGraphicBufferProducer> Layer::getProducer() const {    return mProducer; //gbp实体就是这位大哥,                      //在Layer创建的时候创建的MonitoredProducer,但是这个只是一个包装,实体还不是这个。}

继续看…

///frameworks/native/libs/gui/BufferQueue.cpp//!!createBufferQueue是创建BufferQueue需要的元素:BufferQueueCore, Producer和Consumer。void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,        sp<IGraphicBufferConsumer>* outConsumer,        const sp<IGraphicBufferAlloc>& allocator) {    LOG_ALWAYS_FATAL_IF(outProducer == NULL,            "BufferQueue: outProducer must not be NULL");    LOG_ALWAYS_FATAL_IF(outConsumer == NULL,            "BufferQueue: outConsumer must not be NULL");    sp<BufferQueueCore> core(new BufferQueueCore(allocator));    LOG_ALWAYS_FATAL_IF(core == NULL,            "BufferQueue: failed to create BufferQueueCore");    //***BufferQueueProducer 才是真正的Producer    sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core));    LOG_ALWAYS_FATAL_IF(producer == NULL,            "BufferQueue: failed to create BufferQueueProducer");    sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));    LOG_ALWAYS_FATAL_IF(consumer == NULL,            "BufferQueue: failed to create BufferQueueConsumer");    *outProducer = producer;    *outConsumer = consumer;}

3. BufferQueue

参考:
Android BufferQueue生产消费原理概述

BufferQueue的消费者模型大概的通信流程:


4. Surface 和 Layer

SurfaceLayer是一一对应的, Surface属于图形生产者(Producer),Layer属于图形消费者(Consumer)。
App通过Surface提交的图形数据,通过enqueueBuffer之后,SurfaceFlinger会通过Layer获取到图形缓冲数据,最终渲染提交到屏幕做显示。

1. Surface绘图过程

ViewRootImpl创建空Surface之后,经过requestLayout操作或创建真正的Surface(见上图),然后App进程会经过measure,layout和draw最终将画面绘制出来。
这里着重看draw方法。

下图是Surface申请 GraphicBuffer, 绘制填充Buffer, 提交Buffer的流程。Buffer的设置其实是设置到了SKBitmap(Skia)中,然后再把SKBitmap设置到Canvas中,所以真正的Buffer携带者其实是Canvas,Surface负责申请Buffer,控制Buffer在绘制过程中的lock和unlock同步操作:

图形绘制的生产者消费者模型:

[在这里Producer是Surface, Consumer是Layer]

2. 整体绘制过程概述:

  • 1_ Surface -> lock,连接BufferQueue, 注册用于接收consumer消费完并会受到Buffer Queue的可用Frame的监听器(DummyProducerListener);
  • 2_ dequeueBuffer, 向QueueBuffer申请可用的GraphicBuffer;
  • 3_ 将申请的GraphicBuffer包装成SkBitmap,并设置到Canvas中,最后返回lockedSurface给Java层;
  • 4_ View绘制Canvas,填充图形数据到Canvas中;
  • 5_ Surface-> unlockAndPost, 提交填充完成的Buffer到BufferQueue;
  • 6_ BufferQueue会通知Consumer(Layer)当前有需要合成的Buffer存在,Layer收到监听之后,会通知SurfaceFlinger,最后通过Layer更新Texture,渲染完成后提交到屏幕显示;

综合两张图可以大致的看下从addView开始到Surface创建、申请Buffer、填充Buffer、绘制到体提交Buffer的整体流程:


5. 总结

从软件层面上看,Android的Graphic框架主要有几个模块:
Activity、Window、Surface、Layer、Canvas、BufferQueue。

其中:

  1. Activity:标记一个活动,是活动的管理者(并不参与绘制),是Window的承载者;
  2. Window:标记一个窗口(真实其实是WindowState),是一个抽象概念,用来对承载和管理Surface;
  3. Surface:标记一个绘制流程,面向开发者弱化了GraphicBuffer的概念,用来申请/提交Buffer,管理Canvas,管理一个绘制回合(绘制流程的同步);
  4. Layer:Graphic服务端的Buffer承载者,对应一个Surface,它受SurfaceFlinger的管理。SurfaceFlinger是Surface的消费者,消费单位是Layer;
  5. Canvas: 真正用于图形数据填充(绘制)的对象,Surface申请的Buffer会保存在Canvas中的SKBitmap中,绘制完成后,Surface会将Canvas对应的已经填充了有效数据的缓冲区enqueue到BufferQueue,然后通消费者有需要渲染的Buffer入队,然后交由消费者消费;

在App侧,只需要使用2D/3D图形绘制引擎来绘制出自己的图形数据,然后提交到这一块申请好的Buffer中,
并提交到BufferQueue,消费者SurfaceFlinger会从BufferQueue取出数据经由opengl渲染之后递交到屏幕显示。

  • App一般使用的事2D图形引擎Skia,3D由OpenGL做渲染。也可以通过开启硬件加速交由opengl来渲染,在Android N上有hwui作为硬件加速的可选项。
  • 关于Android APP中 Skia和openGL的了解,可以参考:
    Android Graphic : apk and Skia/OpenGL|ES
  1. BufferQueue: Android Graphic的核心之一,管理生产者和消费者之间对Buffer使用的同步,还有GPU/CPU的跨硬件同步(Fence),在Graphic系统上起着关键的作用。具体参考上面的第三大点

以上所有的流程个人总结为:
初始化会话链接 -> 添加Window,设置Window信息(显示屏幕、显示大小,格式等等) -> 创建Surface ->
初始化Layer -> 创建BufferQueue -> 申请Buffer -> 填充Buffer -> 提交Buffer -> 消费Buffer(渲染)->显示渲染内容

更多相关文章

  1. Android(安卓)P wakeup 亮屏流程
  2. android中的数据存取 之 File
  3. Android(安卓)onNewIntent的应用
  4. Android-使用OpengGL实现的Canvas进行绘制(简单介绍)
  5. Android(安卓)文字绘制,多行文字绘制
  6. Android的绘制详解(Canvas、Paint、Path等)
  7. Android(安卓)创建与解析XML(四)—— Pull方式
  8. Android(安卓)发布release版本的apk软件
  9. opengl fbo 离屏渲染

随机推荐

  1. Android(安卓)4.0 Ice Cream Sandwich 正
  2. android的文件操作
  3. Android屏幕投影及反向控制原理
  4. 关于android内存管理的原理,及相关自动内
  5. 【Android的从零单排开发日记】之入门篇(
  6. Android大赛首轮获奖作品解析。。。
  7. Android周学习Step By Step(5)--常用widget
  8. WCF 实例 —— Android(安卓)短信助手 (W
  9. Android(安卓)开发 UI 规则
  10. Android(安卓)SDK 2.3与Eclipse最新版开