Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: ui/gfx/color_transform.cc

Issue 2697253002: color: Add support for shader generation (Closed)
Patch Set: Rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« cc/output/program_binding.cc ('K') | « ui/gfx/color_transform.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/color_transform.h" 5 #include "ui/gfx/color_transform.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <list> 9 #include <list>
10 #include <memory> 10 #include <memory>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/strings/stringprintf.h"
14 #include "third_party/qcms/src/qcms.h" 15 #include "third_party/qcms/src/qcms.h"
15 #include "ui/gfx/color_space.h" 16 #include "ui/gfx/color_space.h"
16 #include "ui/gfx/icc_profile.h" 17 #include "ui/gfx/icc_profile.h"
17 #include "ui/gfx/skia_color_space_util.h" 18 #include "ui/gfx/skia_color_space_util.h"
18 #include "ui/gfx/transform.h" 19 #include "ui/gfx/transform.h"
19 20
20 #ifndef THIS_MUST_BE_INCLUDED_AFTER_QCMS_H 21 #ifndef THIS_MUST_BE_INCLUDED_AFTER_QCMS_H
21 extern "C" { 22 extern "C" {
22 #include "third_party/qcms/src/chain.h" 23 #include "third_party/qcms/src/chain.h"
23 }; 24 };
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 virtual ColorTransformNull* GetNull() { return nullptr; } 244 virtual ColorTransformNull* GetNull() { return nullptr; }
244 virtual QCMSColorTransform* GetQCMS() { return nullptr; } 245 virtual QCMSColorTransform* GetQCMS() { return nullptr; }
245 246
246 // Join methods, returns true if the |next| transform was successfully 247 // Join methods, returns true if the |next| transform was successfully
247 // assimilated into |this|. 248 // assimilated into |this|.
248 // If Join() returns true, |next| is no longer needed and can be deleted. 249 // If Join() returns true, |next| is no longer needed and can be deleted.
249 virtual bool Join(ColorTransformStep* next) { return false; } 250 virtual bool Join(ColorTransformStep* next) { return false; }
250 251
251 // Return true if this is a null transform. 252 // Return true if this is a null transform.
252 virtual bool IsNull() { return false; } 253 virtual bool IsNull() { return false; }
253
254 virtual void Transform(ColorTransform::TriStim* color, size_t num) = 0; 254 virtual void Transform(ColorTransform::TriStim* color, size_t num) = 0;
255 virtual bool CanAppendShaderSource() { return false; }
256 virtual void AppendShaderSource(std::string* result) { NOTREACHED(); }
255 257
256 private: 258 private:
257 DISALLOW_COPY_AND_ASSIGN(ColorTransformStep); 259 DISALLOW_COPY_AND_ASSIGN(ColorTransformStep);
258 }; 260 };
259 261
260 class ColorTransformInternal : public ColorTransform { 262 class ColorTransformInternal : public ColorTransform {
261 public: 263 public:
262 ColorTransformInternal(const ColorSpace& from, 264 ColorTransformInternal(const ColorSpace& from,
263 const ColorSpace& to, 265 const ColorSpace& to,
264 Intent intent); 266 Intent intent);
265 ~ColorTransformInternal() override; 267 ~ColorTransformInternal() override;
266 268
267 // Perform transformation of colors, |colors| is both input and output.
268 void Transform(TriStim* colors, size_t num) override { 269 void Transform(TriStim* colors, size_t num) override {
269 for (const auto& step : steps_) 270 for (const auto& step : steps_)
270 step->Transform(colors, num); 271 step->Transform(colors, num);
271 } 272 }
273 bool CanGetShaderSource() const override;
274 std::string GetShaderSource() const override;
275 bool IsIdentity() const override { return steps_.empty(); }
272 size_t NumberOfStepsForTesting() const override { return steps_.size(); } 276 size_t NumberOfStepsForTesting() const override { return steps_.size(); }
273 277
274 private: 278 private:
275 void AppendColorSpaceToColorSpaceTransform(ColorSpace from, 279 void AppendColorSpaceToColorSpaceTransform(ColorSpace from,
276 const ColorSpace& to, 280 const ColorSpace& to,
277 ColorTransform::Intent intent); 281 ColorTransform::Intent intent);
278 void Simplify(); 282 void Simplify();
279 283
280 // Retrieve the ICC profile from which |color_space| was created, only if that 284 // Retrieve the ICC profile from which |color_space| was created, only if that
281 // is a more precise representation of the color space than the primaries and 285 // is a more precise representation of the color space than the primaries and
282 // transfer function in |color_space|. 286 // transfer function in |color_space|.
283 ScopedQcmsProfile GetQCMSProfileIfNecessary(const ColorSpace& color_space); 287 ScopedQcmsProfile GetQCMSProfileIfNecessary(const ColorSpace& color_space);
284 288
285 std::list<std::unique_ptr<ColorTransformStep>> steps_; 289 std::list<std::unique_ptr<ColorTransformStep>> steps_;
286 }; 290 };
287 291
292 #define SRC(...) \
293 do { \
294 *result += std::string(" ") + base::StringPrintf(__VA_ARGS__) + \
295 std::string("\n"); \
296 } while (0)
297
288 class ColorTransformNull : public ColorTransformStep { 298 class ColorTransformNull : public ColorTransformStep {
289 public: 299 public:
290 ColorTransformNull* GetNull() override { return this; } 300 ColorTransformNull* GetNull() override { return this; }
291 bool IsNull() override { return true; } 301 bool IsNull() override { return true; }
292 void Transform(ColorTransform::TriStim* color, size_t num) override {} 302 void Transform(ColorTransform::TriStim* color, size_t num) override {}
303 bool CanAppendShaderSource() override { return true; }
304 void AppendShaderSource(std::string* result) override {}
293 }; 305 };
294 306
295 class ColorTransformMatrix : public ColorTransformStep { 307 class ColorTransformMatrix : public ColorTransformStep {
296 public: 308 public:
297 explicit ColorTransformMatrix(const class Transform& matrix) 309 explicit ColorTransformMatrix(const class Transform& matrix)
298 : matrix_(matrix) {} 310 : matrix_(matrix) {}
299 ColorTransformMatrix* GetMatrix() override { return this; } 311 ColorTransformMatrix* GetMatrix() override { return this; }
300 bool Join(ColorTransformStep* next_untyped) override { 312 bool Join(ColorTransformStep* next_untyped) override {
301 ColorTransformMatrix* next = next_untyped->GetMatrix(); 313 ColorTransformMatrix* next = next_untyped->GetMatrix();
302 if (!next) 314 if (!next)
303 return false; 315 return false;
304 class Transform tmp = next->matrix_; 316 class Transform tmp = next->matrix_;
305 tmp *= matrix_; 317 tmp *= matrix_;
306 matrix_ = tmp; 318 matrix_ = tmp;
307 return true; 319 return true;
308 } 320 }
309 321
310 bool IsNull() override { 322 bool IsNull() override {
311 return SkMatrixIsApproximatelyIdentity(matrix_.matrix()); 323 return SkMatrixIsApproximatelyIdentity(matrix_.matrix());
312 } 324 }
313 325
314 void Transform(ColorTransform::TriStim* colors, size_t num) override { 326 void Transform(ColorTransform::TriStim* colors, size_t num) override {
315 for (size_t i = 0; i < num; i++) 327 for (size_t i = 0; i < num; i++)
316 matrix_.TransformPoint(colors + i); 328 matrix_.TransformPoint(colors + i);
317 } 329 }
318 330
331 bool CanAppendShaderSource() override { return true; }
332
333 void AppendShaderSource(std::string* result) override {
334 const SkMatrix44& m = matrix_.matrix();
335 SRC("color = mat3(%f, %f, %f, %f, %f, %f, %f, %f, %f) * color;",
336 m.get(0, 0), m.get(1, 0), m.get(2, 0), // column 1
337 m.get(0, 1), m.get(1, 1), m.get(2, 1), // column 2
338 m.get(0, 2), m.get(1, 2), m.get(2, 2)); // column 3
339 SRC("color += vec3(%f, %f, %f);", m.get(0, 3), m.get(1, 3), m.get(2, 3));
340 }
341
319 private: 342 private:
320 class Transform matrix_; 343 class Transform matrix_;
321 }; 344 };
322 345
323 class ColorTransformFromLinear : public ColorTransformStep { 346 class ColorTransformFromLinear : public ColorTransformStep {
324 public: 347 public:
325 explicit ColorTransformFromLinear(ColorSpace::TransferID transfer, 348 explicit ColorTransformFromLinear(ColorSpace::TransferID transfer,
326 const SkColorSpaceTransferFn& fn, 349 const SkColorSpaceTransferFn& fn,
327 bool fn_valid) 350 bool fn_valid)
328 : transfer_(transfer), fn_(fn), fn_valid_(fn_valid) { 351 : transfer_(transfer), fn_(fn), fn_valid_(fn_valid) {
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 607
585 // TODO(hubbe): shrink gamuts here (never stretch gamuts) 608 // TODO(hubbe): shrink gamuts here (never stretch gamuts)
586 } 609 }
587 610
588 steps_.push_back( 611 steps_.push_back(
589 base::MakeUnique<ColorTransformMatrix>(GetRangeAdjustMatrix(from))); 612 base::MakeUnique<ColorTransformMatrix>(GetRangeAdjustMatrix(from)));
590 613
591 steps_.push_back( 614 steps_.push_back(
592 base::MakeUnique<ColorTransformMatrix>(Invert(GetTransferMatrix(from)))); 615 base::MakeUnique<ColorTransformMatrix>(Invert(GetTransferMatrix(from))));
593 616
617 // If the target color space is not defined, just apply the adjust and
618 // tranfer matrices.
619 if (!to.IsValid())
620 return;
621
594 SkColorSpaceTransferFn to_linear_fn; 622 SkColorSpaceTransferFn to_linear_fn;
595 bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn); 623 bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn);
596 steps_.push_back(base::MakeUnique<ColorTransformToLinear>( 624 steps_.push_back(base::MakeUnique<ColorTransformToLinear>(
597 from.transfer_, to_linear_fn, to_linear_fn_valid)); 625 from.transfer_, to_linear_fn, to_linear_fn_valid));
598 626
599 if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) { 627 if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) {
600 // BT2020 CL is a special case. 628 // BT2020 CL is a special case.
601 steps_.push_back(base::MakeUnique<ColorTransformFromBT2020CL>()); 629 steps_.push_back(base::MakeUnique<ColorTransformFromBT2020CL>());
602 } 630 }
603 steps_.push_back( 631 steps_.push_back(
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 744
717 if (to_profile) { 745 if (to_profile) {
718 steps_.push_back(base::MakeUnique<QCMSColorTransform>( 746 steps_.push_back(base::MakeUnique<QCMSColorTransform>(
719 GetXYZD50Profile(), std::move(to_profile))); 747 GetXYZD50Profile(), std::move(to_profile)));
720 } 748 }
721 749
722 if (intent != Intent::TEST_NO_OPT) 750 if (intent != Intent::TEST_NO_OPT)
723 Simplify(); 751 Simplify();
724 } 752 }
725 753
754 std::string ColorTransformInternal::GetShaderSource() const {
755 std::string result;
756 result += "vec3 DoColorConversion(vec3 color) {\n";
757 for (const auto& step : steps_)
758 step->AppendShaderSource(&result);
759 result += " return color;\n";
760 result += "}\n";
761 return result;
762 }
763
764 bool ColorTransformInternal::CanGetShaderSource() const {
765 for (const auto& step : steps_) {
766 if (!step->CanAppendShaderSource())
767 return false;
768 }
769 return true;
770 }
771
726 ColorTransformInternal::~ColorTransformInternal() {} 772 ColorTransformInternal::~ColorTransformInternal() {}
727 773
728 void ColorTransformInternal::Simplify() { 774 void ColorTransformInternal::Simplify() {
729 for (auto iter = steps_.begin(); iter != steps_.end();) { 775 for (auto iter = steps_.begin(); iter != steps_.end();) {
730 std::unique_ptr<ColorTransformStep>& this_step = *iter; 776 std::unique_ptr<ColorTransformStep>& this_step = *iter;
731 777
732 // Try to Join |next_step| into |this_step|. If successful, re-visit the 778 // Try to Join |next_step| into |this_step|. If successful, re-visit the
733 // step before |this_step|. 779 // step before |this_step|.
734 auto iter_next = iter; 780 auto iter_next = iter;
735 iter_next++; 781 iter_next++;
(...skipping 26 matching lines...) Expand all
762 const ColorSpace& to, 808 const ColorSpace& to,
763 Intent intent) { 809 Intent intent) {
764 return std::unique_ptr<ColorTransform>( 810 return std::unique_ptr<ColorTransform>(
765 new ColorTransformInternal(from, to, intent)); 811 new ColorTransformInternal(from, to, intent));
766 } 812 }
767 813
768 ColorTransform::ColorTransform() {} 814 ColorTransform::ColorTransform() {}
769 ColorTransform::~ColorTransform() {} 815 ColorTransform::~ColorTransform() {}
770 816
771 } // namespace gfx 817 } // namespace gfx
OLDNEW
« cc/output/program_binding.cc ('K') | « ui/gfx/color_transform.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698