zoukankan      html  css  js  c++  java
  • Android6.0 图像合成过程详解(一) setUpHWComposer函数


    http://blog.csdn.net/kc58236582/article/details/52856341


    上一篇博客分析了,用户进程如何申请一个GraphicBuffer的过程。这篇博客我们进一步分析图像合成过程,其中也解答之前的一些疑惑:

    1. 之前碰到的不支持硬件模块

    2. DisplayDevice类

    3. 消费者的onFrameAvailable函数

    我们直接分析合成的过程,具体的流程我们http://blog.csdn.net/kc58236582/article/details/52778333这篇博客分析了,这篇博客我们增加了一些以前没理解的点。


    一、handleTransactionLocked函数

    1.1 Layer的doTransaction函数

    这里我直接从handleTransactionLocked函数开始分析,这个函数先会调用每个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. }  

    这个函数之前博客也分析过,这里我们看看其中最重要的一个flag就是eVisibleRegion代表这个Layer是否要更新。而这里如果要更新Layer,也只是大小,sequence(也就是属性)变化才会更新这个flag。而Layer内容(buffer)的更新不在这里。这里使用了mDrawingState,mCurrentState两个变量。这两个变量主要是一些属性值。

    最后会把mCurrentState的值赋给mDrawingState。而mCurrentState是在下面一些函数中变化的:

    1. bool Layer::setPosition(float x, float y) {  
    2.     if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)  
    3.         return false;  
    4.     mCurrentState.sequence++;  
    5.     mCurrentState.transform.set(x, y);  
    6.     setTransactionFlags(eTransactionNeeded);  
    7.     return true;  
    8. }  
    9. bool Layer::setLayer(uint32_t z) {  
    10.     if (mCurrentState.z == z)  
    11.         return false;  
    12.     mCurrentState.sequence++;  
    13.     mCurrentState.z = z;  
    14.     setTransactionFlags(eTransactionNeeded);  
    15.     return true;  
    16. }  
    17. bool Layer::setSize(uint32_t w, uint32_t h) {  
    18.     if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)  
    19.         return false;  
    20.     mCurrentState.requested.w = w;  
    21.     mCurrentState.requested.h = h;  
    22.     setTransactionFlags(eTransactionNeeded);  
    23.     return true;  
    24. }  
    25. bool Layer::setAlpha(uint8_t alpha) {  
    26.     if (mCurrentState.alpha == alpha)  
    27.         return false;  
    28.     mCurrentState.sequence++;  
    29.     mCurrentState.alpha = alpha;  
    30.     setTransactionFlags(eTransactionNeeded);  
    31.     return true;  
    32. }  

    我们下面开始看handleTransactionLocked函数。

    先看下处理layer的事务,遍历每个Layer的doTransaction来更新状态,以及根据flags是否要更新layer。

    1. void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)  
    2. {  
    3.     const LayerVector& currentLayers(mCurrentState.layersSortedByZ);//所有的Layer  
    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);//遍历每个layer,更新mDrawingState状态  
    18.             if (flags & Layer::eVisibleRegion)  
    19.                 mVisibleRegionsDirty = true;//有需要更新的layer,把该变量置为true  
    20.         }  
    21.     }  

    1.2 处理显示设备的变化

    下面是handleTransactionLocked中处理显示设备的变化的

    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加入系统中。

    这些在之前博客都分析过,我们主要看下几个变量mCurrentState.displays, mDrawingState.displays。代表之前的设备和现在的设备。

    这些displays是State的一个变量,是每个display的一个唯一码对应一个DisplayDeviceState(状态)。

    1. struct State {  
    2.     LayerVector layersSortedByZ;  
    3.     DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;  
    4. };  

    而mDisplays是一个Display的唯一码 对应一个DisplayDevice。

    1. DefaultKeyedVector< wp<IBinder>, sp<DisplayDevice> > mDisplays;  

    而这里主要用mCurrentState.displays, mDrawingState.displays中的Display的唯一码看哪个DisplayDevice增加了或者删除了,再去根据这个唯一码来对应在mDisplays中的DisplayDevice增加或者删除或者一些状态的修改。


    1.3 设置TransformHint

    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)。



    1.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的可见区域加入到系统需要更新的区域中。

    而这里mVisibleRegionsDirty设为true代表Layer需要更新,如果Layer不需要更新的话后面的rebuildLayerStack函数的执行就是空的了。


    1.5 设置mDrawingState

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

    1.6 小结

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


    二、handlePageFlip函数

    代码如下,这个函数就是更新Layer中的buffer(内容),遍历每个Layer看这个Layer是否有内容更新,就看其hasQueuedFrame函数是否返回true。之前分析过当有更新的话,mQueuedFrames的值会加1.而hasQueuedFrame函数就是看这个值是否为0

    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. }  

    hasQueuedFrame函数如下。

    1. bool hasQueuedFrame() const { return mQueuedFrames > 0 || mSidebandStreamChanged; }  
    最后把所有需要更新的Layer放在layersWithQueuedFrames,然后调用每个Layer的latchBuffer函数。

    调用每个Layer的latchBuffer函数根据返回的更新区域调用invalidateLayerStack来设置更新设备对象的更新区域。

    我们先来看看invalidateLayerStack函数,在SurfaceFlinger.cpp中的invalidateLayerStack。先是遍历所有的设备,找到和Layer的layerStack一样的设备,然后调用了DisplayDevice的dirtyRegion.orSelf方法

    1. void SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,  
    2.         const Region& dirty) {  
    3.     for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {  
    4.         const sp<DisplayDevice>& hw(mDisplays[dpy]);  
    5.         if (hw->getLayerStack() == layerStack) {  
    6.             hw->dirtyRegion.orSelf(dirty);  
    7.         }  
    8.     }  
    9. }  
    orSelf方法,就是把Layer的更新区域 加到 DisplayDevice的dirtyRegion区域上。
    1. Region& Region::orSelf(const Rect& r) {  
    2.     return operationSelf(r, op_or);  
    3. }  

    最后我们再来看看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());//注意这是使用的DrawingState  
    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));//返回Layer的更新区域  
    149.     }  
    150.     return outDirtyRegion;  
    151. }  

    这里我们来看mSurfaceFlingerConsumer->updateTexImage更新纹理

    1. status_t SurfaceFlingerConsumer::updateTexImage(BufferRejecter* rejecter,  
    2.         const DispSync& dispSync, uint64_t maxFrameNumber)  
    3. {  
    4.     ATRACE_CALL();  
    5.     Mutex::Autolock lock(mMutex);  
    6.   
    7.     if (mAbandoned) {  
    8.         ALOGE("updateTexImage: GLConsumer is abandoned!");  
    9.         return NO_INIT;  
    10.     }  
    11.   
    12.     // Make sure the EGL state is the same as in previous calls.  
    13.     status_t err = checkAndUpdateEglStateLocked();  
    14.     if (err != NO_ERROR) {  
    15.         return err;  
    16.     }  
    17.   
    18.     BufferItem item;  
    19.   
    20.     // Acquire the next buffer.  
    21.     // In asynchronous mode the list is guaranteed to be one buffer  
    22.     // deep, while in synchronous mode we use the oldest buffer.  
    23.     err = acquireBufferLocked(&item, computeExpectedPresent(dispSync),//消费者端取数据  
    24.             maxFrameNumber);  
    25.     if (err != NO_ERROR) {  
    26.         if (err == BufferQueue::NO_BUFFER_AVAILABLE) {  
    27.             err = NO_ERROR;  
    28.         } else if (err == BufferQueue::PRESENT_LATER) {  
    29.             // return the error, without logging  
    30.         } else {  
    31.             ALOGE("updateTexImage: acquire failed: %s (%d)",  
    32.                 strerror(-err), err);  
    33.         }  
    34.         return err;  
    35.     }  
    36.   
    37.   
    38.     // We call the rejecter here, in case the caller has a reason to  
    39.     // not accept this buffer.  This is used by SurfaceFlinger to  
    40.     // reject buffers which have the wrong size  
    41.     int buf = item.mBuf;  
    42.     if (rejecter && rejecter->reject(mSlots[buf].mGraphicBuffer, item)) {  
    43.         releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, EGL_NO_SYNC_KHR);  
    44.         return BUFFER_REJECTED;  
    45.     }  
    46.   
    47.     // Release the previous buffer.  
    48.     err = updateAndReleaseLocked(item);  
    49.     if (err != NO_ERROR) {  
    50.         return err;  
    51.     }  
    52.   
    53.     if (!SyncFeatures::getInstance().useNativeFenceSync()) {  
    54.         // Bind the new buffer to the GL texture.  
    55.         //  
    56.         // Older devices require the "implicit" synchronization provided  
    57.         // by glEGLImageTargetTexture2DOES, which this method calls.  Newer  
    58.         // devices will either call this in Layer::onDraw, or (if it's not  
    59.         // a GL-composited layer) not at all.  
    60.         err = bindTextureImageLocked();  
    61.     }  
    62.   
    63.     return err;  
    64. }  
    我们再来看看updateAndReleaseLocked函数,这个函数释放了buffer,然后更新了mCurrentTexture mCurrentTextureImage等。
    1. status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item)  
    2. {  
    3.     status_t err = NO_ERROR;  
    4.   
    5.     int buf = item.mBuf;  
    6.   
    7.     if (!mAttached) {  
    8.         releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,  
    9.                 mEglDisplay, EGL_NO_SYNC_KHR);  
    10.         return INVALID_OPERATION;  
    11.     }  
    12.   
    13.     err = checkAndUpdateEglStateLocked();  
    14.     ......  
    15.     err = mEglSlots[buf].mEglImage->createIfNeeded(mEglDisplay, item.mCrop);  
    16.     ......  
    17.     err = syncForReleaseLocked(mEglDisplay);  
    18.     ......  
    19.   
    20.     //释放buffer  
    21.     if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {  
    22.         status_t status = releaseBufferLocked(  
    23.                 mCurrentTexture, mCurrentTextureImage->graphicBuffer(),  
    24.                 mEglDisplay, mEglSlots[mCurrentTexture].mEglFence);  
    25.         if (status < NO_ERROR) {  
    26.             GLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)",  
    27.                    strerror(-status), status);  
    28.             err = status;  
    29.             // keep going, with error raised [?]  
    30.         }  
    31.     }  
    32.   
    33.     // 更新状态  
    34.     mCurrentTexture = buf;  
    35.     mCurrentTextureImage = mEglSlots[buf].mEglImage;  
    36.     mCurrentCrop = item.mCrop;  
    37.     mCurrentTransform = item.mTransform;  
    38.     mCurrentScalingMode = item.mScalingMode;  
    39.     mCurrentTimestamp = item.mTimestamp;  
    40.     mCurrentFence = item.mFence;  
    41.     mCurrentFrameNumber = item.mFrameNumber;  
    42.   
    43.     computeCurrentTransformMatrixLocked();  
    44.   
    45.     return err;  
    46. }  
    最后Layer的mActiveBuffer是从mSurfaceFlingerConsumer->getCurrentBuffer(),而就是mCurrentTextureImage变量。
    1. sp<GraphicBuffer> GLConsumer::getCurrentBuffer() const {  
    2.     Mutex::Autolock lock(mMutex);  
    3.     return (mCurrentTextureImage == NULL) ?  
    4.             NULL : mCurrentTextureImage->graphicBuffer();  
    5. }  

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

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

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



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



    三、rebuildLayerStack函数

    VSync信号来了之后先是调用的这个函数,前面分析handleTransactionLocked的时候,当mVisibleRegionsDirty为 true代表是要更新Layer,这里上来就是看这个变量是否为true。

    1. void SurfaceFlinger::rebuildLayerStacks() {  
    2.     // rebuild the visible layer list per screen  
    3.     if (CC_UNLIKELY(mVisibleRegionsDirty)) {//mVisibleRegionsDirty是否为true  
    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);//设置每个DisplayDevice的drawRegions 加上dirtyRegion区域  
    44.         }  
    45.     }  
    46. }  

    rebuildLayerStacks函数的作用是重建每个显示设备的可见layer对象列表。其他的说明还是看另一篇博客http://write.blog.csdn.net/postedit?ref=toolbar&ticket=ST-83533-ejxpwYJbCoASdBlu6Tpr-passport.csdn.net


    四、setUpHWComposer函数

    HWComposer中有一个类型为DisplayData结构的数组mDisplayData[],维护每个显示设备的信息。我们先来看在HWComposer构造函数中有下面这段代码,我们这里mFbDev为空,因此我们遍历每个设备,调用queryDisplayProperties函数。

    1. if (mFbDev) {  
    2.     ALOGD("chenchen mFbDev end");  
    3.     ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)),  
    4.             "should only have fbdev if no hwc or hwc is 1.0");  
    5.   
    6.     DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]);  
    7.     disp.connected = true;  
    8.     disp.format = mFbDev->format;  
    9.     DisplayConfig config = DisplayConfig();  
    10.     config.width = mFbDev->width;  
    11.     config.height = mFbDev->height;  
    12.     config.xdpi = mFbDev->xdpi;  
    13.     config.ydpi = mFbDev->ydpi;  
    14.     config.refresh = nsecs_t(1e9 / mFbDev->fps);  
    15.     disp.configs.push_back(config);  
    16.     disp.currentConfig = 0;  
    17. else if (mHwc) {  
    18.     // here we're guaranteed to have at least HWC 1.1  
    19.     for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {  
    20.         queryDisplayProperties(i);  
    21.     }  
    22. }  

    下面我们来看queryDisplayProperties函数,通过hwc模块的getDisplayConfigs和getDisplayAttributes方法来获取configs,最后把格式和connect设置为true。

    1. status_t HWComposer::queryDisplayProperties(int disp) {  
    2.   
    3.     LOG_ALWAYS_FATAL_IF(!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));  
    4.   
    5.     // use zero as default value for unspecified attributes  
    6.     int32_t values[NUM_DISPLAY_ATTRIBUTES - 1];  
    7.     memset(values, 0, sizeof(values));  
    8.   
    9.     const size_t MAX_NUM_CONFIGS = 128;  
    10.     uint32_t configs[MAX_NUM_CONFIGS] = {0};  
    11.     size_t numConfigs = MAX_NUM_CONFIGS;  
    12.     status_t err = mHwc->getDisplayConfigs(mHwc, disp, configs, &numConfigs);  
    13.     if (err != NO_ERROR) {  
    14.         // this can happen if an unpluggable display is not connected  
    15.         mDisplayData[disp].connected = false;  
    16.         return err;  
    17.     }  
    18.   
    19.     mDisplayData[disp].currentConfig = 0;  
    20.     for (size_t c = 0; c < numConfigs; ++c) {  
    21.         err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],  
    22.                 DISPLAY_ATTRIBUTES, values);  
    23.         // If this is a pre-1.5 HWC, it may not know about color transform, so  
    24.         // try again with a smaller set of attributes  
    25.         if (err != NO_ERROR) {  
    26.             err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],  
    27.                     PRE_HWC15_DISPLAY_ATTRIBUTES, values);  
    28.         }  
    29.         if (err != NO_ERROR) {  
    30.             // we can't get this display's info. turn it off.  
    31.             mDisplayData[disp].connected = false;  
    32.             return err;  
    33.         }  
    34.   
    35.         DisplayConfig config = DisplayConfig();  
    36.         for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {  
    37.             switch (DISPLAY_ATTRIBUTES[i]) {  
    38.                 case HWC_DISPLAY_VSYNC_PERIOD:  
    39.                     config.refresh = nsecs_t(values[i]);//设置config  
    40.                     break;  
    41.                 case HWC_DISPLAY_WIDTH:  
    42.                     config.width = values[i];  
    43.                     break;  
    44.                 case HWC_DISPLAY_HEIGHT:  
    45.                     config.height = values[i];  
    46.                     break;  
    47.                 case HWC_DISPLAY_DPI_X:  
    48.                     config.xdpi = values[i] / 1000.0f;  
    49.                     break;  
    50.                 case HWC_DISPLAY_DPI_Y:  
    51.                     config.ydpi = values[i] / 1000.0f;  
    52.                     break;  
    53.                 case HWC_DISPLAY_COLOR_TRANSFORM:  
    54.                     config.colorTransform = values[i];  
    55.                     break;  
    56.                 default:  
    57.                     ALOG_ASSERT(false"unknown display attribute[%zu] %#x",  
    58.                             i, DISPLAY_ATTRIBUTES[i]);  
    59.                     break;  
    60.             }  
    61.         }  
    62.   
    63.         if (config.xdpi == 0.0f || config.ydpi == 0.0f) {  
    64.             float dpi = getDefaultDensity(config.width, config.height);  
    65.             config.xdpi = dpi;  
    66.             config.ydpi = dpi;  
    67.         }  
    68.   
    69.         mDisplayData[disp].configs.push_back(config);  
    70.     }  
    71.   
    72.     // FIXME: what should we set the format to?  
    73.     mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888;//格式  
    74.     mDisplayData[disp].connected = true;//已连接  
    75.     return NO_ERROR;  
    76. }  

    我们再来看SurfaceFlinger中init函数,后面创建DisplayDevice过程。

    1. for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {  
    2.     DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);  
    3.     // set-up the displays that are already connected  
    4.     if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {//当前设备连接了,或者是默认设备(即使没有连接)  
    5.         // All non-virtual displays are currently considered secure.  
    6.         bool isSecure = true;  
    7.         createBuiltinDisplayLocked(type);//分配一个token  
    8.         wp<IBinder> token = mBuiltinDisplays[i];  
    9.   
    10.         sp<IGraphicBufferProducer> producer;  
    11.         sp<IGraphicBufferConsumer> consumer;  
    12.         BufferQueue::createBufferQueue(&producer, &consumer,//创建producer consumer  
    13.                 new GraphicBufferAlloc());  
    14.   
    15.         sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,  
    16.                 consumer);  
    17.         int32_t hwcId = allocateHwcDisplayId(type);  
    18.         sp<DisplayDevice> hw = new DisplayDevice(this,//创建DisplayDevice  
    19.                 type, hwcId, mHwc->getFormat(hwcId), isSecure, token,  
    20.                 fbs, producer,  
    21.                 mRenderEngine->getEGLConfig());  
    22.         if (i > DisplayDevice::DISPLAY_PRIMARY) {  
    23.             // FIXME: currently we don't get blank/unblank requests  
    24.             // for displays other than the main display, so we always  
    25.             // assume a connected display is unblanked.  
    26.             ALOGD("marking display %zu as acquired/unblanked", i);  
    27.             hw->setPowerMode(HWC_POWER_MODE_NORMAL);  
    28.         }  
    29.         mDisplays.add(token, hw);//放入mDisplays中  
    30.     }  
    31. }  

    setUpHWComposer函数的作用是更新HWComposer对象中图层对象列表以及图层属性。下面函数先会遍历各个设备DisplayDevice,然后根据可见layer数量,调用createWorkList创建hwc_layer_list_t列表,然后在每个设备上遍历可见layer,将layer的mActiveBuffer设置到HWComposer中去,最后调用了HWComposer的prepare函数。

    1. void SurfaceFlinger::setUpHWComposer() {  
    2.     ......  
    3.     HWComposer& hwc(getHwComposer());  
    4.     if (hwc.initCheck() == NO_ERROR) {  
    5.         // build the h/w work list  
    6.         if (CC_UNLIKELY(mHwWorkListDirty)) {  
    7.             mHwWorkListDirty = false;  
    8.             for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {//遍历mDisplays  
    9.                 sp<const DisplayDevice> hw(mDisplays[dpy]);  
    10.                 const int32_t id = hw->getHwcDisplayId();  
    11.                 if (id >= 0) {  
    12.                     const Vector< sp<Layer> >& currentLayers(//遍历DisplayDevice所有可见layer  
    13.                         hw->getVisibleLayersSortedByZ());  
    14.                     const size_t count = currentLayers.size();  
    15.                     if (hwc.createWorkList(id, count) == NO_ERROR) {//根据layer数量调用createWorkList创建hwc_layer_list_t列表  
    16.                         HWComposer::LayerListIterator cur = hwc.begin(id);  
    17.                         const HWComposer::LayerListIterator end = hwc.end(id);  
    18.                         for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {  
    19.                             const sp<Layer>& layer(currentLayers[i]);  
    20.                             layer->setGeometry(hw, *cur);  
    21.                             if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {  
    22.                                 cur->setSkip(true);  
    23.                             }  
    24.                         }  
    25.                     }  
    26.                 }  
    27.             }  
    28.         }  
    29.   
    30.         // set the per-frame data  
    31.         for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {  
    32.             sp<const DisplayDevice> hw(mDisplays[dpy]);  
    33.             const int32_t id = hw->getHwcDisplayId();  
    34.             if (id >= 0) {  
    35.                 const Vector< sp<Layer> >& currentLayers(  
    36.                     hw->getVisibleLayersSortedByZ());  
    37.                 const size_t count = currentLayers.size();  
    38.                 HWComposer::LayerListIterator cur = hwc.begin(id);  
    39.                 const HWComposer::LayerListIterator end = hwc.end(id);  
    40.                 for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {  
    41.                     //将layer的mActiveBuffer设置到HWComposer中去  
    42.                     const sp<Layer>& layer(currentLayers[i]);  
    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. }  
    我们先来看下createWorkList函数,我们先为DisplayData的list申请内存,这个内存要先hwc_display_contents_1_t结构体本身的长度加上后面hwc_layer_1_t个数的长度。后面用DisplayData中list中hwLayers最后一个作为DisplayData中的framebufferTarget。注意到这个细节没有,当支持egl合成的时候,会把numLayers加1,这是因为如果支持egl合成list最后一个layer是egl合成后的buffer用的,所以要增加一个layer,而前面都是普通的layer。
    1. status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {  
    2.     if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) {  
    3.         return BAD_INDEX;  
    4.     }  
    5.   
    6.     if (mHwc) {  
    7.         DisplayData& disp(mDisplayData[id]);  
    8.         if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {  
    9.             // we need space for the HWC_FRAMEBUFFER_TARGET  
    10.             numLayers++;//注意到这个细节没有,当支持egl合成的时候,会把numLayers加1  
    11.         }  
    12.         if (disp.capacity < numLayers || disp.list == NULL) {//当DisplayData中的list为空,我们就要malloc  
    13.             size_t size = sizeof(hwc_display_contents_1_t)  
    14.                     + numLayers * sizeof(hwc_layer_1_t);//整个申请内存长度,hwc_display_contents_1_t结构体本身的长度加上后面hwc_layer_1_t个数的长度  
    15.             free(disp.list);  
    16.             disp.list = (hwc_display_contents_1_t*)malloc(size);//malloc  
    17.             disp.capacity = numLayers;  
    18.         }  
    19.         if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {  
    20.             disp.framebufferTarget = &disp.list->hwLayers[numLayers - 1];  
    21.             memset(disp.framebufferTarget, 0, sizeof(hwc_layer_1_t));//DisplayData的framebufferTarget清0  
    22.             const DisplayConfig& currentConfig =  
    23.                     disp.configs[disp.currentConfig];  
    24.             const hwc_rect_t r = { 0, 0,  
    25.                     (int) currentConfig.width, (int) currentConfig.height };  
    26.             disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET;  
    27.             disp.framebufferTarget->hints = 0;  
    28.             disp.framebufferTarget->flags = 0;  
    29.             disp.framebufferTarget->handle = disp.fbTargetHandle;  
    30.             disp.framebufferTarget->transform = 0;  
    31.             disp.framebufferTarget->blending = HWC_BLENDING_PREMULT;  
    32.             if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {  
    33.                 disp.framebufferTarget->sourceCropf.left = 0;  
    34.                 disp.framebufferTarget->sourceCropf.top = 0;  
    35.                 disp.framebufferTarget->sourceCropf.right =  
    36.                         currentConfig.width;  
    37.                 disp.framebufferTarget->sourceCropf.bottom =  
    38.                         currentConfig.height;  
    39.             } else {  
    40.                 disp.framebufferTarget->sourceCrop = r;  
    41.             }  
    42.             disp.framebufferTarget->displayFrame = r;  
    43.             disp.framebufferTarget->visibleRegionScreen.numRects = 1;  
    44.             disp.framebufferTarget->visibleRegionScreen.rects =  
    45.                 &disp.framebufferTarget->displayFrame;  
    46.             disp.framebufferTarget->acquireFenceFd = -1;  
    47.             disp.framebufferTarget->releaseFenceFd = -1;  
    48.             disp.framebufferTarget->planeAlpha = 0xFF;  
    49.         }  
    50.         disp.list->retireFenceFd = -1;  
    51.         disp.list->flags = HWC_GEOMETRY_CHANGED;  
    52.         disp.list->numHwLayers = numLayers;//DisplayData中list中layer的个数  
    53.     }  
    54.     return NO_ERROR;  
    55. }  

    下面我们来看下DisplayData的数据结构

    1. struct DisplayData {  
    2.     DisplayData();  
    3.     ~DisplayData();  
    4.     Vector<DisplayConfig> configs;  
    5.     size_t currentConfig;  
    6.     uint32_t format;    // pixel format from FB hal, for pre-hwc-1.1  
    7.     bool connected;  
    8.     bool hasFbComp;  
    9.     bool hasOvComp;  
    10.     size_t capacity;  
    11.     hwc_display_contents_1* list;  
    12.     hwc_layer_1* framebufferTarget;  
    13.     buffer_handle_t fbTargetHandle;  
    14.     sp<Fence> lastRetireFence;  // signals when the last set op retires  
    15.     sp<Fence> lastDisplayFence; // signals when the last set op takes  
    16.                                 // effect on screen  
    17.     buffer_handle_t outbufHandle;  
    18.     sp<Fence> outbufAcquireFence;  
    19.   
    20.     // protected by mEventControlLock  
    21.     int32_t events;  
    22. };  

    再来看下hwc_display_contents_1。保留了原始的注释,我们先看hwc_display_contents_1,我们先看联合体union,第一个hwc_display_t dpy hwc_surface_t sur这个是EGL使用的,而如果是普通的就使用另外一个联合体outbuf什么的,后面还保存了layer的个数和hwc_layer_1_t 数组的起始地址hwLayers[0]

    1. typedef struct hwc_display_contents_1 {  
    2.     /* File descriptor referring to a Sync HAL fence object which will signal 
    3.      * when this composition is retired. For a physical display, a composition 
    4.      * is retired when it has been replaced on-screen by a subsequent set. For 
    5.      * a virtual display, the composition is retired when the writes to 
    6.      * outputBuffer are complete and can be read. The fence object is created 
    7.      * and returned by the set call; this field will be -1 on entry to prepare 
    8.      * and set. SurfaceFlinger will close the returned file descriptor. 
    9.      */  
    10.     int retireFenceFd;  
    11.   
    12.     union {  
    13.         /* Fields only relevant for HWC_DEVICE_VERSION_1_0. */  
    14.         struct {  
    15.             /* (dpy, sur) is the target of SurfaceFlinger's OpenGL ES 
    16.              * composition for HWC_DEVICE_VERSION_1_0. They aren't relevant to 
    17.              * prepare. The set call should commit this surface atomically to 
    18.              * the display along with any overlay layers. 
    19.              */  
    20.             hwc_display_t dpy;  
    21.             hwc_surface_t sur;  
    22.         };  
    23.   
    24.         /* These fields are used for virtual displays when the h/w composer 
    25.          * version is at least HWC_DEVICE_VERSION_1_3. */  
    26.         struct {  
    27.             /* outbuf is the buffer that receives the composed image for 
    28.              * virtual displays. Writes to the outbuf must wait until 
    29.              * outbufAcquireFenceFd signals. A fence that will signal when 
    30.              * writes to outbuf are complete should be returned in 
    31.              * retireFenceFd. 
    32.              * 
    33.              * This field is set before prepare(), so properties of the buffer 
    34.              * can be used to decide which layers can be handled by h/w 
    35.              * composer. 
    36.              * 
    37.              * If prepare() sets all layers to FRAMEBUFFER, then GLES 
    38.              * composition will happen directly to the output buffer. In this 
    39.              * case, both outbuf and the FRAMEBUFFER_TARGET layer's buffer will 
    40.              * be the same, and set() has no work to do besides managing fences. 
    41.              * 
    42.              * If the TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS board config 
    43.              * variable is defined (not the default), then this behavior is 
    44.              * changed: if all layers are marked for FRAMEBUFFER, GLES 
    45.              * composition will take place to a scratch framebuffer, and 
    46.              * h/w composer must copy it to the output buffer. This allows the 
    47.              * h/w composer to do format conversion if there are cases where 
    48.              * that is more desirable than doing it in the GLES driver or at the 
    49.              * virtual display consumer. 
    50.              * 
    51.              * If some or all layers are marked OVERLAY, then the framebuffer 
    52.              * and output buffer will be different. As with physical displays, 
    53.              * the framebuffer handle will not change between frames if all 
    54.              * layers are marked for OVERLAY. 
    55.              */  
    56.             buffer_handle_t outbuf;  
    57.   
    58.             /* File descriptor for a fence that will signal when outbuf is 
    59.              * ready to be written. The h/w composer is responsible for closing 
    60.              * this when no longer needed. 
    61.              * 
    62.              * Will be -1 whenever outbuf is NULL, or when the outbuf can be 
    63.              * written immediately. 
    64.              */  
    65.             int outbufAcquireFenceFd;  
    66.         };  
    67.     };  
    68.   
    69.     /* List of layers that will be composed on the display. The buffer handles 
    70.      * in the list will be unique. If numHwLayers is 0, all composition will be 
    71.      * performed by SurfaceFlinger. 
    72.      */  
    73.     uint32_t flags;  
    74.     size_t numHwLayers;//layer个数  
    75.     hwc_layer_1_t hwLayers[0];//layer起始地址  
    76.   
    77. } hwc_display_contents_1_t;  

    再来看下每个layer的数据结构体hwc_layer_1 ,其主要数据在buffer_handle_t handle中,buffer_handle_t 其实就是native_handle_t之前分析过,里面有共享内存的fd和地址。

    1. typedef struct hwc_layer_1 {  
    2.     /* 
    3.      * compositionType is used to specify this layer's type and is set by either 
    4.      * the hardware composer implementation, or by the caller (see below). 
    5.      * 
    6.      *  This field is always reset to HWC_BACKGROUND or HWC_FRAMEBUFFER 
    7.      *  before (*prepare)() is called when the HWC_GEOMETRY_CHANGED flag is 
    8.      *  also set, otherwise, this field is preserved between (*prepare)() 
    9.      *  calls. 
    10.      * 
    11.      * HWC_BACKGROUND 
    12.      *   Always set by the caller before calling (*prepare)(), this value 
    13.      *   indicates this is a special "background" layer. The only valid field 
    14.      *   is backgroundColor. 
    15.      *   The HWC can toggle this value to HWC_FRAMEBUFFER to indicate it CANNOT 
    16.      *   handle the background color. 
    17.      * 
    18.      * 
    19.      * HWC_FRAMEBUFFER_TARGET 
    20.      *   Always set by the caller before calling (*prepare)(), this value 
    21.      *   indicates this layer is the framebuffer surface used as the target of 
    22.      *   OpenGL ES composition. If the HWC sets all other layers to HWC_OVERLAY 
    23.      *   or HWC_BACKGROUND, then no OpenGL ES composition will be done, and 
    24.      *   this layer should be ignored during set(). 
    25.      * 
    26.      *   This flag (and the framebuffer surface layer) will only be used if the 
    27.      *   HWC version is HWC_DEVICE_API_VERSION_1_1 or higher. In older versions, 
    28.      *   the OpenGL ES target surface is communicated by the (dpy, sur) fields 
    29.      *   in hwc_compositor_device_1_t. 
    30.      * 
    31.      *   This value cannot be set by the HWC implementation. 
    32.      * 
    33.      * 
    34.      * HWC_FRAMEBUFFER 
    35.      *   Set by the caller before calling (*prepare)() ONLY when the 
    36.      *   HWC_GEOMETRY_CHANGED flag is also set. 
    37.      * 
    38.      *   Set by the HWC implementation during (*prepare)(), this indicates 
    39.      *   that the layer will be drawn into the framebuffer using OpenGL ES. 
    40.      *   The HWC can toggle this value to HWC_OVERLAY to indicate it will 
    41.      *   handle the layer. 
    42.      * 
    43.      * 
    44.      * HWC_OVERLAY 
    45.      *   Set by the HWC implementation during (*prepare)(), this indicates 
    46.      *   that the layer will be handled by the HWC (ie: it must not be 
    47.      *   composited with OpenGL ES). 
    48.      * 
    49.      * 
    50.      * HWC_SIDEBAND 
    51.      *   Set by the caller before calling (*prepare)(), this value indicates 
    52.      *   the contents of this layer come from a sideband video stream. 
    53.      * 
    54.      *   The h/w composer is responsible for receiving new image buffers from 
    55.      *   the stream at the appropriate time (e.g. synchronized to a separate 
    56.      *   audio stream), compositing them with the current contents of other 
    57.      *   layers, and displaying the resulting image. This happens 
    58.      *   independently of the normal prepare/set cycle. The prepare/set calls 
    59.      *   only happen when other layers change, or when properties of the 
    60.      *   sideband layer such as position or size change. 
    61.      * 
    62.      *   If the h/w composer can't handle the layer as a sideband stream for 
    63.      *   some reason (e.g. unsupported scaling/blending/rotation, or too many 
    64.      *   sideband layers) it can set compositionType to HWC_FRAMEBUFFER in 
    65.      *   (*prepare)(). However, doing so will result in the layer being shown 
    66.      *   as a solid color since the platform is not currently able to composite 
    67.      *   sideband layers with the GPU. This may be improved in future 
    68.      *   versions of the platform. 
    69.      * 
    70.      * 
    71.      * HWC_CURSOR_OVERLAY 
    72.      *   Set by the HWC implementation during (*prepare)(), this value 
    73.      *   indicates the layer's composition will now be handled by the HWC. 
    74.      *   Additionally, the client can now asynchronously update the on-screen 
    75.      *   position of this layer using the setCursorPositionAsync() api. 
    76.      */  
    77.     int32_t compositionType;  
    78.   
    79.     /* 
    80.      * hints is bit mask set by the HWC implementation during (*prepare)(). 
    81.      * It is preserved between (*prepare)() calls, unless the 
    82.      * HWC_GEOMETRY_CHANGED flag is set, in which case it is reset to 0. 
    83.      * 
    84.      * see hwc_layer_t::hints 
    85.      */  
    86.     uint32_t hints;  
    87.   
    88.     /* see hwc_layer_t::flags */  
    89.     uint32_t flags;  
    90.   
    91.     union {  
    92.         /* color of the background.  hwc_color_t.a is ignored */  
    93.         hwc_color_t backgroundColor;  
    94.   
    95.         struct {  
    96.             union {  
    97.                 /* When compositionType is HWC_FRAMEBUFFER, HWC_OVERLAY, 
    98.                  * HWC_FRAMEBUFFER_TARGET, this is the handle of the buffer to 
    99.                  * compose. This handle is guaranteed to have been allocated 
    100.                  * from gralloc using the GRALLOC_USAGE_HW_COMPOSER usage flag. 
    101.                  * If the layer's handle is unchanged across two consecutive 
    102.                  * prepare calls and the HWC_GEOMETRY_CHANGED flag is not set 
    103.                  * for the second call then the HWComposer implementation may 
    104.                  * assume that the contents of the buffer have not changed. */  
    105.                 buffer_handle_t handle;  
    106.   
    107.                 /* When compositionType is HWC_SIDEBAND, this is the handle 
    108.                  * of the sideband video stream to compose. */  
    109.                 const native_handle_t* sidebandStream;  
    110.             };  
    111.   
    112.             /* transformation to apply to the buffer during composition */  
    113.             uint32_t transform;  
    114.   
    115.             /* blending to apply during composition */  
    116.             int32_t blending;  
    117.   
    118.             /* area of the source to consider, the origin is the top-left corner of 
    119.              * the buffer. As of HWC_DEVICE_API_VERSION_1_3, sourceRect uses floats. 
    120.              * If the h/w can't support a non-integer source crop rectangle, it should 
    121.              * punt to OpenGL ES composition. 
    122.              */  
    123.             union {  
    124.                 // crop rectangle in integer (pre HWC_DEVICE_API_VERSION_1_3)  
    125.                 hwc_rect_t sourceCropi;  
    126.                 hwc_rect_t sourceCrop; // just for source compatibility  
    127.                 // crop rectangle in floats (as of HWC_DEVICE_API_VERSION_1_3)  
    128.                 hwc_frect_t sourceCropf;  
    129.             };  
    130.   
    131.             /* where to composite the sourceCrop onto the display. The sourceCrop 
    132.              * is scaled using linear filtering to the displayFrame. The origin is the 
    133.              * top-left corner of the screen. 
    134.              */  
    135.             hwc_rect_t displayFrame;  
    136.   
    137.             /* visible region in screen space. The origin is the 
    138.              * top-left corner of the screen. 
    139.              * The visible region INCLUDES areas overlapped by a translucent layer. 
    140.              */  
    141.             hwc_region_t visibleRegionScreen;  
    142.   
    143.             /* Sync fence object that will be signaled when the buffer's 
    144.              * contents are available. May be -1 if the contents are already 
    145.              * available. This field is only valid during set(), and should be 
    146.              * ignored during prepare(). The set() call must not wait for the 
    147.              * fence to be signaled before returning, but the HWC must wait for 
    148.              * all buffers to be signaled before reading from them. 
    149.              * 
    150.              * HWC_FRAMEBUFFER layers will never have an acquire fence, since 
    151.              * reads from them are complete before the framebuffer is ready for 
    152.              * display. 
    153.              * 
    154.              * HWC_SIDEBAND layers will never have an acquire fence, since 
    155.              * synchronization is handled through implementation-defined 
    156.              * sideband mechanisms. 
    157.              * 
    158.              * The HWC takes ownership of the acquireFenceFd and is responsible 
    159.              * for closing it when no longer needed. 
    160.              */  
    161.             int acquireFenceFd;  
    162.   
    163.             /* During set() the HWC must set this field to a file descriptor for 
    164.              * a sync fence object that will signal after the HWC has finished 
    165.              * reading from the buffer. The field is ignored by prepare(). Each 
    166.              * layer should have a unique file descriptor, even if more than one 
    167.              * refer to the same underlying fence object; this allows each to be 
    168.              * closed independently. 
    169.              * 
    170.              * If buffer reads can complete at significantly different times, 
    171.              * then using independent fences is preferred. For example, if the 
    172.              * HWC handles some layers with a blit engine and others with 
    173.              * overlays, then the blit layers can be reused immediately after 
    174.              * the blit completes, but the overlay layers can't be reused until 
    175.              * a subsequent frame has been displayed. 
    176.              * 
    177.              * Since HWC doesn't read from HWC_FRAMEBUFFER layers, it shouldn't 
    178.              * produce a release fence for them. The releaseFenceFd will be -1 
    179.              * for these layers when set() is called. 
    180.              * 
    181.              * Since HWC_SIDEBAND buffers don't pass through the HWC client, 
    182.              * the HWC shouldn't produce a release fence for them. The 
    183.              * releaseFenceFd will be -1 for these layers when set() is called. 
    184.              * 
    185.              * The HWC client taks ownership of the releaseFenceFd and is 
    186.              * responsible for closing it when no longer needed. 
    187.              */  
    188.             int releaseFenceFd;  
    189.   
    190.             /* 
    191.              * Availability: HWC_DEVICE_API_VERSION_1_2 
    192.              * 
    193.              * Alpha value applied to the whole layer. The effective 
    194.              * value of each pixel is computed as: 
    195.              * 
    196.              *   if (blending == HWC_BLENDING_PREMULT) 
    197.              *      pixel.rgb = pixel.rgb * planeAlpha / 255 
    198.              *   pixel.a = pixel.a * planeAlpha / 255 
    199.              * 
    200.              * Then blending proceeds as usual according to the "blending" 
    201.              * field above. 
    202.              * 
    203.              * NOTE: planeAlpha applies to YUV layers as well: 
    204.              * 
    205.              *   pixel.rgb = yuv_to_rgb(pixel.yuv) 
    206.              *   if (blending == HWC_BLENDING_PREMULT) 
    207.              *      pixel.rgb = pixel.rgb * planeAlpha / 255 
    208.              *   pixel.a = planeAlpha 
    209.              * 
    210.              * 
    211.              * IMPLEMENTATION NOTE: 
    212.              * 
    213.              * If the source image doesn't have an alpha channel, then 
    214.              * the h/w can use the HWC_BLENDING_COVERAGE equations instead of 
    215.              * HWC_BLENDING_PREMULT and simply set the alpha channel to 
    216.              * planeAlpha. 
    217.              * 
    218.              * e.g.: 
    219.              * 
    220.              *   if (blending == HWC_BLENDING_PREMULT) 
    221.              *      blending = HWC_BLENDING_COVERAGE; 
    222.              *   pixel.a = planeAlpha; 
    223.              * 
    224.              */  
    225.             uint8_t planeAlpha;  
    226.   
    227.             /* Pad to 32 bits */  
    228.             uint8_t _pad[3];  
    229.   
    230.             /* 
    231.              * Availability: HWC_DEVICE_API_VERSION_1_5 
    232.              * 
    233.              * This defines the region of the source buffer that has been 
    234.              * modified since the last frame. 
    235.              * 
    236.              * If surfaceDamage.numRects > 0, then it may be assumed that any 
    237.              * portion of the source buffer not covered by one of the rects has 
    238.              * not been modified this frame. If surfaceDamage.numRects == 0, 
    239.              * then the whole source buffer must be treated as if it had been 
    240.              * modified. 
    241.              * 
    242.              * If the layer's contents are not modified relative to the prior 
    243.              * prepare/set cycle, surfaceDamage will contain exactly one empty 
    244.              * rect ([0, 0, 0, 0]). 
    245.              * 
    246.              * The damage rects are relative to the pre-transformed buffer, and 
    247.              * their origin is the top-left corner. 
    248.              */  
    249.             hwc_region_t surfaceDamage;  
    250.         };  
    251.     };  
    252.   
    253. #ifdef __LP64__  
    254.     /* 
    255.      * For 64-bit mode, this struct is 120 bytes (and 8-byte aligned), and needs 
    256.      * to be padded as such to maintain binary compatibility. 
    257.      */  
    258.     uint8_t reserved[120 - 112];  
    259. #else  
    260.     /* 
    261.      * For 32-bit mode, this struct is 96 bytes, and needs to be padded as such 
    262.      * to maintain binary compatibility. 
    263.      */  
    264.     uint8_t reserved[96 - 84];  
    265. #endif  
    266.   
    267. } hwc_layer_1_t;  

    回到setUpHWComposer函数,下面是变量所有的设备上的layer调用其setPerFrameData函数。

    在分析setPerFrameData之前我们先分析下setUpHWComposer中的遍历Layer时候用到的cur和end。我把这段代码单独拿出来。

    1. HWComposer::LayerListIterator cur = hwc.begin(id);  
    2. const HWComposer::LayerListIterator end = hwc.end(id);  
    3. for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {  
    4.     /* 
    5.      * update the per-frame h/w composer data for each layer 
    6.      * and build the transparent region of the FB 
    7.      */  
    8.     const sp<Layer>& layer(currentLayers[i]);  
    9.     layer->setPerFrameData(hw, *cur);  
    10. }  
    看下HWComposer中的begin函数
    1. HWComposer::LayerListIterator HWComposer::begin(int32_t id) {  
    2.     return getLayerIterator(id, 0);  
    3. }  

    再来看下getLayerIterator函数,正常应该是最后一个分支。注意这个时候index是0

    1. HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) {  
    2.     if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) {  
    3.         return LayerListIterator();  
    4.     }  
    5.     const DisplayData& disp(mDisplayData[id]);  
    6.     if (!mHwc || !disp.list || index > disp.list->numHwLayers) {  
    7.         return LayerListIterator();  
    8.     }  
    9.     return LayerListIterator(new HWCLayerVersion1(mHwc, disp.list->hwLayers), index);  
    10. }  
    新建了一个LayerListIterator,这里面HWCLayerVersion1就是mLayerList, index就是mIndex. 我们看下*符号的重载,因为我们后面用到了,就是mLayerList。
    1. class LayerListIterator {  
    2.     friend class HWComposer;  
    3.     HWCLayer* const mLayerList;  
    4.     size_t mIndex;  
    5.   
    6.     LayerListIterator() : mLayerList(NULL), mIndex(0) { }  
    7.   
    8.     LayerListIterator(HWCLayer* layer, size_t index)  
    9.         : mLayerList(layer), mIndex(index) { }  
    10.   
    11.     // we don't allow assignment, because we don't need it for now  
    12.     LayerListIterator& operator = (const LayerListIterator& rhs);  
    13.   
    14. public:  
    15.     // copy operators  
    16.     LayerListIterator(const LayerListIterator& rhs)  
    17.         : mLayerList(HWCLayer::copy(rhs.mLayerList)), mIndex(rhs.mIndex) {  
    18.     }  
    19.   
    20.     ~LayerListIterator() { delete mLayerList; }  
    21.   
    22.     // pre-increment  
    23.     LayerListIterator& operator++() {  
    24.         mLayerList->setLayer(++mIndex);  
    25.         return *this;  
    26.     }  
    27.   
    28.     // dereference  
    29.     HWCLayerInterface& operator * () { return *mLayerList; }  
    30.     HWCLayerInterface* operator -> () { return mLayerList; }  
    31.   
    32.     // comparison  
    33.     bool operator == (const LayerListIterator& rhs) const {  
    34.         return mIndex == rhs.mIndex;  
    35.     }  
    36.     bool operator != (const LayerListIterator& rhs) const {  
    37.         return !operator==(rhs);  
    38.     }  
    39. };  
    而上面的mLayerList就是HWCLayerVersion1对象。

    而我们再来看看下HWComposer中的end函数,end函数和begin很像只是在调用getLayerIterator的时候,begin传入0,end传入layer的最后一位。最后就是mIndex成员变量不一样

    1. HWComposer::LayerListIterator HWComposer::end(int32_t id) {  
    2.     size_t numLayers = 0;  
    3.     if (uint32_t(id) <= 31 && mAllocatedDisplayIDs.hasBit(id)) {  
    4.         const DisplayData& disp(mDisplayData[id]);  
    5.         if (mHwc && disp.list) {  
    6.             numLayers = disp.list->numHwLayers;//获取到list中laye的个数  
    7.             if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {  
    8.                 // with HWC 1.1, the last layer is always the HWC_FRAMEBUFFER_TARGET,  
    9.                 // which we ignore when iterating through the layer list.  
    10.                 ALOGE_IF(!numLayers, "mDisplayData[%d].list->numHwLayers is 0", id);  
    11.                 if (numLayers) {  
    12.                     numLayers--;//变成最后一位  
    13.                 }  
    14.             }  
    15.         }  
    16.     }  
    17.     return getLayerIterator(id, numLayers);//和上面一样,只是传入的index不一样。  
    18. }  

    我们再来看LayerListIterator操作符++的重载,会调用mLayerList->setLayer函数

    1. LayerListIterator& operator++() {  
    2.     mLayerList->setLayer(++mIndex);  
    3.     return *this;  
    4. }  
    setLayer会从mLayerList中设置当前的mCurrentLayer,通过mLayerList, 这个变量就是disp.list->hwLayers
    1. virtual status_t setLayer(size_t index) {  
    2.     mCurrentLayer = &mLayerList[index];  
    3.     return NO_ERROR;  
    4. }  
    这样准备工作就好了,我们再来分析Layer的setPerFrameData函数,主要就是调用了HWCLayerVersion1的setBuffer函数
    1. void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,  
    2.         HWComposer::HWCLayerInterface& layer) {  
    3.     // we have to set the visible region on every frame because  
    4.     // we currently free it during onLayerDisplayed(), which is called  
    5.     // after HWComposer::commit() -- every frame.  
    6.     // Apply this display's projection's viewport to the visible region  
    7.     // before giving it to the HWC HAL.  
    8.     const Transform& tr = hw->getTransform();  
    9.     Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));  
    10.     layer.setVisibleRegionScreen(visible);  
    11.     layer.setSurfaceDamage(surfaceDamageRegion);  
    12.   
    13.     if (mSidebandStream.get()) {  
    14.         layer.setSidebandStream(mSidebandStream);  
    15.     } else {  
    16.         // NOTE: buffer can be NULL if the client never drew into this  
    17.         // layer yet, or if we ran out of memory  
    18.         layer.setBuffer(mActiveBuffer);  
    19.     }  
    20. }  
    再来看HWCLayerVersion1的setBuffer函数,调用getLayer函数设置其handle,而getLayer就是mCurrentLayer。之前mCurrentLayer会一个个遍历各个Layer,这样就把所有的layer都设置其handle,就是hwc_layer_1_t中的handle。
    1. virtual void setBuffer(const sp<GraphicBuffer>& buffer) {  
    2.     if (buffer == 0 || buffer->handle == 0) {  
    3.         getLayer()->compositionType = HWC_FRAMEBUFFER;  
    4.         getLayer()->flags |= HWC_SKIP_LAYER;  
    5.         getLayer()->handle = 0;  
    6.     } else {  
    7.         if (getLayer()->compositionType == HWC_SIDEBAND) {  
    8.             // If this was a sideband layer but the stream was removed, reset  
    9.             // it to FRAMEBUFFER. The HWC can change it to OVERLAY in prepare.  
    10.             getLayer()->compositionType = HWC_FRAMEBUFFER;  
    11.         }  
    12.         getLayer()->handle = buffer->handle;  
    13.     }  
    14. }  
    最后会调用HWComposer的prepare函数,我们再来看下这个函数。这里我们先将DisplayData的framebufferTarget的composition设置为HWC_FRAMEBUFFER_TARGET,然后将每个DisplayData的list放入mList中。最后调用了mHwc的prepare函数。
    1. status_t HWComposer::prepare() {  
    2.     Mutex::Autolock _l(mDisplayLock);  
    3.     for (size_t i=0 ; i<mNumDisplays ; i++) {  
    4.         DisplayData& disp(mDisplayData[i]);  
    5.         if (disp.framebufferTarget) {//这里其实就是disp.list中最后一个layer  
    6.             // make sure to reset the type to HWC_FRAMEBUFFER_TARGET  
    7.             // DO NOT reset the handle field to NULL, because it's possible  
    8.             // that we have nothing to redraw (eg: eglSwapBuffers() not called)  
    9.             // in which case, we should continue to use the same buffer.  
    10.             LOG_FATAL_IF(disp.list == NULL);  
    11.             disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET;  
    12.         }  
    13.         if (!disp.connected && disp.list != NULL) {  
    14.             ALOGW("WARNING: disp %zu: connected, non-null list, layers=%zu",  
    15.                   i, disp.list->numHwLayers);  
    16.         }  
    17.         mLists[i] = disp.list;//DisplayData的list就是mList的一个组员  
    18.         if (mLists[i]) {  
    19.             if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {  
    20.                 mLists[i]->outbuf = disp.outbufHandle;  
    21.                 mLists[i]->outbufAcquireFenceFd = -1;  
    22.             } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {  
    23.                 // garbage data to catch improper use  
    24.                 mLists[i]->dpy = (hwc_display_t)0xDEADBEEF;  
    25.                 mLists[i]->sur = (hwc_surface_t)0xDEADBEEF;  
    26.             } else {  
    27.                 mLists[i]->dpy = EGL_NO_DISPLAY;  
    28.                 mLists[i]->sur = EGL_NO_SURFACE;  
    29.             }  
    30.         }  
    31.     }  
    32.   
    33.     int err = mHwc->prepare(mHwc, mNumDisplays, mLists);//调用Hwc模块的prepare函数  
    34.     ALOGE_IF(err, "HWComposer: prepare failed (%s)", strerror(-err));  
    35.   
    36.     if (err == NO_ERROR) {  
    37.         // here we're just making sure that "skip" layers are set  
    38.         // to HWC_FRAMEBUFFER and we're also counting how many layers  
    39.         // we have of each type.  
    40.         //  
    41.         // If there are no window layers, we treat the display has having FB  
    42.         // composition, because SurfaceFlinger will use GLES to draw the  
    43.         // wormhole region.  
    44.         for (size_t i=0 ; i<mNumDisplays ; i++) {  
    45.             DisplayData& disp(mDisplayData[i]);  
    46.             disp.hasFbComp = false;  
    47.             disp.hasOvComp = false;  
    48.             if (disp.list) {  
    49.                 for (size_t i=0 ; i<disp.list->numHwLayers ; i++) {  
    50.                     hwc_layer_1_t& l = disp.list->hwLayers[i];  
    51.   
    52.                     //ALOGD("prepare: %d, type=%d, handle=%p",  
    53.                     //        i, l.compositionType, l.handle);  
    54.   
    55.                     if (l.flags & HWC_SKIP_LAYER) {  
    56.                         l.compositionType = HWC_FRAMEBUFFER;  
    57.                     }  
    58.                     if (l.compositionType == HWC_FRAMEBUFFER) {  
    59.                         disp.hasFbComp = true;  
    60.                     }  
    61.                     if (l.compositionType == HWC_OVERLAY) {  
    62.                         disp.hasOvComp = true;  
    63.                     }  
    64.                     if (l.compositionType == HWC_CURSOR_OVERLAY) {  
    65.                         disp.hasOvComp = true;  
    66.                     }  
    67.                 }  
    68.                 if (disp.list->numHwLayers == (disp.framebufferTarget ? 1 : 0)) {  
    69.                     disp.hasFbComp = true;  
    70.                 }  
    71.             } else {  
    72.                 disp.hasFbComp = true;  
    73.             }  
    74.         }  
    75.     }  
    76.     return (status_t)err;  
    77. }  
    mHwc的prepare主要将每个Layer的composition设置为HWC_FRAMEBUFFER。

  • 相关阅读:
    【转载】python自动提取文本中的时间(包含中文日期)
    【转载】PCA降维
    【转载】从头到尾彻底理解KMP算法
    【转载】傅里叶分析之掐死教程(完整版)更新于2014.06.06(Heinrich)
    【转载】白素贞的身世之谜
    React 路由参数改变页面不刷新问题
    前端学习资源笔记
    Nginx配置网站默认https
    基于Docker搭建大数据集群(一)Docker环境部署
    基于Docker搭建大数据集群(三)Hadoop部署
  • 原文地址:https://www.cnblogs.com/ztguang/p/12645203.html
Copyright © 2011-2022 走看看