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     /**
51      * @brief Interface for accessing data for DPP stages.
52      *
53      * Note that the data returned by this interface is applicable to both DPP
54      * in DPU and the HDR blocks in G2D. These two IPs' register specs are
55      * identical, with one caveat: While all G2D layers support display tone
56      * mapping (DTM) for HDR10+, only DPP layers L1/L3/L5 support this stage.
57      */
58     struct IDpp {
59      private:
60         /// Register data for transfer function LUTs in DPP)
61         template <typename XT, typename YT, size_t N>
62         struct TransferFunctionData {
63             /**
64              * DPP_HDR_LSI_L#_EOTF_POSX0~64[POSXn], #(0..5), n(0..1)
65              * DPP_HDR_LSI_L#_OETF_POSX0~16[POSXn], #(0..5), n(0..1)
66              * DPP_HDR_LSI_L#_TM_POSX0~16[POSXn], #(1, 3, 5), n(0..1)
67              */
68             std::array<XT, N> posx;
69             /**
70              * DPP_HDR_LSI_L#_EOTF_POSY0~128[POSY0], #(0..5)
71              * DPP_HDR_LSI_L#_OETF_POSY0~16[POSYn] #(0..5), n(0..1)
72              * DPP_HDR_LSI_L#_TM_POSY0~32[POSY0], #(1, 3, 5)
73              */
74             std::array<YT, N> posy;
75         };
76 
77         struct EotfConfigType {
78             using XContainer = uint16_t;
79             using YContainer = uint32_t;
80             static constexpr size_t kLutLen = 129;
81 
82             TransferFunctionData<XContainer, YContainer, kLutLen> tf_data;
83         };
84 
85         struct GmConfigType {
86             using Container = uint32_t;
87             static constexpr size_t kDimensions = 3;
88 
89             MatrixData<Container, kDimensions> matrix_data;
90         };
91 
92         struct DtmConfigType {
93             using XContainer = uint16_t;
94             using YContainer = uint32_t;
95             static constexpr size_t kLutLen = 33;
96 
97             TransferFunctionData<XContainer, YContainer, kLutLen> tf_data;
98             uint16_t coeff_r;    // DPP_HDR_LSI_L#_TM_COEF[COEFR] #(1, 3, 5)
99             uint16_t coeff_g;    // DPP_HDR_LSI_L#_TM_COEF[COEFG] #(1, 3, 5)
100             uint16_t coeff_b;    // DPP_HDR_LSI_L#_TM_COEF[COEFB] #(1, 3, 5)
101             uint16_t rng_x_min;  // DPP_HDR_LSI_L#_TM_RNGX[MINX] #(1, 3, 5)
102             uint16_t rng_x_max;  // DPP_HDR_LSI_L#_TM_RNGX[MAXX] #(1, 3, 5)
103             uint16_t rng_y_min;  // DPP_HDR_LSI_L#_TM_RNGY[MINY] #(1, 3, 5)
104             uint16_t rng_y_max;  // DPP_HDR_LSI_L#_TM_RNGY[MAXY] #(1, 3, 5)
105         };
106 
107         struct OetfConfigType {
108             using XContainer = uint32_t;
109             using YContainer = uint16_t;
110             static constexpr size_t kLutLen = 33;
111 
112             TransferFunctionData<XContainer, YContainer, kLutLen> tf_data;
113         };
114 
115      public:
116         /// Register data for the EOTF LUT in DPP.
117         using EotfData = DisplayStage<EotfConfigType>;
118 
119         /// Register data for the gamut mapping (GM) matrix in DPP.
120         using GmData = DisplayStage<GmConfigType>;
121 
122         /**
123          * @brief Register data for the DTM stage in DPP.
124          *
125          * Note that this data is only applicable to DPP in layers L1/L3/L5 and
126          * G2D layers. Other DPPs do not support DTM. DTM data will be provided
127          * for any layer whose DisplayScene::LayerColorData contains HDR dynamic
128          * metadata. It is the caller's (typically HWComposer) responsibility to
129          * validate layers and HW capabilities correctly, before calling this
130          * API.
131          */
132         using DtmData = DisplayStage<DtmConfigType>;
133 
134         /// Register data for the OETF LUT in DPP.
135         using OetfData = DisplayStage<OetfConfigType>;
136 
137         /// Get data for the EOTF LUT.
138         virtual const EotfData& EotfLut() const = 0;
139 
140         /// Get data for the gamut mapping (GM) matrix.
141         virtual const GmData& Gm() const = 0;
142 
143         /**
144          * @brief Get data for the DTM LUT. Only used for HDR10+, and only
145          * applicable to DPPs that support this functionality.
146          */
147         virtual const DtmData& Dtm() const = 0;
148 
149         /// Get data for the OETF LUT.
150         virtual const OetfData& OetfLut() const = 0;
151 
~IDppIDpp152         virtual ~IDpp() {}
153     };
154 
155     /// Interface for accessing data for DQE stages.
156     struct IDqe {
157      private:
158         /// 32-bit DQE dither register, same definition as in uapi
159         struct DitherConfigType {
160             uint8_t en : 1;
161             uint8_t mode : 1;
162             uint8_t frame_con : 1;
163             uint8_t frame_offset : 2;
164             uint8_t table_sel_r : 1;
165             uint8_t table_sel_g : 1;
166             uint8_t table_sel_b : 1;
167             uint32_t reserved : 24;
168         };
169 
170         struct DqeControlConfigType {
171             /// DQE force 10bpc mode
172             bool force_10bpc = false;
173 
174             /// flag to use cgc_dither
175             bool cgc_dither_override = false;
176             /// CGC dither register value
177             union {
178                 DitherConfigType cgc_dither_reg = {};
179                 uint8_t cgc_dither; // only lowest 8 bit is used
180             };
181 
182             /// flag to use disp_dither
183             bool disp_dither_override = false;
184             /// Display dither register value
185             union {
186                 DitherConfigType disp_dither_reg = {};
187                 uint8_t disp_dither; // only lowest 8 bit is used
188             };
189         };
190 
191         struct DqeMatrixConfigType {
192             using Container = uint16_t;
193             static constexpr size_t kDimensions = 3;
194 
195             struct MatrixData<Container, kDimensions> matrix_data;
196         };
197 
198         struct DegammaConfigType {
199             using Container = uint16_t;
200             static constexpr size_t kLutLen = 65;
201 
202             std::array<Container, kLutLen> values;
203         };
204 
205         struct CgcConfigType {
206             using Container = uint32_t;
207             static constexpr size_t kChannelLutLen = 2457;
208 
209             /// DQE0_CGC_LUT_R_N{0-2456} (8 bit: 0~2047, 10 bit: 0~8191)
210             std::array<Container, kChannelLutLen> r_values{};
211             /// DQE0_CGC_LUT_G_N{0-2456} (8 bit: 0~2047, 10 bit: 0~8191)
212             std::array<Container, kChannelLutLen> g_values{};
213             /// DQE0_CGC_LUT_B_N{0-2456} (8 bit: 0~2047, 10 bit: 0~8191)
214             std::array<Container, kChannelLutLen> b_values{};
215         };
216 
217         struct RegammaConfigType {
218             using Container = uint16_t;
219             static constexpr size_t kChannelLutLen = 65;
220 
221             /// REGAMMA LUT_R_{00-64} (8 bit: 0~1024, 10 bit: 0~4096)
222             std::array<Container, kChannelLutLen> r_values{};
223             /// REGAMMA LUT_G_{00-64} (8 bit: 0~1024, 10 bit: 0~4096)
224             std::array<Container, kChannelLutLen> g_values{};
225             /// REGAMMA LUT_B_{00-64} (8 bit: 0~1024, 10 bit: 0~4096)
226             std::array<Container, kChannelLutLen> b_values{};
227         };
228 
229      public:
230         /// DQE control data
231         using DqeControlData = DisplayStage<DqeControlConfigType>;
232 
233         /// Register data for the gamma and linear matrices in DQE.
234         using DqeMatrixData = DisplayStage<DqeMatrixConfigType>;
235 
236         /// Register data for the degamma LUT in DQE.
237         using DegammaLutData = DisplayStage<DegammaConfigType>;
238 
239         /// Register data for CGC.
240         using CgcData = DisplayStage<CgcConfigType>;
241 
242         /// Register data for the regamma LUT.
243         using RegammaLutData = DisplayStage<RegammaConfigType>;
244 
245         /// Get DQE control data
246         virtual const DqeControlData& DqeControl() const = 0;
247 
248         /// Get data for the gamma-space matrix.
249         virtual const DqeMatrixData& GammaMatrix() const = 0;
250 
251         /// Get data for the 1D de-gamma LUT (EOTF).
252         virtual const DegammaLutData& DegammaLut() const = 0;
253 
254         /// Get data for the linear-space matrix.
255         virtual const DqeMatrixData& LinearMatrix() const = 0;
256 
257         /// Get data for the Color Gamut Conversion stage (3D LUT).
258         virtual const CgcData& Cgc() const = 0;
259 
260         /// Get data for the 3x1D re-gamma LUTa (OETF).
261         virtual const RegammaLutData& RegammaLut() const = 0;
262 
263         virtual ~IDqe() {}
264     };
265 
266     /// Interface for accessing particular display color data
267     struct IDisplayPipelineData {
268         /**
269          * @brief Get handles to Display Pre-Processor (DPP) data accessors.
270          *
271          * The order of the returned DPP handles match the order of the
272          * LayerColorData provided as part of struct DisplayScene and
273          * IDisplayColorGeneric::Update().
274          */
275         virtual std::vector<std::reference_wrapper<const IDpp>> Dpp() const = 0;
276 
277         /// Get a handle to Display Quality Enhancer (DQE) data accessors.
278         virtual const IDqe& Dqe() const = 0;
279 
280         /// Get a handle to panel data accessors
281         virtual const IPanel& Panel() const = 0;
282 
283         virtual ~IDisplayPipelineData() {}
284     };
285 
286     /// Get pipeline color data for specified display type
287     virtual const IDisplayPipelineData* GetPipelineData(
288         DisplayType display) const = 0;
289 
290     virtual ~IDisplayColorGS101() {}
291 };
292 
293 extern "C" {
294 
295 /// Get the GS101 instance.
296 IDisplayColorGS101* GetDisplayColorGS101(const std::vector<DisplayInfo> &display_info);
297 }
298 
299 }  // namespace displaycolor
300 
301 #endif  // DISPLAYCOLOR_GS101_H_
302