Send accumulated GPU process telemetry to the UI process. (bug 1304494 part 3, r=gfritzsche)

This commit is contained in:
David Anderson 2016-10-30 22:35:57 -07:00
parent fb068517da
commit ec2b48ff8b
5 changed files with 97 additions and 16 deletions

View File

@ -137,6 +137,20 @@ GPUChild::RecvNotifyUiObservers(const nsCString& aTopic)
return true;
}
bool
GPUChild::RecvAccumulateChildHistogram(InfallibleTArray<Accumulation>&& aAccumulations)
{
Telemetry::AccumulateChild(GeckoProcessType_GPU, aAccumulations);
return true;
}
bool
GPUChild::RecvAccumulateChildKeyedHistogram(InfallibleTArray<KeyedAccumulation>&& aAccumulations)
{
Telemetry::AccumulateChildKeyed(GeckoProcessType_GPU, aAccumulations);
return true;
}
void
GPUChild::ActorDestroy(ActorDestroyReason aWhy)
{

View File

@ -38,6 +38,8 @@ public:
bool RecvInitComplete(const GPUDeviceData& aData) override;
bool RecvReportCheckerboard(const uint32_t& aSeverity, const nsCString& aLog) override;
bool RecvInitCrashReporter(Shmem&& shmem) override;
bool RecvAccumulateChildHistogram(InfallibleTArray<Accumulation>&& aAccumulations) override;
bool RecvAccumulateChildKeyedHistogram(InfallibleTArray<KeyedAccumulation>&& aAccumulations) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
bool RecvGraphicsError(const nsCString& aError) override;
bool RecvNotifyUiObservers(const nsCString& aTopic) override;

View File

@ -137,6 +137,11 @@ public:
return mGPUChild;
}
// Returns whether or not a GPU process was ever launched.
bool AttemptedGPUProcess() const {
return mNumProcessAttempts > 0;
}
private:
// Called from our xpcom-shutdown observer.
void OnXPCOMShutdown();

View File

@ -14,6 +14,8 @@ using base::ProcessId from "base/process.h";
using mozilla::TimeDuration from "mozilla/TimeStamp.h";
using mozilla::CSSToLayoutDeviceScale from "Units.h";
using mozilla::gfx::IntSize from "mozilla/gfx/2D.h";
using mozilla::Telemetry::Accumulation from "mozilla/TelemetryComms.h";
using mozilla::Telemetry::KeyedAccumulation from "mozilla/TelemetryComms.h";
namespace mozilla {
namespace gfx {
@ -88,6 +90,10 @@ child:
// Have a message be broadcasted to the UI process by the UI process
// observer service.
async NotifyUiObservers(nsCString aTopic);
// Messages for reporting telemetry to the UI process.
async AccumulateChildHistogram(Accumulation[] accumulations);
async AccumulateChildKeyedHistogram(KeyedAccumulation[] accumulations);
};
} // namespace gfx

View File

@ -16,6 +16,8 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/gfx/GPUParent.h"
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/Atomics.h"
#include "mozilla/StartupTimeline.h"
#include "mozilla/StaticMutex.h"
@ -100,6 +102,7 @@ using mozilla::Telemetry::KeyedAccumulation;
#define SUBSESSION_HISTOGRAM_PREFIX "sub#"
#define KEYED_HISTOGRAM_NAME_SEPARATOR "#"
#define CONTENT_HISTOGRAM_SUFFIX "#content"
#define GPU_HISTOGRAM_SUFFIX "#gpu"
namespace {
@ -453,16 +456,12 @@ GetProcessFromName(const nsACString& aString)
if (StringEndsWith(aString, NS_LITERAL_CSTRING(CONTENT_HISTOGRAM_SUFFIX))) {
return GeckoProcessType_Content;
}
if (StringEndsWith(aString, NS_LITERAL_CSTRING(GPU_HISTOGRAM_SUFFIX))) {
return GeckoProcessType_GPU;
}
return GeckoProcessType_Default;
}
GeckoProcessType
GetProcessFromName(const std::string& aString)
{
nsDependentCString string(aString.c_str(), aString.length());
return GetProcessFromName(string);
}
const char*
SuffixForProcessType(GeckoProcessType aProcessType)
{
@ -471,6 +470,8 @@ SuffixForProcessType(GeckoProcessType aProcessType)
return nullptr;
case GeckoProcessType_Content:
return CONTENT_HISTOGRAM_SUFFIX;
case GeckoProcessType_GPU:
return GPU_HISTOGRAM_SUFFIX;
default:
MOZ_ASSERT_UNREACHABLE("unknown process type");
return nullptr;
@ -512,6 +513,7 @@ internal_GetHistogramByEnumId(mozilla::Telemetry::ID id, Histogram **ret, GeckoP
{
static Histogram* knownHistograms[mozilla::Telemetry::HistogramCount] = {0};
static Histogram* knownContentHistograms[mozilla::Telemetry::HistogramCount] = {0};
static Histogram* knownGPUHistograms[mozilla::Telemetry::HistogramCount] = {0};
Histogram** knownList = nullptr;
@ -522,6 +524,9 @@ internal_GetHistogramByEnumId(mozilla::Telemetry::ID id, Histogram **ret, GeckoP
case GeckoProcessType_Content:
knownList = knownContentHistograms;
break;
case GeckoProcessType_GPU:
knownList = knownGPUHistograms;
break;
default:
MOZ_ASSERT_UNREACHABLE("unknown process type");
return NS_ERROR_FAILURE;
@ -639,6 +644,13 @@ internal_CloneHistogram(const nsACString& newName,
#if !defined(MOZ_WIDGET_GONK) && !defined(MOZ_WIDGET_ANDROID)
GeckoProcessType
GetProcessFromName(const std::string& aString)
{
nsDependentCString string(aString.c_str(), aString.length());
return GetProcessFromName(string);
}
Histogram*
internal_GetSubsessionHistogram(Histogram& existing)
{
@ -651,6 +663,7 @@ internal_GetSubsessionHistogram(Histogram& existing)
static Histogram* subsession[mozilla::Telemetry::HistogramCount] = {};
static Histogram* subsessionContent[mozilla::Telemetry::HistogramCount] = {};
static Histogram* subsessionGPU[mozilla::Telemetry::HistogramCount] = {};
Histogram** cache = nullptr;
@ -662,6 +675,9 @@ internal_GetSubsessionHistogram(Histogram& existing)
case GeckoProcessType_Content:
cache = subsessionContent;
break;
case GeckoProcessType_GPU:
cache = subsessionGPU;
break;
default:
MOZ_ASSERT_UNREACHABLE("unknown process type");
return nullptr;
@ -2084,6 +2100,13 @@ void TelemetryHistogram::InitializeGlobalState(bool canRecordBase,
gKeyedHistograms.Put(contentId,
new KeyedHistogram(id, expiration, h.histogramType,
h.min, h.max, h.bucketCount, h.dataset));
nsCString gpuId(id);
gpuId.AppendLiteral(GPU_HISTOGRAM_SUFFIX);
gKeyedHistograms.Put(gpuId,
new KeyedHistogram(id, expiration, h.histogramType,
h.min, h.max, h.bucketCount, h.dataset));
}
}
@ -2381,6 +2404,13 @@ TelemetryHistogram::CreateHistogramSnapshots(JSContext *cx,
return NS_ERROR_FAILURE;
ret.setObject(*root_obj);
// Include the GPU process in histogram snapshots only if we actually tried
// to launch a process for it.
bool includeGPUProcess = false;
if (auto gpm = mozilla::gfx::GPUProcessManager::Get()) {
includeGPUProcess = gpm->AttemptedGPUProcess();
}
// Ensure that all the HISTOGRAM_FLAG & HISTOGRAM_COUNT histograms have
// been created, so that their values are snapshotted.
for (size_t i = 0; i < mozilla::Telemetry::HistogramCount; ++i) {
@ -2399,6 +2429,11 @@ TelemetryHistogram::CreateHistogramSnapshots(JSContext *cx,
rv = internal_GetHistogramByEnumId(id, &h, GeckoProcessType_Content);
MOZ_ASSERT(NS_SUCCEEDED(rv));
if (includeGPUProcess) {
rv = internal_GetHistogramByEnumId(id, &h, GeckoProcessType_GPU);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
}
}
@ -2687,17 +2722,36 @@ TelemetryHistogram::IPCTimerFired(nsITimer* aTimer, void* aClosure)
}
}
mozilla::dom::ContentChild* contentChild = mozilla::dom::ContentChild::GetSingleton();
mozilla::Unused << NS_WARN_IF(!contentChild);
if (contentChild) {
if (accumulationsToSend.Length()) {
mozilla::Unused <<
NS_WARN_IF(!contentChild->SendAccumulateChildHistogram(accumulationsToSend));
switch (XRE_GetProcessType()) {
case GeckoProcessType_Content: {
mozilla::dom::ContentChild* contentChild = mozilla::dom::ContentChild::GetSingleton();
mozilla::Unused << NS_WARN_IF(!contentChild);
if (contentChild) {
if (accumulationsToSend.Length()) {
mozilla::Unused <<
NS_WARN_IF(!contentChild->SendAccumulateChildHistogram(accumulationsToSend));
}
if (keyedAccumulationsToSend.Length()) {
mozilla::Unused <<
NS_WARN_IF(!contentChild->SendAccumulateChildKeyedHistogram(keyedAccumulationsToSend));
}
}
break;
}
if (keyedAccumulationsToSend.Length()) {
mozilla::Unused <<
NS_WARN_IF(!contentChild->SendAccumulateChildKeyedHistogram(keyedAccumulationsToSend));
case GeckoProcessType_GPU: {
if (mozilla::gfx::GPUParent* gpu = mozilla::gfx::GPUParent::GetSingleton()) {
if (accumulationsToSend.Length()) {
mozilla::Unused << gpu->SendAccumulateChildHistogram(accumulationsToSend);
}
if (keyedAccumulationsToSend.Length()) {
mozilla::Unused << gpu->SendAccumulateChildKeyedHistogram(keyedAccumulationsToSend);
}
}
break;
}
default:
MOZ_ASSERT_UNREACHABLE("Unsupported process type");
break;
}
gIPCTimerArmed = false;