Android顯示Surface


Surface創(chuàng)建

在ViewRootImpl,創(chuàng)建一個(gè)final的Surface對(duì)象沟娱,任何線(xiàn)程可訪(fǎng)問(wèn)它嗡官,內(nèi)部mLock鎖。ViewRootImpl類(lèi)中的Surface定義膀篮。

final Surface mSurface = new Surface();

第一次performTraversals方法或窗體發(fā)生改變時(shí)嘹狞,Surface的#isValid方法判斷是否有效,relayoutWindow方法誓竿,初始化Surface磅网。

之前無(wú)效,現(xiàn)在有效
1:設(shè)置newSurface標(biāo)志筷屡,下次再繪制涧偷。
2:初始化硬件渲染,mHardwareRenderer#initinitialize方法

之前有效毙死,現(xiàn)在無(wú)效
各種destroy停止

一直有效
硬件渲染更新燎潮,mHardwareRenderer#updateSurface方法

Surface的#isValid方法。

public boolean isValid() {
    synchronized (mLock) {
        if (mNativeObject == 0) return false;
        return nativeIsValid(mNativeObject);
    }
}

當(dāng)Surface內(nèi)部底層指針mNativeObject不空扼倘,且底層JNI方法#nativeIsValid判斷有效時(shí)确封,認(rèn)定Java層Surface有效。
通過(guò)IWindowSession的#relayout方法訪(fǎng)問(wèn)Wms服務(wù)。

public int relayout(IWindow window, int seq, ...,Surface outSurface) {
    int res = mService.relayoutWindow(this, window, ..., outSurface);
    return res;
}

Wms服務(wù)的#relayoutWindow方法爪喘,初始化App進(jìn)程傳過(guò)來(lái)的Surface颜曾。

public int relayoutWindow(Session session, IWindow client, ...,Surface outSurface) {
    ..
    if (viewVisibility == View.VISIBLE &&
                    (win.mAppToken == null || !win.mAppToken.clientHidden)) {
        try {
            ...
            SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
            //創(chuàng)建surfaceControl
            if (surfaceControl != null) {
                outSurface.copyFrom(surfaceControl);
            } else {
                outSurface.release();
            }
        } catch (Exception e) {
        }
    }
    ...
}

創(chuàng)建一個(gè)SurfaceControl對(duì)象,調(diào)用它的copyFrom方法腥放,初始化底層Surface泛啸,該對(duì)象是Surface控制類(lèi)绿语。


創(chuàng)建SurfaceControl

SurfaceControl底層結(jié)構(gòu)圖秃症。

SurfaceControl結(jié)構(gòu)圖.jpg

WindowStateAnimator的createSurfaceLocked方法。

SurfaceControl createSurfaceLocked() {
    if (mSurfaceControl == null) {
        mDrawState = DRAW_PENDING;//狀態(tài)變更為待繪制
        ...
        try {
            mSurfaceW = width;//設(shè)置surface的寬高
            mSurfaceH = height;
            ...
            mSurfaceFormat = format;//設(shè)置surface格式
            mSurfaceControl = new SurfaceControl(
                        mSession.mSurfaceSession,
                        attrs.getTitle().toString(),
                        width, height, format, flags);
            w.mHasSurface = true;//winstate有了surface
            try {
                mSurfaceX = left;
                mSurfaceY = top;
                try {
                    mSurfaceControl.setPosition(left, top);
                    mSurfaceLayer = mAnimLayer;
                    ...
                    mSurfaceControl.setLayer(mAnimLayer);
                    mSurfaceControl.setAlpha(0);
                    mSurfaceShown = false;
                } catch (RuntimeException e) {
                    ...
                }
                mLastHidden = true;//剛創(chuàng)建的設(shè)為隱藏
            }
    }
}

在Java層吕粹,SurfaceControl#構(gòu)造方法种柑,JNI#方法,創(chuàng)建底層SurfaceControl匹耕,參數(shù)是SurfaceSession聚请、寬高、格式等稳其,返回指針驶赏。

static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
        jstring nameStr, jint w, jint h, jint format, jint flags) {
    sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
    //創(chuàng)建底層surfaceControl。
    sp<SurfaceControl> surface = client->createSurface(
            String8(name.c_str()), w, h, format, flags);
    ...
    surface->incStrong((void *)nativeCreate);
    return reinterpret_cast<jlong>(surface.get());
}

底層SurfaceComposerClient既鞠,它在SurfaceSession構(gòu)造方法創(chuàng)建煤傍。創(chuàng)建底層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);
        if (err == NO_ERROR) {
            sur = new SurfaceControl(this, handle, gbp);
        }
    }
    return sur;
}

在Wms服務(wù)進(jìn)程嘱蛋,此方法本質(zhì)是調(diào)用Client#createSurface實(shí)現(xiàn)與SF進(jìn)程通信蚯姆,SF進(jìn)程初始化handle與gbp,最后洒敏,構(gòu)建一個(gè)底層SurfaceControl用于封裝關(guān)鍵的handle與gdp龄恋。
ISurfaceComposerClient是Wms服務(wù)進(jìn)程與SF進(jìn)程通信業(yè)務(wù)接口,SurfaceComposerClient#onFirstRef方法在構(gòu)造方法前調(diào)用凶伙。

void SurfaceComposerClient::onFirstRef() {
    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
    if (sm != 0) {
        sp<ISurfaceComposerClient> conn = sm->createConnection();
        if (conn != 0) {
            mClient = conn;//初始化mClient郭毕。
            mStatus = NO_ERROR;
        }
    }
}

通過(guò)createConnection方法,調(diào)用端得到的業(yè)務(wù)接口的實(shí)現(xiàn)BpSurfaceComposerClient函荣。SF進(jìn)程服務(wù)端創(chuàng)建Client對(duì)象铣卡,繼承BnSurfaceComposerClient。


SF進(jìn)程createSurface方法

Wms進(jìn)程發(fā)起訪(fǎng)問(wèn)后偏竟,SF進(jìn)程啟動(dòng)binder線(xiàn)程處理業(yè)務(wù)煮落,向SF主線(xiàn)程發(fā)送一個(gè)MessageCreateLayer消息。
Client#createSurface方法踊谋。

status_t Client::createSurface(...) {
    //先定義一個(gè)消息類(lèi)MessageCreateLayer 
    class MessageCreateLayer : public MessageBase {
        SurfaceFlinger* flinger;
        Client* client;
        sp<IBinder>* handle;
        sp<IGraphicBufferProducer>* gbp;
        status_t result;
        ..
    public:
        MessageCreateLayer(SurfaceFlinger* flinger,
                const String8& name, Client* client,
                uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
                sp<IBinder>* handle,
                sp<IGraphicBufferProducer>* gbp)
            : flinger(flinger), client(client),
              handle(handle), gbp(gbp),
              name(name), w(w), h(h), format(format), flags(flags) {
        }
        status_t getResult() const { return result; }
        virtual bool handler() {
            result = flinger->createLayer(name, client, w, h, format, flags,
                    handle, gbp);//
            return true;
        }
    };

    sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
            name, this, w, h, format, flags, handle, gbp);
    mFlinger->postMessageSync(msg);
    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}

創(chuàng)建一個(gè)MessageCreateLayer消息蝉仇,postMessageSync發(fā)送給SF主線(xiàn)程。

status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
        nsecs_t reltime, uint32_t /* flags */) {
    status_t res = mEventQueue.postMessage(msg, reltime);
    if (res == NO_ERROR) {
        msg->wait();//柵欄等待
    }
    return res;
}

向EventQueue消息隊(duì)列發(fā)送同步消息,然后通過(guò)柵欄使binder線(xiàn)程陷入wait轿衔,最后由主線(xiàn)程喚醒沉迹。MessageCreateLayer繼承MessageBase,當(dāng)主線(xiàn)程handleMessage方法處理時(shí)害驹,觸發(fā)子類(lèi)MessageCreateLayer重寫(xiě)的handler方法鞭呕,最后打開(kāi)柵欄,喚醒等待的binder線(xiàn)程宛官。

void MessageBase::handleMessage(const Message&) {
    //走到MessageCreateLayer重寫(xiě)的handler方法
    this->handler();
    barrier.open();
};
//MessageCreateLayer重寫(xiě)的handler方法
virtual bool handler() {
    result = flinger->createLayer(name, client, w, h, format, flags,handle, gbp);
    return true;
}

handler處理時(shí)葫松,觸發(fā)主線(xiàn)程SF#createLayer方法,真正初始化handle與gbp底洗,返回result腋么,SF#binder線(xiàn)程被喚醒后,createSurface繼續(xù)執(zhí)行亥揖,此時(shí)珊擂,result已初始化賦值。

總結(jié)
binder線(xiàn)程被柵欄阻擋费变,進(jìn)入等待摧扇,當(dāng)主線(xiàn)程handler方法執(zhí)行后,有了result挚歧,打開(kāi)柵欄扛稽,放行>binder線(xiàn)程,被喚醒拿到result昼激。


SF主線(xiàn)程createLayer方法

status_t SurfaceFlinger::createLayer(
        const String8& name,
        const sp<Client>& client,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) {
    sp<Layer> layer;
    result = createNormalLayer(client,
                    name, w, h, flags, format,//format是java層傳過(guò)來(lái)的
                    handle, gbp, &layer);//創(chuàng)建Layer對(duì)象庇绽,指針在layer中。
    ...
    result = addClientLayer(client, *handle, *gbp, layer);//將layer增加到list中
    ...
    setTransactionFlags(eTransactionNeeded);//0x01 創(chuàng)建Layer橙困,觸發(fā)eTransactionNeeded
    return result;
}

SurfaceFlinger#createNormalLayer方法瞧掺。

status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,//普通Layer
        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer) {
    ...
    *outLayer = new Layer(this, client, name, w, h, flags);//創(chuàng)建Layer
    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
    if (err == NO_ERROR) {
        *handle = (*outLayer)->getHandle();//初始化handle和gbp
        *gbp = (*outLayer)->getProducer();
    }
    return err;
}

創(chuàng)建普通層級(jí)Layer對(duì)象,Layer#getHandle與Layer#getProducer方法初始化handle凡傅、gbp指針辟狈,將Layer加入到Client中的map保存,

每個(gè)Layer對(duì)應(yīng)一個(gè)handle夏跷。

  • Layer#getHandle:handle是IBinder類(lèi)型哼转,創(chuàng)建服務(wù)進(jìn)程端Handle對(duì)象,在內(nèi)核為其創(chuàng)建服務(wù)節(jié)點(diǎn)槽华,客戶(hù)端拿到的handle是BpXxx壹蔓,handle是一個(gè)遠(yuǎn)程進(jìn)程連接到SF進(jìn)程的句柄。
  • Layer#getProducer:返回Layer的IGraphicBufferProducer猫态。IGraphicBufferProducer也是跨進(jìn)程通信的業(yè)務(wù)接口佣蓉,遠(yuǎn)程進(jìn)程拿到的是BpGraphicBufferProducer披摄,通過(guò)它操作圖形內(nèi)存區(qū)的。
  • SF進(jìn)程通過(guò)reply的writeStrongBinder方法寫(xiě)入勇凭,遠(yuǎn)程進(jìn)程通過(guò)readStrongBinder讀取疚膊。

底層Surface

Surface#copyFrom方法。

public void copyFrom(SurfaceControl other) {
    ...
    //底層SurfaceControl指針
    long surfaceControlPtr = other.mNativeObject;
    ...
    long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
    synchronized (mLock) {
        if (mNativeObject != 0) {
            nativeRelease(mNativeObject);//釋放原底層Surface指針
        }
        setNativeObjectLocked(newNativeObject);
    }
}

JNI#方法利用底層SurfaceControl創(chuàng)建底層Surface虾标。
底層SurfaceControl#getSurface方法寓盗。

sp<Surface> SurfaceControl::getSurface() const {
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == 0) { 
        mSurfaceData = new Surface(mGraphicBufferProducer, false);
    }
    return mSurfaceData;
}

底層Surface創(chuàng)建,封裝GraphicBufferProducer指針璧函。

Wms服務(wù)初始化Surface傀蚌,App進(jìn)程通過(guò)Surface操作圖形緩沖區(qū)。
GraphicBufferProducer是生產(chǎn)者柳譬。


任重而道遠(yuǎn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喳张,一起剝皮案震驚了整個(gè)濱河市续镇,隨后出現(xiàn)的幾起案子美澳,更是在濱河造成了極大的恐慌,老刑警劉巖摸航,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件制跟,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡酱虎,警方通過(guò)查閱死者的電腦和手機(jī)雨膨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)读串,“玉大人聊记,你說(shuō)我怎么就攤上這事』峙” “怎么了排监?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)杰捂。 經(jīng)常有香客問(wèn)我舆床,道長(zhǎng),這世上最難降的妖魔是什么嫁佳? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任挨队,我火速辦了婚禮,結(jié)果婚禮上蒿往,老公的妹妹穿的比我還像新娘盛垦。我一直安慰自己,他們只是感情好瓤漏,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布腾夯。 她就那樣靜靜地躺著省撑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪俯在。 梳的紋絲不亂的頭發(fā)上竟秫,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音跷乐,去河邊找鬼肥败。 笑死,一個(gè)胖子當(dāng)著我的面吹牛愕提,可吹牛的內(nèi)容都是我干的馒稍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼浅侨,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼纽谒!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起如输,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鼓黔,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后不见,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體澳化,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年稳吮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缎谷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡灶似,死狀恐怖列林,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情酪惭,我是刑警寧澤希痴,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站撞蚕,受9級(jí)特大地震影響润梯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜甥厦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一纺铭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧刀疙,春花似錦舶赔、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)撵溃。三九已至,卻和暖如春锥累,著一層夾襖步出監(jiān)牢的瞬間缘挑,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工桶略, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留语淘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓际歼,卻偏偏與公主長(zhǎng)得像惶翻,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鹅心,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容