1 /* Copyright (c) 2015-2019, The Linux Foundataion. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above
9 *       copyright notice, this list of conditions and the following
10 *       disclaimer in the documentation and/or other materials provided
11 *       with the distribution.
12 *     * Neither the name of The Linux Foundation nor the names of its
13 *       contributors may be used to endorse or promote products derived
14 *       from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29 
30 #ifndef __COLOR_PARAMS_H__
31 #define __COLOR_PARAMS_H__
32 
33 #include <stdio.h>
34 #include <string.h>
35 #include <utils/locker.h>
36 #include <utils/constants.h>
37 #include <core/sdm_types.h>
38 #include <core/display_interface.h>
39 
40 #include <string>
41 
42 #include "hw_info_types.h"
43 
44 namespace sdm {
45 
46 // Bitmap Pending action to indicate to the caller what's pending to be taken care of.
47 enum PendingAction {
48   kInvalidating = BITMAP(0),
49   kApplySolidFill = BITMAP(1),
50   kDisableSolidFill = BITMAP(2),
51   kEnterQDCMMode = BITMAP(3),
52   kExitQDCMMode = BITMAP(4),
53   kSetPanelBrightness = BITMAP(5),
54   kEnableFrameCapture = BITMAP(6),
55   kDisableFrameCapture = BITMAP(7),
56   kConfigureDetailedEnhancer = BITMAP(8),
57   kModeSet = BITMAP(10),
58   kMultiDispProc = BITMAP(11),
59   kMultiDispGetId = BITMAP(12),
60   kSetModeFromClient = BITMAP(13),
61   kGetDetailedEnhancerData = BITMAP(21),
62   kNoAction = BITMAP(31),
63 };
64 
65 static const uint32_t kOpsEnable = BITMAP(0);
66 static const uint32_t kOpsRead = BITMAP(1);
67 static const uint32_t kOpsWrite = BITMAP(2);
68 static const uint32_t kOpsDisable = BITMAP(3);
69 
70 static const uint32_t kOpsGc8BitRoundEnable = BITMAP(4);
71 
72 static const uint32_t kPaHueEnable = BITMAP(4);
73 static const uint32_t kPaSatEnable = BITMAP(5);
74 static const uint32_t kPaValEnable = BITMAP(6);
75 static const uint32_t kPaContEnable = BITMAP(7);
76 
77 static const uint32_t kPaSixZoneEnable = BITMAP(8);
78 static const uint32_t kPaSkinEnable = BITMAP(9);
79 static const uint32_t kPaSkyEnable = BITMAP(10);
80 static const uint32_t kPaFoliageEnable = BITMAP(11);
81 
82 static const uint32_t kLeftSplitMode = BITMAP(28);   // 0x10000000
83 static const uint32_t kRightSplitMode = BITMAP(29);  // 0x20000000
84 
85 static const int32_t kInvalidModeId = -1;
86 
87 static const std::string kDynamicRangeAttribute = "DynamicRange";
88 static const std::string kColorGamutAttribute = "ColorGamut";
89 static const std::string kPictureQualityAttribute = "PictureQuality";
90 static const std::string kGammaTransferAttribute = "GammaTransfer";
91 
92 static const std::string kHdr = "hdr";
93 static const std::string kSdr = "sdr";
94 
95 static const std::string kNative = "native";
96 static const std::string kDcip3 = "dcip3";
97 static const std::string kSrgb = "srgb";
98 static const std::string kDisplayP3 = "display_p3";
99 static const std::string kBt2020 = "bt2020";
100 
101 static const std::string kHlg = "hlg";
102 static const std::string kSt2084 = "st2084";
103 static const std::string kGamma2_2 = "gamma2_2";
104 
105 static const std::string kVivid = "vivid";
106 static const std::string kSharp = "sharp";
107 static const std::string kStandard = "standard";
108 static const std::string kAmazon = "amazon";
109 static const std::string kNetflix = "netflix";
110 static const std::string kEnhanced = "enhanced";
111 
112 // Enum to identify type of dynamic range of color mode.
113 enum DynamicRangeType {
114   kSdrType,
115   kHdrType,
116 };
117 
118 // ENUM to identify different Postprocessing feature block to program.
119 // Note: For each new entry added here, also need update hw_interface::GetPPFeaturesVersion<>
120 // AND HWPrimary::SetPPFeatures<>.
121 enum PPGlobalColorFeatureID {
122   kGlobalColorFeaturePcc,
123   kGlobalColorFeatureIgc,
124   kGlobalColorFeaturePgc,
125   kMixerColorFeatureGc,
126   kGlobalColorFeaturePaV2,
127   kGlobalColorFeatureDither,
128   kGlobalColorFeatureGamut,
129   kGlobalColorFeaturePADither,
130   kMaxNumPPFeatures,
131 };
132 
133 enum PPSourceColorFeatureID {
134   kSourceColorFeatureIgc = kMaxNumPPFeatures + 1,
135   kSourceColorFeatureGc,
136   kSourceColorFeatureGamut,
137   kMaxNumSourcePPFeatures,
138 };
139 
140 struct PPPendingParams {
141   int32_t action = kNoAction;
142   void *params = NULL;
143 };
144 
145 struct PPColorInfo {
146   uint32_t r_bitdepth = 0;
147   uint32_t r = 0;
148   uint32_t g_bitdepth = 0;
149   uint32_t g = 0;
150   uint32_t b_bitdepth = 0;
151   uint32_t b = 0;
152 };
153 
154 struct PPColorFillParams {
155   uint32_t flags = 0;
156   struct {
157     uint32_t width = 0;
158     uint32_t height = 0;
159     int32_t x = 0;
160     int32_t y = 0;
161   } rect;
162 
163   PPColorInfo color;
164 };
165 
166 struct PPFeatureVersion {
167   // SDE ASIC versioning its PP block at each specific feature level.
168   static const uint32_t kSDEPpVersionInvalid = 0;
169   static const uint32_t kSDEIgcV17 = 1;
170   static const uint32_t kSDEPgcV17 = 5;
171   static const uint32_t kSDEDitherV17 = 7;
172   static const uint32_t kSDEGamutV17 = 9;
173   static const uint32_t kSDEPaV17 = 11;
174   static const uint32_t kSDEPccV17 = 13;
175   static const uint32_t kSDELegacyPP = 15;
176   static const uint32_t kSDEPADitherV17 = 16;
177   static const uint32_t kSDEIgcV30 = 17;
178   static const uint32_t kSDEGamutV4 = 18;
179   static const uint32_t kSDEPccV4 = 19;
180 
181   uint32_t version[kMaxNumPPFeatures];
PPFeatureVersionPPFeatureVersion182   PPFeatureVersion() { memset(version, 0, sizeof(version)); }
183 };
184 
185 struct PPHWAttributes : HWResourceInfo, HWPanelInfo, DisplayConfigVariableInfo {
186   char panel_name[256] = "generic_panel";
187   PPFeatureVersion version;
188   int panel_max_brightness = 0;
189 
190   void Set(const HWResourceInfo &hw_res, const HWPanelInfo &panel_info,
191            const DisplayConfigVariableInfo &attr, const PPFeatureVersion &feature_ver);
192 };
193 
194 struct PPDisplayAPIPayload {
195   bool own_payload = false;  // to indicate if *payload is owned by this or just a reference.
196   uint32_t size = 0;
197   uint8_t *payload = NULL;
198   int fd = -1;
199 
200   PPDisplayAPIPayload() = default;
PPDisplayAPIPayloadPPDisplayAPIPayload201   PPDisplayAPIPayload(uint32_t size, uint8_t *param)
202       : size(size), payload(param) {}
203 
204   template <typename T>
CreatePayloadPPDisplayAPIPayload205   DisplayError CreatePayload(T *&output) {
206     DisplayError ret = kErrorNone;
207 
208     payload = new uint8_t[sizeof(T)]();
209     if (!payload) {
210       ret = kErrorMemory;
211       output = NULL;
212     } else {
213       this->size = sizeof(T);
214       output = reinterpret_cast<T *>(payload);
215       own_payload = true;
216     }
217     return ret;
218   }
219 
CreatePayloadBytesPPDisplayAPIPayload220   DisplayError CreatePayloadBytes(uint32_t size_in_bytes, uint8_t **output) {
221     DisplayError ret = kErrorNone;
222 
223     payload = new uint8_t[size_in_bytes]();
224     if (!payload) {
225       ret = kErrorMemory;
226       *output = NULL;
227     } else {
228       this->size = size_in_bytes;
229       *output = payload;
230       own_payload = true;
231     }
232     return ret;
233   }
234 
DestroyPayloadPPDisplayAPIPayload235   inline void DestroyPayload() {
236     if (payload && own_payload) {
237       delete[] payload;
238       payload = NULL;
239       size = 0;
240     } else {
241       payload = NULL;
242       size = 0;
243     }
244   }
245 };
246 
247 struct PPRectInfo {
248   uint32_t width;
249   uint32_t height;
250   int32_t x;
251   int32_t y;
252 };
253 
254 typedef enum {
255   PP_PIXEL_FORMAT_NONE = 0,
256   PP_PIXEL_FORMAT_RGB_888,
257   PP_PIXEL_FORMAT_RGB_2101010,
258   PP_PIXEL_FORMAT_MAX,
259   PP_PIXEL_FORMAT_FORCE32BIT = 0x7FFFFFFF,
260 } PPPixelFormats;
261 
262 struct PPFrameCaptureInputParams {
263   PPRectInfo rect;
264   PPPixelFormats out_pix_format;
265   uint32_t flags;
266 };
267 
268 struct PPFrameCaptureData {
269   PPFrameCaptureInputParams input_params;
270   uint8_t *buffer;
271   uint32_t buffer_stride;
272   uint32_t buffer_size;
273 };
274 
275 static const uint32_t kDeTuningFlagSharpFactor = 0x01;
276 static const uint32_t kDeTuningFlagClip = 0x02;
277 static const uint32_t kDeTuningFlagThrQuiet = 0x04;
278 static const uint32_t kDeTuningFlagThrDieout = 0x08;
279 static const uint32_t kDeTuningFlagThrLow = 0x10;
280 static const uint32_t kDeTuningFlagThrHigh = 0x20;
281 static const uint32_t kDeTuningFlagContentQualLevel = 0x40;
282 
283 typedef enum {
284   kDeContentQualUnknown,
285   kDeContentQualLow,
286   kDeContentQualMedium,
287   kDeContentQualHigh,
288   kDeContentQualMax,
289 } PPDEContentQualLevel;
290 
291 typedef enum {
292   kDeContentTypeUnknown,
293   kDeContentTypeVideo,
294   kDeContentTypeGraphics,
295   kDeContentTypeMax,
296 } PPDEContentType;
297 
298 struct PPDETuningCfg {
299   uint32_t flags = 0;
300   int32_t sharp_factor = 0;
301   uint16_t thr_quiet = 0;
302   uint16_t thr_dieout = 0;
303   uint16_t thr_low = 0;
304   uint16_t thr_high = 0;
305   uint16_t clip = 0;
306   PPDEContentQualLevel quality = kDeContentQualUnknown;
307   PPDEContentType content_type = kDeContentTypeUnknown;
308 };
309 
310 struct PPDETuningCfgData {
311   uint32_t cfg_en = 0;
312   PPDETuningCfg params;
313   bool cfg_pending = false;
314 };
315 
316 struct SDEGamutCfg {
317   static const int kGamutTableNum = 4;
318   static const int kGamutScaleoffTableNum = 3;
319   static const int kGamutTableSize = 1229;
320   static const int kGamutTableCoarse13Size = 550;
321   static const int kGamutTableCoarseSize = 32;
322   static const int kGamutScaleoffSize = 16;
323   uint32_t mode;
324   uint32_t map_en;
325   uint32_t tbl_size[kGamutTableNum];
326   uint32_t *c0_data[kGamutTableNum];
327   uint32_t *c1_c2_data[kGamutTableNum];
328   uint32_t tbl_scale_off_sz[kGamutScaleoffTableNum];
329   uint32_t *scale_off_data[kGamutScaleoffTableNum];
330 };
331 
332 struct SDEPccCoeff {
333   uint32_t c = 0;
334   uint32_t r = 0;
335   uint32_t g = 0;
336   uint32_t b = 0;
337   uint32_t rg = 0;
338   uint32_t gb = 0;
339   uint32_t rb = 0;
340   uint32_t rgb = 0;
341 };
342 
343 struct SDEPccCfg {
344   SDEPccCoeff red;
345   SDEPccCoeff green;
346   SDEPccCoeff blue;
347 
348   static SDEPccCfg *Init(uint32_t arg __attribute__((__unused__)));
GetConfigSDEPccCfg349   SDEPccCfg *GetConfig() { return this; }
350 };
351 
352 struct SDEPccV4Coeff {
353   uint32_t c = 0;
354   uint32_t r = 0;
355   uint32_t g = 0;
356   uint32_t b = 0;
357   uint32_t rg = 0;
358   uint32_t gb = 0;
359   uint32_t rb = 0;
360   uint32_t rgb = 0;
361   uint32_t rr = 0;
362   uint32_t gg = 0;
363   uint32_t bb = 0;
364 };
365 
366 struct SDEPccV4Cfg {
367   SDEPccV4Coeff red;
368   SDEPccV4Coeff green;
369   SDEPccV4Coeff blue;
370 
371   static SDEPccV4Cfg *Init(uint32_t arg __attribute__((__unused__)));
GetConfigSDEPccV4Cfg372   SDEPccV4Cfg *GetConfig() { return this; }
373 };
374 
375 struct SDEDitherCfg {
376   uint32_t g_y_depth;
377   uint32_t r_cr_depth;
378   uint32_t b_cb_depth;
379   uint32_t length;
380   uint32_t dither_matrix[16];
381   uint32_t temporal_en;
382 
383   static SDEDitherCfg *Init(uint32_t arg __attribute__((__unused__)));
GetConfigSDEDitherCfg384   SDEDitherCfg *GetConfig() { return this; }
385 };
386 
387 struct SDEPADitherData {
388   uint64_t data_flags;
389   uint32_t matrix_size;
390   uint64_t matrix_data_addr;
391   uint32_t strength;
392   uint32_t offset_en;
393 };
394 
395 class SDEPADitherWrapper : private SDEPADitherData {
396  public:
397   static SDEPADitherWrapper *Init(uint32_t arg __attribute__((__unused__)));
~SDEPADitherWrapper()398   ~SDEPADitherWrapper() {
399     if (buffer_)
400       delete[] buffer_;
401   }
GetConfig(void)402   inline SDEPADitherData *GetConfig(void) { return this; }
403 
404  private:
SDEPADitherWrapper()405   SDEPADitherWrapper() {}
406   uint32_t *buffer_ = NULL;
407 };
408 
409 struct SDEPaMemColorData {
410   uint32_t adjust_p0 = 0;
411   uint32_t adjust_p1 = 0;
412   uint32_t adjust_p2 = 0;
413   uint32_t blend_gain = 0;
414   uint8_t sat_hold = 0;
415   uint8_t val_hold = 0;
416   uint32_t hue_region = 0;
417   uint32_t sat_region = 0;
418   uint32_t val_region = 0;
419 };
420 
421 struct SDEPaData {
422   static const int kSixZoneLUTSize = 384;
423   uint32_t mode = 0;
424   uint32_t hue_adj = 0;
425   uint32_t sat_adj = 0;
426   uint32_t val_adj = 0;
427   uint32_t cont_adj;
428   SDEPaMemColorData skin;
429   SDEPaMemColorData sky;
430   SDEPaMemColorData foliage;
431   uint32_t six_zone_thresh = 0;
432   uint32_t six_zone_adj_p0 = 0;
433   uint32_t six_zone_adj_p1 = 0;
434   uint8_t six_zone_sat_hold = 0;
435   uint8_t six_zone_val_hold = 0;
436   uint32_t six_zone_len = 0;
437   uint32_t *six_zone_curve_p0 = NULL;
438   uint32_t *six_zone_curve_p1 = NULL;
439 };
440 
441 struct SDEIgcLUTData {
442   static const int kMaxIgcLUTEntries = 256;
443   uint32_t table_fmt = 0;
444   uint32_t len = 0;
445   uint32_t *c0_c1_data = NULL;
446   uint32_t *c2_data = NULL;
447 };
448 
449 struct SDEIgcV30LUTData {
450   static const int kMaxIgcLUTEntries = 256;
451   uint32_t table_fmt = 0;
452   uint32_t len = 0;
453   uint64_t c0_c1_data = 0;
454   uint64_t c2_data = 0;
455   uint32_t strength = 0;
456 };
457 
458 struct SDEPgcLUTData {
459   static const int kPgcLUTEntries = 1024;
460   uint32_t len = 0;
461   uint32_t *c0_data = NULL;
462   uint32_t *c1_data = NULL;
463   uint32_t *c2_data = NULL;
464 };
465 
466 struct SDEDisplayMode {
467   static const int kMaxModeNameSize = 256;
468   int32_t id = -1;
469   uint32_t type = 0;
470   char name[kMaxModeNameSize] = {0};
471 };
472 
473 // Wrapper on HW block config data structure to encapsulate the details of allocating
474 // and destroying from the caller.
475 class SDEGamutCfgWrapper : private SDEGamutCfg {
476  public:
477   enum GamutMode {
478     GAMUT_FINE_MODE = 0x01,
479     GAMUT_COARSE_MODE,
480     GAMUT_COARSE_MODE_13,
481   };
482 
483   // This factory method will be used by libsdm-color.so data producer to be populated with
484   // converted config values for SDE feature blocks.
485   static SDEGamutCfgWrapper *Init(uint32_t arg);
486 
487   // Data consumer<Commit thread> will be responsible to destroy it once the feature is commited.
~SDEGamutCfgWrapper()488   ~SDEGamutCfgWrapper() {
489     if (buffer_)
490       delete[] buffer_;
491   }
492 
493   // Data consumer will use this method to retrieve contained feature configuration.
GetConfig(void)494   inline SDEGamutCfg *GetConfig(void) { return this; }
495 
496  private:
SDEGamutCfgWrapper()497   SDEGamutCfgWrapper() {}
498   uint32_t *buffer_ = NULL;
499 };
500 
501 class SDEPaCfgWrapper : private SDEPaData {
502  public:
503   static SDEPaCfgWrapper *Init(uint32_t arg = 0);
~SDEPaCfgWrapper()504   ~SDEPaCfgWrapper() {
505     if (buffer_)
506       delete[] buffer_;
507   }
GetConfig(void)508   inline SDEPaData *GetConfig(void) { return this; }
509 
510  private:
SDEPaCfgWrapper()511   SDEPaCfgWrapper() {}
512   uint32_t *buffer_ = NULL;
513 };
514 
515 class SDEIgcLUTWrapper : private SDEIgcLUTData {
516  public:
517   static SDEIgcLUTWrapper *Init(uint32_t arg __attribute__((__unused__)));
~SDEIgcLUTWrapper()518   ~SDEIgcLUTWrapper() {
519     if (buffer_)
520       delete[] buffer_;
521   }
GetConfig(void)522   inline SDEIgcLUTData *GetConfig(void) { return this; }
523 
524  private:
SDEIgcLUTWrapper()525   SDEIgcLUTWrapper() {}
526   uint32_t *buffer_ = NULL;
527 };
528 
529 class SDEIgcV30LUTWrapper : private SDEIgcV30LUTData {
530  public:
531   static SDEIgcV30LUTWrapper *Init(uint32_t arg __attribute__((__unused__)));
~SDEIgcV30LUTWrapper()532   ~SDEIgcV30LUTWrapper() {
533     if (buffer_)
534       delete[] buffer_;
535   }
GetConfig(void)536   inline SDEIgcV30LUTData *GetConfig(void) { return this; }
537 
538  private:
SDEIgcV30LUTWrapper(const SDEIgcV30LUTWrapper & src)539   SDEIgcV30LUTWrapper(const SDEIgcV30LUTWrapper& src __attribute__((__unused__))) {
540     /* do not create copies */ }
541   SDEIgcV30LUTWrapper& operator=(const SDEIgcV30LUTWrapper&) { return *this; }
SDEIgcV30LUTWrapper()542   SDEIgcV30LUTWrapper() {}
543   uint32_t *buffer_ = NULL;
544 };
545 
546 class SDEPgcLUTWrapper : private SDEPgcLUTData {
547  public:
548   static SDEPgcLUTWrapper *Init(uint32_t arg __attribute__((__unused__)));
~SDEPgcLUTWrapper()549   ~SDEPgcLUTWrapper() {
550     if (buffer_)
551       delete[] buffer_;
552   }
GetConfig(void)553   inline SDEPgcLUTData *GetConfig(void) { return this; }
554 
555  private:
SDEPgcLUTWrapper()556   SDEPgcLUTWrapper() {}
557   uint32_t *buffer_ = NULL;
558 };
559 
560 // Individual Postprocessing feature representing physical attributes and information
561 // This template class wrapping around abstract data type representing different
562 // post-processing features. It will take output from ColorManager converting from raw metadata.
563 // The configuration will directly pass into HWInterface to program the hardware accordingly.
564 template <typename T>
565 class TPPFeatureInfo : public PPFeatureInfo {
566  public:
~TPPFeatureInfo()567   virtual ~TPPFeatureInfo() {
568     if (params_)
569       delete params_;
570   }
571 
572   // API for data consumer to get underlying data configs to program into pp hardware block.
GetConfigData(void)573   virtual void *GetConfigData(void) const { return params_->GetConfig(); }
574 
575   // API for data producer to get access to underlying data configs to populate it.
GetParamsReference(void)576   T *GetParamsReference(void) { return params_; }
577 
578   // API for create this template object.
579   static TPPFeatureInfo *Init(uint32_t arg = 0) {
580     TPPFeatureInfo *info = new TPPFeatureInfo();
581     if (info) {
582       info->params_ = T::Init(arg);
583       if (!info->params_) {
584         delete info;
585         info = NULL;
586       }
587     }
588 
589     return info;
590   }
591 
592  protected:
593   TPPFeatureInfo() = default;
594 
595  private:
596   T *params_ = NULL;
597 };
598 
599 // This singleton class serves as data exchanging central between data producer
600 // <libsdm-color.so> and data consumer<SDM and HWC.>
601 // This class defines PP pending features to be programmed, which generated from
602 // ColorManager. Dirty flag indicates some features are available to be programmed.
603 // () Lock is needed since the object wil be accessed from 2 tasks.
604 // All API exposed are not threadsafe, it's caller's responsiblity to acquire the locker.
605 class PPFeaturesConfig {
606  public:
PPFeaturesConfig()607   PPFeaturesConfig() { memset(feature_, 0, sizeof(feature_)); }
~PPFeaturesConfig()608   ~PPFeaturesConfig() { Reset(); }
609 
610   // ColorManager installs one TFeatureInfo<T> to take the output configs computed
611   // from ColorManager, containing all physical features to be programmed and also compute
612   // metadata/populate into T.
AddFeature(uint32_t feature_id,PPFeatureInfo * feature)613   inline DisplayError AddFeature(uint32_t feature_id, PPFeatureInfo *feature) {
614     if (feature_id < kMaxNumPPFeatures) {
615       if (feature_[feature_id]) {
616         delete feature_[feature_id];
617         feature_[feature_id] = NULL;
618       }
619       feature_[feature_id] = feature;
620     }
621     return kErrorNone;
622   }
623 
GetFeature(uint32_t feature_id)624   inline PPFeatureInfo* GetFeature(uint32_t feature_id) {
625     PPFeatureInfo* feature = nullptr;
626     if (feature_id < kMaxNumPPFeatures) {
627       if (feature_[feature_id]) {
628         feature = feature_[feature_id];
629       }
630     }
631     return feature;
632   }
633 
GetLocker(void)634   inline Locker &GetLocker(void) { return locker_; }
GetFrameCaptureData(void)635   inline PPFrameCaptureData *GetFrameCaptureData(void) { return &frame_capture_data; }
GetDETuningCfgData(void)636   inline PPDETuningCfgData *GetDETuningCfgData(void) { return &de_tuning_data_; }
637   // Once all features are consumed, destroy/release all TFeatureInfo<T> on the list,
638   // then clear dirty_ flag and return the lock to the TFeatureInfo<T> producer.
639   void Reset();
640 
641   // Consumer to call this to retrieve all the TFeatureInfo<T> on the list to be programmed.
642   DisplayError RetrieveNextFeature(PPFeatureInfo **feature);
643 
IsDirty()644   inline bool IsDirty() { return dirty_; }
MarkAsDirty()645   inline void MarkAsDirty() { dirty_ = true; }
646 
647  private:
648   bool dirty_ = 0;
649   Locker locker_;
650   PPFeatureInfo *feature_[kMaxNumPPFeatures];  // reference to TFeatureInfo<T>.
651   uint32_t next_idx_ = 0;
652   PPFrameCaptureData frame_capture_data;
653   PPDETuningCfgData de_tuning_data_;
654 };
655 
656 }  // namespace sdm
657 
658 #endif  // __COLOR_PARAMS_H__
659