1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef DISPLAYCOLOR_H_
18 #define DISPLAYCOLOR_H_
19 
20 #include <android/hardware/graphics/common/1.1/types.h>
21 #include <android/hardware/graphics/common/1.2/types.h>
22 
23 #include <functional>
24 #include <memory>
25 #include <optional>
26 #include <sstream>
27 #include <string>
28 #include <vector>
29 
30 namespace displaycolor {
31 
32 namespace hwc {
33 using android::hardware::graphics::common::V1_1::RenderIntent;
34 using android::hardware::graphics::common::V1_2::ColorMode;
35 using android::hardware::graphics::common::V1_2::Dataspace;
36 using android::hardware::graphics::common::V1_2::PixelFormat;
37 }  // namespace hwc
38 
39 /**
40  * hwc/displaycolor interface history
41  *
42  * 7.0.0.2022-03-22 Interface refactor
43  * 6.2.0.2022-05-18 Get calibrated serial number.
44  * 6.1.0.2022-04-29 dim solid color layer
45  * 6.0.0.2022-02-22 Get whether dimming in linear.
46  * 5.0.0.2022-02-17 Add layer dim ratio.
47  * 4.0.0.2021-12-20 Get pixel format and dataspace of blending stage.
48  * 3.0.0.2021-11-18 calibration info intf
49  * 2.0.0.2021-08-27 pass brightness table for hdr10+
50  * 1.0.0.2021-08-25 Initial release
51  */
52 
53 constexpr struct DisplayColorIntfVer {
54     uint16_t major; // increase it for new functionalities
55     uint16_t minor; // for bug fix and cause binary incompatible
56     uint16_t patch; // for bug fix and binary compatible
57 
58     bool operator==(const DisplayColorIntfVer &rhs) const {
59         return major == rhs.major &&
60             minor == rhs.minor &&
61             patch == rhs.patch;
62     }
63 
64     bool operator!=(const DisplayColorIntfVer &rhs) const {
65         return !operator==(rhs);
66     }
67 
CompatibleDisplayColorIntfVer68     bool Compatible(const DisplayColorIntfVer &rhs) const {
69         return major == rhs.major &&
70             minor == rhs.minor;
71     }
72 
73 } kInterfaceVersion {
74     7,
75     0,
76     0,
77 };
78 
79 /// A map associating supported RenderIntents for each supported ColorMode
80 using ColorModesMap = std::map<hwc::ColorMode, std::vector<hwc::RenderIntent>>;
81 
82 /// Image data bit depths.
83 enum class BitDepth { kEight, kTen };
84 
85 // deprecated by 'int64_t display_id' TODO: remove after all clients upgrade to
86 // display_id
87 /// Display type used to get pipeline or update display scene.
88 enum DisplayType {
89     /// builtin primary display
90     DISPLAY_PRIMARY = 0,
91     /// builtin secondary display
92     DISPLAY_SECONDARY = 1,
93     /// external display
94     DISPLAY_EXTERNAL = 2,
95     /// number of display
96     DISPLAY_MAX = 3,
97 };
98 
99 enum BrightnessMode {
100     BM_NOMINAL = 0,
101     BM_HBM = 1,
102     BM_MAX = 2,
103     BM_INVALID = BM_MAX,
104 };
105 
106 enum class HdrLayerState {
107     /// No HDR layer on screen
108     kHdrNone,
109     /// One or more small HDR layer(s), < 50% display size, take it as portrait mode.
110     kHdrSmall,
111     /// At least one large HDR layer, >= 50% display size, take it as full screen mode.
112     kHdrLarge,
113 };
114 
115 struct DisplayBrightnessRange {
116     // inclusive lower bound
117     float nits_min{};
118     // inclusive upper bound
119     float nits_max{};
120 
121     // inclusive lower bound
122     uint32_t dbv_min{};
123     // inclusive upper bound
124     uint32_t dbv_max{};
125 
126     bool brightness_min_exclusive;
127     float brightness_min{};
128     // inclusive upper bound
129     float brightness_max{};
130 
IsValidDisplayBrightnessRange131     bool IsValid() const {
132         // Criteria
133         // 1. max >= min
134         // 2. float min >= 0
135         return nits_min >= 0 && brightness_min >= 0 && nits_max >= nits_min && dbv_max >= dbv_min &&
136                 brightness_max >= brightness_min;
137     }
138 };
139 typedef std::map<BrightnessMode, DisplayBrightnessRange> BrightnessRangeMap;
140 
141 class IBrightnessTable {
142    public:
~IBrightnessTable()143     virtual ~IBrightnessTable(){};
144 
145     virtual std::optional<std::reference_wrapper<const DisplayBrightnessRange>> GetBrightnessRange(
146         BrightnessMode bm) const = 0;
147     virtual std::optional<uint32_t> BrightnessToDbv(float brightness) const = 0;
148     virtual std::optional<float> BrightnessToNits(float brightness, BrightnessMode &bm) const = 0;
149     virtual std::optional<uint32_t> NitsToDbv(BrightnessMode bm, float nits) const = 0;
150     virtual std::optional<float> DbvToNits(BrightnessMode bm, uint32_t dbv) const = 0;
151     virtual std::optional<float> NitsToBrightness(float nits) const = 0;
152     virtual std::optional<float> DbvToBrightness(uint32_t dbv) const = 0;
153 };
154 
155 /**
156  * @brief This structure holds data imported from HWC.
157  */
158 struct DisplayInfo {
159     // deprecated by display_id
160     DisplayType display_type{DISPLAY_MAX};
161     int64_t display_id{-1};
162     std::string panel_name;
163     std::string panel_serial;
164 
165     // If brightness table exists in pb file, it will overwrite values in brightness_ranges
166     BrightnessRangeMap brightness_ranges;
167 
168     // displays that no need to calibrate like virtual or external displays
169     // expect the pipeline outputs pixels with a standard color space
170     bool standard_calibrated_display{false};
171 };
172 
173 struct Color {
174     uint8_t r{};
175     uint8_t g{};
176     uint8_t b{};
177     uint8_t a{};
178 
179     bool operator==(const Color &rhs) const {
180         return r == rhs.r &&
181                g == rhs.g &&
182                b == rhs.b &&
183                a == rhs.a;
184     }
185 };
186 
187 struct LayerColorData {
188     bool operator==(const LayerColorData &rhs) const {
189         return dataspace == rhs.dataspace && matrix == rhs.matrix &&
190                static_metadata == rhs.static_metadata &&
191                dynamic_metadata == rhs.dynamic_metadata &&
192                dim_ratio == rhs.dim_ratio &&
193                is_solid_color_layer == rhs.is_solid_color_layer &&
194                (!is_solid_color_layer || solid_color == rhs.solid_color) &&
195                enabled == rhs.enabled;
196     }
197 
198     bool operator!=(const LayerColorData &rhs) const {
199         return !operator==(rhs);
200     }
201 
202     /**
203      * @brief HDR static metadata.
204      *
205      * See HWC v2.2 (IComposerClient::PerFrameMetadataKey)
206      * for more information.
207      */
208     struct HdrStaticMetadata {
209        private:
210         std::array<int32_t, 13> data;
211 
212        public:
213         HdrStaticMetadata() = default;
HdrStaticMetadataLayerColorData::HdrStaticMetadata214         HdrStaticMetadata(const HdrStaticMetadata &other)
215             : data(other.data), is_valid(other.is_valid) {}
216         HdrStaticMetadata(const HdrStaticMetadata &&other) = delete;
217         HdrStaticMetadata &operator=(const HdrStaticMetadata &other) {
218             data = other.data;
219             is_valid = other.is_valid;
220             return *this;
221         }
222         HdrStaticMetadata &operator=(HdrStaticMetadata &&other) = delete;
223         ~HdrStaticMetadata() = default;
224 
225         bool operator==(const HdrStaticMetadata &rhs) const {
226             return data == rhs.data && is_valid == rhs.is_valid;
227         }
228         bool operator!=(const HdrStaticMetadata &rhs) const {
229             return !operator==(rhs);
230         }
231 
232         /// Indicator for whether the data in this struct should be used.
233         bool is_valid = false;
234         /// This device's display's peak luminance, in nits.
235         int32_t &device_max_luminance = data[0];
236 
237         // Mastering display properties
238         int32_t &display_red_primary_x = data[1];
239         int32_t &display_red_primary_y = data[2];
240         int32_t &display_green_primary_x = data[3];
241         int32_t &display_green_primary_y = data[4];
242         int32_t &display_blue_primary_x = data[5];
243         int32_t &display_blue_primary_y = data[6];
244         int32_t &white_point_x = data[7];
245         int32_t &white_point_y = data[8];
246         int32_t &max_luminance = data[9];
247         int32_t &min_luminance = data[10];
248 
249         // Content properties
250         int32_t &max_content_light_level = data[11];
251         int32_t &max_frame_average_light_level = data[12];
252     };
253 
254     /**
255      * @brief HDR dynamic metadata.
256      *
257      * The members defined here are a subset of metadata define in
258      * SMPTE ST 2094-40:2016.
259      * Also see module videoapi information.
260      */
261     struct HdrDynamicMetadata {
262         bool operator==(const HdrDynamicMetadata &rhs) const {
263             return is_valid == rhs.is_valid &&
264                    display_maximum_luminance == rhs.display_maximum_luminance &&
265                    maxscl == rhs.maxscl &&
266                    maxrgb_percentages == rhs.maxrgb_percentages &&
267                    maxrgb_percentiles == rhs.maxrgb_percentiles &&
268                    tm_flag == rhs.tm_flag && tm_knee_x == rhs.tm_knee_x &&
269                    tm_knee_y == rhs.tm_knee_y &&
270                    bezier_curve_anchors == rhs.bezier_curve_anchors;
271         }
272         bool operator!=(const HdrDynamicMetadata &rhs) const {
273             return !operator==(rhs);
274         }
275 
276         /// Indicator for whether the data in this struct should be used.
277         bool is_valid = false;
278 
279         uint32_t display_maximum_luminance{};
280         std::array<uint32_t, 3> maxscl;
281         std::vector<uint8_t> maxrgb_percentages;
282         std::vector<uint32_t> maxrgb_percentiles;
283         uint16_t tm_flag{};
284         uint16_t tm_knee_x{};
285         uint16_t tm_knee_y{};
286         std::vector<uint16_t> bezier_curve_anchors;
287     };
288 
289     /// This layer's dataspace (color gamut, transfer function, and range).
290     hwc::Dataspace dataspace = hwc::Dataspace::UNKNOWN;
291     /// Color transform for this layer. See SET_LAYER_COLOR_TRANSFORM HWC v2.3.
292     // clang-format off
293     std::array<float, 16> matrix {
294         1.0, 0.0, 0.0, 0.0,
295         0.0, 1.0, 0.0, 0.0,
296         0.0, 0.0, 1.0, 0.0,
297         0.0, 0.0, 0.0, 1.0
298     };
299     // clang-format on
300     /**
301      * @brief This layer's HDR static metadata. Only applicable when dataspace
302      * indicates this is an HDR layer.
303      */
304     HdrStaticMetadata static_metadata;
305     /**
306      * @brief This layer's HDR dynamic metadata. Only applicable when dataspace
307      * indicates this is an HDR layer.
308      */
309     HdrDynamicMetadata dynamic_metadata;
310 
311     /**
312      * @brief the layer's luminance dim ratio
313      */
314     float dim_ratio = 1.0f;
315 
316     /**
317      * @brief is layer solid color
318      */
319     bool is_solid_color_layer{};
320 
321     /**
322      * @brief color for solid color layer
323      */
324     Color solid_color;
325 
326     /**
327      * @brief indicates if the layer is client target
328      *
329      */
330     bool is_client_target = false;
331 
332     /**
333      * @brief indicates if this layer data has enabled. Do not compute the
334      * colordata if its false. true by default for backward compatibility.
335      */
336     bool enabled = true;
337 };
338 
339 struct LtmParams {
340     struct Display {
341         int32_t width{};
342         int32_t height{};
343         bool operator==(const Display &rhs) const {
344           return width == rhs.width && height == rhs.height;
345         }
346     };
347 
348     struct Roi {
349         int32_t left{};
350         int32_t top{};
351         int32_t right{};
352         int32_t bottom{};
353 
ValidLtmParams::Roi354         bool Valid(int32_t display_width, int32_t display_height) const {
355             return left >= 0 && right > left && right <= display_width &&
356                 top >= 0 && bottom > top && bottom <= display_height;
357         }
358 
359         bool operator==(const Roi &rhs) const {
360           return left == rhs.left &&
361               top == rhs.top &&
362               right == rhs.right &&
363               bottom == rhs.bottom;
364         }
365     };
366 
367     Display display;
368     Roi roi;
369     // for debug purpose
370     bool force_enable{};
371     bool sr_in_gtm{true};
ConfigUpdateNeededLtmParams372     bool ConfigUpdateNeeded(const LtmParams &rhs) const {
373         return display == rhs.display && roi == rhs.roi && force_enable == rhs.force_enable;
374     }
375 };
376 
377 /**
378  * @brief DisplayScene holds all the information required for libdisplaycolor to
379  * return correct data.
380  */
381 struct DisplayScene {
382     bool operator==(const DisplayScene &rhs) const {
383         // TODO: if lux is used by HDR tone mapping, need to check here
384         // but should trigger scene change as less as possible, for example,
385         // only when HDR is on screen and lux change exceeds some threshold.
386         return layer_data == rhs.layer_data &&
387                dpu_bit_depth == rhs.dpu_bit_depth &&
388                color_mode == rhs.color_mode &&
389                render_intent == rhs.render_intent &&
390                matrix == rhs.matrix &&
391                force_hdr == rhs.force_hdr &&
392                bm == rhs.bm &&
393                lhbm_on == rhs.lhbm_on &&
394                dbv == rhs.dbv &&
395                refresh_rate == rhs.refresh_rate &&
396                operation_rate == rhs.operation_rate &&
397                hdr_layer_state == rhs.hdr_layer_state &&
398                temperature == rhs.temperature;
399     }
400     bool operator!=(const DisplayScene &rhs) const {
401         return !(*this == rhs);
402     }
403 
404     /// A vector of layer color data.
405     std::vector<LayerColorData> layer_data;
406     /// The bit depth the DPU is currently outputting
407     BitDepth dpu_bit_depth = BitDepth::kTen;
408     /// The current ColorMode (typically set by SurfaceFlinger)
409     hwc::ColorMode color_mode = hwc::ColorMode::NATIVE;
410     /// The current RenderIntent (typically set by SurfaceFlinger)
411     hwc::RenderIntent render_intent = hwc::RenderIntent::COLORIMETRIC;
412     /// Color transform for this layer. See SET_COLOR_TRANSFORM HWC v2.1.
413     // clang-format off
414     std::array<float, 16> matrix {
415         1.0, 0.0, 0.0, 0.0,
416         0.0, 1.0, 0.0, 0.0,
417         0.0, 0.0, 1.0, 0.0,
418         0.0, 0.0, 0.0, 1.0
419     };
420     // clang-format on
421     /// When this bit is set, process hdr layers and the layer matrix even if
422     //it's in native color mode.
423     bool force_hdr = false;
424 
425     /// display brightness mode
426     BrightnessMode bm = BrightnessMode::BM_NOMINAL;
427 
428     /// dbv level
429     uint32_t dbv = 0;
430 
431     /// the nits value corresponding to the dbv above
432     float nits = 0;
433 
434     /// lhbm status
435     bool lhbm_on = false;
436 
437     /// refresh rate
438     float refresh_rate = 60.0f;
439 
440     /// operation rate to switch between hs/ns mode
441     uint32_t operation_rate = 120;
442 
443     /// display temperature in degrees Celsius
444     uint32_t temperature = UINT_MAX;
445 
446     /// hdr layer state on screen
447     HdrLayerState hdr_layer_state = HdrLayerState::kHdrNone;
448 
449     /// ambient lux
450     float lux{};
451 
452     /// Ltm params gathered in HWC
453     LtmParams ltm_params;
454 };
455 
456 struct CalibrationInfo {
457     bool factory_cal_loaded = false;
458     bool golden_cal_loaded = false;
459     bool common_cal_loaded = false;
460     bool dev_cal_loaded = false;
461 };
462 
463 /// An interface specifying functions that are HW-agnostic.
464 class IDisplayColorGeneric {
465    public:
466     /// A generic stage in the display pipeline.
467     template <typename T>
468     struct DisplayStage {
469         using ConfigType = T;
470 
471         std::function<void(void)> data_applied_notifier = nullptr;
NotifyDataAppliedDisplayStage472         void NotifyDataApplied() const {
473             if (data_applied_notifier) {
474                 data_applied_notifier();
475             }
476         }
477 
478         bool enable = false;
479         /// A flag indicating if the data has been changed in last Update call.
480         // It should be set when enable is changed from false to true.
481         bool dirty = false;
482 
483         const ConfigType *config = nullptr;
484     };
485 
486     /// A collection of stages. For example, It could be pre-blending stages
487     //(per-channel) or post-blending stages.
488     template <typename ... IStageData>
489     struct IStageDataCollection : public IStageData ... {
~IStageDataCollectionIStageDataCollection490         virtual ~IStageDataCollection() {}
491     };
492 
493     /// Interface for accessing data for panel
494     class IPanel {
495       public:
496         /// Get the adjusted dbv for panel.
497         virtual uint32_t GetAdjustedBrightnessLevel() const = 0;
498 
~IPanel()499         virtual ~IPanel() {}
500     };
501 
~IDisplayColorGeneric()502     virtual ~IDisplayColorGeneric() {}
503 
504     /**
505      * @brief Update display color data. This function is expected to be called
506      * in the context of HWC::validateDisplay, if the display scene has changed.
507      *
508      * @param display The display relating to the scene.
509      * @param scene Display scene data to use during the update.
510      * @return OK if successful, error otherwise.
511      */
512     //deprecated by the 'int64_t display' version
513     virtual int Update(const DisplayType display, const DisplayScene &scene) = 0;
514     virtual int Update(const int64_t display, const DisplayScene &scene) = 0;
515 
516     /**
517      * @brief Update display color data. This function is expected to be called
518      * in the context of HWC::presentDisplay, if the display scene has changed
519      * since the Update call for HWC::validateDisplay.
520      *
521      * @param display The display relating to the scene.
522      * @param scene Display scene data to use during the update.
523      * @return OK if successful, error otherwise.
524      */
525     //deprecated by the 'int64_t display' version
526     virtual int UpdatePresent(const DisplayType display, const DisplayScene &scene) = 0;
527     virtual int UpdatePresent(const int64_t display, const DisplayScene &scene) = 0;
528 
529     /**
530      * @brief Check if refresh rate regamma compensation is enabled.
531      *
532      * @return true for yes.
533      */
534     //deprecated by the 'int64_t display' version
535     virtual bool IsRrCompensationEnabled(const DisplayType display) = 0;
536     virtual bool IsRrCompensationEnabled(const int64_t display) = 0;
537 
538     /**
539      * @brief Get calibration information for each profiles.
540      * @param display The display to get the calibration information.
541      */
542     //deprecated by the 'int64_t display' version
543     virtual const CalibrationInfo &GetCalibrationInfo(const DisplayType display) const = 0;
544     virtual const CalibrationInfo &GetCalibrationInfo(const int64_t display) const = 0;
545 
546     /**
547      * @brief Get a map of supported ColorModes, and supported RenderIntents for
548      * each ColorMode.
549      * @param display The display to get the color modes and render intents.
550      */
551     //deprecated by the 'int64_t display' version
552     virtual const ColorModesMap &ColorModesAndRenderIntents(const DisplayType display) const = 0;
553     virtual const ColorModesMap &ColorModesAndRenderIntents(const int64_t display) const = 0;
554 
555     /**
556      * @brief Get pixel format and dataspace of blending stage.
557      * @param display to read the properties.
558      * @param pixel_format Pixel format of blending stage
559      * @param dataspace Dataspace of blending stage
560      * @return OK if successful, error otherwise.
561      */
562     //deprecated by the 'int64_t display' version
563     virtual int GetBlendingProperty(const DisplayType display,
564                                     hwc::PixelFormat &pixel_format,
565                                     hwc::Dataspace &dataspace,
566                                     bool &dimming_linear) const = 0;
567     virtual int GetBlendingProperty(const int64_t display,
568                                     hwc::PixelFormat &pixel_format,
569                                     hwc::Dataspace &dataspace,
570                                     bool &dimming_linear) const = 0;
571 
572     /**
573      * @brief Get the serial number for the panel used during calibration.
574      * @param display to get the calibrated serial number.
575      * @return The calibrated serial number.
576      */
577     //deprecated by the 'int64_t display' version
578     virtual const std::string& GetCalibratedSerialNumber(DisplayType display) const = 0;
579     virtual const std::string& GetCalibratedSerialNumber(const int64_t display) const = 0;
580 
581     /**
582      * @brief Get brightness table to do brightness conversion between {normalized brightness, nits,
583      * dbv}.
584      * @param display Reserved field to choose display type.
585      * @param table Return brightness table if successful, nullptr if the table is not valid.
586      * @return OK if successful, error otherwise.
587      */
588     //deprecated by the 'int64_t display' version
589     virtual int GetBrightnessTable(DisplayType display,
590                                    std::unique_ptr<const IBrightnessTable> &table) const = 0;
591     virtual int GetBrightnessTable(const int64_t display,
592                                    std::unique_ptr<const IBrightnessTable> &table) const = 0;
593 
594     /**
595      * @brief Add a display for color pipeline configuration.
596      * @param display_info info of this display
597      * @return OK if successful, error otherwise.
598      */
599     virtual int AddDisplay(const DisplayInfo &display_info) = 0;
600 
601     /**
602      * @brief Remove a display and release its resources.
603      */
604     virtual void RemoveDisplay(const int64_t display) = 0;
605 
606     /**
607      * @brief request a Update call. For example, a debug command has changed
608      * the displaycolor internal states and need to apply to next frame update.
609      */
610     virtual bool CheckUpdateNeeded(const int64_t display) = 0;
611 
612     /**
613      * @brief Check if early power on is needed.
614      *
615      * @return true for yes.
616      */
617     //deprecated by the 'int64_t display' version
618     virtual bool IsEarlyPowerOnNeeded(const DisplayType display) = 0;
619     virtual bool IsEarlyPowerOnNeeded(const int64_t display) = 0;
620 
621     /**
622      * @brief a debug call from command line with arguments, output will show on screen.
623      * @param display id
624      * @param cur_obj for the current object
625      * @param obj_sel a path (object names concatenated by dots) to locate the target object
626      * @param action to apply to the target object
627      * @param args the arguments for the action
628      * @return string to show on screen
629      */
630     virtual std::string Debug(const int64_t display,
631                               const std::string& cur_obj,
632                               const std::string& obj_sel,
633                               const std::string& action,
634                               const std::vector<std::string>& args) = 0;
635 };
636 
637 extern "C" {
638     const DisplayColorIntfVer *GetInterfaceVersion();
639 }
640 
641 }  // namespace displaycolor
642 
643 #endif  // DISPLAYCOLOR_H_
644