Bug 1337062 - Transfer initial gfxVars with SendSetXPCOMProcessAttributes - r?dvander
The content process stores the incoming initial gfxVars updates, which are
lazily used when the gfxVars are first initialized.
MozReview-Commit-ID: ExUVdr5xGLb
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -518,16 +518,17 @@ NS_INTERFACE_MAP_END
mozilla::ipc::IPCResult
ContentChild::RecvSetXPCOMProcessAttributes(const XPCOMInitData& aXPCOMInit,
const StructuredCloneData& aInitialData,
nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache)
{
mLookAndFeelCache = aLookAndFeelIntCache;
+ gfx::gfxVars::GotInitialVarUpdates(aXPCOMInit.gfxNonDefaultVarUpdates());
InitXPCOM(aXPCOMInit, aInitialData);
InitGraphicsDeviceData(aXPCOMInit.contentDeviceData());
#ifdef NS_PRINTING
// Force the creation of the nsPrintingProxy so that it's IPC counterpart,
// PrintingParent, is always available for printing initiated from the parent.
// Create nsPrintingProxy instance later than the SystemGroup initialization.
RefPtr<nsPrintingProxy> printingProxy = nsPrintingProxy::GetInstance();
@@ -956,18 +957,16 @@ ContentChild::AppendProcessId(nsACString
}
unsigned pid = getpid();
aName.Append(nsPrintfCString("(pid %u)", pid));
}
void
ContentChild::InitGraphicsDeviceData(const ContentDeviceData& aData)
{
- // Initialize the graphics platform. This may contact the parent process
- // to read device preferences.
gfxPlatform::InitChild(aData);
}
void
ContentChild::InitXPCOM(const XPCOMInitData& aXPCOMInit,
const mozilla::dom::ipc::StructuredCloneData& aInitialData)
{
SET_PREF_PHASE(pref_initPhase::BEGIN_ALL_PREFS);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2224,17 +2224,22 @@ ContentParent::InitInternal(ProcessPrior
// send the file URL instead.
StyleSheet* ucs = nsLayoutStylesheetCache::For(StyleBackendType::Gecko)->UserContentSheet();
if (ucs) {
SerializeURI(ucs->GetSheetURI(), xpcomInit.userContentSheetURL());
} else {
SerializeURI(nullptr, xpcomInit.userContentSheetURL());
}
+ // 1. Build ContentDeviceData first, as it may affect some gfxVars.
gfxPlatform::GetPlatform()->BuildContentDeviceData(&xpcomInit.contentDeviceData());
+ // 2. Gather non-default gfxVars.
+ xpcomInit.gfxNonDefaultVarUpdates() = gfxVars::FetchNonDefaultVars();
+ // 3. Start listening for gfxVars updates, to notify content process later on.
+ gfxVars::AddReceiver(this);
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
if (gfxInfo) {
for (int32_t i = 1; i <= nsIGfxInfo::FEATURE_MAX_VALUE; ++i) {
int32_t status = 0;
nsAutoCString failureId;
gfxInfo->GetFeatureStatus(i, failureId, &status);
dom::GfxInfoFeatureStatus gfxFeatureStatus;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -262,16 +262,17 @@ struct XPCOMInitData
bool haveBidiKeyboards;
nsString[] dictionaries;
ClipboardCapabilities clipboardCaps;
DomainPolicyClone domainPolicy;
/* used on MacOSX only */
FontFamilyListEntry[] fontFamilies;
OptionalURIParams userContentSheetURL;
PrefSetting[] prefs;
+ GfxVarUpdate[] gfxNonDefaultVarUpdates;
ContentDeviceData contentDeviceData;
GfxInfoFeatureStatus[] gfxFeatureStatus;
DataStorageEntry[] dataStorage;
nsCString[] appLocales;
nsCString[] requestedLocales;
};
/**
--- a/gfx/config/gfxVars.cpp
+++ b/gfx/config/gfxVars.cpp
@@ -9,37 +9,55 @@
#include "mozilla/dom/ContentChild.h"
namespace mozilla {
namespace gfx {
StaticAutoPtr<gfxVars> gfxVars::sInstance;
StaticAutoPtr<nsTArray<gfxVars::VarBase*>> gfxVars::sVarList;
+StaticAutoPtr<nsTArray<GfxVarUpdate>> gGfxVarInitUpdates;
+
+void
+gfxVars::GotInitialVarUpdates(const nsTArray<GfxVarUpdate>& aInitUpdates)
+{
+ // We expect aInitUpdates to be provided before any other gfxVars operation.
+ MOZ_RELEASE_ASSERT(!sInstance, "Initial updates should not be provided after any gfxVars operation");
+
+ gGfxVarInitUpdates = new nsTArray<GfxVarUpdate>(aInitUpdates);
+}
+
void
gfxVars::Initialize()
{
if (sInstance) {
+ // We expect aInitUpdates to be provided before any other gfxVars operation.
+ MOZ_RELEASE_ASSERT(!gGfxVarInitUpdates, "Initial updates should not be present after any gfxVars operation");
return;
}
// sVarList must be initialized first since it's used in the constructor for
// sInstance.
sVarList = new nsTArray<gfxVars::VarBase*>();
sInstance = new gfxVars;
- // Like Preferences, we want content to synchronously get initial data on
- // init. Note the GPU process is not handled here - it cannot send sync
+ // Note the GPU process is not handled here - it cannot send sync
// messages, so instead the initial data is pushed down.
if (XRE_IsContentProcess()) {
- InfallibleTArray<GfxVarUpdate> vars;
- dom::ContentChild::GetSingleton()->SendGetGfxVars(&vars);
- for (const auto& var : vars) {
- ApplyUpdate(var);
+ MOZ_RELEASE_ASSERT(gGfxVarInitUpdates, "Initial updates must be provided in content process");
+ if (!gGfxVarInitUpdates) {
+ // No provided initial updates, sync-request them from parent.
+ InfallibleTArray<GfxVarUpdate> initUpdates;
+ dom::ContentChild::GetSingleton()->SendGetGfxVars(&initUpdates);
+ gGfxVarInitUpdates = new nsTArray<GfxVarUpdate>(Move(initUpdates));
}
+ for (const auto& varUpdate : *gGfxVarInitUpdates) {
+ ApplyUpdate(varUpdate);
+ }
+ gGfxVarInitUpdates = nullptr;
}
}
gfxVars::gfxVars()
{
}
void
--- a/gfx/config/gfxVars.h
+++ b/gfx/config/gfxVars.h
@@ -52,16 +52,17 @@ class gfxVarReceiver;
// void SetCxxName(const DataType& aValue);
//
// Note that the setter may only be called in the UI process; a gfxVar must be
// a variable that is determined in the UI process and pushed to child
// processes.
class gfxVars final
{
public:
+ static void GotInitialVarUpdates(const nsTArray<GfxVarUpdate>& aInitUpdates);
static void Initialize();
static void Shutdown();
static void ApplyUpdate(const GfxVarUpdate& aUpdate);
static void AddReceiver(gfxVarReceiver* aReceiver);
static void RemoveReceiver(gfxVarReceiver* aReceiver);
// Return a list of updates for all variables with non-default values.