最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

一 Surfaceflinger介紹

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

二 bufferqueue 原理

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

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

surfaceflinger作為消費(fèi)者,通過(guò)acquireBuffer()得到一個(gè)要合成的圖形,在合成完畢后再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的連接,通過(guò)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é)這個(gè)顯示層的控制。

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

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

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

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

surface創(chuàng)建后得到 mGraphicBufferProducer,通過(guò)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分配一個(gè)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中就是分配一個(gè)共享內(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)建一個(gè)surface后,surfaceflinger對(duì)應(yīng)的是一個(gè)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分析的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android中l(wèi)ayer-list基本使用詳解

    Android中l(wèi)ayer-list基本使用詳解

    這篇文章主要介紹了Android中l(wèi)ayer-list基本使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Android編程中出現(xiàn)The connection to adb is down問(wèn)題的解決方法

    Android編程中出現(xiàn)The connection to adb is down問(wèn)題的解決方法

    這篇文章主要介紹了Android編程中出現(xiàn)The connection to adb is down問(wèn)題的解決方法,涉及Android進(jìn)程與服務(wù)的相關(guān)操作技巧,需要的朋友可以參考下
    2015-12-12
  • ViewPager實(shí)現(xiàn)輪播圖引導(dǎo)頁(yè)

    ViewPager實(shí)現(xiàn)輪播圖引導(dǎo)頁(yè)

    這篇文章主要為大家詳細(xì)介紹了ViewPager實(shí)現(xiàn)輪播圖引導(dǎo)頁(yè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Android端使用Modbus協(xié)議的簡(jiǎn)單方法

    Android端使用Modbus協(xié)議的簡(jiǎn)單方法

    Modbus協(xié)議是全球第一個(gè)用于工業(yè)現(xiàn)場(chǎng)的總線協(xié)議,與外設(shè)交互可以采用串口通信,tcp等方式,這篇文章主要給大家介紹了關(guān)于Android端使用Modbus協(xié)議的簡(jiǎn)單方法,需要的朋友可以參考下
    2021-11-11
  • Android UI系列-----ScrollView和HorizontalScrollView的詳解

    Android UI系列-----ScrollView和HorizontalScrollView的詳解

    本篇文章主要是介紹的Android UI系列-----ScrollView和HorizontalScrollView,ScrollView和HorizontalScrollView都是布局容器,有需要的可以了解一下。
    2016-11-11
  • Android.mk引入第三方j(luò)ar包和so庫(kù)文件的方法

    Android.mk引入第三方j(luò)ar包和so庫(kù)文件的方法

    這篇文章主要介紹了Android.mk引入第三方j(luò)ar包和so庫(kù)文件的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • Android實(shí)現(xiàn)高德地圖顯示及定位

    Android實(shí)現(xiàn)高德地圖顯示及定位

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)高德地圖顯示及定位,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • Android實(shí)現(xiàn)微信登錄的示例代碼

    Android實(shí)現(xiàn)微信登錄的示例代碼

    微信登錄的實(shí)現(xiàn)與qq登錄類似。本文主要介紹了Android實(shí)現(xiàn)微信登錄,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Android開發(fā)-之環(huán)境的搭建(圖文詳解)

    Android開發(fā)-之環(huán)境的搭建(圖文詳解)

    這篇文章主要介紹了Android開發(fā)-之環(huán)境的搭建(圖文詳解),具有一定的參考價(jià)值,有興趣的可以了解一下。
    2016-11-11
  • android自定義滾動(dòng)上下回彈scollView

    android自定義滾動(dòng)上下回彈scollView

    這篇文章主要為大家詳細(xì)介紹了android自定義滾動(dòng)上下回彈scollView,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04

最新評(píng)論

确山县| 建平县| 台北市| 浏阳市| 外汇| 晋中市| 格尔木市| 仁化县| 定结县| 吴桥县| 邮箱| 双柏县| 吴桥县| 兰考县| 巴林左旗| 巴林左旗| 东乡县| 西盟| 光泽县| 崇信县| 新宁县| 离岛区| 神农架林区| 涿州市| 马边| 锡林郭勒盟| 揭西县| 宝坻区| 通渭县| 郁南县| 乐陵市| 大港区| 扶绥县| 荣成市| 中超| 蓬溪县| 菏泽市| 宽甸| 灌阳县| 上饶县| 洛阳市|