forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SkColorSpacePrimaries: Consolidate more functionality
Add several helper functions for SkColorSpacePrimaries. - Add the ability to produce a D65 SkColorSpacePrimaries from an skcms_Matrix3x3. This is needed to produce primaries from an ICC profile, which only provides a skcms_Matrix3x3 - Add a function to print primaries - Add constants for well-known primaries - And unit tests! Change gfx::ColorSpace to use these functions - Rename gfx::ColorSpace::GetColorSpacePrimaries to just GetPrimaries - Change GetPrimaries to call GetD65PrimariesFromToXYZD50Matrix instead of doing its own calculation. The math in this function is different (the previous version was missing chromatic adaptation). - Use SkColorSpacePrimariesToString when dumping to a string. Update chrome://gpu to display SkColorSpacePrimaries information This creates a single consolidated place where primary constants are stored (as opposed to repeating them in tests). This potentially increases binary size. Binary-Size: See commit description Fuchsia-Binary-Size: See commit description. Bug: 1274220 Change-Id: I04fa1b6d5b274422210170112ec0d90812e2e9e7 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3878588 Reviewed-by: Zhenyao Mo <zmo@chromium.org> Reviewed-by: Brian Osman <brianosman@google.com> Reviewed-by: Jim Shargo <jshargo@chromium.org> Commit-Queue: ccameron chromium <ccameron@chromium.org> Cr-Commit-Position: refs/heads/main@{#1045604}
- Loading branch information
1 parent
2714675
commit 102eed6
Showing
11 changed files
with
231 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "skia/ext/skcolorspace_primaries.h" | ||
|
||
#include <iomanip> | ||
#include <sstream> | ||
|
||
bool operator==(const SkColorSpacePrimaries& a, | ||
const SkColorSpacePrimaries& b) { | ||
return a.fRX == b.fRX && a.fRY == b.fRY && a.fGX == b.fGX && a.fGY == b.fGY && | ||
a.fBX == b.fBX && a.fBY == b.fBY && a.fWX == b.fWX && a.fWY == b.fWY; | ||
} | ||
|
||
bool operator!=(const SkColorSpacePrimaries& a, | ||
const SkColorSpacePrimaries& b) { | ||
return !(a == b); | ||
} | ||
|
||
namespace skia { | ||
|
||
std::string SkColorSpacePrimariesToString( | ||
const SkColorSpacePrimaries& primaries) { | ||
if (primaries == kSkColorSpacePrimariesZero) | ||
return "invalid"; | ||
|
||
std::stringstream ss; | ||
ss << std::fixed << std::setprecision(4); | ||
ss << "{"; | ||
if (primaries == kSkColorSpacePrimariesSRGB) | ||
ss << "name:'srgb', "; | ||
else if (primaries == kSkColorSpacePrimariesP3) | ||
ss << "name:'p3', "; | ||
else if (primaries == kSkColorSpacePrimariesRec2020) | ||
ss << "name:'rec2020', "; | ||
ss << "r:[" << primaries.fRX << ", " << primaries.fRY << "], "; | ||
ss << "g:[" << primaries.fGX << ", " << primaries.fGY << "], "; | ||
ss << "b:[" << primaries.fBX << ", " << primaries.fRY << "], "; | ||
ss << "w:[" << primaries.fWX << ", " << primaries.fWY << "]"; | ||
ss << "}"; | ||
return ss.str(); | ||
} | ||
|
||
SkColorSpacePrimaries GetD65PrimariesFromToXYZD50Matrix( | ||
const skcms_Matrix3x3& m_d50) { | ||
constexpr float kD65_X = 0.3127f; | ||
constexpr float kD65_Y = 0.3290f; | ||
skcms_Matrix3x3 adapt_d65_to_d50; | ||
skcms_AdaptToXYZD50(kD65_X, kD65_Y, &adapt_d65_to_d50); | ||
|
||
skcms_Matrix3x3 adapt_d50_to_d65; | ||
skcms_Matrix3x3_invert(&adapt_d65_to_d50, &adapt_d50_to_d65); | ||
|
||
const skcms_Matrix3x3 m = skcms_Matrix3x3_concat(&adapt_d50_to_d65, &m_d50); | ||
const float sum_R = m.vals[0][0] + m.vals[1][0] + m.vals[2][0]; | ||
const float sum_G = m.vals[0][1] + m.vals[1][1] + m.vals[2][1]; | ||
const float sum_B = m.vals[0][2] + m.vals[1][2] + m.vals[2][2]; | ||
SkColorSpacePrimaries primaries; | ||
primaries.fRX = m.vals[0][0] / sum_R; | ||
primaries.fRY = m.vals[1][0] / sum_R; | ||
primaries.fGX = m.vals[0][1] / sum_G; | ||
primaries.fGY = m.vals[1][1] / sum_G; | ||
primaries.fBX = m.vals[0][2] / sum_B; | ||
primaries.fBY = m.vals[1][2] / sum_B; | ||
primaries.fWX = kD65_X; | ||
primaries.fWY = kD65_Y; | ||
return primaries; | ||
} | ||
|
||
SkColorSpacePrimaries kSkColorSpacePrimariesZero = {0}; | ||
|
||
SkColorSpacePrimaries kSkColorSpacePrimariesSRGB = { | ||
0.640f, 0.330f, 0.300f, 0.600f, 0.150f, 0.060f, 0.3127f, 0.3290f, | ||
}; | ||
|
||
SkColorSpacePrimaries kSkColorSpacePrimariesP3 = { | ||
0.680f, 0.320f, 0.265f, 0.690f, 0.150f, 0.060f, 0.3127f, 0.3290f, | ||
}; | ||
|
||
SkColorSpacePrimaries kSkColorSpacePrimariesRec2020 = { | ||
0.708f, 0.292f, 0.170f, 0.797f, 0.131f, 0.046f, 0.3127f, 0.3290f, | ||
}; | ||
|
||
SkColorSpacePrimaries kSkColorSpacePrimariesProPhotoD50 = { | ||
0.7347f, 0.2653f, 0.1596f, 0.8404f, 0.0366f, 0.0001f, 0.34567f, 0.35850f, | ||
}; | ||
|
||
SkColorSpacePrimaries kSkColorSpacePrimariesWideGamutColorSpin = { | ||
0.01f, 0.98f, 0.01f, 0.01f, 0.98f, 0.01f, 0.3127f, 0.3290f, | ||
}; | ||
|
||
} // namespace skia |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef SKIA_EXT_SKCOLORSPACE_PRIMARIES_H_ | ||
#define SKIA_EXT_SKCOLORSPACE_PRIMARIES_H_ | ||
|
||
#include "third_party/skia/include/core/SkColorSpace.h" | ||
|
||
#include <string> | ||
|
||
// TODO(https://crbug.com/skia/13721): Add these operators to Skia source. | ||
SK_API bool operator==(const SkColorSpacePrimaries& a, | ||
const SkColorSpacePrimaries& b); | ||
|
||
SK_API bool operator!=(const SkColorSpacePrimaries& a, | ||
const SkColorSpacePrimaries& b); | ||
|
||
namespace skia { | ||
|
||
// Display SkColorSpacePrimaries as a string. | ||
SK_API std::string SkColorSpacePrimariesToString( | ||
const SkColorSpacePrimaries& primaries); | ||
|
||
// Given a matrix that transforms to XYZD50, compute the primaries with a D65 | ||
// white point that would produce this matrix. | ||
SK_API SkColorSpacePrimaries | ||
GetD65PrimariesFromToXYZD50Matrix(const skcms_Matrix3x3& m); | ||
|
||
// Primaries initialized to zero (an invalid value). | ||
extern SK_API SkColorSpacePrimaries kSkColorSpacePrimariesZero; | ||
|
||
// The sRGB or BT709 primaries. | ||
extern SK_API SkColorSpacePrimaries kSkColorSpacePrimariesSRGB; | ||
|
||
// P3 primaries. | ||
extern SK_API SkColorSpacePrimaries kSkColorSpacePrimariesP3; | ||
|
||
// Rec2020 primaries. | ||
extern SK_API SkColorSpacePrimaries kSkColorSpacePrimariesRec2020; | ||
|
||
// ProPhoto primaries (this has a D50 white point). | ||
extern SK_API SkColorSpacePrimaries kSkColorSpacePrimariesProPhotoD50; | ||
|
||
// Primaries where the colors are rotated and the gamut is huge. Good for | ||
// testing. | ||
extern SK_API SkColorSpacePrimaries kSkColorSpacePrimariesWideGamutColorSpin; | ||
|
||
} // namespace skia | ||
|
||
#endif // SKIA_EXT_SKCOLORSPACE_PRIMARIES_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "skia/ext/skcolorspace_primaries.h" | ||
|
||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
namespace skia { | ||
namespace { | ||
|
||
constexpr float kEpsilon = 0.0001; | ||
|
||
TEST(SkiaUtils, PrimariesD65) { | ||
// DCI P3 (D65) | ||
const auto p3 = kSkColorSpacePrimariesP3; | ||
|
||
skcms_Matrix3x3 matrix; | ||
EXPECT_TRUE(p3.toXYZD50(&matrix)); | ||
const auto primaries_from_matrix = GetD65PrimariesFromToXYZD50Matrix(matrix); | ||
|
||
// The retrieved primaries from the matrix should be the same as the original | ||
// primaries, because the original primaries had a D65 white point. | ||
EXPECT_NEAR(p3.fRX, primaries_from_matrix.fRX, kEpsilon); | ||
EXPECT_NEAR(p3.fRY, primaries_from_matrix.fRY, kEpsilon); | ||
EXPECT_NEAR(p3.fGX, primaries_from_matrix.fGX, kEpsilon); | ||
EXPECT_NEAR(p3.fGY, primaries_from_matrix.fGY, kEpsilon); | ||
EXPECT_NEAR(p3.fBX, primaries_from_matrix.fBX, kEpsilon); | ||
EXPECT_NEAR(p3.fBY, primaries_from_matrix.fBY, kEpsilon); | ||
EXPECT_NEAR(p3.fWX, primaries_from_matrix.fWX, kEpsilon); | ||
EXPECT_NEAR(p3.fWY, primaries_from_matrix.fWY, kEpsilon); | ||
} | ||
|
||
TEST(SkiaUtils, PrimariesD50) { | ||
// ProPhoto (D50) | ||
const auto pro_photo = kSkColorSpacePrimariesProPhotoD50; | ||
|
||
// Convert primaries to a matrix. | ||
skcms_Matrix3x3 pro_photo_matrix; | ||
EXPECT_TRUE(pro_photo.toXYZD50(&pro_photo_matrix)); | ||
|
||
// The convert the matrix back to primaries with a D65 white point. | ||
const auto d65 = GetD65PrimariesFromToXYZD50Matrix(pro_photo_matrix); | ||
|
||
// And then convert the D65 primaries to a matrix. | ||
skcms_Matrix3x3 d65_matrix; | ||
EXPECT_TRUE(d65.toXYZD50(&d65_matrix)); | ||
|
||
// The two matrices should be the same, but the primaries will not be. | ||
EXPECT_FALSE(pro_photo == d65); | ||
for (size_t i = 0; i < 3; ++i) { | ||
for (size_t j = 0; j < 3; ++j) { | ||
EXPECT_NEAR(pro_photo_matrix.vals[i][j], d65_matrix.vals[i][j], kEpsilon); | ||
} | ||
} | ||
} | ||
|
||
} // namespace | ||
} // namespace skia |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.