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