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