QCamera2: Trigger buffer cache clean invalidate just after dequeuing

- This change moves the buffer cache clean invalidation
  right after the buffer is dequeued from the camera.
  This is done in order to avoid any race conditions
  that could occur when buffers are processed in
  different contexts at the same time.

Change-Id: I590e89bb4175afb57cb873631b210de6b7da48c6
diff --git a/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp b/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp
index 1d3ab6a..2e5266f 100644
--- a/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp
+++ b/camera/QCamera2/HAL/QCamera2HWICallbacks.cpp
@@ -280,7 +280,6 @@
     }
 
     int idx = frame->buf_idx;
-    memory->cleanCache(idx);
     pme->dumpFrameToFile(frame->buffer, frame->frame_len,
                          frame->frame_idx, QCAMERA_DUMP_FRM_PREVIEW);
 
@@ -406,8 +405,6 @@
         preview_mem = previewMemObj->getMemory(frame->buf_idx, false);
     }
     if (NULL != previewMemObj && NULL != preview_mem) {
-        previewMemObj->cleanCache(frame->buf_idx);
-
         pme->dumpFrameToFile(frame->buffer, frame->frame_len,
                              frame->frame_idx, QCAMERA_DUMP_FRM_PREVIEW);
 
@@ -476,8 +473,6 @@
 
     QCameraMemory *memObj = (QCameraMemory *)frame->mem_info;
     if (NULL != memObj) {
-        memObj->cleanCache(frame->buf_idx);
-
         pme->dumpFrameToFile(frame->buffer, frame->frame_len,
                              frame->frame_idx, QCAMERA_DUMP_FRM_THUMBNAIL);
     }
@@ -554,7 +549,6 @@
         video_mem = videoMemObj->getMemory(frame->buf_idx, (pme->mStoreMetaDataInFrame > 0)? true : false);
     }
     if (NULL != videoMemObj && NULL != video_mem) {
-        videoMemObj->cleanCache(frame->buf_idx);
         pme->dumpFrameToFile(frame->buffer, frame->frame_len,
                              frame->frame_idx, QCAMERA_DUMP_FRM_VIDEO);
         if ((pme->mDataCbTimestamp != NULL) &&
diff --git a/camera/QCamera2/HAL/QCameraPostProc.cpp b/camera/QCamera2/HAL/QCameraPostProc.cpp
index 2db1f41..00d0610 100644
--- a/camera/QCamera2/HAL/QCameraPostProc.cpp
+++ b/camera/QCamera2/HAL/QCameraPostProc.cpp
@@ -952,9 +952,6 @@
         return NO_MEMORY;
     }
 
-    // clean and invalidate cache ops through mem obj of the frame
-    memObj->cleanInvalidateCache(main_frame->buf_idx);
-
     // dump snapshot frame if enabled
     m_parent->dumpFrameToFile(main_frame->buffer, main_frame->frame_len,
                               main_frame->frame_idx, QCAMERA_DUMP_FRM_SNAPSHOT);
@@ -983,12 +980,6 @@
     }
 
     if (thumb_frame != NULL) {
-        QCameraMemory *thumb_memObj = (QCameraMemory *)thumb_frame->mem_info;
-        if (NULL != thumb_memObj) {
-            // clean and invalidate cache ops through mem obj of the frame
-            thumb_memObj->cleanInvalidateCache(thumb_frame->buf_idx);
-        }
-
         // dump thumbnail frame if enabled
         m_parent->dumpFrameToFile(thumb_frame->buffer, thumb_frame->frame_len,
                                   thumb_frame->frame_idx, QCAMERA_DUMP_FRM_THUMBNAIL);
@@ -1115,9 +1106,6 @@
     }
 
     if (NULL != rawMemObj && NULL != raw_mem) {
-        // send data callback for COMPRESSED_IMAGE
-        rawMemObj->cleanCache(frame->buf_idx);
-
         // dump frame into file
         m_parent->dumpFrameToFile(frame->buffer, frame->frame_len,
                                   frame->frame_idx, QCAMERA_DUMP_FRM_RAW);
diff --git a/camera/QCamera2/HAL/QCameraStream.cpp b/camera/QCamera2/HAL/QCameraStream.cpp
index da9a547..7a5fd21 100644
--- a/camera/QCamera2/HAL/QCameraStream.cpp
+++ b/camera/QCamera2/HAL/QCameraStream.cpp
@@ -118,6 +118,29 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : clean_invalidate_buf
+ *
+ * DESCRIPTION: static function entry to clean invalidate a specific stream buffer
+ *
+ * PARAMETERS :
+ *   @index      : index of the stream buffer to clean invalidate
+ *   @user_data  : user data ptr of ops_tbl
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraStream::clean_invalidate_buf(int index, void *user_data)
+{
+    QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
+    if (!stream) {
+        ALOGE("invalid stream pointer");
+        return NO_MEMORY;
+    }
+    return stream->cleanInvalidateBuf(index);
+}
+
+/*===========================================================================
  * FUNCTION   : QCameraStream
  *
  * DESCRIPTION: constructor of QCameraStream
@@ -152,6 +175,7 @@
     mMemVtbl.get_bufs = get_bufs;
     mMemVtbl.put_bufs = put_bufs;
     mMemVtbl.invalidate_buf = invalidate_buf;
+    mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
     memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
     memset(&mCropInfo, 0, sizeof(cam_rect_t));
@@ -666,6 +690,23 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : cleanInvalidateBuf
+ *
+ * DESCRIPTION: clean invalidate a specific stream buffer
+ *
+ * PARAMETERS :
+ *   @index   : index of the buffer to clean invalidate
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraStream::cleanInvalidateBuf(int index)
+{
+    return mStreamBufs->cleanInvalidateCache(index);
+}
+
+/*===========================================================================
  * FUNCTION   : isTypeOf
  *
  * DESCRIPTION: helper function to determine if the stream is of the queried type
diff --git a/camera/QCamera2/HAL/QCameraStream.h b/camera/QCamera2/HAL/QCameraStream.h
index d9dbc7e..8bb2c65 100644
--- a/camera/QCamera2/HAL/QCameraStream.h
+++ b/camera/QCamera2/HAL/QCameraStream.h
@@ -118,6 +118,7 @@
                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
                      void *user_data);
     static int32_t invalidate_buf(int index, void *user_data);
+    static int32_t clean_invalidate_buf(int index, void *user_data);
 
     int32_t getBufs(cam_frame_len_offset_t *offset,
                      uint8_t *num_bufs,
@@ -126,6 +127,7 @@
                      mm_camera_map_unmap_ops_tbl_t *ops_tbl);
     int32_t putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl);
     int32_t invalidateBuf(int index);
+    int32_t cleanInvalidateBuf(int index);
 
 };
 
diff --git a/camera/QCamera2/stack/common/mm_camera_interface.h b/camera/QCamera2/stack/common/mm_camera_interface.h
index 78fdd86..7ccc130 100644
--- a/camera/QCamera2/stack/common/mm_camera_interface.h
+++ b/camera/QCamera2/stack/common/mm_camera_interface.h
@@ -183,6 +183,7 @@
   int32_t (*put_bufs) (mm_camera_map_unmap_ops_tbl_t *ops_tbl,
                        void *user_data);
   int32_t (*invalidate_buf)(int index, void *user_data);
+  int32_t (*clean_invalidate_buf)(int index, void *user_data);
 } mm_camera_stream_mem_vtbl_t;
 
 /** mm_camera_stream_config_t: structure for stream
diff --git a/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c b/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
index a3a4f4f..e7c115c 100644
--- a/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
+++ b/camera/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
@@ -977,6 +977,8 @@
         buf_info->buf->ts.tv_nsec = vb.timestamp.tv_usec * 1000;
         CDBG_HIGH("%s: VIDIOC_DQBUF buf_index %d, frame_idx %d, stream type %d\n",
              __func__, vb.index, buf_info->buf->frame_idx, my_obj->stream_info->stream_type);
+        my_obj->mem_vtbl.clean_invalidate_buf(idx,
+                                my_obj->mem_vtbl.user_data);
     }
 
     CDBG("%s :X rc = %d",__func__,rc);
diff --git a/camera/QCamera2/stack/mm-camera-test/inc/mm_qcamera_app.h b/camera/QCamera2/stack/mm-camera-test/inc/mm_qcamera_app.h
index 6063897..a2cdd42 100644
--- a/camera/QCamera2/stack/mm-camera-test/inc/mm_qcamera_app.h
+++ b/camera/QCamera2/stack/mm-camera-test/inc/mm_qcamera_app.h
@@ -189,6 +189,7 @@
                                        void *user_data);
 extern int mm_app_cache_ops(mm_camera_app_meminfo_t *mem_info,
                             unsigned int cmd);
+extern int32_t mm_app_stream_clean_invalidate_buf(int index, void *user_data);
 extern int mm_app_open(mm_camera_app_t *cam_app,
                        uint8_t cam_id,
                        mm_camera_test_obj_t *test_obj);
diff --git a/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_app.c b/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_app.c
index 7107ce6..250ab9c 100644
--- a/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_app.c
+++ b/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_app.c
@@ -420,6 +420,13 @@
     return 0;
 }
 
+int32_t mm_app_stream_clean_invalidate_buf(int index, void *user_data)
+{
+    mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data;
+    return mm_app_cache_ops(&stream->s_bufs[index].mem_info,
+      ION_IOC_CLEAN_INV_CACHES);
+}
+
 static void notify_evt_cb(uint32_t camera_handle,
                           mm_camera_event_t *evt,
                           void *user_data)
diff --git a/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_preview.c b/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_preview.c
index b87aa8e..e55ad6a 100644
--- a/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_preview.c
+++ b/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_preview.c
@@ -164,6 +164,8 @@
 
     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
+    stream->s_config.mem_vtbl.clean_invalidate_buf =
+      mm_app_stream_clean_invalidate_buf;
     stream->s_config.mem_vtbl.user_data = (void *)stream;
     stream->s_config.stream_cb = stream_cb;
     stream->s_config.userdata = userdata;
@@ -206,6 +208,8 @@
 
     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
+    stream->s_config.mem_vtbl.clean_invalidate_buf =
+      mm_app_stream_clean_invalidate_buf;
     stream->s_config.mem_vtbl.user_data = (void *)stream;
     stream->s_config.stream_cb = stream_cb;
     stream->s_config.userdata = userdata;
diff --git a/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_rdi.c b/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_rdi.c
index 503bb42..1a1809d 100644
--- a/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_rdi.c
+++ b/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_rdi.c
@@ -119,6 +119,8 @@
 
     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
+    stream->s_config.mem_vtbl.clean_invalidate_buf =
+      mm_app_stream_clean_invalidate_buf;
     stream->s_config.mem_vtbl.user_data = (void *)stream;
     stream->s_config.stream_cb = stream_cb;
     stream->s_config.userdata = userdata;
@@ -172,6 +174,8 @@
 
     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
+    stream->s_config.mem_vtbl.clean_invalidate_buf =
+      mm_app_stream_clean_invalidate_buf;
     stream->s_config.mem_vtbl.user_data = (void *)stream;
     stream->s_config.stream_cb = stream_cb;
     stream->s_config.userdata = userdata;
diff --git a/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_snapshot.c b/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_snapshot.c
index 28cccd8..28f1703 100644
--- a/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_snapshot.c
+++ b/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_snapshot.c
@@ -310,6 +310,8 @@
 
     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
+    stream->s_config.mem_vtbl.clean_invalidate_buf =
+      mm_app_stream_clean_invalidate_buf;
     stream->s_config.mem_vtbl.user_data = (void *)stream;
     stream->s_config.stream_cb = stream_cb;
     stream->s_config.userdata = userdata;
diff --git a/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_video.c b/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_video.c
index d63c651..86ab614 100644
--- a/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_video.c
+++ b/camera/QCamera2/stack/mm-camera-test/src/mm_qcamera_video.c
@@ -71,6 +71,8 @@
 
     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
+    stream->s_config.mem_vtbl.clean_invalidate_buf =
+      mm_app_stream_clean_invalidate_buf;
     stream->s_config.mem_vtbl.user_data = (void *)stream;
     stream->s_config.stream_cb = stream_cb;
     stream->s_config.userdata = userdata;