//framework/native/libs/gui/Surface.cpp
sp<IGraphicBufferProducer>mGraphicBufferProducer;classSurface:publicANativeObjectBase<ANativeWindow,Surface,RefBase>{intSurface::dequeueBuffer(android_native_buffer_t**buffer,int*fenceFd){ATRACE_CALL();ALOGV("Surface::dequeueBuffer");IGraphicBufferProducer::DequeueBufferInputdqInput;{Mutex::Autolocklock(mMutex);if(mReportRemovedBuffers){mRemovedBuffers.clear();}getDequeueBufferInputLocked(&dqInput);if(mSharedBufferMode&&mAutoRefresh&&mSharedBufferSlot!=BufferItem::INVALID_BUFFER_SLOT){sp<GraphicBuffer>&gbuf(mSlots[mSharedBufferSlot].buffer);if(gbuf!=nullptr){*buffer=gbuf.get();*fenceFd=-1;returnOK;}}}// Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer
intbuf=-1;sp<Fence>fence;nsecs_tstartTime=systemTime();FrameEventHistoryDeltaframeTimestamps;//这里尝试去dequeueBuffer,因为这时SurfaceFlinger对应Layer的slot还没有分配buffer,这时SurfaceFlinger会回复的flag会有BUFFER_NEEDS_REALLOCATIO
status_tresult=mGraphicBufferProducer->dequeueBuffer(&buf,&fence,dqInput.width,dqInput.height,dqInput.format,dqInput.usage,&mBufferAge,dqInput.getTimestamps?&frameTimestamps:nullptr);mLastDequeueDuration=systemTime()-startTime;if(result<0){ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer""(%d, %d, %d, %#"PRIx64") failed: %d",dqInput.width,dqInput.height,dqInput.format,dqInput.usage,result);returnresult;}if(buf<0||buf>=NUM_BUFFER_SLOTS){ALOGE("dequeueBuffer: IGraphicBufferProducer returned invalid slot number %d",buf);android_errorWriteLog(0x534e4554,"36991414");// SafetyNet logging
returnFAILED_TRANSACTION;}Mutex::Autolocklock(mMutex);// Write this while holding the mutex
mLastDequeueStartTime=startTime;sp<GraphicBuffer>&gbuf(mSlots[buf].buffer);// this should never happen
ALOGE_IF(fence==nullptr,"Surface::dequeueBuffer: received null Fence! buf=%d",buf);if(CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))){staticFenceMonitorhwcReleaseThread("HWC release");hwcReleaseThread.queueFence(fence);}if(result&IGraphicBufferProducer::RELEASE_ALL_BUFFERS){freeAllBuffers();}if(dqInput.getTimestamps){mFrameEventHistory->applyDelta(frameTimestamps);}if((result&IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION)||gbuf==nullptr){if(mReportRemovedBuffers&&(gbuf!=nullptr)){mRemovedBuffers.push_back(gbuf);}//这里检查到dequeueBuffer返回的结果里带有BUFFER_NEEDS_REALLOCATION标志就会发出一次requestBuffer
result=mGraphicBufferProducer->requestBuffer(buf,&gbuf);if(result!=NO_ERROR){ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d",result);mGraphicBufferProducer->cancelBuffer(buf,fence);returnresult;}}if(fence->isValid()){*fenceFd=fence->dup();if(*fenceFd==-1){ALOGE("dequeueBuffer: error duping fence: %d",errno);// dup() should never fail; something is badly wrong. Soldier on
// and hope for the best; the worst that should happen is some
// visible corruption that lasts until the next frame.
}}else{*fenceFd=-1;}*buffer=gbuf.get();if(mSharedBufferMode&&mAutoRefresh){mSharedBufferSlot=buf;mSharedBufferHasBeenQueued=false;}elseif(mSharedBufferSlot==buf){mSharedBufferSlot=BufferItem::INVALID_BUFFER_SLOT;mSharedBufferHasBeenQueued=false;}mDequeuedSlots.insert(buf);returnOK;}}
//frameworks/native/libs/gui/IGraphicBufferProducer.cpp
classBpGraphicBufferProducer:publicBpInterface<IGraphicBufferProducer>{virtualstatus_tdequeueBuffer(int*buf,sp<Fence>*fence,uint32_twidth,uint32_theight,PixelFormatformat,uint64_tusage,uint64_t*outBufferAge,FrameEventHistoryDelta*outTimestamps){Parceldata,reply;boolgetFrameTimestamps=(outTimestamps!=nullptr);data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());data.writeUint32(width);data.writeUint32(height);data.writeInt32(static_cast<int32_t>(format));data.writeUint64(usage);data.writeBool(getFrameTimestamps);status_tresult=remote()->transact(DEQUEUE_BUFFER,data,&reply);if(result!=NO_ERROR){returnresult;}*buf=reply.readInt32();*fence=newFence();result=reply.read(**fence);if(result!=NO_ERROR){fence->clear();returnresult;}if(outBufferAge){result=reply.readUint64(outBufferAge);}else{// Read the value even if outBufferAge is nullptr:
uint64_tbufferAge;result=reply.readUint64(&bufferAge);}if(result!=NO_ERROR){ALOGE("IGBP::dequeueBuffer failed to read buffer age: %d",result);returnresult;}if(getFrameTimestamps){result=reply.read(*outTimestamps);if(result!=NO_ERROR){ALOGE("IGBP::dequeueBuffer failed to read timestamps: %d",result);returnresult;}}result=reply.readInt32();returnresult;}}
//frameworks/native/libs/gui/IGraphicBufferProducer.cpp
status_tBnGraphicBufferProducer::onTransact(uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags){switch(code){caseDEQUEUE_BUFFER:{CHECK_INTERFACE(IGraphicBufferProducer,data,reply);uint32_twidth=data.readUint32();uint32_theight=data.readUint32();PixelFormatformat=static_cast<PixelFormat>(data.readInt32());uint64_tusage=data.readUint64();uint64_tbufferAge=0;boolgetTimestamps=data.readBool();intbuf=0;sp<Fence>fence=Fence::NO_FENCE;FrameEventHistoryDeltaframeTimestamps;intresult=dequeueBuffer(&buf,&fence,width,height,format,usage,&bufferAge,getTimestamps?&frameTimestamps:nullptr);if(fence==nullptr){ALOGE("dequeueBuffer returned a NULL fence, setting to Fence::NO_FENCE");fence=Fence::NO_FENCE;}reply->writeInt32(buf);reply->write(*fence);reply->writeUint64(bufferAge);if(getTimestamps){reply->write(frameTimestamps);}reply->writeInt32(result);returnNO_ERROR;}}}
//frameworks/native/libs/gui/BufferQueueProducer.cpp
classBufferQueueProducer:publicBnGraphicBufferProducer{status_tBufferQueueProducer::requestBuffer(intslot,sp<GraphicBuffer>*buf){ATRACE_CALL();BQ_LOGV("requestBuffer: slot %d",slot);std::lock_guard<std::mutex>lock(mCore->mMutex);if(mCore->mIsAbandoned){BQ_LOGE("requestBuffer: BufferQueue has been abandoned");returnNO_INIT;}if(mCore->mConnectedApi==BufferQueueCore::NO_CONNECTED_API){BQ_LOGE("requestBuffer: BufferQueue has no connected producer");returnNO_INIT;}if(slot<0||slot>=BufferQueueDefs::NUM_BUFFER_SLOTS){BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)",slot,BufferQueueDefs::NUM_BUFFER_SLOTS);returnBAD_VALUE;}elseif(!mSlots[slot].mBufferState.isDequeued()){BQ_LOGE("requestBuffer: slot %d is not owned by the producer ""(state = %s)",slot,mSlots[slot].mBufferState.string());returnBAD_VALUE;}mSlots[slot].mRequestBufferCalled=true;*buf=mSlots[slot].mGraphicBuffer;returnNO_ERROR;}}