OLD | NEW |
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 Loading... |
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) const = 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. | 269 gfx::ColorSpace GetSrcColorSpace() const override { return src_; }; |
268 void Transform(TriStim* colors, size_t num) override { | 270 gfx::ColorSpace GetDstColorSpace() const override { return dst_; }; |
| 271 |
| 272 void Transform(TriStim* colors, size_t num) const override { |
269 for (const auto& step : steps_) | 273 for (const auto& step : steps_) |
270 step->Transform(colors, num); | 274 step->Transform(colors, num); |
271 } | 275 } |
| 276 bool CanGetShaderSource() const override; |
| 277 std::string GetShaderSource() const override; |
| 278 bool IsIdentity() const override { return steps_.empty(); } |
272 size_t NumberOfStepsForTesting() const override { return steps_.size(); } | 279 size_t NumberOfStepsForTesting() const override { return steps_.size(); } |
273 | 280 |
274 private: | 281 private: |
275 void AppendColorSpaceToColorSpaceTransform(ColorSpace from, | 282 void AppendColorSpaceToColorSpaceTransform(ColorSpace from, |
276 const ColorSpace& to, | 283 const ColorSpace& to, |
277 ColorTransform::Intent intent); | 284 ColorTransform::Intent intent); |
278 void Simplify(); | 285 void Simplify(); |
279 | 286 |
280 // Retrieve the ICC profile from which |color_space| was created, only if that | 287 // 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 | 288 // is a more precise representation of the color space than the primaries and |
282 // transfer function in |color_space|. | 289 // transfer function in |color_space|. |
283 ScopedQcmsProfile GetQCMSProfileIfNecessary(const ColorSpace& color_space); | 290 ScopedQcmsProfile GetQCMSProfileIfNecessary(const ColorSpace& color_space); |
284 | 291 |
285 std::list<std::unique_ptr<ColorTransformStep>> steps_; | 292 std::list<std::unique_ptr<ColorTransformStep>> steps_; |
| 293 gfx::ColorSpace src_; |
| 294 gfx::ColorSpace dst_; |
286 }; | 295 }; |
287 | 296 |
| 297 #define SRC(...) \ |
| 298 do { \ |
| 299 *result += std::string(" ") + base::StringPrintf(__VA_ARGS__) + \ |
| 300 std::string("\n"); \ |
| 301 } while (0) |
| 302 |
288 class ColorTransformNull : public ColorTransformStep { | 303 class ColorTransformNull : public ColorTransformStep { |
289 public: | 304 public: |
290 ColorTransformNull* GetNull() override { return this; } | 305 ColorTransformNull* GetNull() override { return this; } |
291 bool IsNull() override { return true; } | 306 bool IsNull() override { return true; } |
292 void Transform(ColorTransform::TriStim* color, size_t num) override {} | 307 void Transform(ColorTransform::TriStim* color, size_t num) const override {} |
| 308 bool CanAppendShaderSource() override { return true; } |
| 309 void AppendShaderSource(std::string* result) override {} |
293 }; | 310 }; |
294 | 311 |
295 class ColorTransformMatrix : public ColorTransformStep { | 312 class ColorTransformMatrix : public ColorTransformStep { |
296 public: | 313 public: |
297 explicit ColorTransformMatrix(const class Transform& matrix) | 314 explicit ColorTransformMatrix(const class Transform& matrix) |
298 : matrix_(matrix) {} | 315 : matrix_(matrix) {} |
299 ColorTransformMatrix* GetMatrix() override { return this; } | 316 ColorTransformMatrix* GetMatrix() override { return this; } |
300 bool Join(ColorTransformStep* next_untyped) override { | 317 bool Join(ColorTransformStep* next_untyped) override { |
301 ColorTransformMatrix* next = next_untyped->GetMatrix(); | 318 ColorTransformMatrix* next = next_untyped->GetMatrix(); |
302 if (!next) | 319 if (!next) |
303 return false; | 320 return false; |
304 class Transform tmp = next->matrix_; | 321 class Transform tmp = next->matrix_; |
305 tmp *= matrix_; | 322 tmp *= matrix_; |
306 matrix_ = tmp; | 323 matrix_ = tmp; |
307 return true; | 324 return true; |
308 } | 325 } |
309 | 326 |
310 bool IsNull() override { | 327 bool IsNull() override { |
311 return SkMatrixIsApproximatelyIdentity(matrix_.matrix()); | 328 return SkMatrixIsApproximatelyIdentity(matrix_.matrix()); |
312 } | 329 } |
313 | 330 |
314 void Transform(ColorTransform::TriStim* colors, size_t num) override { | 331 void Transform(ColorTransform::TriStim* colors, size_t num) const override { |
315 for (size_t i = 0; i < num; i++) | 332 for (size_t i = 0; i < num; i++) |
316 matrix_.TransformPoint(colors + i); | 333 matrix_.TransformPoint(colors + i); |
317 } | 334 } |
318 | 335 |
| 336 bool CanAppendShaderSource() override { return true; } |
| 337 |
| 338 void AppendShaderSource(std::string* result) override { |
| 339 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, " |
| 341 "%1.8e) * color;", |
| 342 m.get(0, 0), m.get(1, 0), m.get(2, 0), // column 1 |
| 343 m.get(0, 1), m.get(1, 1), m.get(2, 1), // column 2 |
| 344 m.get(0, 2), m.get(1, 2), m.get(2, 2)); // column 3 |
| 345 SRC("color += vec3(%1.8e, %1.8e, %1.8e);", m.get(0, 3), m.get(1, 3), |
| 346 m.get(2, 3)); |
| 347 } |
| 348 |
319 private: | 349 private: |
320 class Transform matrix_; | 350 class Transform matrix_; |
321 }; | 351 }; |
322 | 352 |
323 class ColorTransformFromLinear : public ColorTransformStep { | 353 class ColorTransformFromLinear : public ColorTransformStep { |
324 public: | 354 public: |
325 explicit ColorTransformFromLinear(ColorSpace::TransferID transfer, | 355 explicit ColorTransformFromLinear(ColorSpace::TransferID transfer, |
326 const SkColorSpaceTransferFn& fn, | 356 const SkColorSpaceTransferFn& fn, |
327 bool fn_valid) | 357 bool fn_valid) |
328 : transfer_(transfer), fn_(fn), fn_valid_(fn_valid) { | 358 : transfer_(transfer), fn_(fn), fn_valid_(fn_valid) { |
329 if (transfer_ == ColorSpace::TransferID::LINEAR_HDR) | 359 if (transfer_ == ColorSpace::TransferID::LINEAR_HDR) |
330 transfer_ = ColorSpace::TransferID::LINEAR; | 360 transfer_ = ColorSpace::TransferID::LINEAR; |
331 } | 361 } |
332 ColorTransformFromLinear* GetFromLinear() override { return this; } | 362 ColorTransformFromLinear* GetFromLinear() override { return this; } |
333 bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; } | 363 bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; } |
334 void Transform(ColorTransform::TriStim* colors, size_t num) override { | 364 void Transform(ColorTransform::TriStim* colors, size_t num) const override { |
335 if (fn_valid_) { | 365 if (fn_valid_) { |
336 for (size_t i = 0; i < num; i++) { | 366 for (size_t i = 0; i < num; i++) { |
337 colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x())); | 367 colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x())); |
338 colors[i].set_y(EvalSkTransferFn(fn_, colors[i].y())); | 368 colors[i].set_y(EvalSkTransferFn(fn_, colors[i].y())); |
339 colors[i].set_z(EvalSkTransferFn(fn_, colors[i].z())); | 369 colors[i].set_z(EvalSkTransferFn(fn_, colors[i].z())); |
340 } | 370 } |
341 } else { | 371 } else { |
342 for (size_t i = 0; i < num; i++) { | 372 for (size_t i = 0; i < num; i++) { |
343 colors[i].set_x(FromLinear(transfer_, colors[i].x())); | 373 colors[i].set_x(FromLinear(transfer_, colors[i].x())); |
344 colors[i].set_y(FromLinear(transfer_, colors[i].y())); | 374 colors[i].set_y(FromLinear(transfer_, colors[i].y())); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 return false; | 422 return false; |
393 } | 423 } |
394 | 424 |
395 bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; } | 425 bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; } |
396 | 426 |
397 // Assumes BT2020 primaries. | 427 // Assumes BT2020 primaries. |
398 static float Luma(const ColorTransform::TriStim& c) { | 428 static float Luma(const ColorTransform::TriStim& c) { |
399 return c.x() * 0.2627f + c.y() * 0.6780f + c.z() * 0.0593f; | 429 return c.x() * 0.2627f + c.y() * 0.6780f + c.z() * 0.0593f; |
400 } | 430 } |
401 | 431 |
402 ColorTransform::TriStim ClipToWhite(ColorTransform::TriStim& c) { | 432 static ColorTransform::TriStim ClipToWhite(ColorTransform::TriStim& c) { |
403 float maximum = max(max(c.x(), c.y()), c.z()); | 433 float maximum = max(max(c.x(), c.y()), c.z()); |
404 if (maximum > 1.0f) { | 434 if (maximum > 1.0f) { |
405 float l = Luma(c); | 435 float l = Luma(c); |
406 c.Scale(1.0f / maximum); | 436 c.Scale(1.0f / maximum); |
407 ColorTransform::TriStim white(1.0f, 1.0f, 1.0f); | 437 ColorTransform::TriStim white(1.0f, 1.0f, 1.0f); |
408 white.Scale((1.0f - 1.0f / maximum) * l / Luma(white)); | 438 white.Scale((1.0f - 1.0f / maximum) * l / Luma(white)); |
409 ColorTransform::TriStim black(0.0f, 0.0f, 0.0f); | 439 ColorTransform::TriStim black(0.0f, 0.0f, 0.0f); |
410 c += white - black; | 440 c += white - black; |
411 } | 441 } |
412 return c; | 442 return c; |
413 } | 443 } |
414 | 444 |
415 void Transform(ColorTransform::TriStim* colors, size_t num) override { | 445 void Transform(ColorTransform::TriStim* colors, size_t num) const override { |
416 if (fn_valid_) { | 446 if (fn_valid_) { |
417 for (size_t i = 0; i < num; i++) { | 447 for (size_t i = 0; i < num; i++) { |
418 colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x())); | 448 colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x())); |
419 colors[i].set_y(EvalSkTransferFn(fn_, colors[i].y())); | 449 colors[i].set_y(EvalSkTransferFn(fn_, colors[i].y())); |
420 colors[i].set_z(EvalSkTransferFn(fn_, colors[i].z())); | 450 colors[i].set_z(EvalSkTransferFn(fn_, colors[i].z())); |
421 } | 451 } |
422 } else if (transfer_ == ColorSpace::TransferID::SMPTEST2084_NON_HDR) { | 452 } else if (transfer_ == ColorSpace::TransferID::SMPTEST2084_NON_HDR) { |
423 for (size_t i = 0; i < num; i++) { | 453 for (size_t i = 0; i < num; i++) { |
424 ColorTransform::TriStim ret(ToLinear(transfer_, colors[i].x()), | 454 ColorTransform::TriStim ret(ToLinear(transfer_, colors[i].x()), |
425 ToLinear(transfer_, colors[i].y()), | 455 ToLinear(transfer_, colors[i].y()), |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 if (!next) | 499 if (!next) |
470 return false; | 500 return false; |
471 if (null_) | 501 if (null_) |
472 return false; | 502 return false; |
473 null_ = true; | 503 null_ = true; |
474 return true; | 504 return true; |
475 } | 505 } |
476 | 506 |
477 bool IsNull() override { return null_; } | 507 bool IsNull() override { return null_; } |
478 | 508 |
479 void Transform(ColorTransform::TriStim* RYB, size_t num) override { | 509 void Transform(ColorTransform::TriStim* RYB, size_t num) const override { |
480 for (size_t i = 0; i < num; i++) { | 510 for (size_t i = 0; i < num; i++) { |
481 float U, V; | 511 float U, V; |
482 float B_Y = RYB[i].z() - RYB[i].y(); | 512 float B_Y = RYB[i].z() - RYB[i].y(); |
483 if (B_Y <= 0) { | 513 if (B_Y <= 0) { |
484 U = B_Y / (-2.0 * -0.9702); | 514 U = B_Y / (-2.0 * -0.9702); |
485 } else { | 515 } else { |
486 U = B_Y / (2.0 * 0.7910); | 516 U = B_Y / (2.0 * 0.7910); |
487 } | 517 } |
488 float R_Y = RYB[i].x() - RYB[i].y(); | 518 float R_Y = RYB[i].x() - RYB[i].y(); |
489 if (R_Y <= 0) { | 519 if (R_Y <= 0) { |
(...skipping 17 matching lines...) Expand all Loading... |
507 if (!next) | 537 if (!next) |
508 return false; | 538 return false; |
509 if (null_) | 539 if (null_) |
510 return false; | 540 return false; |
511 null_ = true; | 541 null_ = true; |
512 return true; | 542 return true; |
513 } | 543 } |
514 | 544 |
515 bool IsNull() override { return null_; } | 545 bool IsNull() override { return null_; } |
516 | 546 |
517 void Transform(ColorTransform::TriStim* YUV, size_t num) override { | 547 void Transform(ColorTransform::TriStim* YUV, size_t num) const override { |
518 if (null_) | 548 if (null_) |
519 return; | 549 return; |
520 for (size_t i = 0; i < num; i++) { | 550 for (size_t i = 0; i < num; i++) { |
521 float Y = YUV[i].x(); | 551 float Y = YUV[i].x(); |
522 float U = YUV[i].y(); | 552 float U = YUV[i].y(); |
523 float V = YUV[i].z(); | 553 float V = YUV[i].z(); |
524 float B_Y, R_Y; | 554 float B_Y, R_Y; |
525 if (U <= 0) { | 555 if (U <= 0) { |
526 B_Y = Y * (-2.0 * -0.9702); | 556 B_Y = Y * (-2.0 * -0.9702); |
527 } else { | 557 } else { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 | 610 |
581 // TODO(hubbe): shrink gamuts here (never stretch gamuts) | 611 // TODO(hubbe): shrink gamuts here (never stretch gamuts) |
582 } | 612 } |
583 | 613 |
584 steps_.push_back( | 614 steps_.push_back( |
585 base::MakeUnique<ColorTransformMatrix>(GetRangeAdjustMatrix(from))); | 615 base::MakeUnique<ColorTransformMatrix>(GetRangeAdjustMatrix(from))); |
586 | 616 |
587 steps_.push_back( | 617 steps_.push_back( |
588 base::MakeUnique<ColorTransformMatrix>(Invert(GetTransferMatrix(from)))); | 618 base::MakeUnique<ColorTransformMatrix>(Invert(GetTransferMatrix(from)))); |
589 | 619 |
| 620 // If the target color space is not defined, just apply the adjust and |
| 621 // tranfer matrices. |
| 622 if (!to.IsValid()) |
| 623 return; |
| 624 |
590 SkColorSpaceTransferFn to_linear_fn; | 625 SkColorSpaceTransferFn to_linear_fn; |
591 bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn); | 626 bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn); |
592 steps_.push_back(base::MakeUnique<ColorTransformToLinear>( | 627 steps_.push_back(base::MakeUnique<ColorTransformToLinear>( |
593 from.transfer_, to_linear_fn, to_linear_fn_valid)); | 628 from.transfer_, to_linear_fn, to_linear_fn_valid)); |
594 | 629 |
595 if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) { | 630 if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) { |
596 // BT2020 CL is a special case. | 631 // BT2020 CL is a special case. |
597 steps_.push_back(base::MakeUnique<ColorTransformFromBT2020CL>()); | 632 steps_.push_back(base::MakeUnique<ColorTransformFromBT2020CL>()); |
598 } | 633 } |
599 steps_.push_back( | 634 steps_.push_back( |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 to_ = std::move(next->to_); | 668 to_ = std::move(next->to_); |
634 return true; | 669 return true; |
635 } | 670 } |
636 return false; | 671 return false; |
637 } | 672 } |
638 bool IsNull() override { | 673 bool IsNull() override { |
639 if (qcms_profile_match(from_.get(), to_.get())) | 674 if (qcms_profile_match(from_.get(), to_.get())) |
640 return true; | 675 return true; |
641 return false; | 676 return false; |
642 } | 677 } |
643 void Transform(ColorTransform::TriStim* colors, size_t num) override { | 678 void Transform(ColorTransform::TriStim* colors, size_t num) const override { |
644 CHECK(sizeof(ColorTransform::TriStim) == sizeof(float[3])); | 679 CHECK(sizeof(ColorTransform::TriStim) == sizeof(float[3])); |
645 // QCMS doesn't like numbers outside 0..1 | 680 // QCMS doesn't like numbers outside 0..1 |
646 for (size_t i = 0; i < num; i++) { | 681 for (size_t i = 0; i < num; i++) { |
647 colors[i].set_x(min(1.0f, max(0.0f, colors[i].x()))); | 682 colors[i].set_x(min(1.0f, max(0.0f, colors[i].x()))); |
648 colors[i].set_y(min(1.0f, max(0.0f, colors[i].y()))); | 683 colors[i].set_y(min(1.0f, max(0.0f, colors[i].y()))); |
649 colors[i].set_z(min(1.0f, max(0.0f, colors[i].z()))); | 684 colors[i].set_z(min(1.0f, max(0.0f, colors[i].z()))); |
650 } | 685 } |
651 qcms_chain_transform(from_.get(), to_.get(), | 686 qcms_chain_transform(from_.get(), to_.get(), |
652 reinterpret_cast<float*>(colors), | 687 reinterpret_cast<float*>(colors), |
653 reinterpret_cast<float*>(colors), num * 3); | 688 reinterpret_cast<float*>(colors), num * 3); |
(...skipping 27 matching lines...) Expand all Loading... |
681 xyz.green.Y = 1.0f; | 716 xyz.green.Y = 1.0f; |
682 xyz.blue.x = 0.0f; | 717 xyz.blue.x = 0.0f; |
683 xyz.blue.y = 0.0f; | 718 xyz.blue.y = 0.0f; |
684 xyz.blue.Y = 1.0f; | 719 xyz.blue.Y = 1.0f; |
685 w.x = 0.34567f; | 720 w.x = 0.34567f; |
686 w.y = 0.35850f; | 721 w.y = 0.35850f; |
687 w.Y = 1.0f; | 722 w.Y = 1.0f; |
688 return ScopedQcmsProfile(qcms_profile_create_rgb_with_gamma(w, xyz, 1.0f)); | 723 return ScopedQcmsProfile(qcms_profile_create_rgb_with_gamma(w, xyz, 1.0f)); |
689 } | 724 } |
690 | 725 |
691 ColorTransformInternal::ColorTransformInternal(const ColorSpace& from, | 726 ColorTransformInternal::ColorTransformInternal(const ColorSpace& src, |
692 const ColorSpace& to, | 727 const ColorSpace& dst, |
693 Intent intent) { | 728 Intent intent) |
| 729 : src_(src), dst_(dst) { |
694 // If no source color space is specified, do no transformation. | 730 // If no source color space is specified, do no transformation. |
695 // TODO(ccameron): We may want to assume sRGB at some point in the future. | 731 // TODO(ccameron): We may want dst assume sRGB at some point in the future. |
696 if (!from.IsValid()) | 732 if (!src_.IsValid()) |
697 return; | 733 return; |
698 | 734 |
699 ScopedQcmsProfile from_profile = GetQCMSProfileIfNecessary(from); | 735 ScopedQcmsProfile src_profile = GetQCMSProfileIfNecessary(src_); |
700 ScopedQcmsProfile to_profile = GetQCMSProfileIfNecessary(to); | 736 ScopedQcmsProfile dst_profile = GetQCMSProfileIfNecessary(dst_); |
701 bool has_from_profile = !!from_profile; | 737 bool has_src_profile = !!src_profile; |
702 bool has_to_profile = !!to_profile; | 738 bool has_dst_profile = !!dst_profile; |
703 | 739 |
704 if (from_profile) { | 740 if (src_profile) { |
705 steps_.push_back(base::MakeUnique<QCMSColorTransform>( | 741 steps_.push_back(base::MakeUnique<QCMSColorTransform>( |
706 std::move(from_profile), GetXYZD50Profile())); | 742 std::move(src_profile), GetXYZD50Profile())); |
707 } | 743 } |
708 | 744 |
709 AppendColorSpaceToColorSpaceTransform( | 745 AppendColorSpaceToColorSpaceTransform( |
710 has_from_profile ? ColorSpace::CreateXYZD50() : from, | 746 has_src_profile ? ColorSpace::CreateXYZD50() : src_, |
711 has_to_profile ? ColorSpace::CreateXYZD50() : to, intent); | 747 has_dst_profile ? ColorSpace::CreateXYZD50() : dst_, intent); |
712 | 748 |
713 if (to_profile) { | 749 if (dst_profile) { |
714 steps_.push_back(base::MakeUnique<QCMSColorTransform>( | 750 steps_.push_back(base::MakeUnique<QCMSColorTransform>( |
715 GetXYZD50Profile(), std::move(to_profile))); | 751 GetXYZD50Profile(), std::move(dst_profile))); |
716 } | 752 } |
717 | 753 |
718 if (intent != Intent::TEST_NO_OPT) | 754 if (intent != Intent::TEST_NO_OPT) |
719 Simplify(); | 755 Simplify(); |
720 } | 756 } |
721 | 757 |
| 758 std::string ColorTransformInternal::GetShaderSource() const { |
| 759 std::string result; |
| 760 result += "vec3 DoColorConversion(vec3 color) {\n"; |
| 761 for (const auto& step : steps_) |
| 762 step->AppendShaderSource(&result); |
| 763 result += " return color;\n"; |
| 764 result += "}\n"; |
| 765 return result; |
| 766 } |
| 767 |
| 768 bool ColorTransformInternal::CanGetShaderSource() const { |
| 769 for (const auto& step : steps_) { |
| 770 if (!step->CanAppendShaderSource()) |
| 771 return false; |
| 772 } |
| 773 return true; |
| 774 } |
| 775 |
722 ColorTransformInternal::~ColorTransformInternal() {} | 776 ColorTransformInternal::~ColorTransformInternal() {} |
723 | 777 |
724 void ColorTransformInternal::Simplify() { | 778 void ColorTransformInternal::Simplify() { |
725 for (auto iter = steps_.begin(); iter != steps_.end();) { | 779 for (auto iter = steps_.begin(); iter != steps_.end();) { |
726 std::unique_ptr<ColorTransformStep>& this_step = *iter; | 780 std::unique_ptr<ColorTransformStep>& this_step = *iter; |
727 | 781 |
728 // Try to Join |next_step| into |this_step|. If successful, re-visit the | 782 // Try to Join |next_step| into |this_step|. If successful, re-visit the |
729 // step before |this_step|. | 783 // step before |this_step|. |
730 auto iter_next = iter; | 784 auto iter_next = iter; |
731 iter_next++; | 785 iter_next++; |
(...skipping 26 matching lines...) Expand all Loading... |
758 const ColorSpace& to, | 812 const ColorSpace& to, |
759 Intent intent) { | 813 Intent intent) { |
760 return std::unique_ptr<ColorTransform>( | 814 return std::unique_ptr<ColorTransform>( |
761 new ColorTransformInternal(from, to, intent)); | 815 new ColorTransformInternal(from, to, intent)); |
762 } | 816 } |
763 | 817 |
764 ColorTransform::ColorTransform() {} | 818 ColorTransform::ColorTransform() {} |
765 ColorTransform::~ColorTransform() {} | 819 ColorTransform::~ColorTransform() {} |
766 | 820 |
767 } // namespace gfx | 821 } // namespace gfx |
OLD | NEW |