Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android4.2.2 SurfaceFlinger之圖形渲染queueBuffer實現和VSYNC的存在感

Android4.2.2 SurfaceFlinger之圖形渲染queueBuffer實現和VSYNC的存在感

編輯:關於Android編程

本文均屬自己閱讀源碼的點滴總結,轉賬請注明出處謝謝。

 

 

Android源碼版本Version:4.2.2; 硬件平台 全志A31

 

前一博文總結了Android4.2.2 SurfaceFlinger之圖形緩存區申請與分配dequeueBuffer的實現,由於受到OpenGL Es的中介作用(內部實現圖層繪制並寫入到分配好的圖形緩存中去),eglSwapBuffers()函數內部的實現就是如此。好了作為生產者以及使用dequeueBuffer獲取了圖形緩存並寫入了繪圖數據,這下就該是渲染的過程queueBuffer來看看他的實現:

status_t BufferQueue::queueBuffer(int buf,
        const QueueBufferInput& input, QueueBufferOutput* output) {
    ATRACE_CALL();
.......
{ // scope for the lock
        Mutex::Autolock lock(mMutex);
        if (mAbandoned) {
            ST_LOGE(queueBuffer: SurfaceTexture has been abandoned!);
            return NO_INIT;
        }
        int maxBufferCount = getMaxBufferCountLocked();
        if (buf < 0 || buf >= maxBufferCount) {
            ST_LOGE(queueBuffer: slot index out of range [0, %d]: %d,
                    maxBufferCount, buf);
            return -EINVAL;
        } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {//非DEQUEUD,未被客戶端獲取
            ST_LOGE(queueBuffer: slot %d is not owned by the client 
                    (state=%d), buf, mSlots[buf].mBufferState);
            return -EINVAL;
        } else if (!mSlots[buf].mRequestBufferCalled) {
            ST_LOGE(queueBuffer: slot %d was enqueued without requesting a 
                    buffer, buf);
            return -EINVAL;
        }

        const sp& graphicBuffer(mSlots[buf].mGraphicBuffer);
        Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
        Rect croppedCrop;
        crop.intersect(bufferRect, &croppedCrop);
        if (croppedCrop != crop) {
            ST_LOGE(queueBuffer: crop rect is not contained within the 
                    buffer in slot %d, buf);
            return -EINVAL;
        }

        if (mSynchronousMode) {
            // In synchronous mode we queue all buffers in a FIFO.
            mQueue.push_back(buf);

            // Synchronous mode always signals that an additional frame should
            // be consumed.
            listener = mConsumerListener;//獲取消費者監聽
        } else {
            // In asynchronous mode we only keep the most recent buffer.
            if (mQueue.empty()) {
                mQueue.push_back(buf);

                // Asynchronous mode only signals that a frame should be
                // consumed if no previous frame was pending. If a frame were
                // pending then the consumer would have already been notified.
                listener = mConsumerListener;
            } else {
                Fifo::iterator front(mQueue.begin());
                // buffer currently queued is freed
                mSlots[*front].mBufferState = BufferSlot::FREE;
                // and we record the new buffer index in the queued list
                *front = buf;
            }
        }

        mSlots[buf].mTimestamp = timestamp;
        mSlots[buf].mCrop = crop;
        mSlots[buf].mTransform = transform;
        mSlots[buf].mFence = fence;

        switch (scalingMode) {
            case NATIVE_WINDOW_SCALING_MODE_FREEZE:
            case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
            case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
                break;
            default:
                ST_LOGE(unknown scaling mode: %d (ignoring), scalingMode);
                scalingMode = mSlots[buf].mScalingMode;
                break;
        }

        mSlots[buf].mBufferState = BufferSlot::QUEUED;
        mSlots[buf].mScalingMode = scalingMode;
        mFrameCounter++;
        mSlots[buf].mFrameNumber = mFrameCounter;

        mBufferHasBeenQueued = true;
        mDequeueCondition.broadcast();

        output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
                mQueue.size());

        ATRACE_INT(mConsumerName.string(), mQueue.size());
    }
......
    if (listener != 0) {
        listener->onFrameAvailable();//發布當前幀可以給消費者
    }
}

 

step1: 根據bufferSlot[]的索引值找到對應的buffer後,對其做是否處於DEQUEUED狀態,因為只有被客戶端獲取後才能去進一步的渲染。

 

step2: sp listener = mConsumerListener;

BufferQueue中的一個成員變量mConsumerListener是queueBuffer的主導,這個變量在哪裡何時創建的呢,來看這裡:

ConsumerBase::ConsumerBase(const sp& bufferQueue) :
        mAbandoned(false),
        mBufferQueue(bufferQueue) {
    // Choose a name using the PID and a process-unique ID.
    mName = String8::format(unnamed-%d-%d, getpid(), createProcessUniqueId());

    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
    // reference once the ctor ends, as that would cause the refcount of 'this'
    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
    // that's what we create.
    wp listener;
    sp proxy;
    listener = static_cast(this);
    proxy = new BufferQueue::ProxyConsumerListener(listener);//新建一個監聽代理

    status_t err = mBufferQueue->consumerConnect(proxy);//創建一個ConsumerListener代理
    if (err != NO_ERROR) {
        CB_LOGE(SurfaceTexture: error connecting to BufferQueue: %s (%d),
                strerror(-err), err);
    } else {
        mBufferQueue->setConsumerName(mName);
    }
}

在ConsumerBase的構造函數之中,而該類被SurfaceTexture繼承,且SurfaceFlinger在新建Layer時創建new SurfaceTexture時進行的。這裡可以看到調用了一個consumerConnect函數:

status_t BufferQueue::consumerConnect(const sp& consumerListener) {
.......
    mConsumerListener = consumerListener;

    return OK;
}

這裡就看到了BufferQueue的成員變量mConsumerListener完成了賦值初始化,從調用可知,傳入的proxy為BufferQueue的一個內部類ProxyConsumerListener,理解為消費者監聽代理。

而實際上的這個proxy自己也是有一個成員變量mConsumerListener即為上面傳入的listener(這裡的this是什麼?,當初ConsumerBase是基於new SurfaceTexture()來構造 ,該類繼承了ConsumerBase,故可以理解為這個this實際是SurfaceFLinger側的SurfaceTexture對象),為BufferQueue的內部類ConsumerListener。

BufferQueue::ProxyConsumerListener::ProxyConsumerListener(
        const wp& consumerListener):
        mConsumerListener(consumerListener) {}

 

step3:回到queueBuffer函數的最後listener->onFrameAvailable()

由於listener是ConsumerListener類,proxy是ProxyConsumerListener,且繼承public與ConsumerListener,故通過上面的分析最終調用的是proxy->onFrameAvailable,最終來到這裡:

void BufferQueue::ProxyConsumerListener::onFrameAvailable() {
    sp listener(mConsumerListener.promote());
    if (listener != NULL) {
        listener->onFrameAvailable();//調用消費者consumerbase的onFrameAvailable進行調用
    }
}

這裡的mConsumerListerner成員對象其實是指向派生類對象ConsumerBase的基類指針,故最終回到了ConsumerBase的onFrameAvailable().

因此上面的理解應該是一個proxy監聽代理,最終還是提交給消費者來處理,而最下層的消費者就是SurfaceTexture。

 

step4:由於SurfaceTexture沒有重載,則調用的ConsumerBase如下:

void ConsumerBase::onFrameAvailable() {
    CB_LOGV(onFrameAvailable);

    sp<frameavailablelistener> listener;
    { // scope for the lock
        Mutex::Autolock lock(mMutex);
        listener = mFrameAvailableListener;
    }

    if (listener != NULL) {
        CB_LOGV(actually calling onFrameAvailable);
        listener->onFrameAvailable();
    }
}
</frameavailablelistener>

這裡有出現了一個FrameAvailableListener類,幀可用監聽類,那這個ConsumerBase的成員變量mFrameAvailableListener是在哪裡初始化的呢,回到這裡?


void Layer::onFirstRef() { LayerBaseClient::onFirstRef();//基類LayerBaseClient

struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {//內部類繼承FrameAvailableListener FrameQueuedListener(Layer* layer) : mLayer(layer) { } private: wp mLayer; virtual void onFrameAvailable() { sp that(mLayer.promote()); if (that != 0) { that->onFrameQueued();//調用Layer的onFrameQueued } } };

// Creates a custom BufferQueue for SurfaceTexture to use sp bq = new SurfaceTextureLayer();//新建一個SurfaceTextureLayer,即BufferQueue mSurfaceTexture = new SurfaceTexture(mTextureName, true, GL_TEXTURE_EXTERNAL_OES, false, bq);//新建的表面紋理

mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));//新建立一個幀隊列監聽 mSurfaceTexture->setSynchronousMode(true);//支持同步模式

#ifdef TARGET_DISABLE_TRIPLE_BUFFERING #warning disabling triple buffering mSurfaceTexture->setDefaultMaxBufferCount(2); #else mSurfaceTexture->setDefaultMaxBufferCount(3); #endif

const sp hw(mFlinger->getDefaultDisplayDevice()); updateTransformHint(hw); }

這裡出現了一個和SurfaceTexture相關的幀可用監聽設置函數setFrameAvailableListener:

void ConsumerBase::setFrameAvailableListener(
        const sp<frameavailablelistener>& listener) {
    CB_LOGV(setFrameAvailableListener);
    Mutex::Autolock lock(mMutex);
    mFrameAvailableListener = listener;
</frameavailablelistener>

這裡可以看到listener = new FrameQueuedListener()對象,故最終調用的是FrameQueuedListener->onFrameAvailable()函數,而該類其實是Layer::onFirstRef的內部類FrameQueuedListener,該函數最終還是調用如下:

        virtual void onFrameAvailable() {
            sp that(mLayer.promote());
            if (that != 0) {
                that->onFrameQueued();//調用Layer的onFrameQueued
            }
        }

而這個mLayer是在對象FrameQueuedListener傳入的this參數,這個this就是傳入的layer對象,故最終這個that->onFrameQueued就回到了Layer::onFrameQueued函數。

 

step5:回到了熟悉的Layer處的調用

void Layer::onFrameQueued() {
    android_atomic_inc(&mQueuedFrames);
    mFlinger->signalLayerUpdate();//發送給SF Layer圖層更新
}

這裡的結果很顯然,一切還得有SurfaceFlinger來完成圖形緩存區的渲染,發出圖層更新的信號:

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

mEventQueue又涉及到了SurfaceFLinger的消息處理機制,意味著又要觸發一個Event的發生:

void MessageQueue::invalidate() {
#if INVALIDATE_ON_VSYNC
    mEvents->requestNextVsync();
#else
    mHandler->dispatchInvalidate();
#endif
}

這裡執行requestNextVsync()函數,即請求下一個VSYNC。那麼這個mEvents是什麼呢?可以在這裡看到被初始化

void MessageQueue::setEventThread(const sp& eventThread)
{
    mEventThread = eventThread;
    mEvents = eventThread->createEventConnection();//建立連接
   ....}
sp EventThread::createEventConnection() const {
    return new Connection(const_cast(this));
}

這個函數內部新建了一個Connection類對象,該類是EventThread的內部類繼承了BnDisplayEventConnection類。這裡有必要深入的看看connection的構造過程:

EventThread::Connection::Connection(
        const sp& eventThread)
    : count(-1), mEventThread(eventThread), mChannel(new BitTube())
{
}

該類繼承RefBase則執行onFirstRef()函數,看看他做了什麼特別的事情:

void EventThread::Connection::onFirstRef() {
    // NOTE: mEventThread doesn't hold a strong reference on us
    mEventThread->registerDisplayEventConnection(this);//將隨著eventthread新建的connection對象注冊到mDisplayEventConnections
}

將這個新建出來的Connection對象this注冊到顯示事件中去:

status_t EventThread::registerDisplayEventConnection(
        const sp& connection) {
    Mutex::Autolock _l(mLock);
    mDisplayEventConnections.add(connection);
    mCondition.broadcast();
    return NO_ERROR;
}

最終是將這個connection維護在了一個SortedVector< wp > mDisplayEventConnections存儲類中。

 

上述分析後,可知最終requestNextVsync調用的是Connection的requestNextVsync來完成的:

void EventThread::Connection::requestNextVsync() {
    mEventThread->requestNextVsync(this);
}

mEventThread是直接新建時傳入的this,且為EventThread;故最終調用的是EventThread類的成員函數requestNextVsync()

 

step6:EventThread的requestNextVsync函數

void EventThread::requestNextVsync(
        const sp& connection) {
    Mutex::Autolock _l(mLock);
    if (connection->count < 0) {
        connection->count = 0;
        mCondition.broadcast();//條件滿足時,發出一個廣播請求下一個VSYNC
    }
}

這裡是將count清0,並觸發一個進程鎖的解鎖,這個鎖等待在EventThread的threadLoop()中,以EventThread::waitForEvent()函數的形式睡眠,下面來看部分代碼:

Vector< sp > EventThread::waitForEvent(
        DisplayEventReceiver::Event* event){
        // find out connections waiting for events
        size_t count = mDisplayEventConnections.size();
        for (size_t i=0 ; i connection(mDisplayEventConnections[i].promote());
            if (connection != NULL) {
                bool added = false;
                if (connection->count >= 0) {
                    // we need vsync events because at least
                    // one connection is waiting for it
                    waitForVSync = true;
                    if (timestamp) {
                        // we consume the event only if it's time
                        // (ie: we received a vsync event)
                        if (connection->count == 0) {
                            // fired this time around
                            connection->count = -1;
                            signalConnections.add(connection);
                            added = true;
                        } else if (connection->count == 1 ||
                                (vsyncCount % connection->count) == 0) {
                            // continuous event, and time to report it
                            signalConnections.add(connection);
                            added = true;
                        }
                    }
                }
while (signalConnections.isEmpty())............
}

在獲得之前注冊到mDisplayEventConnections數組之中connection對象,依據之前的requestNextVsync(),他會將count=0,故這裡執行signalConnections.add(connection);

有了連擊信號後,直接退出waitEvent()。

 

step7:到這裡我們需要回到Android4.2.2 SurfaceFlinger的相關事件和消息處理機制這裡,因為我們知道如果要渲染當前的圖像,需要接受到底層硬件返回的一個VSYNC,而這裡有HWComposer來完成(當然硬件不支持時會由一個VSyncThread來軟件模擬)。

在SF運行時就會創建一個HWComposer:

    mHwc = new HWComposer(this,
            *static_cast(this));//新建一個軟硬件合成器HWComposer

在HWComposer的構造函數內,可以看到向hwcomposer的HAL層注冊了回調業務函數:

 if (mHwc) {//如果支持硬件hw
        ALOGI(Using %s version %u.%u, HWC_HARDWARE_COMPOSER,
              (hwcApiVersion(mHwc) >> 24) & 0xff,
              (hwcApiVersion(mHwc) >> 16) & 0xff);//1.1版本
        if (mHwc->registerProcs) {
            mCBContext->hwc = this;
            mCBContext->procs.invalidate = &hook_invalidate;
            mCBContext->procs.vsync = &hook_vsync;//相關hwc的回調函數初始化,用於向上層發出VSYNC信號
            if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
                mCBContext->procs.hotplug = &hook_hotplug;
            else
                mCBContext->procs.hotplug = NULL;
            memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
            mHwc->registerProcs(mHwc, &mCBContext->procs);//向HAL注冊回調函數
        }

很容易的可以看到底層硬件產生一個硬件的VSYNC時,傳入的回調函數即為hook_vsync。那麼底層硬件又是如何反饋回這個VSYNC信號的呢?

 

step8: VSYNC的硬件信號捕獲進程分析

在之前已經說到registerProcs會將回調函數進行注冊,而這個不單單是注冊這麼簡單,我們來看看:

static void hwc_registerProcs(struct hwc_composer_device_1* dev,
                              hwc_procs_t const* procs)
{
    ALOGI(%s, __FUNCTION__);
    hwc_context_t* ctx = (hwc_context_t*)(dev);
    if(!ctx) {
        ALOGE(%s: Invalid context, __FUNCTION__);
        return;
    }
    ctx->proc = procs;

    // Now that we have the functions needed, kick off
    // the uevent & vsync threads
    init_uevent_thread(ctx);
    init_vsync_thread(ctx);
}

果然這裡出現了線程的存在感,即這裡新建了兩個線程而init_vsync_thread就是輪詢捕獲VSYNC的真正線程:

void init_vsync_thread(hwc_context_t* ctx)
{
    int ret;
    pthread_t vsync_thread;
    ALOGI(Initializing VSYNC Thread);
    ret = pthread_create(&vsync_thread, NULL, vsync_loop, (void*) ctx);
    if (ret) {
        ALOGE(%s: failed to create %s: %s, __FUNCTION__,
              HWC_VSYNC_THREAD_NAME, strerror(ret));
    }
}

這裡創建了一個vsync_loop的線程函數,且傳入的參數為回調函數的內容。進入線程後,基本就是和內核進行交互,捕獲VSYNC,而且肯定是處於死循環中。

static void *vsync_loop(void *param)
{
    const char* vsync_timestamp_fb0 = /sys/class/graphics/fb0/vsync_event;
    const char* vsync_timestamp_fb1 = /sys/class/graphics/fb1/vsync_event;
    int dpy = HWC_DISPLAY_PRIMARY;
.....
do
{
        ctx->proc->vsync(ctx->proc, dpy, cur_timestamp);
}while(true);
}
}

從而屬於SurfaceFlinger進程 一個VSYNC線程就在實時監聽VSYNC的存在,並回調給vsync()函數,即注冊的hook_sync().

 

step9: hook_sync()的作用

void HWComposer::hook_vsync(const struct hwc_procs* procs, int disp,
        int64_t timestamp) {
    cb_context* ctx = reinterpret_cast(
            const_cast(procs));
    ctx->hwc->vsync(disp, timestamp);
}

繼續該函數的執行,回到了HWComposer中來執行

void HWComposer::vsync(int disp, int64_t timestamp) {
    ATRACE_INT(VSYNC, ++mVSyncCount&1);
    mEventHandler.onVSyncReceived(disp, timestamp);//調用SF的onVSyncReceived
    Mutex::Autolock _l(mLock);
    mLastHwVSync = timestamp;
}

而這裡利用的mEventHandle是對象就是SurfaceFlinger對象,故轉到SurfaceFlinger::onVSyncReceived函數來執行

void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
    if (mEventThread == NULL) {
        // This is a temporary workaround for b/7145521.  A non-null pointer
        // does not mean EventThread has finished initializing, so this
        // is not a correct fix.
        ALOGW(WARNING: EventThread not started, ignoring vsync);
        return;
    }
    if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) {
        // we should only receive DisplayDevice::DisplayType from the vsync callback
        mEventThread->onVSyncReceived(type, timestamp);//發出一個VSYNC接收
    }
}

上面函數利用SF處的事件處理線程進一步執行,完成了對當前的VSYNC事件進行初始化,並提交一個broadcast,供相應的阻塞線程進行喚醒。

void EventThread::onVSyncReceived(int type, nsecs_t timestamp) {
    ALOGE_IF(type >= HWC_DISPLAY_TYPES_SUPPORTED,
            received event for an invalid display (id=%d), type);

    Mutex::Autolock _l(mLock);
    if (type < HWC_DISPLAY_TYPES_SUPPORTED) {
        mVSyncEvent[type].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
        mVSyncEvent[type].header.id = type;
        mVSyncEvent[type].header.timestamp = timestamp;
        mVSyncEvent[type].vsync.count++;
        mCondition.broadcast();
    }
}

喚醒的線程就是EventThread的waitEvent()函數,故回到step6處繼續分析。

 

step10:VSYNC的事件處理

VSYNC的處理過程在Android4.2.2 SurfaceFlinger的相關事件和消息處理機制已經詳細的分析過,這裡不做過多的分析。要補充的是只有一個connection對象存在時,才會提交一個Event事件:

bool EventThread::threadLoop() {
    DisplayEventReceiver::Event event;
    Vector< sp > signalConnections;
    signalConnections = waitForEvent(&event);//輪詢等待event的發生,一般是硬件的請求
const size_t count = signalConnections.size();
    for (size_t i=0 ; i& conn(signalConnections[i]);
        // now see if we still need to report this event
        status_t err = conn->postEvent(event);//發送事件,一般的硬件觸發了事件的發生

很容易看到只有需要渲染的一個buffer發出connection時即讓waitEvent從睡眠中醒過來mCondition.wait(mLock);

簡單的幾個分支情況如下:

1.如果沒有VSYNC時,喚醒waitEvent()中的阻塞函數,且會執行psotEvent(),但是沒有Event的相關信息。

2.如果只有VSYNC,則signalConnections不會被add相關的connection,只會繼續睡眠,喚醒,睡眠。

3.從而只有在step6中那樣,喚醒線程且添加對象connection到signalConnections裡面,再次進入睡眠,等著VSYNC喚醒後直接退出循環,最終才會提交一次Event

 

step11: 最終事件被eventReceiver()回調後並發出一個消息,消息處理由下面的函數來處理

int MessageQueue::eventReceiver(int fd, int events) {
    ssize_t n;
    DisplayEventReceiver::Event buffer[8];
    while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {//得到事件的數據
        for (int i=0 ; idispatchInvalidate();
#else
                mHandler->dispatchRefresh();//刷新
#endif
                break;
            }
        }
    }
    return 1;
}
void MessageQueue::Handler::dispatchInvalidate() {
    if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
        mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
    }
}

發出的消息類型為INVALIDATE。

void MessageQueue::Handler::handleMessage(const Message& message) {//事件消息處理機制
    switch (message.what) {
        case INVALIDATE:
            android_atomic_and(~eventMaskInvalidate, &mEventMask);
            mQueue.mFlinger->onMessageReceived(message.what);
            break;
        case REFRESH:
            android_atomic_and(~eventMaskRefresh, &mEventMask);
            mQueue.mFlinger->onMessageReceived(message.what);//線程接收到了消息後處理
            break;
    }
}

首先是執行INVALIDATE函數,先來看看他完成的任務,最終發現他還是提交給SurfaceFlinger來完成:

void SurfaceFlinger::onMessageReceived(int32_t what) {//收到消息
    ATRACE_CALL();
    switch (what) {
    case MessageQueue::INVALIDATE://SurfaceFlinger的處理
        handleMessageTransaction();
        handleMessageInvalidate();
        signalRefresh();
        break;
    case MessageQueue::REFRESH:
        handleMessageRefresh();
        break;
    }
}

上面的函數分別是對當前的繪圖的信息發生變化時來做處理的,比如z軸發生變化,透傳變化等等。

void SurfaceFlinger::handleMessageTransaction() {
    uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
    if (transactionFlags) {
        handleTransaction(transactionFlags);//事務處理
    }
}

void SurfaceFlinger::handleMessageInvalidate() {
    ATRACE_CALL();
    handlePageFlip();//
}

處理完後最終發出signalRefresh();信號來完成最終的繪圖。

void SurfaceFlinger::signalRefresh() {
    mEventQueue.refresh();//刷新
}
void MessageQueue::refresh() {
#if INVALIDATE_ON_VSYNC
    mHandler->dispatchRefresh();
#else
    mEvents->requestNextVsync();
#endif
}

最終這裡發出REFRESH類型的消息

void MessageQueue::Handler::dispatchRefresh() {
    if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
        mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
    }
}

而最終的處理同理還是由SurfaceFlinger::onMessageReceived(int32_t what)裡的handleMessageRefresh()來完成處理:

void SurfaceFlinger::handleMessageRefresh() {//處理layer的刷新,實際是調用SF繪圖
    ATRACE_CALL();
    preComposition();
    rebuildLayerStacks();
    setUpHWComposer();
    doDebugFlashRegions();
    doComposition();
    postComposition();//寫入到FrameBuffer中
}

最終依舊上述函數完成繪圖送顯。

到這裡就完成了queueBuffer的整個流程,細節上的東西比較多,講的也比較粗。

 

 

 

 

 

 

 

 

 

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved