diff --git a/dom/camera/GonkCameraHwMgr.cpp b/dom/camera/GonkCameraHwMgr.cpp index d16c6a24395..07459320e39 100644 --- a/dom/camera/GonkCameraHwMgr.cpp +++ b/dom/camera/GonkCameraHwMgr.cpp @@ -25,6 +25,9 @@ #include "mozilla/layers/TextureClient.h" #include "CameraPreferences.h" #include "mozilla/RefPtr.h" +#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21 +#include "GonkBufferQueueProducer.h" +#endif #include "GonkCameraControl.h" #include "GonkNativeWindow.h" #include "CameraCommon.h" @@ -187,6 +190,7 @@ GonkCameraHardware::Init() sp producer; sp consumer; GonkBufferQueue::createBufferQueue(&producer, &consumer); + static_cast(producer.get())->setSynchronousMode(false); mNativeWindow = new GonkNativeWindow(consumer, GonkCameraHardware::MIN_UNDEQUEUED_BUFFERS); mCamera->setPreviewTarget(producer); #elif ANDROID_VERSION >= 19 diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.cpp b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.cpp index 5d3bbedb2c1..8073a65823a 100644 --- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.cpp +++ b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.cpp @@ -42,6 +42,7 @@ GonkBufferQueueProducer::GonkBufferQueueProducer(const sp& mCore(core), mSlots(core->mSlots), mConsumerName(), + mSynchronousMode(true), mStickyTransform(0) {} GonkBufferQueueProducer::~GonkBufferQueueProducer() {} @@ -501,6 +502,22 @@ status_t GonkBufferQueueProducer::attachBuffer(int* outSlot, return returnFlags; } +status_t GonkBufferQueueProducer::setSynchronousMode(bool enabled) { + ALOGV("setSynchronousMode: enabled=%d", enabled); + Mutex::Autolock lock(mCore->mMutex); + + if (mCore->mIsAbandoned) { + ALOGE("setSynchronousMode: BufferQueue has been abandoned!"); + return NO_INIT; + } + + if (mSynchronousMode != enabled) { + mSynchronousMode = enabled; + mCore->mDequeueCondition.broadcast(); + } + return OK; +} + status_t GonkBufferQueueProducer::queueBuffer(int slot, const QueueBufferInput &input, QueueBufferOutput *output) { ATRACE_CALL(); @@ -619,7 +636,7 @@ status_t GonkBufferQueueProducer::queueBuffer(int slot, // When the queue is not empty, we need to look at the front buffer // state to see if we need to replace it GonkBufferQueueCore::Fifo::iterator front(mCore->mQueue.begin()); - if (front->mIsDroppable) { + if (front->mIsDroppable || !mSynchronousMode) { // If the front queued buffer is still being tracked, we first // mark it as freed if (mCore->stillTracking(front)) { @@ -630,6 +647,7 @@ status_t GonkBufferQueueProducer::queueBuffer(int slot, } // Overwrite the droppable buffer with the incoming one *front = item; + listener = mCore->mConsumerListener; } else { mCore->mQueue.push_back(item); listener = mCore->mConsumerListener; diff --git a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.h b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.h index ef3b70a413b..17f94c201c8 100644 --- a/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.h +++ b/widget/gonk/nativewindow/GonkBufferQueueLL/GonkBufferQueueProducer.h @@ -174,6 +174,16 @@ public: virtual void allocateBuffers(bool async, uint32_t width, uint32_t height, uint32_t format, uint32_t usage); + // setSynchronousMode sets whether dequeueBuffer is synchronous or + // asynchronous. In synchronous mode, dequeueBuffer blocks until + // a buffer is available, the currently bound buffer can be dequeued and + // queued buffers will be acquired in order. In asynchronous mode, + // a queued buffer may be replaced by a subsequently queued buffer. + // + // The default mode is synchronous. + // This should be called only during initialization. + virtual status_t setSynchronousMode(bool enabled); + private: // This is required by the IBinder::DeathRecipient interface virtual void binderDied(const wp& who); @@ -196,6 +206,9 @@ private: // most updates). String8 mConsumerName; + // mSynchronousMode whether we're in synchronous mode or not + bool mSynchronousMode; + uint32_t mStickyTransform; }; // class GonkBufferQueueProducer diff --git a/widget/gonk/nativewindow/moz.build b/widget/gonk/nativewindow/moz.build index 416ed09ba6d..0870c63e180 100644 --- a/widget/gonk/nativewindow/moz.build +++ b/widget/gonk/nativewindow/moz.build @@ -29,6 +29,7 @@ if CONFIG['ANDROID_VERSION'] >= '21': EXPORTS += [ 'GonkBufferQueueLL/GonkBufferQueueDefs.h', 'GonkBufferQueueLL/GonkBufferQueueLL.h', + 'GonkBufferQueueLL/GonkBufferQueueProducer.h', 'GonkBufferQueueLL/GonkBufferSlot.h', 'GonkConsumerBaseLL.h', 'GonkNativeWindowClientLL.h',