1 /*
2 * Copyright (c) 2014 - 2019, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are permitted
5 * provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright notice, this list of
7 * conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright notice, this list of
9 * conditions and the following disclaimer in the documentation and/or other materials provided
10 * with the distribution.
11 * * Neither the name of The Linux Foundation nor the names of its contributors may be used to
12 * endorse or promote products derived from this software without specific prior written
13 * permission.
14 *
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25 #include <stdio.h>
26 #include <utils/constants.h>
27 #include <utils/debug.h>
28 #include <utils/formats.h>
29 #include <utils/rect.h>
30 #include <utils/utils.h>
31
32 #include <iomanip>
33 #include <map>
34 #include <sstream>
35 #include <string>
36 #include <vector>
37 #include <algorithm>
38
39 #include "display_base.h"
40 #include "hw_info_interface.h"
41
42 #define __CLASS__ "DisplayBase"
43
44 namespace sdm {
45
46 bool DisplayBase::display_power_reset_pending_ = false;
47 Locker DisplayBase::display_power_reset_lock_;
48
GetColorPrimariesFromAttribute(const std::string & gamut)49 static ColorPrimaries GetColorPrimariesFromAttribute(const std::string &gamut) {
50 if (gamut.find(kDisplayP3) != std::string::npos || gamut.find(kDcip3) != std::string::npos) {
51 return ColorPrimaries_DCIP3;
52 } else if (gamut.find(kHdr) != std::string::npos || gamut.find("bt2020") != std::string::npos ||
53 gamut.find("BT2020") != std::string::npos) {
54 // BT2020 is hdr, but the dynamicrange of kHdr means its BT2020
55 return ColorPrimaries_BT2020;
56 } else if (gamut.find(kSrgb) != std::string::npos) {
57 return ColorPrimaries_BT709_5;
58 } else if (gamut.find(kNative) != std::string::npos) {
59 DLOGW("Native Gamut found, returning default: sRGB");
60 return ColorPrimaries_BT709_5;
61 }
62
63 return ColorPrimaries_BT709_5;
64 }
65
66 // TODO(user): Have a single structure handle carries all the interface pointers and variables.
DisplayBase(DisplayType display_type,DisplayEventHandler * event_handler,HWDeviceType hw_device_type,BufferSyncHandler * buffer_sync_handler,BufferAllocator * buffer_allocator,CompManager * comp_manager,HWInfoInterface * hw_info_intf)67 DisplayBase::DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
68 HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
69 BufferAllocator *buffer_allocator, CompManager *comp_manager,
70 HWInfoInterface *hw_info_intf)
71 : display_type_(display_type), event_handler_(event_handler), hw_device_type_(hw_device_type),
72 buffer_sync_handler_(buffer_sync_handler), buffer_allocator_(buffer_allocator),
73 comp_manager_(comp_manager), hw_info_intf_(hw_info_intf) {
74 }
75
DisplayBase(int32_t display_id,DisplayType display_type,DisplayEventHandler * event_handler,HWDeviceType hw_device_type,BufferSyncHandler * buffer_sync_handler,BufferAllocator * buffer_allocator,CompManager * comp_manager,HWInfoInterface * hw_info_intf)76 DisplayBase::DisplayBase(int32_t display_id, DisplayType display_type,
77 DisplayEventHandler *event_handler, HWDeviceType hw_device_type,
78 BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
79 CompManager *comp_manager, HWInfoInterface *hw_info_intf)
80 : display_id_(display_id),
81 display_type_(display_type),
82 event_handler_(event_handler),
83 hw_device_type_(hw_device_type),
84 buffer_sync_handler_(buffer_sync_handler),
85 buffer_allocator_(buffer_allocator),
86 comp_manager_(comp_manager),
87 hw_info_intf_(hw_info_intf) {}
88
Init()89 DisplayError DisplayBase::Init() {
90 lock_guard<recursive_mutex> obj(recursive_mutex_);
91 DisplayError error = kErrorNone;
92 hw_panel_info_ = HWPanelInfo();
93 hw_intf_->GetHWPanelInfo(&hw_panel_info_);
94 if (hw_info_intf_) {
95 hw_info_intf_->GetHWResourceInfo(&hw_resource_info_);
96 }
97 auto max_mixer_stages = hw_resource_info_.num_blending_stages;
98 int property_value = Debug::GetMaxPipesPerMixer(display_type_);
99
100 uint32_t active_index = 0;
101 int drop_vsync = 0;
102 hw_intf_->GetActiveConfig(&active_index);
103 hw_intf_->GetDisplayAttributes(active_index, &display_attributes_);
104 fb_config_ = display_attributes_;
105
106 error = Debug::GetMixerResolution(&mixer_attributes_.width, &mixer_attributes_.height);
107 if (error == kErrorNone) {
108 hw_intf_->SetMixerAttributes(mixer_attributes_);
109 custom_mixer_resolution_ = true;
110 }
111
112 error = hw_intf_->GetMixerAttributes(&mixer_attributes_);
113 if (error != kErrorNone) {
114 return error;
115 }
116
117 // Override x_pixels and y_pixels of frame buffer with mixer width and height
118 fb_config_.x_pixels = mixer_attributes_.width;
119 fb_config_.y_pixels = mixer_attributes_.height;
120
121 if (IsPrimaryDisplay()) {
122 HWScaleLutInfo lut_info = {};
123 error = comp_manager_->GetScaleLutConfig(&lut_info);
124 if (error == kErrorNone) {
125 error = hw_intf_->SetScaleLutConfig(&lut_info);
126 if (error != kErrorNone) {
127 goto CleanupOnError;
128 }
129 }
130 }
131
132 // ColorManager supported for built-in display.
133 if (kBuiltIn == display_type_) {
134 color_mgr_ = ColorManagerProxy::CreateColorManagerProxy(display_type_, hw_intf_,
135 display_attributes_, hw_panel_info_);
136
137 if (color_mgr_) {
138 if (InitializeColorModes() != kErrorNone) {
139 DLOGW("InitColorModes failed for display %d-%d", display_id_, display_type_);
140 }
141 color_mgr_->ColorMgrCombineColorModes();
142 } else {
143 DLOGW("Unable to create ColorManagerProxy for display %d-%d", display_id_, display_type_);
144 }
145 }
146
147 error = comp_manager_->RegisterDisplay(display_id_, display_type_, display_attributes_,
148 hw_panel_info_, mixer_attributes_, fb_config_,
149 &display_comp_ctx_, &(default_qos_data_.clock_hz));
150 if (error != kErrorNone) {
151 DLOGW("Display %d comp manager registration failed!", display_id_);
152 goto CleanupOnError;
153 }
154
155 if (color_modes_cs_.size() > 0) {
156 error = comp_manager_->SetColorModesInfo(display_comp_ctx_, color_modes_cs_);
157 if (error) {
158 DLOGW("SetColorModesInfo failed on display = %d", display_type_);
159 }
160 }
161
162 if (property_value >= 0) {
163 max_mixer_stages = std::min(UINT32(property_value), hw_resource_info_.num_blending_stages);
164 }
165 DisplayBase::SetMaxMixerStages(max_mixer_stages);
166
167 Debug::GetProperty(DISABLE_HDR_LUT_GEN, &disable_hdr_lut_gen_);
168 // TODO(user): Temporary changes, to be removed when DRM driver supports
169 // Partial update with Destination scaler enabled.
170 SetPUonDestScaler();
171
172 Debug::GetProperty(DISABLE_HW_RECOVERY_DUMP_PROP, &disable_hw_recovery_dump_);
173 DLOGI("disable_hw_recovery_dump_ set to %d", disable_hw_recovery_dump_);
174
175 Debug::Get()->GetProperty(DROP_SKEWED_VSYNC, &drop_vsync);
176 drop_skewed_vsync_ = (drop_vsync == 1);
177
178 return kErrorNone;
179
180 CleanupOnError:
181 ClearColorInfo();
182 if (display_comp_ctx_) {
183 comp_manager_->UnregisterDisplay(display_comp_ctx_);
184 }
185
186 return error;
187 }
188
Deinit()189 DisplayError DisplayBase::Deinit() {
190 { // Scope for lock
191 lock_guard<recursive_mutex> obj(recursive_mutex_);
192 ClearColorInfo();
193 comp_manager_->UnregisterDisplay(display_comp_ctx_);
194 if (IsPrimaryDisplay()) {
195 hw_intf_->UnsetScaleLutConfig();
196 }
197 }
198 HWEventsInterface::Destroy(hw_events_intf_);
199 HWInterface::Destroy(hw_intf_);
200
201 return kErrorNone;
202 }
203
BuildLayerStackStats(LayerStack * layer_stack)204 DisplayError DisplayBase::BuildLayerStackStats(LayerStack *layer_stack) {
205 std::vector<Layer *> &layers = layer_stack->layers;
206 HWLayersInfo &hw_layers_info = hw_layers_.info;
207 hw_layers_info.app_layer_count = 0;
208
209 hw_layers_info.stack = layer_stack;
210
211 for (auto &layer : layers) {
212 if (layer->buffer_map == nullptr) {
213 layer->buffer_map = std::make_shared<LayerBufferMap>();
214 }
215 if (layer->composition == kCompositionGPUTarget) {
216 hw_layers_info.gpu_target_index = hw_layers_info.app_layer_count;
217 break;
218 }
219 hw_layers_info.app_layer_count++;
220 if (IsWideColor(layer->input_buffer.color_metadata.colorPrimaries)) {
221 hw_layers_info.wide_color_primaries.push_back(
222 layer->input_buffer.color_metadata.colorPrimaries);
223 }
224 }
225
226 DLOGD_IF(kTagDisplay,
227 "LayerStack layer_count: %d, app_layer_count: %d, gpu_target_index: %d, display: %d-%d",
228 layers.size(), hw_layers_info.app_layer_count, hw_layers_info.gpu_target_index,
229 display_id_, display_type_);
230
231 if (!hw_layers_info.app_layer_count) {
232 DLOGW("Layer count is zero");
233 return kErrorNoAppLayers;
234 }
235
236 if (hw_layers_info.gpu_target_index) {
237 return ValidateGPUTargetParams();
238 }
239
240 return kErrorNone;
241 }
242
ValidateGPUTargetParams()243 DisplayError DisplayBase::ValidateGPUTargetParams() {
244 HWLayersInfo &hw_layers_info = hw_layers_.info;
245 Layer *gpu_target_layer = hw_layers_info.stack->layers.at(hw_layers_info.gpu_target_index);
246
247 if (!IsValid(gpu_target_layer->src_rect)) {
248 DLOGE("Invalid src rect for GPU target layer");
249 return kErrorParameters;
250 }
251
252 if (!IsValid(gpu_target_layer->dst_rect)) {
253 DLOGE("Invalid dst rect for GPU target layer");
254 return kErrorParameters;
255 }
256
257 float layer_mixer_width = FLOAT(mixer_attributes_.width);
258 float layer_mixer_height = FLOAT(mixer_attributes_.height);
259 float fb_width = FLOAT(fb_config_.x_pixels);
260 float fb_height = FLOAT(fb_config_.y_pixels);
261 LayerRect src_domain = (LayerRect){0.0f, 0.0f, fb_width, fb_height};
262 LayerRect dst_domain = (LayerRect){0.0f, 0.0f, layer_mixer_width, layer_mixer_height};
263 LayerRect out_rect = gpu_target_layer->dst_rect;
264
265 MapRect(src_domain, dst_domain, gpu_target_layer->dst_rect, &out_rect);
266 Normalize(1, 1, &out_rect);
267
268 auto gpu_target_layer_dst_xpixels = out_rect.right - out_rect.left;
269 auto gpu_target_layer_dst_ypixels = out_rect.bottom - out_rect.top;
270
271 if (gpu_target_layer_dst_xpixels > mixer_attributes_.width ||
272 gpu_target_layer_dst_ypixels > mixer_attributes_.height) {
273 DLOGE("GPU target layer dst rect is not with in limits gpu wxh %fx%f, mixer wxh %dx%d",
274 gpu_target_layer_dst_xpixels, gpu_target_layer_dst_ypixels,
275 mixer_attributes_.width, mixer_attributes_.height);
276 return kErrorParameters;
277 }
278
279 return kErrorNone;
280 }
281
Prepare(LayerStack * layer_stack)282 DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
283 lock_guard<recursive_mutex> obj(recursive_mutex_);
284 DisplayError error = kErrorNone;
285 needs_validate_ = true;
286
287 DTRACE_SCOPED();
288 if (!active_) {
289 return kErrorPermission;
290 }
291
292 if (!layer_stack) {
293 return kErrorParameters;
294 }
295
296 DLOGI_IF(kTagDisplay, "Entering Prepare for display: %d-%d", display_id_, display_type_);
297 error = BuildLayerStackStats(layer_stack);
298 if (error != kErrorNone) {
299 return error;
300 }
301
302 if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) {
303 DisablePartialUpdateOneFrame();
304 }
305 // TODO(user): Temporary changes, to be removed when DRM driver supports
306 // Partial update with Destination scaler enabled.
307 if (!partial_update_control_ || disable_pu_one_frame_ ||
308 disable_pu_on_dest_scaler_) {
309 comp_manager_->ControlPartialUpdate(display_comp_ctx_, false /* enable */);
310 disable_pu_one_frame_ = false;
311 }
312
313 hw_layers_.updates_mask.set(kUpdateResources);
314 comp_manager_->GenerateROI(display_comp_ctx_, &hw_layers_);
315 comp_manager_->PrePrepare(display_comp_ctx_, &hw_layers_);
316
317 while (true) {
318 error = comp_manager_->Prepare(display_comp_ctx_, &hw_layers_);
319 if (error != kErrorNone) {
320 break;
321 }
322
323 if (layer_stack->flags.fast_path && hw_layers_.info.fast_path_composition) {
324 // In Fast Path, driver validation happens in COMMIT Phase.
325 DLOGI_IF(kTagDisplay, "Draw cycle qualifies for Fast Path!");
326 needs_validate_ = false;
327 break;
328 }
329
330 error = hw_intf_->Validate(&hw_layers_);
331 if (error == kErrorNone) {
332 // Strategy is successful now, wait for Commit().
333 needs_validate_ = false;
334 break;
335 }
336 if (error == kErrorShutDown) {
337 comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
338 return error;
339 }
340 }
341
342 comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
343
344 DLOGI_IF(kTagDisplay, "Exiting Prepare for display type : %d error: %d", display_type_, error);
345 return error;
346 }
347
Commit(LayerStack * layer_stack)348 DisplayError DisplayBase::Commit(LayerStack *layer_stack) {
349 lock_guard<recursive_mutex> obj(recursive_mutex_);
350 DisplayError error = kErrorNone;
351
352 if (!active_) {
353 needs_validate_ = true;
354 return kErrorPermission;
355 }
356
357 if (!layer_stack) {
358 return kErrorParameters;
359 }
360
361 if (needs_validate_) {
362 DLOGE("Commit: Corresponding Prepare() is not called for display %d-%d", display_id_,
363 display_type_);
364 return kErrorNotValidated;
365 }
366
367 // Layer stack attributes has changed, need to Reconfigure, currently in use for Hybrid Comp
368 if (layer_stack->flags.attributes_changed) {
369 error = comp_manager_->ReConfigure(display_comp_ctx_, &hw_layers_);
370 if (error != kErrorNone) {
371 return error;
372 }
373
374 error = hw_intf_->Validate(&hw_layers_);
375 if (error != kErrorNone) {
376 return error;
377 }
378 }
379
380 DLOGI_IF(kTagDisplay, "Entering commit for display: %d-%d", display_id_, display_type_);
381 CommitLayerParams(layer_stack);
382
383 error = comp_manager_->Commit(display_comp_ctx_, &hw_layers_);
384 if (error != kErrorNone) {
385 return error;
386 }
387
388 // check if feature list cache is dirty and pending.
389 // If dirty, need program to hardware blocks.
390 if (color_mgr_)
391 error = color_mgr_->Commit();
392 if (error != kErrorNone) { // won't affect this execution path.
393 DLOGW("ColorManager::Commit(...) isn't working");
394 }
395
396 error = hw_intf_->Commit(&hw_layers_);
397 if (error != kErrorNone) {
398 if (layer_stack->flags.fast_path && hw_layers_.info.fast_path_composition) {
399 // If COMMIT fails on the Fast Path, set Safe Mode.
400 DLOGE("COMMIT failed in Fast Path, set Safe Mode!");
401 comp_manager_->SetSafeMode(true);
402 error = kErrorNotValidated;
403 }
404 return error;
405 }
406
407 PostCommitLayerParams(layer_stack);
408
409 if (partial_update_control_) {
410 comp_manager_->ControlPartialUpdate(display_comp_ctx_, true /* enable */);
411 }
412
413 error = comp_manager_->PostCommit(display_comp_ctx_, &hw_layers_);
414 if (error != kErrorNone) {
415 return error;
416 }
417
418 // Stop dropping vsync when first commit is received after idle fallback.
419 drop_hw_vsync_ = false;
420 DLOGI_IF(kTagDisplay, "Exiting commit for display: %d-%d", display_id_, display_type_);
421
422 return kErrorNone;
423 }
424
Flush(LayerStack * layer_stack)425 DisplayError DisplayBase::Flush(LayerStack *layer_stack) {
426 lock_guard<recursive_mutex> obj(recursive_mutex_);
427 DisplayError error = kErrorNone;
428
429 if (!active_) {
430 return kErrorPermission;
431 }
432 hw_layers_.info.hw_layers.clear();
433 hw_layers_.info.stack = layer_stack;
434 error = hw_intf_->Flush(&hw_layers_);
435 if (error == kErrorNone) {
436 comp_manager_->Purge(display_comp_ctx_);
437 needs_validate_ = true;
438 } else {
439 DLOGW("Unable to flush display %d-%d", display_id_, display_type_);
440 }
441
442 return error;
443 }
444
GetDisplayState(DisplayState * state)445 DisplayError DisplayBase::GetDisplayState(DisplayState *state) {
446 lock_guard<recursive_mutex> obj(recursive_mutex_);
447 if (!state) {
448 return kErrorParameters;
449 }
450
451 *state = state_;
452 return kErrorNone;
453 }
454
GetNumVariableInfoConfigs(uint32_t * count)455 DisplayError DisplayBase::GetNumVariableInfoConfigs(uint32_t *count) {
456 lock_guard<recursive_mutex> obj(recursive_mutex_);
457 return hw_intf_->GetNumDisplayAttributes(count);
458 }
459
GetConfig(uint32_t index,DisplayConfigVariableInfo * variable_info)460 DisplayError DisplayBase::GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info) {
461 lock_guard<recursive_mutex> obj(recursive_mutex_);
462 HWDisplayAttributes attrib;
463 if (hw_intf_->GetDisplayAttributes(index, &attrib) == kErrorNone) {
464 *variable_info = attrib;
465 if (custom_mixer_resolution_) {
466 variable_info->x_pixels = fb_config_.x_pixels;
467 variable_info->y_pixels = fb_config_.y_pixels;
468 }
469 return kErrorNone;
470 }
471
472 return kErrorNotSupported;
473 }
474
GetConfig(DisplayConfigFixedInfo * fixed_info)475 DisplayError DisplayBase::GetConfig(DisplayConfigFixedInfo *fixed_info) {
476 lock_guard<recursive_mutex> obj(recursive_mutex_);
477 fixed_info->is_cmdmode = (hw_panel_info_.mode == kModeCommand);
478
479 HWResourceInfo hw_resource_info = HWResourceInfo();
480 hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
481 bool hdr_supported = hw_resource_info.has_hdr;
482 HWDisplayInterfaceInfo hw_disp_info = {};
483 hw_info_intf_->GetFirstDisplayInterfaceType(&hw_disp_info);
484 if (hw_disp_info.type == kHDMI) {
485 hdr_supported = (hdr_supported && hw_panel_info_.hdr_enabled);
486 }
487
488 fixed_info->hdr_supported = hdr_supported;
489 // Populate luminance values only if hdr will be supported on that display
490 fixed_info->max_luminance = fixed_info->hdr_supported ? hw_panel_info_.peak_luminance: 0;
491 fixed_info->average_luminance = fixed_info->hdr_supported ? hw_panel_info_.average_luminance : 0;
492 fixed_info->min_luminance = fixed_info->hdr_supported ? hw_panel_info_.blackness_level: 0;
493 fixed_info->hdr_eotf = hw_panel_info_.hdr_eotf;
494 fixed_info->hdr_metadata_type_one = hw_panel_info_.hdr_metadata_type_one;
495 fixed_info->partial_update = hw_panel_info_.partial_update;
496
497 return kErrorNone;
498 }
499
GetActiveConfig(uint32_t * index)500 DisplayError DisplayBase::GetActiveConfig(uint32_t *index) {
501 lock_guard<recursive_mutex> obj(recursive_mutex_);
502 return hw_intf_->GetActiveConfig(index);
503 }
504
GetVSyncState(bool * enabled)505 DisplayError DisplayBase::GetVSyncState(bool *enabled) {
506 lock_guard<recursive_mutex> obj(recursive_mutex_);
507 if (!enabled) {
508 return kErrorParameters;
509 }
510
511 *enabled = vsync_enable_;
512
513 return kErrorNone;
514 }
515
SetDisplayState(DisplayState state,bool teardown,int * release_fence)516 DisplayError DisplayBase::SetDisplayState(DisplayState state, bool teardown,
517 int *release_fence) {
518 lock_guard<recursive_mutex> obj(recursive_mutex_);
519 DisplayError error = kErrorNone;
520 bool active = false;
521
522 DLOGI("Set state = %d, display %d-%d, teardown = %d", state, display_id_,
523 display_type_, teardown);
524
525 if (state == state_) {
526 DLOGI("Same state transition is requested.");
527 return kErrorNone;
528 }
529
530 switch (state) {
531 case kStateOff:
532 hw_layers_.info.hw_layers.clear();
533 error = hw_intf_->Flush(&hw_layers_);
534 if (error == kErrorNone) {
535 error = hw_intf_->PowerOff(teardown);
536 }
537 break;
538
539 case kStateOn:
540 error = hw_intf_->PowerOn(default_qos_data_, release_fence);
541 if (error != kErrorNone) {
542 return error;
543 }
544
545 error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_,
546 hw_panel_info_, mixer_attributes_, fb_config_,
547 &(default_qos_data_.clock_hz));
548 if (error != kErrorNone) {
549 return error;
550 }
551
552 active = true;
553 break;
554
555 case kStateDoze:
556 error = hw_intf_->Doze(default_qos_data_, release_fence);
557 active = true;
558 break;
559
560 case kStateDozeSuspend:
561 error = hw_intf_->DozeSuspend(default_qos_data_, release_fence);
562 if (display_type_ != kBuiltIn) {
563 active = true;
564 }
565 break;
566
567 case kStateStandby:
568 error = hw_intf_->Standby();
569 break;
570
571 default:
572 DLOGE("Spurious state = %d transition requested.", state);
573 return kErrorParameters;
574 }
575
576 DisablePartialUpdateOneFrame();
577
578 if (error == kErrorNone) {
579 active_ = active;
580 state_ = state;
581 comp_manager_->SetDisplayState(display_comp_ctx_, state);
582 }
583
584 return error;
585 }
586
SetActiveConfig(uint32_t index)587 DisplayError DisplayBase::SetActiveConfig(uint32_t index) {
588 lock_guard<recursive_mutex> obj(recursive_mutex_);
589 DisplayError error = kErrorNone;
590 uint32_t active_index = 0;
591
592 hw_intf_->GetActiveConfig(&active_index);
593
594 if (active_index == index) {
595 return kErrorNone;
596 }
597
598 error = hw_intf_->SetDisplayAttributes(index);
599 if (error != kErrorNone) {
600 return error;
601 }
602
603 return ReconfigureDisplay();
604 }
605
SetMaxMixerStages(uint32_t max_mixer_stages)606 DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) {
607 lock_guard<recursive_mutex> obj(recursive_mutex_);
608 DisplayError error = kErrorNone;
609
610 error = comp_manager_->SetMaxMixerStages(display_comp_ctx_, max_mixer_stages);
611
612 if (error == kErrorNone) {
613 max_mixer_stages_ = max_mixer_stages;
614 }
615
616 return error;
617 }
618
Dump()619 std::string DisplayBase::Dump() {
620 lock_guard<recursive_mutex> obj(recursive_mutex_);
621 HWDisplayAttributes attrib;
622 uint32_t active_index = 0;
623 uint32_t num_modes = 0;
624 std::ostringstream os;
625
626 hw_intf_->GetNumDisplayAttributes(&num_modes);
627 hw_intf_->GetActiveConfig(&active_index);
628 hw_intf_->GetDisplayAttributes(active_index, &attrib);
629
630 os << "device type:" << display_type_;
631 os << "\nstate: " << state_ << " vsync on: " << vsync_enable_
632 << " max. mixer stages: " << max_mixer_stages_;
633 os << "\nnum configs: " << num_modes << " active config index: " << active_index;
634 os << "\nDisplay Attributes:";
635 os << "\n Mode:" << (hw_panel_info_.mode == kModeVideo ? "Video" : "Command");
636 os << std::boolalpha;
637 os << " Primary:" << hw_panel_info_.is_primary_panel;
638 os << " DynFPS:" << hw_panel_info_.dynamic_fps;
639 os << "\n HDR Panel:" << hw_panel_info_.hdr_enabled;
640 os << " QSync:" << hw_panel_info_.qsync_support;
641 os << " DynBitclk:" << hw_panel_info_.dyn_bitclk_support;
642 os << "\n Left Split:" << hw_panel_info_.split_info.left_split << " Right Split:"
643 << hw_panel_info_.split_info.right_split;
644 os << "\n PartialUpdate:" << hw_panel_info_.partial_update;
645 if (hw_panel_info_.partial_update) {
646 os << "\n ROI Min w:" << hw_panel_info_.min_roi_width;
647 os << " Min h:" << hw_panel_info_.min_roi_height;
648 os << " NeedsMerge: " << hw_panel_info_.needs_roi_merge;
649 os << " Alignment: l:" << hw_panel_info_.left_align << " w:" << hw_panel_info_.width_align;
650 os << " t:" << hw_panel_info_.top_align << " b:" << hw_panel_info_.height_align;
651 }
652 os << "\n FPS min:" << hw_panel_info_.min_fps << " max:" << hw_panel_info_.max_fps
653 << " cur:" << display_attributes_.fps;
654 os << " TransferTime: " << hw_panel_info_.transfer_time_us <<"us";
655 os << "\n Display WxH: " << display_attributes_.x_pixels << "x"
656 << display_attributes_.y_pixels;
657 os << " MixerWxH: " << mixer_attributes_.width << "x" << mixer_attributes_.height;
658 os << " DPI: " << display_attributes_.x_dpi << "x" << display_attributes_.y_dpi;
659 os << " LM_Split: " << display_attributes_.is_device_split;
660 os << "\n vsync_period " << display_attributes_.vsync_period_ns;
661 os << " v_back_porch: " << display_attributes_.v_back_porch;
662 os << " v_front_porch: " << display_attributes_.v_front_porch;
663 os << " v_pulse_width: " << display_attributes_.v_pulse_width;
664 os << "\n v_total: " << display_attributes_.v_total;
665 os << " h_total: " << display_attributes_.h_total;
666 os << " clk: " << display_attributes_.clock_khz;
667 os << " Topology: " << display_attributes_.topology;
668 os << std::noboolalpha;
669
670 os << "\nCurrent Color Mode: " << current_color_mode_.c_str();
671 os << "\nAvailable Color Modes:\n";
672 for (auto it : color_mode_map_) {
673 os << " " << it.first << " " << std::setw(35 - INT(it.first.length())) <<
674 it.second->id;
675 os << " ";
676 for (auto attr_it : color_mode_attr_map_[it.first]) {
677 os << std::right << " " << attr_it.first << ": " << attr_it.second;
678 }
679 os << "\n";
680 }
681
682 uint32_t num_hw_layers = 0;
683 if (hw_layers_.info.stack) {
684 num_hw_layers = UINT32(hw_layers_.info.hw_layers.size());
685 }
686
687 if (num_hw_layers == 0) {
688 os << "\nNo hardware layers programmed";
689 return os.str();
690 }
691
692 LayerBuffer *out_buffer = hw_layers_.info.stack->output_buffer;
693 if (out_buffer) {
694 os << "\n Output buffer res: " << out_buffer->width << "x" << out_buffer->height << " format: "
695 << GetFormatString(out_buffer->format);
696 }
697 HWLayersInfo &layer_info = hw_layers_.info;
698 for (uint32_t i = 0; i < layer_info.left_frame_roi.size(); i++) {
699 LayerRect &l_roi = layer_info.left_frame_roi.at(i);
700 LayerRect &r_roi = layer_info.right_frame_roi.at(i);
701
702 os << "\nROI(LTRB)#" << i << " LEFT(" << INT(l_roi.left) << " " << INT(l_roi.top) << " " <<
703 INT(l_roi.right) << " " << INT(l_roi.bottom) << ")";
704 if (IsValid(r_roi)) {
705 os << " RIGHT(" << INT(r_roi.left) << " " << INT(r_roi.top) << " " << INT(r_roi.right) << " "
706 << INT(r_roi.bottom) << ")";
707 }
708 }
709
710 LayerRect &fb_roi = layer_info.partial_fb_roi;
711 if (IsValid(fb_roi)) {
712 os << "\nPartial FB ROI(LTRB):(" << INT(fb_roi.left) << " " << INT(fb_roi.top) << " " <<
713 INT(fb_roi.right) << " " << INT(fb_roi.bottom) << ")";
714 }
715
716 const char *header = "\n| Idx | Comp Type | Split | Pipe | W x H | Format | Src Rect (L T R B) | Dst Rect (L T R B) | Z | Pipe Flags | Deci(HxV) | CS | Tr | Rng |"; //NOLINT
717 const char *newline = "\n|-----|------------|-----------|------|-------------|--------------------------|---------------------|---------------------|----|------------|-----------|----|----|-----|"; //NOLINT
718 const char *format = "\n| %3s | %10s | %9s | %4d | %4d x %4d | %24s | %4d %4d %4d %4d | %4d %4d %4d %4d | %2s | %10s | %9s | %2s | %2s | %3s |"; //NOLINT
719
720 os << "\n";
721 os << newline;
722 os << header;
723 os << newline;
724
725 for (uint32_t i = 0; i < num_hw_layers; i++) {
726 uint32_t layer_index = hw_layers_.info.index.at(i);
727 // sdm-layer from client layer stack
728 Layer *sdm_layer = hw_layers_.info.stack->layers.at(layer_index);
729 // hw-layer from hw layers info
730 Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
731 LayerBuffer *input_buffer = &hw_layer.input_buffer;
732 HWLayerConfig &layer_config = hw_layers_.config[i];
733 HWRotatorSession &hw_rotator_session = layer_config.hw_rotator_session;
734
735 const char *comp_type = GetName(sdm_layer->composition);
736 const char *buffer_format = GetFormatString(input_buffer->format);
737 const char *pipe_split[2] = { "Pipe-1", "Pipe-2" };
738 char idx[8];
739
740 snprintf(idx, sizeof(idx), "%d", layer_index);
741
742 for (uint32_t count = 0; count < hw_rotator_session.hw_block_count; count++) {
743 char row[1024];
744 HWRotateInfo &rotate = hw_rotator_session.hw_rotate_info[count];
745 LayerRect &src_roi = rotate.src_roi;
746 LayerRect &dst_roi = rotate.dst_roi;
747 char rot[12] = { 0 };
748
749 snprintf(rot, sizeof(rot), "Rot-%s-%d", hw_rotator_session.mode == kRotatorInline ?
750 "inl" : "off", count + 1);
751
752 snprintf(row, sizeof(row), format, idx, comp_type, rot,
753 0, input_buffer->width, input_buffer->height, buffer_format,
754 INT(src_roi.left), INT(src_roi.top), INT(src_roi.right), INT(src_roi.bottom),
755 INT(dst_roi.left), INT(dst_roi.top), INT(dst_roi.right), INT(dst_roi.bottom),
756 "-", "- ", "- ", "-", "-", "-");
757 os << row;
758 // print the below only once per layer block, fill with spaces for rest.
759 idx[0] = 0;
760 comp_type = "";
761 }
762
763 if (hw_rotator_session.hw_block_count > 0) {
764 input_buffer = &hw_rotator_session.output_buffer;
765 buffer_format = GetFormatString(input_buffer->format);
766 }
767
768 if (layer_config.use_solidfill_stage) {
769 LayerRect src_roi = layer_config.hw_solidfill_stage.roi;
770 const char *decimation = "";
771 char flags[16] = { 0 };
772 char z_order[8] = { 0 };
773 const char *color_primary = "";
774 const char *transfer = "";
775 const char *range = "";
776 char row[1024] = { 0 };
777
778 snprintf(z_order, sizeof(z_order), "%d", layer_config.hw_solidfill_stage.z_order);
779 snprintf(flags, sizeof(flags), "0x%08x", hw_layer.flags.flags);
780 snprintf(row, sizeof(row), format, idx, comp_type, pipe_split[0],
781 0, INT(src_roi.right), INT(src_roi.bottom),
782 buffer_format, INT(src_roi.left), INT(src_roi.top),
783 INT(src_roi.right), INT(src_roi.bottom), INT(src_roi.left),
784 INT(src_roi.top), INT(src_roi.right), INT(src_roi.bottom),
785 z_order, flags, decimation, color_primary, transfer, range);
786 os << row;
787 continue;
788 }
789
790 for (uint32_t count = 0; count < 2; count++) {
791 char decimation[16] = { 0 };
792 char flags[16] = { 0 };
793 char z_order[8] = { 0 };
794 char color_primary[8] = { 0 };
795 char transfer[8] = { 0 };
796 char range[8] = { 0 };
797
798 HWPipeInfo &pipe = (count == 0) ? layer_config.left_pipe : layer_config.right_pipe;
799
800 if (!pipe.valid) {
801 continue;
802 }
803
804 LayerRect src_roi = pipe.src_roi;
805 LayerRect &dst_roi = pipe.dst_roi;
806 if (hw_rotator_session.mode == kRotatorInline) {
807 src_roi = hw_rotator_session.hw_rotate_info[count].dst_roi;
808 }
809
810 snprintf(z_order, sizeof(z_order), "%d", pipe.z_order);
811 snprintf(flags, sizeof(flags), "0x%08x", pipe.flags);
812 snprintf(decimation, sizeof(decimation), "%3d x %3d", pipe.horizontal_decimation,
813 pipe.vertical_decimation);
814 ColorMetaData &color_metadata = hw_layer.input_buffer.color_metadata;
815 snprintf(color_primary, sizeof(color_primary), "%d", color_metadata.colorPrimaries);
816 snprintf(transfer, sizeof(transfer), "%d", color_metadata.transfer);
817 snprintf(range, sizeof(range), "%d", color_metadata.range);
818
819 char row[1024];
820 snprintf(row, sizeof(row), format, idx, comp_type, pipe_split[count],
821 pipe.pipe_id, input_buffer->width, input_buffer->height,
822 buffer_format, INT(src_roi.left), INT(src_roi.top),
823 INT(src_roi.right), INT(src_roi.bottom), INT(dst_roi.left),
824 INT(dst_roi.top), INT(dst_roi.right), INT(dst_roi.bottom),
825 z_order, flags, decimation, color_primary, transfer, range);
826
827 os << row;
828 // print the below only once per layer block, fill with spaces for rest.
829 idx[0] = 0;
830 comp_type = "";
831 }
832 }
833
834 os << newline << "\n";
835
836 return os.str();
837 }
838
GetName(const LayerComposition & composition)839 const char * DisplayBase::GetName(const LayerComposition &composition) {
840 switch (composition) {
841 case kCompositionGPU: return "GPU";
842 case kCompositionSDE: return "SDE";
843 case kCompositionCursor: return "CURSOR";
844 case kCompositionHybrid: return "HYBRID";
845 case kCompositionBlit: return "BLIT";
846 case kCompositionGPUTarget: return "GPU_TARGET";
847 case kCompositionBlitTarget: return "BLIT_TARGET";
848 default: return "UNKNOWN";
849 }
850 }
851
ColorSVCRequestRoute(const PPDisplayAPIPayload & in_payload,PPDisplayAPIPayload * out_payload,PPPendingParams * pending_action)852 DisplayError DisplayBase::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
853 PPDisplayAPIPayload *out_payload,
854 PPPendingParams *pending_action) {
855 lock_guard<recursive_mutex> obj(recursive_mutex_);
856 if (color_mgr_)
857 return color_mgr_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
858 else
859 return kErrorParameters;
860 }
861
GetColorModeCount(uint32_t * mode_count)862 DisplayError DisplayBase::GetColorModeCount(uint32_t *mode_count) {
863 lock_guard<recursive_mutex> obj(recursive_mutex_);
864 if (!mode_count) {
865 return kErrorParameters;
866 }
867
868 if (!color_mgr_) {
869 return kErrorNotSupported;
870 }
871
872 DLOGV_IF(kTagQDCM, "Display = %d Number of modes from color manager = %d", display_type_,
873 num_color_modes_);
874
875 *mode_count = num_color_modes_;
876
877 return kErrorNone;
878 }
879
GetColorModes(uint32_t * mode_count,std::vector<std::string> * color_modes)880 DisplayError DisplayBase::GetColorModes(uint32_t *mode_count,
881 std::vector<std::string> *color_modes) {
882 lock_guard<recursive_mutex> obj(recursive_mutex_);
883 if (!mode_count || !color_modes) {
884 return kErrorParameters;
885 }
886
887 if (!color_mgr_) {
888 return kErrorNotSupported;
889 }
890 uint32_t i = 0;
891 for (ColorModeAttrMap::iterator it = color_mode_attr_map_.begin();
892 ((i < num_color_modes_) && (it != color_mode_attr_map_.end())); i++, it++) {
893 DLOGI("ColorMode name = %s", it->first.c_str());
894 color_modes->at(i) = it->first.c_str();
895 }
896
897 return kErrorNone;
898 }
899
GetColorModeAttr(const std::string & color_mode,AttrVal * attr)900 DisplayError DisplayBase::GetColorModeAttr(const std::string &color_mode, AttrVal *attr) {
901 lock_guard<recursive_mutex> obj(recursive_mutex_);
902 if (!attr) {
903 return kErrorParameters;
904 }
905
906 if (!color_mgr_) {
907 return kErrorNotSupported;
908 }
909
910 auto it = color_mode_attr_map_.find(color_mode);
911 if (it == color_mode_attr_map_.end()) {
912 DLOGI("Mode %s has no attribute", color_mode.c_str());
913 return kErrorNotSupported;
914 }
915 *attr = it->second;
916
917 return kErrorNone;
918 }
919
SetColorMode(const std::string & color_mode)920 DisplayError DisplayBase::SetColorMode(const std::string &color_mode) {
921 lock_guard<recursive_mutex> obj(recursive_mutex_);
922 if (!color_mgr_) {
923 return kErrorNotSupported;
924 }
925
926 DisplayError error = kErrorNone;
927 error = SetColorModeInternal(color_mode);
928 if (error != kErrorNone) {
929 return error;
930 }
931
932 std::string dynamic_range = kSdr;
933 if (IsSupportColorModeAttribute(color_mode)) {
934 auto it_mode = color_mode_attr_map_.find(color_mode);
935 GetValueOfModeAttribute(it_mode->second, kDynamicRangeAttribute, &dynamic_range);
936 }
937
938 comp_manager_->ControlDpps(dynamic_range != kHdr);
939
940 current_color_mode_ = color_mode;
941 PrimariesTransfer blend_space = {};
942 blend_space = GetBlendSpaceFromColorMode();
943 error = comp_manager_->SetBlendSpace(display_comp_ctx_, blend_space);
944 if (error != kErrorNone) {
945 DLOGE("SetBlendSpace failed, error = %d display_type_= %d", error, display_type_);
946 }
947
948 return error;
949 }
950
SetColorModeById(int32_t color_mode_id)951 DisplayError DisplayBase::SetColorModeById(int32_t color_mode_id) {
952 return color_mgr_->ColorMgrSetMode(color_mode_id);
953 }
954
SetColorModeInternal(const std::string & color_mode)955 DisplayError DisplayBase::SetColorModeInternal(const std::string &color_mode) {
956 DLOGV_IF(kTagQDCM, "Color Mode = %s", color_mode.c_str());
957
958 ColorModeMap::iterator it = color_mode_map_.find(color_mode);
959 if (it == color_mode_map_.end()) {
960 DLOGE("Failed: Unknown Mode : %s", color_mode.c_str());
961 return kErrorNotSupported;
962 }
963
964 SDEDisplayMode *sde_display_mode = it->second;
965
966 DLOGV_IF(kTagQDCM, "Color Mode Name = %s corresponding mode_id = %d", sde_display_mode->name,
967 sde_display_mode->id);
968 DisplayError error = kErrorNone;
969 error = color_mgr_->ColorMgrSetMode(sde_display_mode->id);
970 if (error != kErrorNone) {
971 DLOGE("Failed for mode id = %d", sde_display_mode->id);
972 return error;
973 }
974
975 return error;
976 }
977
GetColorModeName(int32_t mode_id,std::string * mode_name)978 DisplayError DisplayBase::GetColorModeName(int32_t mode_id, std::string *mode_name) {
979 if (!mode_name) {
980 DLOGE("Invalid parameters");
981 return kErrorParameters;
982 }
983 for (uint32_t i = 0; i < num_color_modes_; i++) {
984 if (color_modes_[i].id == mode_id) {
985 *mode_name = color_modes_[i].name;
986 return kErrorNone;
987 }
988 }
989
990 DLOGE("Failed to get color mode name for mode id = %d", mode_id);
991 return kErrorUndefined;
992 }
993
GetValueOfModeAttribute(const AttrVal & attr,const std::string & type,std::string * value)994 DisplayError DisplayBase::GetValueOfModeAttribute(const AttrVal &attr, const std::string &type,
995 std::string *value) {
996 if (!value) {
997 return kErrorParameters;
998 }
999 for (auto &it : attr) {
1000 if (it.first.find(type) != std::string::npos) {
1001 *value = it.second;
1002 }
1003 }
1004
1005 return kErrorNone;
1006 }
1007
IsSupportColorModeAttribute(const std::string & color_mode)1008 bool DisplayBase::IsSupportColorModeAttribute(const std::string &color_mode) {
1009 auto it = color_mode_attr_map_.find(color_mode);
1010 if (it == color_mode_attr_map_.end()) {
1011 return false;
1012 }
1013 return true;
1014 }
1015
SetColorTransform(const uint32_t length,const double * color_transform)1016 DisplayError DisplayBase::SetColorTransform(const uint32_t length, const double *color_transform) {
1017 lock_guard<recursive_mutex> obj(recursive_mutex_);
1018 if (!color_mgr_) {
1019 return kErrorNotSupported;
1020 }
1021
1022 if (!color_transform) {
1023 return kErrorParameters;
1024 }
1025
1026 return color_mgr_->ColorMgrSetColorTransform(length, color_transform);
1027 }
1028
GetDefaultColorMode(std::string * color_mode)1029 DisplayError DisplayBase::GetDefaultColorMode(std::string *color_mode) {
1030 lock_guard<recursive_mutex> obj(recursive_mutex_);
1031 if (!color_mode) {
1032 return kErrorParameters;
1033 }
1034
1035 if (!color_mgr_) {
1036 return kErrorNotSupported;
1037 }
1038
1039 int32_t default_id = kInvalidModeId;
1040 DisplayError error = color_mgr_->ColorMgrGetDefaultModeID(&default_id);
1041 if (error != kErrorNone) {
1042 DLOGE("Failed for get default color mode id");
1043 return error;
1044 }
1045
1046 for (uint32_t i = 0; i < num_color_modes_; i++) {
1047 if (color_modes_[i].id == default_id) {
1048 *color_mode = color_modes_[i].name;
1049 return kErrorNone;
1050 }
1051 }
1052
1053 return kErrorNotSupported;
1054 }
1055
SetCursorPosition(int x,int y)1056 DisplayError DisplayBase::SetCursorPosition(int x, int y) {
1057 lock_guard<recursive_mutex> obj(recursive_mutex_);
1058 if (state_ != kStateOn) {
1059 return kErrorNotSupported;
1060 }
1061
1062 DisplayError error = comp_manager_->ValidateAndSetCursorPosition(display_comp_ctx_, &hw_layers_,
1063 x, y);
1064 if (error == kErrorNone) {
1065 return hw_intf_->SetCursorPosition(&hw_layers_, x, y);
1066 }
1067
1068 return kErrorNone;
1069 }
1070
GetRefreshRateRange(uint32_t * min_refresh_rate,uint32_t * max_refresh_rate)1071 DisplayError DisplayBase::GetRefreshRateRange(uint32_t *min_refresh_rate,
1072 uint32_t *max_refresh_rate) {
1073 lock_guard<recursive_mutex> obj(recursive_mutex_);
1074 // The min and max refresh rates will be same when the HWPanelInfo does not contain valid rates.
1075 // Usually for secondary displays, command mode panels
1076 HWDisplayAttributes display_attributes;
1077 uint32_t active_index = 0;
1078 hw_intf_->GetActiveConfig(&active_index);
1079 DisplayError error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
1080 if (error) {
1081 return error;
1082 }
1083
1084 *min_refresh_rate = display_attributes.fps;
1085 *max_refresh_rate = display_attributes.fps;
1086
1087 return error;
1088 }
1089
SetVSyncState(bool enable)1090 DisplayError DisplayBase::SetVSyncState(bool enable) {
1091 lock_guard<recursive_mutex> obj(recursive_mutex_);
1092 DisplayError error = kErrorNone;
1093 if (vsync_enable_ != enable) {
1094 error = hw_intf_->SetVSyncState(enable);
1095 if (error == kErrorNotSupported) {
1096 if (drop_skewed_vsync_ && (hw_panel_info_.mode == kModeVideo) &&
1097 enable && (current_refresh_rate_ < hw_panel_info_.max_fps)) {
1098 drop_hw_vsync_ = true;
1099 }
1100 error = hw_events_intf_->SetEventState(HWEvent::VSYNC, enable);
1101 }
1102 if (error == kErrorNone) {
1103 vsync_enable_ = enable;
1104 }
1105 }
1106
1107 return error;
1108 }
1109
ReconfigureDisplay()1110 DisplayError DisplayBase::ReconfigureDisplay() {
1111 lock_guard<recursive_mutex> obj(recursive_mutex_);
1112 DisplayError error = kErrorNone;
1113 HWDisplayAttributes display_attributes;
1114 HWMixerAttributes mixer_attributes;
1115 HWPanelInfo hw_panel_info;
1116 uint32_t active_index = 0;
1117
1118 DTRACE_SCOPED();
1119
1120 error = hw_intf_->GetActiveConfig(&active_index);
1121 if (error != kErrorNone) {
1122 return error;
1123 }
1124
1125 error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
1126 if (error != kErrorNone) {
1127 return error;
1128 }
1129
1130 error = hw_intf_->GetMixerAttributes(&mixer_attributes);
1131 if (error != kErrorNone) {
1132 return error;
1133 }
1134
1135 error = hw_intf_->GetHWPanelInfo(&hw_panel_info);
1136 if (error != kErrorNone) {
1137 return error;
1138 }
1139
1140 bool display_unchanged = (display_attributes == display_attributes_);
1141 bool mixer_unchanged = (mixer_attributes == mixer_attributes_);
1142 bool panel_unchanged = (hw_panel_info == hw_panel_info_);
1143 if (display_unchanged && mixer_unchanged && panel_unchanged) {
1144 return kErrorNone;
1145 }
1146
1147 error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info,
1148 mixer_attributes, fb_config_,
1149 &(default_qos_data_.clock_hz));
1150 if (error != kErrorNone) {
1151 return error;
1152 }
1153
1154 bool disble_pu = true;
1155 if (mixer_unchanged && panel_unchanged) {
1156 // Do not disable Partial Update for one frame, if only FPS has changed.
1157 // Because if first frame after transition, has a partial Frame-ROI and
1158 // is followed by Skip Validate frames, then it can benefit those frames.
1159 disble_pu = !display_attributes_.OnlyFpsChanged(display_attributes);
1160 }
1161
1162 if (disble_pu) {
1163 DisablePartialUpdateOneFrame();
1164 }
1165
1166 display_attributes_ = display_attributes;
1167 mixer_attributes_ = mixer_attributes;
1168 hw_panel_info_ = hw_panel_info;
1169 // TODO(user): Temporary changes, to be removed when DRM driver supports
1170 // Partial update with Destination scaler enabled.
1171 SetPUonDestScaler();
1172
1173 return kErrorNone;
1174 }
1175
SetMixerResolution(uint32_t width,uint32_t height)1176 DisplayError DisplayBase::SetMixerResolution(uint32_t width, uint32_t height) {
1177 lock_guard<recursive_mutex> obj(recursive_mutex_);
1178
1179 DisplayError error = ReconfigureMixer(width, height);
1180 if (error != kErrorNone) {
1181 return error;
1182 }
1183
1184 req_mixer_width_ = width;
1185 req_mixer_height_ = height;
1186
1187 return kErrorNone;
1188 }
1189
GetMixerResolution(uint32_t * width,uint32_t * height)1190 DisplayError DisplayBase::GetMixerResolution(uint32_t *width, uint32_t *height) {
1191 lock_guard<recursive_mutex> obj(recursive_mutex_);
1192 if (!width || !height) {
1193 return kErrorParameters;
1194 }
1195
1196 *width = mixer_attributes_.width;
1197 *height = mixer_attributes_.height;
1198
1199 return kErrorNone;
1200 }
1201
ReconfigureMixer(uint32_t width,uint32_t height)1202 DisplayError DisplayBase::ReconfigureMixer(uint32_t width, uint32_t height) {
1203 lock_guard<recursive_mutex> obj(recursive_mutex_);
1204 DisplayError error = kErrorNone;
1205
1206 DTRACE_SCOPED();
1207 if (!width || !height) {
1208 return kErrorParameters;
1209 }
1210
1211 DLOGD_IF(kTagQDCM, "Reconfiguring mixer with width : %d, height : %d", width, height);
1212 HWMixerAttributes mixer_attributes;
1213 mixer_attributes.width = width;
1214 mixer_attributes.height = height;
1215
1216 error = hw_intf_->SetMixerAttributes(mixer_attributes);
1217 if (error != kErrorNone) {
1218 return error;
1219 }
1220
1221 return ReconfigureDisplay();
1222 }
1223
NeedsDownScale(const LayerRect & src_rect,const LayerRect & dst_rect,bool needs_rotation)1224 bool DisplayBase::NeedsDownScale(const LayerRect &src_rect, const LayerRect &dst_rect,
1225 bool needs_rotation) {
1226 float src_width = FLOAT(src_rect.right - src_rect.left);
1227 float src_height = FLOAT(src_rect.bottom - src_rect.top);
1228 float dst_width = FLOAT(dst_rect.right - dst_rect.left);
1229 float dst_height = FLOAT(dst_rect.bottom - dst_rect.top);
1230
1231 if (needs_rotation) {
1232 std::swap(src_width, src_height);
1233 }
1234
1235 if ((src_width > dst_width) || (src_height > dst_height)) {
1236 return true;
1237 }
1238
1239 return false;
1240 }
1241
NeedsMixerReconfiguration(LayerStack * layer_stack,uint32_t * new_mixer_width,uint32_t * new_mixer_height)1242 bool DisplayBase::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
1243 uint32_t *new_mixer_height) {
1244 lock_guard<recursive_mutex> obj(recursive_mutex_);
1245 uint32_t mixer_width = mixer_attributes_.width;
1246 uint32_t mixer_height = mixer_attributes_.height;
1247
1248 if (req_mixer_width_ && req_mixer_height_) {
1249 DLOGD_IF(kTagDisplay, "Required mixer width : %d, height : %d",
1250 req_mixer_width_, req_mixer_height_);
1251 *new_mixer_width = req_mixer_width_;
1252 *new_mixer_height = req_mixer_height_;
1253 return (req_mixer_width_ != mixer_width || req_mixer_height_ != mixer_height);
1254 }
1255
1256 if (!custom_mixer_resolution_) {
1257 return false;
1258 }
1259
1260 uint32_t layer_count = UINT32(layer_stack->layers.size());
1261 uint32_t fb_width = fb_config_.x_pixels;
1262 uint32_t fb_height = fb_config_.y_pixels;
1263 uint32_t fb_area = fb_width * fb_height;
1264 LayerRect fb_rect = (LayerRect) {0.0f, 0.0f, FLOAT(fb_width), FLOAT(fb_height)};
1265 uint32_t display_width = display_attributes_.x_pixels;
1266 uint32_t display_height = display_attributes_.y_pixels;
1267
1268 RectOrientation fb_orientation = GetOrientation(fb_rect);
1269 uint32_t max_layer_area = 0;
1270 uint32_t max_area_layer_index = 0;
1271 std::vector<Layer *> layers = layer_stack->layers;
1272 uint32_t align_x = display_attributes_.is_device_split ? 4 : 2;
1273 uint32_t align_y = 2;
1274
1275 for (uint32_t i = 0; i < layer_count; i++) {
1276 Layer *layer = layers.at(i);
1277
1278 uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
1279 uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
1280 uint32_t layer_area = layer_width * layer_height;
1281
1282 if (layer_area > max_layer_area) {
1283 max_layer_area = layer_area;
1284 max_area_layer_index = i;
1285 }
1286 }
1287 DLOGV_IF(kTagDisplay, "Max area layer at index : %d", max_area_layer_index);
1288
1289 // TODO(user): Mark layer which needs downscaling on GPU fallback as priority layer and use MDP
1290 // for composition to avoid quality mismatch between GPU and MDP switch(idle timeout usecase).
1291 if (max_layer_area >= fb_area) {
1292 Layer *layer = layers.at(max_area_layer_index);
1293 bool needs_rotation = (layer->transform.rotation == 90.0f);
1294
1295 uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
1296 uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
1297 LayerRect layer_dst_rect = {};
1298
1299 RectOrientation layer_orientation = GetOrientation(layer->src_rect);
1300 if (layer_orientation != kOrientationUnknown &&
1301 fb_orientation != kOrientationUnknown) {
1302 if (layer_orientation != fb_orientation) {
1303 std::swap(layer_width, layer_height);
1304 }
1305 }
1306
1307 // Align the width and height according to fb's aspect ratio
1308 *new_mixer_width = FloorToMultipleOf(UINT32((FLOAT(fb_width) / FLOAT(fb_height)) *
1309 layer_height), align_x);
1310 *new_mixer_height = FloorToMultipleOf(layer_height, align_y);
1311
1312 LayerRect dst_domain = {0.0f, 0.0f, FLOAT(*new_mixer_width), FLOAT(*new_mixer_height)};
1313
1314 MapRect(fb_rect, dst_domain, layer->dst_rect, &layer_dst_rect);
1315 if (NeedsDownScale(layer->src_rect, layer_dst_rect, needs_rotation)) {
1316 *new_mixer_width = display_width;
1317 *new_mixer_height = display_height;
1318 }
1319 if (*new_mixer_width > display_width || *new_mixer_height > display_height) {
1320 *new_mixer_width = display_width;
1321 *new_mixer_height = display_height;
1322 }
1323 return ((*new_mixer_width != mixer_width) || (*new_mixer_height != mixer_height));
1324 }
1325
1326 return false;
1327 }
1328
SetFrameBufferConfig(const DisplayConfigVariableInfo & variable_info)1329 DisplayError DisplayBase::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) {
1330 lock_guard<recursive_mutex> obj(recursive_mutex_);
1331 uint32_t width = variable_info.x_pixels;
1332 uint32_t height = variable_info.y_pixels;
1333
1334 if (width == 0 || height == 0) {
1335 DLOGE("Unsupported resolution: (%dx%d)", width, height);
1336 return kErrorParameters;
1337 }
1338
1339 // Create rects to represent the new source and destination crops
1340 LayerRect crop = LayerRect(0, 0, FLOAT(width), FLOAT(height));
1341 LayerRect dst = LayerRect(0, 0, FLOAT(mixer_attributes_.width), FLOAT(mixer_attributes_.height));
1342 // Set rotate90 to false since this is taken care of during regular composition.
1343 bool rotate90 = false;
1344
1345 DisplayError error = comp_manager_->ValidateScaling(crop, dst, rotate90);
1346 if (error != kErrorNone) {
1347 DLOGE("Unsupported resolution: (%dx%d)", width, height);
1348 return kErrorParameters;
1349 }
1350
1351 error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_, hw_panel_info_,
1352 mixer_attributes_, variable_info,
1353 &(default_qos_data_.clock_hz));
1354 if (error != kErrorNone) {
1355 return error;
1356 }
1357
1358 fb_config_.x_pixels = width;
1359 fb_config_.y_pixels = height;
1360
1361 DLOGI("New framebuffer resolution (%dx%d)", fb_config_.x_pixels, fb_config_.y_pixels);
1362
1363 return kErrorNone;
1364 }
1365
GetFrameBufferConfig(DisplayConfigVariableInfo * variable_info)1366 DisplayError DisplayBase::GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) {
1367 lock_guard<recursive_mutex> obj(recursive_mutex_);
1368 if (!variable_info) {
1369 return kErrorParameters;
1370 }
1371
1372 *variable_info = fb_config_;
1373
1374 return kErrorNone;
1375 }
1376
SetDetailEnhancerData(const DisplayDetailEnhancerData & de_data)1377 DisplayError DisplayBase::SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) {
1378 lock_guard<recursive_mutex> obj(recursive_mutex_);
1379 DisplayError error = comp_manager_->SetDetailEnhancerData(display_comp_ctx_, de_data);
1380 if (error != kErrorNone) {
1381 return error;
1382 }
1383 // TODO(user): Temporary changes, to be removed when DRM driver supports
1384 // Partial update with Destination scaler enabled.
1385 if (GetDriverType() == DriverType::DRM) {
1386 if (de_data.enable) {
1387 disable_pu_on_dest_scaler_ = true;
1388 } else {
1389 SetPUonDestScaler();
1390 }
1391 } else {
1392 DisablePartialUpdateOneFrame();
1393 }
1394
1395 return kErrorNone;
1396 }
1397
GetDisplayPort(DisplayPort * port)1398 DisplayError DisplayBase::GetDisplayPort(DisplayPort *port) {
1399 lock_guard<recursive_mutex> obj(recursive_mutex_);
1400
1401 if (!port) {
1402 return kErrorParameters;
1403 }
1404
1405 *port = hw_panel_info_.port;
1406
1407 return kErrorNone;
1408 }
1409
GetDisplayId(int32_t * display_id)1410 DisplayError DisplayBase::GetDisplayId(int32_t *display_id) {
1411 lock_guard<recursive_mutex> obj(recursive_mutex_);
1412
1413 if (!display_id) {
1414 return kErrorParameters;
1415 }
1416
1417 *display_id = display_id_;
1418
1419 return kErrorNone;
1420 }
1421
GetDisplayType(DisplayType * display_type)1422 DisplayError DisplayBase::GetDisplayType(DisplayType *display_type) {
1423 lock_guard<recursive_mutex> obj(recursive_mutex_);
1424
1425 if (!display_type) {
1426 return kErrorParameters;
1427 }
1428
1429 *display_type = display_type_;
1430
1431 return kErrorNone;
1432 }
1433
IsPrimaryDisplay()1434 bool DisplayBase::IsPrimaryDisplay() {
1435 lock_guard<recursive_mutex> obj(recursive_mutex_);
1436
1437 return hw_panel_info_.is_primary_panel;
1438 }
1439
SetCompositionState(LayerComposition composition_type,bool enable)1440 DisplayError DisplayBase::SetCompositionState(LayerComposition composition_type, bool enable) {
1441 lock_guard<recursive_mutex> obj(recursive_mutex_);
1442
1443 return comp_manager_->SetCompositionState(display_comp_ctx_, composition_type, enable);
1444 }
1445
CommitLayerParams(LayerStack * layer_stack)1446 void DisplayBase::CommitLayerParams(LayerStack *layer_stack) {
1447 // Copy the acquire fence from clients layers to HWLayers
1448 uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size());
1449
1450 for (uint32_t i = 0; i < hw_layers_count; i++) {
1451 uint32_t sdm_layer_index = hw_layers_.info.index.at(i);
1452 Layer *sdm_layer = layer_stack->layers.at(sdm_layer_index);
1453 Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
1454
1455 hw_layer.input_buffer.planes[0].fd = sdm_layer->input_buffer.planes[0].fd;
1456 hw_layer.input_buffer.planes[0].offset = sdm_layer->input_buffer.planes[0].offset;
1457 hw_layer.input_buffer.planes[0].stride = sdm_layer->input_buffer.planes[0].stride;
1458 hw_layer.input_buffer.size = sdm_layer->input_buffer.size;
1459 hw_layer.input_buffer.acquire_fence_fd = sdm_layer->input_buffer.acquire_fence_fd;
1460 hw_layer.input_buffer.handle_id = sdm_layer->input_buffer.handle_id;
1461 // TODO(user): Other FBT layer attributes like surface damage, dataspace, secure camera and
1462 // secure display flags are also updated during SetClientTarget() called between validate and
1463 // commit. Need to revist this and update it accordingly for FBT layer.
1464 if (hw_layers_.info.gpu_target_index == sdm_layer_index) {
1465 hw_layer.input_buffer.flags.secure = sdm_layer->input_buffer.flags.secure;
1466 hw_layer.input_buffer.format = sdm_layer->input_buffer.format;
1467 hw_layer.input_buffer.width = sdm_layer->input_buffer.width;
1468 hw_layer.input_buffer.height = sdm_layer->input_buffer.height;
1469 hw_layer.input_buffer.unaligned_width = sdm_layer->input_buffer.unaligned_width;
1470 hw_layer.input_buffer.unaligned_height = sdm_layer->input_buffer.unaligned_height;
1471 }
1472 }
1473
1474 return;
1475 }
1476
PostCommitLayerParams(LayerStack * layer_stack)1477 void DisplayBase::PostCommitLayerParams(LayerStack *layer_stack) {
1478 // Copy the release fence from HWLayers to clients layers
1479 uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size());
1480
1481 std::vector<uint32_t> fence_dup_flag;
1482
1483 for (uint32_t i = 0; i < hw_layers_count; i++) {
1484 uint32_t sdm_layer_index = hw_layers_.info.index.at(i);
1485 Layer *sdm_layer = layer_stack->layers.at(sdm_layer_index);
1486 Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
1487
1488 // Copy the release fence only once for a SDM Layer.
1489 // In S3D use case, two hw layers can share the same input buffer, So make sure to merge the
1490 // output fence fd and assign it to layer's input buffer release fence fd.
1491 if (std::find(fence_dup_flag.begin(), fence_dup_flag.end(), sdm_layer_index) ==
1492 fence_dup_flag.end()) {
1493 sdm_layer->input_buffer.release_fence_fd = hw_layer.input_buffer.release_fence_fd;
1494 fence_dup_flag.push_back(sdm_layer_index);
1495 } else {
1496 int temp = -1;
1497 buffer_sync_handler_->SyncMerge(hw_layer.input_buffer.release_fence_fd,
1498 sdm_layer->input_buffer.release_fence_fd, &temp);
1499
1500 if (hw_layer.input_buffer.release_fence_fd >= 0) {
1501 Sys::close_(hw_layer.input_buffer.release_fence_fd);
1502 hw_layer.input_buffer.release_fence_fd = -1;
1503 }
1504
1505 if (sdm_layer->input_buffer.release_fence_fd >= 0) {
1506 Sys::close_(sdm_layer->input_buffer.release_fence_fd);
1507 sdm_layer->input_buffer.release_fence_fd = -1;
1508 }
1509
1510 sdm_layer->input_buffer.release_fence_fd = temp;
1511 }
1512 }
1513
1514 return;
1515 }
1516
InitializeColorModes()1517 DisplayError DisplayBase::InitializeColorModes() {
1518 if (!color_mgr_) {
1519 return kErrorNotSupported;
1520 }
1521
1522 DisplayError error = color_mgr_->ColorMgrGetNumOfModes(&num_color_modes_);
1523 if (error != kErrorNone || !num_color_modes_) {
1524 DLOGV_IF(kTagQDCM, "GetNumModes failed = %d count = %d", error, num_color_modes_);
1525 return kErrorNotSupported;
1526 }
1527 DLOGI("Number of Color Modes = %d", num_color_modes_);
1528
1529 if (!color_modes_.size()) {
1530 color_modes_.resize(num_color_modes_);
1531
1532 DisplayError error = color_mgr_->ColorMgrGetModes(&num_color_modes_, color_modes_.data());
1533 if (error != kErrorNone) {
1534 color_modes_.clear();
1535 DLOGE("Failed");
1536 return error;
1537 }
1538 int32_t default_id = kInvalidModeId;
1539 error = color_mgr_->ColorMgrGetDefaultModeID(&default_id);
1540
1541 AttrVal var;
1542 for (uint32_t i = 0; i < num_color_modes_; i++) {
1543 DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
1544 color_modes_[i].id);
1545 // get the name of default color mode
1546 if (color_modes_[i].id == default_id) {
1547 current_color_mode_ = color_modes_[i].name;
1548 }
1549 auto it = color_mode_map_.find(color_modes_[i].name);
1550 if (it != color_mode_map_.end()) {
1551 if (it->second->id < color_modes_[i].id) {
1552 color_mode_map_.erase(it);
1553 color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
1554 }
1555 } else {
1556 color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
1557 }
1558
1559 var.clear();
1560 error = color_mgr_->ColorMgrGetModeInfo(color_modes_[i].id, &var);
1561 if (error != kErrorNone) {
1562 DLOGE("Failed for get attributes of mode_id = %d", color_modes_[i].id);
1563 continue;
1564 }
1565 if (!var.empty()) {
1566 auto it = color_mode_attr_map_.find(color_modes_[i].name);
1567 if (it == color_mode_attr_map_.end()) {
1568 color_mode_attr_map_.insert(std::make_pair(color_modes_[i].name, var));
1569 // If target doesn't support SSPP tone maping and color mode is HDR,
1570 // add bt2020pq and bt2020hlg color modes.
1571 if (hw_resource_info_.src_tone_map.none() && IsHdrMode(var)) {
1572 color_mode_map_.insert(std::make_pair(kBt2020Pq, &color_modes_[i]));
1573 color_mode_map_.insert(std::make_pair(kBt2020Hlg, &color_modes_[i]));
1574 InsertBT2020PqHlgModes();
1575 }
1576 }
1577 std::vector<PrimariesTransfer> pt_list = {};
1578 GetColorPrimaryTransferFromAttributes(var, &pt_list);
1579 for (const PrimariesTransfer &pt : pt_list) {
1580 if (std::find(color_modes_cs_.begin(), color_modes_cs_.end(), pt) ==
1581 color_modes_cs_.end()) {
1582 color_modes_cs_.push_back(pt);
1583 }
1584 }
1585 }
1586 }
1587 PrimariesTransfer pt = {};
1588 if (std::find(color_modes_cs_.begin(), color_modes_cs_.end(), pt) ==
1589 color_modes_cs_.end()) {
1590 color_modes_cs_.push_back(pt);
1591 }
1592 }
1593
1594 return kErrorNone;
1595 }
1596
GetDisplayIdentificationData(uint8_t * out_port,uint32_t * out_data_size,uint8_t * out_data)1597 DisplayError DisplayBase::GetDisplayIdentificationData(uint8_t *out_port, uint32_t *out_data_size,
1598 uint8_t *out_data) {
1599 if (!out_port || !out_data_size) {
1600 return kErrorParameters;
1601 }
1602
1603 return hw_intf_->GetDisplayIdentificationData(out_port, out_data_size, out_data);
1604 }
1605
GetClientTargetSupport(uint32_t width,uint32_t height,LayerBufferFormat format,const ColorMetaData & color_metadata)1606 DisplayError DisplayBase::GetClientTargetSupport(uint32_t width, uint32_t height,
1607 LayerBufferFormat format,
1608 const ColorMetaData &color_metadata) {
1609 if (format != kFormatRGBA8888 && format != kFormatRGBA1010102) {
1610 DLOGW("Unsupported format = %d", format);
1611 return kErrorNotSupported;
1612 } else if (ValidateScaling(width, height) != kErrorNone) {
1613 DLOGW("Unsupported width = %d height = %d", width, height);
1614 return kErrorNotSupported;
1615 } else if (color_metadata.transfer && color_metadata.colorPrimaries) {
1616 DisplayError error = ValidateDataspace(color_metadata);
1617 if (error != kErrorNone) {
1618 DLOGW("Unsupported Transfer Request = %d Color Primary = %d",
1619 color_metadata.transfer, color_metadata.colorPrimaries);
1620 return error;
1621 }
1622
1623 // Check for BT2020 support
1624 if (color_metadata.colorPrimaries == ColorPrimaries_BT2020) {
1625 DLOGW("Unsupported Color Primary = %d", color_metadata.colorPrimaries);
1626 return kErrorNotSupported;
1627 }
1628 }
1629
1630 return kErrorNone;
1631 }
1632
IsSupportSsppTonemap()1633 bool DisplayBase::IsSupportSsppTonemap() {
1634 if (hw_resource_info_.src_tone_map.none()) {
1635 return false;
1636 } else {
1637 return true;
1638 }
1639 }
1640
ValidateScaling(uint32_t width,uint32_t height)1641 DisplayError DisplayBase::ValidateScaling(uint32_t width, uint32_t height) {
1642 uint32_t display_width = display_attributes_.x_pixels;
1643 uint32_t display_height = display_attributes_.y_pixels;
1644
1645 float max_scale_down = FLOAT(hw_resource_info_.max_scale_down);
1646 float max_scale_up = FLOAT(hw_resource_info_.max_scale_up);
1647
1648 float scale_x = FLOAT(width / display_width);
1649 float scale_y = FLOAT(height / display_height);
1650
1651 if (scale_x > max_scale_down || scale_y > max_scale_down) {
1652 return kErrorNotSupported;
1653 }
1654
1655 if (UINT32(scale_x) < 1 && scale_x > 0.0f) {
1656 if ((1.0f / scale_x) > max_scale_up) {
1657 return kErrorNotSupported;
1658 }
1659 }
1660
1661 if (UINT32(scale_y) < 1 && scale_y > 0.0f) {
1662 if ((1.0f / scale_y) > max_scale_up) {
1663 return kErrorNotSupported;
1664 }
1665 }
1666
1667 return kErrorNone;
1668 }
1669
ValidateDataspace(const ColorMetaData & color_metadata)1670 DisplayError DisplayBase::ValidateDataspace(const ColorMetaData &color_metadata) {
1671 // Handle transfer
1672 switch (color_metadata.transfer) {
1673 case Transfer_sRGB:
1674 case Transfer_SMPTE_170M:
1675 case Transfer_SMPTE_ST2084:
1676 case Transfer_HLG:
1677 case Transfer_Linear:
1678 case Transfer_Gamma2_2:
1679 break;
1680 default:
1681 DLOGW("Unsupported Transfer Request = %d", color_metadata.transfer);
1682 return kErrorNotSupported;
1683 }
1684
1685 // Handle colorPrimaries
1686 switch (color_metadata.colorPrimaries) {
1687 case ColorPrimaries_BT709_5:
1688 case ColorPrimaries_BT601_6_525:
1689 case ColorPrimaries_BT601_6_625:
1690 case ColorPrimaries_DCIP3:
1691 case ColorPrimaries_BT2020:
1692 break;
1693 default:
1694 DLOGW("Unsupported Color Primary = %d", color_metadata.colorPrimaries);
1695 return kErrorNotSupported;
1696 }
1697
1698 return kErrorNone;
1699 }
1700
1701 // TODO(user): Temporary changes, to be removed when DRM driver supports
1702 // Partial update with Destination scaler enabled.
SetPUonDestScaler()1703 void DisplayBase::SetPUonDestScaler() {
1704 if (GetDriverType() == DriverType::FB) {
1705 return;
1706 }
1707 uint32_t mixer_width = mixer_attributes_.width;
1708 uint32_t mixer_height = mixer_attributes_.height;
1709 uint32_t display_width = display_attributes_.x_pixels;
1710 uint32_t display_height = display_attributes_.y_pixels;
1711
1712 disable_pu_on_dest_scaler_ = (mixer_width != display_width ||
1713 mixer_height != display_height);
1714 }
1715
ClearColorInfo()1716 void DisplayBase::ClearColorInfo() {
1717 color_modes_.clear();
1718 color_mode_map_.clear();
1719 color_mode_attr_map_.clear();
1720 color_modes_cs_.clear();
1721
1722 if (color_mgr_) {
1723 delete color_mgr_;
1724 color_mgr_ = NULL;
1725 }
1726 }
1727
DeInitializeColorModes()1728 void DisplayBase::DeInitializeColorModes() {
1729 color_mode_map_.clear();
1730 color_modes_.clear();
1731 color_mode_attr_map_.clear();
1732 num_color_modes_ = 0;
1733 }
1734
GetColorPrimaryTransferFromAttributes(const AttrVal & attr,std::vector<PrimariesTransfer> * supported_pt)1735 void DisplayBase::GetColorPrimaryTransferFromAttributes(const AttrVal &attr,
1736 std::vector<PrimariesTransfer> *supported_pt) {
1737 std::string attribute_field = {};
1738 if (attr.empty()) {
1739 return;
1740 }
1741
1742 for (auto &it : attr) {
1743 if ((it.first.find(kColorGamutAttribute) != std::string::npos) ||
1744 (it.first.find(kDynamicRangeAttribute) != std::string::npos)) {
1745 attribute_field = it.second;
1746 PrimariesTransfer pt = {};
1747 pt.primaries = GetColorPrimariesFromAttribute(attribute_field);
1748 if (pt.primaries == ColorPrimaries_BT709_5) {
1749 pt.transfer = Transfer_sRGB;
1750 supported_pt->push_back(pt);
1751 } else if (pt.primaries == ColorPrimaries_DCIP3) {
1752 pt.transfer = Transfer_sRGB;
1753 supported_pt->push_back(pt);
1754 } else if (pt.primaries == ColorPrimaries_BT2020) {
1755 pt.transfer = Transfer_SMPTE_ST2084;
1756 supported_pt->push_back(pt);
1757 pt.transfer = Transfer_HLG;
1758 supported_pt->push_back(pt);
1759 }
1760 }
1761 }
1762 }
1763
HwRecovery(const HWRecoveryEvent sdm_event_code)1764 void DisplayBase::HwRecovery(const HWRecoveryEvent sdm_event_code) {
1765 DLOGI("Handling event = %" PRIu32, sdm_event_code);
1766 if (DisplayPowerResetPending()) {
1767 DLOGI("Skipping handling for display = %d, display power reset in progress", display_type_);
1768 return;
1769 }
1770 switch (sdm_event_code) {
1771 case HWRecoveryEvent::kSuccess:
1772 hw_recovery_logs_captured_ = false;
1773 break;
1774 case HWRecoveryEvent::kCapture:
1775 if (!disable_hw_recovery_dump_ && !hw_recovery_logs_captured_) {
1776 hw_intf_->DumpDebugData();
1777 hw_recovery_logs_captured_ = true;
1778 DLOGI("Captured debugfs data for display = %d", display_type_);
1779 } else if (!disable_hw_recovery_dump_) {
1780 DLOGI("Multiple capture events without intermediate success event, skipping debugfs"
1781 "capture for display = %d", display_type_);
1782 } else {
1783 DLOGI("Debugfs data dumping is disabled for display = %d", display_type_);
1784 }
1785 break;
1786 case HWRecoveryEvent::kDisplayPowerReset:
1787 DLOGI("display = %d attempting to start display power reset", display_type_);
1788 if (StartDisplayPowerReset()) {
1789 DLOGI("display = %d allowed to start display power reset", display_type_);
1790 event_handler_->HandleEvent(kDisplayPowerResetEvent);
1791 EndDisplayPowerReset();
1792 DLOGI("display = %d has finished display power reset", display_type_);
1793 }
1794 break;
1795 default:
1796 return;
1797 }
1798 }
1799
DisplayPowerResetPending()1800 bool DisplayBase::DisplayPowerResetPending() {
1801 SCOPE_LOCK(display_power_reset_lock_);
1802 return display_power_reset_pending_;
1803 }
1804
StartDisplayPowerReset()1805 bool DisplayBase::StartDisplayPowerReset() {
1806 SCOPE_LOCK(display_power_reset_lock_);
1807 if (!display_power_reset_pending_) {
1808 display_power_reset_pending_ = true;
1809 return true;
1810 }
1811 return false;
1812 }
1813
EndDisplayPowerReset()1814 void DisplayBase::EndDisplayPowerReset() {
1815 SCOPE_LOCK(display_power_reset_lock_);
1816 display_power_reset_pending_ = false;
1817 }
1818
SetHdrModeAtStart(LayerStack * layer_stack)1819 bool DisplayBase::SetHdrModeAtStart(LayerStack *layer_stack) {
1820 return (hw_resource_info_.src_tone_map.none() && layer_stack->flags.hdr_present);
1821 }
1822
GetBlendSpaceFromColorMode()1823 PrimariesTransfer DisplayBase::GetBlendSpaceFromColorMode() {
1824 PrimariesTransfer pt = {};
1825 auto current_color_attr_ = color_mode_attr_map_.find(current_color_mode_);
1826 AttrVal attr = current_color_attr_->second;
1827 std::string color_gamut = kNative, dynamic_range = kSdr, pic_quality = kStandard;
1828 std::string transfer = {};
1829
1830 if (attr.begin() != attr.end()) {
1831 for (auto &it : attr) {
1832 if (it.first.find(kColorGamutAttribute) != std::string::npos) {
1833 color_gamut = it.second;
1834 } else if (it.first.find(kDynamicRangeAttribute) != std::string::npos) {
1835 dynamic_range = it.second;
1836 } else if (it.first.find(kPictureQualityAttribute) != std::string::npos) {
1837 pic_quality = it.second;
1838 } else if (it.first.find(kGammaTransferAttribute) != std::string::npos) {
1839 transfer = it.second;
1840 }
1841 }
1842 }
1843 // TODO(user): Check is if someone calls with hal_display_p3
1844 if (hw_resource_info_.src_tone_map.none() &&
1845 (pic_quality == kStandard && color_gamut == kBt2020)) {
1846 pt.primaries = GetColorPrimariesFromAttribute(color_gamut);
1847 if (transfer == kHlg) {
1848 pt.transfer = Transfer_HLG;
1849 } else {
1850 pt.transfer = Transfer_SMPTE_ST2084;
1851 }
1852 } else if (color_gamut == kDcip3) {
1853 pt.primaries = GetColorPrimariesFromAttribute(color_gamut);
1854 pt.transfer = Transfer_sRGB;
1855 }
1856
1857 return pt;
1858 }
1859
InsertBT2020PqHlgModes()1860 void DisplayBase::InsertBT2020PqHlgModes() {
1861 AttrVal hdr_var = {};
1862 hdr_var.push_back(std::make_pair(kColorGamutAttribute, kBt2020));
1863 hdr_var.push_back(std::make_pair(kPictureQualityAttribute, kStandard));
1864 hdr_var.push_back(std::make_pair(kGammaTransferAttribute, kSt2084));
1865 color_mode_attr_map_.insert(std::make_pair(kBt2020Pq, hdr_var));
1866 hdr_var.pop_back();
1867 hdr_var.push_back(std::make_pair(kGammaTransferAttribute, kHlg));
1868 color_mode_attr_map_.insert(std::make_pair(kBt2020Hlg, hdr_var));
1869
1870 return;
1871 }
1872
IsHdrMode(const AttrVal & attr)1873 bool DisplayBase::IsHdrMode(const AttrVal &attr) {
1874 std::string color_gamut, dynamic_range;
1875 GetValueOfModeAttribute(attr, kColorGamutAttribute, &color_gamut);
1876 GetValueOfModeAttribute(attr, kDynamicRangeAttribute, &dynamic_range);
1877 if (color_gamut == kDcip3 && dynamic_range == kHdr) {
1878 return true;
1879 }
1880
1881 return false;
1882 }
1883
colorSamplingOn()1884 DisplayError DisplayBase::colorSamplingOn() {
1885 return kErrorNone;
1886 }
1887
colorSamplingOff()1888 DisplayError DisplayBase::colorSamplingOff() {
1889 return kErrorNone;
1890 }
1891
1892 } // namespace sdm
1893