Bug 1248450: Send the graphics messages to the parent process. r=dvander
MozReview-Commit-ID: EshCrdT5lYu
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -5693,16 +5693,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
@@ -1007,16 +1007,18 @@ private:
virtual bool RecvAllocateLayerTreeId(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
@@ -1011,16 +1011,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
@@ -205,16 +205,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