Bug 1097498 - Wait fence for the graphic buffer. r=sotaro
authorBenjamin Chen <bechen@mozilla.com>
Thu, 23 Jul 2015 17:54:08 +0800
changeset 287048 cd609a45509718ed38ff64ce32573d6daccacd47
parent 287047 4d4d72da36714aa5882f7a0f5852eb60b83cd7a9
child 287049 68766dca3878ae5399be8dcc9508aee0c9a25a91
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro
bugs1097498
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1097498 - Wait fence for the graphic buffer. r=sotaro
dom/media/platforms/gonk/GonkVideoDecoderManager.cpp
dom/media/platforms/gonk/GonkVideoDecoderManager.h
--- a/dom/media/platforms/gonk/GonkVideoDecoderManager.cpp
+++ b/dom/media/platforms/gonk/GonkVideoDecoderManager.cpp
@@ -42,17 +42,17 @@ namespace mozilla {
 GonkVideoDecoderManager::GonkVideoDecoderManager(
   mozilla::layers::ImageContainer* aImageContainer,
   const VideoInfo& aConfig)
   : mImageContainer(aImageContainer)
   , mReaderCallback(nullptr)
   , mLastDecodedTime(0)
   , mColorConverterBufferSize(0)
   , mNativeWindow(nullptr)
-  , mPendingVideoBuffersLock("GonkVideoDecoderManager::mPendingVideoBuffersLock")
+  , mPendingReleaseItemsLock("GonkVideoDecoderManager::mPendingReleaseItemsLock")
   , mMonitor("GonkVideoDecoderManager")
 {
   MOZ_COUNT_CTOR(GonkVideoDecoderManager);
   mMimeType = aConfig.mMimeType;
   mVideoWidth  = aConfig.mDisplay.width;
   mVideoHeight = aConfig.mDisplay.height;
   mDisplayWidth = aConfig.mDisplay.width;
   mDisplayHeight = aConfig.mDisplay.height;
@@ -568,49 +568,49 @@ GonkVideoDecoderManager::GetColorConvert
 /* static */
 void
 GonkVideoDecoderManager::RecycleCallback(TextureClient* aClient, void* aClosure)
 {
   MOZ_ASSERT(aClient && !aClient->IsDead());
   GonkVideoDecoderManager* videoManager = static_cast<GonkVideoDecoderManager*>(aClosure);
   GrallocTextureClientOGL* client = static_cast<GrallocTextureClientOGL*>(aClient);
   aClient->ClearRecycleCallback();
-  videoManager->PostReleaseVideoBuffer(client->GetMediaBuffer());
+  FenceHandle handle = aClient->GetAndResetReleaseFenceHandle();
+  videoManager->PostReleaseVideoBuffer(client->GetMediaBuffer(), handle);
 }
 
 void GonkVideoDecoderManager::PostReleaseVideoBuffer(
-                                android::MediaBuffer *aBuffer)
+                                android::MediaBuffer *aBuffer,
+                                FenceHandle aReleaseFence)
 {
   {
-    MutexAutoLock autoLock(mPendingVideoBuffersLock);
+    MutexAutoLock autoLock(mPendingReleaseItemsLock);
     if (aBuffer) {
-      mPendingVideoBuffers.append(aBuffer);
+      mPendingReleaseItems.AppendElement(ReleaseItem(aBuffer, aReleaseFence));
     }
   }
   sp<AMessage> notify =
             new AMessage(kNotifyPostReleaseBuffer, mHandler->id());
   notify->post();
 
 }
 
 void GonkVideoDecoderManager::ReleaseAllPendingVideoBuffers()
 {
-  Vector<android::MediaBuffer*> releasingVideoBuffers;
+  nsTArray<ReleaseItem> releasingItems;
   {
-    MutexAutoLock autoLock(mPendingVideoBuffersLock);
-    int size = mPendingVideoBuffers.length();
-    for (int i = 0; i < size; i++) {
-      releasingVideoBuffers.append(mPendingVideoBuffers[i]);
-    }
-    mPendingVideoBuffers.clear();
+    MutexAutoLock autoLock(mPendingReleaseItemsLock);
+    releasingItems.AppendElements(mPendingReleaseItems);
+    mPendingReleaseItems.Clear();
   }
-  // Free all pending video buffers without holding mPendingVideoBuffersLock.
-  int size = releasingVideoBuffers.length();
-  for (int i = 0; i < size; i++) {
-    android::MediaBuffer *buffer;
-    buffer = releasingVideoBuffers[i];
-    mDecoder->ReleaseMediaBuffer(buffer);
-    buffer = nullptr;
+
+  // Free all pending video buffers without holding mPendingReleaseItemsLock.
+  size_t size = releasingItems.Length();
+  for (size_t i = 0; i < size; i++) {
+    nsRefPtr<FenceHandle::FdObj> fdObj = releasingItems[i].mReleaseFence.GetAndResetFdObj();
+    sp<Fence> fence = new Fence(fdObj->GetAndResetFd());
+    fence->waitForever("GonkVideoDecoderManager");
+    mDecoder->ReleaseMediaBuffer(releasingItems[i].mBuffer);
   }
-  releasingVideoBuffers.clear();
+  releasingItems.Clear();
 }
 
 } // namespace mozilla
--- a/dom/media/platforms/gonk/GonkVideoDecoderManager.h
+++ b/dom/media/platforms/gonk/GonkVideoDecoderManager.h
@@ -11,16 +11,18 @@
 #include "nsRect.h"
 #include "GonkMediaDataDecoder.h"
 #include "mozilla/RefPtr.h"
 #include "I420ColorConverterHelper.h"
 #include "MediaCodecProxy.h"
 #include <stagefright/foundation/AHandler.h>
 #include "GonkNativeWindow.h"
 #include "GonkNativeWindowClient.h"
+#include "mozilla/layers/FenceUtils.h"
+#include <ui/Fence.h>
 
 using namespace android;
 
 namespace android {
 struct ALooper;
 class MediaBuffer;
 struct MOZ_EXPORT AString;
 class GonkNativeWindow;
@@ -112,17 +114,18 @@ private:
   uint8_t* GetColorConverterBuffer(int32_t aWidth, int32_t aHeight);
 
   // For codec resource management
   void codecReserved();
   void codecCanceled();
   void onMessageReceived(const sp<AMessage> &aMessage);
 
   void ReleaseAllPendingVideoBuffers();
-  void PostReleaseVideoBuffer(android::MediaBuffer *aBuffer);
+  void PostReleaseVideoBuffer(android::MediaBuffer *aBuffer,
+                              layers::FenceHandle mReleaseFence);
 
   uint32_t mVideoWidth;
   uint32_t mVideoHeight;
   uint32_t mDisplayWidth;
   uint32_t mDisplayHeight;
   nsIntRect mPicture;
   nsIntSize mInitialFrame;
 
@@ -145,21 +148,27 @@ private:
   nsAutoArrayPtr<uint8_t> mColorConverterBuffer;
   size_t mColorConverterBufferSize;
 
   android::sp<android::GonkNativeWindow> mNativeWindow;
   enum {
     kNotifyPostReleaseBuffer = 'nprb',
   };
 
-  // Hold video's MediaBuffers that are released.
-  // The holded MediaBuffers are released soon after flush.
-  Vector<android::MediaBuffer*> mPendingVideoBuffers;
-  // The lock protects mPendingVideoBuffers.
-  Mutex mPendingVideoBuffersLock;
+  struct ReleaseItem {
+    ReleaseItem(android::MediaBuffer* aBuffer, layers::FenceHandle& aFence)
+    : mBuffer(aBuffer)
+    , mReleaseFence(aFence) {}
+    android::MediaBuffer* mBuffer;
+    layers::FenceHandle mReleaseFence;
+  };
+  nsTArray<ReleaseItem> mPendingReleaseItems;
+
+  // The lock protects mPendingReleaseItems.
+  Mutex mPendingReleaseItemsLock;
 
   // MediaCodedc's wrapper that performs the decoding.
   android::sp<android::MediaCodecProxy> mDecoder;
 
   // This monitor protects mQueueSample.
   Monitor mMonitor;
 
   // An queue with the MP4 samples which are waiting to be sent into OMX.