Chinaunix首页 | 论坛 | 博客
  • 博客访问: 51886
  • 博文数量: 50
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-30 20:59
文章分类

全部博文(50)

文章存档

2015年(9)

2014年(41)

我的朋友

分类: Android平台

2014-07-25 14:13:44

 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.     int i;

  8.     ///@todo Do cropping based on the stabilized frame coordinates
  9.     ///@todo Insert logic to drop frames here based on refresh rate of
  10.     ///display or rendering rate whichever is lower
  11.     ///Queue the buffer to overlay

  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.         // Set crop only if current x and y offsets do not match 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 based on the pixel format
  40.             if(strcmp(mPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0)
  41.                 {
  42.                 bytesPerPixel = 2;
  43.                 }
  44.             else if(strcmp(mPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0)
  45.                 {
  46.                 bytesPerPixel = 2;
  47.                 }
  48.             else if(strcmp(mPixelFormat, (const char *) 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, if the surface is
  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 x and y 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 sending to display
  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 has not minimum buffer requirement. We should be able to dequeue
  78.         // the buffer immediately
  79.         TIUTILS::Message msg;
  80.         mDisplayQ.put(&msg);


  81. #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS

  82.         if ( mMeasureStandby )
  83.             {
  84.             CameraHal::PPM("Standby to first shot: Sensor Change completed - ", &mStandbyToShot);
  85.             mMeasureStandby = false;
  86.             }
  87.         else if (CameraFrame::CameraFrame::SNAPSHOT_FRAME == dispFrame.mType)
  88.             {
  89.             CameraHal::PPM("Shot to snapshot: ", &mStartCapture);
  90.             mShotToShot = true;
  91.             }
  92.         else if ( 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 buffer and dequeue 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 used to automatically refcount ANativeWindow's. */
  13.     void incStrong(const void* id) const {
  14.         common.incRef(const_cast<android_native_base_t*>(&common));
  15.     }
  16.     void decStrong(const void* 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 surface or its updater */
  22.     const uint32_t flags;

  23.     /* min swap interval supported by this updated */
  24.     const int minSwapInterval;

  25.     /* max swap interval supported by this updated */
  26.     const int maxSwapInterval;

  27.     /* horizontal and vertical resolution in DPI */
  28.     const float xdpi;
  29.     const float ydpi;

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

  32.     /*
  33.      * Set the swap interval for this surface.
  34.      *
  35.      * Returns 0 on success or -errno on error.
  36.      */
  37.     int (*setSwapInterval)(struct ANativeWindow* window, int interval);

  38.     /*
  39.      * hook called by EGL to acquire a buffer. After this call, the buffer
  40.      * is not locked, so its content cannot be modified.
  41.      * this call may block if no buffers are available.
  42.      *
  43.      * Returns 0 on success or -errno on error.
  44.      */
  45.     int (*dequeueBuffer)(struct ANativeWindow* window, struct ANativeWindowBuffer** buffer);

  46.     /*
  47.      * hook called by EGL to lock 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 0 on success or -errno on error.
  52.      */
  53.     int (*lockBuffer)(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer);
  54.    /*
  55.     * hook called by EGL when modifications to the render buffer are done.
  56.     * This unlocks and post the buffer.
  57.     *
  58.     * Buffers MUST be queued in the same order than they were dequeued.
  59.     *
  60.     * Returns 0 on success or -errno on error.
  61.     */
  62.     int (*queueBuffer)(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer);

  63.     /*
  64.      * hook used to retrieve information about the native window.
  65.      *
  66.      * Returns 0 on success or -errno on error.
  67.      */
  68.     int (*query)(const struct ANativeWindow* window, int what, int* value);

  69.     /*
  70.      * hook used to perform various operations on the surface.
  71.      * (*perform)() is a generic mechanism to add functionality to
  72.      * ANativeWindow while keeping backward binary compatibility.
  73.      *
  74.      * DO NOT CALL THIS HOOK DIRECTLY. Instead, use the helper functions
  75.      * defined below.
  76.      *
  77.      * (*perform)() returns -ENOENT if the 'what' parameter is not supported
  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, int operation, ... );

  99.     /*
  100.      * hook used to cancel a buffer that has been dequeued.
  101.      * No synchronization is performed between dequeue() and cancel(), so
  102.      * either external synchronization is needed, or these 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. int ANativeWindowDisplayAdapter::setPreviewWindow(preview_stream_ops_t* window)
  2. {
  3.     LOG_FUNCTION_NAME;
  4.     ///Note that Display Adapter cannot work without a valid window object
  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 existing window object, if it exists
  15.     destroy();

  16.     ///Move to new window obj
  17.     mANativeWindow = window;

  18.     LOG_FUNCTION_NAME_EXIT;

  19.     return NO_ERROR;
  20. }
这个window参数最终要往上层追溯,我们这里直接说了,其实window的初始化定义在hardware interface那里,和camera service在一个目录下
  1. /** Set the ANativeWindow to which preview frames are sent */
  2.     status_t setPreviewWindow(const sp<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.         int rc = 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.     static int __cancel_buffer(struct preview_stream_ops* w,
  2.                       buffer_handle_t* buffer)
  3.     {
  4.         ANativeWindow *a = anw(w);
  5.         return a->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(const sp<IBinder>& binder,
  2.         const sp<ANativeWindow>& window) {
  3.     Mutex::Autolock lock(mLock);
  4.     status_t result = checkPidAndHardware();
  5.     if (result != NO_ERROR) return result;

  6.     // return if no change in surface.
  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.     // If preview has been already started, register preview buffers now.
  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 old window and remember the
  28.         // new window.
  29.         disconnectWindow(mPreviewWindow);
  30.         mSurface = binder;
  31.         mPreviewWindow = window;
  32.     } else {
  33.         // Something went wrong after we connected to the new window, 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.         const sp<ISurfaceTexture>& surfaceTexture)
  3. {
  4.     SurfaceTextureClient::init();
  5.     SurfaceTextureClient::setISurfaceTexture(surfaceTexture);
  6. }
先看看init方法:

  1. void SurfaceTextureClient::init() {
  2.     // Initialize the ANativeWindow function pointers.
  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. int SurfaceTextureClient::hook_dequeueBuffer(ANativeWindow* window,
  2.         ANativeWindowBuffer** buffer) {
  3.     SurfaceTextureClient* c = getSelf(window);
  4.     return c->dequeueBuffer(buffer);
  5. }
接着调用SurfaceTextureClient类的dequeueBuffer方法

  1. int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
  2.     LOGV("SurfaceTextureClient::dequeueBuffer");
  3.     Mutex::Autolock lock(mMutex);
  4.     int buf = -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.     public void open(FilterContext context) {
  3.         if (mLogVerbose) Log.v(TAG, "Opening");
  4.         // Open camera
  5.         mCamera = Camera.open(mCameraId);

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

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

  11.         // Bind it to our 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 SurfaceTexture to callback
  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 PID and a 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.     int found, foundSync;
  11.     int dequeuedCount = 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 need to wait for the FIFO to drain if the number of buffer
  19.         // needs to change.
  20.         //
  21.         // The condition "number of buffers needs to change" is true if
  22.         // - the client doesn't care about how many buffers there are
  23.         // - AND the actual number of buffer is different from what was
  24.         // set in the last setBufferCountServer()
  25.         // - OR -
  26.         // setBufferCountServer() was set to a value incompatible with
  27.         // the synchronization mode (for instance because the sync mode
  28.         // changed since)
  29.         //
  30.         // As long as this condition is true AND the FIFO is not empty, we
  31.         // wait on mDequeueCondition.

  32.         const int minBufferCountNeeded = mSynchronousMode ?
  33.                 MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;

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

  37.         if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) {
  38.             // wait for the FIFO to drain
  39.             mDequeueCondition.wait(mMutex);
  40.             // NOTE: we continue here because we need to reevaluate our
  41.             // whole state (eg: we could be abandoned or disconnected)
  42.             continue;
  43.         }

  44.         if (numberOfBuffersNeedsToChange) {
  45.             // here we're guaranteed that mQueue is empty
  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.         // look for a free buffer to give to the client
  54.         found = INVALID_BUFFER_SLOT;
  55.         foundSync = INVALID_BUFFER_SLOT;
  56.         dequeuedCount = 0;
  57.         for (int i = 0; i < mBufferCount; i++) {
  58.             const int state = mSlots[i].mBufferState;
  59.             if (state == BufferSlot::DEQUEUED) {
  60.                 dequeuedCount++;
  61.             }

  62.             // if buffer is FREE 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 are not allowed to dequeue more than one buffer
  82.         // if they didn't set a 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 whether to perform the MIN_UNDEQUEUED_BUFFERS check below.
  88.         bool bufferHasBeenQueued = mCurrentTexture != INVALID_BUFFER_SLOT;
  89.         if (bufferHasBeenQueued) {
  90.             // make sure the client is not trying to dequeue more buffers
  91.             // than allowed.
  92.             const int avail = 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're in synchronous mode and didn't find a buffer, we need to wait
  102.         // for some buffers to be 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 guaranteed to be != INVALID_BUFFER_SLOT
  110.         found = foundSync;
  111.     }

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

  115.     const int buf = found;
  116.     *outBuf = found;

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

  123.     const bool updateFormat = (format != 0);
  124.     if (!updateFormat) {
  125.         // keep the current (or default) format
  126.         format = mPixelFormat;
  127.     }

  128.     // buffer is now in DEQUEUED (but can also be current at the same time,
  129.     // if we're in synchronous mode)
  130.     mSlots[buf].mBufferState = BufferSlot::DEQUEUED;

  131.     const sp<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_t error;
  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.             return error;
  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 have to read the BufferReference from
  17.             // the parcel, it'll die with the parcel.
  18.         }
  19.         *error = result;
  20.         return graphicBuffer;
  21.     }
这里实例化GraphicBuffer类的对象,并且用返回的这个对象实例化graphicBuffer变量

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

待续。。。。
阅读(312) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~