зеркало из https://github.com/mozilla/pjs.git
Force cms to use sRGB as an output profile during reftests - bug 452125.r=vlad
This commit is contained in:
Родитель
8c04d70d74
Коммит
709e0585e0
|
@ -42,6 +42,8 @@
|
|||
#include "prtypes.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
#include "nsIObserver.h"
|
||||
|
||||
#include "gfxTypes.h"
|
||||
#include "gfxASurface.h"
|
||||
|
||||
|
@ -266,6 +268,8 @@ protected:
|
|||
|
||||
private:
|
||||
virtual cmsHPROFILE GetPlatformCMSOutputProfile();
|
||||
|
||||
nsCOMPtr<nsIObserver> overrideObserver;
|
||||
};
|
||||
|
||||
#endif /* GFX_PLATFORM_H */
|
||||
|
|
|
@ -60,6 +60,8 @@
|
|||
#include "nsIPref.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
#ifdef MOZ_ENABLE_GLITZ
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
@ -70,6 +72,7 @@
|
|||
#include "plstr.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
|
||||
gfxPlatform *gPlatform = nsnull;
|
||||
int gGlitzState = -1;
|
||||
|
@ -82,11 +85,44 @@ static cmsHTRANSFORM gCMSRGBTransform = nsnull;
|
|||
static cmsHTRANSFORM gCMSInverseRGBTransform = nsnull;
|
||||
static cmsHTRANSFORM gCMSRGBATransform = nsnull;
|
||||
|
||||
static PRBool gCMSInitialized = PR_FALSE;
|
||||
static eCMSMode gCMSMode = eCMSMode_Off;
|
||||
static int gCMSIntent = -2;
|
||||
|
||||
static const char *CMPrefName = "gfx.color_management.mode";
|
||||
static const char *CMPrefNameOld = "gfx.color_management.enabled";
|
||||
static const char *CMIntentPrefName = "gfx.color_management.rendering_intent";
|
||||
static const char *CMProfilePrefName = "gfx.color_management.display_profile";
|
||||
static const char *CMForceSRGBPrefName = "gfx.color_management.force_srgb";
|
||||
|
||||
static void ShutdownCMS();
|
||||
static void MigratePrefs();
|
||||
|
||||
/* Class to listen for pref changes so that chrome code can dynamically
|
||||
force sRGB as an output profile. See Bug #452125. */
|
||||
class SRGBOverrideObserver : public nsIObserver,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS2(SRGBOverrideObserver, nsIObserver, nsISupportsWeakReference)
|
||||
|
||||
NS_IMETHODIMP
|
||||
SRGBOverrideObserver::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const PRUnichar *someData)
|
||||
{
|
||||
NS_ASSERTION(NS_strcmp(someData,
|
||||
NS_LITERAL_STRING("gfx.color_mangement.force_srgb").get()),
|
||||
"Restarting CMS on wrong pref!");
|
||||
ShutdownCMS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// this needs to match the list of pref font.default.xx entries listed in all.js!
|
||||
// the order *must* match the order in eFontPrefLang
|
||||
static const char *gPrefLangNames[] = {
|
||||
|
@ -185,6 +221,12 @@ gfxPlatform::Init()
|
|||
/* Pref migration hook. */
|
||||
MigratePrefs();
|
||||
|
||||
/* Create and register our CMS Override observer. */
|
||||
gPlatform->overrideObserver = new SRGBOverrideObserver();
|
||||
nsCOMPtr<nsIPrefBranch2> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (prefs)
|
||||
prefs->AddObserver(CMForceSRGBPrefName, gPlatform->overrideObserver, PR_TRUE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -201,30 +243,12 @@ gfxPlatform::Shutdown()
|
|||
#endif
|
||||
|
||||
// Free the various non-null transforms and loaded profiles
|
||||
if (gCMSRGBTransform) {
|
||||
cmsDeleteTransform(gCMSRGBTransform);
|
||||
gCMSRGBTransform = nsnull;
|
||||
}
|
||||
if (gCMSInverseRGBTransform) {
|
||||
cmsDeleteTransform(gCMSInverseRGBTransform);
|
||||
gCMSInverseRGBTransform = nsnull;
|
||||
}
|
||||
if (gCMSRGBATransform) {
|
||||
cmsDeleteTransform(gCMSRGBATransform);
|
||||
gCMSRGBATransform = nsnull;
|
||||
}
|
||||
if (gCMSOutputProfile) {
|
||||
cmsCloseProfile(gCMSOutputProfile);
|
||||
ShutdownCMS();
|
||||
|
||||
// handle the aliased case
|
||||
if (gCMSsRGBProfile == gCMSOutputProfile)
|
||||
gCMSsRGBProfile = nsnull;
|
||||
gCMSOutputProfile = nsnull;
|
||||
}
|
||||
if (gCMSsRGBProfile) {
|
||||
cmsCloseProfile(gCMSsRGBProfile);
|
||||
gCMSsRGBProfile = nsnull;
|
||||
}
|
||||
/* Unregister our CMS Override callback. */
|
||||
nsCOMPtr<nsIPrefBranch2> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (prefs)
|
||||
prefs->RemoveObserver(CMForceSRGBPrefName, gPlatform->overrideObserver);
|
||||
|
||||
delete gPlatform;
|
||||
gPlatform = nsnull;
|
||||
|
@ -465,22 +489,19 @@ gfxPlatform::AppendPrefLang(eFontPrefLang aPrefLangs[], PRUint32& aLen, eFontPre
|
|||
eCMSMode
|
||||
gfxPlatform::GetCMSMode()
|
||||
{
|
||||
static eCMSMode sMode = eCMSMode_Off;
|
||||
static PRBool initialized = PR_FALSE;
|
||||
|
||||
if (initialized == PR_FALSE) {
|
||||
initialized = PR_TRUE;
|
||||
if (gCMSInitialized == PR_FALSE) {
|
||||
gCMSInitialized = PR_TRUE;
|
||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (prefs) {
|
||||
PRInt32 mode;
|
||||
nsresult rv =
|
||||
prefs->GetIntPref(CMPrefName, &mode);
|
||||
if (NS_SUCCEEDED(rv) && (mode >= 0) && (mode < eCMSMode_AllCount)) {
|
||||
sMode = static_cast<eCMSMode>(mode);
|
||||
gCMSMode = static_cast<eCMSMode>(mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sMode;
|
||||
return gCMSMode;
|
||||
}
|
||||
|
||||
/* Chris Murphy (CM consultant) suggests this as a default in the event that we
|
||||
|
@ -491,10 +512,7 @@ unacceptable performance overhead, so we go with perceptual. */
|
|||
PRBool
|
||||
gfxPlatform::GetRenderingIntent()
|
||||
{
|
||||
/* -2 means that we haven't tried querying the pref service yet. */
|
||||
static int sIntent = -2;
|
||||
|
||||
if (sIntent == -2) {
|
||||
if (gCMSIntent == -2) {
|
||||
|
||||
/* Try to query the pref system for a rendering intent. */
|
||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
|
@ -505,19 +523,19 @@ gfxPlatform::GetRenderingIntent()
|
|||
|
||||
/* If the pref is within range, use it as an override. */
|
||||
if ((pIntent >= INTENT_MIN) && (pIntent <= INTENT_MAX))
|
||||
sIntent = pIntent;
|
||||
gCMSIntent = pIntent;
|
||||
|
||||
/* If the pref is out of range, use embedded profile. */
|
||||
else
|
||||
sIntent = -1;
|
||||
gCMSIntent = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we didn't get a valid intent from prefs, use the default. */
|
||||
if (sIntent == -2)
|
||||
sIntent = INTENT_DEFAULT;
|
||||
if (gCMSIntent == -2)
|
||||
gCMSIntent = INTENT_DEFAULT;
|
||||
}
|
||||
return sIntent;
|
||||
return gCMSIntent;
|
||||
}
|
||||
|
||||
|
||||
|
@ -540,18 +558,31 @@ gfxPlatform::GetCMSOutputProfile()
|
|||
|
||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (prefs) {
|
||||
nsXPIDLCString fname;
|
||||
nsresult rv =
|
||||
prefs->GetCharPref("gfx.color_management.display_profile",
|
||||
getter_Copies(fname));
|
||||
if (NS_SUCCEEDED(rv) && !fname.IsEmpty()) {
|
||||
gCMSOutputProfile = cmsOpenProfileFromFile(fname, "r");
|
||||
#ifdef DEBUG_tor
|
||||
if (gCMSOutputProfile)
|
||||
fprintf(stderr,
|
||||
"ICM profile read from %s successfully\n",
|
||||
fname.get());
|
||||
#endif
|
||||
|
||||
nsresult rv;
|
||||
|
||||
/* Determine if we're using the internal override to force sRGB as
|
||||
an output profile for reftests. See Bug 452125. */
|
||||
PRBool hasSRGBOverride, doSRGBOverride;
|
||||
rv = prefs->PrefHasUserValue(CMForceSRGBPrefName, &hasSRGBOverride);
|
||||
if (NS_SUCCEEDED(rv) && hasSRGBOverride) {
|
||||
rv = prefs->GetBoolPref(CMForceSRGBPrefName, &doSRGBOverride);
|
||||
if (NS_SUCCEEDED(rv) && doSRGBOverride)
|
||||
gCMSOutputProfile = GetCMSsRGBProfile();
|
||||
}
|
||||
|
||||
if (!gCMSOutputProfile) {
|
||||
|
||||
nsXPIDLCString fname;
|
||||
rv = prefs->GetCharPref(CMProfilePrefName,
|
||||
getter_Copies(fname));
|
||||
if (NS_SUCCEEDED(rv) && !fname.IsEmpty()) {
|
||||
gCMSOutputProfile = cmsOpenProfileFromFile(fname, "r");
|
||||
if (gCMSOutputProfile)
|
||||
fprintf(stderr,
|
||||
"ICM profile read from %s successfully\n",
|
||||
fname.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -644,6 +675,41 @@ gfxPlatform::GetCMSRGBATransform()
|
|||
return gCMSRGBATransform;
|
||||
}
|
||||
|
||||
/* Shuts down various transforms and profiles for CMS. */
|
||||
static void ShutdownCMS()
|
||||
{
|
||||
|
||||
if (gCMSRGBTransform) {
|
||||
cmsDeleteTransform(gCMSRGBTransform);
|
||||
gCMSRGBTransform = nsnull;
|
||||
}
|
||||
if (gCMSInverseRGBTransform) {
|
||||
cmsDeleteTransform(gCMSInverseRGBTransform);
|
||||
gCMSInverseRGBTransform = nsnull;
|
||||
}
|
||||
if (gCMSRGBATransform) {
|
||||
cmsDeleteTransform(gCMSRGBATransform);
|
||||
gCMSRGBATransform = nsnull;
|
||||
}
|
||||
if (gCMSOutputProfile) {
|
||||
cmsCloseProfile(gCMSOutputProfile);
|
||||
|
||||
// handle the aliased case
|
||||
if (gCMSsRGBProfile == gCMSOutputProfile)
|
||||
gCMSsRGBProfile = nsnull;
|
||||
gCMSOutputProfile = nsnull;
|
||||
}
|
||||
if (gCMSsRGBProfile) {
|
||||
cmsCloseProfile(gCMSsRGBProfile);
|
||||
gCMSsRGBProfile = nsnull;
|
||||
}
|
||||
|
||||
// Reset the state variables
|
||||
gCMSIntent = -2;
|
||||
gCMSMode = eCMSMode_Off;
|
||||
gCMSInitialized = PR_FALSE;
|
||||
}
|
||||
|
||||
static void MigratePrefs()
|
||||
{
|
||||
|
||||
|
|
|
@ -97,6 +97,12 @@ RefTestCmdLineHandler.prototype =
|
|||
cmdLine.handleFlag("reftest", true);
|
||||
}
|
||||
|
||||
/* Force sRGB as an output profile for color management before we load a
|
||||
window. */
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch2);
|
||||
prefs.setBoolPref("gfx.color_management.force_srgb", true);
|
||||
|
||||
var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
|
||||
.getService(nsIWindowWatcher);
|
||||
wwatch.openWindow(null, "chrome://reftest/content/reftest.xul", "_blank",
|
||||
|
|
|
@ -121,6 +121,11 @@ function OnRefTestLoad()
|
|||
|
||||
function OnRefTestUnload()
|
||||
{
|
||||
/* Clear the sRGB forcing pref to leave the profile as we found it. */
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch2);
|
||||
prefs.clearUserPref("gfx.color_management.force_srgb");
|
||||
|
||||
gBrowser.removeEventListener("load", OnDocumentLoad, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -254,6 +254,22 @@ void NullXFORM(_LPcmsTRANSFORM p,
|
|||
output = (LPBYTE) out;
|
||||
n = Size; // Buffer len
|
||||
|
||||
// If the input and output formats are the same,
|
||||
// we don't need to pack and unpack pixels
|
||||
if (p -> InputFormat == p -> OutputFormat) {
|
||||
|
||||
// Only copy bytes if the buffers aren't the same
|
||||
if (in != out) {
|
||||
|
||||
// Copy in a nondestructive manner in case
|
||||
// the buffers overlap for some reason
|
||||
memmove(out, in,
|
||||
Size * T_BYTES(p -> InputFormat) * T_CHANNELS(p -> InputFormat));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i < n; i++)
|
||||
{
|
||||
accum = p -> FromInput(p, wIn, accum);
|
||||
|
@ -1523,6 +1539,12 @@ _LPcmsTRANSFORM PickTransformRoutine(_LPcmsTRANSFORM p,
|
|||
(p -> ExitColorSpace == icSigRgbData) &&
|
||||
!(p -> dwOriginalFlags & cmsFLAGS_BLACKPOINTCOMPENSATION)) {
|
||||
|
||||
// If the input profile pointer-matches with the output profile,
|
||||
// optimize the transformation away into a null xform
|
||||
if (p -> InputProfile == p -> OutputProfile) {
|
||||
p -> xform = NullXFORM;
|
||||
return p;
|
||||
}
|
||||
|
||||
// If the floating point path is requested, see if we support it
|
||||
if (p -> dwOriginalFlags & cmsFLAGS_FLOATSHAPER)
|
||||
|
|
Загрузка…
Ссылка в новой задаче