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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
// 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_constants.h"
namespace base {
class SequencedTaskRunner;
}
namespace display {
class DisplaySnapshot;
struct GammaRampRGBEntry;
} // 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 given |color_matrix| on the display hardware of |display_id|,
// combining the given matrix with any available color calibration matrix for
// this display. This doesn't affect gamma or degamma values.
// Returns true if the hardware supports this operation and the matrix was
// successfully sent to the GPU.
bool SetDisplayColorMatrix(int64_t display_id, const SkM44& color_matrix);
// Similar to the above but can be used when a display snapshot is known to
// the caller.
bool SetDisplayColorMatrix(const display::DisplaySnapshot* display_snapshot,
const SkM44& color_matrix);
// display::DisplayConfigurator::Observer
void OnDisplayModeChanged(
const display::DisplayConfigurator::DisplayStateList& outputs) override;
void OnDisplayModeChangeFailed(
const display::DisplayConfigurator::DisplayStateList& displays,
display::MultipleDisplayState failed_new_state) override {}
// display::DisplayObserver:
void OnDisplayRemoved(const display::Display& old_display) override;
struct ColorCalibrationData {
ColorCalibrationData();
~ColorCalibrationData();
std::vector<display::GammaRampRGBEntry> degamma_lut;
std::vector<display::GammaRampRGBEntry> gamma_lut;
// Initialized to identity to reset color correction.
std::vector<float> correction_matrix;
};
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<ColorCalibrationData> data);
private:
friend class DisplayColorManagerTest;
void ApplyDisplayColorCalibration(
int64_t display_id,
const ColorCalibrationData& 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, ExperimentalAsh> 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<ColorCalibrationData>>
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_
|