Android Camera数据流分析全程记录(overlay方式)
这篇文章接着上一篇文章继续: http://blog.chinaunix.net/uid-26765074-id-3568436.html
上一篇文章overlay这个过程已经走了一遍,但是根本是这个流程还没有走完,由上一篇文章知道,最后调用了postFrame方法, postFrame这个方法都实现了什么样的功能呢???他是怎样是的从driver获得的数据最终显示成图像的呢??
这个问题我一直在寻求答案,不过很悲催啊??这个postFrame方法我始终没有理解清楚,这里有多少说多少自己的看法,希望有大神能指点指点
这里就从postFrame入手了:

  1. status_t ANativeWindowDisplayAdapter::PostFrame(ANativeWindowDisplayAdapter::DisplayFrame&dispFrame)
  2. {
  3. status_t ret=NO_ERROR;
  4. uint32_t actualFramesWithDisplay=0;
  5. android_native_buffer_t*buffer=NULL;
  6. GraphicBufferMapper&mapper=GraphicBufferMapper::get();
  7. inti;

  8. ///@todoDocropping basedonthe stabilized frame coordinates
  9. ///@todo Insert logictodrop frames here basedonrefresh rate of
  10. ///displayorrendering rate whicheverislower
  11. ///Queue the buffertooverlay

  12. if(NULL==mANativeWindow){
  13. return NO_INIT;
  14. }

  15. if(!mBuffers||!dispFrame.mBuffer){
  16. CAMHAL_LOGEA("NULL sent to PostFrame");
  17. return BAD_VALUE;
  18. }

  19. for(i=0;i<mBufferCount;i++)
  20. {
  21. if(dispFrame.mBuffer==&mBuffers[i])
  22. {
  23. break;
  24. }
  25. }


  26. mFramesType.add((int)mBuffers[i].opaque,dispFrame.mType);

  27. if(mDisplayState==ANativeWindowDisplayAdapter::DISPLAY_STARTED&&
  28. (!mPaused||CameraFrame::CameraFrame::SNAPSHOT_FRAME==dispFrame.mType)&&
  29. !mSuspend)
  30. {
  31. Mutex::Autolock lock(mLock);
  32. uint32_t xOff=(dispFrame.mOffset%PAGE_SIZE);
  33. uint32_t yOff=(dispFrame.mOffset/PAGE_SIZE);

  34. //Setcrop onlyifcurrent xandy offsetsdonotmatch with frame offsets
  35. if((mXOff!=xOff)||(mYOff!=yOff))
  36. {
  37. CAMHAL_LOGDB("Offset %d xOff = %d, yOff = %d",dispFrame.mOffset,xOff,yOff);
  38. uint8_t bytesPerPixel;
  39. ///Calculate bytes per pixel basedonthe pixel format
  40. if(strcmp(mPixelFormat,(constchar*)CameraParameters::PIXEL_FORMAT_YUV422I)==0)
  41. {
  42. bytesPerPixel=2;
  43. }
  44. elseif(strcmp(mPixelFormat,(constchar*)CameraParameters::PIXEL_FORMAT_RGB565)==0)
  45. {
  46. bytesPerPixel=2;
  47. }
  48. elseif(strcmp(mPixelFormat,(constchar*)CameraParameters::PIXEL_FORMAT_YUV420SP)==0)
  49. {
  50. bytesPerPixel=1;
  51. }
  52. else
  53. {
  54. bytesPerPixel=1;
  55. }

  56. CAMHAL_LOGVB(" crop.left = %d crop.top = %d crop.right = %d crop.bottom = %d",
  57. xOff/bytesPerPixel,yOff,(xOff/bytesPerPixel)+mPreviewWidth,yOff+mPreviewHeight);
  58. //We'll ignore any errors here,ifthe surfaceis
  59. //already invalid,we'll know soon enough.
  60. mANativeWindow->set_crop(mANativeWindow,xOff/bytesPerPixel,yOff,
  61. (xOff/bytesPerPixel)+mPreviewWidth,yOff+mPreviewHeight);

  62. ///Update the current xandy offsets
  63. mXOff=xOff;
  64. mYOff=yOff;
  65. }
  66. //这里说说自己对以上代码的理解,上面通过传入的displayFrame类型变量check,传入的配置是否与系统此时实际显示属性一致,不一致,则从新进行裁剪,配置显示大小,位置等
  67. {
  68. buffer_handle_t*handle=(buffer_handle_t*)mBuffers[i].opaque;
  69. //unlock buffer before sendingtodisplay
  70. mapper.unlock(*handle);
  71. ret=mANativeWindow->enqueue_buffer(mANativeWindow,handle);//这里将buffer入栈,下面会分析道这个函数的由来
  72. }
  73. if(NO_ERROR!=ret){
  74. CAMHAL_LOGE("Surface::queueBuffer returned error %d",ret);
  75. }

  76. mFramesWithCameraAdapterMap.removeItem((buffer_handle_t*)dispFrame.mBuffer->opaque);


  77. //HWComposer hasnotminimum buffer requirement.We should be abletodequeue
  78. //the buffer immediately
  79. TIUTILS::Message msg;
  80. mDisplayQ.put(&msg);


  81. #ifPPM_INSTRUMENTATION||PPM_INSTRUMENTATION_ABS

  82. if(mMeasureStandby)
  83. {
  84. CameraHal::PPM("Standby to first shot: Sensor Change completed - ",&mStandbyToShot);
  85. mMeasureStandby=false;
  86. }
  87. elseif(CameraFrame::CameraFrame::SNAPSHOT_FRAME==dispFrame.mType)
  88. {
  89. CameraHal::PPM("Shot to snapshot: ",&mStartCapture);
  90. mShotToShot=true;
  91. }
  92. elseif(mShotToShot)
  93. {
  94. CameraHal::PPM("Shot to shot: ",&mStartCapture);
  95. mShotToShot=false;
  96. }
  97. #endif

  98. }
  99. else
  100. {
  101. Mutex::Autolock lock(mLock);
  102. buffer_handle_t*handle=(buffer_handle_t*)mBuffers[i].opaque;

  103. //unlock buffer before giving it up
  104. mapper.unlock(*handle);

  105. //cancel bufferanddequeue another one
  106. ret=mANativeWindow->cancel_buffer(mANativeWindow,handle);
  107. if(NO_ERROR!=ret){
  108. CAMHAL_LOGE("Surface::cancelBuffer returned error %d",ret);
  109. }

  110. mFramesWithCameraAdapterMap.removeItem((buffer_handle_t*)dispFrame.mBuffer->opaque);

  111. TIUTILS::Message msg;
  112. mDisplayQ.put(&msg);
  113. ret=NO_ERROR;
  114. }

  115. return ret;
  116. }
我们还是着重分析一下这个方法吧: mANativeWindow - > enqueue_buffer ( mANativeWindow , handle )
首先要找的mANativewindow这个变量类型的定义,找了好久才找到的,悲催:system\core\include\system\Window.h
  1. struct ANativeWindow
  2. {
  3. #ifdef __cplusplus
  4. ANativeWindow()
  5. :flags(0),minSwapInterval(0),maxSwapInterval(0),xdpi(0),ydpi(0)
  6. {
  7. common.magic=ANDROID_NATIVE_WINDOW_MAGIC;
  8. common.version=sizeof(ANativeWindow);
  9. memset(common.reserved,0,sizeof(common.reserved));
  10. }

  11. /*Implement the methods that sp<ANativeWindow>expects so that it
  12. can be usedtoautomatically refcount ANativeWindow's.*/
  13. void incStrong(constvoid*id)const{
  14. common.incRef(const_cast<android_native_base_t*>(&common));
  15. }
  16. void decStrong(constvoid*id)const{
  17. common.decRef(const_cast<android_native_base_t*>(&common));
  18. }
  19. #endif

  20. struct android_native_base_t common;

  21. /*flags describing some attributes of this surfaceorits updater*/
  22. constuint32_t flags;

  23. /*min swap interval supported by this updated*/
  24. constintminSwapInterval;

  25. /*max swap interval supported by this updated*/
  26. constintmaxSwapInterval;

  27. /*horizontalandvertical resolutioninDPI*/
  28. constfloat xdpi;
  29. constfloat ydpi;

  30. /*Some storage reservedforthe OEM's driver.*/
  31. intptr_t oem[4];

  32. /*
  33. *Setthe swap intervalforthis surface.
  34. *
  35. *Returns 0onsuccessor-errnoonerror.
  36. */
  37. int(*setSwapInterval)(struct ANativeWindow*window,intinterval);

  38. /*
  39. *hook called by EGLtoacquire a buffer.After thiscall,the buffer
  40. *isnotlocked,so its content cannot be modified.
  41. *thiscallmay blockifno buffers are available.
  42. *
  43. *Returns 0onsuccessor-errnoonerror.
  44. */
  45. int(*dequeueBuffer)(struct ANativeWindow*window,struct ANativeWindowBuffer**buffer);

  46. /*
  47. *hook called by EGLtolock a buffer.This MUST be called before modifying
  48. *the content of a buffer.The buffer must have been acquired with
  49. *dequeueBuffer first.
  50. *
  51. *Returns 0onsuccessor-errnoonerror.
  52. */
  53. int(*lockBuffer)(struct ANativeWindow*window,struct ANativeWindowBuffer*buffer);
  54. /*
  55. *hook called by EGL when modificationstothe render buffer are done.
  56. *This unlocksandpost the buffer.
  57. *
  58. *Buffers MUST be queuedinthe same order than they were dequeued.
  59. *
  60. *Returns 0onsuccessor-errnoonerror.
  61. */
  62. int(*queueBuffer)(struct ANativeWindow*window,struct ANativeWindowBuffer*buffer);

  63. /*
  64. *hook usedtoretrieve information about the nativewindow.
  65. *
  66. *Returns 0onsuccessor-errnoonerror.
  67. */
  68. int(*query)(conststruct ANativeWindow*window,intwhat,int*value);

  69. /*
  70. *hook usedtoperform various operationsonthe surface.
  71. *(*perform)()isa generic mechanismtoadd functionalityto
  72. *ANativeWindowwhilekeeping backward binary compatibility.
  73. *
  74. *DONOTCALLTHIS HOOK DIRECTLY.Instead,use the helper functions
  75. *defined below.
  76. *
  77. *(*perform)()returns-ENOENTifthe'what'parameterisnotsupported
  78. *by the surface's implementation.
  79. *
  80. *The valid operations are:
  81. *NATIVE_WINDOW_SET_USAGE
  82. *NATIVE_WINDOW_CONNECT(deprecated)
  83. *NATIVE_WINDOW_DISCONNECT(deprecated)
  84. *NATIVE_WINDOW_SET_CROP
  85. *NATIVE_WINDOW_SET_BUFFER_COUNT
  86. *NATIVE_WINDOW_SET_BUFFERS_GEOMETRY(deprecated)
  87. *NATIVE_WINDOW_SET_BUFFERS_TRANSFORM
  88. *NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP
  89. *NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS
  90. *NATIVE_WINDOW_SET_BUFFERS_FORMAT
  91. *NATIVE_WINDOW_SET_SCALING_MODE
  92. *NATIVE_WINDOW_LOCK(private)
  93. *NATIVE_WINDOW_UNLOCK_AND_POST(private)
  94. *NATIVE_WINDOW_API_CONNECT(private)
  95. *NATIVE_WINDOW_API_DISCONNECT(private)
  96. *
  97. */

  98. int(*perform)(struct ANativeWindow*window,intoperation,...);

  99. /*
  100. *hook usedtocancel a buffer that has been dequeued.
  101. *No synchronizationisperformed between dequeue()andcancel(),so
  102. *either external synchronizationisneeded,orthese functions must be
  103. *called from the same thread.
  104. */
  105. int(*cancelBuffer)(struct ANativeWindow*window,struct ANativeWindowBuffer*buffer);


  106. void*reserved_proc[2];
  107. };
既然上面调用了这个对象的方法,那么必然你要找到他的方法是在什么地方实现的,怎么实现的
我们首先看看 mANativewindow到底前身是什么,我们调用的这个方法到底是在哪里实现的,首先我们看一下他是从哪里引入进来的??
  1. intANativeWindowDisplayAdapter::setPreviewWindow(preview_stream_ops_t*window)
  2. {
  3. LOG_FUNCTION_NAME;
  4. ///Note that Display Adapter cannot work without a validwindowobject
  5. if(!window)
  6. {
  7. CAMHAL_LOGEA("NULL window object passed to DisplayAdapter");
  8. LOG_FUNCTION_NAME_EXIT;
  9. return BAD_VALUE;
  10. }

  11. if(window==mANativeWindow){
  12. return ALREADY_EXISTS;
  13. }

  14. ///Destroy the existingwindowobject,ifit exists
  15. destroy();

  16. ///Movetonewwindowobj
  17. mANativeWindow=window;

  18. LOG_FUNCTION_NAME_EXIT;

  19. return NO_ERROR;
  20. }
这个window参数最终要往上层追溯,我们这里直接说了,其实window的初始化定义在hardware interface那里,和camera service在一个目录下
  1. /**Setthe ANativeWindowtowhich preview frames are sent*/
  2. status_t setPreviewWindow(constsp<ANativeWindow>&buf)
  3. {
  4. LOGV("%s(%s) buf %p",__FUNCTION__,mName.string(),buf.get());

  5. if(mDevice->ops->set_preview_window){
  6. mPreviewWindow=buf;
  7. #ifdef OMAP_ENHANCEMENT_CPCAM
  8. mHalPreviewWindow.user=mPreviewWindow.get();
  9. #else
  10. mHalPreviewWindow.user=this;
  11. #endif
  12. LOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p",__FUNCTION__,
  13. &mHalPreviewWindow,mHalPreviewWindow.user);
  14. return mDevice->ops->set_preview_window(mDevice,buf.get()?&mHalPreviewWindow.nw:0);
  15. }
  16. return INVALID_OPERATION;
  17. }
上面我们看到,window通过mHalPreviewWindow传入到底层,我们还是要看看 mHalPreviewWindow这个变量的初始化和实现在哪里??
  1. status_t initialize(hw_module_t*module)
  2. {
  3. LOGI("Opening camera %s",mName.string());
  4. intrc=module->methods->open(module,mName.string(),
  5. (hw_device_t**)&mDevice);
  6. if(rc!=OK){
  7. LOGE("Could not open camera %s: %d",mName.string(),rc);
  8. return rc;
  9. }
  10. #ifdef OMAP_ENHANCEMENT_CPCAM
  11. initHalPreviewWindow(&mHalPreviewWindow);
  12. initHalPreviewWindow(&mHalTapin);
  13. initHalPreviewWindow(&mHalTapout);
  14. #else
  15. initHalPreviewWindow();
  16. #endif
  17. return rc;
  18. }
在最初打开camera的时候会调用上面initialize方法,通过initHalPreviewWindow这个方法实现mHalPrevieWindow的初始化以及hal层需要方法是实现
  1. void initHalPreviewWindow(struct camera_preview_window*window)
  2. {

  3. window->nw.cancel_buffer=__cancel_buffer;
  4. window->nw.lock_buffer=__lock_buffer;
  5. window->nw.dequeue_buffer=__dequeue_buffer;
  6. window->nw.enqueue_buffer=__enqueue_buffer;
  7. window->nw.set_buffer_count=__set_buffer_count;
  8. window->nw.set_buffers_geometry=__set_buffers_geometry;
  9. window->nw.set_crop=__set_crop;
  10. window->nw.set_metadata=__set_metadata;
  11. window->nw.set_usage=__set_usage;
  12. window->nw.set_swap_interval=__set_swap_interval;
  13. window->nw.update_and_get_buffer=__update_and_get_buffer;
  14. window->nw.get_metadata=__get_metadata;
  15. window->nw.get_buffer_dimension=__get_buffer_dimension;
  16. window->nw.get_buffer_format=__get_buffer_format;

  17. window->nw.get_min_undequeued_buffer_count=
  18. __get_min_undequeued_buffer_count;
  19. }
这里进行了填充,我们就看看cancel_buffer方法的实现吧

  1. staticint__cancel_buffer(struct preview_stream_ops*w,
  2. buffer_handle_t*buffer)
  3. {
  4. ANativeWindow*a=anw(w);
  5. returna->cancelBuffer(a,container_of(buffer,ANativeWindowBuffer,handle));
  6. }
这里只是作为一个转接点,没有做任何事情,而是直接去调用了其他实现了的方法实现操作
这里通过anm这个方法转换而来的ANativeWindow类型的变量a其实就是我们在上面initialize方式中初始化的 mPreviewWindow
而这个 mPreviewWindow就是上层传下来的的surface

这里是camera service层,个人认为是在这里对window这个参数进行了配置,连接api...还有其他的操作
  1. status_t CameraService::Client::setPreviewWindow(constsp<IBinder>&binder,
  2. constsp<ANativeWindow>&window){
  3. Mutex::Autolock lock(mLock);
  4. status_t result=checkPidAndHardware();
  5. if(result!=NO_ERROR)return result;

  6. //returnifno changeinsurface.
  7. if(binder==mSurface){
  8. return NO_ERROR;
  9. }

  10. if(window!=0){
  11. result=native_window_api_connect(window.get(),NATIVE_WINDOW_API_CAMERA);
  12. if(result!=NO_ERROR){
  13. LOGE("native_window_api_connect failed: %s (%d)",strerror(-result),
  14. result);
  15. return result;
  16. }
  17. }

  18. //Ifpreview has been already started,register preview buffersnow.
  19. if(mHardware->previewEnabled()){
  20. if(window!=0){
  21. native_window_set_scaling_mode(window.get(),NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
  22. native_window_set_buffers_transform(window.get(),mOrientation);
  23. result=mHardware->setPreviewWindow(window);
  24. }
  25. }

  26. if(result==NO_ERROR){
  27. //Everything has succeeded.Disconnect the oldwindowandremember the
  28. //newwindow.
  29. disconnectWindow(mPreviewWindow);
  30. mSurface=binder;
  31. mPreviewWindow=window;
  32. }else{
  33. //Something went wrong after we connectedtothe newwindow,so
  34. //disconnect here.
  35. disconnectWindow(window);
  36. }

  37. return result;
  38. }
这里我还是暂时不做说明吧,始终不是很理解这里为什么要这样做,一直以来上面调用的 cancelBuffer方法到底是在哪里实现的,这个问题纠结了我很久
这里先说说现在的想法,自己的理解, maybe wrong
这里跳度很大,看看下面的方法,来源:frameworks\base\libs\gui\SurfaceTextureClient.cpp
说的是 SurfaceTextureClient类的构造方法
  1. SurfaceTextureClient::SurfaceTextureClient(
  2. constsp<ISurfaceTexture>&surfaceTexture)
  3. {
  4. SurfaceTextureClient::init();
  5. SurfaceTextureClient::setISurfaceTexture(surfaceTexture);
  6. }
先看看init方法:

  1. void SurfaceTextureClient::init(){
  2. //Initialize the ANativeWindowfunctionpointers.
  3. ANativeWindow::setSwapInterval=hook_setSwapInterval;
  4. ANativeWindow::dequeueBuffer=hook_dequeueBuffer;
  5. ANativeWindow::cancelBuffer=hook_cancelBuffer;
  6. ANativeWindow::lockBuffer=hook_lockBuffer;
  7. ANativeWindow::queueBuffer=hook_queueBuffer;
  8. ANativeWindow::query=hook_query;
  9. ANativeWindow::perform=hook_perform;

  10. const_cast<int&>(ANativeWindow::minSwapInterval)=0;
  11. const_cast<int&>(ANativeWindow::maxSwapInterval)=1;

  12. mReqWidth=0;
  13. mReqHeight=0;
  14. mReqFormat=0;
  15. mReqUsage=0;
  16. mTimestamp=NATIVE_WINDOW_TIMESTAMP_AUTO;
  17. mDefaultWidth=0;
  18. mDefaultHeight=0;
  19. mTransformHint=0;
  20. mConnectedToCpu=false;
  21. }
重点是上面我标注出来的部分,就现在的理解,这里就是上面说的 cancelBuffer方法的归宿了,另外包括其他的所有方法,方法基本相同,这里为方便分析理解
我们以dequeueBuffer为例进行讲解,那就先看看 hook_dequeueBuffer的实现
  1. intSurfaceTextureClient::hook_dequeueBuffer(ANativeWindow*window,
  2. ANativeWindowBuffer**buffer){
  3. SurfaceTextureClient*c=getSelf(window);
  4. return c->dequeueBuffer(buffer);
  5. }
接着调用SurfaceTextureClient类的dequeueBuffer方法

  1. intSurfaceTextureClient::dequeueBuffer(android_native_buffer_t**buffer){
  2. LOGV("SurfaceTextureClient::dequeueBuffer");
  3. Mutex::Autolock lock(mMutex);
  4. intbuf=-1;
  5. status_t result=mSurfaceTexture->dequeueBuffer(&buf,mReqWidth,mReqHeight,mReqFormat,mReqUsage);
  6. if(result<0){
  7. LOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer(%d, %d, %d, %d)"
  8. "failed: %d",mReqWidth,mReqHeight,mReqFormat,mReqUsage,
  9. result);
  10. return result;
  11. }
  12. sp<GraphicBuffer>&gbuf(mSlots[buf]);
  13. if(result&ISurfaceTexture::RELEASE_ALL_BUFFERS){
  14. freeAllBuffers();
  15. }

  16. if((result&ISurfaceTexture::BUFFER_NEEDS_REALLOCATION)||gbuf==0){
  17. result=mSurfaceTexture->requestBuffer(buf,&gbuf);
  18. if(result!=NO_ERROR){
  19. LOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed: %d",
  20. result);
  21. return result;
  22. }
  23. }
  24. *buffer=gbuf.get();
  25. return OK;
  26. }
我们需要先找到mSurfaceTexture是在哪里定义的:system\media\mca\filterpacks\videosrc\java\CameraSource.java
private SurfaceTexture mSurfaceTexture;
接下来看看他是在哪里实例化的
  1. @Override
  2. publicvoid open(FilterContext context){
  3. if(mLogVerbose)Log.v(TAG,"Opening");
  4. //Open camera
  5. mCamera=Camera.open(mCameraId);

  6. //Setparameters
  7. getCameraParameters();
  8. mCamera.setParameters(mCameraParameters);

  9. //Create frame formats
  10. createFormats();

  11. //Bind ittoour camera frame
  12. mCameraFrame=(GLFrame)context.getFrameManager().newBoundFrame(mOutputFormat,
  13. GLFrame.EXTERNAL_TEXTURE,
  14. 0);
  15. mSurfaceTexture=new SurfaceTexture(mCameraFrame.getTextureId());
  16. try{
  17. mCamera.setPreviewTexture(mSurfaceTexture);
  18. }catch(IOException e){
  19. throw new RuntimeException("Could not bind camera surface texture: "+
  20. e.getMessage()+"!");
  21. }

  22. //Connect SurfaceTexturetocallback
  23. mSurfaceTexture.setOnFrameAvailableListener(onCameraFrameAvailableListener);
  24. //Start the preview
  25. mNewFrameAvailable=false;
  26. mCamera.startPreview();
  27. }
其他方法先不做过多分析,这里实例化了SurfaceTexture的对象,看看他的构造函数:frameworks\base\libs\gui\SurfaceTexture.cpp

  1. SurfaceTexture::SurfaceTexture(GLuint tex,bool allowSynchronousMode,
  2. GLenum texTarget):
  3. mDefaultWidth(1),
  4. mDefaultHeight(1),
  5. mPixelFormat(PIXEL_FORMAT_RGBA_8888),
  6. mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
  7. mClientBufferCount(0),
  8. mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
  9. mCurrentTexture(INVALID_BUFFER_SLOT),
  10. mCurrentTransform(0),
  11. mCurrentTimestamp(0),
  12. mNextTransform(0),
  13. mNextScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
  14. mTexName(tex),
  15. mSynchronousMode(false),
  16. mAllowSynchronousMode(allowSynchronousMode),
  17. mConnectedApi(NO_CONNECTED_API),
  18. mAbandoned(false),
  19. mTexTarget(texTarget){
  20. //Choose a name using the PIDanda process-unique ID.
  21. mName=String8::format("unnamed-%d-%d",getpid(),createProcessUniqueId());

  22. ST_LOGV("SurfaceTexture::SurfaceTexture");
  23. sp<ISurfaceComposer>composer(ComposerService::getComposerService());
  24. mGraphicBufferAlloc=composer->createGraphicBufferAlloc();
  25. mNextCrop.makeInvalid();
  26. memcpy(mCurrentTransformMatrix,mtxIdentity,
  27. sizeof(mCurrentTransformMatrix));
  28. }
我们接着往下看, mSurfaceTexture - > dequeueBuffer ( & buf , mReqWidth , mReqHeight , mReqFormat , mReqUsage ) ;
这里调用了类 SurfaceTexture的方法 dequeueBuffer

  1. status_t SurfaceTexture::dequeueBuffer(int*outBuf,uint32_t w,uint32_t h,
  2. uint32_t format,uint32_t usage){
  3. ST_LOGV("SurfaceTexture::dequeueBuffer");

  4. if((w&&!h)||(!w&&h)){
  5. ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u",w,h);
  6. return BAD_VALUE;
  7. }

  8. Mutex::Autolock lock(mMutex);

  9. status_t returnFlags(OK);

  10. intfound,foundSync;
  11. intdequeuedCount=0;
  12. bool tryAgain=true;
  13. while(tryAgain){
  14. if(mAbandoned){
  15. ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
  16. return NO_INIT;
  17. }

  18. //We needtowaitforthe FIFOtodrainifthe number of buffer
  19. //needstochange.
  20. //
  21. //The condition"number of buffers needs to change"istrueif
  22. //-the client doesn't care about how many buffers there are
  23. //-ANDthe actual number of bufferisdifferent from what was
  24. //setinthe last setBufferCountServer()
  25. //-OR-
  26. //setBufferCountServer()wassettoa value incompatible with
  27. //the synchronization mode(forinstance because the sync mode
  28. //changed since)
  29. //
  30. //As long as this conditionistrueANDthe FIFOisnotempty,we
  31. //waitonmDequeueCondition.

  32. constintminBufferCountNeeded=mSynchronousMode?
  33. MIN_SYNC_BUFFER_SLOTS:MIN_ASYNC_BUFFER_SLOTS;

  34. constbool numberOfBuffersNeedsToChange=!mClientBufferCount&&
  35. ((mServerBufferCount!=mBufferCount)||
  36. (mServerBufferCount<minBufferCountNeeded));

  37. if(!mQueue.isEmpty()&&numberOfBuffersNeedsToChange){
  38. //waitforthe FIFOtodrain
  39. mDequeueCondition.wait(mMutex);
  40. //NOTE:we continue here because we needtoreevaluate our
  41. //whole state(eg:we could be abandonedordisconnected)
  42. continue;
  43. }

  44. if(numberOfBuffersNeedsToChange){
  45. //here we're guaranteed that mQueueisempty
  46. freeAllBuffersLocked();
  47. mBufferCount=mServerBufferCount;
  48. if(mBufferCount<minBufferCountNeeded)
  49. mBufferCount=minBufferCountNeeded;
  50. mCurrentTexture=INVALID_BUFFER_SLOT;
  51. returnFlags|=ISurfaceTexture::RELEASE_ALL_BUFFERS;
  52. }

  53. //lookfora free buffertogivetothe client
  54. found=INVALID_BUFFER_SLOT;
  55. foundSync=INVALID_BUFFER_SLOT;
  56. dequeuedCount=0;
  57. for(inti=0;i<mBufferCount;i++){
  58. constintstate=mSlots[i].mBufferState;
  59. if(state==BufferSlot::DEQUEUED){
  60. dequeuedCount++;
  61. }

  62. //ifbufferisFREE it CANNOT be current
  63. LOGW_IF((state==BufferSlot::FREE)&&(mCurrentTexture==i),
  64. "dequeueBuffer: buffer %d is both FREE and current!",i);

  65. if(ALLOW_DEQUEUE_CURRENT_BUFFER){
  66. if(state==BufferSlot::FREE||i==mCurrentTexture){
  67. foundSync=i;
  68. if(i!=mCurrentTexture){
  69. found=i;
  70. break;
  71. }
  72. }
  73. }else{
  74. if(state==BufferSlot::FREE){
  75. foundSync=i;
  76. found=i;
  77. break;
  78. }
  79. }
  80. }

  81. //clients arenotallowedtodequeue more than one buffer
  82. //ifthey didn'tseta buffer count.
  83. if(!mClientBufferCount&&dequeuedCount){
  84. return-EINVAL;
  85. }

  86. //See whether a buffer has been queued since the last setBufferCount so
  87. //we know whethertoperform the MIN_UNDEQUEUED_BUFFERS check below.
  88. bool bufferHasBeenQueued=mCurrentTexture!=INVALID_BUFFER_SLOT;
  89. if(bufferHasBeenQueued){
  90. //make sure the clientisnottryingtodequeue more buffers
  91. //than allowed.
  92. constintavail=mBufferCount-(dequeuedCount+1);
  93. if(avail<(MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))){
  94. ST_LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded "
  95. "(dequeued=%d)",
  96. MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
  97. dequeuedCount);
  98. return-EBUSY;
  99. }
  100. }

  101. //we'reinsynchronous modeanddidn't find a buffer,we needtowait
  102. //forsome bufferstobe consumed
  103. tryAgain=mSynchronousMode&&(foundSync==INVALID_BUFFER_SLOT);
  104. if(tryAgain){
  105. mDequeueCondition.wait(mMutex);
  106. }
  107. }

  108. if(mSynchronousMode&&found==INVALID_BUFFER_SLOT){
  109. //foundSync guaranteedtobe!=INVALID_BUFFER_SLOT
  110. found=foundSync;
  111. }

  112. if(found==INVALID_BUFFER_SLOT){
  113. return-EBUSY;
  114. }

  115. constintbuf=found;
  116. *outBuf=found;

  117. constbool useDefaultSize=!w&&!h;
  118. if(useDefaultSize){
  119. //use the default size
  120. w=mDefaultWidth;
  121. h=mDefaultHeight;
  122. }

  123. constbool updateFormat=(format!=0);
  124. if(!updateFormat){
  125. //keep the current(ordefault)format
  126. format=mPixelFormat;
  127. }

  128. //bufferisnowinDEQUEUED(but can also be current at the sametime,
  129. //ifwe'reinsynchronous mode)
  130. mSlots[buf].mBufferState=BufferSlot::DEQUEUED;

  131. constsp<GraphicBuffer>&buffer(mSlots[buf].mGraphicBuffer);
  132. if((buffer==NULL)||
  133. (uint32_t(buffer->width)!=w)||
  134. (uint32_t(buffer->height)!=h)||
  135. (uint32_t(buffer->format)!=format)||
  136. ((uint32_t(buffer->usage)&usage)!=usage))
  137. {
  138. usage|=GraphicBuffer::USAGE_HW_TEXTURE;
  139. status_terror;
  140. sp<GraphicBuffer>graphicBuffer(
  141. mGraphicBufferAlloc->createGraphicBuffer(
  142. w,h,format,usage,&error));
  143. if(graphicBuffer==0){
  144. ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
  145. "failed");
  146. returnerror;
  147. }
  148. if(updateFormat){
  149. mPixelFormat=format;
  150. }
  151. mSlots[buf].mGraphicBuffer=graphicBuffer;
  152. mSlots[buf].mRequestBufferCalled=false;
  153. if(mSlots[buf].mEglImage!=EGL_NO_IMAGE_KHR){
  154. eglDestroyImageKHR(mSlots[buf].mEglDisplay,mSlots[buf].mEglImage);
  155. mSlots[buf].mEglImage=EGL_NO_IMAGE_KHR;
  156. mSlots[buf].mEglDisplay=EGL_NO_DISPLAY;
  157. }
  158. returnFlags|=ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
  159. }
  160. return returnFlags;
  161. }
到这里为止,其实底层调用的那些方法最终在这里都有实现,应该也已经走到了系统的ui层,本想到此为止,我还是深入看看这个方法吧
很纠结啊,看的

当已存在申请的buffer,返回buffer序号
在初始化SurfaceTexture对象时,上面的构造函数中实例化 mGraphicBufferAlloc = composer - > createGraphicBufferAlloc ( ) ;
createGraphicBufferAlloc的实现在以下路径:frameworks\base\libs\gui\ISurfaceComposer.cpp
  1. virtual sp<IGraphicBufferAlloc>createGraphicBufferAlloc()
  2. {
  3. uint32_t n;
  4. Parcel data,reply;
  5. data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
  6. remote()->transact(BnSurfaceComposer::CREATE_GRAPHIC_BUFFER_ALLOC,data,&reply);
  7. return interface_cast<IGraphicBufferAlloc>(reply.readStrongBinder());
  8. }
由上面接着他会调用 IGraphicBufferAlloc::createGraphicBuffer(),路径:frameworks\base\libs\gui\IGraphicBufferAlloc.cpp

  1. virtual sp<GraphicBuffer>createGraphicBuffer(uint32_t w,uint32_t h,
  2. PixelFormat format,uint32_t usage,status_t*error){
  3. Parcel data,reply;
  4. data.writeInterfaceToken(IGraphicBufferAlloc::getInterfaceDescriptor());
  5. data.writeInt32(w);
  6. data.writeInt32(h);
  7. data.writeInt32(format);
  8. data.writeInt32(usage);
  9. remote()->transact(CREATE_GRAPHIC_BUFFER,data,&reply);
  10. sp<GraphicBuffer>graphicBuffer;
  11. status_t result=reply.readInt32();
  12. if(result==NO_ERROR){
  13. graphicBuffer=new GraphicBuffer();
  14. reply.read(*graphicBuffer);
  15. //reply.readStrongBinder();
  16. //here we don't even havetoread the BufferReference from
  17. //the parcel,it'll die with the parcel.
  18. }
  19. *error=result;
  20. return graphicBuffer;
  21. }
这里实例化GraphicBuffer类的对象,并且用返回的这个对象实例化 graphicBuffer变量

这篇文章写得很吃力,不是理解的很透彻,其中可能很多思路根本就是错误的,待修正啊。。

待续。。。。

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. android jni方法模拟高频按键点击
  3. Android调用webservice接口
  4. Android电池驱动
  5. Android开发中的单元测试-初级教程(01)
  6. Android(安卓)Camera从App层到framework层到HAL层的初始化过程
  7. Android(安卓)SurfaceFlinger 学习之路(五)----VSync 工作原理
  8. EP28-DownloadManager分析(1)
  9. Android视图加载流程(3)之ViewRootImpl的UI刷新机制

随机推荐

  1. requestWindowFeature(Window.FEATURE_NO
  2. ant编译android工程用批处理打包
  3. Android之DatePickerDialog用法(日历的用
  4. Android(安卓)activity的生命周期
  5. android启动另一应用
  6. Android(安卓)修改WiFi热点的默认SSID和
  7. android 启动流程
  8. 自定义View
  9. service的隐式启动和显示启动
  10. Android(安卓)网络状态实时监测