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