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