ipc changes draft
authorDoug Thayer <dothayer@mozilla.com>
Wed, 11 Jul 2018 08:56:50 -0700
changeset 816927 1e8f60cf244c367b2af7b2ac10ce38c63b6c3181
parent 816225 9624b3d7472df507b4a63a17fda3f924ef7ee817
push id115882
push userbmo:dothayer@mozilla.com
push dateWed, 11 Jul 2018 15:57:09 +0000
milestone63.0a1
ipc changes MozReview-Commit-ID: dkQ3mXO0Pk
gfx/layers/TextureSourceProvider.cpp
gfx/layers/TextureSync.cpp
gfx/layers/client/ClientLayerManager.cpp
--- a/gfx/layers/TextureSourceProvider.cpp
+++ b/gfx/layers/TextureSourceProvider.cpp
@@ -15,37 +15,41 @@ namespace layers {
 TextureSourceProvider::~TextureSourceProvider()
 {
   ReadUnlockTextures();
 }
 
 void
 TextureSourceProvider::ReadUnlockTextures()
 {
+#ifdef XP_DARWIN
   nsClassHashtable<nsUint32HashKey, nsTArray<uint64_t>> texturesIdsToUnlockByPid;
   for (auto& texture : mUnlockAfterComposition) {
     auto bufferTexture = texture->AsBufferTextureHost();
     if (bufferTexture && bufferTexture->IsDirectMap()) {
       texture->ReadUnlock();
       auto actor = texture->GetIPDLActor();
       if (actor) {
         base::ProcessId pid = actor->OtherPid();
         nsTArray<uint64_t>* textureIds = texturesIdsToUnlockByPid.LookupOrAdd(pid);
         textureIds->AppendElement(TextureHost::GetTextureSerial(actor));
       }
     } else {
       texture->ReadUnlock();
     }
   }
-  mUnlockAfterComposition.Clear();
-#ifdef XP_DARWIN
   for (auto it = texturesIdsToUnlockByPid.ConstIter(); !it.Done(); it.Next()) {
     TextureSync::SetTexturesUnlocked(it.Key(), *it.UserData());
   }
+#else
+  for (auto& texture : mUnlockAfterComposition) {
+    texture->ReadUnlock();
+  }
 #endif
+  mUnlockAfterComposition.Clear();
 }
 
 void
 TextureSourceProvider::UnlockAfterComposition(TextureHost* aTexture)
 {
   mUnlockAfterComposition.AppendElement(aTexture);
 }
 
--- a/gfx/layers/TextureSync.cpp
+++ b/gfx/layers/TextureSync.cpp
@@ -56,37 +56,44 @@ GetLockedTextureIdsForProcess(pid_t pid)
   if (gProcessTextureIds.find(pid) == gProcessTextureIds.end()) {
     gProcessTextureIds[pid] = std::unordered_set<uint64_t>();
   }
 
   return &gProcessTextureIds.at(pid);
 }
 
 bool
-WaitForTextureIdsToUnlock(pid_t pid, uint64_t* textureIds, uint32_t textureIdsLength)
+WaitForTextureIdsToUnlock(pid_t pid, const Span<const uint64_t>& textureIds)
 {
   {
     StaticMonitorAutoLock lock(gTextureLockMonitor);
     std::unordered_set<uint64_t>* freedTextureIds = GetLockedTextureIdsForProcess(pid);
 
+    TimeStamp start = TimeStamp::Now();
     while (true) {
       bool allCleared = true;
-      for (uint32_t i = 0; i < textureIdsLength; ++i) {
-        if (freedTextureIds->find(textureIds[i]) != freedTextureIds->end()) {
+      for (uint64_t textureId : textureIds) {
+        if (freedTextureIds->find(textureId) != freedTextureIds->end()) {
           allCleared = false;
         }
       }
 
       if (allCleared) {
         return true;
       }
 
       if (lock.Wait(TimeDuration::FromMilliseconds(kTextureLockTimeout)) == CVStatus::Timeout) {
         return false;
       }
+
+      // In case the monitor gets signaled multiple times, each less than kTextureLockTimeout.
+      // This ensures that the total time we wait is < 2 * kTextureLockTimeout
+      if ((TimeStamp::Now() - start).ToMilliseconds() > (double)kTextureLockTimeout) {
+        return false;
+      }
     }
   }
 }
 
 void
 CheckTexturesForUnlock()
 {
   for (auto& textureSourceProvider : gTextureSourceProviders) {
@@ -105,17 +112,17 @@ TextureSync::DispatchCheckTexturesForUnl
 
 void
 TextureSync::HandleWaitForTexturesMessage(MachReceiveMessage* rmsg, ipc::MemoryPorts* ports)
 {
   WaitForTexturesRequest* req = reinterpret_cast<WaitForTexturesRequest*>(rmsg->GetData());
   uint64_t* textureIds = (uint64_t*)(req + 1);
   uint32_t textureIdsLength = (rmsg->GetDataLength() - sizeof(WaitForTexturesRequest)) / sizeof(uint64_t);
 
-  bool success = WaitForTextureIdsToUnlock(req->pid, textureIds, textureIdsLength);
+  bool success = WaitForTextureIdsToUnlock(req->pid, MakeSpan<uint64_t>(textureIds, textureIdsLength));
 
   if (!success) {
     LOG_ERROR("Waiting for textures to unlock failed.\n");
   }
 
   MachSendMessage msg(ipc::kReturnWaitForTexturesMsg);
   WaitForTexturesReply replydata;
   replydata.success = success;
@@ -124,20 +131,18 @@ TextureSync::HandleWaitForTexturesMessag
   if (KERN_SUCCESS != err) {
     LOG_ERROR("SendMessage failed 0x%x %s\n", err, mach_error_string(err));
   }
 }
 
 void
 TextureSync::RegisterTextureSourceProvider(TextureSourceProvider* textureSourceProvider)
 {
-  RefPtr<TextureSourceProvider> ref(textureSourceProvider);
-  MOZ_RELEASE_ASSERT(!gTextureSourceProviders.Contains(ref));
-
-  gTextureSourceProviders.AppendElement(ref.forget());
+  MOZ_RELEASE_ASSERT(!gTextureSourceProviders.Contains(textureSourceProvider));
+  gTextureSourceProviders.AppendElement(textureSourceProvider);
 }
 
 void
 TextureSync::SetTexturesLocked(pid_t pid, const nsTArray<uint64_t>& textureIds)
 {
   StaticMonitorAutoLock mal(gTextureLockMonitor);
   std::unordered_set<uint64_t>* lockedTextureIds = GetLockedTextureIdsForProcess(pid);
   for (uint64_t textureId : textureIds) {
@@ -196,21 +201,17 @@ TextureSync::UpdateTextureLocks(base::Pr
   smsg.SetData(&aProcessId, sizeof(aProcessId));
   ipc::SharedMemoryBasic::SendMachMessage(aProcessId, smsg, NULL);
 }
 
 bool
 TextureSync::WaitForTextures(base::ProcessId aProcessId, const nsTArray<uint64_t>& textureIds)
 {
   if (aProcessId == getpid()) {
-    UniquePtr<uint64_t[]> reqTextureIds = MakeUnique<uint64_t[]>(textureIds.Length());
-    for (uint32_t i = 0; i < textureIds.Length(); ++i) {
-      reqTextureIds[i] = textureIds[i];
-    }
-    bool success = WaitForTextureIdsToUnlock(aProcessId, reqTextureIds.get(), textureIds.Length());
+    bool success = WaitForTextureIdsToUnlock(aProcessId, MakeSpan<uint64_t>(textureIds));
     if (!success) {
       LOG_ERROR("Failed waiting for textures to unlock.\n");
     }
 
     return success;
   }
 
   MachSendMessage smsg(ipc::kWaitForTexturesMsg);
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -312,16 +312,21 @@ ClientLayerManager::BeginTransaction()
   return BeginTransactionWithTarget(nullptr);
 }
 
 bool
 ClientLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
                                            void* aCallbackData,
                                            EndTransactionFlags)
 {
+  // This just causes the compositor to check whether the GPU is done with its
+  // textures or not and unlock them if it is. This helps us avoid the case
+  // where we take a long time painting asynchronously, turn IPC back on at
+  // the end of that, and then have to wait for the compositor to to get into
+  // TiledLayerBufferComposite::UseTiles before getting a response.
   if (mForwarder) {
     mForwarder->UpdateTextureLocks();
   }
 
   // Wait for any previous async paints to complete before starting to paint again.
   // Do this outside the profiler and telemetry block so this doesn't count as time
   // spent rasterizing.
   {