Bug 1041695 - Make ShadowLayersForwarder::RemoveTexture run on worker thread, as required by TextureClient::Finalize. r=nical
authorDavid Parks <davidp99@gmail.com>
Wed, 30 Jul 2014 23:44:31 -0700
changeset 198527 e16fe0c38119cfce434b37263f1435a8c659f877
parent 198526 3200ed3305db4b7b46c722fe098ddb56e43e402a
child 198528 be762cafe3474f267677b606f2a3846ef03a677f
push id47419
push userryanvm@gmail.com
push dateFri, 08 Aug 2014 13:48:51 +0000
treeherdermozilla-inbound@2c6e6c9b37a1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1041695
milestone34.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 1041695 - Make ShadowLayersForwarder::RemoveTexture run on worker thread, as required by TextureClient::Finalize. r=nical
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -28,16 +28,17 @@
 #include "mozilla/layers/TextureClient.h"  // for TextureClient
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsAutoPtr.h"                  // for nsRefPtr, getter_AddRefs, etc
 #include "nsDebug.h"                    // for NS_ABORT_IF_FALSE, etc
 #include "nsRect.h"                     // for nsIntRect
 #include "nsSize.h"                     // for nsIntSize
 #include "nsTArray.h"                   // for nsAutoTArray, nsTArray, etc
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType, etc
+#include "mozilla/ReentrantMonitor.h"
 
 struct nsIntPoint;
 
 namespace mozilla {
 namespace ipc {
 class Shmem;
 }
 
@@ -468,21 +469,52 @@ ShadowLayerForwarder::RemoveTextureFromC
                                      aAsyncTransactionTracker->GetId(),
                                      nullptr, aCompositable->GetIPDLActor(),
                                      nullptr, aTexture->GetIPDLActor()));
   // Hold AsyncTransactionTracker until receving reply
   CompositableClient::HoldUntilComplete(aCompositable->GetIPDLActor(),
                                         aAsyncTransactionTracker);
 }
 
+bool
+ShadowLayerForwarder::InWorkerThread()
+{
+  return GetMessageLoop()->id() == MessageLoop::current()->id();
+}
+
+static void RemoveTextureWorker(TextureClient* aTexture, ReentrantMonitor* aBarrier, bool* aDone)
+{
+  aTexture->ForceRemove();
+
+  ReentrantMonitorAutoEnter autoMon(*aBarrier);
+  *aDone = true;
+  aBarrier->NotifyAll();
+}
+
 void
 ShadowLayerForwarder::RemoveTexture(TextureClient* aTexture)
 {
   MOZ_ASSERT(aTexture);
-  aTexture->ForceRemove();
+  if (InWorkerThread()) {
+    aTexture->ForceRemove();
+    return;
+  }
+
+  ReentrantMonitor barrier("ShadowLayerForwarder::RemoveTexture Lock");
+  ReentrantMonitorAutoEnter autoMon(barrier);
+  bool done = false;
+
+  GetMessageLoop()->PostTask(
+    FROM_HERE,
+    NewRunnableFunction(&RemoveTextureWorker, aTexture, &barrier, &done));
+
+  // Wait until the TextureClient has been ForceRemoved on the worker thread
+  while (!done) {
+    barrier.Wait();
+  }
 }
 
 bool
 ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
                                      const nsIntRegion& aRegionToClear,
                                      uint64_t aId,
                                      bool aScheduleComposite,
                                      uint32_t aPaintSequenceNumber,
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -388,16 +388,18 @@ protected:
   ShadowLayerForwarder();
 
 #ifdef DEBUG
   void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const;
 #else
   void CheckSurfaceDescriptor(const SurfaceDescriptor* aDescriptor) const {}
 #endif
 
+  bool InWorkerThread();
+
   RefPtr<LayerTransactionChild> mShadowManager;
 
 private:
 
   Transaction* mTxn;
   DiagnosticTypes mDiagnosticTypes;
   bool mIsFirstPaint;
   bool mWindowOverlayChanged;