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 #include <dlfcn.h>
31 #include <private/color_interface.h>
32 #include <utils/constants.h>
33 #include <utils/debug.h>
34 #include <algorithm>
35 #include <vector>
36 #include <string>
37 
38 #include "color_manager.h"
39 
40 #define __CLASS__ "ColorManager"
41 
42 namespace sdm {
43 
44 DynLib ColorManagerProxy::color_lib_;
45 CreateColorInterface ColorManagerProxy::create_intf_ = NULL;
46 DestroyColorInterface ColorManagerProxy::destroy_intf_ = NULL;
47 HWResourceInfo ColorManagerProxy::hw_res_info_;
48 
NeedsToneMap(const std::vector<Layer> & layers)49 bool NeedsToneMap(const std::vector<Layer> &layers) {
50   for (auto &layer : layers) {
51     if (layer.request.flags.dest_tone_map) {
52       return true;
53     }
54   }
55   return false;
56 }
57 
58 // Below two functions are part of concrete implementation for SDM core private
59 // color_params.h
Reset()60 void PPFeaturesConfig::Reset() {
61   for (int i = 0; i < kMaxNumPPFeatures; i++) {
62     if (feature_[i]) {
63       delete feature_[i];
64       feature_[i] = NULL;
65     }
66   }
67   dirty_ = false;
68   next_idx_ = 0;
69 }
70 
RetrieveNextFeature(PPFeatureInfo ** feature)71 DisplayError PPFeaturesConfig::RetrieveNextFeature(PPFeatureInfo **feature) {
72   DisplayError ret = kErrorNone;
73   uint32_t i(0);
74 
75   for (i = next_idx_; i < kMaxNumPPFeatures; i++) {
76     if (feature_[i]) {
77       *feature = feature_[i];
78       next_idx_ = i + 1;
79       break;
80     }
81   }
82 
83   if (i == kMaxNumPPFeatures) {
84     ret = kErrorParameters;
85     next_idx_ = 0;
86   }
87 
88   return ret;
89 }
90 
GetPostedStartFeatureCheckIntf(HWInterface * intf,PPFeaturesConfig * config)91 FeatureInterface* GetPostedStartFeatureCheckIntf(HWInterface *intf, PPFeaturesConfig *config) {
92   return new ColorFeatureCheckingImpl(intf, config);
93 }
94 
Init(const std::string & panel_name)95 DisplayError STCIntfClient::Init(const std::string &panel_name) {
96   lock_guard<mutex> obj(lock_);
97   if (stc_intf_) {
98     DLOGI("stc interface is already instantiated");
99     return kErrorNone;
100   }
101 
102   if (!stc_intf_lib_.Open(kStcIntfLib_)) {
103     DLOGW("STC library is not present");
104     return kErrorNotSupported;
105   }
106 
107   if (!stc_intf_lib_.Sym("GetScPostBlendInterface",
108                     reinterpret_cast<void **>(&GetScPostBlendInterface))) {
109     DLOGE("GetHdrInterface symbol not found!, error = %s", dlerror());
110     stc_intf_lib_.~DynLib();
111     return kErrorNotSupported;
112   }
113 
114   uint32_t major_version = 1;
115   uint32_t minor_version = 0;
116 
117   stc_intf_ = GetScPostBlendInterface(major_version, minor_version);
118   if (!stc_intf_) {
119     DLOGE("Failed to get STC Interface!");
120     stc_intf_lib_.~DynLib();
121     return kErrorNotSupported;
122   }
123 
124   int ret = stc_intf_->Init(panel_name);
125   if (ret) {
126     DLOGE("STC Interface init failed!, error = %d", ret);
127     stc_intf_lib_.~DynLib();
128     return kErrorNotSupported;
129   }
130 
131   return kErrorNone;;
132 }
133 
DeInit()134 DisplayError STCIntfClient::DeInit() {
135   lock_guard<mutex> obj(lock_);
136   if (stc_intf_) {
137     stc_intf_->DeInit();
138   }
139   stc_intf_lib_.~DynLib();
140   return kErrorNone;
141 }
142 
SetProperty(const ScPayload & payload)143 DisplayError STCIntfClient::SetProperty(const ScPayload &payload) {
144   lock_guard<mutex> obj(lock_);
145   int ret;
146 
147   if (!stc_intf_) {
148     return kErrorNotSupported;
149   }
150   ret = stc_intf_->SetProperty(payload);
151   if (ret) {
152     DLOGE("Failed to SetProperty: %d, length = %d, ret = %d", payload.prop, payload.len, ret);
153     return kErrorNotSupported;
154   }
155 
156   return kErrorNone;
157 }
158 
GetProperty(ScPayload * payload)159 DisplayError STCIntfClient::GetProperty(ScPayload *payload) {
160   lock_guard<mutex> obj(lock_);
161   int ret = 0;
162 
163   if (!stc_intf_) {
164     return kErrorNotSupported;
165   }
166   if (!payload) {
167     DLOGE("Invalid parameters");
168     return kErrorParameters;
169   }
170 
171   ret = stc_intf_->GetProperty(payload);
172   if (ret) {
173     DLOGE("Failed to GetProperty: %d, length = %d, ret = %d", payload->prop, payload->len, ret);
174     return kErrorNotSupported;
175   }
176 
177   return kErrorNone;
178 }
179 
ProcessOps(const ScOps op,const ScPayload & input,ScPayload * output)180 DisplayError STCIntfClient::ProcessOps(const ScOps op, const ScPayload &input, ScPayload *output) {
181   lock_guard<mutex> obj(lock_);
182   int ret;
183 
184   if (!stc_intf_) {
185     return kErrorNotSupported;
186   }
187   if (!output) {
188     DLOGE("Invalid parameters");
189     return kErrorParameters;
190   }
191 
192   DisplayError error = kErrorNone;
193   ret = stc_intf_->ProcessOps(op, input, output);
194   if (ret) {
195     DLOGE("Failed to ProcessOps: %d, ret = %d", op, ret);
196     return kErrorNotSupported;
197   }
198 
199   return error;
200 }
201 
Init(const HWResourceInfo & hw_res_info)202 DisplayError ColorManagerProxy::Init(const HWResourceInfo &hw_res_info) {
203   DisplayError error = kErrorNone;
204 
205   // Load color service library and retrieve its entry points.
206   if (color_lib_.Open(COLORMGR_LIBRARY_NAME)) {
207     if (!color_lib_.Sym(CREATE_COLOR_INTERFACE_NAME, reinterpret_cast<void **>(&create_intf_)) ||
208         !color_lib_.Sym(DESTROY_COLOR_INTERFACE_NAME, reinterpret_cast<void **>(&destroy_intf_))) {
209       DLOGW("Fail to retrieve = %s from %s", CREATE_COLOR_INTERFACE_NAME, COLORMGR_LIBRARY_NAME);
210       error = kErrorResources;
211     }
212   } else {
213     DLOGW("Fail to load = %s", COLORMGR_LIBRARY_NAME);
214     error = kErrorResources;
215   }
216 
217   hw_res_info_ = hw_res_info;
218 
219   return error;
220 }
221 
Deinit()222 void ColorManagerProxy::Deinit() {
223   color_lib_.~DynLib();
224 }
225 
ColorManagerProxy(int32_t id,DisplayType type,HWInterface * intf,const HWDisplayAttributes & attr,const HWPanelInfo & info)226 ColorManagerProxy::ColorManagerProxy(int32_t id, DisplayType type, HWInterface *intf,
227                                      const HWDisplayAttributes &attr,
228                                      const HWPanelInfo &info)
229     : display_id_(id), device_type_(type), pp_hw_attributes_(), hw_intf_(intf),
230       color_intf_(NULL), pp_features_(), feature_intf_(NULL) {
231   int32_t enable_posted_start_dyn = 0;
232   Debug::Get()->GetProperty(ENABLE_POSTED_START_DYN_PROP, &enable_posted_start_dyn);
233   if (enable_posted_start_dyn && info.mode == kModeCommand) {
234     feature_intf_ = GetPostedStartFeatureCheckIntf(intf, &pp_features_);
235     if (!feature_intf_) {
236       DLOGI("Failed to create feature interface");
237     } else {
238       DisplayError err = feature_intf_->Init();
239       if (err) {
240         DLOGE("Failed to init feature interface");
241         delete feature_intf_;
242         feature_intf_ = NULL;
243       }
244     }
245   }
246 
247   convert_[kPbGamut] = &ColorManagerProxy::ConvertToGamut;
248   convert_[kPbIgc] = &ColorManagerProxy::ConvertToIgc;
249   convert_[kPbGC] = &ColorManagerProxy::ConvertToGc;
250 }
251 
CreateColorManagerProxy(DisplayType type,HWInterface * hw_intf,const HWDisplayAttributes & attribute,const HWPanelInfo & panel_info,DppsControlInterface * dpps_intf)252 ColorManagerProxy *ColorManagerProxy::CreateColorManagerProxy(DisplayType type,
253                                                               HWInterface *hw_intf,
254                                                               const HWDisplayAttributes &attribute,
255                                                               const HWPanelInfo &panel_info,
256                                                               DppsControlInterface *dpps_intf) {
257   DisplayError error = kErrorNone;
258   PPFeatureVersion versions;
259   int32_t display_id = -1;
260   ColorManagerProxy *color_manager_proxy = NULL;
261 
262   // check if all resources are available before invoking factory method from libsdm-color.so.
263   if (!color_lib_ || !create_intf_ || !destroy_intf_) {
264     DLOGW("Information for %s isn't available!", COLORMGR_LIBRARY_NAME);
265     return NULL;
266   }
267 
268   hw_intf->GetDisplayId(&display_id);
269   color_manager_proxy = new ColorManagerProxy(display_id, type, hw_intf, attribute, panel_info);
270 
271   if (color_manager_proxy) {
272     // 1. need query post-processing feature version from HWInterface.
273     error = color_manager_proxy->hw_intf_->GetPPFeaturesVersion(&versions);
274     PPHWAttributes &hw_attr = color_manager_proxy->pp_hw_attributes_;
275     if (error != kErrorNone) {
276       DLOGW("Fail to get DSPP feature versions");
277     } else {
278       hw_attr.Set(hw_res_info_, panel_info, attribute, versions, dpps_intf);
279       DLOGI("PAV2 version is versions = %d, version = %d ",
280             hw_attr.version.version[kGlobalColorFeaturePaV2],
281             versions.version[kGlobalColorFeaturePaV2]);
282     }
283 
284     // 2. instantiate concrete ColorInterface from libsdm-color.so, pass all hardware info in.
285     error = create_intf_(COLOR_VERSION_TAG, color_manager_proxy->display_id_,
286                          color_manager_proxy->device_type_, hw_attr,
287                          &color_manager_proxy->color_intf_);
288     if (error != kErrorNone) {
289       DLOGW("Unable to instantiate concrete ColorInterface from %s", COLORMGR_LIBRARY_NAME);
290       delete color_manager_proxy;
291       color_manager_proxy = NULL;
292       return color_manager_proxy;
293     }
294 
295     color_manager_proxy->stc_intf_client_ = new STCIntfClient();
296     if (!color_manager_proxy->stc_intf_client_) {
297       DLOGW("Unable to instantiate concrete StcInterface");
298       return color_manager_proxy;
299     }
300 
301     error = color_manager_proxy->stc_intf_client_->Init(hw_attr.panel_name);
302     if (error != kErrorNone) {
303       DLOGW("Failed to init StcInterface");
304       delete color_manager_proxy->stc_intf_client_;
305       color_manager_proxy->stc_intf_client_ = NULL;
306       return color_manager_proxy;
307     }
308     color_manager_proxy->support_stc_tonemap_ = color_manager_proxy->GetSupportStcTonemap();
309   }
310 
311   return color_manager_proxy;
312 }
313 
~ColorManagerProxy()314 ColorManagerProxy::~ColorManagerProxy() {
315   if (destroy_intf_)
316     destroy_intf_(display_id_);
317   color_intf_ = NULL;
318   if (feature_intf_) {
319     feature_intf_->Deinit();
320     delete feature_intf_;
321     feature_intf_ = NULL;
322   }
323   if (stc_intf_client_) {
324     stc_intf_client_->DeInit();
325   }
326 }
327 
ColorSVCRequestRoute(const PPDisplayAPIPayload & in_payload,PPDisplayAPIPayload * out_payload,PPPendingParams * pending_action)328 DisplayError ColorManagerProxy::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
329                                                      PPDisplayAPIPayload *out_payload,
330                                                      PPPendingParams *pending_action) {
331   DisplayError ret = kErrorNone;
332 
333   // On completion, dspp_features_ will be populated and mark dirty with all resolved dspp
334   // feature list with paramaters being transformed into target requirement.
335   ret = color_intf_->ColorSVCRequestRoute(in_payload, out_payload, &pp_features_, pending_action);
336 
337   return ret;
338 }
339 
ApplyDefaultDisplayMode(void)340 DisplayError ColorManagerProxy::ApplyDefaultDisplayMode(void) {
341   DisplayError ret = kErrorNone;
342 
343   // On POR, will be invoked from prepare<> request once bootanimation is done.
344   ret = color_intf_->ApplyDefaultDisplayMode(&pp_features_);
345 
346   return ret;
347 }
348 
NeedsPartialUpdateDisable()349 bool ColorManagerProxy::NeedsPartialUpdateDisable() {
350   Locker &locker(pp_features_.GetLocker());
351   SCOPE_LOCK(locker);
352 
353   return pp_features_.IsDirty();
354 }
355 
Commit()356 DisplayError ColorManagerProxy::Commit() {
357   Locker &locker(pp_features_.GetLocker());
358   SCOPE_LOCK(locker);
359 
360   DisplayError ret = kErrorNone;
361   bool is_dirty = pp_features_.IsDirty();
362   if (feature_intf_) {
363     feature_intf_->SetParams(kFeatureSwitchMode, &is_dirty);
364   }
365   if (is_dirty) {
366     ret = hw_intf_->SetPPFeatures(&pp_features_);
367   }
368 
369   return ret;
370 }
371 
Set(const HWResourceInfo & hw_res,const HWPanelInfo & panel_info,const DisplayConfigVariableInfo & attr,const PPFeatureVersion & feature_ver,DppsControlInterface * intf)372 void PPHWAttributes::Set(const HWResourceInfo &hw_res,
373                          const HWPanelInfo &panel_info,
374                          const DisplayConfigVariableInfo &attr,
375                          const PPFeatureVersion &feature_ver,
376                          DppsControlInterface *intf) {
377   HWResourceInfo &res = *this;
378   res = hw_res;
379   HWPanelInfo &panel = *this;
380   panel = panel_info;
381   DisplayConfigVariableInfo &attributes = *this;
382   attributes = attr;
383   version = feature_ver;
384   dpps_intf = intf;
385 
386   if (strlen(panel_info.panel_name)) {
387     snprintf(&panel_name[0], sizeof(panel_name), "%s", &panel_info.panel_name[0]);
388     char *tmp = panel_name;
389     while ((tmp = strstr(tmp, " ")) != NULL)
390       *tmp = '_';
391     if ((tmp = strstr(panel_name, "\n")) != NULL)
392       *tmp = '\0';
393   }
394 }
395 
ColorMgrGetNumOfModes(uint32_t * mode_cnt)396 DisplayError ColorManagerProxy::ColorMgrGetNumOfModes(uint32_t *mode_cnt) {
397   return color_intf_->ColorIntfGetNumDisplayModes(&pp_features_, 0, mode_cnt);
398 }
399 
ColorMgrGetModes(uint32_t * mode_cnt,SDEDisplayMode * modes)400 DisplayError ColorManagerProxy::ColorMgrGetModes(uint32_t *mode_cnt,
401                                                  SDEDisplayMode *modes) {
402   return color_intf_->ColorIntfEnumerateDisplayModes(&pp_features_, 0, modes, mode_cnt);
403 }
404 
ColorMgrSetMode(int32_t color_mode_id)405 DisplayError ColorManagerProxy::ColorMgrSetMode(int32_t color_mode_id) {
406   return color_intf_->ColorIntfSetDisplayMode(&pp_features_, 0, color_mode_id);
407 }
408 
ColorMgrGetModeInfo(int32_t mode_id,AttrVal * query)409 DisplayError ColorManagerProxy::ColorMgrGetModeInfo(int32_t mode_id, AttrVal *query) {
410   return color_intf_->ColorIntfGetModeInfo(&pp_features_, 0, mode_id, query);
411 }
412 
ColorMgrSetColorTransform(uint32_t length,const double * trans_data)413 DisplayError ColorManagerProxy::ColorMgrSetColorTransform(uint32_t length,
414                                                           const double *trans_data) {
415   return color_intf_->ColorIntfSetColorTransform(&pp_features_, 0, length, trans_data);
416 }
417 
ColorMgrGetDefaultModeID(int32_t * mode_id)418 DisplayError ColorManagerProxy::ColorMgrGetDefaultModeID(int32_t *mode_id) {
419   return color_intf_->ColorIntfGetDefaultModeID(&pp_features_, 0, mode_id);
420 }
421 
ColorMgrCombineColorModes()422 DisplayError ColorManagerProxy::ColorMgrCombineColorModes() {
423   return color_intf_->ColorIntfCombineColorModes();
424 }
425 
ColorMgrSetModeWithRenderIntent(int32_t color_mode_id,const PrimariesTransfer & blend_space,uint32_t intent)426 DisplayError ColorManagerProxy::ColorMgrSetModeWithRenderIntent(int32_t color_mode_id,
427                                          const PrimariesTransfer &blend_space, uint32_t intent) {
428   cur_blend_space_ = blend_space;
429   cur_intent_ = intent;
430   cur_mode_id_ = color_mode_id;
431   apply_mode_ = true;
432   return kErrorNone;
433 }
434 
Validate(HWLayers * hw_layers)435 DisplayError ColorManagerProxy::Validate(HWLayers *hw_layers) {
436   DisplayError ret = kErrorNone;
437   if (!hw_layers) {
438     return ret;
439   }
440 
441   bool updates = NeedHwassetsUpdate();
442   bool valid_meta_data = false;
443   bool update_meta_data = false, update_mode_Hwassets = false;
444   Layer hdr_layer = {};
445   bool hdr_present = false, hdr_plus_present = false;
446 
447   valid_meta_data = NeedsToneMap(hw_layers->info.hw_layers);
448   if (valid_meta_data) {
449     if (hw_layers->info.hdr_layer_info.in_hdr_mode &&
450           hw_layers->info.hdr_layer_info.operation == HWHDRLayerInfo::kSet) {
451       hdr_layer = *(hw_layers->info.stack->layers.at(
452                                  UINT32(hw_layers->info.hdr_layer_info.layer_index)));
453       hdr_present = true;
454     }
455 
456     if (hdr_present) {
457       if (hdr_layer.input_buffer.color_metadata.dynamicMetaDataValid &&
458           hdr_layer.input_buffer.color_metadata.dynamicMetaDataLen) {
459         hdr_plus_present = true;
460       }
461     }
462   }
463 
464   if (apply_mode_) {
465     update_mode_Hwassets = true;
466     apply_mode_ = false;
467   }
468 
469   if (updates) {
470     update_mode_Hwassets = true;
471   }
472 
473   if (hdr_present || hdr_plus_present) {
474     update_meta_data = true;
475     meta_data_ = hdr_layer.input_buffer.color_metadata;
476     update_mode_Hwassets = true;
477   }
478 
479   if (update_mode_Hwassets) {
480     snapdragoncolor::ColorMode color_mode;
481     color_mode = GetColorPrimaries(cur_blend_space_, cur_intent_);
482     UpdateModeHwassets(cur_mode_id_, color_mode, update_meta_data, meta_data_);
483     DumpColorMetaData(meta_data_);
484   }
485 
486   return kErrorNone;
487 }
488 
IsSupportStcTonemap()489 bool ColorManagerProxy::IsSupportStcTonemap() {
490   return support_stc_tonemap_;
491 }
492 
GameEnhanceSupported()493 bool ColorManagerProxy::GameEnhanceSupported() {
494   bool supported = false;
495 
496   if (color_intf_) {
497     color_intf_->ColorIntfGameEnhancementSupported(&supported);
498   }
499 
500   return supported;
501 }
502 
ConvertToPPFeatures(HwConfigOutputParams * params,PPFeaturesConfig * out_data)503 DisplayError ColorManagerProxy::ConvertToPPFeatures(HwConfigOutputParams *params,
504                                                     PPFeaturesConfig *out_data) {
505   if (!params || !out_data) {
506     DLOGE("Invalid input parameters");
507     return kErrorParameters;
508   }
509 
510   if (params->payload.empty()) {
511     return kErrorNone;
512   }
513 
514   DisplayError error = kErrorNone;
515   for (auto it = params->payload.begin(); it != params->payload.end(); it++) {
516     ConvertTable::const_iterator found = convert_.find(it->hw_asset);
517     if (found == convert_.end()) {
518       DLOGE("%s is not supported", it->hw_asset.c_str());
519       return kErrorNotSupported;
520     }
521 
522     ConvertProc func = found->second;
523     error = (this->*func)(*it, out_data);
524     if (error != kErrorNone) {
525       DLOGE("Failer to convert %s, error = %d", it->hw_asset.c_str(), error);
526       return error;
527     }
528   }
529 
530   return error;
531 }
532 
ConvertToIgc(const HwConfigPayload & in_data,PPFeaturesConfig * out_data)533 DisplayError ColorManagerProxy::ConvertToIgc(const HwConfigPayload &in_data,
534                                                    PPFeaturesConfig *out_data) {
535   if (in_data.hw_payload_len != sizeof(GammaPostBlendConfig)) {
536     DLOGE("Invalid parameters size = %d", in_data.hw_payload_len);
537     return kErrorParameters;
538   }
539   DisplayError ret = kErrorNone;
540   GammaPostBlendConfig *ptr = reinterpret_cast<GammaPostBlendConfig*>(in_data.hw_payload.get());
541   if (!ptr) {
542     DLOGE("Invalid parameters");
543     return kErrorUndefined;
544   }
545   ret = color_intf_->ColorIntfConvertToPPFeature(out_data, UINT32(display_id_), ptr->enabled,
546                            kPbIgc, reinterpret_cast<void *>(ptr));
547   if (ret != kErrorNone) {
548     DLOGE("Failed to convert Igc config date to PPFeture info: ret = %d", ret);
549     return ret;
550   }
551   return ret;
552 }
553 
ConvertToGc(const HwConfigPayload & in_data,PPFeaturesConfig * out_data)554 DisplayError ColorManagerProxy::ConvertToGc(const HwConfigPayload &in_data,
555                                                   PPFeaturesConfig *out_data) {
556   if (in_data.hw_payload_len != sizeof(GammaPostBlendConfig)) {
557     DLOGE("Invalid parameters size = %d", in_data.hw_payload_len);
558     return kErrorParameters;
559   }
560   DisplayError ret = kErrorNone;
561   GammaPostBlendConfig *ptr = reinterpret_cast<GammaPostBlendConfig*>(in_data.hw_payload.get());
562   ret = color_intf_->ColorIntfConvertToPPFeature(out_data, UINT32(display_id_), ptr->enabled,
563                            kPbGC, reinterpret_cast<void *>(ptr));
564   if (ret != kErrorNone) {
565     DLOGE("Failed to convert Gc config date to PPFeture info: ret = %d", ret);
566     ret = kErrorUndefined;
567     return ret;
568   }
569   return ret;
570 }
571 
ConvertToGamut(const HwConfigPayload & in_data,PPFeaturesConfig * out_data)572 DisplayError ColorManagerProxy::ConvertToGamut(const HwConfigPayload &in_data,
573                                                      PPFeaturesConfig *out_data) {
574   if (in_data.hw_payload_len != sizeof(GamutConfig)) {
575     DLOGE("Invalid parameters size = %d", in_data.hw_payload_len);
576     return kErrorParameters;
577   }
578 
579   DisplayError ret = kErrorNone;
580   GamutConfig *ptr = reinterpret_cast<GamutConfig*>(in_data.hw_payload.get());
581   ret = color_intf_->ColorIntfConvertToPPFeature(out_data, UINT32(display_id_), ptr->enabled,
582                            kPbGamut, reinterpret_cast<void *>(&ptr->gamut_info));
583   if (ret != kErrorNone) {
584     DLOGE("Failed to convert Gamut config date to PPFeture info: ret = %d", ret);
585     ret = kErrorUndefined;
586     return ret;
587   }
588   return ret;
589 }
590 
NeedHwassetsUpdate()591 bool ColorManagerProxy::NeedHwassetsUpdate() {
592   bool need_update = false;
593   if (!stc_intf_client_) {
594     return need_update;
595   }
596   ScPayload payload;
597 
598   payload.len = sizeof(need_update);
599   payload.prop = kNeedsUpdate;
600   payload.payload = reinterpret_cast<uint64_t>(&need_update);
601   stc_intf_client_->GetProperty(&payload);
602   return need_update;
603 }
604 
UpdateModeHwassets(int32_t mode_id,snapdragoncolor::ColorMode color_mode,bool valid_meta_data,const ColorMetaData & meta_data)605 DisplayError ColorManagerProxy::UpdateModeHwassets(int32_t mode_id,
606                                   snapdragoncolor::ColorMode color_mode, bool valid_meta_data,
607                                   const ColorMetaData &meta_data) {
608   if (!stc_intf_client_) {
609     return kErrorUndefined;
610   }
611 
612   DisplayError error = kErrorNone;
613   struct snapdragoncolor::ModeRenderInputParams mode_params = {};
614   struct snapdragoncolor::HwConfigOutputParams hw_params = {};
615   mode_params.valid_meta_data = valid_meta_data;
616   mode_params.meta_data = meta_data;
617   mode_params.color_mode = color_mode;
618   mode_params.mode_id = mode_id;
619 
620   struct snapdragoncolor::HwConfigPayload payload = {};
621   payload.hw_asset = kPbGamut;
622   payload.hw_payload_len = sizeof(GamutConfig);
623   payload.hw_payload = std::make_shared<GamutConfig>();
624   hw_params.payload.push_back(payload);
625 
626   payload.hw_asset = kPbIgc;
627   payload.hw_payload = std::make_shared<GammaPostBlendConfig>(LUT1D_ENTRIES_SIZE);
628   payload.hw_payload_len = sizeof(GammaPostBlendConfig);
629   hw_params.payload.push_back(payload);
630 
631   payload.hw_asset = kPbGC;
632   payload.hw_payload_len = sizeof(GammaPostBlendConfig);
633   payload.hw_payload = std::make_shared<GammaPostBlendConfig>(LUT3D_GC_ENTRIES_SIZE);
634   hw_params.payload.push_back(payload);
635 
636   ScPayload in_data = {};
637   ScPayload out_data = {};
638   in_data.prop = kModeRenderInputParams;
639   in_data.len = sizeof(mode_params);
640   in_data.payload = reinterpret_cast<uint64_t>(&mode_params);
641 
642   out_data.prop = kHwConfigPayloadParam;
643   out_data.len = sizeof(hw_params);
644   out_data.payload = reinterpret_cast<uint64_t>(&hw_params);
645   error = stc_intf_client_->ProcessOps(kScModeRenderIntent, in_data, &out_data);
646   if (error != kErrorNone) {
647     DLOGE("Failed to call ProcessOps, error = %d", error);
648     return error;
649   }
650 
651   error = ConvertToPPFeatures(&hw_params, &pp_features_);
652   if (error != kErrorNone) {
653     DLOGE("Failed to convert hw assets to PP features, error = %d", error);
654     return kErrorUndefined;
655   }
656   pp_features_.MarkAsDirty();
657   return error;
658 }
659 
GetSupportStcTonemap()660 bool ColorManagerProxy::GetSupportStcTonemap() {
661   bool support_tonemap = false;
662   if (!stc_intf_client_) {
663     return support_tonemap;
664   }
665   ScPayload payload;
666 
667   payload.len = sizeof(support_tonemap);
668   payload.prop = kSupportToneMap;
669   payload.payload = reinterpret_cast<uint64_t>(&support_tonemap);
670   stc_intf_client_->GetProperty(&payload);
671   return support_tonemap;
672 }
673 
DumpColorMetaData(const ColorMetaData & color_metadata)674 void ColorManagerProxy::DumpColorMetaData(const ColorMetaData &color_metadata) {
675   DLOGI_IF(kTagResources, "Primaries = %d, Range = %d, Transfer = %d, Matrix Coeffs = %d",
676            color_metadata.colorPrimaries, color_metadata.range, color_metadata.transfer,
677            color_metadata.matrixCoefficients);
678 
679   for (uint32_t i = 0; i < 3; i++) {
680     for (uint32_t j = 0; j < 2; j++) {
681       DLOGV_IF(kTagResources, "RGB Primaries[%d][%d] = %d", i, j,
682                color_metadata.masteringDisplayInfo.primaries.rgbPrimaries[i][j]);
683     }
684   }
685   DLOGV_IF(kTagResources, "White Point[0] = %d White Point[1] = %d",
686            color_metadata.masteringDisplayInfo.primaries.whitePoint[0],
687            color_metadata.masteringDisplayInfo.primaries.whitePoint[1]);
688   DLOGV_IF(kTagResources, "Max Disp Luminance = %d Min Disp Luminance= %d",
689            color_metadata.masteringDisplayInfo.maxDisplayLuminance,
690            color_metadata.masteringDisplayInfo.minDisplayLuminance);
691   DLOGV_IF(kTagResources, "Max ContentLightLevel = %d Max AvgLightLevel = %d",
692            color_metadata.contentLightLevel.maxContentLightLevel,
693            color_metadata.contentLightLevel.minPicAverageLightLevel);
694   DLOGV_IF(kTagResources, "DynamicMetaDataValid = %d DynamicMetaDataLen = %d",
695            color_metadata.dynamicMetaDataValid,
696            color_metadata.dynamicMetaDataLen);
697 }
698 
GetColorPrimaries(const PrimariesTransfer & blend_space,uint32_t intent)699 snapdragoncolor::ColorMode ColorManagerProxy::GetColorPrimaries(
700                         const PrimariesTransfer &blend_space, uint32_t intent) {
701   snapdragoncolor::ColorMode mode = {};
702 
703   mode.intent = static_cast<snapdragoncolor::RenderIntent>(intent + 1);
704 
705   mode.gamut = blend_space.primaries;
706   mode.gamma = blend_space.transfer;
707 
708   return mode;
709 }
710 
ColorFeatureCheckingImpl(HWInterface * hw_intf,PPFeaturesConfig * pp_features)711 ColorFeatureCheckingImpl::ColorFeatureCheckingImpl(HWInterface *hw_intf,
712                                                    PPFeaturesConfig *pp_features)
713   : hw_intf_(hw_intf), pp_features_(pp_features) {}
714 
Init()715 DisplayError ColorFeatureCheckingImpl::Init() {
716   states_.at(kFrameTriggerDefault) = new FeatureStateDefaultTrigger(this);
717   states_.at(kFrameTriggerSerialize) = new FeatureStateSerializedTrigger(this);
718   states_.at(kFrameTriggerPostedStart) = new FeatureStatePostedStart(this);
719 
720   if (std::any_of(states_.begin(), states_.end(),
721       [](const FeatureInterface *p) {
722       if (!p) {
723         return true;
724       } else {
725         return false;
726       }})) {
727     (void)std::all_of(states_.begin(), states_.end(),
728       [](const FeatureInterface *p) {
729       if (p) {delete p;} return true;});
730     states_.fill(NULL);
731     curr_state_ = NULL;
732   } else {
733     curr_state_ = states_.at(kFrameTriggerDefault);
734   }
735 
736   if (curr_state_) {
737     single_buffer_feature_.clear();
738     single_buffer_feature_.push_back(kGlobalColorFeatureIgc);
739     single_buffer_feature_.push_back(kGlobalColorFeatureGamut);
740   } else {
741     DLOGE("Failed to create curr_state_");
742     return kErrorMemory;
743   }
744   return kErrorNone;
745 }
746 
Deinit()747 DisplayError ColorFeatureCheckingImpl::Deinit() {
748   (void)std::all_of(states_.begin(), states_.end(),
749     [](const FeatureInterface *p)
750     {if (p) {delete p;} return true;});
751   states_.fill(NULL);
752   curr_state_ = NULL;
753   single_buffer_feature_.clear();
754   return kErrorNone;
755 }
756 
SetParams(FeatureOps param_type,void * payload)757 DisplayError ColorFeatureCheckingImpl::SetParams(FeatureOps param_type,
758                                                  void *payload) {
759   DisplayError error = kErrorNone;
760   FrameTriggerMode mode = kFrameTriggerDefault;
761 
762   if (!payload) {
763     DLOGE("Invalid input payload");
764     return kErrorParameters;
765   }
766 
767   if (!curr_state_) {
768     DLOGE("Invalid curr state");
769     return kErrorParameters;
770   }
771 
772   bool is_dirty = *reinterpret_cast<bool *>(payload);
773   switch (param_type) {
774   case kFeatureSwitchMode:
775     if (is_dirty) {
776       CheckColorFeature(&mode);
777     } else {
778       mode = kFrameTriggerPostedStart;
779     }
780     DLOGV_IF(kTagQDCM, "Set frame trigger mode %d", mode);
781     error = curr_state_->SetParams(param_type, &mode);
782     if (error) {
783       DLOGE_IF(kTagQDCM, "Failed to set params to state, error %d", error);
784     }
785     break;
786   default:
787     DLOGW("unhandled param_type %d", param_type);
788     error = kErrorNotSupported;
789     break;
790   }
791   return error;
792 }
793 
GetParams(FeatureOps param_type,void * payload)794 DisplayError ColorFeatureCheckingImpl::GetParams(FeatureOps param_type,
795                                                  void *payload) {
796   DisplayError error = kErrorNone;
797 
798   if (!payload) {
799     DLOGE("Invalid input payload");
800     return kErrorParameters;
801   }
802 
803   if (!curr_state_) {
804     DLOGE("Invalid curr state");
805     return kErrorParameters;
806   }
807 
808   switch (param_type) {
809   case kFeatureSwitchMode:
810     if (curr_state_) {
811       curr_state_->GetParams(param_type, payload);
812     } else {
813       DLOGE_IF(kTagQDCM, "curr_state_ NULL");
814       error = kErrorUndefined;
815     }
816     break;
817   default:
818     DLOGW("unhandled param_type %d", param_type);
819     error = kErrorNotSupported;
820     break;
821   }
822   return error;
823 }
824 
825 // This function checks through the feature list for the single buffer features.
826 // If there is single buffer feature existed in the feature list, the posted start
827 // should be disabled.
CheckColorFeature(FrameTriggerMode * mode)828 void ColorFeatureCheckingImpl::CheckColorFeature(FrameTriggerMode *mode) {
829   PPFeatureInfo *feature = NULL;
830   PPGlobalColorFeatureID id = kMaxNumPPFeatures;
831 
832   if (!pp_features_) {
833     DLOGW("Invalid pp features");
834     *mode = kFrameTriggerPostedStart;
835     return;
836   }
837 
838   for (uint32_t i = 0; i < single_buffer_feature_.size(); i++) {
839     id = single_buffer_feature_[i];
840     feature = pp_features_->GetFeature(id);
841     if (feature && (feature->enable_flags_ & kOpsEnable)) {
842       *mode = kFrameTriggerDefault;
843       return;
844     }
845   }
846 
847   *mode = kFrameTriggerPostedStart;
848 }
849 
FeatureStatePostedStart(ColorFeatureCheckingImpl * obj)850 FeatureStatePostedStart::FeatureStatePostedStart(ColorFeatureCheckingImpl *obj)
851   : obj_(obj) {}
852 
Init()853 DisplayError FeatureStatePostedStart::Init() {
854   return kErrorNone;
855 }
856 
Deinit()857 DisplayError FeatureStatePostedStart::Deinit() {
858   return kErrorNone;
859 }
860 
SetParams(FeatureOps param_type,void * payload)861 DisplayError FeatureStatePostedStart::SetParams(FeatureOps param_type,
862                                                 void *payload) {
863   DisplayError error = kErrorNone;
864   FrameTriggerMode mode = kFrameTriggerPostedStart;
865 
866   if (!obj_) {
867     DLOGE("Invalid param obj_");
868     return kErrorParameters;
869   }
870 
871   if (!payload) {
872     DLOGE("Invalid payload");
873     return kErrorParameters;
874   }
875 
876   switch (param_type) {
877   case kFeatureSwitchMode:
878     mode = *(reinterpret_cast<FrameTriggerMode *>(payload));
879     if (mode >= kFrameTriggerMax) {
880       DLOGE("Invalid mode %d", mode);
881       return kErrorParameters;
882     }
883     if (mode != kFrameTriggerPostedStart) {
884       error = obj_->hw_intf_->SetFrameTrigger(mode);
885       if (!error) {
886         obj_->curr_state_ = obj_->states_.at(mode);
887       }
888     } else {
889       DLOGV_IF(kTagQDCM, "Already in posted start mode");
890     }
891     break;
892   default:
893     DLOGW("unhandled param_type %d", param_type);
894     error = kErrorNotSupported;
895     break;
896   }
897   return error;
898 }
899 
GetParams(FeatureOps param_type,void * payload)900 DisplayError FeatureStatePostedStart::GetParams(FeatureOps param_type,
901                                                 void *payload) {
902   DisplayError error = kErrorNone;
903 
904   if (!obj_) {
905     DLOGE("Invalid param obj_");
906     return kErrorParameters;
907   }
908 
909   if (!payload) {
910     DLOGE("Invalid payload");
911     return kErrorParameters;
912   }
913 
914   switch (param_type) {
915   case kFeatureSwitchMode:
916     *(reinterpret_cast<FrameTriggerMode *>(payload)) = kFrameTriggerPostedStart;
917     break;
918   default:
919     DLOGW("unhandled param_type %d", param_type);
920     error = kErrorNotSupported;
921     break;
922   }
923 
924   return error;
925 }
926 
FeatureStateDefaultTrigger(ColorFeatureCheckingImpl * obj)927 FeatureStateDefaultTrigger::FeatureStateDefaultTrigger(ColorFeatureCheckingImpl *obj)
928   : obj_(obj) {}
929 
Init()930 DisplayError FeatureStateDefaultTrigger::Init() {
931   return kErrorNone;
932 }
933 
Deinit()934 DisplayError FeatureStateDefaultTrigger::Deinit() {
935   return kErrorNone;
936 }
937 
SetParams(FeatureOps param_type,void * payload)938 DisplayError FeatureStateDefaultTrigger::SetParams(FeatureOps param_type,
939                                                    void *payload) {
940   DisplayError error = kErrorNone;
941   FrameTriggerMode mode = kFrameTriggerDefault;
942 
943   if (!obj_) {
944     DLOGE("Invalid param obj_");
945     return kErrorParameters;
946   }
947 
948   if (!payload) {
949     DLOGE("Invalid payload");
950     return kErrorParameters;
951   }
952 
953   switch (param_type) {
954   case kFeatureSwitchMode:
955     mode = *(reinterpret_cast<FrameTriggerMode *>(payload));
956     if (mode >= kFrameTriggerMax) {
957       DLOGE("Invalid mode %d", mode);
958       return kErrorParameters;
959     }
960     if (mode != kFrameTriggerDefault) {
961       error = obj_->hw_intf_->SetFrameTrigger(mode);
962       if (!error) {
963         obj_->curr_state_ = obj_->states_.at(mode);
964       }
965     } else {
966       DLOGV_IF(kTagQDCM, "Already in default trigger mode");
967     }
968     break;
969   default:
970     DLOGW("unhandled param_type %d", param_type);
971     error = kErrorNotSupported;
972     break;
973   }
974   return error;
975 }
976 
GetParams(FeatureOps param_type,void * payload)977 DisplayError FeatureStateDefaultTrigger::GetParams(FeatureOps param_type,
978                                                    void *payload) {
979   DisplayError error = kErrorNone;
980 
981   if (!obj_) {
982     DLOGE("Invalid param obj_");
983     return kErrorParameters;
984   }
985 
986   if (!payload) {
987     DLOGE("Invalid payload");
988     return kErrorParameters;
989   }
990 
991   switch (param_type) {
992   case kFeatureSwitchMode:
993     *(reinterpret_cast<FrameTriggerMode *>(payload)) = kFrameTriggerDefault;
994     break;
995   default:
996     DLOGW("unhandled param_type %d", param_type);
997     error = kErrorNotSupported;
998     break;
999   }
1000 
1001   return error;
1002 }
1003 
FeatureStateSerializedTrigger(ColorFeatureCheckingImpl * obj)1004 FeatureStateSerializedTrigger::FeatureStateSerializedTrigger(ColorFeatureCheckingImpl *obj)
1005   : obj_(obj) {}
1006 
Init()1007 DisplayError FeatureStateSerializedTrigger::Init() {
1008   return kErrorNone;
1009 }
1010 
Deinit()1011 DisplayError FeatureStateSerializedTrigger::Deinit() {
1012   return kErrorNone;
1013 }
1014 
SetParams(FeatureOps param_type,void * payload)1015 DisplayError FeatureStateSerializedTrigger::SetParams(FeatureOps param_type,
1016                                                       void *payload) {
1017   DisplayError error = kErrorNone;
1018   FrameTriggerMode mode = kFrameTriggerSerialize;
1019 
1020   if (!obj_) {
1021     DLOGE("Invalid param obj_");
1022     return kErrorParameters;
1023   }
1024 
1025   if (!payload) {
1026     DLOGE("Invalid payload");
1027     return kErrorParameters;
1028   }
1029 
1030   switch (param_type) {
1031   case kFeatureSwitchMode:
1032     mode = *(reinterpret_cast<FrameTriggerMode *>(payload));
1033     if (mode >= kFrameTriggerMax) {
1034       DLOGE("Invalid mode %d", mode);
1035       return kErrorParameters;
1036     }
1037     if (mode != kFrameTriggerSerialize) {
1038       error = obj_->hw_intf_->SetFrameTrigger(mode);
1039       if (!error) {
1040         obj_->curr_state_ = obj_->states_.at(mode);
1041       }
1042     } else {
1043       DLOGV_IF(kTagQDCM, "Already in serialized trigger mode");
1044     }
1045     break;
1046   default:
1047     DLOGW("unhandled param_type %d", param_type);
1048     error = kErrorNotSupported;
1049     break;
1050   }
1051   return error;
1052 }
1053 
GetParams(FeatureOps param_type,void * payload)1054 DisplayError FeatureStateSerializedTrigger::GetParams(FeatureOps param_type,
1055                                                       void *payload) {
1056   DisplayError error = kErrorNone;
1057 
1058   if (!obj_) {
1059     DLOGE("Invalid param obj_");
1060     return kErrorParameters;
1061   }
1062 
1063   if (!payload) {
1064     DLOGE("Invalid payload");
1065     return kErrorParameters;
1066   }
1067 
1068   switch (param_type) {
1069   case kFeatureSwitchMode:
1070     *(reinterpret_cast<FrameTriggerMode *>(payload)) = kFrameTriggerSerialize;
1071     break;
1072   default:
1073     DLOGW("unhandled param_type %d", param_type);
1074     error = kErrorNotSupported;
1075     break;
1076   }
1077 
1078   return error;
1079 }
1080 
1081 }  // namespace sdm
1082