欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android顯示系統(tǒng)SurfaceFlinger分析

 更新時間:2021年12月19日 17:16:33   作者:Little熊貓  
本文詳細(xì)講解了Android顯示系統(tǒng)SurfaceFlinger,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

一 Surfaceflinger介紹

surfaceflinger作用是接受多個來源的圖形顯示數(shù)據(jù),將他們合成,然后發(fā)送到顯示設(shè)備。比如打開應(yīng)用,常見的有三層顯示,頂部的statusbar底部或者側(cè)面的導(dǎo)航欄以及應(yīng)用的界面,每個層是單獨更新和渲染,這些界面都是有surfaceflinger合成一個刷新到硬件顯示。在顯示過程中使用到了bufferqueue,surfaceflinger作為consumer方,比如windwomanager管理的surface作為生產(chǎn)方產(chǎn)生頁面,交由surfaceflinger進(jìn)行合成。

二 bufferqueue 原理

bufferqueue分為生產(chǎn)者和消費者

比如應(yīng)用通過windowsmanager分配一個surface,需要分配(dequeueBuffer)顯示空間在上面進(jìn)行繪圖,在圖形繪制完成后需要推送(queueBuffer)到surfaceflinger進(jìn)行合成顯示。

surfaceflinger作為消費者,通過acquireBuffer()得到一個要合成的圖形,在合成完畢后再releaseBuffer()將圖形釋放。

bufferqueue類圖關(guān)系如下:

三 surfaceflinger 關(guān)系圖

ComposerService 為單例模式負(fù)責(zé)與surfaceflinger建立binder連接代碼如下:

class ComposerService : public Singleton<ComposerService>
{
    sp<ISurfaceComposer> mComposerService;
    sp<IBinder::DeathRecipient> mDeathObserver;
    Mutex mLock;

    ComposerService();
    void connectLocked();
    void composerServiceDied();
    friend class Singleton<ComposerService>;
public:

    // Get a connection to the Composer Service.  This will block until
    // a connection is established.
    static sp<ISurfaceComposer> getComposerService();
};

void ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {
        usleep(250000);
    }
    assert(mComposerService != NULL);

    // Create the death listener.
    class DeathObserver : public IBinder::DeathRecipient {
        ComposerService& mComposerService;
        virtual void binderDied(const wp<IBinder>& who) {
            ALOGW("ComposerService remote (surfaceflinger) died [%p]",
                  who.unsafe_get());
            mComposerService.composerServiceDied();
        }
     public:
        DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
    };

    mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
    mComposerService->asBinder()->linkToDeath(mDeathObserver);
}
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
    ComposerService& instance = ComposerService::getInstance();
    Mutex::Autolock _l(instance.mLock);
    if (instance.mComposerService == NULL) {
        ComposerService::getInstance().connectLocked();
        assert(instance.mComposerService != NULL);
        ALOGD("ComposerService reconnected");
    }
    return instance.mComposerService;
}

SurfaceComposerClient則在于surfaceflinger建立連接后建立與Client的連接,通過client調(diào)用createSurface,然后返回SurfaceControl

sp<SurfaceControl> SurfaceComposerClient::createSurface(
        const String8& name,
        uint32_t w,
        uint32_t h,
        PixelFormat format,
        uint32_t flags)
{
    sp<SurfaceControl> sur;
    if (mStatus == NO_ERROR) {
        sp<IBinder> handle;
        sp<IGraphicBufferProducer> gbp;
        status_t err = mClient->createSurface(name, w, h, format, flags,
                &handle, &gbp);
        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
        if (err == NO_ERROR) {
            sur = new SurfaceControl(this, handle, gbp);
        }
    }
    return sur;
}

SurfaceControl負(fù)責(zé)這個顯示層的控制。

sp<Surface> SurfaceControl::getSurface() const
{
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == 0) {
        // This surface is always consumed by SurfaceFlinger, so the
        // producerControlledByApp value doesn't matter; using false.
        mSurfaceData = new Surface(mGraphicBufferProducer, false);
    }
    return mSurfaceData;
}

通過SurfaceControl::getSurface(),得到的真正的顯示層,這樣之后可以通過Lock和unlock將surface空間分配繪圖,再返回給surfaceflinger

上面只是cpp側(cè)的分析,上層比如WMS是java層,他的管理也是同底層一樣,只不過是有層JNI的封裝。

四 layer顯示內(nèi)存分配

surface創(chuàng)建后得到 mGraphicBufferProducer,通過mGraphicBufferProducer dequeubuffer在surfaceflinger的BnGraphicBufferProducer dequeuebuffer

int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, mSwapIntervalZero,
            reqW, reqH, mReqFormat, mReqUsage);

    sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);

    if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
        result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
        if (result != NO_ERROR) {
            ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
            return result;
        }
       *buffer = gbuf.get();
    }

}

在producer的server側(cè),new GraphicBuffer分配一個GraphicBuffer

    if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
        BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
        sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
                width, height, format, BQ_LAYER_COUNT, usage,
                {mConsumerName.string(), mConsumerName.size()});

在graphicbuffer中就是分配一個共享內(nèi)存

GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
        PixelFormat inFormat, uint32_t inLayerCount, uint64_t usage, std::string requestorName)
    : GraphicBuffer()
{
    mInitCheck = initWithSize(inWidth, inHeight, inFormat, inLayerCount,
            usage, std::move(requestorName));
}

status_t GraphicBuffer::initWithSize(uint32_t inWidth, uint32_t inHeight,
        PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage,
        std::string requestorName)
{
    GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
    uint32_t outStride = 0;
    status_t err = allocator.allocate(inWidth, inHeight, inFormat, inLayerCount,
            inUsage, &handle, &outStride, mId,
            std::move(requestorName));
    if (err == NO_ERROR) {
        mBufferMapper.getTransportSize(handle, &mTransportNumFds, &mTransportNumInts);

        width = static_cast<int>(inWidth);
        height = static_cast<int>(inHeight);
        format = inFormat;
        layerCount = inLayerCount;
        usage = inUsage;
        usage_deprecated = int(usage);
        stride = static_cast<int>(outStride);
    }
    return err;
}

GraphicBufferAllocator::get() 使用gralloc進(jìn)行內(nèi)存分配,分配完成后,得到bufferIdx 將他發(fā)給client端也就是surface端

    virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeInt32(bufferIdx);
        status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
        bool nonNull = reply.readInt32();
        if (nonNull) {
            *buf = new GraphicBuffer();
            result = reply.read(**buf);
            if(result != NO_ERROR) {
                (*buf).clear();
                return result;
            }
        }
        result = reply.readInt32();
        return result;
    

返回虛擬地址給上層

        void* vaddr;
        status_t res = backBuffer->lockAsync(
                GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
                newDirtyRegion.bounds(), &vaddr, fenceFd);

五 surfaceflinger Layer

上面創(chuàng)建一個surface后,surfaceflinger對應(yīng)的是一個layer,當(dāng)上層layer調(diào)用刷新后,onFrameAvailable被調(diào)用,通知surfaceflinger有l(wèi)ayer更新

void BufferLayer::onFrameAvailable(const BufferItem& item) {
    mFlinger->signalLayerUpdate();
}

到此這篇關(guān)于Android顯示系統(tǒng)SurfaceFlinger分析的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android調(diào)用系統(tǒng)照相機(jī)拍照與攝像的方法

    Android調(diào)用系統(tǒng)照相機(jī)拍照與攝像的方法

    這篇文章主要為大家詳細(xì)介紹了Android如何調(diào)用系統(tǒng)現(xiàn)有的照相機(jī)拍照與攝像,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Android NDK開發(fā)的環(huán)境搭建與簡單示例

    Android NDK開發(fā)的環(huán)境搭建與簡單示例

    本文主要介紹Android NDK的知識,這里整理了相關(guān)資料,來說明如何搭建相應(yīng)環(huán)境和簡單實例,幫助大家理解,有興趣的小伙伴可以參考下
    2016-09-09
  • Android手勢左右滑動效果

    Android手勢左右滑動效果

    這篇文章主要為大家詳細(xì)介紹了Android手勢左右滑動效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Flutter啟動頁(閃屏頁)的具體實現(xiàn)及原理詳析

    Flutter啟動頁(閃屏頁)的具體實現(xiàn)及原理詳析

    這篇文章主要給大家介紹了關(guān)于Flutter啟動頁(閃屏頁)的具體實現(xiàn)及原理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Flutter具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 詳解Android app自動更新總結(jié)(已適配9.0)

    詳解Android app自動更新總結(jié)(已適配9.0)

    這篇文章主要介紹了詳解Android app自動更新總結(jié)(已適配9.0),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Android WaveView實現(xiàn)水流波動效果

    Android WaveView實現(xiàn)水流波動效果

    這篇文章主要介紹了 Android自定義控件 WaveView實現(xiàn)水流波動效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-03-03
  • Android自定義View實現(xiàn)微信語音界面

    Android自定義View實現(xiàn)微信語音界面

    這篇文章主要為大家詳細(xì)介紹了Android自定義View實現(xiàn)微信語音界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • RecyclerView嵌套RecyclerView滑動卡頓的解決方法

    RecyclerView嵌套RecyclerView滑動卡頓的解決方法

    這篇文章主要為大家詳細(xì)介紹了RecyclerView嵌套RecyclerView滑動卡頓的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • Android編程自定義進(jìn)度條顏色的方法詳解

    Android編程自定義進(jìn)度條顏色的方法詳解

    這篇文章主要介紹了Android編程自定義進(jìn)度條顏色的方法,結(jié)合實例形式分析了Android進(jìn)度條顏色相關(guān)的屬性設(shè)置操作技巧,需要的朋友可以參考下
    2017-09-09
  • Kotlin協(xié)程Channel源碼示例淺析

    Kotlin協(xié)程Channel源碼示例淺析

    這篇文章主要為大家介紹了Kotlin協(xié)程Channel源碼示例淺析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12

最新評論