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