图像输出过程总结

81 篇文章 5 订阅

上篇博客分析到SurfaceFlinger收到了VSync信号后,调用了handleMessageRefresh函数,这篇博客主要就是分析这个函数,我们先看看它的代码:

  1. void SurfaceFlinger::handleMessageRefresh() {  
  2.     ATRACE_CALL();  
  3.   
  4.     static nsecs_t previousExpectedPresent = 0;  
  5.     nsecs_t expectedPresent = mPrimaryDispSync.computeNextRefresh(0);  
  6.     static bool previousFrameMissed = false;  
  7.     bool frameMissed = (expectedPresent == previousExpectedPresent);  
  8.     if (frameMissed != previousFrameMissed) {  
  9.         ATRACE_INT("FrameMissed"static_cast<int>(frameMissed));  
  10.     }  
  11.     previousFrameMissed = frameMissed;  
  12.   
  13.     if (CC_UNLIKELY(mDropMissedFrames && frameMissed)) {  
  14.         // Latch buffers, but don't send anything to HWC, then signal another  
  15.         // wakeup for the next vsync  
  16.         preComposition();  
  17.         repaintEverything();  
  18.     } else {  
  19.         preComposition();  
  20.         rebuildLayerStacks();  
  21.         setUpHWComposer();  
  22.         doDebugFlashRegions();  
  23.         doComposition();  
  24.         postComposition();  
  25.     }  
  26.   
  27.     previousExpectedPresent = mPrimaryDispSync.computeNextRefresh(0);  
  28. }  

我们主要看下下面几个函数。

  1. preComposition();  
  2. rebuildLayerStacks();  
  3. setUpHWComposer();  
  4. doDebugFlashRegions();  
  5. doComposition();  
  6. postComposition();  


一、preComposition函数

我们先来看第一个函数preComposition

  1. void SurfaceFlinger::preComposition()  
  2. {  
  3.     bool needExtraInvalidate = false;  
  4.     const LayerVector& layers(mDrawingState.layersSortedByZ);  
  5.     const size_t count = layers.size();  
  6.     for (size_t i=0 ; i<count ; i++) {  
  7.         if (layers[i]->onPreComposition()) {  
  8.             needExtraInvalidate = true;  
  9.         }  
  10.     }  
  11.     if (needExtraInvalidate) {  
  12.         signalLayerUpdate();  
  13.     }  
  14. }  

上面函数先是调用了mDrawingState的layersSortedByZ来得到上次绘图的Layer层列表。并不是所有的Layer都会参与屏幕图像的绘制,因此SurfaceFlinger用state对象来记录参与绘制的Layer对象。

记得在之前的博客,我们分析过createLayer函数来创建Layer,创建之后会调用addClientLayer函数。

  1. status_t SurfaceFlinger::createLayer(  
  2.         const String8& name,  
  3.         const sp<Client>& client,  
  4.         uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,  
  5.         sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)  
  6. {  
  7.     //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());  
  8.     if (int32_t(w|h) < 0) {  
  9.         ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",  
  10.                 int(w), int(h));  
  11.         return BAD_VALUE;  
  12.     }  
  13.   
  14.     status_t result = NO_ERROR;  
  15.   
  16.     sp<Layer> layer;  
  17.   
  18.     switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {  
  19.         case ISurfaceComposerClient::eFXSurfaceNormal:  
  20.             result = createNormalLayer(client,  
  21.                     name, w, h, flags, format,  
  22.                     handle, gbp, &layer);  
  23.             break;  
  24.         case ISurfaceComposerClient::eFXSurfaceDim:  
  25.             result = createDimLayer(client,  
  26.                     name, w, h, flags,  
  27.                     handle, gbp, &layer);  
  28.             break;  
  29.         default:  
  30.             result = BAD_VALUE;  
  31.             break;  
  32.     }  
  33.   
  34.     if (result != NO_ERROR) {  
  35.         return result;  
  36.     }  
  37.   
  38.     result = addClientLayer(client, *handle, *gbp, layer);  
  39.     if (result != NO_ERROR) {  
  40.         return result;  
  41.     }  
  42.   
  43.     setTransactionFlags(eTransactionNeeded);  
  44.     return result;  
  45. }  

我们来看下addClientLayer函数,这里会把Layer对象放在mCurrentState的layersSortedByZ对象中。而mDrawingState和mCurrentState什么关系呢?在后面我们会介绍,mDrawingState代表上一次绘图时的状态,处理完之后会把mCurrentState赋给mDrawingState。

  1. status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,  
  2.         const sp<IBinder>& handle,  
  3.         const sp<IGraphicBufferProducer>& gbc,  
  4.         const sp<Layer>& lbc)  
  5. {  
  6.     // add this layer to the current state list  
  7.     {  
  8.         Mutex::Autolock _l(mStateLock);  
  9.         if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) {  
  10.             return NO_MEMORY;  
  11.         }  
  12.         mCurrentState.layersSortedByZ.add(lbc);  
  13.         mGraphicBufferProducerList.add(IInterface::asBinder(gbc));  
  14.     }  
  15.   
  16.     // attach this layer to the client  
  17.     client->attachLayer(handle, lbc);  
  18.   
  19.     return NO_ERROR;  
  20. }  

回到preComposition函数,遍历所有的Layer对象,调用其onPreComposition函数来检测Layer层中的图像是否有变化。

  1. void SurfaceFlinger::preComposition()  
  2. {  
  3.     bool needExtraInvalidate = false;  
  4.     const LayerVector& layers(mDrawingState.layersSortedByZ);  
  5.     const size_t count = layers.size();  
  6.     for (size_t i=0 ; i<count ; i++) {  
  7.         if (layers[i]->onPreComposition()) {  
  8.             needExtraInvalidate = true;  
  9.         }  
  10.     }  
  11.     if (needExtraInvalidate) {  
  12.         signalLayerUpdate();  
  13.     }  
  14. }  


1.1 每个Layer的onFrameAvailable函数

onPreComposition函数来根据mQueuedFrames来判断图像是否发生了变化,或者是mSidebandStreamChanged。

  1. bool Layer::onPreComposition() {  
  2.     mRefreshPending = false;  
  3.     return mQueuedFrames > 0 || mSidebandStreamChanged;  
  4. }  

当Layer所对应的Surface更新图像后,它所对应的Layer对象的onFrameAvailable函数会被调用来通知这种变化。
我们看Layer的onFirstRef函数,先调用BufferQueue::createBufferQueue来获取一个Buffer的消费者和生产者。然后新建了一个MonitoredProducer和一个SurfaceFlingerConsumer

  1. void Layer::onFirstRef() {  
  2.     // Creates a custom BufferQueue for SurfaceFlingerConsumer to use  
  3.     sp<IGraphicBufferProducer> producer;  
  4.     sp<IGraphicBufferConsumer> consumer;  
  5.     BufferQueue::createBufferQueue(&producer, &consumer);  
  6.     mProducer = new MonitoredProducer(producer, mFlinger);  
  7.     mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);  
  8.     mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));  
  9.     mSurfaceFlingerConsumer->setContentsChangedListener(this);  
  10.     mSurfaceFlingerConsumer->setName(mName);  

我们再来看SurfaceFlingerConsumer的setContentsChangedListener函数

  1. void SurfaceFlingerConsumer::setContentsChangedListener(  
  2.         const wp<ContentsChangedListener>& listener) {  
  3.     setFrameAvailableListener(listener);  
  4.     Mutex::Autolock lock(mMutex);  
  5.     mContentsChangedListener = listener;  
  6. }  

上面函数是调用了基类ConsumerBase的setFrameAvailableListener函数,将listener赋给了mFrameAvailableListener。

  1. void ConsumerBase::setFrameAvailableListener(  
  2.         const wp<FrameAvailableListener>& listener) {  
  3.     CB_LOGV("setFrameAvailableListener");  
  4.     Mutex::Autolock lock(mMutex);  
  5.     mFrameAvailableListener = listener;  
  6. }  

而最终在其onFrameAvailable函数中调用了listener->onFrameAvailable函数。

  1. void ConsumerBase::onFrameAvailable(const BufferItem& item) {  
  2.     CB_LOGV("onFrameAvailable");  
  3.   
  4.     sp<FrameAvailableListener> listener;  
  5.     { // scope for the lock  
  6.         Mutex::Autolock lock(mMutex);  
  7.         listener = mFrameAvailableListener.promote();  
  8.     }  
  9.   
  10.     if (listener != NULL) {  
  11.         CB_LOGV("actually calling onFrameAvailable");  
  12.         listener->onFrameAvailable(item);  
  13.     }  
  14. }  
因此我们再来看看Layer的onFrameAvailable函数,主要是将mQueuedFrames加1,然后调用了SurfaceFlinger的signalLayerUpdate函数。
  1. void Layer::onFrameAvailable(const BufferItem& item) {  
  2.     // Add this buffer from our internal queue tracker  
  3.     { // Autolock scope  
  4.         Mutex::Autolock lock(mQueueItemLock);  
  5.   
  6.         // Reset the frame number tracker when we receive the first buffer after  
  7.         // a frame number reset  
  8.         if (item.mFrameNumber == 1) {  
  9.             mLastFrameNumberReceived = 0;  
  10.         }  
  11.   
  12.         // Ensure that callbacks are handled in order  
  13.         while (item.mFrameNumber != mLastFrameNumberReceived + 1) {  
  14.             status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,  
  15.                     ms2ns(500));  
  16.             if (result != NO_ERROR) {  
  17.                 ALOGE("[%s] Timed out waiting on callback", mName.string());  
  18.             }  
  19.         }  
  20.   
  21.         mQueueItems.push_back(item);  
  22.         android_atomic_inc(&mQueuedFrames);  
  23.   
  24.         // Wake up any pending callbacks  
  25.         mLastFrameNumberReceived = item.mFrameNumber;  
  26.         mQueueItemCondition.broadcast();  
  27.     }  
  28.   
  29.     mFlinger->signalLayerUpdate();  
  30. }  

同样在SurfaceFlinger的preComposition函数中当有Layer的图像改变了,最后也会调用SurfaceFlinger的signalLayerUpdate函数。

  1. void SurfaceFlinger::preComposition()  
  2. {  
  3.     bool needExtraInvalidate = false;  
  4.     const LayerVector& layers(mDrawingState.layersSortedByZ);  
  5.     const size_t count = layers.size();  
  6.     for (size_t i=0 ; i<count ; i++) {  
  7.         if (layers[i]->onPreComposition()) {  
  8.             needExtraInvalidate = true;  
  9.         }  
  10.     }  
  11.     if (needExtraInvalidate) {  
  12.         signalLayerUpdate();  
  13.     }  
  14. }  

SurfaceFlinger::signalLayerUpdate是调用了MessageQueue的invalidate函数

  1. void SurfaceFlinger::signalLayerUpdate() {  
  2.     mEventQueue.invalidate();  
  3. }  

调用了handler的dispatchInvalidate函数,

  1. void MessageQueue::invalidate() {  
  2. #if INVALIDATE_ON_VSYNC  
  3.     mEvents->requestNextVsync();  
  4. #else  
  5.     mHandler->dispatchInvalidate();  
  6. #endif  
  7. }  

Handler::dispatchInvalidate只是发送了一个消息

  1. void MessageQueue::Handler::dispatchInvalidate() {  
  2.     if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {  
  3.         mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));  
  4.     }  
  5. }  

最后处理还是调用了SurfaceFlinger的onMessageReceived函数。

  1. case INVALIDATE:  
  2.     android_atomic_and(~eventMaskInvalidate, &mEventMask);  
  3.     mQueue.mFlinger->onMessageReceived(message.what);  
  4.     break;  

我们再来看看SurfaceFlinger的onMessageReceived函数对NVALIDATE的处理

  1. void SurfaceFlinger::onMessageReceived(int32_t what) {  
  2.     ATRACE_CALL();  
  3.     switch (what) {  
  4.         ......  
  5.         case MessageQueue::INVALIDATE: {  
  6.             bool refreshNeeded = handleMessageTransaction();  
  7.             refreshNeeded |= handleMessageInvalidate();  
  8.             refreshNeeded |= mRepaintEverything;  
  9.             if (refreshNeeded) {  
  10.                 // Signal a refresh if a transaction modified the window state,  
  11.                 // a new buffer was latched, or if HWC has requested a full  
  12.                 // repaint  
  13.                 signalRefresh();  
  14.             }  
  15.             break;  

我们先来看下handleMessageTransaction和handleMessageInvalidate函数。

  1. bool SurfaceFlinger::handleMessageTransaction() {  
  2.     uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);  
  3.     if (transactionFlags) {  
  4.         handleTransaction(transactionFlags);  
  5.         return true;  
  6.     }  
  7.     return false;  
  8. }  
  9.   
  10. bool SurfaceFlinger::handleMessageInvalidate() {  
  11.     ATRACE_CALL();  
  12.     return handlePageFlip();  
  13. }  

handleMessageInvalidate函数中调用了handlePageFlip函数,这个函数将会处理Layer中的缓冲区,把更新过的图像缓冲区切换到前台,等待VSync信号更新到FrameBuffer。


1.2 绘制流程

具体完整的绘制流程如图。


用户进程更新Surface图像,将导致SurfaceFlinger中的Layer发送invalidate消息,处理该消息会调用handleTransaction函数和handlePageFilp函数来更新Layer对象。一旦VSync信号到来,再调用rebuildlayerStacks setUpHWComposer doComposition postComposition函数将所有Layer的图像混合后更新到显示设备上去。


二、handleTransaction handPageFlip更新Layer对象

在上一节中的绘图的流程中,我们看到了handleTransaction和handPageFlip这两个函数通常是在用户进程更新Surface图像时会调用,来更新Layer对象。这节就主要讲解这两个函数。

2.1 handleTransaction函数

handleTransaction函数的参数是transactionFlags,不过函数中没有使用这个参数,而是通过getTransactionFlags(eTransactionMask)来重新对transactionFlags赋值,然后使用它作为参数来调用函数handleTransactionLocked。

  1. void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)  
  2. {  
  3.     ATRACE_CALL();  
  4.   
  5.     State drawingState(mDrawingState);  
  6.   
  7.     Mutex::Autolock _l(mStateLock);  
  8.     const nsecs_t now = systemTime();  
  9.     mDebugInTransaction = now;  
  10.   
  11.     transactionFlags = getTransactionFlags(eTransactionMask);//产生一个新的transactionFlags变量  
  12.     handleTransactionLocked(transactionFlags);  
  13.   
  14.     mLastTransactionTime = systemTime() - now;  
  15.     mDebugInTransaction = 0;  
  16.     invalidateHwcGeometry();  
  17. }  

getTransactionFlags函数的参数是eTransactionMask只是屏蔽其他位。

  1. uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {  
  2.     return android_atomic_and(~flags, &mTransactionFlags) & flags;  
  3. }  

handleTransactionLocked函数会调用每个Layer类的doTransaction函数,在分析handleTransactionLocked函数之前,我们先看看Layer类 的doTransaction函数。


2.2 Layer的doTransaction函数

下面是Layer的doTransaction函数代码

  1. uint32_t Layer::doTransaction(uint32_t flags) {  
  2.     ATRACE_CALL();  
  3.   
  4.     const Layer::State& s(getDrawingState());//上次绘制的State对象  
  5.     const Layer::State& c(getCurrentState());//当前使用的State对象  
  6.   
  7.     const bool sizeChanged = (c.requested.w != s.requested.w) ||//如果两个对象的大小不相等,说明Layer的尺寸发生变化  
  8.                              (c.requested.h != s.requested.h);  
  9.   
  10.     if (sizeChanged) {//如果Layer的尺寸发生变化,就要改变Surface的缓冲区的尺寸  
  11.         mSurfaceFlingerConsumer->setDefaultBufferSize(  
  12.                 c.requested.w, c.requested.h);  
  13.     }  
  14.   
  15.     if (!isFixedSize()) {  
  16.         //如果Layer不是固定尺寸的类型,比较它的实际大小和要求的改变大小  
  17.         const bool resizePending = (c.requested.w != c.active.w) ||  
  18.                                    (c.requested.h != c.active.h);  
  19.   
  20.         if (resizePending && mSidebandStream == NULL) {//如果两者不一样,flags加上不更新Geometry标志  
  21.             flags |= eDontUpdateGeometryState;  
  22.         }  
  23.     }  
  24.   
  25.     if (flags & eDontUpdateGeometryState)  {  
  26.     } else {  
  27.         //如果没有eDontUpdateGeometryState标志,更新active的值为request  
  28.         Layer::State& editCurrentState(getCurrentState());  
  29.         editCurrentState.active = c.requested;  
  30.     }  
  31.   
  32.     if (s.active != c.active) {  
  33.         // 如果当前state的active和以前的State的active不等,设置更新标志  
  34.         flags |= Layer::eVisibleRegion;  
  35.     }  
  36.   
  37.     if (c.sequence != s.sequence) {  
  38.         //如果当前state的sequence和以前state的sequence不等,设置更新标志  
  39.         flags |= eVisibleRegion;  
  40.         this->contentDirty = true;  
  41.   
  42.         const uint8_t type = c.transform.getType();  
  43.         mNeedsFiltering = (!c.transform.preserveRects() ||  
  44.                 (type >= Transform::SCALE));  
  45.     }  
  46.   
  47.     // Commit the transaction  
  48.     commitTransaction();//将mCurrentState的值赋给mDrawingState  
  49.     return flags;  
  50. }  

Layer类中的两个类型为Layer::State的成员变量mDrawingState、mCurrentState,我们来看下Layer::State类型

  1. struct State {  
  2.     Geometry active;//实际大小  
  3.     Geometry requested;//用户大小  
  4.     uint32_t z;//Layer的Z轴值  
  5.     uint32_t layerStack;//和显示设备的关联值  
  6.     uint8_t alpha;//Layer的透明度  
  7.     uint8_t flags;//Layer的标志  
  8.     uint8_t reserved[2];  
  9.     int32_t sequence; //序列值,Layer的属性变化一次,这个值就加1  
  10.     Transform transform;  
  11.     // the transparentRegion hint is a bit special, it's latched only  
  12.     // when we receive a buffer -- this is because it's "content"  
  13.     // dependent.  
  14.     Region activeTransparentRegion;//实际的透明区域  
  15.     Region requestedTransparentRegion;//用户社会中的透明区域  
  16. };  

这里为什么要两个对象呢?Layer对象在绘制图形时,使用的是mDrawingState变量,用户调用接口设置Layer对象属性是,设置的值保存在mCurrentState对象中,这样就不会因为用户的操作而干扰Layer对象的绘制了。

Layer的doTransaction函数据你是比较这两个变量,如果有不同的地方,说明在上次绘制以后,用户改变的Layer的设置,要把这种变化通过flags返回。

State的结构中有两个Geometry字段,active和requested。他们表示layer的尺寸,其中requested保存是用户设置的尺寸,而active保存的值通过计算后的实际尺寸。

State中的z字段的值就是Layer在显示轴的位置,值越小位置越靠下。

layerStack字段是用户指定的一个值,用户可以给DisplayDevice也指定一个layerStack值,只有Layer对象和DisplayDevice对象的layerStack相等,这个Layer才能在这个显示设备上输出,这样的好处是可以让显示设备只显示某个Surface的内容。例如,可以让HDMI显示设备只显示手机上播放视频的Surface窗口,但不显示Activity窗口。

sequence字段是个序列值,每当用户调用了Layer的接口,例如setAlpha、setSize或者setLayer等改变Layer对象属性的哈数,这个值都会加1。因此在doTransaction函数中能通过比较sequence值来判断Layer的属性值有没有变化。

doTransaction函数最后会调用commitTransaction函数,就是把mCurrentState赋值给mDrawingState

  1. void Layer::commitTransaction() {  
  2.     mDrawingState = mCurrentState;  
  3. }  


2.3 handleTransactionLocked函数

下面我们来分析handleTransactionLocked函数,这个函数比较长,我们分段分析


2.3.1 处理Layer的事务
  1. void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)  
  2. {  
  3.     const LayerVector& currentLayers(mCurrentState.layersSortedByZ);  
  4.     const size_t count = currentLayers.size();  
  5.   
  6.     /* 
  7.      * Traversal of the children 
  8.      * (perform the transaction for each of them if needed) 
  9.      */  
  10.   
  11.     if (transactionFlags & eTraversalNeeded) {  
  12.         for (size_t i=0 ; i<count ; i++) {  
  13.             const sp<Layer>& layer(currentLayers[i]);  
  14.             uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);  
  15.             if (!trFlags) continue;  
  16.   
  17.             const uint32_t flags = layer->doTransaction(0);  
  18.             if (flags & Layer::eVisibleRegion)  
  19.                 mVisibleRegionsDirty = true;  
  20.         }  
  21.     }  
在SurfaceFlinger中也有两个类型为State的变量mCurrentState和mDrawingState,但是和Layer中的不要混起来。它的名字相同而已
  1. struct State {  
  2.     LayerVector layersSortedByZ;  
  3.     DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;  
  4. };  

结构layersSortedByZ字段保存所有参与绘制的Layer对象,而字段displays保存的是所有输出设备的DisplayDeviceState对象

这里用两个变量的目的是和Layer中使用两个变量是一样的。

上面代码根据eTraversalNeeded标志来决定是否要检查所有的Layer对象。如果某个Layer对象中有eTransactionNeeded标志,将调用它的doTransaction函数。Layer的doTransaction函数返回的flags如果有eVisibleRegion,说明这个Layer需要更新,就把mVisibleRegionsDirty设置为true


2.3.2 处理显示设备的变化
  1. if (transactionFlags & eDisplayTransactionNeeded) {  
  2.     //得到当前显示设备列表和之前使用的显示设备列表  
  3.     const KeyedVector<  wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);  
  4.     const KeyedVector<  wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);  
  5.     if (!curr.isIdenticalTo(draw)) {  
  6.         mVisibleRegionsDirty = true;  
  7.         const size_t cc = curr.size();//现在显示设备的数量  
  8.               size_t dc = draw.size();//以前显示设备的数量  
  9.   
  10.         for (size_t i=0 ; i<dc ; i++) {  
  11.             const ssize_t j = curr.indexOfKey(draw.keyAt(i));  
  12.             if (j < 0) {//j< 0代表当前设备列表中找不到以前设备列表中的某个设备,设备被删除了  
  13.                 if (!draw[i].isMainDisplay()) {  
  14.                     ......  
  15.                     //如果不是主设备移除它  
  16.                     mDisplays.removeItem(draw.keyAt(i));  
  17.                 } else {  
  18.                     ALOGW("trying to remove the main display");  
  19.                 }  
  20.             } else {//j>0代表这个设备两个列表中都存在,再检查有没有其他变化  
  21.                 // this display is in both lists. see if something changed.  
  22.                 const DisplayDeviceState& state(curr[j]);  
  23.                 const wp<IBinder>& display(curr.keyAt(j));  
  24.                 const sp<IBinder> state_binder = IInterface::asBinder(state.surface);  
  25.                 const sp<IBinder> draw_binder = IInterface::asBinder(draw[i].surface);  
  26.                 if (state_binder != draw_binder) {  
  27.                     //设备的Surface已经发生了变化(Surface对象不是一个了),旧的设备必须先删除掉  
  28.                     sp<DisplayDevice> hw(getDisplayDevice(display));  
  29.                     if (hw != NULL)  
  30.                         hw->disconnect(getHwComposer());  
  31.                     mDisplays.removeItem(display);  
  32.                     mDrawingState.displays.removeItemsAt(i);  
  33.                     dc--; i--;  
  34.                     // at this point we must loop to the next item  
  35.                     continue;  
  36.                 }  
  37.   
  38.                 const sp<DisplayDevice> disp(getDisplayDevice(display));  
  39.                 if (disp != NULL) {  
  40.                     //两个对象的layerStack不相等,使用当前对象的  
  41.                     if (state.layerStack != draw[i].layerStack) {  
  42.                         disp->setLayerStack(state.layerStack);  
  43.                     }  
  44.                     //如果两个对象的方向、viewport、frame不相等,使用当前对象的  
  45.                     if ((state.orientation != draw[i].orientation)  
  46.                             || (state.viewport != draw[i].viewport)  
  47.                             || (state.frame != draw[i].frame))  
  48.                     {  
  49.                         disp->setProjection(state.orientation,  
  50.                                 state.viewport, state.frame);  
  51.                     }  
  52.                     if (state.width != draw[i].width || state.height != draw[i].height) {  
  53.                         disp->setDisplaySize(state.width, state.height);  
  54.                     }  
  55.                 }  
  56.             }  
  57.         }  
  58.   
  59.         // 处理显示设备增加的情况  
  60.         for (size_t i=0 ; i<cc ; i++) {  
  61.             if (draw.indexOfKey(curr.keyAt(i)) < 0) {  
  62.             //当前列表中某个设备在以前列表中没有找到,说明是增加的设备  
  63.             //创建DisplayDevice对象,把它加入到mDisplays列表中  
  64.                 ......  
  65.                 const wp<IBinder>& display(curr.keyAt(i));  
  66.                 if (dispSurface != NULL) {  
  67.                     sp<DisplayDevice> hw = new DisplayDevice(this,  
  68.                             state.type, hwcDisplayId,  
  69.                             mHwc->getFormat(hwcDisplayId), state.isSecure,  
  70.                             display, dispSurface, producer,  
  71.                             mRenderEngine->getEGLConfig());  
  72.                     ......  
  73.                     mDisplays.add(display, hw);  
  74.                     ......  
  75.                 }  
  76.             }  
  77.         }  
  78.     }  
  79. }  

这段代码的作用是处理显示设备的变化,分成3种情况:

1.显示设备减少了,需要把显示设备对应的DisplayDevice移除

2.显示设备发生了变化,例如用户设置了Surface、重新设置了layerStack、旋转了屏幕等,这就需要重新设置显示对象的属性

3.显示设备增加了,创建新的DisplayDevice加入系统中。


2.3.3 设置TransfromHit
  1. if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {  
  2.     sp<const DisplayDevice> disp;  
  3.     uint32_t currentlayerStack = 0;  
  4.     for (size_t i=0; i<count; i++) {  
  5.         // NOTE: we rely on the fact that layers are sorted by  
  6.         // layerStack first (so we don't have to traverse the list  
  7.         // of displays for every layer).  
  8.         const sp<Layer>& layer(currentLayers[i]);  
  9.         uint32_t layerStack = layer->getDrawingState().layerStack;  
  10.         if (i==0 || currentlayerStack != layerStack) {  
  11.             currentlayerStack = layerStack;  
  12.             // figure out if this layerstack is mirrored  
  13.             // (more than one display) if so, pick the default display,  
  14.             // if not, pick the only display it's on.  
  15.             disp.clear();//清除disp  
  16.             for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {  
  17.                 sp<const DisplayDevice> hw(mDisplays[dpy]);  
  18.                 if (hw->getLayerStack() == currentlayerStack) {  
  19.                     if (disp == NULL) {  
  20.                         disp = hw;//找到了一个layerStacker相同的显示设备  
  21.                     } else {  
  22.                         disp = NULL;//如果有两个显示设备的layerStacker相同,都不用  
  23.                         break;  
  24.                     }  
  25.                 }  
  26.             }  
  27.         }  
  28.         if (disp == NULL) {  
  29.             // 没有找到具有相同layerStack的显示设备,使用缺省设备  
  30.             disp = getDefaultDisplayDevice();  
  31.         }  
  32.         layer->updateTransformHint(disp);//设置Layer对象的TransformHint  
  33.     }  
  34. }  

这段代码的作用是根据每种显示设备的不同,设置和显示设备关联在一起的Layer(主要看Layer的layerStack是否和DisplayDevice的layerStack)的TransformHint(主要指设备的显示方向orientation)。



2.3.4 处理Layer增加情况
  1. const LayerVector& layers(mDrawingState.layersSortedByZ);  
  2. if (currentLayers.size() > layers.size()) {  
  3.     // 如果有Layer加入,设置需要更新  
  4.     mVisibleRegionsDirty = true;  
  5. }  
  6.   
  7. // 处理有Layer删除的情况  
  8. if (mLayersRemoved) {  
  9.     mLayersRemoved = false;  
  10.     mVisibleRegionsDirty = true;  
  11.     const size_t count = layers.size();  
  12.     for (size_t i=0 ; i<count ; i++) {  
  13.         const sp<Layer>& layer(layers[i]);  
  14.         if (currentLayers.indexOf(layer) < 0) {  
  15.             //如果这个Layer已经不存在了,把它的所在区域设置为需要更新的区域  
  16.             const Layer::State& s(layer->getDrawingState());  
  17.             Region visibleReg = s.transform.transform(  
  18.                     Region(Rect(s.active.w, s.active.h)));  
  19.             invalidateLayerStack(s.layerStack, visibleReg);  
  20.         }  
  21.     }  
  22. }  

这段代码处理Layer的增加情况,如果Layer增加了,需要重新计算设备的更新区域,因此把mVisibleRegionsDirty设为true,如果Layer删除了,需要把Layer的可见区域加入到系统需要更新的区域中。


2.3.5 设置mDrawingState
  1. commitTransaction();  
  2.   
  3. updateCursorAsync();  

调用commitTransaction和updateCursorAsync函数 commitTransaction函数作用是把mDrawingState的值设置成mCurrentState的值。而updateCursorAsync函数会更新所有显示设备中光标的位置。


2.3.6 小结

handleTransaction函数的作用的就是处理系统在两次刷新期间的各种变化。SurfaceFlinger模块中不管是SurfaceFlinger类还是Layer类,都采用了双缓冲的方式来保存他们的属性,这样的好处是刚改变SurfaceFlinger对象或者Layer类对象的属性是,不需要上锁,大大的提高了系统效率。只有在最后的图像输出是,才进行一次上锁,并进行内存的属性变化处理。正因此,应用进程必须收到VSync信号才开始改变Surface的内容。


2.4 handlePageFlip函数

handlePageFlip函数代码如下:

  1. bool SurfaceFlinger::handlePageFlip()  
  2. {  
  3.     Region dirtyRegion;  
  4.   
  5.     bool visibleRegions = false;  
  6.     const LayerVector& layers(mDrawingState.layersSortedByZ);  
  7.     bool frameQueued = false;  
  8.   
  9.     Vector<Layer*> layersWithQueuedFrames;  
  10.     //查找需要更新的Layer  
  11.     for (size_t i = 0, count = layers.size(); i<count ; i++) {  
  12.         const sp<Layer>& layer(layers[i]);  
  13.         if (layer->hasQueuedFrame()) {  
  14.             frameQueued = true;  
  15.             if (layer->shouldPresentNow(mPrimaryDispSync)) {  
  16.                 layersWithQueuedFrames.push_back(layer.get());  
  17.             } else {  
  18.                 layer->useEmptyDamage();  
  19.             }  
  20.         } else {  
  21.             layer->useEmptyDamage();  
  22.         }  
  23.     }  
  24.     for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {  
  25.         Layer* layer = layersWithQueuedFrames[i];  
  26.         const Region dirty(layer->latchBuffer(visibleRegions));  
  27.         layer->useSurfaceDamage();  
  28.         const Layer::State& s(layer->getDrawingState());  
  29.         invalidateLayerStack(s.layerStack, dirty);  
  30.     }  
  31.   
  32.     mVisibleRegionsDirty |= visibleRegions;  
  33.   
  34.     if (frameQueued && layersWithQueuedFrames.empty()) {  
  35.         signalLayerUpdate();  
  36.     }  
  37.   
  38.     return !layersWithQueuedFrames.empty();  
  39. }  

handlePageFlip函数先调用每个Layer对象的hasQueuedFrame函数,确定这个Layer对象是否有需要更新的图层,然后把需要更新的Layer对象放到layersWithQueuedFrames中。

我们先来看Layer的hasQueuedFrame方法就是看其mQueuedFrames是否大于0 和mSidebandStreamChanged。前面小节分析只要Surface有数据写入,就会调用Layer的onFrameAvailable函数,然后mQueuedFrames值加1.

  1. bool hasQueuedFrame() const { return mQueuedFrames > 0 || mSidebandStreamChanged; }  

继续看handlePageFlip函数,接着调用需要更新的Layer对象的latchBuffer函数,然后根据返回的更新区域调用invalidateLayerStack函数来设置更新设备对象的更新区域。
下面我们看看latchBuffer函数

  1. Region Layer::latchBuffer(bool& recomputeVisibleRegions)  
  2. {  
  3.     ATRACE_CALL();  
  4.   
  5.     if (android_atomic_acquire_cas(truefalse, &mSidebandStreamChanged) == 0) {  
  6.         // mSidebandStreamChanged was true  
  7.         mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();  
  8.         if (mSidebandStream != NULL) {  
  9.             setTransactionFlags(eTransactionNeeded);  
  10.             mFlinger->setTransactionFlags(eTraversalNeeded);  
  11.         }  
  12.         recomputeVisibleRegions = true;  
  13.   
  14.         const State& s(getDrawingState());  
  15.         return s.transform.transform(Region(Rect(s.active.w, s.active.h)));  
  16.     }  
  17.   
  18.     Region outDirtyRegion;  
  19.     if (mQueuedFrames > 0) { //mQueuedFrames大于0代表有Surface更新的要求  
  20.         if (mRefreshPending) {  
  21.             return outDirtyRegion;  
  22.         }  
  23.   
  24.         // Capture the old state of the layer for comparisons later  
  25.         const State& s(getDrawingState());  
  26.         const bool oldOpacity = isOpaque(s);  
  27.         sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;  
  28.   
  29.         struct Reject : public SurfaceFlingerConsumer::BufferRejecter {  
  30.             ......//定义Reject结构体  
  31.         };  
  32.   
  33.         Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,  
  34.                 getProducerStickyTransform() != 0);  
  35.   
  36.         uint64_t maxFrameNumber = 0;  
  37.         {  
  38.             Mutex::Autolock lock(mQueueItemLock);  
  39.             maxFrameNumber = mLastFrameNumberReceived;  
  40.         }  
  41.   
  42.         status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,//更新纹理  
  43.                 mFlinger->mPrimaryDispSync, maxFrameNumber);  
  44.         if (updateResult == BufferQueue::PRESENT_LATER) {  
  45.             mFlinger->signalLayerUpdate();//如果结果是推迟处理,发送Invalidate消息  
  46.             return outDirtyRegion;  
  47.         } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {  
  48.             // If the buffer has been rejected, remove it from the shadow queue  
  49.             // and return early  
  50.             Mutex::Autolock lock(mQueueItemLock);  
  51.             mQueueItems.removeAt(0);  
  52.             android_atomic_dec(&mQueuedFrames);  
  53.             return outDirtyRegion;  
  54.         } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {  
  55.             // This can occur if something goes wrong when trying to create the  
  56.             // EGLImage for this buffer. If this happens, the buffer has already  
  57.             // been released, so we need to clean up the queue and bug out  
  58.             // early.  
  59.             {  
  60.                 Mutex::Autolock lock(mQueueItemLock);  
  61.                 mQueueItems.clear();  
  62.                 android_atomic_and(0, &mQueuedFrames);  
  63.             }  
  64.   
  65.             // Once we have hit this state, the shadow queue may no longer  
  66.             // correctly reflect the incoming BufferQueue's contents, so even if  
  67.             // updateTexImage starts working, the only safe course of action is  
  68.             // to continue to ignore updates.  
  69.             mUpdateTexImageFailed = true;  
  70.   
  71.             return outDirtyRegion;  
  72.         }  
  73.   
  74.         { // Autolock scope  
  75.             auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();  
  76.   
  77.             Mutex::Autolock lock(mQueueItemLock);  
  78.   
  79.             // Remove any stale buffers that have been dropped during  
  80.             // updateTexImage  
  81.             while (mQueueItems[0].mFrameNumber != currentFrameNumber) {  
  82.                 mQueueItems.removeAt(0);  
  83.                 android_atomic_dec(&mQueuedFrames);  
  84.             }  
  85.   
  86.             mQueueItems.removeAt(0);  
  87.         }  
  88.   
  89.   
  90.         // Decrement the queued-frames count.  Signal another event if we  
  91.         // have more frames pending.  
  92.         if (android_atomic_dec(&mQueuedFrames) > 1) {//减少mQueuedFrames的值  
  93.             mFlinger->signalLayerUpdate();//如果还有更多frame需要处理,要发消息  
  94.         }  
  95.   
  96.         if (updateResult != NO_ERROR) {  
  97.             // something happened!  
  98.             recomputeVisibleRegions = true;  
  99.             return outDirtyRegion;  
  100.         }  
  101.   
  102.         //更新mActiveBuffer,得到现在需要输出的图像数据  
  103.         mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();  
  104.         if (mActiveBuffer == NULL) {  
  105.             return outDirtyRegion;//出错  
  106.         }  
  107.   
  108.         mRefreshPending = true;  
  109.         mFrameLatencyNeeded = true;  
  110.         //下面根据各种情况是否重新计算更新区域  
  111.         if (oldActiveBuffer == NULL) {  
  112.              // the first time we receive a buffer, we need to trigger a  
  113.              // geometry invalidation.  
  114.             recomputeVisibleRegions = true;  
  115.          }  
  116.   
  117.         Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());  
  118.         const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());  
  119.         const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());  
  120.         if ((crop != mCurrentCrop) ||  
  121.             (transform != mCurrentTransform) ||  
  122.             (scalingMode != mCurrentScalingMode))  
  123.         {  
  124.             mCurrentCrop = crop;  
  125.             mCurrentTransform = transform;  
  126.             mCurrentScalingMode = scalingMode;  
  127.             recomputeVisibleRegions = true;  
  128.         }  
  129.   
  130.         if (oldActiveBuffer != NULL) {  
  131.             uint32_t bufWidth  = mActiveBuffer->getWidth();  
  132.             uint32_t bufHeight = mActiveBuffer->getHeight();  
  133.             if (bufWidth != uint32_t(oldActiveBuffer->width) ||  
  134.                 bufHeight != uint32_t(oldActiveBuffer->height)) {  
  135.                 recomputeVisibleRegions = true;  
  136.             }  
  137.         }  
  138.   
  139.         mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);  
  140.         if (oldOpacity != isOpaque(s)) {  
  141.             recomputeVisibleRegions = true;  
  142.         }  
  143.   
  144.         // FIXME: postedRegion should be dirty & bounds  
  145.         Region dirtyRegion(Rect(s.active.w, s.active.h));  
  146.   
  147.         // transform the dirty region to window-manager space  
  148.         outDirtyRegion = (s.transform.transform(dirtyRegion));  
  149.     }  
  150.     return outDirtyRegion;  
  151. }  

LatchBuffer函数调用updateTextImage来得到需要的图像。这里参数r是Reject对象,其作用是判断在缓冲区的尺寸是否符合要求。调用updateTextImage函数如果得到的结果是PRESENT_LATER,表示推迟处理,然后调用signalLayerUpdate函数来发送invalidate消息,这次绘制过程就不处理这个Surface的图像了。

如果不需要推迟处理,把mQueuedFrames的值减1.

最后LatchBuffer函数调用mSurfaceFlingerConsumer的getCurrentBuffer来取回当前的图像缓冲区指针,保存在mActiveBuffer中。


2.5 小结

这样经过handleTransaction handlePageFlip两个函数处理,SurfaceFlinger中无论是Layer属性的变化还是图像的变化都处理好了,只等VSync信号到来就可以输出了。



三、rebuildLayerStacks函数

前面介绍,VSync信号到来后,先是调用了rebuildLayerStacks函数

  1. void SurfaceFlinger::rebuildLayerStacks() {  
  2.     // rebuild the visible layer list per screen  
  3.     if (CC_UNLIKELY(mVisibleRegionsDirty)) {  
  4.         ATRACE_CALL();  
  5.         mVisibleRegionsDirty = false;  
  6.         invalidateHwcGeometry();  
  7.           
  8.         //计算每个显示设备上可见的Layer  
  9.         const LayerVector& layers(mDrawingState.layersSortedByZ);  
  10.         for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {  
  11.             Region opaqueRegion;  
  12.             Region dirtyRegion;  
  13.             Vector< sp<Layer> > layersSortedByZ;  
  14.             const sp<DisplayDevice>& hw(mDisplays[dpy]);  
  15.             const Transform& tr(hw->getTransform());  
  16.             const Rect bounds(hw->getBounds());  
  17.             if (hw->isDisplayOn()) {  
  18.                 //计算每个layer的可见区域,确定设备需要重新绘制的区域  
  19.                 SurfaceFlinger::computeVisibleRegions(layers,  
  20.                         hw->getLayerStack(), dirtyRegion, opaqueRegion);  
  21.   
  22.                 const size_t count = layers.size();  
  23.                 for (size_t i=0 ; i<count ; i++) {  
  24.                     const sp<Layer>& layer(layers[i]);  
  25.                     const Layer::State& s(layer->getDrawingState());  
  26.                     if (s.layerStack == hw->getLayerStack()) {  
  27.                         //只需要和显示设备的LayerStack相同的layer  
  28.                         Region drawRegion(tr.transform(  
  29.                                 layer->visibleNonTransparentRegion));  
  30.                         drawRegion.andSelf(bounds);  
  31.                         if (!drawRegion.isEmpty()) {  
  32.                             //如果Layer的显示区域和显示设备的窗口有交集  
  33.                             //把Layer加入列表中  
  34.                             layersSortedByZ.add(layer);  
  35.                         }  
  36.                     }  
  37.                 }  
  38.             }  
  39.             //设置显示设备的可见Layer列表  
  40.             hw->setVisibleLayersSortedByZ(layersSortedByZ);  
  41.             hw->undefinedRegion.set(bounds);  
  42.             hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));  
  43.             hw->dirtyRegion.orSelf(dirtyRegion);  
  44.         }  
  45.     }  
  46. }  

rebuildLayerStacks函数的作用是重建每个显示设备的可见layer对象列表。对于按显示轴(Z轴)排列的Layer对象,排在最前面的当然会优先显示,但是Layer图像可能有透明域,也可能有尺寸没有覆盖整个屏幕,因此下面的layer也有显示的机会。rebuildLayerStacks函数对每个显示设备,先计算和显示设备具有相同layerStack值的Layer对象在该显示设备上的可见区域。然后将可见区域和显示设备的窗口区域有交集的layer组成一个新的列表,最后把这个列表设置到显示设备对象中。

computeVisibleRegions函数首先计算每个Layer在设备上的可见区域visibleRegion。计算方法就是用整个Layer的区域减去上层所有不透明区域aboveOpaqueLayers。而上层所有不透明区域值是一个逐层累计的过程,每层都需要把自己的不透明区域累加到aboveOpaqueLayers中。

而每层的不透明区域的计算方法:如果Layer的alpha的值为255,并且layer的isOpaque函数为true,则本层的不透明区域等于Layer所在区域,否则为0.这样一层层算下来,就很容易得到每层的可见区域大小了。

其次,计算整个显示设备需要更新的区域outDirtyRegion。outDirtyRegion的值也是累计所有层的需要重回的区域得到的。如果Layer中的显示内容发生了变化,则整个可见区域visibleRegion都需要更新,同时还要包括上一次的可见区域,然后在去掉被上层覆盖后的区域得到的就是Layer需要更新的区域。如果Layer显示的内容没有变化,但是考虑到窗口大小的变化或者上层窗口的变化,因此Layer中还是有区域可以需要重绘的地方。这种情况下最简单的算法是用Layer计算出可见区域减去以前的可见区域就可以了。但是在computeVisibleRegions函数还引入了被覆盖区域,通常被覆盖区域和可见区域并不重复,因此函数中计算暴露区域是用可见区域减去被覆盖区域的。


四、setUpHWComposer函数

setUpHWComposer函数的作用是更新HWComposer对象中图层对象列表以及图层属性。

  1. void SurfaceFlinger::setUpHWComposer() {  
  2.     for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {  
  3.         bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();  
  4.         bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;  
  5.         bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;  
  6.         bool mustRecompose = dirty && !(empty && wasEmpty);  
  7.         mDisplays[dpy]->beginFrame(mustRecompose);  
  8.   
  9.         if (mustRecompose) {  
  10.             mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;  
  11.         }  
  12.     }  
  13.   
  14.     HWComposer& hwc(getHwComposer());//得到系统HWComposer对象  
  15.     if (hwc.initCheck() == NO_ERROR) {  
  16.         // build the h/w work list  
  17.         if (CC_UNLIKELY(mHwWorkListDirty)) {  
  18.             mHwWorkListDirty = false;  
  19.             for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {  
  20.                 sp<const DisplayDevice> hw(mDisplays[dpy]);  
  21.                 const int32_t id = hw->getHwcDisplayId();  
  22.                 if (id >= 0) {  
  23.                     const Vector< sp<Layer> >& currentLayers(  
  24.                         hw->getVisibleLayersSortedByZ());  
  25.                     const size_t count = currentLayers.size();  
  26.                     //根据Layer数量在HWComposer中创建hwc_layer_list_t列表  
  27.                     if (hwc.createWorkList(id, count) == NO_ERROR) {  
  28.                         ......  
  29.                     }  
  30.                 }  
  31.             }  
  32.         }  
  33.   
  34.         // set the per-frame data  
  35.         for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {  
  36.             sp<const DisplayDevice> hw(mDisplays[dpy]);  
  37.             const int32_t id = hw->getHwcDisplayId();  
  38.             if (id >= 0) {  
  39.                 ......  
  40.                 for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {  
  41.                     const sp<Layer>& layer(currentLayers[i]);  
  42.                     //将Layer的mActiveBuffer设置到HWComposer中  
  43.                     layer->setPerFrameData(hw, *cur);  
  44.                 }  
  45.             }  
  46.         }  
  47.   
  48.         // If possible, attempt to use the cursor overlay on each display.  
  49.         for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {  
  50.             sp<const DisplayDevice> hw(mDisplays[dpy]);  
  51.             const int32_t id = hw->getHwcDisplayId();  
  52.             if (id >= 0) {  
  53.                 const Vector< sp<Layer> >& currentLayers(  
  54.                     hw->getVisibleLayersSortedByZ());  
  55.                 const size_t count = currentLayers.size();  
  56.                 HWComposer::LayerListIterator cur = hwc.begin(id);  
  57.                 const HWComposer::LayerListIterator end = hwc.end(id);  
  58.                 for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {  
  59.                     const sp<Layer>& layer(currentLayers[i]);  
  60.                     if (layer->isPotentialCursor()) {  
  61.                         cur->setIsCursorLayerHint();  
  62.                         break;  
  63.                     }  
  64.                 }  
  65.             }  
  66.         }  
  67.   
  68.         status_t err = hwc.prepare();  
  69.         ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));  
  70.   
  71.         for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {  
  72.             sp<const DisplayDevice> hw(mDisplays[dpy]);  
  73.             hw->prepareFrame(hwc);  
  74.         }  
  75.     }  
  76. }  

HWComposer中有一个类型为DisplayData结构的数组mDisplayData,它维护着每个显示设备的信息。DisplayData结构中有一个类型为hwc_display_contents_l字段list,这个字段又有一个hwc_layer_l类型的数组hwLayers,记录该显示设备所有需要输出的Layer信息。

setUpHWComposer函数调用HWComposer的createWorkList函数就是根据每种显示设备的Layer数量,创建和初始化hwc_display_contents_l对象和hwc_layer_l数组

创建完HWComposer中的列表后,接下来是对每个Layer对象调用它的setPerFrameData函数,参数是HWComposer和HWCLayerInterface。setPerFrameData函数将Layer对象的当前图像缓冲区mActiveBuffer设置到HWCLayerInterface对象对应的hwc_layer_l对象中。

HWComposer类中除了前面介绍的Gralloc还管理着Composer模块,这个模块实现了硬件的图像合成功能。setUpHWComposer函数接下来调用HWComposer类的prepare函数,而prepare函数会调用Composer模块的prepare接口。最后到各个厂家的实现hwc_prepare函数将每种HWComposer中的所有图层的类型都设置为HWC_FRAMEBUFFER就结束了。


五、合成所有层的图像 (doComposition函数)

doComposition函数是合成所有层的图像,代码如下:

  1. void SurfaceFlinger::doComposition() {  
  2.     ATRACE_CALL();  
  3.     const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);  
  4.     for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {  
  5.         const sp<DisplayDevice>& hw(mDisplays[dpy]);  
  6.         if (hw->isDisplayOn()) {  
  7.             // transform the dirty region into this screen's coordinate space  
  8.             const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));  
  9.   
  10.             // 图像合成  
  11.             doDisplayComposition(hw, dirtyRegion);  
  12.   
  13.             hw->dirtyRegion.clear();  
  14.             hw->flip(hw->swapRegion);  
  15.             hw->swapRegion.clear();  
  16.         }  
  17.         // inform the h/w that we're done compositing  
  18.         hw->compositionComplete();  
  19.     }  
  20.     postFramebuffer();  
  21. }  

doComposition函数针对每种显示设备调用doDisplayComposition函数来合成,合成后调用postFramebuffer函数,我们先来看看doDisplayComposition函数

  1. void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,  
  2.         const Region& inDirtyRegion)  
  3. {  
  4.     bool isHwcDisplay = hw->getHwcDisplayId() >= 0;  
  5.     if (!isHwcDisplay && inDirtyRegion.isEmpty()) {  
  6.         return;  
  7.     }  
  8.   
  9.     Region dirtyRegion(inDirtyRegion);  
  10.   
  11.     //swapRegion设置为需要更新的区域  
  12.     hw->swapRegion.orSelf(dirtyRegion);  
  13.   
  14.     uint32_t flags = hw->getFlags();//获得显示设备支持的更新方式标志  
  15.     if (flags & DisplayDevice::SWAP_RECTANGLE) {//支持矩阵更新          
  16.         dirtyRegion.set(hw->swapRegion.bounds());  
  17.     } else {  
  18.         if (flags & DisplayDevice::PARTIAL_UPDATES) {//支持部分更新  
  19.             dirtyRegion.set(hw->swapRegion.bounds());  
  20.         } else {  
  21.             //将更新区域调整为整个窗口大小  
  22.             dirtyRegion.set(hw->bounds());  
  23.             hw->swapRegion = dirtyRegion;  
  24.         }  
  25.     }  
  26.   
  27.     if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {  
  28.         if (!doComposeSurfaces(hw, dirtyRegion)) return;//合成  
  29.     } else {  
  30.         RenderEngine& engine(getRenderEngine());  
  31.         mat4 colorMatrix = mColorMatrix;  
  32.         if (mDaltonize) {  
  33.             colorMatrix = colorMatrix * mDaltonizer();  
  34.         }  
  35.         mat4 oldMatrix = engine.setupColorTransform(colorMatrix);  
  36.         doComposeSurfaces(hw, dirtyRegion);//合成  
  37.         engine.setupColorTransform(oldMatrix);  
  38.     }  
  39.   
  40.     // update the swap region and clear the dirty region  
  41.     hw->swapRegion.orSelf(dirtyRegion);  
  42.   
  43.     // swap buffers (presentation)  
  44.     hw->swapBuffers(getHwComposer());//没有硬件composer的情况,输出图像  
  45. }  

doDisplayComposition函数根据显示设备支持的更新方式,重新设置需要更新区域的大小。
真正的合成工作是在doComposerSurfaces函数中完成,这个函数在layer的类型为HWC_FRAMEBUFFER,或者不支持硬件的composer的情况下,调用layer的draw函数来一层一层低合成最后的图像。

合成完后,doDisplayComposition函数调用了hw的swapBuffers函数,这个函数前面介绍过了,它将在系统不支持硬件的composer情况下调用eglSwapBuffers来输出图像到显示设备。


六、postFramebuffer函数

上一节的doComposition函数最后调用了postFramebuffer函数,代码如下:

  1. void SurfaceFlinger::postFramebuffer()  
  2. {  
  3.     ATRACE_CALL();  
  4.   
  5.     const nsecs_t now = systemTime();  
  6.     mDebugInSwapBuffers = now;  
  7.   
  8.     HWComposer& hwc(getHwComposer());  
  9.     if (hwc.initCheck() == NO_ERROR) {  
  10.         if (!hwc.supportsFramebufferTarget()) {  
  11.             // EGL spec says:  
  12.             //   "surface must be bound to the calling thread's current context,  
  13.             //    for the current rendering API."  
  14.             getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);  
  15.         }  
  16.         hwc.commit();  
  17.     }  
  18.   
  19.     ......  
  20. }  

postFramebuffer先判断系统是否支持composer,如果不支持,我们知道图像已经在doComposition函数时调用hw->swapBuffers输出了,就返回了。如果支持硬件composer,postFramebuffer函数将调用HWComposer的commit函数继续执行。

  1. status_t HWComposer::commit() {  
  2.     int err = NO_ERROR;  
  3.     if (mHwc) {  
  4.         if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {  
  5.             // On version 1.0, the OpenGL ES target surface is communicated  
  6.             // by the (dpy, sur) fields and we are guaranteed to have only  
  7.             // a single display.  
  8.             mLists[0]->dpy = eglGetCurrentDisplay();  
  9.             mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW);  
  10.         }  
  11.   
  12.         for (size_t i=VIRTUAL_DISPLAY_ID_BASE; i<mNumDisplays; i++) {  
  13.             DisplayData& disp(mDisplayData[i]);  
  14.             if (disp.outbufHandle) {  
  15.                 mLists[i]->outbuf = disp.outbufHandle;  
  16.                 mLists[i]->outbufAcquireFenceFd =  
  17.                         disp.outbufAcquireFence->dup();  
  18.             }  
  19.         }  
  20.   
  21.         err = mHwc->set(mHwc, mNumDisplays, mLists);  
  22.         ......  
  23.     }  
  24.     return (status_t)err;  
  25. }  

commit函数又调用了composer模块的set接口来完成工作,这就到HAL层的代码了,最后输出到显示屏上。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值