From 65292a10f3ec0f3c18e746b85388ddf4e1c6927e Mon Sep 17 00:00:00 2001 From: Chris Martin Date: Thu, 26 Mar 2020 13:44:56 +0000 Subject: [PATCH] Bug 1540776 - Have parent send color profile to child during launch r=aosmond,jld,jfkthame For Win32k lockdown, we need to remove the content processes' ability to call GetICMProfileW(). Since it needs this to retrieve the output color profile, a new synchronous call is added that allows it to request the parent process to read this file on its behalf. The contents of the file are now being cached as well, as this should help ease some of the increased parent process I/O caused by the children not being able to do this in their process anymore. For performance reasons, during launch this information is passed directly to the child through the SetXPCOMProcessAttributes call Differential Revision: https://phabricator.services.mozilla.com/D66126 --HG-- extra : moz-landing-system : lando --- dom/ipc/ContentParent.cpp | 7 ++++++ dom/ipc/ContentParent.h | 3 +++ dom/ipc/PContent.ipdl | 9 ++++++++ gfx/ipc/GraphicsMessages.ipdlh | 1 + gfx/thebes/gfxPlatform.cpp | 38 +++++++++++++++++++++++++------ gfx/thebes/gfxPlatform.h | 12 ++++++++-- gfx/thebes/gfxWindowsPlatform.cpp | 6 +++++ ipc/ipdl/sync-messages.ini | 4 +++- 8 files changed, 70 insertions(+), 10 deletions(-) diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 32d494f86185..d8fab99ae886 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -4988,6 +4988,13 @@ mozilla::ipc::IPCResult ContentParent::RecvGetGraphicsDeviceInitData( return IPC_OK(); } +mozilla::ipc::IPCResult ContentParent::RecvGetOutputColorProfileData( + nsTArray* aOutputColorProfileData) { + (*aOutputColorProfileData) = + gfxPlatform::GetPlatform()->GetCMSOutputProfileData(); + return IPC_OK(); +} + mozilla::ipc::IPCResult ContentParent::RecvGetFontListShmBlock( const uint32_t& aGeneration, const uint32_t& aIndex, mozilla::ipc::SharedMemoryBasic::Handle* aOut) { diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index c1c6bd80f6f2..7395890471ca 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -1150,6 +1150,9 @@ class ContentParent final mozilla::ipc::IPCResult RecvGetGraphicsDeviceInitData( ContentDeviceData* aOut); + mozilla::ipc::IPCResult RecvGetOutputColorProfileData( + nsTArray* aOutputColorProfileData); + mozilla::ipc::IPCResult RecvGetFontListShmBlock( const uint32_t& aGeneration, const uint32_t& aIndex, mozilla::ipc::SharedMemoryBasic::Handle* aOut); diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index ad804ed0b74b..948284731418 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -1184,6 +1184,15 @@ parent: sync GetGraphicsDeviceInitData() returns (ContentDeviceData aData); + /** + * Request a buffer containing the contents of the output color profile. + * If set, this is the file pointed to by + * gfx.color_management.display_profile, otherwise it contains a + * platform-specific default + */ + sync GetOutputColorProfileData() + returns (uint8_t[] aOutputColorProfileData); + /** * A shared font list (see gfx/thebes/SharedFontList.*) contains a list * of shared-memory blocks that are used to store all the font list data. diff --git a/gfx/ipc/GraphicsMessages.ipdlh b/gfx/ipc/GraphicsMessages.ipdlh index e244d0522072..da51ad527f51 100644 --- a/gfx/ipc/GraphicsMessages.ipdlh +++ b/gfx/ipc/GraphicsMessages.ipdlh @@ -41,6 +41,7 @@ struct ContentDeviceData { DevicePrefs prefs; D3D11DeviceStatus d3d11; + uint8_t[] cmsOutputProfileData; }; // Represents the state of a feature that has failed to initialize. diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index 63f834afe33d..c06d54325450 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -2191,25 +2191,47 @@ nsTArray gfxPlatform::GetPlatformCMSOutputProfileData() { } nsTArray gfxPlatform::GetCMSOutputProfileData() { + if (XRE_IsContentProcess()) { + // This will be passed in during InitChild so we can avoid sending a + // sync message back to the parent during init. + if (gContentDeviceInitData) { + MOZ_ASSERT(!gContentDeviceInitData->cmsOutputProfileData().IsEmpty()); + return gContentDeviceInitData->cmsOutputProfileData(); + } + + // Otherwise we need to ask the parent for the updated color profile + mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton(); + nsTArray result; + Unused << cc->SendGetOutputColorProfileData(&result); + return result; + } + + if (!mCachedOutputColorProfile.IsEmpty()) { + return nsTArray(mCachedOutputColorProfile); + } + nsAutoCString fname; Preferences::GetCString("gfx.color_management.display_profile", fname); if (fname.IsEmpty()) { - return gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfileData(); + mCachedOutputColorProfile = GetPlatformCMSOutputProfileData(); + return nsTArray(mCachedOutputColorProfile); } void* mem = nullptr; size_t size = 0; qcms_data_from_path(fname.get(), &mem, &size); if (mem == nullptr) { - return gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfileData(); + mCachedOutputColorProfile = GetPlatformCMSOutputProfileData(); + return nsTArray(mCachedOutputColorProfile); } - nsTArray result; - result.AppendElements(static_cast(mem), size); + MOZ_ASSERT(mCachedOutputColorProfile.IsEmpty()); + + mCachedOutputColorProfile.AppendElements(static_cast(mem), size); free(mem); - return result; + return nsTArray(mCachedOutputColorProfile); } void gfxPlatform::CreateCMSOutputProfile() { @@ -2226,7 +2248,8 @@ void gfxPlatform::CreateCMSOutputProfile() { } if (!gCMSOutputProfile) { - nsTArray outputProfileData = GetCMSOutputProfileData(); + nsTArray outputProfileData = + gfxPlatform::GetPlatform()->GetCMSOutputProfileData(); if (!outputProfileData.IsEmpty()) { gCMSOutputProfile = qcms_profile_from_memory( outputProfileData.Elements(), outputProfileData.Length()); @@ -3404,7 +3427,8 @@ void gfxPlatform::GetFrameStats(mozilla::widget::InfoObject& aObj) { } void gfxPlatform::GetCMSSupportInfo(mozilla::widget::InfoObject& aObj) { - nsTArray outputProfileData = GetCMSOutputProfileData(); + nsTArray outputProfileData = + gfxPlatform::GetPlatform()->GetCMSOutputProfileData(); if (outputProfileData.IsEmpty()) { nsPrintfCString msg("Empty profile data"); aObj.DefineProperty("CMSOutputProfile", msg.get()); diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h index 20071561bead..09bfb020522b 100644 --- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -738,6 +738,13 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener { */ virtual void ImportGPUDeviceData(const mozilla::gfx::GPUDeviceData& aData); + /** + * Returns the contents of the file containing the output color profile. + * The result may change if gfx.color_management.display_profile is changed + * or the platform-specific default is changed + */ + nsTArray GetCMSOutputProfileData(); + bool HasVariationFontSupport() const { return mHasVariationFontSupport; } bool HasNativeColrFontSupport() const { return mHasNativeColrFontSupport; } @@ -879,8 +886,6 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener { static void InitOpenGLConfig(); static void CreateCMSOutputProfile(); - static nsTArray GetCMSOutputProfileData(); - friend void RecordingPrefChanged(const char* aPrefName, void* aClosure); virtual nsTArray GetPlatformCMSOutputProfileData(); @@ -948,6 +953,9 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener { // Total number of screen pixels across all monitors. int64_t mScreenPixels; + // Cached contents of the output color profile file + nsTArray mCachedOutputColorProfile; + // An instance of gfxSkipChars which is empty. It is used as the // basis for error-case iterators. const gfxSkipChars kEmptySkipChars; diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 0f21359cab15..4fa59692b140 100644 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -1905,6 +1905,9 @@ void gfxWindowsPlatform::ImportContentDeviceData( DeviceManagerDx* dm = DeviceManagerDx::Get(); dm->ImportDeviceInfo(aData.d3d11()); } + + // aData->cmsOutputProfileData() will be read during color profile init, + // not as part of this import function } void gfxWindowsPlatform::BuildContentDeviceData(ContentDeviceData* aOut) { @@ -1921,6 +1924,9 @@ void gfxWindowsPlatform::BuildContentDeviceData(ContentDeviceData* aOut) { DeviceManagerDx* dm = DeviceManagerDx::Get(); dm->ExportDeviceInfo(&aOut->d3d11()); } + + aOut->cmsOutputProfileData() = + gfxPlatform::GetPlatform()->GetCMSOutputProfileData(); } bool gfxWindowsPlatform::CheckVariationFontSupport() { diff --git a/ipc/ipdl/sync-messages.ini b/ipc/ipdl/sync-messages.ini index bbdc7a73b763..12199aae42b9 100644 --- a/ipc/ipdl/sync-messages.ini +++ b/ipc/ipdl/sync-messages.ini @@ -1014,7 +1014,9 @@ description = legacy sync IPC - please add detailed description [PContent::EndDriverCrashGuard] description = legacy sync IPC - please add detailed description [PContent::GetGraphicsDeviceInitData] -description = legacy sync IPC - please add detailed description +description = Retrieve information needed to initialize the graphics device in the content process +[PContent::GetOutputColorProfileData] +description = Retrieve the contents of the output color profile file [PContent::GetFontListShmBlock] description = for bug 1514869 - layout code needs synchronous access to font list, but this is used only once per block, after which content directly reads the shared memory [PContent::InitializeFamily]