Home | History | Annotate | Download | only in core
      1 /*
      2 * Copyright (c) 2014 - 2016, 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                          CompManager *comp_manager, RotatorInterface *rotator_intf,
     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), comp_manager_(comp_manager),
     48     rotator_intf_(rotator_intf), 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 = hw_intf_->GetMixerAttributes(&mixer_attributes_);
     63   if (error != kErrorNone) {
     64     return error;
     65   }
     66 
     67   // Override x_pixels and y_pixels of frame buffer with mixer width and height
     68   fb_config_.x_pixels = mixer_attributes_.width;
     69   fb_config_.y_pixels = mixer_attributes_.height;
     70 
     71   HWScaleLutInfo lut_info = {};
     72   error = comp_manager_->GetScaleLutConfig(&lut_info);
     73   if (error == kErrorNone) {
     74     error = hw_intf_->SetScaleLutConfig(&lut_info);
     75   }
     76 
     77   if (error != kErrorNone) {
     78     goto CleanupOnError;
     79   }
     80 
     81   error = comp_manager_->RegisterDisplay(display_type_, display_attributes_, hw_panel_info_,
     82                                          mixer_attributes_, fb_config_, &display_comp_ctx_);
     83   if (error != kErrorNone) {
     84     goto CleanupOnError;
     85   }
     86 
     87   if (rotator_intf_) {
     88     error = rotator_intf_->RegisterDisplay(display_type_, &display_rotator_ctx_);
     89     if (error != kErrorNone) {
     90       goto CleanupOnError;
     91     }
     92   }
     93 
     94   if (hw_info_intf_) {
     95     HWResourceInfo hw_resource_info = HWResourceInfo();
     96     hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
     97     auto max_mixer_stages = hw_resource_info.num_blending_stages;
     98     int property_value = Debug::GetMaxPipesPerMixer(display_type_);
     99     if (property_value >= 0) {
    100       max_mixer_stages = std::min(UINT32(property_value), hw_resource_info.num_blending_stages);
    101     }
    102     DisplayBase::SetMaxMixerStages(max_mixer_stages);
    103   }
    104 
    105   color_mgr_ = ColorManagerProxy::CreateColorManagerProxy(display_type_, hw_intf_,
    106                                display_attributes_, hw_panel_info_);
    107   if (!color_mgr_) {
    108     DLOGW("Unable to create ColorManagerProxy for display = %d", display_type_);
    109   }
    110 
    111   return kErrorNone;
    112 
    113 CleanupOnError:
    114   if (display_comp_ctx_) {
    115     comp_manager_->UnregisterDisplay(display_comp_ctx_);
    116   }
    117 
    118   return error;
    119 }
    120 
    121 DisplayError DisplayBase::Deinit() {
    122   lock_guard<recursive_mutex> obj(recursive_mutex_);
    123   if (rotator_intf_) {
    124     rotator_intf_->UnregisterDisplay(display_rotator_ctx_);
    125   }
    126 
    127   if (color_mgr_) {
    128     delete color_mgr_;
    129     color_mgr_ = NULL;
    130   }
    131 
    132   comp_manager_->UnregisterDisplay(display_comp_ctx_);
    133   HWEventsInterface::Destroy(hw_events_intf_);
    134   HWInterface::Destroy(hw_intf_);
    135 
    136   return kErrorNone;
    137 }
    138 
    139 DisplayError DisplayBase::BuildLayerStackStats(LayerStack *layer_stack) {
    140   std::vector<Layer *> &layers = layer_stack->layers;
    141   HWLayersInfo &hw_layers_info = hw_layers_.info;
    142 
    143   hw_layers_info.stack = layer_stack;
    144 
    145   for (auto &layer : layers) {
    146     if (layer->composition == kCompositionGPUTarget) {
    147       hw_layers_info.gpu_target_index = hw_layers_info.app_layer_count;
    148       break;
    149     }
    150     hw_layers_info.app_layer_count++;
    151   }
    152 
    153   DLOGV_IF(kTagNone, "LayerStack layer_count: %d, app_layer_count: %d, gpu_target_index: %d, "
    154            "display type: %d", layers.size(), hw_layers_info.app_layer_count,
    155            hw_layers_info.gpu_target_index, display_type_);
    156 
    157   if (!hw_layers_info.app_layer_count) {
    158     DLOGE("Layer count is zero");
    159     return kErrorParameters;
    160   }
    161 
    162   if (hw_layers_info.gpu_target_index) {
    163     return ValidateGPUTargetParams();
    164   }
    165 
    166   return kErrorNone;
    167 }
    168 
    169 DisplayError DisplayBase::ValidateGPUTargetParams() {
    170   HWLayersInfo &hw_layers_info = hw_layers_.info;
    171   Layer *gpu_target_layer = hw_layers_info.stack->layers.at(hw_layers_info.gpu_target_index);
    172 
    173   if (!IsValid(gpu_target_layer->src_rect)) {
    174     DLOGE("Invalid src rect for GPU target layer");
    175     return kErrorParameters;
    176   }
    177 
    178   if (!IsValid(gpu_target_layer->dst_rect)) {
    179     DLOGE("Invalid dst rect for GPU target layer");
    180     return kErrorParameters;
    181   }
    182 
    183   float layer_mixer_width = FLOAT(mixer_attributes_.width);
    184   float layer_mixer_height = FLOAT(mixer_attributes_.height);
    185   float fb_width = FLOAT(fb_config_.x_pixels);
    186   float fb_height = FLOAT(fb_config_.y_pixels);
    187   LayerRect src_domain = (LayerRect){0.0f, 0.0f, fb_width, fb_height};
    188   LayerRect dst_domain = (LayerRect){0.0f, 0.0f, layer_mixer_width, layer_mixer_height};
    189   LayerRect out_rect = gpu_target_layer->dst_rect;
    190 
    191   MapRect(src_domain, dst_domain, gpu_target_layer->dst_rect, &out_rect);
    192 
    193   auto gpu_target_layer_dst_xpixels = out_rect.right - out_rect.left;
    194   auto gpu_target_layer_dst_ypixels = out_rect.bottom - out_rect.top;
    195 
    196   if (gpu_target_layer_dst_xpixels > mixer_attributes_.width ||
    197     gpu_target_layer_dst_ypixels > mixer_attributes_.height) {
    198     DLOGE("GPU target layer dst rect is not with in limits gpu wxh %fx%f, mixer wxh %dx%d",
    199                   gpu_target_layer_dst_xpixels, gpu_target_layer_dst_ypixels,
    200                   mixer_attributes_.width, mixer_attributes_.height);
    201     return kErrorParameters;
    202   }
    203 
    204   return kErrorNone;
    205 }
    206 
    207 DisplayError DisplayBase::Prepare(LayerStack *layer_stack) {
    208   lock_guard<recursive_mutex> obj(recursive_mutex_);
    209   DisplayError error = kErrorNone;
    210 
    211   if (!active_) {
    212     return kErrorPermission;
    213   }
    214 
    215   if (!layer_stack) {
    216     return kErrorParameters;
    217   }
    218 
    219   error = BuildLayerStackStats(layer_stack);
    220   if (error != kErrorNone) {
    221     return error;
    222   }
    223 
    224   if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) {
    225     DisablePartialUpdateOneFrame();
    226   }
    227 
    228   if (partial_update_control_ == false || disable_pu_one_frame_) {
    229     comp_manager_->ControlPartialUpdate(display_comp_ctx_, false /* enable */);
    230     disable_pu_one_frame_ = false;
    231   }
    232 
    233   comp_manager_->PrePrepare(display_comp_ctx_, &hw_layers_);
    234   while (true) {
    235     error = comp_manager_->Prepare(display_comp_ctx_, &hw_layers_);
    236     if (error != kErrorNone) {
    237       break;
    238     }
    239 
    240     if (IsRotationRequired(&hw_layers_)) {
    241       if (!rotator_intf_) {
    242         continue;
    243       }
    244       error = rotator_intf_->Prepare(display_rotator_ctx_, &hw_layers_);
    245     } else {
    246       // Release all the previous rotator sessions.
    247       if (rotator_intf_) {
    248         error = rotator_intf_->Purge(display_rotator_ctx_);
    249       }
    250     }
    251 
    252     if (error == kErrorNone) {
    253       error = hw_intf_->Validate(&hw_layers_);
    254       if (error == kErrorNone) {
    255         // Strategy is successful now, wait for Commit().
    256         pending_commit_ = true;
    257         break;
    258       }
    259       if (error == kErrorShutDown) {
    260         comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
    261         return error;
    262       }
    263     }
    264   }
    265 
    266   comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
    267 
    268   return error;
    269 }
    270 
    271 DisplayError DisplayBase::Commit(LayerStack *layer_stack) {
    272   lock_guard<recursive_mutex> obj(recursive_mutex_);
    273   DisplayError error = kErrorNone;
    274 
    275   if (!active_) {
    276     pending_commit_ = false;
    277     return kErrorPermission;
    278   }
    279 
    280   if (!layer_stack) {
    281     return kErrorParameters;
    282   }
    283 
    284   if (!pending_commit_) {
    285     DLOGE("Commit: Corresponding Prepare() is not called for display = %d", display_type_);
    286     return kErrorUndefined;
    287   }
    288 
    289   pending_commit_ = false;
    290 
    291   // Layer stack attributes has changed, need to Reconfigure, currently in use for Hybrid Comp
    292   if (layer_stack->flags.attributes_changed) {
    293     error = comp_manager_->ReConfigure(display_comp_ctx_, &hw_layers_);
    294     if (error != kErrorNone) {
    295       return error;
    296     }
    297 
    298     error = hw_intf_->Validate(&hw_layers_);
    299     if (error != kErrorNone) {
    300         return error;
    301     }
    302   }
    303 
    304   if (rotator_intf_ && IsRotationRequired(&hw_layers_)) {
    305     error = rotator_intf_->Commit(display_rotator_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   if (rotator_intf_ && IsRotationRequired(&hw_layers_)) {
    325     error = rotator_intf_->PostCommit(display_rotator_ctx_, &hw_layers_);
    326     if (error != kErrorNone) {
    327       return error;
    328     }
    329   }
    330 
    331   if (partial_update_control_) {
    332     comp_manager_->ControlPartialUpdate(display_comp_ctx_, true /* enable */);
    333   }
    334 
    335   error = comp_manager_->PostCommit(display_comp_ctx_, &hw_layers_);
    336   if (error != kErrorNone) {
    337     return error;
    338   }
    339 
    340   return kErrorNone;
    341 }
    342 
    343 DisplayError DisplayBase::Flush() {
    344   lock_guard<recursive_mutex> obj(recursive_mutex_);
    345   DisplayError error = kErrorNone;
    346 
    347   if (!active_) {
    348     return kErrorPermission;
    349   }
    350 
    351   hw_layers_.info.count = 0;
    352   error = hw_intf_->Flush();
    353   if (error == kErrorNone) {
    354     // Release all the rotator sessions.
    355     if (rotator_intf_) {
    356       error = rotator_intf_->Purge(display_rotator_ctx_);
    357       if (error != kErrorNone) {
    358         DLOGE("Rotator purge failed for display %d", display_type_);
    359         return error;
    360       }
    361     }
    362 
    363     comp_manager_->Purge(display_comp_ctx_);
    364 
    365     pending_commit_ = false;
    366   } else {
    367     DLOGW("Unable to flush display = %d", display_type_);
    368   }
    369 
    370   return error;
    371 }
    372 
    373 DisplayError DisplayBase::GetDisplayState(DisplayState *state) {
    374   lock_guard<recursive_mutex> obj(recursive_mutex_);
    375   if (!state) {
    376     return kErrorParameters;
    377   }
    378 
    379   *state = state_;
    380   return kErrorNone;
    381 }
    382 
    383 DisplayError DisplayBase::GetNumVariableInfoConfigs(uint32_t *count) {
    384   lock_guard<recursive_mutex> obj(recursive_mutex_);
    385   return hw_intf_->GetNumDisplayAttributes(count);
    386 }
    387 
    388 DisplayError DisplayBase::GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info) {
    389   lock_guard<recursive_mutex> obj(recursive_mutex_);
    390   HWDisplayAttributes attrib;
    391   if (hw_intf_->GetDisplayAttributes(index, &attrib) == kErrorNone) {
    392     *variable_info = attrib;
    393     return kErrorNone;
    394   }
    395 
    396   return kErrorNotSupported;
    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   switch (state) {
    428   case kStateOff:
    429     hw_layers_.info.count = 0;
    430     error = hw_intf_->Flush();
    431     if (error == kErrorNone) {
    432       // Release all the rotator sessions.
    433       if (rotator_intf_) {
    434         error = rotator_intf_->Purge(display_rotator_ctx_);
    435         if (error != kErrorNone) {
    436           DLOGE("Rotator purge failed for display %d", display_type_);
    437           return error;
    438         }
    439       }
    440 
    441       comp_manager_->Purge(display_comp_ctx_);
    442 
    443       error = hw_intf_->PowerOff();
    444     }
    445     break;
    446 
    447   case kStateOn:
    448     error = hw_intf_->PowerOn();
    449     active = true;
    450     break;
    451 
    452   case kStateDoze:
    453     error = hw_intf_->Doze();
    454     active = true;
    455     break;
    456 
    457   case kStateDozeSuspend:
    458     error = hw_intf_->DozeSuspend();
    459     break;
    460 
    461   case kStateStandby:
    462     error = hw_intf_->Standby();
    463     break;
    464 
    465   default:
    466     DLOGE("Spurious state = %d transition requested.", state);
    467     break;
    468   }
    469 
    470   if (error == kErrorNone) {
    471     active_ = active;
    472     state_ = state;
    473   }
    474 
    475   return error;
    476 }
    477 
    478 DisplayError DisplayBase::SetActiveConfig(uint32_t index) {
    479   lock_guard<recursive_mutex> obj(recursive_mutex_);
    480   DisplayError error = kErrorNone;
    481   uint32_t active_index = 0;
    482 
    483   hw_intf_->GetActiveConfig(&active_index);
    484 
    485   if (active_index == index) {
    486     return kErrorNone;
    487   }
    488 
    489   error = hw_intf_->SetDisplayAttributes(index);
    490   if (error != kErrorNone) {
    491     return error;
    492   }
    493 
    494   return ReconfigureDisplay();
    495 }
    496 
    497 DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) {
    498   lock_guard<recursive_mutex> obj(recursive_mutex_);
    499   DisplayError error = kErrorNone;
    500 
    501   error = comp_manager_->SetMaxMixerStages(display_comp_ctx_, max_mixer_stages);
    502 
    503   if (error == kErrorNone) {
    504     max_mixer_stages_ = max_mixer_stages;
    505   }
    506 
    507   return error;
    508 }
    509 
    510 void DisplayBase::AppendDump(char *buffer, uint32_t length) {
    511   lock_guard<recursive_mutex> obj(recursive_mutex_);
    512   HWDisplayAttributes attrib;
    513   uint32_t active_index = 0;
    514   uint32_t num_modes = 0;
    515   hw_intf_->GetNumDisplayAttributes(&num_modes);
    516   hw_intf_->GetActiveConfig(&active_index);
    517   hw_intf_->GetDisplayAttributes(active_index, &attrib);
    518 
    519   DumpImpl::AppendString(buffer, length, "\n-----------------------");
    520   DumpImpl::AppendString(buffer, length, "\ndevice type: %u", display_type_);
    521   DumpImpl::AppendString(buffer, length, "\nstate: %u, vsync on: %u, max. mixer stages: %u",
    522                          state_, INT(vsync_enable_), max_mixer_stages_);
    523   DumpImpl::AppendString(buffer, length, "\nnum configs: %u, active config index: %u",
    524                          num_modes, active_index);
    525 
    526   DisplayConfigVariableInfo &info = attrib;
    527 
    528   uint32_t num_hw_layers = 0;
    529   if (hw_layers_.info.stack) {
    530     num_hw_layers = hw_layers_.info.count;
    531   }
    532 
    533   if (num_hw_layers == 0) {
    534     DumpImpl::AppendString(buffer, length, "\nNo hardware layers programmed");
    535     return;
    536   }
    537 
    538   LayerBuffer *out_buffer = hw_layers_.info.stack->output_buffer;
    539   if (out_buffer) {
    540     DumpImpl::AppendString(buffer, length, "\nres:%u x %u format: %s", out_buffer->width,
    541                            out_buffer->height, GetFormatString(out_buffer->format));
    542   } else {
    543     DumpImpl::AppendString(buffer, length, "\nres:%u x %u, dpi:%.2f x %.2f, fps:%u,"
    544                            "vsync period: %u", info.x_pixels, info.y_pixels, info.x_dpi,
    545                            info.y_dpi, info.fps, info.vsync_period_ns);
    546   }
    547 
    548   DumpImpl::AppendString(buffer, length, "\n");
    549 
    550   HWLayersInfo &layer_info = hw_layers_.info;
    551   LayerRect &l_roi = layer_info.left_partial_update;
    552   LayerRect &r_roi = layer_info.right_partial_update;
    553   DumpImpl::AppendString(buffer, length, "\nROI(L T R B) : LEFT(%d %d %d %d)", INT(l_roi.left),
    554                          INT(l_roi.top), INT(l_roi.right), INT(l_roi.bottom));
    555 
    556   if (IsValid(r_roi)) {
    557     DumpImpl::AppendString(buffer, length, ", RIGHT(%d %d %d %d)", INT(r_roi.left),
    558                            INT(r_roi.top), INT(r_roi.right), INT(r_roi.bottom));
    559   }
    560 
    561   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 |";  //NOLINT
    562   const char *newline = "\n|-----|-------------|--------|----|-------|-------------|--------------------------|---------------------|---------------------|----|------------|-----------|----|";  //NOLINT
    563   const char *format  = "\n| %3s | %11s "     "| %6s " "| %2s | 0x%03x | %4d x %4d | %24s "                  "| %4d %4d %4d %4d "  "| %4d %4d %4d %4d "  "| %2s | %10s "   "| %9s | %2s |";  //NOLINT
    564 
    565   DumpImpl::AppendString(buffer, length, "\n");
    566   DumpImpl::AppendString(buffer, length, newline);
    567   DumpImpl::AppendString(buffer, length, header);
    568   DumpImpl::AppendString(buffer, length, newline);
    569 
    570   for (uint32_t i = 0; i < num_hw_layers; i++) {
    571     uint32_t layer_index = hw_layers_.info.index[i];
    572     Layer *layer = hw_layers_.info.stack->layers.at(layer_index);
    573     LayerBuffer *input_buffer = layer->input_buffer;
    574     HWLayerConfig &layer_config = hw_layers_.config[i];
    575     HWRotatorSession &hw_rotator_session = layer_config.hw_rotator_session;
    576 
    577     char idx[8] = { 0 };
    578     const char *comp_type = GetName(layer->composition);
    579     const char *buffer_format = GetFormatString(input_buffer->format);
    580     const char *rotate_split[2] = { "Rot-1", "Rot-2" };
    581     const char *comp_split[2] = { "Comp-1", "Comp-2" };
    582 
    583     snprintf(idx, sizeof(idx), "%d", layer_index);
    584 
    585     for (uint32_t count = 0; count < hw_rotator_session.hw_block_count; count++) {
    586       char writeback_id[8] = { 0 };
    587       HWRotateInfo &rotate = hw_rotator_session.hw_rotate_info[count];
    588       LayerRect &src_roi = rotate.src_roi;
    589       LayerRect &dst_roi = rotate.dst_roi;
    590 
    591       snprintf(writeback_id, sizeof(writeback_id), "%d", rotate.writeback_id);
    592 
    593       DumpImpl::AppendString(buffer, length, format, idx, comp_type, rotate_split[count],
    594                              writeback_id, rotate.pipe_id, input_buffer->width,
    595                              input_buffer->height, buffer_format, INT(src_roi.left),
    596                              INT(src_roi.top), INT(src_roi.right), INT(src_roi.bottom),
    597                              INT(dst_roi.left), INT(dst_roi.top), INT(dst_roi.right),
    598                              INT(dst_roi.bottom), "-", "-    ", "-    ", "-");
    599 
    600       // print the below only once per layer block, fill with spaces for rest.
    601       idx[0] = 0;
    602       comp_type = "";
    603     }
    604 
    605     if (hw_rotator_session.hw_block_count > 0) {
    606       input_buffer = &hw_rotator_session.output_buffer;
    607       buffer_format = GetFormatString(input_buffer->format);
    608     }
    609 
    610     for (uint32_t count = 0; count < 2; count++) {
    611       char decimation[16] = { 0 };
    612       char flags[16] = { 0 };
    613       char z_order[8] = { 0 };
    614       char csc[8] = { 0 };
    615 
    616       HWPipeInfo &pipe = (count == 0) ? layer_config.left_pipe : layer_config.right_pipe;
    617 
    618       if (!pipe.valid) {
    619         continue;
    620       }
    621 
    622       LayerRect &src_roi = pipe.src_roi;
    623       LayerRect &dst_roi = pipe.dst_roi;
    624 
    625       snprintf(z_order, sizeof(z_order), "%d", pipe.z_order);
    626       snprintf(flags, sizeof(flags), "0x%08x", layer->flags.flags);
    627       snprintf(decimation, sizeof(decimation), "%3d x %3d", pipe.horizontal_decimation,
    628                pipe.vertical_decimation);
    629       snprintf(csc, sizeof(csc), "%d", layer->input_buffer->csc);
    630 
    631       DumpImpl::AppendString(buffer, length, format, idx, comp_type, comp_split[count],
    632                              "-", pipe.pipe_id, input_buffer->width, input_buffer->height,
    633                              buffer_format, INT(src_roi.left), INT(src_roi.top),
    634                              INT(src_roi.right), INT(src_roi.bottom), INT(dst_roi.left),
    635                              INT(dst_roi.top), INT(dst_roi.right), INT(dst_roi.bottom),
    636                              z_order, flags, decimation, csc);
    637 
    638       // print the below only once per layer block, fill with spaces for rest.
    639       idx[0] = 0;
    640       comp_type = "";
    641     }
    642 
    643     DumpImpl::AppendString(buffer, length, newline);
    644   }
    645 }
    646 
    647 bool DisplayBase::IsRotationRequired(HWLayers *hw_layers) {
    648   lock_guard<recursive_mutex> obj(recursive_mutex_);
    649   HWLayersInfo &layer_info = hw_layers->info;
    650 
    651   for (uint32_t i = 0; i < layer_info.count; i++) {
    652     HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
    653 
    654     if (hw_rotator_session->hw_block_count) {
    655       return true;
    656     }
    657   }
    658 
    659   return false;
    660 }
    661 
    662 const char * DisplayBase::GetName(const LayerComposition &composition) {
    663   switch (composition) {
    664   case kCompositionGPU:         return "GPU";
    665   case kCompositionSDE:         return "SDE";
    666   case kCompositionHWCursor:    return "CURSOR";
    667   case kCompositionHybrid:      return "HYBRID";
    668   case kCompositionBlit:        return "BLIT";
    669   case kCompositionGPUTarget:   return "GPU_TARGET";
    670   case kCompositionBlitTarget:  return "BLIT_TARGET";
    671   default:                      return "UNKNOWN";
    672   }
    673 }
    674 
    675 DisplayError DisplayBase::ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
    676                                                PPDisplayAPIPayload *out_payload,
    677                                                PPPendingParams *pending_action) {
    678   lock_guard<recursive_mutex> obj(recursive_mutex_);
    679   if (color_mgr_)
    680     return color_mgr_->ColorSVCRequestRoute(in_payload, out_payload, pending_action);
    681   else
    682     return kErrorParameters;
    683 }
    684 
    685 DisplayError DisplayBase::GetColorModeCount(uint32_t *mode_count) {
    686   lock_guard<recursive_mutex> obj(recursive_mutex_);
    687   if (!mode_count) {
    688     return kErrorParameters;
    689   }
    690 
    691   if (!color_mgr_) {
    692     return kErrorNotSupported;
    693   }
    694 
    695   DisplayError error = color_mgr_->ColorMgrGetNumOfModes(&num_color_modes_);
    696   if (error != kErrorNone || !num_color_modes_) {
    697     return kErrorNotSupported;
    698   }
    699 
    700   DLOGV_IF(kTagQDCM, "Number of modes from color manager = %d", num_color_modes_);
    701   *mode_count = num_color_modes_;
    702 
    703   return kErrorNone;
    704 }
    705 
    706 DisplayError DisplayBase::GetColorModes(uint32_t *mode_count,
    707                                         std::vector<std::string> *color_modes) {
    708   lock_guard<recursive_mutex> obj(recursive_mutex_);
    709   if (!mode_count || !color_modes) {
    710     return kErrorParameters;
    711   }
    712 
    713   if (!color_mgr_) {
    714     return kErrorNotSupported;
    715   }
    716 
    717   if (!color_modes_.size()) {
    718     color_modes_.resize(num_color_modes_);
    719 
    720     DisplayError error = color_mgr_->ColorMgrGetModes(&num_color_modes_, color_modes_.data());
    721     if (error != kErrorNone) {
    722       DLOGE("Failed");
    723       return error;
    724     }
    725 
    726     for (uint32_t i = 0; i < num_color_modes_; i++) {
    727       DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
    728                color_modes_[i].id);
    729       auto it = color_mode_map_.find(color_modes_[i].name);
    730       if (it != color_mode_map_.end()) {
    731         if (it->second->id < color_modes_[i].id) {
    732           color_mode_map_.erase(it);
    733           color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
    734         }
    735       } else {
    736         color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
    737       }
    738     }
    739   }
    740 
    741   for (uint32_t i = 0; i < num_color_modes_; i++) {
    742     DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
    743              color_modes_[i].id);
    744     color_modes->at(i) = color_modes_[i].name;
    745   }
    746 
    747   return kErrorNone;
    748 }
    749 
    750 DisplayError DisplayBase::SetColorMode(const std::string &color_mode) {
    751   lock_guard<recursive_mutex> obj(recursive_mutex_);
    752   if (!color_mgr_) {
    753     return kErrorNotSupported;
    754   }
    755 
    756   DLOGV_IF(kTagQDCM, "Color Mode = %s", color_mode.c_str());
    757 
    758   ColorModeMap::iterator it = color_mode_map_.find(color_mode);
    759   if (it == color_mode_map_.end()) {
    760     DLOGE("Failed: Unknown Mode : %s", color_mode.c_str());
    761     return kErrorNotSupported;
    762   }
    763 
    764   SDEDisplayMode *sde_display_mode = it->second;
    765 
    766   DLOGD("Color Mode Name = %s corresponding mode_id = %d", sde_display_mode->name,
    767            sde_display_mode->id);
    768   DisplayError error = kErrorNone;
    769   error = color_mgr_->ColorMgrSetMode(sde_display_mode->id);
    770   if (error != kErrorNone) {
    771     DLOGE("Failed for mode id = %d", sde_display_mode->id);
    772     return error;
    773   }
    774 
    775   return error;
    776 }
    777 
    778 DisplayError DisplayBase::SetColorTransform(const uint32_t length, const double *color_transform) {
    779   lock_guard<recursive_mutex> obj(recursive_mutex_);
    780   if (!color_mgr_) {
    781     return kErrorNotSupported;
    782   }
    783 
    784   if (!color_transform) {
    785     return kErrorParameters;
    786   }
    787 
    788   return color_mgr_->ColorMgrSetColorTransform(length, color_transform);
    789 }
    790 
    791 DisplayError DisplayBase::ApplyDefaultDisplayMode() {
    792   lock_guard<recursive_mutex> obj(recursive_mutex_);
    793   if (color_mgr_)
    794     return color_mgr_->ApplyDefaultDisplayMode();
    795   else
    796     return kErrorParameters;
    797 }
    798 
    799 DisplayError DisplayBase::SetCursorPosition(int x, int y) {
    800   lock_guard<recursive_mutex> obj(recursive_mutex_);
    801   if (state_ != kStateOn) {
    802     return kErrorNotSupported;
    803   }
    804 
    805   DisplayError error = comp_manager_->ValidateCursorPosition(display_comp_ctx_, &hw_layers_, x, y);
    806   if (error == kErrorNone) {
    807     return hw_intf_->SetCursorPosition(&hw_layers_, x, y);
    808   }
    809 
    810   return kErrorNone;
    811 }
    812 
    813 DisplayError DisplayBase::GetRefreshRateRange(uint32_t *min_refresh_rate,
    814                                               uint32_t *max_refresh_rate) {
    815   lock_guard<recursive_mutex> obj(recursive_mutex_);
    816   // The min and max refresh rates will be same when the HWPanelInfo does not contain valid rates.
    817   // Usually for secondary displays, command mode panels
    818   HWDisplayAttributes display_attributes;
    819   uint32_t active_index = 0;
    820   hw_intf_->GetActiveConfig(&active_index);
    821   DisplayError error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
    822   if (error) {
    823     return error;
    824   }
    825 
    826   *min_refresh_rate = display_attributes.fps;
    827   *max_refresh_rate = display_attributes.fps;
    828 
    829   return error;
    830 }
    831 
    832 DisplayError DisplayBase::SetVSyncState(bool enable) {
    833   lock_guard<recursive_mutex> obj(recursive_mutex_);
    834   DisplayError error = kErrorNone;
    835   if (vsync_enable_ != enable) {
    836     error = hw_intf_->SetVSyncState(enable);
    837     if (error == kErrorNone) {
    838       vsync_enable_ = enable;
    839     }
    840   }
    841   return error;
    842 }
    843 
    844 DisplayError DisplayBase::ReconfigureDisplay() {
    845   lock_guard<recursive_mutex> obj(recursive_mutex_);
    846   DisplayError error = kErrorNone;
    847   HWDisplayAttributes display_attributes;
    848   HWMixerAttributes mixer_attributes;
    849   HWPanelInfo hw_panel_info;
    850   uint32_t active_index = 0;
    851 
    852   error = hw_intf_->GetActiveConfig(&active_index);
    853   if (error != kErrorNone) {
    854     return error;
    855   }
    856 
    857   error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
    858   if (error != kErrorNone) {
    859     return error;
    860   }
    861 
    862   error = hw_intf_->GetMixerAttributes(&mixer_attributes);
    863   if (error != kErrorNone) {
    864     return error;
    865   }
    866 
    867   error = hw_intf_->GetHWPanelInfo(&hw_panel_info);
    868   if (error != kErrorNone) {
    869     return error;
    870   }
    871 
    872   if (display_attributes == display_attributes_ && mixer_attributes == mixer_attributes_ &&
    873       hw_panel_info == hw_panel_info_) {
    874     return kErrorNone;
    875   }
    876 
    877   error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info,
    878                                             mixer_attributes, fb_config_);
    879   if (error != kErrorNone) {
    880     return error;
    881   }
    882 
    883   if (mixer_attributes != mixer_attributes_) {
    884     DisablePartialUpdateOneFrame();
    885   }
    886 
    887   display_attributes_ = display_attributes;
    888   mixer_attributes_ = mixer_attributes;
    889   hw_panel_info_ = hw_panel_info;
    890 
    891   return kErrorNone;
    892 }
    893 
    894 DisplayError DisplayBase::SetMixerResolution(uint32_t width, uint32_t height) {
    895   lock_guard<recursive_mutex> obj(recursive_mutex_);
    896   return ReconfigureMixer(width, height);
    897 }
    898 
    899 DisplayError DisplayBase::GetMixerResolution(uint32_t *width, uint32_t *height) {
    900   lock_guard<recursive_mutex> obj(recursive_mutex_);
    901   if (!width || !height) {
    902     return kErrorParameters;
    903   }
    904 
    905   *width = mixer_attributes_.width;
    906   *height = mixer_attributes_.height;
    907 
    908   return kErrorNone;
    909 }
    910 
    911 DisplayError DisplayBase::ReconfigureMixer(uint32_t width, uint32_t height) {
    912   lock_guard<recursive_mutex> obj(recursive_mutex_);
    913   DisplayError error = kErrorNone;
    914 
    915   HWMixerAttributes mixer_attributes;
    916   mixer_attributes.width = width;
    917   mixer_attributes.height = height;
    918 
    919   error = hw_intf_->SetMixerAttributes(mixer_attributes);
    920   if (error != kErrorNone) {
    921     return error;
    922   }
    923 
    924   return ReconfigureDisplay();
    925 }
    926 
    927 bool DisplayBase::NeedsMixerReconfiguration(LayerStack *layer_stack, uint32_t *new_mixer_width,
    928                                             uint32_t *new_mixer_height) {
    929   lock_guard<recursive_mutex> obj(recursive_mutex_);
    930   uint32_t layer_count = UINT32(layer_stack->layers.size());
    931 
    932   uint32_t fb_width  = fb_config_.x_pixels;
    933   uint32_t fb_height  = fb_config_.y_pixels;
    934   uint32_t fb_area = fb_width * fb_height;
    935   LayerRect fb_rect = (LayerRect) {0.0f, 0.0f, FLOAT(fb_width), FLOAT(fb_height)};
    936   uint32_t mixer_width = mixer_attributes_.width;
    937   uint32_t mixer_height = mixer_attributes_.height;
    938 
    939   RectOrientation fb_orientation = GetOrientation(fb_rect);
    940   uint32_t max_layer_area = 0;
    941   uint32_t max_area_layer_index = 0;
    942   std::vector<Layer *> layers = layer_stack->layers;
    943 
    944   for (uint32_t i = 0; i < layer_count; i++) {
    945     Layer *layer = layers.at(i);
    946     LayerBuffer *layer_buffer = layer->input_buffer;
    947 
    948     if (!layer_buffer->flags.video) {
    949       continue;
    950     }
    951 
    952     uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
    953     uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
    954     uint32_t layer_area = layer_width * layer_height;
    955 
    956     if (layer_area > max_layer_area) {
    957       max_layer_area = layer_area;
    958       max_area_layer_index = i;
    959     }
    960   }
    961 
    962   if (max_layer_area > fb_area) {
    963     Layer *layer = layers.at(max_area_layer_index);
    964 
    965     uint32_t layer_width = UINT32(layer->src_rect.right - layer->src_rect.left);
    966     uint32_t layer_height = UINT32(layer->src_rect.bottom - layer->src_rect.top);
    967     LayerRect layer_rect = (LayerRect){0.0f, 0.0f, FLOAT(layer_width), FLOAT(layer_height)};
    968 
    969     RectOrientation layer_orientation = GetOrientation(layer_rect);
    970     if (layer_orientation != kOrientationUnknown &&
    971         fb_orientation != kOrientationUnknown) {
    972       if (layer_orientation != fb_orientation) {
    973         std::swap(layer_width, layer_height);
    974       }
    975     }
    976 
    977     // Align the width and height according to fb's aspect ratio
    978     layer_width = UINT32((FLOAT(fb_width) / FLOAT(fb_height)) * layer_height);
    979 
    980     *new_mixer_width = layer_width;
    981     *new_mixer_height = layer_height;
    982 
    983     return true;
    984   } else {
    985     if (fb_width != mixer_width || fb_height != mixer_height) {
    986       *new_mixer_width = fb_width;
    987       *new_mixer_height = fb_height;
    988 
    989       return true;
    990     }
    991   }
    992 
    993   return false;
    994 }
    995 
    996 DisplayError DisplayBase::SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info) {
    997   lock_guard<recursive_mutex> obj(recursive_mutex_);
    998   uint32_t width = variable_info.x_pixels;
    999   uint32_t height = variable_info.y_pixels;
   1000 
   1001   if (width == 0 || height == 0) {
   1002     DLOGE("Unsupported resolution: (%dx%d)", width, height);
   1003     return kErrorParameters;
   1004   }
   1005 
   1006   // Create rects to represent the new source and destination crops
   1007   LayerRect crop = LayerRect(0, 0, FLOAT(width), FLOAT(height));
   1008   LayerRect dst = LayerRect(0, 0, FLOAT(mixer_attributes_.width), FLOAT(mixer_attributes_.height));
   1009   // Set rotate90 to false since this is taken care of during regular composition.
   1010   bool rotate90 = false;
   1011 
   1012   DisplayError error = comp_manager_->ValidateScaling(crop, dst, rotate90);
   1013   if (error != kErrorNone) {
   1014     DLOGE("Unsupported resolution: (%dx%d)", width, height);
   1015     return kErrorParameters;
   1016   }
   1017 
   1018   error =  comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_, hw_panel_info_,
   1019                                              mixer_attributes_, variable_info);
   1020   if (error != kErrorNone) {
   1021     return error;
   1022   }
   1023 
   1024   fb_config_.x_pixels = width;
   1025   fb_config_.y_pixels = height;
   1026 
   1027   DLOGI("New framebuffer resolution (%dx%d)", fb_config_.x_pixels, fb_config_.y_pixels);
   1028 
   1029   return kErrorNone;
   1030 }
   1031 
   1032 DisplayError DisplayBase::GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info) {
   1033   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1034   if (!variable_info) {
   1035     return kErrorParameters;
   1036   }
   1037 
   1038   *variable_info = fb_config_;
   1039 
   1040   return kErrorNone;
   1041 }
   1042 
   1043 DisplayError DisplayBase::SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) {
   1044   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1045   DisplayError error = comp_manager_->SetDetailEnhancerData(display_comp_ctx_, de_data);
   1046   if (error != kErrorNone) {
   1047     return error;
   1048   }
   1049 
   1050   DisablePartialUpdateOneFrame();
   1051 
   1052   return kErrorNone;
   1053 }
   1054 
   1055 DisplayError DisplayBase::GetDisplayPort(DisplayPort *port) {
   1056   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1057 
   1058   if (!port) {
   1059     return kErrorParameters;
   1060   }
   1061 
   1062   *port = hw_panel_info_.port;
   1063 
   1064   return kErrorNone;
   1065 }
   1066 
   1067 bool DisplayBase::IsPrimaryDisplay() {
   1068   lock_guard<recursive_mutex> obj(recursive_mutex_);
   1069 
   1070   return hw_panel_info_.is_primary_panel;
   1071 }
   1072 
   1073 }  // namespace sdm
   1074