//frameworks/base/core/java/android/view/Surface.javasp<IGraphicBufferProducer>mGraphicBufferProducer;classSurface:publicANativeObjectBase<ANativeWindow,Surface,RefBase>{intSurface::connect(intapi,constsp<IProducerListener>&listener,boolreportBufferRemoval){ATRACE_CALL();ALOGV("Surface::connect");Mutex::Autolocklock(mMutex);IGraphicBufferProducer::QueueBufferOutputoutput;mReportRemovedBuffers=reportBufferRemoval;interr=mGraphicBufferProducer->connect(listener,api,mProducerControlledByApp,&output);if(err==NO_ERROR){mDefaultWidth=output.width;mDefaultHeight=output.height;mNextFrameNumber=output.nextFrameNumber;mMaxBufferCount=output.maxBufferCount;// Ignore transform hint if sticky transform is set or transform to display inverse flag is// set. Transform hint should be ignored if the client is expected to always submit buffers// in the same orientation.if(mStickyTransform==0&&!transformToDisplayInverse()){mTransformHint=output.transformHint;}mConsumerRunningBehind=(output.numPendingBuffers>=2);}if(!err&&api==NATIVE_WINDOW_API_CPU){mConnectedToCpu=true;// Clear the dirty region in case we're switching from a non-CPU APImDirtyRegion.clear();}elseif(!err){// Initialize the dirty region for tracking surface damagemDirtyRegion=Region::INVALID_REGION;}returnerr;}}
//frameworks/native/libs/gui/BufferQueueProducer.cpp
classBufferQueueProducer:publicBnGraphicBufferProducer,privateIBinder::DeathRecipient{sp<BufferQueueCore>mCore;status_tBufferQueueProducer::connect(constsp<IProducerListener>&listener,intapi,boolproducerControlledByApp,QueueBufferOutput*output){ATRACE_CALL();std::lock_guard<std::mutex>lock(mCore->mMutex);mConsumerName=mCore->mConsumerName;BQ_LOGV("connect: api=%d producerControlledByApp=%s",api,producerControlledByApp?"true":"false");if(mCore->mIsAbandoned){BQ_LOGE("connect: BufferQueue has been abandoned");returnNO_INIT;}if(mCore->mConsumerListener==nullptr){BQ_LOGE("connect: BufferQueue has no consumer");returnNO_INIT;}if(output==nullptr){BQ_LOGE("connect: output was NULL");returnBAD_VALUE;}//如果已经连接过,就不允许再链接。也就是BufferQueueCore只允许由一个connected producer
if(mCore->mConnectedApi!=BufferQueueCore::NO_CONNECTED_API){BQ_LOGE("connect: already connected (cur=%d req=%d)",mCore->mConnectedApi,api);returnBAD_VALUE;}intdelta=mCore->getMaxBufferCountLocked(mCore->mAsyncMode,mDequeueTimeout<0?mCore->mConsumerControlledByApp&&producerControlledByApp:false,mCore->mMaxBufferCount)-mCore->getMaxBufferCountLocked();if(!mCore->adjustAvailableSlotsLocked(delta)){BQ_LOGE("connect: BufferQueue failed to adjust the number of available ""slots. Delta = %d",delta);returnBAD_VALUE;}intstatus=NO_ERROR;switch(api){caseNATIVE_WINDOW_API_EGL:caseNATIVE_WINDOW_API_CPU:caseNATIVE_WINDOW_API_MEDIA:caseNATIVE_WINDOW_API_CAMERA:mCore->mConnectedApi=api;output->width=mCore->mDefaultWidth;output->height=mCore->mDefaultHeight;output->transformHint=mCore->mTransformHintInUse=mCore->mTransformHint;output->numPendingBuffers=static_cast<uint32_t>(mCore->mQueue.size());output->nextFrameNumber=mCore->mFrameCounter+1;output->bufferReplaced=false;output->maxBufferCount=mCore->mMaxBufferCount;if(listener!=nullptr){// Set up a death notification so that we can disconnect
// automatically if the remote producer dies
#ifndef NO_BINDER
if(IInterface::asBinder(listener)->remoteBinder()!=nullptr){status=IInterface::asBinder(listener)->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));if(status!=NO_ERROR){BQ_LOGE("connect: linkToDeath failed: %s (%d)",strerror(-status),status);}mCore->mLinkedToDeath=listener;}#endif
mCore->mConnectedProducerListener=listener;mCore->mBufferReleasedCbEnabled=listener->needsReleaseNotify();}break;default:BQ_LOGE("connect: unknown API %d",api);status=BAD_VALUE;break;}mCore->mConnectedPid=BufferQueueThreadState::getCallingPid();mCore->mBufferHasBeenQueued=false;mCore->mDequeueBufferCannotBlock=false;mCore->mQueueBufferCanDrop=false;mCore->mLegacyBufferDrop=true;if(mCore->mConsumerControlledByApp&&producerControlledByApp){mCore->mDequeueBufferCannotBlock=mDequeueTimeout<0;mCore->mQueueBufferCanDrop=mDequeueTimeout<=0;}mCore->mAllowAllocation=true;VALIDATE_CONSISTENCY();returnstatus;}}