Bug 1248450: Send the graphics messages to the parent process. r=dvander
authorMilan Sreckovic <milan@mozilla.com>
Tue, 16 Feb 2016 18:07:37 -0500
changeset 331622 22d0921df35a835486e42e258487bcb1d82567af
parent 331621 266e1a6642b10ac593587674119db65f6aeb0da5
child 331623 1594c41619ffbb23ef02de913fc96236d516cac5
push id11020
push userjolesen@mozilla.com
push dateWed, 17 Feb 2016 18:16:38 +0000
reviewersdvander
bugs1248450
milestone47.0a1
Bug 1248450: Send the graphics messages to the parent process. r=dvander MozReview-Commit-ID: EshCrdT5lYu
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
gfx/2d/Logging.h
gfx/thebes/gfxPlatform.cpp
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -5759,16 +5759,28 @@ ContentParent::RecvProfile(const nsCStri
 bool
 ContentParent::RecvGetGraphicsDeviceInitData(DeviceInitData* aOut)
 {
   gfxPlatform::GetPlatform()->GetDeviceInitData(aOut);
   return true;
 }
 
 bool
+ContentParent::RecvGraphicsError(const nsCString& aError)
+{
+  gfx::LogForwarder* lf = gfx::Factory::GetLogForwarder();
+  if (lf) {
+    std::stringstream message;
+    message << "CP+" << aError.get();
+    lf->UpdateStringsVector(message.str());
+  }
+  return true;
+}
+
+bool
 ContentParent::RecvBeginDriverCrashGuard(const uint32_t& aGuardType, bool* aOutCrashed)
 {
   // Only one driver crash guard should be active at a time, per-process.
   MOZ_ASSERT(!mDriverCrashGuard);
 
   UniquePtr<gfx::DriverCrashGuard> guard;
   switch (gfx::CrashGuardType(aGuardType)) {
   case gfx::CrashGuardType::D3D11Layers:
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -1020,16 +1020,18 @@ private:
                                        uint64_t* aId) override;
 
   virtual bool RecvDeallocateLayerTreeId(const uint64_t& aId) override;
 
   virtual bool RecvGetGraphicsFeatureStatus(const int32_t& aFeature,
                                             int32_t* aStatus,
                                             bool* aSuccess) override;
 
+  virtual bool RecvGraphicsError(const nsCString& aError) override;
+
   virtual bool
   RecvBeginDriverCrashGuard(const uint32_t& aGuardType,
                             bool* aOutCrashed) override;
 
   virtual bool RecvEndDriverCrashGuard(const uint32_t& aGuardType) override;
 
   virtual bool RecvAddIdleObserver(const uint64_t& observerId,
                                    const uint32_t& aIdleTimeInS) override;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -1015,16 +1015,19 @@ parent:
      */
     async RecordingDeviceEvents(nsString recordingStatus,
                                 nsString pageURL,
                                 bool isAudio,
                                 bool isVideo);
 
     sync GetGraphicsFeatureStatus(int32_t aFeature) returns (int32_t aStatus, bool aSuccess);
 
+    // Graphics errors
+    async GraphicsError(nsCString aError);
+
     // Driver crash guards. aGuardType must be a member of CrashGuardType.
     sync BeginDriverCrashGuard(uint32_t aGuardType) returns (bool crashDetected);
     sync EndDriverCrashGuard(uint32_t aGuardType);
 
     async AddIdleObserver(uint64_t observerId, uint32_t idleTimeInS);
     async RemoveIdleObserver(uint64_t observerId, uint32_t idleTimeInS);
 
     /**
--- a/gfx/2d/Logging.h
+++ b/gfx/2d/Logging.h
@@ -206,16 +206,17 @@ typedef mozilla::Tuple<int32_t,std::stri
 // Implement this interface and init the Factory with an instance to
 // forward critical logs.
 typedef std::vector<LoggingRecordEntry> LoggingRecord;
 class LogForwarder {
 public:
   virtual ~LogForwarder() {}
   virtual void Log(const std::string &aString) = 0;
   virtual void CrashAction(LogReason aReason) = 0;
+  virtual bool UpdateStringsVector(const std::string& aString) = 0;
 
   // Provide a copy of the logs to the caller.
   virtual LoggingRecord LoggingRecordCopy() = 0;
 };
 
 class NoLog
 {
 public:
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -191,24 +191,24 @@ public:
 /// this gets called to be large - it is meant for critical errors only.
 
 class CrashStatsLogForwarder: public mozilla::gfx::LogForwarder
 {
 public:
   explicit CrashStatsLogForwarder(const char* aKey);
   virtual void Log(const std::string& aString) override;
   virtual void CrashAction(LogReason aReason) override;
+  virtual bool UpdateStringsVector(const std::string& aString) override;
 
   virtual LoggingRecord LoggingRecordCopy() override;
 
   void SetCircularBufferSize(uint32_t aCapacity);
 
 private:
-  // Helpers for the Log()
-  bool UpdateStringsVector(const std::string& aString);
+  // Helper for the Log()
   void UpdateCrashReport();
 
 private:
   LoggingRecord mBuffer;
   nsCString mCrashCriticalKey;
   uint32_t mMaxCapacity;
   int32_t mIndex;
   Mutex mMutex;
@@ -266,39 +266,78 @@ CrashStatsLogForwarder::UpdateStringsVec
     mBuffer[index] = newEntry;
   }
   return true;
 }
 
 void CrashStatsLogForwarder::UpdateCrashReport()
 {
   std::stringstream message;
-  for(LoggingRecord::iterator it = mBuffer.begin(); it != mBuffer.end(); ++it) {
-    message << "|[" << Get<0>(*it) << "]" << Get<1>(*it) << " (t=" << Get<2>(*it) << ") ";
+  if (XRE_IsParentProcess()) {
+    for(LoggingRecord::iterator it = mBuffer.begin(); it != mBuffer.end(); ++it) {
+      message << "|[" << Get<0>(*it) << "]" << Get<1>(*it) << " (t=" << Get<2>(*it) << ") ";
+    }
+  } else {
+    for(LoggingRecord::iterator it = mBuffer.begin(); it != mBuffer.end(); ++it) {
+      message << "|[C" << Get<0>(*it) << "]" << Get<1>(*it) << " (t=" << Get<2>(*it) << ") ";
+    }
   }
 
 #ifdef MOZ_CRASHREPORTER
   nsCString reportString(message.str().c_str());
   nsresult annotated = CrashReporter::AnnotateCrashReport(mCrashCriticalKey, reportString);
 #else
   nsresult annotated = NS_ERROR_NOT_IMPLEMENTED;
 #endif
   if (annotated != NS_OK) {
     printf("Crash Annotation %s: %s",
            mCrashCriticalKey.get(), message.str().c_str());
   }
 }
 
+class LogForwarderEvent : public nsRunnable
+{
+  virtual ~LogForwarderEvent() {}
+
+  NS_DECL_ISUPPORTS_INHERITED
+
+  explicit LogForwarderEvent(const nsCString& aMessage) : mMessage(aMessage) {}
+
+  NS_IMETHOD Run() override {
+    MOZ_ASSERT(NS_IsMainThread() && XRE_IsContentProcess());
+    dom::ContentChild* cc = dom::ContentChild::GetSingleton();
+    cc->SendGraphicsError(mMessage);
+    return NS_OK;
+  }
+
+protected:
+  nsCString mMessage;
+};
+
+NS_IMPL_ISUPPORTS_INHERITED0(LogForwarderEvent, nsRunnable);
+
 void CrashStatsLogForwarder::Log(const std::string& aString)
 {
   MutexAutoLock lock(mMutex);
 
   if (UpdateStringsVector(aString)) {
     UpdateCrashReport();
   }
+
+  // Add it to the parent strings
+  if (!XRE_IsParentProcess()) {
+    nsCString stringToSend(aString.c_str());
+    if (NS_IsMainThread()) {
+      dom::ContentChild* cc = dom::ContentChild::GetSingleton();
+      cc->SendGraphicsError(stringToSend);
+    } else {
+      nsCOMPtr<nsIRunnable> r1 = new LogForwarderEvent(stringToSend);
+      NS_DispatchToMainThread(r1);
+    }
+  }
 }
 
 class CrashTelemetryEvent : public nsRunnable
 {
   virtual ~CrashTelemetryEvent() {}
 
   NS_DECL_ISUPPORTS_INHERITED