Home | History | Annotate | Download | only in core
      1 /*
      2 * Copyright (c) 2014 - 2017, 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 <string>
     31 #include <vector>
     32 #include <algorithm>
     33 
     34 #include "display_base.h"
     35 #include "hw_info_interface.h"
     36 
     37 #define __CLASS__ "DisplayBase"
     38 
     39 namespace sdm {
     40 
     41 // TODO(user): Have a single structure handle carries all the interface pointers and variables.
     42 DisplayBase::DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
     43                          HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
     44                          BufferAllocator *buffer_allocator, CompManager *comp_manager,
     45                          HWInfoInterface *hw_info_intf)
     46   : display_type_(display_type), event_handler_(event_handler), hw_device_type_(hw_device_type),
     47     buffer_sync_handler_(buffer_sync_handler), buffer_allocator_(buffer_allocator),
     48     comp_manager_(comp_manager), hw_info_intf_(hw_info_intf) {
     49 }
     50 
     51 DisplayError DisplayBase::Init() {
     52   lock_guard<recursive_mutex> obj(recursive_mutex_);
     53   DisplayError error = kErrorNone;
     54   hw_panel_info_ = HWPanelInfo();
     55   hw_intf_->GetHWPanelInfo(&hw_panel_info_);
     56 
     57   uint32_t active_index = 0;
     58   hw_intf_->GetActiveConfig(&active_index);
     59   hw_intf_->GetDisplayAttributes(active_index, &display_attributes_);
     60   fb_config_ = display_attributes_;
     61 
     62   error = Debug::GetMixerResolution(&mixer_attributes_.width, &mixer_attributes_.height);
     63   if (error == kErrorNone) {
     64     hw_intf_->SetMixerAttributes(mixer_attributes_);
     65   }
     66 
     67   error = hw_intf_->GetMixerAttributes(&mixer_attributes_);
     68   if (error != kErrorNone) {
     69     return error;
     70   }
     71 
     72   // Override x_pixels and y_pixels of frame buffer with mixer width and height
     73   fb_config_.x_pixels = mixer_attributes_.width;
     74   fb_config_.y_pixels = mixer_attributes_.height;
     75 
     76   HWScaleLutInfo lut_info = {};
     77   error = comp_manager_->GetScaleLutConfig(&lut_info);
     78   if (error == kErrorNone) {
     79     error = hw_intf_->SetScaleLutConfig(&lut_info);
     80     if (error != kErrorNone) {
     81       goto CleanupOnError;
     82     }
     83   }
     84 
     85   error = comp_manager_->RegisterDisplay(display_type_, display_attributes_, hw_panel_info_,
     86                                          mixer_attributes_, fb_config_, &display_comp_ctx_);
     87   if (error != kErrorNone) {
     88     goto CleanupOnError;
     89   }
     90 
     91   if (hw_info_intf_) {
     92     HWResourceInfo hw_resource_info = HWResourceInfo();
     93     hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
     94     auto max_mixer_stages = hw_resource_info.num_blending_stages;
     95     int property_value = Debug::GetMaxPipesPerMixer(display_type_);
     96     if (property_value >= 0) {
     97       max_mixer_stages = std::min(UINT32(property_value), hw_resource_info.num_blending_stages);
     98     }
     99     DisplayBase::SetMaxMixerStages(max_mixer_stages);
    100   }
    101 
    102   color_mgr_ = ColorManagerProxy::CreateColorManagerProxy(display_type_, hw_intf_,
    103                                display_attributes_, hw_panel_info_);
    104   if (!color_mgr_) {
    105     DLOGW("Unable to create ColorManagerProxy for display = %d", display_type_);
    106   } else if (InitializeColorModes() != kErrorNone) {
    107     DLOGW("InitColorModes failed for display = %d", display_type_);
    108   }
    109 
    110   Debug::Get()->GetProperty("sdm.disable_hdr_lut_gen", &disable_hdr_lut_gen_);
    111 
    112   return kErrorNone;
    113 
    114 CleanupOnError:
    115   if (display_comp_ctx_) {
    116     comp_manager_->UnregisterDisplay(display_comp_ctx_);
    117   }
    118 
    119   return error;
    120 }
    121 
    122 DisplayError DisplayBase::Deinit() {
    123   {  // Scope for lock
    124     lock_guard<recursive_mutex> obj(recursive_mutex_);
    125     color_modes_.clear();
    126     color_mode_map_.clear();
    127     color_mode_attr_map_.clear();
    128 
    129     if (color_mgr_) {
    130       delete color_mgr_;
    131       color_mgr_ = NULL;
    132     }
    133 
    134     comp_manager_->UnregisterDisplay(display_comp_ctx_);
    135   }
    136   HWEventsInterface::Destroy(hw_events_intf_);
    137   HWInterface::Destroy(hw_intf_);
    138 
    139   return kErrorNone;
    140 }
    141 
    142 DisplayError DisplayBase::BuildLayerStackStats(LayerStack *layer_stack) {
    143   std::vector<Layer *> &layers = layer_stack->layers;
    144   HWLayersInfo &hw_layers_info = hw_layers_.info;
    145 
    146   hw_layers_info.stack = layer_stack;
    147 
    148   for (auto &layer : layers) {
    149     if (layer->composition == kCompositionGPUTarget) {
    150       hw_layers_info.gpu_target_index = hw_layers_info.app_layer_count;
    151       break;
    152     }
    153     hw_layers_info.app_layer_count++;
    154   }
    155 
    156   DLOGV_IF(kTagNone, "LayerStack layer_count: %d, app_layer_count: %d, gpu_target_index: %d, "
    157            "display type: %d", layers.size(), hw_layers_info.app_layer_count,
    158            hw_layers_info.gpu_target_index, display_type_);
    159 
    160   if (!hw_layers_info.app_layer_count) {
    161     DLOGW("Layer count is zero");
    162     return kErrorNoAppLayers;
    163   }
    164 
    165   if (hw_layers_info.gpu_target_index) {
    166     return ValidateGPUTargetParams();
    167   }
    168 
    169   return kErrorNone;
    170 }
    171 
    172 DisplayError DisplayBase::ValidateGPUTargetParams() {
    173   HWLayersInfo &hw_layers_info = hw_layers_.info;
    174   Layer *gpu_target_layer = hw_layers_info.stack->layers.at(hw_layers_info.gpu_target_index);
    175 
    176   if (!IsValid(gpu_target_layer->src_rect)) {
    177     DLOGE("Invalid src rect for GPU target layer");
    178     return kErrorParameters;
    179   }
    180 
    181   if (!IsValid(gpu_target_layer->dst_rect)) {
    182     DLOGE("Invalid dst rect for GPU target layer");
    183     return kErrorParameters;
    184   }
    185 
    186   float layer_mixer_width = FLOAT(mixer_attributes_.width);
    187   float layer_mixer_height = FLOAT(mixer_attributes_.height);
    188   float fb_width = FLOAT(fb_config_.x_pixels);
    189   float fb_height = FLOAT(fb_config_.y_pixels);
    190   LayerRect src_domain = (LayerRect){0.0f, 0.0f, fb_width, fb_height};
    191   LayerRect dst_domain = (LayerRect){0.0f, 0.0f, layer_mixer_width, layer_mixer_height};
    192   LayerRect out_rect = gpu_target_layer->dst_rect;
    193 
    194   MapRect(src_domain, dst_domain, gpu_target_layer->dst_rect, &out_rect);
    195   Normalize(1, 1, &out_rect);
    196 
    197   auto gpu_target_layer_dst_xpixels = out_rect.right - out_rect.left;
    198   auto gpu_target_layer_dst_ypixels = out_rect.bottom - out_rect.top;
    199 
    200   if (gpu_target_layer_dst_xpixels > mixer_attributes_.width ||
    201     gpu_target_layer_dst_ypixels > mixer_attributes_.height) {
    202     DLOGE("GPU target layer dst rect is not with in limits gpu wxh %fx%f, mixer wxh %dx%d",
    203                   gpu_target_layer_dst_xpixels, gpu_target_layer_dst_ypixels,
    204                   mixer_attributes_.width, mixer_attributes_.height);
    205     return kErrorParameters;
    206   }
    207 
    208   return kErrorNone;
    209 }
    210 
    211 DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
    212   lock_guard<recursive_mutex> obj(recursive_mutex_);
    213   DisplayError error = kErrorNone;
    214 
    215   if (!active_) {
    216     return kErrorPermission;
    217   }
    218 
    219   if (!layer_stack) {
    220     return kErrorParameters;
    221   }
    222 
    223   error = BuildLayerStackStats(layer_stack);
    224   if (error != kErrorNone) {
    225     return error;
    226   }
    227 
    228   error = HandleHDR(layer_stack);
    229   if (error != kErrorNone) {
    230     DLOGW("HandleHDR failed");
    231     return error;
    232   }
    233 
    234   if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) {
    235     DisablePartialUpdateOneFrame();
    236   }
    237 
    238   if (partial_update_control_ == false || disable_pu_one_frame_) {
    239     comp_manager_->ControlPartialUpdate(display_comp_ctx_, false /* enable */);
    240     disable_pu_one_frame_ = false;
    241   }
    242 
    243   comp_manager_->PrePrepare(display_comp_ctx_, &hw_layers_);
    244   while (true) {
    245     error = comp_manager_->Prepare(display_comp_ctx_, &hw_layers_);
    246     if (error != kErrorNone) {
    247       break;
    248     }
    249 
    250     error = hw_intf_->Validate(&hw_layers_);
    251     if (error == kErrorNone) {
    252       // Strategy is successful now, wait for Commit().
    253       pending_commit_ = true;
    254       break;
    255     }
    256     if (error == kErrorShutDown) {
    257       comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
    258       return error;
    259     }
    260   }
    261 
    262   comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
    263 
    264   return error;
    265 }
    266 
    267 DisplayError DisplayBase::Commit(LayerStack *layer_stack) {
    268   lock_guard<recursive_mutex> obj(recursive_mutex_);
    269   DisplayError error = kErrorNone;
    270 
    271   if (!active_) {
    272     pending_commit_ = false;
    273     return kErrorPermission;
    274   }
    275 
    276   if (!layer_stack) {
    277     return kErrorParameters;
    278   }
    279 
    280   if (!pending_commit_) {
    281     DLOGE("Commit: Corresponding Prepare() is not called for display = %d", display_type_);
    282     return kErrorUndefined;
    283   }
    284 
    285   pending_commit_ = false;
    286 
    287   // Layer stack attributes has changed, need to Reconfigure, currently in use for Hybrid Comp
    288   if (layer_stack->flags.attributes_changed) {
    289     error = comp_manager_->ReConfigure(display_comp_ctx_, &hw_layers_);
    290     if (error != kErrorNone) {
    291       return error;
    292     }
    293 
    294     error = hw_intf_->Validate(&hw_layers_);
    295     if (error != kErrorNone) {
    296         return error;
    297     }
    298   }
    299 
    300   CommitLayerParams(layer_stack);
    301 
    302   if (comp_manager_->Commit(display_comp_ctx_, &hw_layers_)) {
    303     if (error != kErrorNone) {
    304       return error;
    305     }
    306   }
    307 
    308   // check if feature list cache is dirty and pending.
    309   // If dirty, need program to hardware blocks.
    310   if (color_mgr_)
    311     error = color_mgr_->Commit();
    312   if (error != kErrorNone) {  // won't affect this execution path.
    313     DLOGW("ColorManager::Commit(...) isn't working");
    314   }
    315 
    316   error = hw_intf_->Commit(&hw_layers_);
    317   if (error != kErrorNone) {
    318     return error;
    319   }
    320 
    321   PostCommitLayerParams(layer_stack);
    322 
    323   if (partial_update_control_) {
    324     comp_manager_->ControlPartialUpdate(display_comp_ctx_, true /* enable */);
    325   }
    326 
    327   error = comp_manager_->PostCommit(display_comp_ctx_, &hw_layers_);
    328   if (error != kErrorNone) {
    329     return error;
    330   }
    331 
    332   return kErrorNone;
    333 }
    334 
    335 DisplayError DisplayBase::Flush() {
    336   lock_guard<recursive_mutex> obj(recursive_mutex_);
    337   DisplayError error = kErrorNone;
    338 
    339   if (!active_) {
    340     return kErrorPermission;
    341   }
    342   hw_layers_.info.hw_layers.clear();
    343   error = hw_intf_->Flush();
    344   if (error == kErrorNone) {
    345     comp_manager_->Purge(display_comp_ctx_);
    346     pending_commit_ = false;
    347   } else {
    348     DLOGW("Unable to flush display = %d", display_type_);
    349   }
    350 
    351   return error;
    352 }
    353 
    354 DisplayError DisplayBase::GetDisplayState(DisplayState *state) {
    355   lock_guard<recursive_mutex> obj(recursive_mutex_);
    356   if (!state) {
    357     return kErrorParameters;
    358   }
    359 
    360   *state = state_;
    361   return kErrorNone;
    362 }
    363 
    364 DisplayError DisplayBase::GetNumVariableInfoConfigs(uint32_t *count) {
    365   lock_guard<recursive_mutex> obj(recursive_mutex_);
    366   return hw_intf_->GetNumDisplayAttributes(count);
    367 }
    368 
    369 DisplayError DisplayBase::GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info) {
    370   lock_guard<recursive_mutex> obj(recursive_mutex_);
    371   HWDisplayAttributes attrib;
    372   if (hw_intf_->GetDisplayAttributes(index, &attrib) == kErrorNone) {
    373     *variable_info = attrib;
    374     return kErrorNone;
    375   }
    376 
    377   return kErrorNotSupported;
    378 }
    379 
    380 DisplayError DisplayBase::GetConfig(DisplayConfigFixedInfo *fixed_info) {
    381   lock_guard<recursive_mutex> obj(recursive_mutex_);
    382   fixed_info->is_cmdmode = (hw_panel_info_.mode == kModeCommand);
    383 
    384   HWResourceInfo hw_resource_info = HWResourceInfo();
    385   hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
    386   // hdr can be supported by display when target and panel supports HDR.
    387   fixed_info->hdr_supported = (hw_resource_info.has_hdr && hw_panel_info_.hdr_enabled);
    388   // Populate luminance values only if hdr will be supported on that display
    389   fixed_info->max_luminance = fixed_info->hdr_supported ? hw_panel_info_.peak_luminance: 0;
    390   fixed_info->average_luminance = fixed_info->hdr_supported ? hw_panel_info_.average_luminance : 0;
    391   fixed_info->min_luminance = fixed_info->hdr_supported ?  hw_panel_info_.blackness_level: 0;
    392 
    393   return kErrorNone;
    394 }
    395 
    396 DisplayError DisplayBase::GetActiveConfig(uint32_t *index) {
    397   lock_guard<recursive_mutex> obj(recursive_mutex_);
    398   return hw_intf_->GetActiveConfig(index);
    399 }
    400 
    401 DisplayError DisplayBase::GetVSyncState(bool *enabled) {
    402   lock_guard<recursive_mutex> obj(recursive_mutex_);
    403   if (!enabled) {
    404     return kErrorParameters;
    405   }
    406 
    407   *enabled = vsync_enable_;
    408 
    409   return kErrorNone;
    410 }
    411 
    412 DisplayError DisplayBase::SetDisplayState(DisplayState state) {
    413   lock_guard<recursive_mutex> obj(recursive_mutex_);
    414   DisplayError error = kErrorNone;
    415   bool active = false;
    416 
    417   DLOGI("Set state = %d, display %d", state, display_type_);
    418 
    419   if (state == state_) {
    420     DLOGI("Same state transition is requested.");
    421     return kErrorNone;
    422   }
    423 
    424   switch (state) {
    425   case kStateOff:
    426     hw_layers_.info.hw_layers.clear();
    427     error = hw_intf_->Flush();
    428     if (error == kErrorNone) {
    429       error = hw_intf_->PowerOff();
    430     }
    431     break;
    432 
    433   case kStateOn:
    434     error = hw_intf_->PowerOn();
    435     if (error != kErrorNone) {
    436       return error;
    437     }
    438 
    439     error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_,
    440                                               hw_panel_info_, mixer_attributes_, fb_config_);
    441     if (error != kErrorNone) {
    442       return error;
    443     }
    444 
    445     active = true;
    446     break;
    447 
    448   case kStateDoze:
    449     error = hw_intf_->Doze();
    450     active = true;
    451     break;
    452 
    453   case kStateDozeSuspend:
    454     error = hw_intf_->DozeSuspend();
    455     if (display_type_ != kPrimary) {
    456       active = true;
    457     }
    458 
    459     break;
    460 
    461   case kStateStandby:
    462     error = hw_intf_->Standby();
    463     break;
    464 
    465   default:
    466     DLOGE("Spurious state = %d transition requested.", state);
    467     break;
    468   }
    469 
    470   if (error == kErrorNone) {
    471     active_ = active;
    472     state_ = state;
    473     comp_manager_->SetDisplayState(display_comp_ctx_, state, display_type_);
    474   }
    475 
    476   return error;
    477 }
    478 
    479 DisplayError DisplayBase::SetActiveConfig(uint32_t index) {
    480   lock_guard<recursive_mutex> obj(recursive_mutex_);
    481   DisplayError error = kErrorNone;
    482   uint32_t active_index = 0;
    483 
    484   hw_intf_->GetActiveConfig(&active_index);
    485 
    486   if (active_index == index) {
    487     return kErrorNone;
    488   }
    489 
    490   error = hw_intf_->SetDisplayAttributes(index);
    491   if (error != kErrorNone) {
    492     return error;
    493   }
    494 
    495   return ReconfigureDisplay();
    496 }
    497 
    498 DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) {
    499   lock_guard<recursive_mutex> obj(recursive_mutex_);
    500   DisplayError error = kErrorNone;
    501 
    502   error = comp_manager_->SetMaxMixerStages(display_comp_ctx_, max_mixer_stages);
    503 
    504   if (error == kErrorNone) {
    505     max_mixer_stages_ = max_mixer_stages;
    506   }
    507 
    508   return error;
    509 }
    510 
    511 void DisplayBase::AppendDump(char *buffer, uint32_t length) {
    512   lock_guard<recursive_mutex> obj(recursive_mutex_);
    513   HWDisplayAttributes attrib;
    514   uint32_t active_index = 0;
    515   uint32_t num_modes = 0;
    516   hw_intf_->GetNumDisplayAttributes(&num_modes);
    517   hw_intf_->GetActiveConfig(&active_index);
    518   hw_intf_->GetDisplayAttributes(active_index, &attrib);
    519 
    520   DumpImpl::AppendString(buffer, length, "\n-----------------------");
    521   DumpImpl::AppendString(buffer, length, "\ndevice type: %u", display_type_);
    522   DumpImpl::AppendString(buffer, length, "\nstate: %u, vsync on: %u, max. mixer stages: %u",
    523                          state_, INT(vsync_enable_), max_mixer_stages_);
    524   DumpImpl::AppendString(buffer, length, "\nnum configs: %u, active config index: %u",
    525                          num_modes, active_index);
    526 
    527   DisplayConfigVariableInfo &info = attrib;
    528 
    529   uint32_t num_hw_layers = 0;
    530   if (hw_layers_.info.stack) {
    531     num_hw_layers = UINT32(hw_layers_.info.hw_layers.size());
    532   }
    533 
    534   if (num_hw_layers == 0) {
    535     DumpImpl::AppendString(buffer, length, "\nNo hardware layers programmed");
    536     return;
    537   }
    538 
    539   LayerBuffer *out_buffer = hw_layers_.info.stack->output_buffer;
    540   if (out_buffer) {
    541     DumpImpl::AppendString(buffer, length, "\nres:%u x %u format: %s", out_buffer->width,
    542                            out_buffer->height, GetFormatString(out_buffer->format));
    543   } else {
    544     DumpImpl::AppendString(buffer, length, "\nres:%u x %u, dpi:%.2f x %.2f, fps:%u,"
    545                            "vsync period: %u", info.x_pixels, info.y_pixels, info.x_dpi,
    546                            info.y_dpi, info.fps, info.vsync_period_ns);
    547   }
    548 
    549   DumpImpl::AppendString(buffer, length, "\n");
    550 
    551   HWLayersInfo &layer_info = hw_layers_.info;
    552 
    553   for (uint32_t i = 0; i < layer_info.left_frame_roi.size(); i++) {
    554     LayerRect &l_roi = layer_info.left_frame_roi.at(i);
    555     LayerRect &r_roi = layer_info.right_frame_roi.at(i);
    556 
    557     DumpImpl::AppendString(buffer, length, "\nROI%d(L T R B) : LEFT(%d %d %d %d)", i,
    558                            INT(l_roi.left), INT(l_roi.top), INT(l_roi.right), INT(l_roi.bottom));
    559     if (IsValid(r_roi)) {
    560       DumpImpl::AppendString(buffer, length, ", RIGHT(%d %d %d %d)", INT(r_roi.left),
    561                              INT(r_roi.top), INT(r_roi.right), INT(r_roi.bottom));
    562     }
    563   }
    564 
    565   LayerRect &fb_roi = layer_info.partial_fb_roi;
    566   if (IsValid(fb_roi)) {
    567     DumpImpl::AppendString(buffer, length, "\nPartial FB ROI(L T R B) : (%d %d %d %d)",
    568                           INT(fb_roi.left), INT(fb_roi.top), INT(fb_roi.right), INT(fb_roi.bottom));
    569   }
    570 
    571   const char *header  = "\n| Idx |  Comp Type  |  Split | WB |  Pipe  |    W x H    |          Format          |  Src Rect (L T R B) |  Dst Rect (L T R B) |  Z |    Flags   | Deci(HxV) | CS | Rng |";  //NOLINT
    572   const char *newline = "\n|-----|-------------|--------|----|--------|-------------|--------------------------|---------------------|---------------------|----|------------|-----------|----|-----|";  //NOLINT
    573   const char *format  = "\n| %3s | %11s "     "| %6s " "| %2s | 0x%04x | %4d x %4d | %24s "                  "| %4d %4d %4d %4d "  "| %4d %4d %4d %4d "  "| %2s | %10s "   "| %9s | %2s | %3s |";  //NOLINT
    574 
    575   DumpImpl::AppendString(buffer, length, "\n");
    576   DumpImpl::AppendString(buffer, length, newline);
    577   DumpImpl::AppendString(buffer, length, header);
    578   DumpImpl::AppendString(buffer, length, newline);
    579 
    580   for (uint32_t i = 0; i < num_hw_layers; i++) {
    581     uint32_t layer_index = hw_layers_.info.index[i];
    582     // sdm-layer from client layer stack
    583     Layer *sdm_layer = hw_layers_.info.stack->layers.at(layer_index);
    584     // hw-layer from hw layers info
    585     Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
    586     LayerBuffer *input_buffer = &hw_layer.input_buffer;
    587     HWLayerConfig &layer_config = hw_layers_.config[i];
    588     HWRotatorSession &hw_rotator_session = layer_config.hw_rotator_session;
    589 
    590     char idx[8] = { 0 };
    591     const char *comp_type = GetName(sdm_layer->composition);
    592     const char *buffer_format = GetFormatString(input_buffer->format);
    593     const char *rotate_split[2] = { "Rot-1", "Rot-2" };
    594     const char *comp_split[2] = { "Comp-1", "Comp-2" };
    595 
    596     snprintf(idx, sizeof(idx), "%d", layer_index);
    597 
    598     for (uint32_t count = 0; count < hw_rotator_session.hw_block_count; count++) {
    599       char writeback_id[8] = { 0 };
    600       HWRotateInfo &rotate = hw_rotator_session.hw_rotate_info[count];
    601       LayerRect &src_roi = rotate.src_roi;
    602       LayerRect &dst_roi = rotate.dst_roi;
    603 
    604       snprintf(writeback_id, sizeof(writeback_id), "%d", rotate.writeback_id);
    605 
    606       DumpImpl::AppendString(buffer, length, format, idx, comp_type, rotate_split[count],
    607                              writeback_id, rotate.pipe_id, input_buffer->width,
    608                              input_buffer->height, buffer_format, INT(src_roi.left),
    609                              INT(src_roi.top), INT(src_roi.right), INT(src_roi.bottom),
    610                              INT(dst_roi.left), INT(dst_roi.top), INT(dst_roi.right),
    611                              INT(dst_roi.bottom), "-", "-    ", "-    ", "-", "-");
    612 
    613       // print the below only once per layer block, fill with spaces for rest.
    614       idx[0] = 0;
    615       comp_type = "";
    616     }
    617 
    618     if (hw_rotator_session.hw_block_count > 0) {
    619       input_buffer = &hw_rotator_session.output_buffer;
    620       buffer_format = GetFormatString(input_buffer->format);
    621     }
    622 
    623     for (uint32_t count = 0; count < 2; count++) {
    624       char decimation[16] = { 0 };
    625       char flags[16] = { 0 };
    626       char z_order[8] = { 0 };
    627       char color_primary[8] = { 0 };
    628       char range[8] = { 0 };
    629 
    630       HWPipeInfo &pipe = (count == 0) ? layer_config.left_pipe : layer_config.right_pipe;
    631 
    632       if (!pipe.valid) {
    633         continue;
    634       }
    635 
    636       LayerRect &src_roi = pipe.src_roi;
    637       LayerRect &dst_roi = pipe.dst_roi;
    638 
    639       snprintf(z_order, sizeof(z_order), "%d", pipe.z_order);
    640       snprintf(flags, sizeof(flags), "0x%08x", hw_layer.flags.flags);
    641       snprintf(decimation, sizeof(decimation), "%3d x %3d", pipe.horizontal_decimation,
    642                pipe.vertical_decimation);
    643       ColorMetaData &color_metadata = hw_layer.input_buffer.color_metadata;
    644       snprintf(color_primary, sizeof(color_primary), "%d", color_metadata.colorPrimaries);
    645       snprintf(range, sizeof(range), "%d", color_metadata.range);
    646 
    647       DumpImpl::AppendString(buffer, length, format, idx, comp_type, comp_split[count],
    648                              "-", pipe.pipe_id, input_buffer->width, input_buffer->height,
    649                              buffer_format, INT(src_roi.left), INT(src_roi.top),
    650                              INT(src_roi.right), INT(src_roi.bottom), INT(dst_roi.left),
    651                              INT(dst_roi.top), INT(dst_roi.right), INT(dst_roi.bottom),
    652                              z_order, flags, decimation, color_primary, range);
    653 
    654       // print the below only once per layer block, fill with spaces for rest.
    655       idx[0] = 0;
    656       comp_type = "";
    657     }
    658 
    659     DumpImpl::AppendString(buffer, length, newline);
    660   }
    661 }
    662 
    663 const char * DisplayBase::GetName(const LayerComposition &composition) {
    664   switch (composition) {
    665   case kCompositionGPU:         return "GPU";
    666   case kCompositionSDE:         return "SDE";
    667   case kCompositionCursor:      return "CURSOR";
    668   case kCompositionHybrid:      return "HYBRID";
    669   case kCompositionBlit:        return "BLIT";
    670   case kCompositionGPUTarget:   return "GPU_TARGET";
    671   case kCompositionBlitTarget:  return "BLIT_TARGET";
    672   default:                      return "UNKNOWN";
    673   }
    674 }
    675 
    676 DisplayError DisplayBase::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
    677                                                PPDisplayAPIPayload *out_payload,
    678                                                PPPendingParams *pending_action) {
    679   lock_guard<recursive_mutex> obj(recursive_mutex_);
    680   if (color_mgr_)
    681     return color_mgr_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
    682   else
    683     return kErrorParameters;
    684 }
    685 
    686 DisplayError DisplayBase::GetColorModeCount(uint32_t *mode_count) {
    687   lock_guard<recursive_mutex> obj(recursive_mutex_);
    688   if (!mode_count) {
    689     return kErrorParameters;
    690   }
    691 
    692   if (!color_mgr_) {
    693     return kErrorNotSupported;
    694   }
    695 
    696   DLOGV_IF(kTagQDCM, "Number of modes from color manager = %d", num_color_modes_);
    697   *mode_count = num_color_modes_;
    698 
    699   return kErrorNone;
    700 }
    701 
    702 DisplayError DisplayBase::GetColorModes(uint32_t *mode_count,
    703                                         std::vector<std::string> *color_modes) {
    704   lock_guard<recursive_mutex> obj(recursive_mutex_);
    705   if (!mode_count || !color_modes) {
    706     return kErrorParameters;
    707   }
    708 
    709   if (!color_mgr_) {
    710     return kErrorNotSupported;
    711   }
    712 
    713   for (uint32_t i = 0; i < num_color_modes_; i++) {
    714     DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
    715              color_modes_[i].id);
    716     color_modes->at(i) = color_modes_[i].name;
    717   }
    718 
    719   return kErrorNone;
    720 }
    721 
    722 DisplayError DisplayBase::GetColorModeAttr(const std::string &color_mode, AttrVal *attr) {
    723   lock_guard<recursive_mutex> obj(recursive_mutex_);
    724   if (!attr) {
    725     return kErrorParameters;
    726   }
    727 
    728   if (!color_mgr_) {
    729     return kErrorNotSupported;
    730   }
    731 
    732   auto it = color_mode_attr_map_.find(color_mode);
    733   if (it == color_mode_attr_map_.end()) {
    734     DLOGE("Failed: Mode %s without attribute", color_mode.c_str());
    735     return kErrorNotSupported;
    736   }
    737   *attr = it->second;
    738 
    739   return kErrorNone;
    740 }
    741 
    742 DisplayError DisplayBase::SetColorMode(const std::string &color_mode) {
    743   lock_guard<recursive_mutex> obj(recursive_mutex_);
    744   if (!color_mgr_) {
    745     return kErrorNotSupported;
    746   }
    747 
    748   DynamicRangeType dynamic_range_type;
    749   if (IsSupportColorModeAttribute(color_mode)) {
    750     auto it_mode = color_mode_attr_map_.find(color_mode);
    751     std::string dynamic_range;
    752     GetValueOfModeAttribute(it_mode->second, kDynamicRangeAttribute, &dynamic_range);
    753     if (dynamic_range == kHdr) {
    754       dynamic_range_type = kHdrType;
    755     } else {
    756       dynamic_range_type = kSdrType;
    757     }
    758   } else {
    759     if (color_mode.find("hal_hdr") != std::string::npos) {
    760       dynamic_range_type = kHdrType;
    761     } else {
    762       dynamic_range_type = kSdrType;
    763     }
    764   }
    765 
    766   DisplayError error = kErrorNone;
    767   if (disable_hdr_lut_gen_) {
    768     error = SetColorModeInternal(color_mode);
    769     if (error != kErrorNone) {
    770       return error;
    771     }
    772     // Store the new SDR color mode request by client
    773     if (dynamic_range_type == kSdrType) {
    774       current_color_mode_ = color_mode;
    775     }
    776     return error;
    777   }
    778 
    779   if (hdr_playback_mode_) {
    780     // HDR playback on, If incoming mode is SDR mode,
    781     // cache the mode and apply it after HDR playback stop.
    782     if (dynamic_range_type == kHdrType) {
    783       error = SetColorModeInternal(color_mode);
    784       if (error != kErrorNone) {
    785         return error;
    786       }
    787     } else if (dynamic_range_type == kSdrType) {
    788       current_color_mode_ = color_mode;
    789     }
    790   } else {
    791     // HDR playback off, do not apply HDR mode
    792     if (dynamic_range_type == kHdrType) {
    793       DLOGE("Failed: Forbid setting HDR Mode : %s when HDR playback off", color_mode.c_str());
    794       return kErrorNotSupported;
    795     }
    796     error = SetColorModeInternal(color_mode);
    797     if (error != kErrorNone) {
    798       return error;
    799     }
    800     current_color_mode_ = color_mode;
    801   }
    802 
    803   return error;
    804 }
    805 
    806 DisplayError DisplayBase::SetColorModeById(int32_t color_mode_id) {
    807   return color_mgr_->ColorMgrSetMode(color_mode_id);
    808 }
    809 
    810 DisplayError DisplayBase::SetColorModeInternal(const std::string &color_mode) {
    811   DLOGV_IF(kTagQDCM, "Color Mode = %s", color_mode.c_str());
    812 
    813   ColorModeMap::iterator it = color_mode_map_.find(color_mode);
    814   if (it == color_mode_map_.end()) {
    815     DLOGE("Failed: Unknown Mode : %s", color_mode.c_str());
    816     return kErrorNotSupported;
    817   }
    818 
    819   SDEDisplayMode *sde_display_mode = it->second;
    820 
    821   DLOGV_IF(kTagQDCM, "Color Mode Name = %s corresponding mode_id = %d", sde_display_mode->name,
    822            sde_display_mode->id);
    823   DisplayError error = kErrorNone;
    824   error = color_mgr_->ColorMgrSetMode(sde_display_mode->id);
    825   if (error != kErrorNone) {
    826     DLOGE("Failed for mode id = %d", sde_display_mode->id);
    827     return error;
    828   }
    829 
    830   return error;
    831 }
    832 
    833 DisplayError DisplayBase::GetValueOfModeAttribute(const AttrVal &attr, const std::string &type,
    834                                                   std::string *value) {
    835   if (!value) {
    836     return kErrorParameters;
    837   }
    838   for (auto &it : attr) {
    839     if (it.first.find(type) != std::string::npos) {
    840       *value = it.second;
    841     }
    842   }
    843 
    844   return kErrorNone;
    845 }
    846 
    847 bool DisplayBase::IsSupportColorModeAttribute(const std::string &color_mode) {
    848   auto it = color_mode_attr_map_.find(color_mode);
    849   if (it == color_mode_attr_map_.end()) {
    850     return false;
    851   }
    852   return true;
    853 }
    854 
    855 DisplayError DisplayBase::GetHdrColorMode(std::string *color_mode, bool *found_hdr) {
    856   if (!found_hdr || !color_mode) {
    857     return kErrorParameters;
    858   }
    859   auto it_mode = color_mode_attr_map_.find(current_color_mode_);
    860   if (it_mode == color_mode_attr_map_.end()) {
    861     DLOGE("Failed: Unknown Mode : %s", current_color_mode_.c_str());
    862     return kErrorNotSupported;
    863   }
    864 
    865   *found_hdr = false;
    866   std::string cur_color_gamut, cur_pic_quality;
    867   // get the attributes of current color mode
    868   GetValueOfModeAttribute(it_mode->second, kColorGamutAttribute, &cur_color_gamut);
    869   GetValueOfModeAttribute(it_mode->second, kPictureQualityAttribute, &cur_pic_quality);
    870 
    871   // found the corresponding HDR mode id which
    872   // has the same attributes with current SDR mode.
    873   for (auto &it_hdr : color_mode_attr_map_) {
    874     std::string dynamic_range, color_gamut, pic_quality;
    875     GetValueOfModeAttribute(it_hdr.second, kDynamicRangeAttribute, &dynamic_range);
    876     GetValueOfModeAttribute(it_hdr.second, kColorGamutAttribute, &color_gamut);
    877     GetValueOfModeAttribute(it_hdr.second, kPictureQualityAttribute, &pic_quality);
    878     if (dynamic_range == kHdr && cur_color_gamut == color_gamut &&
    879         cur_pic_quality == pic_quality) {
    880       *color_mode = it_hdr.first;
    881       *found_hdr = true;
    882       DLOGV_IF(kTagQDCM, "corresponding hdr mode  = %s", color_mode->c_str());
    883       return kErrorNone;
    884     }
    885   }
    886 
    887   // The corresponding HDR mode was not be found,
    888   // apply the first HDR mode that we encouter.
    889   for (auto &it_hdr : color_mode_attr_map_) {
    890     std::string dynamic_range;
    891     GetValueOfModeAttribute(it_hdr.second, kDynamicRangeAttribute, &dynamic_range);
    892     if (dynamic_range == kHdr) {
    893       *color_mode = it_hdr.first;
    894       *found_hdr = true;
    895       DLOGV_IF(kTagQDCM, "First hdr mode = %s", color_mode->c_str());
    896       return kErrorNone;
    897     }
    898   }
    899 
    900   return kErrorNone;
    901 }
    902 
    903 DisplayError DisplayBase::SetColorTransform(const uint32_t length, const double *color_transform) {
    904   lock_guard<recursive_mutex> obj(recursive_mutex_);
    905   if (!color_mgr_) {
    906     return kErrorNotSupported;
    907   }
    908 
    909   if (!color_transform) {
    910     return kErrorParameters;
    911   }
    912 
    913   return color_mgr_->ColorMgrSetColorTransform(length, color_transform);
    914 }
    915 
    916 DisplayError DisplayBase::GetDefaultColorMode(std::string *color_mode) {
    917   lock_guard<recursive_mutex> obj(recursive_mutex_);
    918   if (!color_mode) {
    919     return kErrorParameters;
    920   }
    921 
    922   if (!color_mgr_) {
    923     return kErrorNotSupported;
    924   }
    925 
    926   int32_t default_id = kInvalidModeId;
    927   DisplayError error = color_mgr_->ColorMgrGetDefaultModeID(&default_id);
    928   if (error != kErrorNone) {
    929     DLOGE("Failed for get default color mode id");
    930     return error;
    931   }
    932 
    933   for (uint32_t i = 0; i < num_color_modes_; i++) {
    934     if (color_modes_[i].id == default_id) {
    935       *color_mode = color_modes_[i].name;
    936       return kErrorNone;
    937     }
    938   }
    939 
    940   return kErrorNotSupported;
    941 }
    942 
    943 DisplayError DisplayBase::ApplyDefaultDisplayMode() {
    944   lock_guard<recursive_mutex> obj(recursive_mutex_);
    945   if (color_mgr_)
    946     return color_mgr_->ApplyDefaultDisplayMode();
    947   else
    948     return kErrorParameters;
    949 }
    950 
    951 DisplayError DisplayBase::SetCursorPosition(int x, int y) {
    952   lock_guard<recursive_mutex> obj(recursive_mutex_);
    953   if (state_ != kStateOn) {
    954     return kErrorNotSupported;
    955   }
    956 
    957   DisplayError error = comp_manager_->ValidateCursorPosition(display_comp_ctx_, &hw_layers_, x, y);
    958   if (error == kErrorNone) {
    959     return hw_intf_->SetCursorPosition(&hw_layers_, x, y);
    960   }
    961 
    962   return kErrorNone;
    963 }
    964 
    965 DisplayError DisplayBase::GetRefreshRateRange(uint32_t *min_refresh_rate,
    966                                               uint32_t *max_refresh_rate) {
    967   lock_guard<recursive_mutex> obj(recursive_mutex_);
    968   // The min and max refresh rates will be same when the HWPanelInfo does not contain valid rates.
    969   // Usually for secondary displays, command mode panels
    970   HWDisplayAttributes display_attributes;
    971   uint32_t active_index = 0;
    972   hw_intf_->GetActiveConfig(&active_index);
    973   DisplayError error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
    974   if (error) {
    975     return error;
    976   }
    977 
    978   *min_refresh_rate = display_attributes.fps;
    979   *max_refresh_rate = display_attributes.fps;
    980 
    981   return error;
    982 }
    983 
    984 DisplayError DisplayBase::SetVSyncState(bool enable) {
    985   lock_guard<recursive_mutex> obj(recursive_mutex_);
    986   DisplayError error = kErrorNone;
    987   if (vsync_enable_ != enable) {
    988     error = hw_intf_->SetVSyncState(enable);
    989     if (error == kErrorNotSupported) {
    990       error = hw_events_intf_->SetEventState(HWEvent::VSYNC, enable);
    991     }
    992     if (error == kErrorNone) {
    993       vsync_enable_ = enable;
    994     }
    995   }
    996 
    997   return error;
    998 }
    999 
   1000 DisplayError DisplayBase::ReconfigureDisplay() {
   1001   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1002   DisplayError error = kErrorNone;
   1003   HWDisplayAttributes display_attributes;
   1004   HWMixerAttributes mixer_attributes;
   1005   HWPanelInfo hw_panel_info;
   1006   uint32_t active_index = 0;
   1007 
   1008   error = hw_intf_->GetActiveConfig(&active_index);
   1009   if (error != kErrorNone) {
   1010     return error;
   1011   }
   1012 
   1013   error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
   1014   if (error != kErrorNone) {
   1015     return error;
   1016   }
   1017 
   1018   error = hw_intf_->GetMixerAttributes(&mixer_attributes);
   1019   if (error != kErrorNone) {
   1020     return error;
   1021   }
   1022 
   1023   error = hw_intf_->GetHWPanelInfo(&hw_panel_info);
   1024   if (error != kErrorNone) {
   1025     return error;
   1026   }
   1027 
   1028   if (display_attributes == display_attributes_ && mixer_attributes == mixer_attributes_ &&
   1029       hw_panel_info == hw_panel_info_) {
   1030     return kErrorNone;
   1031   }
   1032 
   1033   error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info,
   1034                                             mixer_attributes, fb_config_);
   1035   if (error != kErrorNone) {
   1036     return error;
   1037   }
   1038 
   1039   if (mixer_attributes != mixer_attributes_) {
   1040     DisablePartialUpdateOneFrame();
   1041   }
   1042 
   1043   display_attributes_ = display_attributes;
   1044   mixer_attributes_ = mixer_attributes;
   1045   hw_panel_info_ = hw_panel_info;
   1046 
   1047   return kErrorNone;
   1048 }
   1049 
   1050 DisplayError DisplayBase::SetMixerResolution(uint32_t width, uint32_t height) {
   1051   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1052 
   1053   DisplayError error = ReconfigureMixer(width, height);
   1054   if (error != kErrorNone) {
   1055     return error;
   1056   }
   1057 
   1058   req_mixer_width_ = width;
   1059   req_mixer_height_ = height;
   1060 
   1061   return kErrorNone;
   1062 }
   1063 
   1064 DisplayError DisplayBase::GetMixerResolution(uint32_t *width, uint32_t *height) {
   1065   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1066   if (!width || !height) {
   1067     return kErrorParameters;
   1068   }
   1069 
   1070   *width = mixer_attributes_.width;
   1071   *height = mixer_attributes_.height;
   1072 
   1073   return kErrorNone;
   1074 }
   1075 
   1076 DisplayError DisplayBase::ReconfigureMixer(uint32_t width, uint32_t height) {
   1077   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1078   DisplayError error = kErrorNone;
   1079 
   1080   if (!width || !height) {
   1081     return kErrorParameters;
   1082   }
   1083 
   1084   HWMixerAttributes mixer_attributes;
   1085   mixer_attributes.width = width;
   1086   mixer_attributes.height = height;
   1087 
   1088   error = hw_intf_->SetMixerAttributes(mixer_attributes);
   1089   if (error != kErrorNone) {
   1090     return error;
   1091   }
   1092 
   1093   return ReconfigureDisplay();
   1094 }
   1095 
   1096 bool DisplayBase::NeedsDownScale(const LayerRect &src_rect, const LayerRect &dst_rect,
   1097                                  bool needs_rotation) {
   1098   float src_width = FLOAT(src_rect.right - src_rect.left);
   1099   float src_height = FLOAT(src_rect.bottom - src_rect.top);
   1100   float dst_width = FLOAT(dst_rect.right - dst_rect.left);
   1101   float dst_height = FLOAT(dst_rect.bottom - dst_rect.top);
   1102 
   1103   if (needs_rotation) {
   1104     std::swap(src_width, src_height);
   1105   }
   1106 
   1107   if ((src_width > dst_width) || (src_height > dst_height)) {
   1108     return true;
   1109   }
   1110 
   1111   return false;
   1112 }
   1113 
   1114 bool DisplayBase::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
   1115                                             uint32_t *new_mixer_height) {
   1116   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1117   uint32_t layer_count = UINT32(layer_stack->layers.size());
   1118 
   1119   uint32_t fb_width  = fb_config_.x_pixels;
   1120   uint32_t fb_height  = fb_config_.y_pixels;
   1121   uint32_t fb_area = fb_width * fb_height;
   1122   LayerRect fb_rect = (LayerRect) {0.0f, 0.0f, FLOAT(fb_width), FLOAT(fb_height)};
   1123   uint32_t mixer_width = mixer_attributes_.width;
   1124   uint32_t mixer_height = mixer_attributes_.height;
   1125   uint32_t display_width = display_attributes_.x_pixels;
   1126   uint32_t display_height = display_attributes_.y_pixels;
   1127 
   1128   RectOrientation fb_orientation = GetOrientation(fb_rect);
   1129   uint32_t max_layer_area = 0;
   1130   uint32_t max_area_layer_index = 0;
   1131   std::vector<Layer *> layers = layer_stack->layers;
   1132   uint32_t align_x = display_attributes_.is_device_split ? 4 : 2;
   1133   uint32_t align_y = 2;
   1134 
   1135   if (req_mixer_width_ && req_mixer_height_) {
   1136     *new_mixer_width = req_mixer_width_;
   1137     *new_mixer_height = req_mixer_height_;
   1138 
   1139     return (req_mixer_width_ != mixer_width || req_mixer_height_ != mixer_height);
   1140   }
   1141 
   1142   for (uint32_t i = 0; i < layer_count; i++) {
   1143     Layer *layer = layers.at(i);
   1144 
   1145     uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
   1146     uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
   1147     uint32_t layer_area = layer_width * layer_height;
   1148 
   1149     if (layer_area > max_layer_area) {
   1150       max_layer_area = layer_area;
   1151       max_area_layer_index = i;
   1152     }
   1153   }
   1154 
   1155   // TODO(user): Mark layer which needs downscaling on GPU fallback as priority layer and use MDP
   1156   // for composition to avoid quality mismatch between GPU and MDP switch(idle timeout usecase).
   1157   if (max_layer_area >= fb_area) {
   1158     Layer *layer = layers.at(max_area_layer_index);
   1159     bool needs_rotation = (layer->transform.rotation == 90.0f);
   1160 
   1161     uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
   1162     uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
   1163     LayerRect layer_dst_rect = {};
   1164 
   1165     RectOrientation layer_orientation = GetOrientation(layer->src_rect);
   1166     if (layer_orientation != kOrientationUnknown &&
   1167         fb_orientation != kOrientationUnknown) {
   1168       if (layer_orientation != fb_orientation) {
   1169         std::swap(layer_width, layer_height);
   1170       }
   1171     }
   1172 
   1173     // Align the width and height according to fb's aspect ratio
   1174     *new_mixer_width = FloorToMultipleOf(UINT32((FLOAT(fb_width) / FLOAT(fb_height)) *
   1175                                          layer_height), align_x);
   1176     *new_mixer_height = FloorToMultipleOf(layer_height, align_y);
   1177 
   1178     LayerRect dst_domain = {0.0f, 0.0f, FLOAT(*new_mixer_width), FLOAT(*new_mixer_height)};
   1179 
   1180     MapRect(fb_rect, dst_domain, layer->dst_rect, &layer_dst_rect);
   1181     if (NeedsDownScale(layer->src_rect, layer_dst_rect, needs_rotation)) {
   1182       *new_mixer_width = display_width;
   1183       *new_mixer_height = display_height;
   1184     }
   1185 
   1186     return true;
   1187   }
   1188 
   1189   return false;
   1190 }
   1191 
   1192 DisplayError DisplayBase::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) {
   1193   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1194   uint32_t width = variable_info.x_pixels;
   1195   uint32_t height = variable_info.y_pixels;
   1196 
   1197   if (width == 0 || height == 0) {
   1198     DLOGE("Unsupported resolution: (%dx%d)", width, height);
   1199     return kErrorParameters;
   1200   }
   1201 
   1202   // Create rects to represent the new source and destination crops
   1203   LayerRect crop = LayerRect(0, 0, FLOAT(width), FLOAT(height));
   1204   LayerRect dst = LayerRect(0, 0, FLOAT(mixer_attributes_.width), FLOAT(mixer_attributes_.height));
   1205   // Set rotate90 to false since this is taken care of during regular composition.
   1206   bool rotate90 = false;
   1207 
   1208   DisplayError error = comp_manager_->ValidateScaling(crop, dst, rotate90);
   1209   if (error != kErrorNone) {
   1210     DLOGE("Unsupported resolution: (%dx%d)", width, height);
   1211     return kErrorParameters;
   1212   }
   1213 
   1214   error =  comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_, hw_panel_info_,
   1215                                              mixer_attributes_, variable_info);
   1216   if (error != kErrorNone) {
   1217     return error;
   1218   }
   1219 
   1220   fb_config_.x_pixels = width;
   1221   fb_config_.y_pixels = height;
   1222 
   1223   DLOGI("New framebuffer resolution (%dx%d)", fb_config_.x_pixels, fb_config_.y_pixels);
   1224 
   1225   return kErrorNone;
   1226 }
   1227 
   1228 DisplayError DisplayBase::GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) {
   1229   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1230   if (!variable_info) {
   1231     return kErrorParameters;
   1232   }
   1233 
   1234   *variable_info = fb_config_;
   1235 
   1236   return kErrorNone;
   1237 }
   1238 
   1239 DisplayError DisplayBase::SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) {
   1240   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1241   DisplayError error = comp_manager_->SetDetailEnhancerData(display_comp_ctx_, de_data);
   1242   if (error != kErrorNone) {
   1243     return error;
   1244   }
   1245 
   1246   DisablePartialUpdateOneFrame();
   1247 
   1248   return kErrorNone;
   1249 }
   1250 
   1251 DisplayError DisplayBase::GetDisplayPort(DisplayPort *port) {
   1252   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1253 
   1254   if (!port) {
   1255     return kErrorParameters;
   1256   }
   1257 
   1258   *port = hw_panel_info_.port;
   1259 
   1260   return kErrorNone;
   1261 }
   1262 
   1263 bool DisplayBase::IsPrimaryDisplay() {
   1264   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1265 
   1266   return hw_panel_info_.is_primary_panel;
   1267 }
   1268 
   1269 DisplayError DisplayBase::SetCompositionState(LayerComposition composition_type, bool enable) {
   1270   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1271 
   1272   return comp_manager_->SetCompositionState(display_comp_ctx_, composition_type, enable);
   1273 }
   1274 
   1275 void DisplayBase::CommitLayerParams(LayerStack *layer_stack) {
   1276   // Copy the acquire fence from clients layers  to HWLayers
   1277   uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size());
   1278 
   1279   for (uint32_t i = 0; i < hw_layers_count; i++) {
   1280     Layer *sdm_layer = layer_stack->layers.at(hw_layers_.info.index[i]);
   1281     Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
   1282 
   1283     hw_layer.input_buffer.planes[0].fd = sdm_layer->input_buffer.planes[0].fd;
   1284     hw_layer.input_buffer.planes[0].offset = sdm_layer->input_buffer.planes[0].offset;
   1285     hw_layer.input_buffer.planes[0].stride = sdm_layer->input_buffer.planes[0].stride;
   1286     hw_layer.input_buffer.size = sdm_layer->input_buffer.size;
   1287     hw_layer.input_buffer.acquire_fence_fd = sdm_layer->input_buffer.acquire_fence_fd;
   1288   }
   1289 
   1290   return;
   1291 }
   1292 
   1293 void DisplayBase::PostCommitLayerParams(LayerStack *layer_stack) {
   1294   // Copy the release fence from HWLayers to clients layers
   1295     uint32_t hw_layers_count = UINT32(hw_layers_.info.hw_layers.size());
   1296 
   1297   std::vector<uint32_t> fence_dup_flag;
   1298 
   1299   for (uint32_t i = 0; i < hw_layers_count; i++) {
   1300     uint32_t sdm_layer_index = hw_layers_.info.index[i];
   1301     Layer *sdm_layer = layer_stack->layers.at(sdm_layer_index);
   1302     Layer &hw_layer = hw_layers_.info.hw_layers.at(i);
   1303 
   1304     // Copy the release fence only once for a SDM Layer.
   1305     // In S3D use case, two hw layers can share the same input buffer, So make sure to merge the
   1306     // output fence fd and assign it to layer's input buffer release fence fd.
   1307     if (std::find(fence_dup_flag.begin(), fence_dup_flag.end(), sdm_layer_index) ==
   1308         fence_dup_flag.end()) {
   1309       sdm_layer->input_buffer.release_fence_fd = hw_layer.input_buffer.release_fence_fd;
   1310       fence_dup_flag.push_back(sdm_layer_index);
   1311     } else {
   1312       int temp = -1;
   1313       buffer_sync_handler_->SyncMerge(hw_layer.input_buffer.release_fence_fd,
   1314                                       sdm_layer->input_buffer.release_fence_fd, &temp);
   1315 
   1316       if (hw_layer.input_buffer.release_fence_fd >= 0) {
   1317         Sys::close_(hw_layer.input_buffer.release_fence_fd);
   1318         hw_layer.input_buffer.release_fence_fd = -1;
   1319       }
   1320 
   1321       if (sdm_layer->input_buffer.release_fence_fd >= 0) {
   1322         Sys::close_(sdm_layer->input_buffer.release_fence_fd);
   1323         sdm_layer->input_buffer.release_fence_fd = -1;
   1324       }
   1325 
   1326       sdm_layer->input_buffer.release_fence_fd = temp;
   1327     }
   1328 
   1329     // Reset the sync fence fds of HWLayer
   1330     hw_layer.input_buffer.acquire_fence_fd = -1;
   1331     hw_layer.input_buffer.release_fence_fd = -1;
   1332   }
   1333 
   1334   return;
   1335 }
   1336 
   1337 DisplayError DisplayBase::InitializeColorModes() {
   1338   if (!color_mgr_) {
   1339     return kErrorNotSupported;
   1340   }
   1341 
   1342   DisplayError error = color_mgr_->ColorMgrGetNumOfModes(&num_color_modes_);
   1343   if (error != kErrorNone || !num_color_modes_) {
   1344     DLOGV_IF(kTagQDCM, "GetNumModes failed = %d count = %d", error, num_color_modes_);
   1345     return kErrorNotSupported;
   1346   }
   1347   DLOGI("Number of Color Modes = %d", num_color_modes_);
   1348 
   1349   if (!color_modes_.size()) {
   1350     color_modes_.resize(num_color_modes_);
   1351 
   1352     DisplayError error = color_mgr_->ColorMgrGetModes(&num_color_modes_, color_modes_.data());
   1353     if (error != kErrorNone) {
   1354       color_modes_.clear();
   1355       DLOGE("Failed");
   1356       return error;
   1357     }
   1358     int32_t default_id = kInvalidModeId;
   1359     error = color_mgr_->ColorMgrGetDefaultModeID(&default_id);
   1360 
   1361     AttrVal var;
   1362     for (uint32_t i = 0; i < num_color_modes_; i++) {
   1363       DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
   1364                color_modes_[i].id);
   1365       // get the name of default color mode
   1366       if (color_modes_[i].id == default_id) {
   1367         current_color_mode_ = color_modes_[i].name;
   1368       }
   1369       auto it = color_mode_map_.find(color_modes_[i].name);
   1370       if (it != color_mode_map_.end()) {
   1371         if (it->second->id < color_modes_[i].id) {
   1372           color_mode_map_.erase(it);
   1373           color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
   1374         }
   1375       } else {
   1376         color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
   1377       }
   1378 
   1379       var.clear();
   1380       error = color_mgr_->ColorMgrGetModeInfo(color_modes_[i].id, &var);
   1381       if (error != kErrorNone) {
   1382         DLOGE("Failed for get attributes of mode_id = %d", color_modes_[i].id);
   1383         continue;
   1384       }
   1385       if (!var.empty()) {
   1386         auto it = color_mode_attr_map_.find(color_modes_[i].name);
   1387         if (it == color_mode_attr_map_.end()) {
   1388           color_mode_attr_map_.insert(std::make_pair(color_modes_[i].name, var));
   1389         }
   1390       }
   1391     }
   1392   }
   1393 
   1394   return kErrorNone;
   1395 }
   1396 
   1397 DisplayError DisplayBase::HandleHDR(LayerStack *layer_stack) {
   1398   DisplayError error = kErrorNone;
   1399 
   1400   if (display_type_ != kPrimary) {
   1401     // Handling is needed for only primary displays
   1402     return kErrorNone;
   1403   }
   1404 
   1405   if (!layer_stack->flags.hdr_present) {
   1406     //  HDR playback off - set prev mode
   1407     if (hdr_playback_mode_) {
   1408       hdr_playback_mode_ = false;
   1409       if (color_mgr_ && !disable_hdr_lut_gen_) {
   1410         // Do not apply HDR Mode when hdr lut generation is disabled
   1411         DLOGI("Setting color mode = %s", current_color_mode_.c_str());
   1412         // HDR playback off - set prev mode
   1413         error = SetColorModeInternal(current_color_mode_);
   1414       }
   1415       comp_manager_->ControlDpps(true);  // Enable Dpps
   1416     }
   1417   } else {
   1418     // hdr is present
   1419     if (!hdr_playback_mode_ && !layer_stack->flags.animating) {
   1420       // hdr is starting
   1421       hdr_playback_mode_ = true;
   1422       if (color_mgr_ && !disable_hdr_lut_gen_) {
   1423         std::string hdr_color_mode;
   1424         if (IsSupportColorModeAttribute(current_color_mode_)) {
   1425           bool found_hdr = false;
   1426           error = GetHdrColorMode(&hdr_color_mode, &found_hdr);
   1427           // try to set "hal-hdr" mode if did not found that
   1428           // the dynamic range of mode is hdr
   1429           if (!found_hdr) {
   1430             hdr_color_mode = "hal_hdr";
   1431           }
   1432         } else {
   1433           hdr_color_mode = "hal_hdr";
   1434         }
   1435         DLOGI("Setting color mode = %s", hdr_color_mode.c_str());
   1436         error = SetColorModeInternal(hdr_color_mode);
   1437       }
   1438       comp_manager_->ControlDpps(false);  // Disable Dpps
   1439     }
   1440   }
   1441 
   1442   return error;
   1443 }
   1444 
   1445 }  // namespace sdm
   1446