編輯:Android開發教程
1.1.1 BufferQueue中的緩沖區分配
我們知道,BufferQueue中有一個mSlots數組用於管理其內的各緩沖區,最大容量為32。從它的聲明方式來看,這個mSlots在程序一開始就靜態分配了32個BufferSlot大小的空間。不過這並不代表緩沖區也是一次性靜態分配的,恰恰相反,從BufferSlot的內部變量指針mGraphicBuffer可以看出,緩沖區的空間分配應當是動態的(從下面的注釋也能看出一些端倪):
// mGraphicBuffer points to the buffer allocated for this slot or isNULL if no buffer has been allocated.
sp<GraphicBuffer> mGraphicBuffer;
現在的問題就轉移為,在什麼情況下會給一個Slot實際的分配空間呢?
首先能想到的就是dequeueBuffer。理由如下:
緩沖區的空間分配應該既要滿足使用者的需求,又要防止浪費。後面這一點mSlots已經滿足了,因為它並沒有采取一開始就靜態預分配的方式
既然Producer對buffer的操作是“主動”的,那麼就意味著它是整個需求的發起者。換句話說,只要它沒有dequeueBuffer,或者dequeueBuffer時能獲取到可用的緩沖區,那當然就沒有必要再重新分配空間了
來詳細分析下這個函數:
/*frameworks/native/libs/gui/BufferQueue.cpp*/
status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w,uint32_t h, uint32_t format, uint32_t usage) {…
status_t returnFlags(OK);
…
{ // Scope for the lock
Mutex::Autolocklock(mMutex); /*這裡采用了自動鎖,所以上面需要加個“{”,這樣當lock變量生
命期結束後鎖也就自動釋放了。這種寫法非常常見*/
…
int found = -1;
int foundSync = -1;
int dequeuedCount = 0;
bool tryAgain = true;
while (tryAgain) {/*Step1. 循環查找符合要求的slot*/
…
found = INVALID_BUFFER_SLOT;//初始值
foundSync =INVALID_BUFFER_SLOT;
dequeuedCount = 0;
for (int i = 0; i< mBufferCount; i++) {
const intstate = mSlots[i].mBufferState;
/*Step2.統計dequeued buffer數量,後面會用到*/
if (state ==BufferSlot::DEQUEUED) {
dequeuedCount++;
}
if (false) {
//肯定不會走這邊
} else {
if (state== BufferSlot::FREE) { /*Step3.尋找符合要求的Slot*/
boolisOlder = mSlots[i].mFrameNumber <mSlots[found].mFrameNumber;
if(found < 0 || isOlder) {
foundSync = i;
found = i; //找到符合要求的Slot
}
}// if (state ==BufferSlot::FREE)結束
}//if(false)else結束
}// for循環結束
/*Step4.如果Client沒有設置buffer count的話,就不允許dequeue一個以上的buffer*/
if(!mClientBufferCount && dequeuedCount) {
ST_LOGE("dequeueBuffer:can't dequeue multiple buffers without setting the buffer count");
return-EINVAL;
}
…
/*Step5. 判斷是否要重試*/
tryAgain = found== INVALID_BUFFER_SLOT;
if (tryAgain) {
mDequeueCondition.wait(mMutex);
}
}//while循環結束
if (found ==INVALID_BUFFER_SLOT) {
/*因為前面while循環如果沒找到的話是不會返回的,所以理論上不會出現這種情況*/
ST_LOGE("dequeueBuffer: no available buffer slots");
return -EBUSY;
}
const int buf = found;
*outBuf = found; //返回值
/*成功找到可用的Slot序號,接下來就開始對這個指定的Slot進行初始操作,及狀態變遷等*/
…
Remote Service Controller 和使用Local Service的Android ApiDemo示例解析(40):App->Service-&g
近年來,互聯網電視開始火熱,樂視TV,小米TV,最近愛奇藝也在大肆的招人做愛奇藝電視,當然還有更被關注的蘋果電視。其實,這個趨勢很正常,也很合理,傳統單純的接收電視節目的
博主思來想去,覺得還是想把這個教程寫的再細一點,讓讀者能夠更清楚的了解LibGDX這個游戲引擎整體 的架構,所以也就總結出了這樣一篇文章。一、模塊概述作為游戲開發人員,我
我們已經了解了如何在自己的單個應用中調用activity。但是,android開發中比較重要的一點,就是使 用intent調用其他應用的activity。特別地,你的應用