SurfaceFlinger 属于system_server进程,在system_init.cpp中利用SurfaceFlinger::instantiate()启动,在此加入到service manager中,所以本身提供service服务功能。
首先看下SurfaceFlinger的类声明: class SurfaceFlinger : public BinderService<SurfaceFlinger>, public BnSurfaceComposer, protected Thread 从接口可以看出使用Binder与客户端通讯,并且继承线程 Thread 类,则循环执行threadLoop。完成系统中的各个Layer-Surface进行混合,然后将一帧帧混合好的图像传送到显示framebuffer中。 其主线程工作流程图如下: 下面就这以上图五步将代码一一过一遍: 1、waitForEvent() 等待什么事情呢? void SurfaceFlinger::waitForEvent() { while (true) { ...... sp<MessageBase> msg = mEventQueue.waitMessage(timeout); ...... if (msg != 0) { switch (msg->what) { //等的就是这个消息事件哟。。。。 case MessageQueue::INVALIDATE: // invalidate message, just return to the main loop return; } } } } 原来是等待收到MessageQueue::INVALIDATE重绘消息才退回到主线程,那么这个消息由谁来发送呢? 请看下面代码: void SurfaceFlinger::signalEvent() { mEventQueue.invalidate(); } void SurfaceFlinger::signal() const { // this is the IPC call const_cast<SurfaceFlinger*>(this)->signalEvent(); } 这是就是发送消息的点,这个函数signalEvent由谁来调用呢?其个这个发起都是上一节说的,在释放Surface对应的显示缓冲区需要显示时调用: unlockAndPost() --> queueBuffer() --> mClient.signalServer() --> SurfaceFlinger::signal() 2、handlePageFlip() 该阶段会遍历各个Layer,在每个Layer中,取得并锁住该Layer的frontBuffer,然后利用frontBuffer 中的图像数据生成该Layer的2D贴图(Texture),并且计算更新区域,为后续的混合操作做准备。 void SurfaceFlinger::handlePageFlip() { //调用 lockPageFlip visibleRegions |= lockPageFlip(currentLayers); //取得屏幕的区域 const Region screenRegion(hw.bounds()); if (visibleRegions) { Region opaqueRegion; computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); ..... mWormholeRegion = screenRegion.subtract(opaqueRegion); } ..... //调用 unlockPageFlip unlockPageFlip(currentLayers); } 上面的调用实际上是一对函数:lockPageFlip & lockPageFlip,那么主要干些啥呢? bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) { bool recomputeVisibleRegions = false; size_t count = currentLayers.size(); sp<LayerBase> const* layers = currentLayers.array(); //逐个 layer 进行处理 for (size_t i=0 ; i<count ; i++) { const sp<LayerBase>& layer(layers[i]); layer->lockPageFlip(recomputeVisibleRegions); } return recomputeVisibleRegions; } void Layer::lockPageFlip(bool& recomputeVisibleRegions) { SharedBufferServer* lcblk(sharedClient.get()); // 获取当前可用的 frontbuffer 索引号 ssize_t buf = lcblk->retireAndLock(); // 计算当前的脏区域 sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); if (newFrontBuffer != NULL) { // get the dirty region // compute the posted region const Region dirty(lcblk->getDirtyRegion(buf)); mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); .... // 如果有脏区域需要重绘,则生成 OpenGL ES 纹理贴图 reloadTexture( mPostedDirtyRegion ); } void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) { const GraphicPlane& plane(graphicPlane(0)); const Transform& planeTransform(plane.transform()); size_t count = currentLayers.size(); sp<LayerBase> const* layers = currentLayers.array(); for (size_t i=0 ; i<count ; i++) { const sp<LayerBase>& layer(layers[i]); //进行区域的清理工作 layer->unlockPageFlip(planeTransform, mDirtyRegion); } } void Layer::unlockPageFlip( const Transform& planeTransform, Region& outDirtyRegion) { Region dirtyRegion(mPostedDirtyRegion); if (!dirtyRegion.isEmpty()) { mPostedDirtyRegion.clear(); .... if (visibleRegionScreen.isEmpty()) { // an invisible layer should not hold a freeze-lock // (because it may never be updated and therefore never release it) mFreezeLock.clear(); } } 以上的工作就是按照 Zorder 序计算自已屏幕上的可显示区域: 1、以自己的W,H给出自己初始的可见区域 2、减去自己上面窗口所覆盖的区域 3、handleRepaint 每个Layer的数据都准备好了,并且各个脏区域也计算ok,下步就是根据 Zorder 序从底部将数据绘制到主Surface上 void SurfaceFlinger::handleRepaint() { // compute the invalid region mInvalidRegion.orSelf(mDirtyRegion); .... // compose all surfaces composeSurfaces(mDirtyRegion); // clear the dirty regions mDirtyRegion.clear(); } void SurfaceFlinger::composeSurfaces(const Region& dirty) { ... const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { const sp<LayerBase>& layer(layers[i]); const Region clip(dirty.intersect(layer->visibleRegionScreen)); if (!clip.isEmpty()) { // 这就是绘图核心函数 layer->draw(clip); } } } void Layer::onDraw(const Region& clip) const ---> drawWithOpenGL(clip, tex); 基本上都是OpenGL ES 操作函数 while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); // 裁剪 glScissor(r.left, sy, r.width(), r.height()); // 画矩形 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } 4、unlockClients() 释放 handlePageFlip 占用的 frontbuffer 索引号,以便客户端可以继续在新的surface画图 void SurfaceFlinger::unlockClients() { ... for (size_t i=0 ; i<count ; ++i) { const sp<LayerBase>& layer = layers[i]; layer->finishPageFlip(); } } --> SharedBufferServer* lcblk(sharedClient.get()); status_t err = lcblk->unlock( buf ); 5、postFramebuffer() 现在已经将所有的Layer图层数据合成完成,最后就是输入到屏幕上显示了 void SurfaceFlinger::postFramebuffer() { //调用此函数将混合后的图像传递到屏幕中进行显示 hw.flip(mInvalidRegion); ... } void DisplayHardware::flip(const Region& dirty) const { // 显示图像吧。。。。。 eglSwapBuffers(dpy, surface); } |
|