display_color_manager.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef ASH_DISPLAY_DISPLAY_COLOR_MANAGER_H_
  5. #define ASH_DISPLAY_DISPLAY_COLOR_MANAGER_H_
  6. #include <stdint.h>
  7. #include <memory>
  8. #include <vector>
  9. #include "ash/ash_export.h"
  10. #include "base/containers/flat_map.h"
  11. #include "base/files/file_path.h"
  12. #include "base/memory/weak_ptr.h"
  13. #include "base/sequence_checker.h"
  14. #include "third_party/skia/include/core/SkM44.h"
  15. #include "ui/display/display_observer.h"
  16. #include "ui/display/manager/display_configurator.h"
  17. #include "ui/display/types/display_constants.h"
  18. namespace base {
  19. class SequencedTaskRunner;
  20. }
  21. namespace display {
  22. class DisplaySnapshot;
  23. struct GammaRampRGBEntry;
  24. } // namespace display
  25. namespace ash {
  26. // An object that observes changes in display configuration applies any color
  27. // calibration where needed.
  28. class ASH_EXPORT DisplayColorManager
  29. : public display::DisplayConfigurator::Observer,
  30. public display::DisplayObserver {
  31. public:
  32. // The type of CRTC color transform matrix (CTM) support for the currently
  33. // connected displays.
  34. // WARNING: These values are persisted to logs. Entries should not be
  35. // renumbered and numeric values should never be reused.
  36. enum class DisplayCtmSupport {
  37. // All connected displays don't support CRTC CTMs.
  38. kNone = 0,
  39. // Mixed support; some displays support CRTC CTMs while others don't.
  40. kMixed = 1,
  41. // All connected displays support CRTC CTMs.
  42. kAll = 2,
  43. kMaxValue = kAll,
  44. };
  45. explicit DisplayColorManager(display::DisplayConfigurator* configurator);
  46. DisplayColorManager(const DisplayColorManager&) = delete;
  47. DisplayColorManager& operator=(const DisplayColorManager&) = delete;
  48. ~DisplayColorManager() override;
  49. DisplayCtmSupport displays_ctm_support() const {
  50. return displays_ctm_support_;
  51. }
  52. // Sets the given |color_matrix| on the display hardware of |display_id|,
  53. // combining the given matrix with any available color calibration matrix for
  54. // this display. This doesn't affect gamma or degamma values.
  55. // Returns true if the hardware supports this operation and the matrix was
  56. // successfully sent to the GPU.
  57. bool SetDisplayColorMatrix(int64_t display_id, const SkM44& color_matrix);
  58. // Similar to the above but can be used when a display snapshot is known to
  59. // the caller.
  60. bool SetDisplayColorMatrix(const display::DisplaySnapshot* display_snapshot,
  61. const SkM44& color_matrix);
  62. // display::DisplayConfigurator::Observer
  63. void OnDisplayModeChanged(
  64. const display::DisplayConfigurator::DisplayStateList& outputs) override;
  65. void OnDisplayModeChangeFailed(
  66. const display::DisplayConfigurator::DisplayStateList& displays,
  67. display::MultipleDisplayState failed_new_state) override {}
  68. // display::DisplayObserver:
  69. void OnDisplayRemoved(const display::Display& old_display) override;
  70. struct ColorCalibrationData {
  71. ColorCalibrationData();
  72. ~ColorCalibrationData();
  73. std::vector<display::GammaRampRGBEntry> degamma_lut;
  74. std::vector<display::GammaRampRGBEntry> gamma_lut;
  75. // Initialized to identity to reset color correction.
  76. std::vector<float> correction_matrix;
  77. };
  78. protected:
  79. virtual void FinishLoadCalibrationForDisplay(
  80. int64_t display_id,
  81. int64_t product_code,
  82. bool has_color_correction_matrix,
  83. display::DisplayConnectionType type,
  84. const base::FilePath& path,
  85. bool file_downloaded);
  86. virtual void UpdateCalibrationData(
  87. int64_t display_id,
  88. int64_t product_code,
  89. std::unique_ptr<ColorCalibrationData> data);
  90. private:
  91. friend class DisplayColorManagerTest;
  92. void ApplyDisplayColorCalibration(
  93. int64_t display_id,
  94. const ColorCalibrationData& calibration_data);
  95. // Attempts to start requesting the ICC profile for |display|. Returns true if
  96. // it was successful at initiating the request, false otherwise.
  97. // TODO(jchinlee): Investigate if we need this return value, or if we can
  98. // switch to a callback model.
  99. bool LoadCalibrationForDisplay(const display::DisplaySnapshot* display);
  100. // Display-specific calibration methods.
  101. // Look for VPD-written calibration.
  102. void QueryVpdForCalibration(int64_t display_id,
  103. int64_t product_code,
  104. bool has_color_correction_matrix,
  105. display::DisplayConnectionType type);
  106. void FinishQueryVpdForCalibration(int64_t display_id,
  107. int64_t product_code,
  108. bool has_color_correction_matrix,
  109. display::DisplayConnectionType type,
  110. const base::FilePath& expected_icc_path,
  111. bool found_icc);
  112. // Look for calibration for this display in Quirks.
  113. void QueryQuirksForCalibration(int64_t display_id,
  114. const std::string& display_name,
  115. int64_t product_code,
  116. bool has_color_correction_matrix,
  117. display::DisplayConnectionType type);
  118. // Applies an empty color calibration data, potentially with a color
  119. // matrix from |displays_color_matrix_map_| (if any for this display is
  120. // available). This is needed in cases we fail to load ICC profiles for
  121. // displays and we won't be getting any calibration data for them. We must
  122. // reset their configuration because some drivers hold on to it across screen
  123. // changes, https://crrev.com/1914343003.
  124. void ResetDisplayColorCalibration(int64_t display_id);
  125. display::DisplayConfigurator* configurator_;
  126. // This is a pre-allocated storage in order to avoid re-allocating the
  127. // matrix array every time when converting a skia matrix to a matrix array.
  128. std::vector<float> matrix_buffer_;
  129. // Contains a per display color transform matrix that can be post-multiplied
  130. // by any available color calibration matrix for the corresponding display.
  131. // The key is the display ID.
  132. base::flat_map<int64_t, SkM44> displays_color_matrix_map_;
  133. // Maps a display's color calibration data by the display's product code as
  134. // the key.
  135. base::flat_map<int64_t, std::unique_ptr<ColorCalibrationData>>
  136. calibration_map_;
  137. SEQUENCE_CHECKER(sequence_checker_);
  138. scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
  139. DisplayCtmSupport displays_ctm_support_;
  140. display::ScopedOptionalDisplayObserver display_observer_{this};
  141. // Factory for callbacks.
  142. base::WeakPtrFactory<DisplayColorManager> weak_ptr_factory_{this};
  143. };
  144. } // namespace ash
  145. #endif // ASH_DISPLAY_DISPLAY_COLOR_MANAGER_H_