android Graphiics data output

来源:互联网 发布:软件 开发的软件环境 编辑:程序博客网 时间:2024/06/06 03:59

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

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

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

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

 

一、preComposition函数

我们先来看第一个函数preComposition

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

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

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

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

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

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

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

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

 

1.1 每个Layer的onFrameAvailable函数

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

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

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

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

我们再来看SurfaceFlingerConsumer的setContentsChangedListener函数

?
1
2
3
4
5
6
void SurfaceFlingerConsumer::setContentsChangedListener(
        constwp<contentschangedlistener>& listener) {
    setFrameAvailableListener(listener);
    Mutex::Autolock lock(mMutex);
    mContentsChangedListener = listener;
}</contentschangedlistener>

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

?
1
2
3
4
5
6
void ConsumerBase::setFrameAvailableListener(
        constwp<frameavailablelistener>& listener) {
    CB_LOGV("setFrameAvailableListener");
    Mutex::Autolock lock(mMutex);
    mFrameAvailableListener = listener;
}</frameavailablelistener>

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

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void ConsumerBase::onFrameAvailable(const BufferItem& item) {
    CB_LOGV("onFrameAvailable");
 
    sp<frameavailablelistener> listener;
    {// scope for the lock
        Mutex::Autolock lock(mMutex);
        listener = mFrameAvailableListener.promote();
    }
 
    if(listener != NULL) {
        CB_LOGV("actually calling onFrameAvailable");
        listener->onFrameAvailable(item);
    }
}</frameavailablelistener>
因此我们再来看看Layer的onFrameAvailable函数,主要是将mQueuedFrames加1,然后调用了SurfaceFlinger的signalLayerUpdate函数。

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void Layer::onFrameAvailable(const BufferItem& item) {
    // Add this buffer from our internal queue tracker
    {// Autolock scope
        Mutex::Autolock lock(mQueueItemLock);
 
        // Reset the frame number tracker when we receive the first buffer after
        // a frame number reset
        if(item.mFrameNumber == 1) {
            mLastFrameNumberReceived =0;
        }
 
        // Ensure that callbacks are handled in order
        while(item.mFrameNumber != mLastFrameNumberReceived + 1) {
            status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
                    ms2ns(500));
            if(result != NO_ERROR) {
                ALOGE("[%s] Timed out waiting on callback", mName.string());
            }
        }
 
        mQueueItems.push_back(item);
        android_atomic_inc(&mQueuedFrames);
 
        // Wake up any pending callbacks
        mLastFrameNumberReceived = item.mFrameNumber;
        mQueueItemCondition.broadcast();
    }
 
    mFlinger->signalLayerUpdate();
}

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

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

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

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

调用了handler的dispatchInvalidate函数,

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

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

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

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

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
bool SurfaceFlinger::handleMessageTransaction() {
    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
    if(transactionFlags) {
        handleTransaction(transactionFlags);
        returntrue;
    }
    returnfalse;
}
 
bool SurfaceFlinger::handleMessageInvalidate() {
    ATRACE_CALL();
    returnhandlePageFlip();
}

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.1handleTransaction函数

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

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

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

 

?
1
2
3
uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
    returnandroid_atomic_and(~flags, &mTransactionFlags) & flags;
}

 

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

 

2.2 Layer的doTransaction函数

下面是Layer的doTransaction函数代码

 

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

 

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

 

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

 

这里为什么要两个对象呢?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
2
3
void Layer::commitTransaction() {
    mDrawingState = mCurrentState;
}






首页 >程序开发 > 移动开发 > Android > 正文
Android6.0 显示系统(六) 图像的输出过程
2016-10-14     0 个评论   来源:kc58236582的博客  
收藏  我要投稿

2.3 handleTransactionLocked函数

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

 

2.3.1 处理Layer的事务

 

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

 

 

?
1
2
3
4
struct State {
    LayerVector layersSortedByZ;
    DefaultKeyedVector< wp<ibinder>, DisplayDeviceState> displays;
};</ibinder>

 

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

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

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

 

2.3.2 处理显示设备的变化

 

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

 

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

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

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

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

 

2.3.3 设置TransfromHit

 

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

 

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



2.3.4 处理Layer增加情况

 

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

 

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

 

2.3.5 设置mDrawingState

 

?
1
2
3
commitTransaction();
 
updateCursorAsync();

 

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

 

2.3.6 小结

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

 

2.4 handlePageFlip函数

handlePageFlip函数代码如下:

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

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

 

六、postFramebuffer函数

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

 

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

 

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

 

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

 

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


原创粉丝点击