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
|
// 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_;
}
// Returns whether |display_id| has color correction matrix according to
// |configurator_|
bool HasColorCorrectionMatrix(int64_t display_id);
// 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_
|