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