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