summaryrefslogtreecommitdiff
path: root/camera
diff options
context:
space:
mode:
authorTyler Luu <tluu@ti.com>2011-08-27 16:18:55 -0500
committerIliyan Malchev <malchev@google.com>2011-08-30 09:36:21 -0700
commit6c73fda9fdca5431e4e7911bb3171e36088a861e (patch)
tree8e1aabdfa00779b8097fdd5100a99d611fcfa083 /camera
parent97db71f3a06c88c16f46fea8189f542dcde28f7f (diff)
downloadomap4-aah-6c73fda9fdca5431e4e7911bb3171e36088a861e.tar.gz
CameraHal: Lock buffers sent to FrameProvider
Use GraphicBufferMapper API to lock buffer before sending to FrameProvider to ensure there isn't simultaneous accesses to bufffer by SGX Change-Id: Ifbb5c88bac49b1b494bd984137b523d35f4a6f57 Signed-off-by: Tyler Luu <tluu@ti.com>
Diffstat (limited to 'camera')
-rw-r--r--camera/ANativeWindowDisplayAdapter.cpp49
-rw-r--r--camera/AppCallbackNotifier.cpp18
2 files changed, 61 insertions, 6 deletions
diff --git a/camera/ANativeWindowDisplayAdapter.cpp b/camera/ANativeWindowDisplayAdapter.cpp
index f880e6f..4942193 100644
--- a/camera/ANativeWindowDisplayAdapter.cpp
+++ b/camera/ANativeWindowDisplayAdapter.cpp
@@ -21,6 +21,7 @@
#include "ANativeWindowDisplayAdapter.h"
#include <OMX_IVCommon.h>
+#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferMapper.h>
#include <hal_public.h>
@@ -34,7 +35,6 @@ const int ANativeWindowDisplayAdapter::DISPLAY_TIMEOUT = 1000; // seconds
const int ANativeWindowDisplayAdapter::FAILED_DQS_TO_SUSPEND = 3;
-
OMX_COLOR_FORMATTYPE toOMXPixFormat(const char* parameters_format)
{
OMX_COLOR_FORMATTYPE pixFormat;
@@ -407,6 +407,7 @@ int ANativeWindowDisplayAdapter::enableDisplay(int width, int height, struct tim
int ANativeWindowDisplayAdapter::disableDisplay(bool cancel_buffer)
{
status_t ret = NO_ERROR;
+ GraphicBufferMapper &mapper = GraphicBufferMapper::get();
LOG_FUNCTION_NAME;
@@ -461,6 +462,10 @@ int ANativeWindowDisplayAdapter::disableDisplay(bool cancel_buffer)
if (mANativeWindow)
for(unsigned int i = 0; i < mFramesWithCameraAdapterMap.size(); i++) {
int value = mFramesWithCameraAdapterMap.valueAt(i);
+
+ // unlock buffer before giving it up
+ mapper.unlock((buffer_handle_t) mGrallocHandleMap[value]);
+
ret = mANativeWindow->cancel_buffer(mANativeWindow, mBufferHandleMap[value]);
if ( ENODEV == ret ) {
CAMHAL_LOGEA("Preview surface abandoned!");
@@ -533,6 +538,9 @@ void* ANativeWindowDisplayAdapter::allocateBuffer(int width, int height, const c
mBufferHandleMap = new buffer_handle_t*[lnumBufs];
mGrallocHandleMap = new IMG_native_handle_t*[lnumBufs];
int undequeued = 0;
+ GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+ Rect bounds;
+
if ( NULL == mANativeWindow ) {
return NULL;
@@ -632,11 +640,23 @@ void* ANativeWindowDisplayAdapter::allocateBuffer(int width, int height, const c
CAMHAL_LOGDB("Adding buffer index=%d, address=0x%x", i, buffers[i]);
}
-
// lock the initial queueable buffers
+ bounds.left = 0;
+ bounds.top = 0;
+ bounds.right = width;
+ bounds.bottom = height;
+
for( i = 0; i < mBufferCount-undequeued; i++ )
{
+ void *y_uv[2];
+
mANativeWindow->lock_buffer(mANativeWindow, mBufferHandleMap[i]);
+
+ mapper.lock((buffer_handle_t) mGrallocHandleMap[i],
+ GRALLOC_USAGE_HW_RENDER |
+ GRALLOC_USAGE_SW_READ_RARELY |
+ GRALLOC_USAGE_SW_WRITE_NEVER,
+ bounds, y_uv);
}
// return the rest of the buffers back to ANativeWindow
@@ -653,6 +673,7 @@ void* ANativeWindowDisplayAdapter::allocateBuffer(int width, int height, const c
goto fail;
}
+ mFramesWithCameraAdapterMap.removeItem((int) mGrallocHandleMap[i]);
}
mFirstInit = true;
@@ -670,6 +691,7 @@ void* ANativeWindowDisplayAdapter::allocateBuffer(int width, int height, const c
CAMHAL_LOGEB("cancelBuffer failed w/ error 0x%08x", err);
break;
}
+ mFramesWithCameraAdapterMap.removeItem((int) mGrallocHandleMap[start]);
}
CAMHAL_LOGEA("Error occurred, performing cleanup");
if ( buffers )
@@ -978,6 +1000,7 @@ status_t ANativeWindowDisplayAdapter::PostFrame(ANativeWindowDisplayAdapter::Dis
status_t ret = NO_ERROR;
uint32_t actualFramesWithDisplay = 0;
android_native_buffer_t *buffer = NULL;
+ GraphicBufferMapper &mapper = GraphicBufferMapper::get();
int i;
///@todo Do cropping based on the stabilized frame coordinates
@@ -1035,6 +1058,9 @@ status_t ANativeWindowDisplayAdapter::PostFrame(ANativeWindowDisplayAdapter::Dis
mYOff = yOff;
}
+ // unlock buffer before sending to display
+ mapper.unlock((buffer_handle_t) mGrallocHandleMap[i]);
+
ret = mANativeWindow->enqueue_buffer(mANativeWindow, mBufferHandleMap[i]);
if (ret != 0) {
LOGE("Surface::queueBuffer returned error %d", ret);
@@ -1072,6 +1098,10 @@ status_t ANativeWindowDisplayAdapter::PostFrame(ANativeWindowDisplayAdapter::Dis
else
{
Mutex::Autolock lock(mLock);
+
+ // unlock buffer before giving it up
+ mapper.unlock((buffer_handle_t) mGrallocHandleMap[i]);
+
// cancel buffer and dequeue another one
ret = mANativeWindow->cancel_buffer(mANativeWindow, mBufferHandleMap[i]);
if (ret != 0) {
@@ -1095,6 +1125,10 @@ bool ANativeWindowDisplayAdapter::handleFrameReturn()
buffer_handle_t* buf;
int i = 0;
int stride; // dummy variable to get stride
+ GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+ Rect bounds;
+ void *y_uv[2];
+
// TODO(XXX): Do we need to keep stride information in camera hal?
if ( NULL == mANativeWindow ) {
@@ -1131,6 +1165,17 @@ bool ANativeWindowDisplayAdapter::handleFrameReturn()
break;
}
+ // lock buffer before sending to FrameProvider for filling
+ bounds.left = 0;
+ bounds.top = 0;
+ bounds.right = mFrameWidth;
+ bounds.bottom = mFrameHeight;
+ mapper.lock((buffer_handle_t) mGrallocHandleMap[i],
+ GRALLOC_USAGE_HW_RENDER |
+ GRALLOC_USAGE_SW_READ_RARELY |
+ GRALLOC_USAGE_SW_WRITE_NEVER,
+ bounds, y_uv);
+
mFramesWithCameraAdapterMap.add((int) mGrallocHandleMap[i], i);
CAMHAL_LOGVB("handleFrameReturn: found graphic buffer %d of %d", i, mBufferCount-1);
diff --git a/camera/AppCallbackNotifier.cpp b/camera/AppCallbackNotifier.cpp
index 1c5482d..68ab850 100644
--- a/camera/AppCallbackNotifier.cpp
+++ b/camera/AppCallbackNotifier.cpp
@@ -26,7 +26,7 @@
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferMapper.h>
-
+#define LOCK_BUFFER_TRIES 5
namespace android {
const int AppCallbackNotifier::NOTIFIER_TIMEOUT = -1;
@@ -319,6 +319,7 @@ static void copy2Dto1D(void *dst,
unsigned char *bufferDstEnd, *bufferSrcEnd;
uint16_t *bufferSrc_UV;
void *y_uv[2]; //y_uv[0]=> y pointer; y_uv[1]=>uv pointer
+ int lock_try_count = 0;
GraphicBufferMapper &mapper = GraphicBufferMapper::get();
Rect bounds;
@@ -329,9 +330,18 @@ static void copy2Dto1D(void *dst,
bounds.bottom = height;
// get the y & uv pointers from the gralloc handle;
- mapper.lock((buffer_handle_t)src,
- GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_NEVER,
- bounds, y_uv);
+ while (mapper.lock((buffer_handle_t)src,
+ GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_NEVER,
+ bounds, y_uv) < 0) {
+ // give up after LOCK_BUFFER_TRIES (defined in this file)
+ if (++lock_try_count > LOCK_BUFFER_TRIES) {
+ return;
+ }
+
+ // sleep for 50 ms before we try to lock again.
+ // somebody else has a write lock on this buffer
+ usleep(50000);
+ }
CAMHAL_LOGDB("copy2Dto1D() y= %p ; uv=%p.",y_uv[0],y_uv[1]);
CAMHAL_LOGDB("pixelFormat,= %d; offset=%d",*pixelFormat,offset);