Force cms to use sRGB as an output profile during reftests - bug 452125.r=vlad

This commit is contained in:
Bobby Holley 2008-09-08 14:47:26 -07:00
Родитель b76029e429
Коммит 107ed7aaa9
5 изменённых файлов: 154 добавлений и 51 удалений

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

@ -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)