Android SurfaceTexture簡析

簡介

最近工作中接觸到SurfaceTexture诫钓,因此打算分析一下SurfaceTexture的原理赋咽,提到SurfaceTexture一般會(huì)提到與它相關(guān)的SurfaceView、GLSurfaceView芹扭、TextureView麻顶,這幾個(gè)都可以將圖形生產(chǎn)者的數(shù)據(jù)(比如Camera)送到SurfaceFlinger中顯示,而SurfaceTexture可以看做Surface和Texture的組合舱卡,是將圖形生產(chǎn)者的數(shù)據(jù)送到Texture辅肾,然后是由應(yīng)用程序自己來處理。這里的Texture應(yīng)該是屬于opengl的概念轮锥,由于本人對這塊不熟矫钓,等后續(xù)熟悉了再來分析Texture吧。

調(diào)用流程

一般SurfaceTexture的調(diào)用流程如下所示:

圖一

應(yīng)用程序會(huì)先創(chuàng)建一個(gè)SurfaceTexture舍杜,然后將SurfaceTexture傳遞給圖形生產(chǎn)者對象(比如Camera新娜,通過調(diào)用setPreviewTexture傳遞),圖形生產(chǎn)者對象生產(chǎn)一幀數(shù)據(jù)后既绩,會(huì)回調(diào)onFrameAvailable通知應(yīng)用程序有新的圖像數(shù)據(jù)可以使用杯活,應(yīng)用程序就可以調(diào)用updateTexImage將圖像數(shù)據(jù)先送到Texture,之后就可以調(diào)用opengl接口做些具體的業(yè)務(wù)了熬词。

下面說說具體的流程吧。

step1到step13

這幾個(gè)流程就是初始化SurfaceTexture吸重,在native層創(chuàng)建了BufferQueue互拾、GLConsumer、JNISurfaceTextureContext嚎幸,BufferQueue提供圖形生產(chǎn)者消費(fèi)者機(jī)制颜矿,具體內(nèi)容請見Android BufferQueue簡析,GLConsumer就是SurfaceTexture的圖形消費(fèi)者嫉晶,即通過調(diào)用opengl接口將圖形生產(chǎn)者的圖像數(shù)據(jù)送到Texture骑疆,JNISurfaceTextureContext是個(gè)簡單的代理對象,持有java層的SurfaceTexture對象替废,完成幀可用事件回調(diào)箍铭。

主要類的關(guān)系如下所示,綠色的為java層的SurfaceTexture對象椎镣,黃色的都是native層的對象诈火,可見SurfaceTexture功能基本都在native層實(shí)現(xiàn),java層的SurfaceTexture對象的mSurfaceTexture成員指向的是native層的GLConsumer對象状答,mProducer成員指向的是native層的BufferQueueProducer對象冷守,當(dāng)將SurfaceTexture對象傳給圖形生產(chǎn)者對象比如Camera時(shí)刀崖,就可以從該成員獲取到native層的BufferQueueProducer,用于生產(chǎn)者對象輸出拍摇。如下所示:

static void android_hardware_Camera_setPreviewTexture(JNIEnv *env,
        jobject thiz, jobject jSurfaceTexture)
{
    ALOGV("setPreviewTexture");
    sp<Camera> camera = get_native_camera(env, thiz, NULL);
    if (camera == 0) return;

    sp<IGraphicBufferProducer> producer = NULL;
    if (jSurfaceTexture != NULL) {
        producer = SurfaceTexture_getProducer(env, jSurfaceTexture);
        if (producer == NULL) {
            jniThrowException(env, "java/lang/IllegalArgumentException",
                    "SurfaceTexture already released in setPreviewTexture");
            return;
        }

    }

    if (camera->setPreviewTarget(producer) != NO_ERROR) {
        jniThrowException(env, "java/io/IOException",
                "setPreviewTexture failed");
    }
}

mFrameAvailableListener成員指向的是native層的JNISurfaceTextureContext對象亮钦,JNISurfaceTextureContext是OnFrameAvailableListener從native到j(luò)ava的跳板。

該類圖與Android BufferQueue簡析圖三的類圖很像充活,那張類圖說的是顯示流程中的主要類之間的關(guān)系蜂莉,可見SurfaceTexture和SurfaceView原理上基本相似,BufferQueue都是其核心堪唐,當(dāng)然也有一些不同的地方巡语,比如SurfaceTexture的BufferQueue是在應(yīng)用程序進(jìn)程這邊創(chuàng)建的,而SurfaceView對應(yīng)的BufferQueue是在SurfaceFlinger進(jìn)程創(chuàng)建的淮菠。

圖二

step14到step16

這幾個(gè)流程就是圖形生產(chǎn)者生產(chǎn)一幀數(shù)據(jù)后男公,通過BufferQueueCore層層調(diào)用,最后回調(diào)OnFrameAvailableListener的onFrameAvailable合陵,通知Listener有新的圖像數(shù)據(jù)可以使用枢赔,一般應(yīng)用程序會(huì)實(shí)現(xiàn)該Listener以接收通知。

step17到step35

這幾個(gè)流程就是從BufferQueueCore取出圖形生產(chǎn)者生產(chǎn)的幀數(shù)據(jù)GraphicBuffer拥知,然后調(diào)用opengl接口將GraphicBuffer更新到Texture上踏拜,等熟悉了opengl再來分析。

step36到step36

應(yīng)用程序一般還會(huì)根據(jù)需要調(diào)用getTransformMatrix低剔、getTimestamp獲取矩陣和時(shí)間戳信息速梗,這些信息是在調(diào)用updateTexImage時(shí)更新的。

通過以上分析襟齿,可見要理解SurfaceTexture的關(guān)鍵是要理解BufferQueue和opengl姻锁,BufferQueue已經(jīng)分析過了,opengl等后續(xù)熟悉了再抽空分析吧猜欺。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末位隶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子开皿,更是在濱河造成了極大的恐慌涧黄,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赋荆,死亡現(xiàn)場離奇詭異笋妥,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)窄潭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門挽鞠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事信认〔囊澹” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵嫁赏,是天一觀的道長其掂。 經(jīng)常有香客問我,道長潦蝇,這世上最難降的妖魔是什么款熬? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮攘乒,結(jié)果婚禮上贤牛,老公的妹妹穿的比我還像新娘。我一直安慰自己则酝,他們只是感情好殉簸,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著沽讹,像睡著了一般般卑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上爽雄,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天蝠检,我揣著相機(jī)與錄音,去河邊找鬼挚瘟。 笑死叹谁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的乘盖。 我是一名探鬼主播本慕,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼侧漓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起监氢,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤布蔗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后浪腐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纵揍,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年议街,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了泽谨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,566評論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖吧雹,靈堂內(nèi)的尸體忽然破棺而出骨杂,到底是詐尸還是另有隱情,我是刑警寧澤雄卷,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布搓蚪,位于F島的核電站,受9級特大地震影響丁鹉,放射性物質(zhì)發(fā)生泄漏妒潭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一揣钦、第九天 我趴在偏房一處隱蔽的房頂上張望雳灾。 院中可真熱鬧,春花似錦冯凹、人聲如沸谎亩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽团驱。三九已至,卻和暖如春空凸,著一層夾襖步出監(jiān)牢的瞬間嚎花,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工呀洲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留紊选,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓道逗,卻偏偏與公主長得像兵罢,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子滓窍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評論 2 348

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