Backed out 2 changesets (bug 1678487) for static gfxPlatform::InitializeCMS crashes CLOSED TREE

Backed out changeset af0927300d51 (bug 1678487)
Backed out changeset 9ed081f10e63 (bug 1678487)
This commit is contained in:
Bogdan Tara 2021-03-08 04:47:16 +02:00
Родитель 8153a8daa8
Коммит 544268f5a4
4 изменённых файлов: 168 добавлений и 149 удалений

Просмотреть файл

@ -152,9 +152,6 @@ static const uint32_t kDefaultGlyphCacheSize = -1;
#include "mozilla/gfx/GPUParent.h"
#include "prsystem.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/SourceSurfaceCairo.h"
using namespace mozilla;
using namespace mozilla::layers;
using namespace mozilla::gl;
@ -169,17 +166,23 @@ const ContentDeviceData* gContentDeviceInitData = nullptr;
static Mutex* gGfxPlatformPrefsLock = nullptr;
Atomic<bool, MemoryOrdering::ReleaseAcquire> gfxPlatform::gCMSInitialized;
CMSMode gfxPlatform::gCMSMode = CMSMode::Off;
// These two may point to the same profile
qcms_profile* gfxPlatform::gCMSOutputProfile = nullptr;
qcms_profile* gfxPlatform::gCMSsRGBProfile = nullptr;
static qcms_profile* gCMSOutputProfile = nullptr;
static qcms_profile* gCMSsRGBProfile = nullptr;
qcms_transform* gfxPlatform::gCMSRGBTransform = nullptr;
qcms_transform* gfxPlatform::gCMSInverseRGBTransform = nullptr;
qcms_transform* gfxPlatform::gCMSRGBATransform = nullptr;
qcms_transform* gfxPlatform::gCMSBGRATransform = nullptr;
static bool gCMSRGBTransformFailed = false;
static qcms_transform* gCMSRGBTransform = nullptr;
static qcms_transform* gCMSInverseRGBTransform = nullptr;
static qcms_transform* gCMSRGBATransform = nullptr;
static qcms_transform* gCMSBGRATransform = nullptr;
static bool gCMSInitialized = false;
static CMSMode gCMSMode = CMSMode::Off;
static void ShutdownCMS();
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/SourceSurfaceCairo.h"
/// This override of the LogForwarder, initially used for the critical graphics
/// errors, is sending the log to the crash annotations as well, but only
@ -999,9 +1002,13 @@ void gfxPlatform::Init() {
Preferences::RegisterCallbackAndCall(RecordingPrefChanged,
"gfx.2d.recording");
CreateCMSOutputProfile();
// Create the sRGB to output display profile transforms. They can be accessed
// off the main thread so we want to avoid a race condition.
InitializeCMS();
GetCMSRGBTransform();
GetCMSRGBATransform();
GetCMSBGRATransform();
// Listen to memory pressure event so we can purge DrawTarget caches
gPlatform->mMemoryPressureObserver =
@ -2035,6 +2042,22 @@ bool gfxPlatform::OffMainThreadCompositingEnabled() {
return UsesOffMainThreadCompositing();
}
CMSMode gfxPlatform::GetCMSMode() {
if (!gCMSInitialized) {
int32_t mode = StaticPrefs::gfx_color_management_mode();
if (mode >= 0 && mode < int32_t(CMSMode::AllCount)) {
gCMSMode = CMSMode(mode);
}
bool enableV4 = StaticPrefs::gfx_color_management_enablev4();
if (enableV4) {
qcms_enable_iccv4();
}
gCMSInitialized = true;
}
return gCMSMode;
}
void gfxPlatform::SetCMSModeOverride(CMSMode aMode) {
MOZ_ASSERT(gCMSInitialized);
gCMSMode = aMode;
@ -2109,85 +2132,121 @@ const mozilla::gfx::ContentDeviceData* gfxPlatform::GetInitContentDeviceData() {
return gContentDeviceInitData;
}
void gfxPlatform::InitializeCMS() {
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread(),
"CMS should be initialized on the main thread");
if (gCMSInitialized) {
return;
}
{
int32_t mode = StaticPrefs::gfx_color_management_mode();
if (mode >= 0 && mode < int32_t(CMSMode::AllCount)) {
gCMSMode = CMSMode(mode);
}
bool enableV4 = StaticPrefs::gfx_color_management_enablev4();
if (enableV4) {
qcms_enable_iccv4();
}
}
gCMSsRGBProfile = qcms_profile_sRGB();
/* Determine if we're using the internal override to force sRGB as
an output profile for reftests. See Bug 452125.
Note that we don't normally (outside of tests) set a default value
of this preference, which means nsIPrefBranch::GetBoolPref will
typically throw (and leave its out-param untouched).
*/
if (StaticPrefs::gfx_color_management_force_srgb()) {
gCMSOutputProfile = gCMSsRGBProfile;
}
void gfxPlatform::CreateCMSOutputProfile() {
if (!gCMSOutputProfile) {
nsTArray<uint8_t> outputProfileData =
gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfileData();
if (!outputProfileData.IsEmpty()) {
gCMSOutputProfile = qcms_profile_from_memory(outputProfileData.Elements(),
outputProfileData.Length());
/* Determine if we're using the internal override to force sRGB as
an output profile for reftests. See Bug 452125.
Note that we don't normally (outside of tests) set a default value
of this preference, which means nsIPrefBranch::GetBoolPref will
typically throw (and leave its out-param untouched).
*/
if (StaticPrefs::gfx_color_management_force_srgb()) {
gCMSOutputProfile = GetCMSsRGBProfile();
}
if (!gCMSOutputProfile) {
nsTArray<uint8_t> outputProfileData =
gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfileData();
if (!outputProfileData.IsEmpty()) {
gCMSOutputProfile = qcms_profile_from_memory(
outputProfileData.Elements(), outputProfileData.Length());
}
}
/* Determine if the profile looks bogus. If so, close the profile
* and use sRGB instead. See bug 460629, */
if (gCMSOutputProfile && qcms_profile_is_bogus(gCMSOutputProfile)) {
NS_ASSERTION(gCMSOutputProfile != GetCMSsRGBProfile(),
"Builtin sRGB profile tagged as bogus!!!");
qcms_profile_release(gCMSOutputProfile);
gCMSOutputProfile = nullptr;
}
if (!gCMSOutputProfile) {
gCMSOutputProfile = GetCMSsRGBProfile();
}
/* Precache the LUT16 Interpolations for the output profile. See
bug 444661 for details. */
qcms_profile_precache_output_transform(gCMSOutputProfile);
}
}
qcms_profile* gfxPlatform::GetCMSOutputProfile() { return gCMSOutputProfile; }
qcms_profile* gfxPlatform::GetCMSsRGBProfile() {
if (!gCMSsRGBProfile) {
/* Create the profile using qcms. */
gCMSsRGBProfile = qcms_profile_sRGB();
}
return gCMSsRGBProfile;
}
qcms_transform* gfxPlatform::GetCMSRGBTransform() {
if (!gCMSRGBTransform && !gCMSRGBTransformFailed) {
qcms_profile *inProfile, *outProfile;
outProfile = GetCMSOutputProfile();
inProfile = GetCMSsRGBProfile();
if (!inProfile || !outProfile) return nullptr;
gCMSRGBTransform =
qcms_transform_create(inProfile, QCMS_DATA_RGB_8, outProfile,
QCMS_DATA_RGB_8, QCMS_INTENT_PERCEPTUAL);
if (!gCMSRGBTransform) {
gCMSRGBTransformFailed = true;
}
}
/* Determine if the profile looks bogus. If so, close the profile
* and use sRGB instead. See bug 460629, */
if (gCMSOutputProfile && qcms_profile_is_bogus(gCMSOutputProfile)) {
NS_ASSERTION(gCMSOutputProfile != gCMSsRGBProfile,
"Builtin sRGB profile tagged as bogus!!!");
qcms_profile_release(gCMSOutputProfile);
gCMSOutputProfile = nullptr;
return gCMSRGBTransform;
}
qcms_transform* gfxPlatform::GetCMSInverseRGBTransform() {
if (!gCMSInverseRGBTransform) {
qcms_profile *inProfile, *outProfile;
inProfile = GetCMSOutputProfile();
outProfile = GetCMSsRGBProfile();
if (!inProfile || !outProfile) return nullptr;
gCMSInverseRGBTransform =
qcms_transform_create(inProfile, QCMS_DATA_RGB_8, outProfile,
QCMS_DATA_RGB_8, QCMS_INTENT_PERCEPTUAL);
}
if (!gCMSOutputProfile) {
gCMSOutputProfile = gCMSsRGBProfile;
return gCMSInverseRGBTransform;
}
qcms_transform* gfxPlatform::GetCMSRGBATransform() {
if (!gCMSRGBATransform) {
qcms_profile *inProfile, *outProfile;
outProfile = GetCMSOutputProfile();
inProfile = GetCMSsRGBProfile();
if (!inProfile || !outProfile) return nullptr;
gCMSRGBATransform =
qcms_transform_create(inProfile, QCMS_DATA_RGBA_8, outProfile,
QCMS_DATA_RGBA_8, QCMS_INTENT_PERCEPTUAL);
}
/* Precache the LUT16 Interpolations for the output profile. See
bug 444661 for details. */
qcms_profile_precache_output_transform(gCMSOutputProfile);
return gCMSRGBATransform;
}
// Create the RGB transform.
gCMSRGBTransform =
qcms_transform_create(gCMSsRGBProfile, QCMS_DATA_RGB_8, gCMSOutputProfile,
QCMS_DATA_RGB_8, QCMS_INTENT_PERCEPTUAL);
qcms_transform* gfxPlatform::GetCMSBGRATransform() {
if (!gCMSBGRATransform) {
qcms_profile *inProfile, *outProfile;
outProfile = GetCMSOutputProfile();
inProfile = GetCMSsRGBProfile();
// And the inverse.
gCMSInverseRGBTransform =
qcms_transform_create(gCMSOutputProfile, QCMS_DATA_RGB_8, gCMSsRGBProfile,
QCMS_DATA_RGB_8, QCMS_INTENT_PERCEPTUAL);
if (!inProfile || !outProfile) return nullptr;
// The RGBA transform.
gCMSRGBATransform = qcms_transform_create(gCMSsRGBProfile, QCMS_DATA_RGBA_8,
gCMSOutputProfile, QCMS_DATA_RGBA_8,
QCMS_INTENT_PERCEPTUAL);
gCMSBGRATransform =
qcms_transform_create(inProfile, QCMS_DATA_BGRA_8, outProfile,
QCMS_DATA_BGRA_8, QCMS_INTENT_PERCEPTUAL);
}
// And the BGRA one.
gCMSBGRATransform = qcms_transform_create(gCMSsRGBProfile, QCMS_DATA_BGRA_8,
gCMSOutputProfile, QCMS_DATA_BGRA_8,
QCMS_INTENT_PERCEPTUAL);
gCMSInitialized = true;
return gCMSBGRATransform;
}
qcms_transform* gfxPlatform::GetCMSOSRGBATransform() {
@ -2215,7 +2274,7 @@ qcms_data_type gfxPlatform::GetCMSOSRGBAType() {
}
/* Shuts down various transforms and profiles for CMS. */
void gfxPlatform::ShutdownCMS() {
static void ShutdownCMS() {
if (gCMSRGBTransform) {
qcms_transform_release(gCMSRGBTransform);
gCMSRGBTransform = nullptr;
@ -2236,9 +2295,7 @@ void gfxPlatform::ShutdownCMS() {
qcms_profile_release(gCMSOutputProfile);
// handle the aliased case
if (gCMSsRGBProfile == gCMSOutputProfile) {
gCMSsRGBProfile = nullptr;
}
if (gCMSsRGBProfile == gCMSOutputProfile) gCMSsRGBProfile = nullptr;
gCMSOutputProfile = nullptr;
}
if (gCMSsRGBProfile) {

Просмотреть файл

@ -535,10 +535,7 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
/**
* Are we going to try color management?
*/
static CMSMode GetCMSMode() {
EnsureCMSInitialized();
return gCMSMode;
}
static CMSMode GetCMSMode();
/**
* Used only for testing. Override the pref setting.
@ -566,50 +563,32 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
/**
* Return the output device ICC profile.
*/
static qcms_profile* GetCMSOutputProfile() {
EnsureCMSInitialized();
return gCMSOutputProfile;
}
static qcms_profile* GetCMSOutputProfile();
/**
* Return the sRGB ICC profile.
*/
static qcms_profile* GetCMSsRGBProfile() {
EnsureCMSInitialized();
return gCMSsRGBProfile;
}
static qcms_profile* GetCMSsRGBProfile();
/**
* Return sRGB -> output device transform.
*/
static qcms_transform* GetCMSRGBTransform() {
EnsureCMSInitialized();
return gCMSRGBTransform;
}
static qcms_transform* GetCMSRGBTransform();
/**
* Return output -> sRGB device transform.
*/
static qcms_transform* GetCMSInverseRGBTransform() {
MOZ_ASSERT(gCMSInitialized);
return gCMSInverseRGBTransform;
}
static qcms_transform* GetCMSInverseRGBTransform();
/**
* Return sRGBA -> output device transform.
*/
static qcms_transform* GetCMSRGBATransform() {
MOZ_ASSERT(gCMSInitialized);
return gCMSRGBATransform;
}
static qcms_transform* GetCMSRGBATransform();
/**
* Return sBGRA -> output device transform.
*/
static qcms_transform* GetCMSBGRATransform() {
MOZ_ASSERT(gCMSInitialized);
return gCMSBGRATransform;
}
static qcms_transform* GetCMSBGRATransform();
/**
* Return OS RGBA -> output device transform.
@ -978,28 +957,7 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
static void Init();
static void InitOpenGLConfig();
static mozilla::Atomic<bool, mozilla::MemoryOrdering::ReleaseAcquire>
gCMSInitialized;
static CMSMode gCMSMode;
// These two may point to the same profile
static qcms_profile* gCMSOutputProfile;
static qcms_profile* gCMSsRGBProfile;
static qcms_transform* gCMSRGBTransform;
static qcms_transform* gCMSInverseRGBTransform;
static qcms_transform* gCMSRGBATransform;
static qcms_transform* gCMSBGRATransform;
inline static void EnsureCMSInitialized() {
if (MOZ_UNLIKELY(!gCMSInitialized)) {
InitializeCMS();
}
}
static void InitializeCMS();
static void ShutdownCMS();
static void CreateCMSOutputProfile();
friend void RecordingPrefChanged(const char* aPrefName, void* aClosure);

Просмотреть файл

@ -55,6 +55,7 @@ AutoInitializeImageLib::AutoInitializeImageLib() {
gfxPlatform::GetPlatform();
// Ensure we always color manage images with gtests.
gfxPlatform::GetCMSMode();
gfxPlatform::SetCMSModeOverride(CMSMode::All);
// Depending on initialization order, it is possible that our pref changes

Просмотреть файл

@ -824,23 +824,26 @@ nsresult nsXPLookAndFeel::GetColorValue(ColorID aID,
}
if (NS_SUCCEEDED(NativeGetColor(aID, aResult))) {
if (gfxPlatform::GetCMSMode() == CMSMode::All &&
!IsSpecialColor(aID, aResult)) {
qcms_transform* transform = gfxPlatform::GetCMSInverseRGBTransform();
if (transform) {
uint8_t color[4];
color[0] = NS_GET_R(aResult);
color[1] = NS_GET_G(aResult);
color[2] = NS_GET_B(aResult);
color[3] = NS_GET_A(aResult);
qcms_transform_data(transform, color, color, 1);
aResult = NS_RGBA(color[0], color[1], color[2], color[3]);
// TODO(bug 1678487): We should color-correct style colors as well when in
// the traversal.
if (!mozilla::ServoStyleSet::IsInServoTraversal()) {
MOZ_ASSERT(NS_IsMainThread());
if (gfxPlatform::GetCMSMode() == CMSMode::All &&
!IsSpecialColor(aID, aResult)) {
qcms_transform* transform = gfxPlatform::GetCMSInverseRGBTransform();
if (transform) {
uint8_t color[4];
color[0] = NS_GET_R(aResult);
color[1] = NS_GET_G(aResult);
color[2] = NS_GET_B(aResult);
color[3] = NS_GET_A(aResult);
qcms_transform_data(transform, color, color, 1);
aResult = NS_RGBA(color[0], color[1], color[2], color[3]);
}
}
}
// NOTE: Servo holds a lock and the main thread is paused, so writing to the
// global cache here is fine.
CACHE_COLOR(aID, aResult);
CACHE_COLOR(aID, aResult);
}
return NS_OK;
}