Index: ui/gfx/color_transform.cc |
diff --git a/ui/gfx/color_transform.cc b/ui/gfx/color_transform.cc |
index 933252a9fc43f9b3b12e5061e3e03359f77e8b68..1d562d48401ec84c1b60a4d3f80bfb59954f310a 100644 |
--- a/ui/gfx/color_transform.cc |
+++ b/ui/gfx/color_transform.cc |
@@ -11,6 +11,7 @@ |
#include "base/logging.h" |
#include "base/memory/ptr_util.h" |
+#include "base/strings/stringprintf.h" |
#include "third_party/qcms/src/qcms.h" |
#include "ui/gfx/color_space.h" |
#include "ui/gfx/icc_profile.h" |
@@ -250,8 +251,9 @@ class ColorTransformStep { |
// Return true if this is a null transform. |
virtual bool IsNull() { return false; } |
- |
- virtual void Transform(ColorTransform::TriStim* color, size_t num) = 0; |
+ virtual void Transform(ColorTransform::TriStim* color, size_t num) const = 0; |
+ virtual bool CanAppendShaderSource() { return false; } |
+ virtual void AppendShaderSource(std::string* result) { NOTREACHED(); } |
private: |
DISALLOW_COPY_AND_ASSIGN(ColorTransformStep); |
@@ -264,11 +266,16 @@ class ColorTransformInternal : public ColorTransform { |
Intent intent); |
~ColorTransformInternal() override; |
- // Perform transformation of colors, |colors| is both input and output. |
- void Transform(TriStim* colors, size_t num) override { |
+ gfx::ColorSpace GetSrcColorSpace() const override { return src_; }; |
+ gfx::ColorSpace GetDstColorSpace() const override { return dst_; }; |
+ |
+ void Transform(TriStim* colors, size_t num) const override { |
for (const auto& step : steps_) |
step->Transform(colors, num); |
} |
+ bool CanGetShaderSource() const override; |
+ std::string GetShaderSource() const override; |
+ bool IsIdentity() const override { return steps_.empty(); } |
size_t NumberOfStepsForTesting() const override { return steps_.size(); } |
private: |
@@ -283,13 +290,23 @@ class ColorTransformInternal : public ColorTransform { |
ScopedQcmsProfile GetQCMSProfileIfNecessary(const ColorSpace& color_space); |
std::list<std::unique_ptr<ColorTransformStep>> steps_; |
+ gfx::ColorSpace src_; |
+ gfx::ColorSpace dst_; |
}; |
+#define SRC(...) \ |
+ do { \ |
+ *result += std::string(" ") + base::StringPrintf(__VA_ARGS__) + \ |
+ std::string("\n"); \ |
+ } while (0) |
+ |
class ColorTransformNull : public ColorTransformStep { |
public: |
ColorTransformNull* GetNull() override { return this; } |
bool IsNull() override { return true; } |
- void Transform(ColorTransform::TriStim* color, size_t num) override {} |
+ void Transform(ColorTransform::TriStim* color, size_t num) const override {} |
+ bool CanAppendShaderSource() override { return true; } |
+ void AppendShaderSource(std::string* result) override {} |
}; |
class ColorTransformMatrix : public ColorTransformStep { |
@@ -311,11 +328,24 @@ class ColorTransformMatrix : public ColorTransformStep { |
return SkMatrixIsApproximatelyIdentity(matrix_.matrix()); |
} |
- void Transform(ColorTransform::TriStim* colors, size_t num) override { |
+ void Transform(ColorTransform::TriStim* colors, size_t num) const override { |
for (size_t i = 0; i < num; i++) |
matrix_.TransformPoint(colors + i); |
} |
+ bool CanAppendShaderSource() override { return true; } |
+ |
+ void AppendShaderSource(std::string* result) override { |
+ const SkMatrix44& m = matrix_.matrix(); |
+ SRC("color = mat3(%1.8e, %1.8e, %1.8e, %1.8e, %1.8e, %1.8e, %1.8e, %1.8e, " |
+ "%1.8e) * color;", |
+ m.get(0, 0), m.get(1, 0), m.get(2, 0), // column 1 |
+ m.get(0, 1), m.get(1, 1), m.get(2, 1), // column 2 |
+ m.get(0, 2), m.get(1, 2), m.get(2, 2)); // column 3 |
+ SRC("color += vec3(%1.8e, %1.8e, %1.8e);", m.get(0, 3), m.get(1, 3), |
+ m.get(2, 3)); |
+ } |
+ |
private: |
class Transform matrix_; |
}; |
@@ -331,7 +361,7 @@ class ColorTransformFromLinear : public ColorTransformStep { |
} |
ColorTransformFromLinear* GetFromLinear() override { return this; } |
bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; } |
- void Transform(ColorTransform::TriStim* colors, size_t num) override { |
+ void Transform(ColorTransform::TriStim* colors, size_t num) const override { |
if (fn_valid_) { |
for (size_t i = 0; i < num; i++) { |
colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x())); |
@@ -399,7 +429,7 @@ class ColorTransformToLinear : public ColorTransformStep { |
return c.x() * 0.2627f + c.y() * 0.6780f + c.z() * 0.0593f; |
} |
- ColorTransform::TriStim ClipToWhite(ColorTransform::TriStim& c) { |
+ static ColorTransform::TriStim ClipToWhite(ColorTransform::TriStim& c) { |
float maximum = max(max(c.x(), c.y()), c.z()); |
if (maximum > 1.0f) { |
float l = Luma(c); |
@@ -412,7 +442,7 @@ class ColorTransformToLinear : public ColorTransformStep { |
return c; |
} |
- void Transform(ColorTransform::TriStim* colors, size_t num) override { |
+ void Transform(ColorTransform::TriStim* colors, size_t num) const override { |
if (fn_valid_) { |
for (size_t i = 0; i < num; i++) { |
colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x())); |
@@ -476,7 +506,7 @@ class ColorTransformToBT2020CL : public ColorTransformStep { |
bool IsNull() override { return null_; } |
- void Transform(ColorTransform::TriStim* RYB, size_t num) override { |
+ void Transform(ColorTransform::TriStim* RYB, size_t num) const override { |
for (size_t i = 0; i < num; i++) { |
float U, V; |
float B_Y = RYB[i].z() - RYB[i].y(); |
@@ -514,7 +544,7 @@ class ColorTransformFromBT2020CL : public ColorTransformStep { |
bool IsNull() override { return null_; } |
- void Transform(ColorTransform::TriStim* YUV, size_t num) override { |
+ void Transform(ColorTransform::TriStim* YUV, size_t num) const override { |
if (null_) |
return; |
for (size_t i = 0; i < num; i++) { |
@@ -587,6 +617,11 @@ void ColorTransformInternal::AppendColorSpaceToColorSpaceTransform( |
steps_.push_back( |
base::MakeUnique<ColorTransformMatrix>(Invert(GetTransferMatrix(from)))); |
+ // If the target color space is not defined, just apply the adjust and |
+ // tranfer matrices. |
+ if (!to.IsValid()) |
+ return; |
+ |
SkColorSpaceTransferFn to_linear_fn; |
bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn); |
steps_.push_back(base::MakeUnique<ColorTransformToLinear>( |
@@ -640,7 +675,7 @@ class QCMSColorTransform : public ColorTransformStep { |
return true; |
return false; |
} |
- void Transform(ColorTransform::TriStim* colors, size_t num) override { |
+ void Transform(ColorTransform::TriStim* colors, size_t num) const override { |
CHECK(sizeof(ColorTransform::TriStim) == sizeof(float[3])); |
// QCMS doesn't like numbers outside 0..1 |
for (size_t i = 0; i < num; i++) { |
@@ -688,37 +723,56 @@ ScopedQcmsProfile GetXYZD50Profile() { |
return ScopedQcmsProfile(qcms_profile_create_rgb_with_gamma(w, xyz, 1.0f)); |
} |
-ColorTransformInternal::ColorTransformInternal(const ColorSpace& from, |
- const ColorSpace& to, |
- Intent intent) { |
+ColorTransformInternal::ColorTransformInternal(const ColorSpace& src, |
+ const ColorSpace& dst, |
+ Intent intent) |
+ : src_(src), dst_(dst) { |
// If no source color space is specified, do no transformation. |
- // TODO(ccameron): We may want to assume sRGB at some point in the future. |
- if (!from.IsValid()) |
+ // TODO(ccameron): We may want dst assume sRGB at some point in the future. |
+ if (!src_.IsValid()) |
return; |
- ScopedQcmsProfile from_profile = GetQCMSProfileIfNecessary(from); |
- ScopedQcmsProfile to_profile = GetQCMSProfileIfNecessary(to); |
- bool has_from_profile = !!from_profile; |
- bool has_to_profile = !!to_profile; |
+ ScopedQcmsProfile src_profile = GetQCMSProfileIfNecessary(src_); |
+ ScopedQcmsProfile dst_profile = GetQCMSProfileIfNecessary(dst_); |
+ bool has_src_profile = !!src_profile; |
+ bool has_dst_profile = !!dst_profile; |
- if (from_profile) { |
+ if (src_profile) { |
steps_.push_back(base::MakeUnique<QCMSColorTransform>( |
- std::move(from_profile), GetXYZD50Profile())); |
+ std::move(src_profile), GetXYZD50Profile())); |
} |
AppendColorSpaceToColorSpaceTransform( |
- has_from_profile ? ColorSpace::CreateXYZD50() : from, |
- has_to_profile ? ColorSpace::CreateXYZD50() : to, intent); |
+ has_src_profile ? ColorSpace::CreateXYZD50() : src_, |
+ has_dst_profile ? ColorSpace::CreateXYZD50() : dst_, intent); |
- if (to_profile) { |
+ if (dst_profile) { |
steps_.push_back(base::MakeUnique<QCMSColorTransform>( |
- GetXYZD50Profile(), std::move(to_profile))); |
+ GetXYZD50Profile(), std::move(dst_profile))); |
} |
if (intent != Intent::TEST_NO_OPT) |
Simplify(); |
} |
+std::string ColorTransformInternal::GetShaderSource() const { |
+ std::string result; |
+ result += "vec3 DoColorConversion(vec3 color) {\n"; |
+ for (const auto& step : steps_) |
+ step->AppendShaderSource(&result); |
+ result += " return color;\n"; |
+ result += "}\n"; |
+ return result; |
+} |
+ |
+bool ColorTransformInternal::CanGetShaderSource() const { |
+ for (const auto& step : steps_) { |
+ if (!step->CanAppendShaderSource()) |
+ return false; |
+ } |
+ return true; |
+} |
+ |
ColorTransformInternal::~ColorTransformInternal() {} |
void ColorTransformInternal::Simplify() { |