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]