mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1540776 - Have parent send color profile to child during launch r=aosmond,jld,jfkthame,florian
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
This commit is contained in:
parent
5004affc0e
commit
64e1fb7a45
@ -357,6 +357,12 @@ const startupPhases = {
|
||||
ignoreIfUnused: true, // Only on Win7
|
||||
read: 1,
|
||||
},
|
||||
{
|
||||
// Bug 1626738
|
||||
path: "SysD:spool/drivers/color/*",
|
||||
condition: WIN,
|
||||
read: 1,
|
||||
},
|
||||
{
|
||||
// bug 1541246
|
||||
path: "UAppData:",
|
||||
|
@ -4968,6 +4968,13 @@ mozilla::ipc::IPCResult ContentParent::RecvGetGraphicsDeviceInitData(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvGetOutputColorProfileData(
|
||||
nsTArray<uint8_t>* aOutputColorProfileData) {
|
||||
(*aOutputColorProfileData) =
|
||||
gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfileData();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvGetFontListShmBlock(
|
||||
const uint32_t& aGeneration, const uint32_t& aIndex,
|
||||
mozilla::ipc::SharedMemoryBasic::Handle* aOut) {
|
||||
|
@ -1143,6 +1143,9 @@ class ContentParent final
|
||||
mozilla::ipc::IPCResult RecvGetGraphicsDeviceInitData(
|
||||
ContentDeviceData* aOut);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetOutputColorProfileData(
|
||||
nsTArray<uint8_t>* aOutputColorProfileData);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetFontListShmBlock(
|
||||
const uint32_t& aGeneration, const uint32_t& aIndex,
|
||||
mozilla::ipc::SharedMemoryBasic::Handle* aOut);
|
||||
|
@ -1187,6 +1187,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.
|
||||
|
@ -41,6 +41,7 @@ struct ContentDeviceData
|
||||
{
|
||||
DevicePrefs prefs;
|
||||
D3D11DeviceStatus d3d11;
|
||||
uint8_t[] cmsOutputProfileData;
|
||||
};
|
||||
|
||||
// Represents the state of a feature that has failed to initialize.
|
||||
|
@ -2204,31 +2204,35 @@ DeviceColor gfxPlatform::TransformPixel(const sRGBColor& in,
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> gfxPlatform::GetPlatformCMSOutputProfileData() {
|
||||
return nsTArray<uint8_t>();
|
||||
return GetPrefCMSOutputProfileData();
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> gfxPlatform::GetCMSOutputProfileData() {
|
||||
nsTArray<uint8_t> gfxPlatform::GetPrefCMSOutputProfileData() {
|
||||
nsAutoCString fname;
|
||||
Preferences::GetCString("gfx.color_management.display_profile", fname);
|
||||
|
||||
if (fname.IsEmpty()) {
|
||||
return gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfileData();
|
||||
return nsTArray<uint8_t>();
|
||||
}
|
||||
|
||||
void* mem = nullptr;
|
||||
size_t size = 0;
|
||||
qcms_data_from_path(fname.get(), &mem, &size);
|
||||
if (mem == nullptr) {
|
||||
return gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfileData();
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> result;
|
||||
result.AppendElements(static_cast<uint8_t*>(mem), size);
|
||||
free(mem);
|
||||
|
||||
if (mem) {
|
||||
result.AppendElements(static_cast<uint8_t*>(mem), size);
|
||||
free(mem);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const mozilla::gfx::ContentDeviceData* gfxPlatform::GetInitContentDeviceData() {
|
||||
return gContentDeviceInitData;
|
||||
}
|
||||
|
||||
void gfxPlatform::CreateCMSOutputProfile() {
|
||||
if (!gCMSOutputProfile) {
|
||||
/* Determine if we're using the internal override to force sRGB as
|
||||
@ -2243,7 +2247,8 @@ void gfxPlatform::CreateCMSOutputProfile() {
|
||||
}
|
||||
|
||||
if (!gCMSOutputProfile) {
|
||||
nsTArray<uint8_t> outputProfileData = GetCMSOutputProfileData();
|
||||
nsTArray<uint8_t> outputProfileData =
|
||||
gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfileData();
|
||||
if (!outputProfileData.IsEmpty()) {
|
||||
gCMSOutputProfile = qcms_profile_from_memory(
|
||||
outputProfileData.Elements(), outputProfileData.Length());
|
||||
@ -3418,7 +3423,8 @@ void gfxPlatform::GetFrameStats(mozilla::widget::InfoObject& aObj) {
|
||||
}
|
||||
|
||||
void gfxPlatform::GetCMSSupportInfo(mozilla::widget::InfoObject& aObj) {
|
||||
nsTArray<uint8_t> outputProfileData = GetCMSOutputProfileData();
|
||||
nsTArray<uint8_t> outputProfileData =
|
||||
gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfileData();
|
||||
if (outputProfileData.IsEmpty()) {
|
||||
nsPrintfCString msg("Empty profile data");
|
||||
aObj.DefineProperty("CMSOutputProfile", msg.get());
|
||||
|
@ -728,6 +728,12 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
|
||||
|
||||
const gfxSkipChars& EmptySkipChars() const { return kEmptySkipChars; }
|
||||
|
||||
/**
|
||||
* Returns a buffer containing the CMS output profile data. The way this
|
||||
* is obtained is platform-specific.
|
||||
*/
|
||||
virtual nsTArray<uint8_t> GetPlatformCMSOutputProfileData();
|
||||
|
||||
/**
|
||||
* Return information on how child processes should initialize graphics
|
||||
* devices.
|
||||
@ -806,6 +812,23 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
|
||||
virtual void ImportContentDeviceData(
|
||||
const mozilla::gfx::ContentDeviceData& aData);
|
||||
|
||||
/**
|
||||
* Returns the contents of the file pointed to by the
|
||||
* gfx.color_management.display_profile pref, if set.
|
||||
* Returns an empty array if not set, or if an error occurs
|
||||
*/
|
||||
nsTArray<uint8_t> GetPrefCMSOutputProfileData();
|
||||
|
||||
/**
|
||||
* If inside a child process and currently being initialized by the
|
||||
* SetXPCOMProcessAttributes message, this can be used by subclasses to
|
||||
* retrieve the ContentDeviceData passed by the message
|
||||
*
|
||||
* If not currently being initialized, will return nullptr. In this case,
|
||||
* child should send a sync message to ask parent for color profile
|
||||
*/
|
||||
const mozilla::gfx::ContentDeviceData* GetInitContentDeviceData();
|
||||
|
||||
/**
|
||||
* Increase the global device counter after a device has been removed/reset.
|
||||
*/
|
||||
@ -881,12 +904,8 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
|
||||
static void InitOpenGLConfig();
|
||||
static void CreateCMSOutputProfile();
|
||||
|
||||
static nsTArray<uint8_t> GetCMSOutputProfileData();
|
||||
|
||||
friend void RecordingPrefChanged(const char* aPrefName, void* aClosure);
|
||||
|
||||
virtual nsTArray<uint8_t> GetPlatformCMSOutputProfileData();
|
||||
|
||||
/**
|
||||
* Calling this function will compute and set the ideal tile size for the
|
||||
* platform. This will only have an effect in the parent process; child
|
||||
|
@ -376,6 +376,11 @@ static nsTArray<uint8_t> GetDisplayICCProfile(Display* dpy, Window& root) {
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> gfxPlatformGtk::GetPlatformCMSOutputProfileData() {
|
||||
nsTArray<uint8_t> prefProfileData = GetPrefCMSOutputProfileData();
|
||||
if (!prefProfileData.IsEmpty()) {
|
||||
return prefProfileData;
|
||||
}
|
||||
|
||||
if (!mIsX11Display) {
|
||||
return nsTArray<uint8_t>();
|
||||
}
|
||||
|
@ -560,6 +560,11 @@ gfxPlatformMac::CreateHardwareVsyncSource() {
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> gfxPlatformMac::GetPlatformCMSOutputProfileData() {
|
||||
nsTArray<uint8_t> prefProfileData = GetPrefCMSOutputProfileData();
|
||||
if (!prefProfileData.IsEmpty()) {
|
||||
return prefProfileData;
|
||||
}
|
||||
|
||||
CGColorSpaceRef cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID());
|
||||
if (!cspace) {
|
||||
cspace = ::CGColorSpaceCreateDeviceRGB();
|
||||
|
@ -897,36 +897,66 @@ void gfxWindowsPlatform::CheckForContentOnlyDeviceReset() {
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> gfxWindowsPlatform::GetPlatformCMSOutputProfileData() {
|
||||
HDC dc = ::GetDC(nullptr);
|
||||
if (!dc) {
|
||||
return nsTArray<uint8_t>();
|
||||
if (XRE_IsContentProcess()) {
|
||||
// This will be passed in during InitChild so we can avoid sending a
|
||||
// sync message back to the parent during init.
|
||||
const mozilla::gfx::ContentDeviceData* contentDeviceData =
|
||||
GetInitContentDeviceData();
|
||||
if (contentDeviceData) {
|
||||
MOZ_ASSERT(!contentDeviceData->cmsOutputProfileData().IsEmpty());
|
||||
return contentDeviceData->cmsOutputProfileData();
|
||||
}
|
||||
|
||||
// Otherwise we need to ask the parent for the updated color profile
|
||||
mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
|
||||
nsTArray<uint8_t> result;
|
||||
Unused << cc->SendGetOutputColorProfileData(&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
WCHAR profilePath[MAX_PATH];
|
||||
DWORD profilePathLen = MAX_PATH;
|
||||
|
||||
bool getProfileResult = ::GetICMProfileW(dc, &profilePathLen, profilePath);
|
||||
|
||||
::ReleaseDC(nullptr, dc);
|
||||
|
||||
if (!getProfileResult) {
|
||||
return nsTArray<uint8_t>();
|
||||
if (!mCachedOutputColorProfile.IsEmpty()) {
|
||||
return nsTArray<uint8_t>(mCachedOutputColorProfile);
|
||||
}
|
||||
|
||||
void* mem = nullptr;
|
||||
size_t size = 0;
|
||||
mCachedOutputColorProfile = [&] {
|
||||
nsTArray<uint8_t> prefProfileData = GetPrefCMSOutputProfileData();
|
||||
if (!prefProfileData.IsEmpty()) {
|
||||
return prefProfileData;
|
||||
}
|
||||
|
||||
qcms_data_from_unicode_path(profilePath, &mem, &size);
|
||||
if (!mem) {
|
||||
return nsTArray<uint8_t>();
|
||||
}
|
||||
HDC dc = ::GetDC(nullptr);
|
||||
if (!dc) {
|
||||
return nsTArray<uint8_t>();
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> result;
|
||||
result.AppendElements(static_cast<uint8_t*>(mem), size);
|
||||
WCHAR profilePath[MAX_PATH];
|
||||
DWORD profilePathLen = MAX_PATH;
|
||||
|
||||
free(mem);
|
||||
bool getProfileResult = ::GetICMProfileW(dc, &profilePathLen, profilePath);
|
||||
|
||||
return result;
|
||||
::ReleaseDC(nullptr, dc);
|
||||
|
||||
if (!getProfileResult) {
|
||||
return nsTArray<uint8_t>();
|
||||
}
|
||||
|
||||
void* mem = nullptr;
|
||||
size_t size = 0;
|
||||
|
||||
qcms_data_from_unicode_path(profilePath, &mem, &size);
|
||||
if (!mem) {
|
||||
return nsTArray<uint8_t>();
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> result;
|
||||
result.AppendElements(static_cast<uint8_t*>(mem), size);
|
||||
|
||||
free(mem);
|
||||
|
||||
return result;
|
||||
}();
|
||||
|
||||
return nsTArray<uint8_t>(mCachedOutputColorProfile);
|
||||
}
|
||||
|
||||
void gfxWindowsPlatform::GetDLLVersion(char16ptr_t aDLLPath,
|
||||
@ -1907,6 +1937,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) {
|
||||
@ -1923,6 +1956,9 @@ void gfxWindowsPlatform::BuildContentDeviceData(ContentDeviceData* aOut) {
|
||||
DeviceManagerDx* dm = DeviceManagerDx::Get();
|
||||
dm->ExportDeviceInfo(&aOut->d3d11());
|
||||
}
|
||||
|
||||
aOut->cmsOutputProfileData() =
|
||||
gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfileData();
|
||||
}
|
||||
|
||||
bool gfxWindowsPlatform::CheckVariationFontSupport() {
|
||||
|
@ -253,6 +253,9 @@ class gfxWindowsPlatform final : public gfxPlatform {
|
||||
|
||||
RefPtr<mozilla::layers::ReadbackManagerD3D11> mD3D11ReadbackManager;
|
||||
bool mInitializedDevices = false;
|
||||
|
||||
// Cached contents of the output color profile file
|
||||
nsTArray<uint8_t> mCachedOutputColorProfile;
|
||||
};
|
||||
|
||||
#endif /* GFX_WINDOWS_PLATFORM_H */
|
||||
|
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user