天天看點

android emulator虛拟裝置分析第五篇之pipe上的opengles一、概述二、opengles —— pipe上的另一個service三、使用host gpu

據說qemu的gpu的實作,運作起來非常慢。是以android emulator提供了一種use host gpu的方式,guest os可以使用host機器的opengl庫去畫圖,速度快很多。

guest os把畫圖的指令通過pipe傳遞給emulator(encode, send via pipe, decode),然後emulator将opengles的畫圖指令轉為opengl的畫圖指令(translate),并執行。

老規矩,看文檔,opengles是使用tcp實作的,tcp也是pipe service

<a target="_blank" href="http://androidxref.com/5.1.0_r1/xref/external/qemu/docs/ANDROID-QEMU-PIPE.TXT#306">ANDROID-QEMU-PIPE.TXT:306</a>

初始化代碼如下,初始化了opengles,tcp和unix三種

netPipe_initUnix or netPipe_initTcp建立了opengles pipe service和emulator中畫圖服務端的socket連接配接

netPipe_initUnix or netPipe_initTcp都會調用到netPipe_initFromAddress函數,裡面的loopIo_init和asyncConnector_init需要注意一下,大概意思是有個公用的循環,使用LoopIo把fd包裝起來,循環裡面會檢查哪些fd可讀,或者可寫,并且調用callback函數netPipe_io_func

netPipe_io_func是剛才那個callback函數,就是用來喚醒等待讀寫的線程的,如果未連接配接,那麼會先連接配接一下(connect)

通過/dev/qemu_pipe寫東西,最終會調用到netPipe_sendBuffers函數(evil switch in pipeConnector_sendBuffers),然後通過剛才建立的socket發送給畫圖服務端

從/dev/qemu_pipe讀東西,最終會調用到netPipe_recvBuffers函數(evil switch in pipeConnector_sendBuffers),然後通過剛才建立的socket從畫圖服務端接收資料

netPipe_poll調用loopIo_poll判斷是否POLLIN, POLLOUT

netPipe_wakeOn設定想等待什麼事件

老規矩,先看文檔,文檔在模拟器的repo中可以找到,我在android的repo裡面沒找到

重點看external/qemu/distrib/android-emugl/DESIGN

libEGL.so、libGLESv1_CM.so和libGLESv2.so是純軟體方面的通用的代碼,在模拟器上不需要任何特殊的處理

libEGL.so會根據egl.cfg的配置,dlopen幾個庫,在模拟器上是libEGL_emulation.so、libGLESv1_CM_emulation.so和libGLESv2_emulation.so,這幾個庫是硬體相關的

libEGL_emulation.so、libGLESv1_CM_emulation.so和libGLESv2_emulation.so對應了GUEST SYSTEM LIBRARIES,它們的函數最終都會通過&lt;function_name&gt;_enc進行encode,然後通過opengles pipe serice給到emulator,emulator再通過tcp socket發送給畫圖服務端,服務端的libOpenglRender.so使用幾個decode的庫去進行decode,然後分發給libEGL_translator.so、libGLES_CM_translator.so和libGLESv2_translator.so,它們将opengles的調用轉為opengl的調用,然後使用host系統的opengl庫去執行

qemu和ui是兩個不同的程序,ui裡面的是畫圖的服務端,qemu裡面的是socket client,也就是opengles pipe service中建立的socket連接配接。

再看看external/qemu/docs/GPU-EMULATION.TXT

繼續閱讀