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_GS101_H_
18 #define DISPLAYCOLOR_GS101_H_
19 
20 #include <array>
21 #include <functional>
22 #include <memory>
23 
24 #include <displaycolor/displaycolor.h>
25 
26 namespace displaycolor {
27 
28 /// An interface for accessing GS101 color management data.
29 class IDisplayColorGS101 : public IDisplayColorGeneric {
30    private:
31     /// Register data for matrices in DPP and DQE.
32     template <typename T, size_t kDimensions>
33     struct MatrixData {
34         /**
35          * DQE0_GAMMA_MATRIX_COEFF0..4[GAMMA_MATRIX_COEFF_xx]
36          * DQE0_LINEAR_MATRIX_COEFF0..4[LINEAR_MATRIX_COEFF_xx]
37          * DPP_HDR_LSI_L#_GM_COEF0..8[COEF], #(0..5)
38          */
39         std::array<T, kDimensions * kDimensions> coeffs{};
40 
41         /**
42          * DQE0_GAMMA_MATRIX_OFFSET0..1[GAMMA_MATRIX_COEFF_n]
43          * DQE0_LINEAR_MATRIX_OFFSET0..1[LINEAR_MATRIX_COEFF_n]
44          * DPP_HDR_LSI_L#_GM_OFFS0..2[OFFS], #(0..5)
45          */
46         std::array<T, kDimensions> offsets{};
47     };
48 
49    public:
50     /// LUT with programmable X and Y
51     template <typename XT, typename YT, size_t N>
52     struct TransferFunctionData {
53         std::array<XT, N> posx;
54         std::array<YT, N> posy;
55     };
56 
57     template <typename XType, typename YType, size_t N>
58     struct FlexLutConfigType {
59         // keep XContainer, YContainer and kLutLen for backward compatibility.
60         using XContainer = XType;
61         using YContainer = YType;
62         static constexpr size_t kLutLen = N;
63 
64         TransferFunctionData<XContainer, YContainer, kLutLen> tf_data;
65     };
66 
67     template <typename DType, size_t N>
68     struct MatrixConfigType {
69         using Container = DType;
70         static constexpr size_t kDimensions = N;
71 
72         MatrixData<Container, kDimensions> matrix_data;
73     };
74 
75     /**
76      * @brief Interface for accessing data for DPP stages.
77      *
78      * Note that the data returned by this interface is applicable to both DPP
79      * in DPU and the HDR blocks in G2D. These two IPs' register specs are
80      * identical, with one caveat: While all G2D layers support display tone
81      * mapping (DTM) for HDR10+, only DPP layers L1/L3/L5 support this stage.
82      */
83     struct IDppData {
84         struct IEotfData {
85             /// Register data for the EOTF LUT in DPP.
86             using EotfData = DisplayStage<FlexLutConfigType<uint16_t, uint32_t, 129>>;
87 
88             /// Get data for the EOTF LUT.
89             virtual const EotfData& EotfLut() const = 0;
~IEotfDataIDppData::IEotfData90             virtual ~IEotfData() {}
91         };
92 
93         struct IGmData {
94            public:
95             /// Register data for the gamut mapping (GM) matrix in DPP.
96             using GmData = DisplayStage<MatrixConfigType<uint32_t, 3>>;
97 
98             /// Get data for the gamut mapping (GM) matrix.
99             virtual const GmData& Gm() const = 0;
~IGmDataIDppData::IGmData100             virtual ~IGmData() {}
101         };
102 
103         struct IDtmData {
104            private:
105             struct Rgb2YData {
106                 uint16_t coeff_r;    // DPP_HDR_LSI_L#_TM_COEF[COEFR] #(1, 3, 5)
107                 uint16_t coeff_g;    // DPP_HDR_LSI_L#_TM_COEF[COEFG] #(1, 3, 5)
108                 uint16_t coeff_b;    // DPP_HDR_LSI_L#_TM_COEF[COEFB] #(1, 3, 5)
109                 uint16_t rng_x_min;  // DPP_HDR_LSI_L#_TM_RNGX[MINX] #(1, 3, 5)
110                 uint16_t rng_x_max;  // DPP_HDR_LSI_L#_TM_RNGX[MAXX] #(1, 3, 5)
111                 uint16_t rng_y_min;  // DPP_HDR_LSI_L#_TM_RNGY[MINY] #(1, 3, 5)
112                 uint16_t rng_y_max;  // DPP_HDR_LSI_L#_TM_RNGY[MAXY] #(1, 3, 5)
113             };
114 
115             // To avoid updating legacy source code after separate lut and rgb2y,
116             // use inheritance instead of composition.
117             struct DtmConfigType : public FlexLutConfigType<uint32_t, uint32_t, 33>,
118                                    public Rgb2YData {};
119 
120            public:
121             /**
122              * @brief Register data for the DTM stage in DPP.
123              *
124              * Note that this data is only applicable to DPP in layers L1/L3/L5
125              * and G2D layers. Other DPPs do not support DTM. DTM data will be
126              * provided for any layer whose DisplayScene::LayerColorData
127              * contains HDR dynamic metadata. It is the caller's (typically
128              * HWComposer) responsibility to validate layers and HW capabilities
129              * correctly, before calling this API.
130              */
131             using DtmData = DisplayStage<DtmConfigType>;
132 
133             /**
134              * @brief Get data for the DTM LUT. Only used for HDR10+, and only
135              * applicable to DPPs that support this functionality.
136              */
137             virtual const DtmData& Dtm() const = 0;
~IDtmDataIDppData::IDtmData138             virtual ~IDtmData() {}
139         };
140 
141         struct IOetfData {
142             /// Register data for the OETF LUT in DPP.
143             using OetfData = DisplayStage<FlexLutConfigType<uint32_t, uint16_t, 33>>;
144 
145             /// Get data for the OETF LUT.
146             virtual const OetfData& OetfLut() const = 0;
~IOetfDataIDppData::IOetfData147             virtual ~IOetfData() {}
148         };
149     };
150 
151     struct IDpp
152         : public IStageDataCollection<IDppData::IEotfData, IDppData::IGmData,
153                                       IDppData::IDtmData, IDppData::IOetfData> {
154         /// Get the solid color
155         virtual const Color SolidColor() const = 0;
156 
~IDppIDpp157         virtual ~IDpp() {}
158     };
159 
160     /// Interface for accessing data for DQE stages.
161     struct IDqeData {
162        public:
163         struct IDqeControlData {
164            private:
165             /// 32-bit DQE dither register, same definition as in uapi
166             struct DitherConfigType {
167                 uint8_t en : 1;
168                 uint8_t mode : 1;
169                 uint8_t frame_con : 1;
170                 uint8_t frame_offset : 2;
171                 uint8_t table_sel_r : 1;
172                 uint8_t table_sel_g : 1;
173                 uint8_t table_sel_b : 1;
174                 uint32_t reserved : 24;
175             };
176 
177             struct DqeControlConfigType {
178                 /// DQE force 10bpc mode
179                 bool force_10bpc = false;
180 
181                 /// flag to use cgc_dither
182                 bool cgc_dither_override = false;
183                 /// CGC dither register value
184                 union {
185                     DitherConfigType cgc_dither_reg = {};
186                     uint16_t cgc_dither;  // only lowest 16 bit is used
187                 };
188 
189                 /// flag to use disp_dither
190                 bool disp_dither_override = false;
191                 /// Display dither register value
192                 union {
193                     DitherConfigType disp_dither_reg = {};
194                     uint8_t disp_dither;  // only lowest 8 bit is used
195                 };
196             };
197 
198            public:
199             /// DQE control data
200             using DqeControlData = DisplayStage<DqeControlConfigType>;
201 
202             /// Get DQE control data
203             virtual const DqeControlData& DqeControl() const = 0;
~IDqeControlDataIDqeData::IDqeControlData204             virtual ~IDqeControlData() {}
205         };
206 
207         struct IGammaMatrixData {
208             /// Register data for the gamma and linear matrices in DQE.
209             using DqeMatrixData = DisplayStage<MatrixConfigType<uint16_t, 3>>;
210 
211             /// Get data for the gamma-space matrix.
212             virtual const DqeMatrixData& GammaMatrix() const = 0;
~IGammaMatrixDataIDqeData::IGammaMatrixData213             virtual ~IGammaMatrixData() {}
214         };
215 
216         struct IDegammaLutData {
217            private:
218             struct DegammaConfigType {
219                 using Container = uint16_t;
220                 static constexpr size_t kLutLen = 65;
221 
222                 std::array<Container, kLutLen> values;
223             };
224 
225            public:
226             /// Register data for the degamma LUT in DQE.
227             using DegammaLutData = DisplayStage<DegammaConfigType>;
228 
229             /// Get data for the 1D de-gamma LUT (EOTF).
230             virtual const DegammaLutData& DegammaLut() const = 0;
~IDegammaLutDataIDqeData::IDegammaLutData231             virtual ~IDegammaLutData() {}
232         };
233 
234         struct ILinearMatrixData {
235             /// Register data for the gamma and linear matrices in DQE.
236             using DqeMatrixData = DisplayStage<MatrixConfigType<uint16_t, 3>>;
237 
238             /// Get data for the linear-space matrix.
239             virtual const DqeMatrixData& LinearMatrix() const = 0;
~ILinearMatrixDataIDqeData::ILinearMatrixData240             virtual ~ILinearMatrixData() {}
241         };
242 
243         struct ICgcData {
244            private:
245             struct CgcConfigType {
246                 using Container = uint32_t;
247                 static constexpr size_t kChannelLutLen = 2457;
248                 // nodes number at each dimension of this 3d lut
249                 static constexpr size_t kVirtualChanelLen = 17;
250 
251                 /// DQE0_CGC_LUT_R_N{0-2456} (8 bit: 0~2047, 10 bit: 0~8191)
252                 std::array<Container, kChannelLutLen> r_values{};
253                 /// DQE0_CGC_LUT_G_N{0-2456} (8 bit: 0~2047, 10 bit: 0~8191)
254                 std::array<Container, kChannelLutLen> g_values{};
255                 /// DQE0_CGC_LUT_B_N{0-2456} (8 bit: 0~2047, 10 bit: 0~8191)
256                 std::array<Container, kChannelLutLen> b_values{};
257             };
258 
259            public:
260             /// Register data for CGC.
261             using CgcData = DisplayStage<CgcConfigType>;
262 
263             /// Get data for the Color Gamut Conversion stage (3D LUT).
264             virtual const CgcData& Cgc() const = 0;
~ICgcDataIDqeData::ICgcData265             virtual ~ICgcData() {}
266         };
267 
268         struct IRegammaLutData {
269            private:
270             struct RegammaConfigType {
271                 using Container = uint16_t;
272                 static constexpr size_t kChannelLutLen = 65;
273 
274                 /// REGAMMA LUT_R_{00-64} (8 bit: 0~1024, 10 bit: 0~4096)
275                 std::array<Container, kChannelLutLen> r_values{};
276                 /// REGAMMA LUT_G_{00-64} (8 bit: 0~1024, 10 bit: 0~4096)
277                 std::array<Container, kChannelLutLen> g_values{};
278                 /// REGAMMA LUT_B_{00-64} (8 bit: 0~1024, 10 bit: 0~4096)
279                 std::array<Container, kChannelLutLen> b_values{};
280             };
281 
282            public:
283             /// Register data for the regamma LUT.
284             using RegammaLutData = DisplayStage<RegammaConfigType>;
285 
286             /// Get data for the 3x1D re-gamma LUTa (OETF).
287             virtual const RegammaLutData& RegammaLut() const = 0;
~IRegammaLutDataIDqeData::IRegammaLutData288             virtual ~IRegammaLutData() {}
289         };
290     };
291 
292     struct IDqe : public IStageDataCollection<
293                       IDqeData::IDqeControlData, IDqeData::IGammaMatrixData,
294                       IDqeData::IDegammaLutData, IDqeData::ILinearMatrixData,
295                       IDqeData::ICgcData, IDqeData::IRegammaLutData> {
~IDqeIDqe296         virtual ~IDqe() {}
297     };
298 
299     /// Interface for accessing particular display color data
300     struct IDisplayPipelineData {
301         /**
302          * @brief Get handles to Display Pre-Processor (DPP) data accessors.
303          *
304          * The order of the returned DPP handles match the order of the
305          * LayerColorData provided as part of struct DisplayScene and
306          * IDisplayColorGeneric::Update().
307          */
308         virtual std::vector<std::reference_wrapper<const IDpp>> Dpp() const = 0;
309 
310         /// Get a handle to Display Quality Enhancer (DQE) data accessors.
311         virtual const IDqe& Dqe() const = 0;
312 
313         /// Get a handle to panel data accessors
314         virtual const IPanel& Panel() const = 0;
315 
~IDisplayPipelineDataIDisplayPipelineData316         virtual ~IDisplayPipelineData() {}
317     };
318 
319     /// Get pipeline color data for specified display type
320     // deprecated by the 'int64_t display' version
321     virtual const IDisplayPipelineData* GetPipelineData(DisplayType display) const = 0;
322     virtual const IDisplayPipelineData* GetPipelineData(const int64_t display) const = 0;
323 
~IDisplayColorGS101()324     virtual ~IDisplayColorGS101() {}
325 };
326 
327 extern "C" {
328 
329 /// Get the GS101 instance.
330 IDisplayColorGS101* GetDisplayColorGS101(const std::vector<DisplayInfo> &display_info);
331 }
332 
333 }  // namespace displaycolor
334 
335 #endif  // DISPLAYCOLOR_GS101_H_
336