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

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

Issue 2697413002: color: Add analytic transfer functions in shaders (Closed)
Patch Set: Disable on android 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
« no previous file with comments | « cc/output/gl_renderer_unittest.cc ('k') | ui/gfx/color_transform_unittest.cc » ('j') | 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>
(...skipping 17 matching lines...) Expand all
28 using std::log; 28 using std::log;
29 using std::max; 29 using std::max;
30 using std::min; 30 using std::min;
31 using std::pow; 31 using std::pow;
32 using std::sqrt; 32 using std::sqrt;
33 33
34 namespace gfx { 34 namespace gfx {
35 35
36 namespace { 36 namespace {
37 37
38 std::string Str(float f) {
39 return base::StringPrintf("%+1.8e", f);
40 }
41
38 // Helper for scoped QCMS profiles. 42 // Helper for scoped QCMS profiles.
39 struct QcmsProfileDeleter { 43 struct QcmsProfileDeleter {
40 void operator()(qcms_profile* p) { 44 void operator()(qcms_profile* p) {
41 if (p) { 45 if (p) {
42 qcms_profile_release(p); 46 qcms_profile_release(p);
43 } 47 }
44 } 48 }
45 }; 49 };
46 using ScopedQcmsProfile = std::unique_ptr<qcms_profile, QcmsProfileDeleter>; 50 using ScopedQcmsProfile = std::unique_ptr<qcms_profile, QcmsProfileDeleter>;
47 51
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 224
221 Transform GetPrimaryTransform(const gfx::ColorSpace& color_space) { 225 Transform GetPrimaryTransform(const gfx::ColorSpace& color_space) {
222 SkMatrix44 primary_matrix; 226 SkMatrix44 primary_matrix;
223 color_space.GetPrimaryMatrix(&primary_matrix); 227 color_space.GetPrimaryMatrix(&primary_matrix);
224 return Transform(primary_matrix); 228 return Transform(primary_matrix);
225 } 229 }
226 230
227 } // namespace 231 } // namespace
228 232
229 class ColorTransformMatrix; 233 class ColorTransformMatrix;
234 class ColorTransformSkTransferFn;
230 class ColorTransformFromLinear; 235 class ColorTransformFromLinear;
231 class ColorTransformToBT2020CL; 236 class ColorTransformToBT2020CL;
232 class ColorTransformFromBT2020CL; 237 class ColorTransformFromBT2020CL;
233 class ColorTransformNull; 238 class ColorTransformNull;
234 class QCMSColorTransform; 239 class QCMSColorTransform;
235 240
236 class ColorTransformStep { 241 class ColorTransformStep {
237 public: 242 public:
238 ColorTransformStep() {} 243 ColorTransformStep() {}
239 virtual ~ColorTransformStep() {} 244 virtual ~ColorTransformStep() {}
240 virtual ColorTransformFromLinear* GetFromLinear() { return nullptr; } 245 virtual ColorTransformFromLinear* GetFromLinear() { return nullptr; }
241 virtual ColorTransformToBT2020CL* GetToBT2020CL() { return nullptr; } 246 virtual ColorTransformToBT2020CL* GetToBT2020CL() { return nullptr; }
242 virtual ColorTransformFromBT2020CL* GetFromBT2020CL() { return nullptr; } 247 virtual ColorTransformFromBT2020CL* GetFromBT2020CL() { return nullptr; }
248 virtual ColorTransformSkTransferFn* GetSkTransferFn() { return nullptr; }
243 virtual ColorTransformMatrix* GetMatrix() { return nullptr; } 249 virtual ColorTransformMatrix* GetMatrix() { return nullptr; }
244 virtual ColorTransformNull* GetNull() { return nullptr; } 250 virtual ColorTransformNull* GetNull() { return nullptr; }
245 virtual QCMSColorTransform* GetQCMS() { return nullptr; } 251 virtual QCMSColorTransform* GetQCMS() { return nullptr; }
246 252
247 // Join methods, returns true if the |next| transform was successfully 253 // Join methods, returns true if the |next| transform was successfully
248 // assimilated into |this|. 254 // assimilated into |this|.
249 // If Join() returns true, |next| is no longer needed and can be deleted. 255 // If Join() returns true, |next| is no longer needed and can be deleted.
250 virtual bool Join(ColorTransformStep* next) { return false; } 256 virtual bool Join(ColorTransformStep* next) { return false; }
251 257
252 // Return true if this is a null transform. 258 // Return true if this is a null transform.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 336
331 void Transform(ColorTransform::TriStim* colors, size_t num) const override { 337 void Transform(ColorTransform::TriStim* colors, size_t num) const override {
332 for (size_t i = 0; i < num; i++) 338 for (size_t i = 0; i < num; i++)
333 matrix_.TransformPoint(colors + i); 339 matrix_.TransformPoint(colors + i);
334 } 340 }
335 341
336 bool CanAppendShaderSource() override { return true; } 342 bool CanAppendShaderSource() override { return true; }
337 343
338 void AppendShaderSource(std::string* result) override { 344 void AppendShaderSource(std::string* result) override {
339 const SkMatrix44& m = matrix_.matrix(); 345 const SkMatrix44& m = matrix_.matrix();
340 SRC("color = mat3(%1.8e, %1.8e, %1.8e, %1.8e, %1.8e, %1.8e, %1.8e, %1.8e, " 346 SRC("color = mat3(%+1.8e, %+1.8e, %+1.8e,", // column 1
341 "%1.8e) * color;", 347 m.get(0, 0), m.get(1, 0), m.get(2, 0));
342 m.get(0, 0), m.get(1, 0), m.get(2, 0), // column 1 348 SRC(" %+1.8e, %+1.8e, %+1.8e,", // column 2
343 m.get(0, 1), m.get(1, 1), m.get(2, 1), // column 2 349 m.get(0, 1), m.get(1, 1), m.get(2, 1));
344 m.get(0, 2), m.get(1, 2), m.get(2, 2)); // column 3 350 SRC(" %+1.8e, %+1.8e, %+1.8e) * color;", // column 3
345 SRC("color += vec3(%1.8e, %1.8e, %1.8e);", m.get(0, 3), m.get(1, 3), 351 m.get(0, 2), m.get(1, 2), m.get(2, 2));
346 m.get(2, 3)); 352 SRC("color = vec3(%+1.8e, %+1.8e, %+1.8e) + color;", // column 4
353 m.get(0, 3), m.get(1, 3), m.get(2, 3));
347 } 354 }
348 355
349 private: 356 private:
350 class Transform matrix_; 357 class Transform matrix_;
351 }; 358 };
352 359
360 class ColorTransformSkTransferFn : public ColorTransformStep {
361 public:
362 explicit ColorTransformSkTransferFn(const SkColorSpaceTransferFn& fn)
363 : fn_(fn) {}
364 ColorTransformSkTransferFn* GetSkTransferFn() override { return this; }
365
366 bool Join(ColorTransformStep* next_untyped) override {
367 ColorTransformSkTransferFn* next = next_untyped->GetSkTransferFn();
368 if (!next)
369 return false;
370 if (SkTransferFnsApproximatelyCancel(fn_, next->fn_)) {
371 // Set to be the identity.
372 fn_.fA = 1;
373 fn_.fB = 0;
374 fn_.fC = 1;
375 fn_.fD = 0;
376 fn_.fE = 0;
377 fn_.fF = 0;
378 fn_.fG = 1;
379 return true;
380 }
381 return false;
382 }
383
384 bool IsNull() override { return SkTransferFnIsApproximatelyIdentity(fn_); }
385
386 void Transform(ColorTransform::TriStim* colors, size_t num) const override {
387 for (size_t i = 0; i < num; i++) {
388 colors[i].set_x(SkTransferFnEval(fn_, colors[i].x()));
389 colors[i].set_y(SkTransferFnEval(fn_, colors[i].y()));
390 colors[i].set_z(SkTransferFnEval(fn_, colors[i].z()));
391 }
392 }
393
394 bool CanAppendShaderSource() override { return true; }
395
396 void AppendShaderSourceChannel(std::string* result, const char* value) {
397 const float kEpsilon = 1.f / 1024.f;
398
399 // Construct the linear segment
400 // linear = C * x + F
401 // Elide operations that will be close to the identity.
402 std::string linear = value;
403 if (std::abs(fn_.fC - 1.f) > kEpsilon)
404 linear = Str(fn_.fC) + " * " + linear;
405 if (std::abs(fn_.fF) > kEpsilon)
406 linear = linear + " + " + Str(fn_.fF);
407
408 // Construct the nonlinear segment.
409 // nonlinear = pow(A * x + B, G) + E
410 // Elide operations (especially the pow) that will be close to the
411 // identity.
412 std::string nonlinear = value;
413 if (std::abs(fn_.fA - 1.f) > kEpsilon)
414 nonlinear = Str(fn_.fA) + " * " + nonlinear;
415 if (std::abs(fn_.fB) > kEpsilon)
416 nonlinear = nonlinear + " + " + Str(fn_.fB);
417 if (std::abs(fn_.fG - 1.f) > kEpsilon)
418 nonlinear = "pow(" + nonlinear + ", " + Str(fn_.fG) + ")";
419 if (std::abs(fn_.fE) > kEpsilon)
420 nonlinear = nonlinear + " + " + Str(fn_.fE);
421
422 // Add both parts, skpping the if clause if possible.
423 if (fn_.fD > kEpsilon) {
424 SRC("if (%s < %f)", value, fn_.fD);
425 SRC(" %s = %s;", value, linear.c_str());
426 SRC("else");
427 SRC(" %s = %s;", value, nonlinear.c_str());
428 } else {
429 SRC("%s = %s;", value, nonlinear.c_str());
430 }
431 }
432
433 void AppendShaderSource(std::string* result) override {
434 // Append the transfer function for each channel.
435 AppendShaderSourceChannel(result, "color.r");
436 AppendShaderSourceChannel(result, "color.g");
437 AppendShaderSourceChannel(result, "color.b");
438 }
439
440 private:
441 SkColorSpaceTransferFn fn_;
442 };
443
353 class ColorTransformFromLinear : public ColorTransformStep { 444 class ColorTransformFromLinear : public ColorTransformStep {
354 public: 445 public:
355 explicit ColorTransformFromLinear(ColorSpace::TransferID transfer, 446 explicit ColorTransformFromLinear(ColorSpace::TransferID transfer)
356 const SkColorSpaceTransferFn& fn, 447 : transfer_(transfer) {}
357 bool fn_valid)
358 : transfer_(transfer), fn_(fn), fn_valid_(fn_valid) {
359 if (transfer_ == ColorSpace::TransferID::LINEAR_HDR)
360 transfer_ = ColorSpace::TransferID::LINEAR;
361 }
362 ColorTransformFromLinear* GetFromLinear() override { return this; } 448 ColorTransformFromLinear* GetFromLinear() override { return this; }
363 bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; } 449 bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; }
364 void Transform(ColorTransform::TriStim* colors, size_t num) const override { 450 void Transform(ColorTransform::TriStim* colors, size_t num) const override {
365 if (fn_valid_) { 451 for (size_t i = 0; i < num; i++) {
366 for (size_t i = 0; i < num; i++) { 452 colors[i].set_x(FromLinear(transfer_, colors[i].x()));
367 colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x())); 453 colors[i].set_y(FromLinear(transfer_, colors[i].y()));
368 colors[i].set_y(EvalSkTransferFn(fn_, colors[i].y())); 454 colors[i].set_z(FromLinear(transfer_, colors[i].z()));
369 colors[i].set_z(EvalSkTransferFn(fn_, colors[i].z()));
370 }
371 } else {
372 for (size_t i = 0; i < num; i++) {
373 colors[i].set_x(FromLinear(transfer_, colors[i].x()));
374 colors[i].set_y(FromLinear(transfer_, colors[i].y()));
375 colors[i].set_z(FromLinear(transfer_, colors[i].z()));
376 }
377 } 455 }
378 } 456 }
379 457
380 private: 458 private:
381 friend class ColorTransformToLinear; 459 friend class ColorTransformToLinear;
382 ColorSpace::TransferID transfer_; 460 ColorSpace::TransferID transfer_;
383 SkColorSpaceTransferFn fn_;
384 bool fn_valid_ = false;
385 }; 461 };
386 462
387 class ColorTransformToLinear : public ColorTransformStep { 463 class ColorTransformToLinear : public ColorTransformStep {
388 public: 464 public:
389 explicit ColorTransformToLinear(ColorSpace::TransferID transfer, 465 explicit ColorTransformToLinear(ColorSpace::TransferID transfer)
390 const SkColorSpaceTransferFn& fn, 466 : transfer_(transfer) {}
391 bool fn_valid)
392 : transfer_(transfer), fn_(fn), fn_valid_(fn_valid) {
393 if (transfer_ == ColorSpace::TransferID::LINEAR_HDR)
394 transfer_ = ColorSpace::TransferID::LINEAR;
395 }
396
397 static bool IsGamma22(ColorSpace::TransferID transfer) {
398 switch (transfer) {
399 // We don't need to check BT709 here because it's been translated into
400 // SRGB in ColorSpaceToColorSpaceTransform::ColorSpaceToLinear below.
401 case ColorSpace::TransferID::GAMMA22:
402 case ColorSpace::TransferID::IEC61966_2_1: // SRGB
403 return true;
404
405 default:
406 return false;
407 }
408 }
409 467
410 bool Join(ColorTransformStep* next_untyped) override { 468 bool Join(ColorTransformStep* next_untyped) override {
411 ColorTransformFromLinear* next = next_untyped->GetFromLinear(); 469 ColorTransformFromLinear* next = next_untyped->GetFromLinear();
412 if (!next) 470 if (!next)
413 return false; 471 return false;
414 // TODO(ccameron): Use SkTransferFnsApproximatelyCancel and 472 if (transfer_ == next->transfer_) {
415 // SkTransferFnIsApproximatelyIdentity to merge parametric transfer
416 // functions.
417 if (transfer_ == next->transfer_ ||
418 (IsGamma22(transfer_) && IsGamma22(next->transfer_))) {
419 transfer_ = ColorSpace::TransferID::LINEAR; 473 transfer_ = ColorSpace::TransferID::LINEAR;
420 return true; 474 return true;
421 } 475 }
422 return false; 476 return false;
423 } 477 }
424 478
425 bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; } 479 bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; }
426 480
427 // Assumes BT2020 primaries. 481 // Assumes BT2020 primaries.
428 static float Luma(const ColorTransform::TriStim& c) { 482 static float Luma(const ColorTransform::TriStim& c) {
429 return c.x() * 0.2627f + c.y() * 0.6780f + c.z() * 0.0593f; 483 return c.x() * 0.2627f + c.y() * 0.6780f + c.z() * 0.0593f;
430 } 484 }
431 485
432 static ColorTransform::TriStim ClipToWhite(ColorTransform::TriStim& c) { 486 static ColorTransform::TriStim ClipToWhite(ColorTransform::TriStim& c) {
433 float maximum = max(max(c.x(), c.y()), c.z()); 487 float maximum = max(max(c.x(), c.y()), c.z());
434 if (maximum > 1.0f) { 488 if (maximum > 1.0f) {
435 float l = Luma(c); 489 float l = Luma(c);
436 c.Scale(1.0f / maximum); 490 c.Scale(1.0f / maximum);
437 ColorTransform::TriStim white(1.0f, 1.0f, 1.0f); 491 ColorTransform::TriStim white(1.0f, 1.0f, 1.0f);
438 white.Scale((1.0f - 1.0f / maximum) * l / Luma(white)); 492 white.Scale((1.0f - 1.0f / maximum) * l / Luma(white));
439 ColorTransform::TriStim black(0.0f, 0.0f, 0.0f); 493 ColorTransform::TriStim black(0.0f, 0.0f, 0.0f);
440 c += white - black; 494 c += white - black;
441 } 495 }
442 return c; 496 return c;
443 } 497 }
444 498
445 void Transform(ColorTransform::TriStim* colors, size_t num) const override { 499 void Transform(ColorTransform::TriStim* colors, size_t num) const override {
446 if (fn_valid_) { 500 if (transfer_ == ColorSpace::TransferID::SMPTEST2084_NON_HDR) {
447 for (size_t i = 0; i < num; i++) {
448 colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x()));
449 colors[i].set_y(EvalSkTransferFn(fn_, colors[i].y()));
450 colors[i].set_z(EvalSkTransferFn(fn_, colors[i].z()));
451 }
452 } else if (transfer_ == ColorSpace::TransferID::SMPTEST2084_NON_HDR) {
453 for (size_t i = 0; i < num; i++) { 501 for (size_t i = 0; i < num; i++) {
454 ColorTransform::TriStim ret(ToLinear(transfer_, colors[i].x()), 502 ColorTransform::TriStim ret(ToLinear(transfer_, colors[i].x()),
455 ToLinear(transfer_, colors[i].y()), 503 ToLinear(transfer_, colors[i].y()),
456 ToLinear(transfer_, colors[i].z())); 504 ToLinear(transfer_, colors[i].z()));
457 if (Luma(ret) > 0.0) { 505 if (Luma(ret) > 0.0) {
458 ColorTransform::TriStim smpte2084( 506 ColorTransform::TriStim smpte2084(
459 ToLinear(ColorSpace::TransferID::SMPTEST2084, colors[i].x()), 507 ToLinear(ColorSpace::TransferID::SMPTEST2084, colors[i].x()),
460 ToLinear(ColorSpace::TransferID::SMPTEST2084, colors[i].y()), 508 ToLinear(ColorSpace::TransferID::SMPTEST2084, colors[i].y()),
461 ToLinear(ColorSpace::TransferID::SMPTEST2084, colors[i].z())); 509 ToLinear(ColorSpace::TransferID::SMPTEST2084, colors[i].z()));
462 smpte2084.Scale(Luma(ret) / Luma(smpte2084)); 510 smpte2084.Scale(Luma(ret) / Luma(smpte2084));
463 ret = ClipToWhite(smpte2084); 511 ret = ClipToWhite(smpte2084);
464 } 512 }
465 colors[i] = ret; 513 colors[i] = ret;
466 } 514 }
467 } else { 515 } else {
468 for (size_t i = 0; i < num; i++) { 516 for (size_t i = 0; i < num; i++) {
469 colors[i].set_x(ToLinear(transfer_, colors[i].x())); 517 colors[i].set_x(ToLinear(transfer_, colors[i].x()));
470 colors[i].set_y(ToLinear(transfer_, colors[i].y())); 518 colors[i].set_y(ToLinear(transfer_, colors[i].y()));
471 colors[i].set_z(ToLinear(transfer_, colors[i].z())); 519 colors[i].set_z(ToLinear(transfer_, colors[i].z()));
472 } 520 }
473 } 521 }
474 } 522 }
475 523
476 private: 524 private:
477 ColorSpace::TransferID transfer_; 525 ColorSpace::TransferID transfer_;
478 SkColorSpaceTransferFn fn_;
479 bool fn_valid_ = false;
480 }; 526 };
481 527
482 // BT2020 Constant Luminance is different than most other 528 // BT2020 Constant Luminance is different than most other
483 // ways to encode RGB values as YUV. The basic idea is that 529 // ways to encode RGB values as YUV. The basic idea is that
484 // transfer functions are applied on the Y value instead of 530 // transfer functions are applied on the Y value instead of
485 // on the RGB values. However, running the transfer function 531 // on the RGB values. However, running the transfer function
486 // on the U and V values doesn't make any sense since they 532 // on the U and V values doesn't make any sense since they
487 // are centered at 0.5. To work around this, the transfer function 533 // are centered at 0.5. To work around this, the transfer function
488 // is applied to the Y, R and B values, and then the U and V 534 // is applied to the Y, R and B values, and then the U and V
489 // values are calculated from that. 535 // values are calculated from that.
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 662
617 steps_.push_back( 663 steps_.push_back(
618 base::MakeUnique<ColorTransformMatrix>(Invert(GetTransferMatrix(from)))); 664 base::MakeUnique<ColorTransformMatrix>(Invert(GetTransferMatrix(from))));
619 665
620 // If the target color space is not defined, just apply the adjust and 666 // If the target color space is not defined, just apply the adjust and
621 // tranfer matrices. 667 // tranfer matrices.
622 if (!to.IsValid()) 668 if (!to.IsValid())
623 return; 669 return;
624 670
625 SkColorSpaceTransferFn to_linear_fn; 671 SkColorSpaceTransferFn to_linear_fn;
626 bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn); 672 if (from.GetTransferFunction(&to_linear_fn)) {
627 steps_.push_back(base::MakeUnique<ColorTransformToLinear>( 673 steps_.push_back(
628 from.transfer_, to_linear_fn, to_linear_fn_valid)); 674 base::MakeUnique<ColorTransformSkTransferFn>(to_linear_fn));
675 } else {
676 steps_.push_back(base::MakeUnique<ColorTransformToLinear>(from.transfer_));
677 }
629 678
630 if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) { 679 if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) {
631 // BT2020 CL is a special case. 680 // BT2020 CL is a special case.
632 steps_.push_back(base::MakeUnique<ColorTransformFromBT2020CL>()); 681 steps_.push_back(base::MakeUnique<ColorTransformFromBT2020CL>());
633 } 682 }
634 steps_.push_back( 683 steps_.push_back(
635 base::MakeUnique<ColorTransformMatrix>(GetPrimaryTransform(from))); 684 base::MakeUnique<ColorTransformMatrix>(GetPrimaryTransform(from)));
636 685
637 steps_.push_back( 686 steps_.push_back(
638 base::MakeUnique<ColorTransformMatrix>(Invert(GetPrimaryTransform(to)))); 687 base::MakeUnique<ColorTransformMatrix>(Invert(GetPrimaryTransform(to))));
639 if (to.matrix_ == ColorSpace::MatrixID::BT2020_CL) { 688 if (to.matrix_ == ColorSpace::MatrixID::BT2020_CL) {
640 // BT2020 CL is a special case. 689 // BT2020 CL is a special case.
641 steps_.push_back(base::MakeUnique<ColorTransformToBT2020CL>()); 690 steps_.push_back(base::MakeUnique<ColorTransformToBT2020CL>());
642 } 691 }
643 692
644 SkColorSpaceTransferFn from_linear_fn; 693 SkColorSpaceTransferFn from_linear_fn;
645 bool from_linear_fn_valid = to.GetInverseTransferFunction(&from_linear_fn); 694 if (to.GetInverseTransferFunction(&from_linear_fn)) {
646 steps_.push_back(base::MakeUnique<ColorTransformFromLinear>( 695 steps_.push_back(
647 to.transfer_, from_linear_fn, from_linear_fn_valid)); 696 base::MakeUnique<ColorTransformSkTransferFn>(from_linear_fn));
697 } else {
698 steps_.push_back(base::MakeUnique<ColorTransformFromLinear>(to.transfer_));
699 }
648 700
649 steps_.push_back( 701 steps_.push_back(
650 base::MakeUnique<ColorTransformMatrix>(GetTransferMatrix(to))); 702 base::MakeUnique<ColorTransformMatrix>(GetTransferMatrix(to)));
651 703
652 steps_.push_back( 704 steps_.push_back(
653 base::MakeUnique<ColorTransformMatrix>(Invert(GetRangeAdjustMatrix(to)))); 705 base::MakeUnique<ColorTransformMatrix>(Invert(GetRangeAdjustMatrix(to))));
654 } 706 }
655 707
656 class QCMSColorTransform : public ColorTransformStep { 708 class QCMSColorTransform : public ColorTransformStep {
657 public: 709 public:
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 const ColorSpace& to, 864 const ColorSpace& to,
813 Intent intent) { 865 Intent intent) {
814 return std::unique_ptr<ColorTransform>( 866 return std::unique_ptr<ColorTransform>(
815 new ColorTransformInternal(from, to, intent)); 867 new ColorTransformInternal(from, to, intent));
816 } 868 }
817 869
818 ColorTransform::ColorTransform() {} 870 ColorTransform::ColorTransform() {}
819 ColorTransform::~ColorTransform() {} 871 ColorTransform::~ColorTransform() {}
820 872
821 } // namespace gfx 873 } // namespace gfx
OLDNEW
« no previous file with comments | « cc/output/gl_renderer_unittest.cc ('k') | ui/gfx/color_transform_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698