Bug 1275314 - Allow flushing in-progress checkerboard reports in the GPU process as well. r?dvander
MozReview-Commit-ID: D1tfkLBPSHi
--- 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
@@ -292,16 +292,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) {
+ nsCString topic(aTopic);
+ mGPUChild->SendNotifyGpuObservers(topic);
+ return true;
+ }
+ return false;
+}
+
} // 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);
}
}