Transaction是“事務”的意思。在我腦海中,關于事務的知識來自于數據庫。在數據庫操作中,事務意味著一次可以提交多個SQL語句,然后一個commit就可讓它們集中執行,而且數據庫中的事務還可以回滾,即恢復到事務提交前的狀態。
SurfaceFlinger為什么需要事務呢?從上面對數據庫事務的描述來看,是不是意味著一次執行多個請求呢?如直接盯著SF的源碼來分析,可能不太容易搞清楚事務的前因后果,我想還是用老辦法,從一個例子入手吧。
在WindowManagerService.java中,有一個函數之前分析過,現在再看看,代碼如下所示:
**WindowManagerService.java::WinState**
~~~
Surface createSurfaceLocked() {
Surface.openTransaction(); //開始一次transaction
try {
try {
mSurfaceX = mFrame.left + mXOffset;
mSurfaceY = mFrame.top + mYOffset;
//設置Surface的位置
mSurface.setPosition(mSurfaceX, mSurfaceY);
......
}
}finally {
Surface.closeTransaction(); //關閉這次事務
}
~~~
這個例子很好地展示了事務的調用流程,它會依次調用:
- openTransaction
- setPosition
- closeTransaction
下面就來分析這幾個函數的調用。
1. openTransaction的分析
看JNI對應的函數,代碼如下所示:
**android_View_Surface.cpp**
~~~
static void Surface_openTransaction(JNIEnv* env,jobject clazz)
{
//調用SurfaceComposerClient的openGlobalTransaction函數
SurfaceComposerClient::openGlobalTransaction();
}
~~~
下面轉到SurfaceComposerClient,代碼如下所示:
**SurfaceComposerClient.cpp**
~~~
voidSurfaceComposerClient::openGlobalTransaction()
{
Mutex::Autolock _l(gLock);
......
constsize_t N = gActiveConnections.size();
for(size_t i=0; i<N; i++) {
sp<SurfaceComposerClient>client(gActiveConnections.valueAt(i).promote());
//gOpenTransactions存儲當前提交事務請求的Client
if(client != 0 && gOpenTransactions.indexOf(client) < 0) {
//Client是保存在全局變量gActiveConnections中的SurfaceComposerClient
//對象,調用它的openTransaction。
if (client->openTransaction() == NO_ERROR) {
if (gOpenTransactions.add(client) < 0) {
client->closeTransaction();
}
}
......
}
}
}
~~~
上面是一個靜態函數,內部調用了各個SurfaceComposerClient對象的openTranscation,代碼如下所示:
**SurfaceComposerClient.cpp**
~~~
status_tSurfaceComposerClient::openTransaction()
{
if(mStatus != NO_ERROR)
return mStatus;
Mutex::Autolock _l(mLock);
mTransactionOpen++; //一個計數值,用來控制事務的提交。
if(mPrebuiltLayerState == 0) {
mPrebuiltLayerState = new layer_state_t;
}
returnNO_ERROR;
}
~~~
layer_state_t是用來保存Surface的一些信息的,比如位置、寬、高等信息。實際上,調用的setPosition等函數,就是為了改變這個layer_state_t中的值。
2. setPosition的分析
上文說過,SFC中有一個layer_state_t對象用來保存Surface的各種信息。這里以setPosition為例,來看它的使用情況。這個函數是用來改變surface在屏幕上的位置的,代碼如下所示:
**android_View_Surface.cpp**
~~~
static void Surface_setPosition(JNIEnv* env,jobject clazz, jint x, jint y)
{
constsp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
if(surface == 0) return;
status_t err = surface->setPosition(x, y);
}
~~~
**Surface.cpp**
~~~
status_t SurfaceControl::setPosition(int32_t x,int32_t y) {
constsp<SurfaceComposerClient>& client(mClient);
status_t err = validate();
if (err < 0) return err;
//調用SurfaceComposerClient的setPosition函數
returnclient->setPosition(mToken, x, y);
}
~~~
**SurfaceComposerClient.cpp**
~~~
status_tSurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y)
{
layer_state_t* s = _lockLayerState(id); //找到對應的layer_state_t
if(!s) return BAD_INDEX;
s->what |= ISurfaceComposer::ePositionChanged;
s->x = x;
s->y = y; //上面幾句修改了這塊layer的參數
_unlockLayerState(); //該函數將unlock一個同步對象,其他沒有做什么工作
returnNO_ERROR;
}
~~~
setPosition就是修改了layer_state_t中的一些參數,那么,這個狀態是什么時候傳遞到SurfaceFlinger中的呢?
3. 分析closeTransaction
相信讀者此時已明白為什么叫“事務”了。原來,在openTransaction和closeTransaction中可以有很多操作,然后由closeTransaction一次性地把這些修改提交到SF上,來看代碼:
**android_View_Surface.cpp**
~~~
static void Surface_closeTransaction(JNIEnv*env, jobject clazz)
{
SurfaceComposerClient::closeGlobalTransaction();
}
~~~
**SurfaceComposerClient.cpp**
~~~
voidSurfaceComposerClient::closeGlobalTransaction()
{
......
const size_t N = clients.size();
sp<ISurfaceComposer>sm(getComposerService());
//①先調用SF的openGlobalTransaction
sm->openGlobalTransaction();
for (size_t i=0; i<N; i++) {
//②然后調用每個SurfaceComposerClient對象的closeTransaction
clients[i]->closeTransaction();
}
//③最后調用SF的closeGlobalTransaction
sm->closeGlobalTransaction();
}
~~~
上面一共列出了三個函數,它們都是跨進程的調用,下面對其一一進行分析。
(1)SurfaceFlinger的openGlobalTransaction分析
這個函數其實很簡單,略看就行了。
**SurfaceFlinger.cpp**
~~~
void SurfaceFlinger::openGlobalTransaction()
{
android_atomic_inc(&mTransactionCount);//又是一個計數控制
}
~~~
(2)SurfaceComposerClient的closeTransaction分析
代碼如下所示:
**SurfaceComposerClient.cpp**
~~~
status_tSurfaceComposerClient::closeTransaction()
{
if(mStatus != NO_ERROR)
return mStatus;
Mutex::Autolock _l(mLock);
......
constssize_t count = mStates.size();
if (count) {
//mStates是這個SurfaceComposerClient中保存的所有layer_state_t數組,也就是
//每個Surface一個。然后調用跨進程的setState
mClient->setState(count, mStates.array());
mStates.clear();
}
returnNO_ERROR;
}
~~~
BClient的setState,最終會轉到SF的setClientState上,代碼如下所示:
**SurfaceFlinger.cpp**
~~~
status_t SurfaceFlinger::setClientState(ClientIDcid, int32_t count,
const layer_state_t*states)
{
Mutex::Autolock _l(mStateLock);
uint32_t flags = 0;
cid<<= 16;
for(int i=0 ; i<count ; i++) {
const layer_state_t& s = states[i];
sp<LayerBaseClient> layer(getLayerUser_l(s.surface | cid));
if(layer != 0) {
const uint32_t what = s.what;
if (what & ePositionChanged) {
if (layer->setPosition(s.x, s.y))
//eTraversalNeeded表示需要遍歷所有顯示層
flags |= eTraversalNeeded;
}
....
if(flags) {
setTransactionFlags(flags);//這里將會觸發threadLoop的事件。
}
returnNO_ERROR;
}
~~~
**SurfaceFlinger.cpp**
~~~
uint32_tSurfaceFlinger::setTransactionFlags(uint32_t flags, nsecs_t delay)
{
uint32_t old = android_atomic_or(flags, &mTransactionFlags);
if((old & flags)==0) {
if(delay > 0) {
signalDelayedEvent(delay);
}else {
signalEvent(); //設置完mTransactionFlags后,觸發事件。
}
}
returnold;
}
~~~
(3)SurfaceFlinger的closeGlobalTransaction分析
來看代碼:
**SurfaceFlinger.cpp**
~~~
void SurfaceFlinger::closeGlobalTransaction()
{
if (android_atomic_dec(&mTransactionCount) ==1) {
//注意下面語句的執行條件,當mTransactionCount變為零時才執行,這意味著
//openGlobalTransaction兩次的話,只有最后一個closeGlobalTransaction調用
//才會真正地提交事務
signalEvent();
Mutex::Autolock _l(mStateLock);
//如果這次事務涉及尺寸調整,則需要等一段時間
while (mResizeTransationPending) {
status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
if (CC_UNLIKELY(err != NO_ERROR)) {
mResizeTransationPending = false;
break;
}
}
}
}
~~~
關于事務的目的,相信讀者已經比較清楚了:
- 就是將一些控制操作(例如setPosition)的修改結果,一次性地傳遞給SF進行處理。
那么,哪些操作需要通過事務來傳遞呢?通過查看Surface.h可以知道,下面這些操作需要通過事務來傳遞(這里只列出了幾個經常用的函數):setPosition、setAlpha、show/hide、setSize、setFlag等。
由于這些修改不像重繪那么簡單,有時它會涉及其他的顯示層,例如在顯示層A的位置調整后,之前被A遮住的顯示層B,現在可能變得可見了。對于這種情況,所提交的事務會設置eTraversalNeeded標志,這個標志表示要遍歷所有顯示層進行處理。關于這一點,來看工作線程中的事務處理。
4. 工作線程中的事務處理
還是從代碼入手分析,如下所示:
**SurfaceFlinger.cpp**
~~~
bool SurfaceFlinger::threadLoop()
{
waitForEvent();
if(LIKELY(mTransactionCount == 0)) {
const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
uint32_ttransactionFlags = getTransactionFlags(mask);
if(LIKELY(transactionFlags)) {
handleTransaction(transactionFlags);
}
}
...
}
~~~
getTransactionFlags函數的實現蠻有意思,不妨看看其代碼,如下所示:
**SurfaceFlinger.cpp**
~~~
uint32_t SurfaceFlinger::getTransactionFlags(uint32_tflags)
{
//先通過原子操作去掉mTransactionFlags中對應的位。
//而后原子操作返回的舊值和flags進行與操作
return android_atomic_and(~flags,&mTransactionFlags) & flags;
}
~~~
getTransactionFlags所做的工作不僅僅是get那么簡單,它還設置了mTransactionFlags,從這個角度來看,getTransactionFlags這個名字有點名不副實。
接著來看最重要的handleTransaction函數,代碼如下所示:
**SurfaceFlinger.cpp**
~~~
void SurfaceFlinger::handleTransaction(uint32_ttransactionFlags)
{
Vector< sp<LayerBase> > ditchedLayers;
{
Mutex::Autolock _l(mStateLock);
//調用handleTransactionLocked函數處理
handleTransactionLocked(transactionFlags, ditchedLayers);
}
constsize_t count = ditchedLayers.size();
for(size_t i=0 ; i<count ; i++) {
if(ditchedLayers[i] != 0) {
//ditch是丟棄的意思,有些顯示層可能被hide了,所以這里做些收尾的工作
ditchedLayers[i]->ditch();
}
}
}
~~~
**SurfaceFlinger.cpp**
~~~
void SurfaceFlinger::handleTransactionLocked(
uint32_t transactionFlags, Vector< sp<LayerBase> >&ditchedLayers)
{
//這里使用了mCurrentState,它的layersSortedByZ數組存儲了SF中所有的顯示層
constLayerVector& currentLayers(mCurrentState.layersSortedByZ);
constsize_t count = currentLayers.size();
constbool layersNeedTransaction = transactionFlags & eTraversalNeeded;
//如果需要遍歷所有顯示的話。
if(layersNeedTransaction) {
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer = currentLayers[i];
uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
if (!trFlags) continue;
//調用各個顯示層的doTransaction函數。
constuint32_t flags = layer->doTransaction(0);
if (flags & Layer::eVisibleRegion)
mVisibleRegionsDirty = true;
}
}
if(transactionFlags & eTransactionNeeded) {
if(mCurrentState.orientation != mDrawingState.orientation) {
//橫豎屏如果發生切換,需要對應變換設置。
const int dpy = 0;
const int orientation = mCurrentState.orientation;
const uint32_t type = mCurrentState.orientationType;
GraphicPlane& plane(graphicPlane(dpy));
plane.setOrientation(orientation);
......
}
/*
mLayersRemoved變量在顯示層被移除的時候設置,例如removeLayer函數,這些函數
也會觸發handleTranscation函數的執行
*/
if(mLayersRemoved) {
mLayersRemoved = false;
mVisibleRegionsDirty = true;
const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
const size_t count = previousLayers.size();
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(previousLayers[i]);
if (currentLayers.indexOf( layer ) < 0) {
ditchedLayers.add(layer);
mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
}
}
}
free_resources_l();
}
//提交事務處理,有必要進去看看。
commitTransaction();
}
~~~
每個顯示層對事務的具體處理,都在它們的doTranscation函數中,讀者若有興趣,可進去看看。需要說明的是,每個顯示層內部也有一個狀態變量,doTransaction會更新這些狀態變量。
回到上面的函數,最后它將調用commitTransaction提交事務,代碼如下所示:
**SurfaceFlinger.cpp**
~~~
void SurfaceFlinger::commitTransaction()
{
//mDrawingState將使用更新后的mCurrentState
mDrawingState = mCurrentState;
mResizeTransationPending = false;
//觸發一個條件變量,這樣等待在closeGlobalTransaction函數中的線程可以放心地返回了。
mTransactionCV.broadcast();
}
~~~
- 前言
- 第1章 閱讀前的準備工作
- 1.1 系統架構
- 1.1.1 Android系統架構
- 1.1.2 本書的架構
- 1.2 搭建開發環境
- 1.2.1 下載源碼
- 1.2.2 編譯源碼
- 1.3 工具介紹
- 1.3.1 Source Insight介紹
- 1.3.2 Busybox的使用
- 1.4 本章小結
- 第2章 深入理解JNI
- 2.1 JNI概述
- 2.2 學習JNI的實例:MediaScanner
- 2.3 Java層的MediaScanner分析
- 2.3.1 加載JNI庫
- 2.3.2 Java的native函數和總結
- 2.4 JNI層MediaScanner的分析
- 2.4.1 注冊JNI函數
- 2.4.2 數據類型轉換
- 2.4.3 JNIEnv介紹
- 2.4.4 通過JNIEnv操作jobject
- 2.4.5 jstring介紹
- 2.4.6 JNI類型簽名介紹
- 2.4.7 垃圾回收
- 2.4.8 JNI中的異常處理
- 2.5 本章小結
- 第3章 深入理解init
- 3.1 概述
- 3.2 init分析
- 3.2.1 解析配置文件
- 3.2.2 解析service
- 3.2.3 init控制service
- 3.2.4 屬性服務
- 3.3 本章小結
- 第4章 深入理解zygote
- 4.1 概述
- 4.2 zygote分析
- 4.2.1 AppRuntime分析
- 4.2.2 Welcome to Java World
- 4.2.3 關于zygote的總結
- 4.3 SystemServer分析
- 4.3.1 SystemServer的誕生
- 4.3.2 SystemServer的重要使命
- 4.3.3 關于 SystemServer的總結
- 4.4 zygote的分裂
- 4.4.1 ActivityManagerService發送請求
- 4.4.2 有求必應之響應請求
- 4.4.3 關于zygote分裂的總結
- 4.5 拓展思考
- 4.5.1 虛擬機heapsize的限制
- 4.5.2 開機速度優化
- 4.5.3 Watchdog分析
- 4.6 本章小結
- 第5章 深入理解常見類
- 5.1 概述
- 5.2 以“三板斧”揭秘RefBase、sp和wp
- 5.2.1 第一板斧--初識影子對象
- 5.2.2 第二板斧--由弱生強
- 5.2.3 第三板斧--破解生死魔咒
- 5.2.4 輕量級的引用計數控制類LightRefBase
- 5.2.5 題外話-三板斧的來歷
- 5.3 Thread類及常用同步類分析
- 5.3.1 一個變量引發的思考
- 5.3.2 常用同步類
- 5.4 Looper和Handler類分析
- 5.4.1 Looper類分析
- 5.4.2 Handler分析
- 5.4.3 Looper和Handler的同步關系
- 5.4.4 HandlerThread介紹
- 5.5 本章小結
- 第6章 深入理解Binder
- 6.1 概述
- 6.2 庖丁解MediaServer
- 6.2.1 MediaServer的入口函數
- 6.2.2 獨一無二的ProcessState
- 6.2.3 時空穿越魔術-defaultServiceManager
- 6.2.4 注冊MediaPlayerService
- 6.2.5 秋風掃落葉-StartThread Pool和join Thread Pool分析
- 6.2.6 你徹底明白了嗎
- 6.3 服務總管ServiceManager
- 6.3.1 ServiceManager的原理
- 6.3.2 服務的注冊
- 6.3.3 ServiceManager存在的意義
- 6.4 MediaPlayerService和它的Client
- 6.4.1 查詢ServiceManager
- 6.4.2 子承父業
- 6.5 拓展思考
- 6.5.1 Binder和線程的關系
- 6.5.2 有人情味的訃告
- 6.5.3 匿名Service
- 6.6 學以致用
- 6.6.1 純Native的Service
- 6.6.2 扶得起的“阿斗”(aidl)
- 6.7 本章小結
- 第7章 深入理解Audio系統
- 7.1 概述
- 7.2 AudioTrack的破解
- 7.2.1 用例介紹
- 7.2.2 AudioTrack(Java空間)分析
- 7.2.3 AudioTrack(Native空間)分析
- 7.2.4 關于AudioTrack的總結
- 7.3 AudioFlinger的破解
- 7.3.1 AudioFlinger的誕生
- 7.3.2 通過流程分析AudioFlinger
- 7.3.3 audio_track_cblk_t分析
- 7.3.4 關于AudioFlinger的總結
- 7.4 AudioPolicyService的破解
- 7.4.1 AudioPolicyService的創建
- 7.4.2 重回AudioTrack
- 7.4.3 聲音路由切換實例分析
- 7.4.4 關于AudioPolicy的總結
- 7.5 拓展思考
- 7.5.1 DuplicatingThread破解
- 7.5.2 題外話
- 7.6 本章小結
- 第8章 深入理解Surface系統
- 8.1 概述
- 8.2 一個Activity的顯示
- 8.2.1 Activity的創建
- 8.2.2 Activity的UI繪制
- 8.2.3 關于Activity的總結
- 8.3 初識Surface
- 8.3.1 和Surface有關的流程總結
- 8.3.2 Surface之乾坤大挪移
- 8.3.3 乾坤大挪移的JNI層分析
- 8.3.4 Surface和畫圖
- 8.3.5 初識Surface小結
- 8.4 深入分析Surface
- 8.4.1 與Surface相關的基礎知識介紹
- 8.4.2 SurfaceComposerClient分析
- 8.4.3 SurfaceControl分析
- 8.4.4 writeToParcel和Surface對象的創建
- 8.4.5 lockCanvas和unlockCanvasAndPost分析
- 8.4.6 GraphicBuffer介紹
- 8.4.7 深入分析Surface的總結
- 8.5 SurfaceFlinger分析
- 8.5.1 SurfaceFlinger的誕生
- 8.5.2 SF工作線程分析
- 8.5.3 Transaction分析
- 8.5.4 關于SurfaceFlinger的總結
- 8.6 拓展思考
- 8.6.1 Surface系統的CB對象分析
- 8.6.2 ViewRoot的你問我答
- 8.6.3 LayerBuffer分析
- 8.7 本章小結
- 第9章 深入理解Vold和Rild
- 9.1 概述
- 9.2 Vold的原理與機制分析
- 9.2.1 Netlink和Uevent介紹
- 9.2.2 初識Vold
- 9.2.3 NetlinkManager模塊分析
- 9.2.4 VolumeManager模塊分析
- 9.2.5 CommandListener模塊分析
- 9.2.6 Vold實例分析
- 9.2.7 關于Vold的總結
- 9.3 Rild的原理與機制分析
- 9.3.1 初識Rild
- 9.3.2 RIL_startEventLoop分析
- 9.3.3 RIL_Init分析
- 9.3.4 RIL_register分析
- 9.3.5 關于Rild main函數的總結
- 9.3.6 Rild實例分析
- 9.3.7 關于Rild的總結
- 9.4 拓展思考
- 9.4.1 嵌入式系統的存儲知識介紹
- 9.4.2 Rild和Phone的改進探討
- 9.5 本章小結
- 第10章 深入理解MediaScanner
- 10.1 概述
- 10.2 android.process.media分析
- 10.2.1 MSR模塊分析
- 10.2.2 MSS模塊分析
- 10.2.3 android.process.media媒體掃描工作的流程總結
- 10.3 MediaScanner分析
- 10.3.1 Java層分析
- 10.3.2 JNI層分析
- 10.3.3 PVMediaScanner分析
- 10.3.4 關于MediaScanner的總結
- 10.4 拓展思考
- 10.4.1 MediaScannerConnection介紹
- 10.4.2 我問你答
- 10.5 本章小結