Bug 1337062 - Transfer initial gfxVars with SendSetXPCOMProcessAttributes - r=dvander
MozReview-Commit-ID: 5gJjiyTct5X
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -520,17 +520,17 @@ NS_INTERFACE_MAP_END
mozilla::ipc::IPCResult
ContentChild::RecvSetXPCOMProcessAttributes(const XPCOMInitData& aXPCOMInit,
const StructuredCloneData& aInitialData,
nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache)
{
mLookAndFeelCache = aLookAndFeelIntCache;
InitXPCOM(aXPCOMInit, aInitialData);
- InitGraphicsDeviceData();
+ 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();
#endif
@@ -961,21 +961,21 @@ ContentChild::AppendProcessId(nsACString
if (!aName.IsEmpty()) {
aName.Append(' ');
}
unsigned pid = getpid();
aName.Append(nsPrintfCString("(pid %u)", pid));
}
void
-ContentChild::InitGraphicsDeviceData()
+ContentChild::InitGraphicsDeviceData(const ContentDeviceData& aData)
{
// Initialize the graphics platform. This may contact the parent process
// to read device preferences.
- gfxPlatform::GetPlatform();
+ gfxPlatform::InitChild(aData);
}
void
ContentChild::InitXPCOM(const XPCOMInitData& aXPCOMInit,
const mozilla::dom::ipc::StructuredCloneData& aInitialData)
{
SET_PREF_PHASE(pref_initPhase::BEGIN_ALL_PREFS);
for (unsigned int i = 0; i < aXPCOMInit.prefs().Length(); i++) {
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -101,17 +101,17 @@ public:
base::ProcessId aParentPid,
IPC::Channel* aChannel,
uint64_t aChildID,
bool aIsForBrowser);
void InitXPCOM(const XPCOMInitData& aXPCOMInit,
const mozilla::dom::ipc::StructuredCloneData& aInitialData);
- void InitGraphicsDeviceData();
+ void InitGraphicsDeviceData(const ContentDeviceData& aData);
static ContentChild* GetSingleton()
{
return sSingleton;
}
const AppInfo& GetAppInfo()
{
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2229,16 +2229,18 @@ 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());
}
+ gfxPlatform::GetPlatform()->BuildContentDeviceData(&xpcomInit.contentDeviceData());
+
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;
gfxFeatureStatus.feature() = i;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -263,16 +263,17 @@ struct XPCOMInitData
bool haveBidiKeyboards;
nsString[] dictionaries;
ClipboardCapabilities clipboardCaps;
DomainPolicyClone domainPolicy;
/* used on MacOSX only */
FontFamilyListEntry[] fontFamilies;
OptionalURIParams userContentSheetURL;
PrefSetting[] prefs;
+ ContentDeviceData contentDeviceData;
GfxInfoFeatureStatus[] gfxFeatureStatus;
DataStorageEntry[] dataStorage;
nsCString[] appLocales;
nsCString[] requestedLocales;
};
/**
* The PContent protocol is a top-level protocol between the UI process
--- a/gfx/ipc/D3DMessageUtils.cpp
+++ b/gfx/ipc/D3DMessageUtils.cpp
@@ -42,18 +42,16 @@ ParamTraits<DxgiAdapterDesc>::Write(Mess
WriteParam(aMsg, aParam.DeviceId);
WriteParam(aMsg, aParam.SubSysId);
WriteParam(aMsg, aParam.Revision);
WriteParam(aMsg, aParam.DedicatedVideoMemory);
WriteParam(aMsg, aParam.DedicatedSystemMemory);
WriteParam(aMsg, aParam.SharedSystemMemory);
WriteParam(aMsg, aParam.AdapterLuid.LowPart);
WriteParam(aMsg, aParam.AdapterLuid.HighPart);
-#else
- MOZ_ASSERT_UNREACHABLE("DxgiAdapterDesc is Windows-only");
#endif
}
bool
ParamTraits<DxgiAdapterDesc>::Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
#if defined(XP_WIN)
if (!aMsg->ReadBytesInto(aIter, aResult->Description, sizeof(aResult->Description))) {
@@ -67,15 +65,15 @@ ParamTraits<DxgiAdapterDesc>::Read(const
ReadParam(aMsg, aIter, &aResult->DedicatedVideoMemory) &&
ReadParam(aMsg, aIter, &aResult->DedicatedSystemMemory) &&
ReadParam(aMsg, aIter, &aResult->SharedSystemMemory) &&
ReadParam(aMsg, aIter, &aResult->AdapterLuid.LowPart) &&
ReadParam(aMsg, aIter, &aResult->AdapterLuid.HighPart))
{
return true;
}
+ return false;
#else
- MOZ_ASSERT_UNREACHABLE("DxgiAdapterDesc is Windows-only");
+ return true;
#endif
- return false;
}
} // namespace IPC
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -147,16 +147,18 @@ void ShutdownTileCache();
using namespace mozilla;
using namespace mozilla::layers;
using namespace mozilla::gl;
using namespace mozilla::gfx;
gfxPlatform *gPlatform = nullptr;
static bool gEverInitialized = false;
+const ContentDeviceData* gContentDeviceInitData = nullptr;
+
static Mutex* gGfxPlatformPrefsLock = nullptr;
// These two may point to the same profile
static qcms_profile *gCMSOutputProfile = nullptr;
static qcms_profile *gCMSsRGBProfile = nullptr;
static qcms_transform *gCMSRGBTransform = nullptr;
static qcms_transform *gCMSInverseRGBTransform = nullptr;
@@ -522,27 +524,42 @@ gfxPlatform::gfxPlatform()
VRManager::ManagerInit();
}
gfxPlatform*
gfxPlatform::GetPlatform()
{
if (!gPlatform) {
+ MOZ_RELEASE_ASSERT(!XRE_IsContentProcess(),
+ "Content Process should have called InitChild() before first GetPlatform()");
Init();
}
return gPlatform;
}
bool
gfxPlatform::Initialized()
{
return !!gPlatform;
}
+/* static */ void
+gfxPlatform::InitChild(const ContentDeviceData& aData)
+{
+ MOZ_ASSERT(XRE_IsContentProcess());
+ MOZ_RELEASE_ASSERT(!gPlatform,
+ "InitChild() should be called before first GetPlatform()");
+ // Make the provided initial ContentDeviceData available to the init
+ // routines, so they don't have to do a sync request from the parent.
+ gContentDeviceInitData = &aData;
+ Init();
+ gContentDeviceInitData = nullptr;
+}
+
void RecordingPrefChanged(const char *aPrefName, void *aClosure)
{
if (Preferences::GetBool("gfx.2d.recording", false)) {
nsAutoCString fileName;
nsAdoptingString prefFileName = Preferences::GetString("gfx.2d.recordingfile");
if (prefFileName) {
fileName.Append(NS_ConvertUTF16toUTF8(prefFileName));
@@ -2666,16 +2683,21 @@ gfxPlatform::NotifyGPUProcessDisabled()
}
}
void
gfxPlatform::FetchAndImportContentDeviceData()
{
MOZ_ASSERT(XRE_IsContentProcess());
+ if (gContentDeviceInitData) {
+ ImportContentDeviceData(*gContentDeviceInitData);
+ return;
+ }
+
mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
mozilla::gfx::ContentDeviceData data;
cc->SendGetGraphicsDeviceInitData(&data);
ImportContentDeviceData(data);
}
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -170,16 +170,22 @@ public:
static bool Initialized();
/**
* Shut down Thebes.
* Init() arranges for this to be called at an appropriate time.
*/
static void Shutdown();
+ /**
+ * Initialize gfxPlatform (if not already done) in a child process, with
+ * the provided ContentDeviceData.
+ */
+ static void InitChild(const mozilla::gfx::ContentDeviceData& aData);
+
static void InitLayersIPC();
static void ShutdownLayersIPC();
/**
* Initialize ScrollMetadata statics. Does not depend on gfxPlatform.
*/
static void InitNullMetadata();