Bug 1275314 - Allow flushing in-progress checkerboard reports in the GPU process as well. r=dvander
authorKartikaya Gupta <kgupta@mozilla.com>
Sat, 15 Oct 2016 08:45:02 -0400
changeset 425764 6fba47ac1541b9110be41ae32fff637f973f550e
parent 425763 0151fc9f97a22552499a49e81fd377516e3eb616
child 425765 db8c5ee6d069306d5b5553e0ec6f2bb6d2224036
push id32504
push userbmo:gasolin@mozilla.com
push dateMon, 17 Oct 2016 02:37:54 +0000
reviewersdvander
bugs1275314
milestone52.0a1
Bug 1275314 - Allow flushing in-progress checkerboard reports in the GPU process as well. r=dvander MozReview-Commit-ID: CXLzkiloHW
gfx/ipc/GPUChild.cpp
gfx/ipc/GPUChild.h
gfx/ipc/GPUParent.cpp
gfx/ipc/GPUParent.h
gfx/ipc/GPUProcessManager.cpp
gfx/ipc/GPUProcessManager.h
gfx/ipc/PGPU.ipdl
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/util/CheckerboardReportService.cpp
--- a/gfx/ipc/GPUChild.cpp
+++ b/gfx/ipc/GPUChild.cpp
@@ -118,16 +118,27 @@ bool
 GPUChild::RecvInitCrashReporter(Shmem&& aShmem)
 {
 #ifdef MOZ_CRASHREPORTER
   mCrashReporter = MakeUnique<ipc::CrashReporterHost>(GeckoProcessType_GPU, aShmem);
 #endif
   return true;
 }
 
+bool
+GPUChild::RecvNotifyUiObservers(const nsCString& aTopic)
+{
+  nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
+  MOZ_ASSERT(obsSvc);
+  if (obsSvc) {
+    obsSvc->NotifyObservers(nullptr, aTopic.get(), nullptr);
+  }
+  return true;
+}
+
 void
 GPUChild::ActorDestroy(ActorDestroyReason aWhy)
 {
   if (aWhy == AbnormalShutdown) {
 #ifdef MOZ_CRASHREPORTER
     if (mCrashReporter) {
       mCrashReporter->GenerateCrashReport(OtherPid());
       mCrashReporter = nullptr;
--- a/gfx/ipc/GPUChild.h
+++ b/gfx/ipc/GPUChild.h
@@ -35,16 +35,17 @@ public:
   void OnVarChanged(const GfxVarUpdate& aVar) override;
 
   // PGPUChild overrides.
   bool RecvInitComplete(const GPUDeviceData& aData) override;
   bool RecvReportCheckerboard(const uint32_t& aSeverity, const nsCString& aLog) override;
   bool RecvInitCrashReporter(Shmem&& shmem) override;
   void ActorDestroy(ActorDestroyReason aWhy) override;
   bool RecvGraphicsError(const nsCString& aError) override;
+  bool RecvNotifyUiObservers(const nsCString& aTopic) override;
 
   static void Destroy(UniquePtr<GPUChild>&& aChild);
 
 private:
   GPUProcessHost* mHost;
   UniquePtr<ipc::CrashReporterHost> mCrashReporter;
   bool mGPUReady;
 };
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -300,16 +300,27 @@ GPUParent::RecvDeallocateLayerTreeId(con
 
 bool
 GPUParent::RecvAddLayerTreeIdMapping(const uint64_t& aLayersId, const ProcessId& aOwnerId)
 {
   LayerTreeOwnerTracker::Get()->Map(aLayersId, aOwnerId);
   return true;
 }
 
+bool
+GPUParent::RecvNotifyGpuObservers(const nsCString& aTopic)
+{
+  nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
+  MOZ_ASSERT(obsSvc);
+  if (obsSvc) {
+    obsSvc->NotifyObservers(nullptr, aTopic.get(), nullptr);
+  }
+  return true;
+}
+
 void
 GPUParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   if (AbnormalShutdown == aWhy) {
     NS_WARNING("Shutting down GPU process early due to a crash!");
     ProcessChild::QuickExit();
   }
 
--- a/gfx/ipc/GPUParent.h
+++ b/gfx/ipc/GPUParent.h
@@ -42,16 +42,17 @@ public:
     const IntSize& aSurfaceSize) override;
   bool RecvNewContentCompositorBridge(Endpoint<PCompositorBridgeParent>&& aEndpoint) override;
   bool RecvNewContentImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) override;
   bool RecvNewContentVRManager(Endpoint<PVRManagerParent>&& aEndpoint) override;
   bool RecvNewContentVideoDecoderManager(Endpoint<PVideoDecoderManagerParent>&& aEndpoint) override;
   bool RecvDeallocateLayerTreeId(const uint64_t& aLayersId) override;
   bool RecvGetDeviceStatus(GPUDeviceData* aOutStatus) override;
   bool RecvAddLayerTreeIdMapping(const uint64_t& aLayersId, const ProcessId& aOwnerId) override;
+  bool RecvNotifyGpuObservers(const nsCString& aTopic) override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
 private:
   RefPtr<VsyncBridgeParent> mVsyncBridge;
 };
 
 } // namespace gfx
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -735,10 +735,21 @@ GPUProcessManager::AddListener(GPUProces
 }
 
 void
 GPUProcessManager::RemoveListener(GPUProcessListener* aListener)
 {
   mListeners.RemoveElement(aListener);
 }
 
+bool
+GPUProcessManager::NotifyGpuObservers(const char* aTopic)
+{
+  if (!mGPUChild) {
+    return false;
+  }
+  nsCString topic(aTopic);
+  mGPUChild->SendNotifyGpuObservers(topic);
+  return true;
+}
+
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/ipc/GPUProcessManager.h
+++ b/gfx/ipc/GPUProcessManager.h
@@ -123,16 +123,20 @@ public:
 
   // Notify the GPUProcessManager that a top-level PGPU protocol has been
   // terminated. This may be called from any thread.
   void NotifyRemoteActorDestroyed(const uint64_t& aProcessToken);
 
   void AddListener(GPUProcessListener* aListener);
   void RemoveListener(GPUProcessListener* aListener);
 
+  // Send a message to the GPU process observer service to broadcast. Returns
+  // true if the message was sent, false if not.
+  bool NotifyGpuObservers(const char* aTopic);
+
   // Returns access to the PGPU protocol if a GPU process is present.
   GPUChild* GetGPUChild() {
     return mGPUChild;
   }
 
 private:
   // Called from our xpcom-shutdown observer.
   void OnXPCOMShutdown();
--- a/gfx/ipc/PGPU.ipdl
+++ b/gfx/ipc/PGPU.ipdl
@@ -63,24 +63,32 @@ parent:
 
   // Called to notify the GPU process of who owns a layersId.
   sync AddLayerTreeIdMapping(uint64_t layersId, ProcessId ownerId);
 
   // Request the current DeviceStatus from the GPU process. This blocks until
   // one is available (i.e., Init has completed).
   sync GetDeviceStatus() returns (GPUDeviceData status);
 
+  // Have a message be broadcasted to the GPU process by the GPU process
+  // observer service.
+  async NotifyGpuObservers(nsCString aTopic);
+
 child:
   // Sent when the GPU process has initialized devices. This occurs once, after
   // Init().
   async InitComplete(GPUDeviceData data);
 
   // Sent when APZ detects checkerboarding and apz checkerboard reporting is enabled.
   async ReportCheckerboard(uint32_t severity, nsCString log);
 
   // Graphics errors, analogous to PContent::GraphicsError
   async GraphicsError(nsCString aError);
 
   async InitCrashReporter(Shmem shmem);
+
+  // Have a message be broadcasted to the UI process by the UI process
+  // observer service.
+  async NotifyUiObservers(nsCString aTopic);
 };
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -9,16 +9,17 @@
 #include "Compositor.h"                 // for Compositor
 #include "DragTracker.h"                // for DragTracker
 #include "gfxPrefs.h"                   // for gfxPrefs
 #include "HitTestingTreeNode.h"         // for HitTestingTreeNode
 #include "InputBlockState.h"            // for InputBlockState
 #include "InputData.h"                  // for InputData, etc
 #include "Layers.h"                     // for Layer, etc
 #include "mozilla/dom/Touch.h"          // for Touch
+#include "mozilla/gfx/GPUParent.h"      // for GPUParent
 #include "mozilla/gfx/Logging.h"        // for gfx::TreeLog
 #include "mozilla/gfx/Point.h"          // for Point
 #include "mozilla/layers/APZThreadUtils.h"  // for AssertOnCompositorThread, etc
 #include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform
 #include "mozilla/layers/AsyncDragMetrics.h" // for AsyncDragMetrics
 #include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent, etc
 #include "mozilla/layers/LayerMetricsWrapper.h"
 #include "mozilla/MouseEvents.h"
@@ -133,20 +134,27 @@ APZCTreeManager::CheckerboardFlushObserv
         [](HitTestingTreeNode* aNode)
         {
           if (aNode->IsPrimaryHolder()) {
             MOZ_ASSERT(aNode->GetApzc());
             aNode->GetApzc()->FlushActiveCheckerboardReport();
           }
         });
   }
-  MOZ_ASSERT(XRE_IsParentProcess());
-  nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
-  if (obsSvc) {
-    obsSvc->NotifyObservers(nullptr, "APZ:FlushActiveCheckerboard:Done", nullptr);
+  if (XRE_IsGPUProcess()) {
+    if (gfx::GPUParent* gpu = gfx::GPUParent::GetSingleton()) {
+      nsCString topic("APZ:FlushActiveCheckerboard:Done");
+      Unused << gpu->SendNotifyUiObservers(topic);
+    }
+  } else {
+    MOZ_ASSERT(XRE_IsParentProcess());
+    nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
+    if (obsSvc) {
+      obsSvc->NotifyObservers(nullptr, "APZ:FlushActiveCheckerboard:Done", nullptr);
+    }
   }
   return NS_OK;
 }
 
 
 /*static*/ const ScreenMargin
 APZCTreeManager::CalculatePendingDisplayPort(
   const FrameMetrics& aFrameMetrics,
--- a/gfx/layers/apz/util/CheckerboardReportService.cpp
+++ b/gfx/layers/apz/util/CheckerboardReportService.cpp
@@ -8,16 +8,17 @@
 #include "gfxPrefs.h" // for gfxPrefs
 #include "jsapi.h" // for JS_Now
 #include "MainThreadUtils.h" // for NS_IsMainThread
 #include "mozilla/Assertions.h" // for MOZ_ASSERT
 #include "mozilla/ClearOnShutdown.h" // for ClearOnShutdown
 #include "mozilla/Unused.h"
 #include "mozilla/dom/CheckerboardReportServiceBinding.h" // for dom::CheckerboardReports
 #include "mozilla/gfx/GPUParent.h"
+#include "mozilla/gfx/GPUProcessManager.h"
 #include "nsContentUtils.h" // for nsContentUtils
 #include "nsXULAppAPI.h"
 
 namespace mozilla {
 namespace layers {
 
 /*static*/ StaticRefPtr<CheckerboardEventStorage> CheckerboardEventStorage::sInstance;
 
@@ -206,16 +207,20 @@ CheckerboardReportService::SetRecordingE
 {
   gfxPrefs::SetAPZRecordCheckerboarding(aEnabled);
 }
 
 void
 CheckerboardReportService::FlushActiveReports()
 {
   MOZ_ASSERT(XRE_IsParentProcess());
+  gfx::GPUProcessManager* gpu = gfx::GPUProcessManager::Get();
+  if (gpu && gpu->NotifyGpuObservers("APZ:FlushActiveCheckerboard")) {
+    return;
+  }
 
   nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
   MOZ_ASSERT(obsSvc);
   if (obsSvc) {
     obsSvc->NotifyObservers(nullptr, "APZ:FlushActiveCheckerboard", nullptr);
   }
 }