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 <utils/constants.h>
     26 #include <utils/debug.h>
     27 #include <utils/rect.h>
     28 #include <map>
     29 #include <algorithm>
     30 #include <functional>
     31 #include <vector>
     32 
     33 #include "display_primary.h"
     34 #include "hw_interface.h"
     35 #include "hw_info_interface.h"
     36 
     37 #define __CLASS__ "DisplayPrimary"
     38 
     39 namespace sdm {
     40 
     41 DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
     42                                BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager)
     43   : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, comp_manager,
     44                 hw_info_intf) {
     45 }
     46 
     47 DisplayError DisplayPrimary::Init() {
     48   lock_guard<recursive_mutex> obj(recursive_mutex_);
     49 
     50   DisplayError error = HWInterface::Create(kPrimary, hw_info_intf_, buffer_sync_handler_,
     51                                            &hw_intf_);
     52   if (error != kErrorNone) {
     53     return error;
     54   }
     55 
     56   error = DisplayBase::Init();
     57   if (error != kErrorNone) {
     58     HWInterface::Destroy(hw_intf_);
     59     return error;
     60   }
     61 
     62   if (hw_panel_info_.mode == kModeCommand && Debug::IsVideoModeEnabled()) {
     63     error = hw_intf_->SetDisplayMode(kModeVideo);
     64     if (error != kErrorNone) {
     65       DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
     66             kModeVideo);
     67     }
     68   }
     69 
     70   avr_prop_disabled_ = Debug::IsAVRDisabled();
     71 
     72   error = HWEventsInterface::Create(INT(display_type_), this, event_list_, &hw_events_intf_);
     73   if (error != kErrorNone) {
     74     DLOGE("Failed to create hardware events interface. Error = %d", error);
     75     DisplayBase::Deinit();
     76     HWInterface::Destroy(hw_intf_);
     77   }
     78 
     79   return error;
     80 }
     81 
     82 DisplayError DisplayPrimary::Prepare(LayerStack *layer_stack) {
     83   lock_guard<recursive_mutex> obj(recursive_mutex_);
     84   DisplayError error = kErrorNone;
     85   uint32_t new_mixer_width = 0;
     86   uint32_t new_mixer_height = 0;
     87   uint32_t display_width = display_attributes_.x_pixels;
     88   uint32_t display_height = display_attributes_.y_pixels;
     89   bool needs_hv_flip = hw_panel_info_.panel_orientation.flip_horizontal &&
     90                           hw_panel_info_.panel_orientation.flip_vertical;
     91   LayerRect src_domain = {};
     92   LayerTransform panel_transform = {};
     93   DisplayConfigVariableInfo variable_info = {};
     94 
     95   if (needs_hv_flip) {
     96     DisplayBase::GetFrameBufferConfig(&variable_info);
     97     src_domain.right = variable_info.x_pixels;
     98     src_domain.bottom = variable_info.y_pixels;
     99     panel_transform.flip_horizontal = hw_panel_info_.panel_orientation.flip_horizontal;
    100     panel_transform.flip_vertical = hw_panel_info_.panel_orientation.flip_vertical;
    101 
    102     for (Layer *layer : layer_stack->layers) {
    103       // Modify destination based on panel flip
    104       TransformHV(src_domain, layer->dst_rect, panel_transform, &layer->dst_rect);
    105 
    106       if (layer->flags.solid_fill) {
    107         continue;
    108       }
    109 
    110       layer->transform.flip_horizontal ^= (hw_panel_info_.panel_orientation.flip_horizontal);
    111       layer->transform.flip_vertical ^= (hw_panel_info_.panel_orientation.flip_vertical);
    112      // TODO(user): Check how to handle rotation, if panel has rotation.
    113     }
    114   }
    115 
    116   if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
    117     error = ReconfigureMixer(new_mixer_width, new_mixer_height);
    118     if (error != kErrorNone) {
    119       ReconfigureMixer(display_width, display_height);
    120     }
    121   }
    122 
    123   // Clean hw layers for reuse.
    124   hw_layers_ = HWLayers();
    125   hw_layers_.hw_avr_info.enable = NeedsAVREnable();
    126 
    127   return DisplayBase::Prepare(layer_stack);
    128 }
    129 
    130 DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) {
    131   lock_guard<recursive_mutex> obj(recursive_mutex_);
    132   DisplayError error = kErrorNone;
    133   uint32_t app_layer_count = hw_layers_.info.app_layer_count;
    134 
    135   // Enabling auto refresh is async and needs to happen before commit ioctl
    136   if (hw_panel_info_.mode == kModeCommand) {
    137     bool enable = (app_layer_count == 1) && layer_stack->flags.single_buffered_layer_present;
    138     bool need_refresh = layer_stack->flags.single_buffered_layer_present && (app_layer_count > 1);
    139 
    140     hw_intf_->SetAutoRefresh(enable);
    141     if (need_refresh) {
    142       event_handler_->Refresh();
    143     }
    144   }
    145 
    146   error = DisplayBase::Commit(layer_stack);
    147   if (error != kErrorNone) {
    148     return error;
    149   }
    150 
    151   DisplayBase::ReconfigureDisplay();
    152 
    153   int idle_time_ms = hw_layers_.info.set_idle_time_ms;
    154   if (idle_time_ms >= 0) {
    155     hw_intf_->SetIdleTimeoutMs(UINT32(idle_time_ms));
    156   }
    157 
    158   if (switch_to_cmd_) {
    159     uint32_t pending;
    160     switch_to_cmd_ = false;
    161     ControlPartialUpdate(true /* enable */, &pending);
    162   }
    163 
    164   return error;
    165 }
    166 
    167 DisplayError DisplayPrimary::SetDisplayState(DisplayState state) {
    168   lock_guard<recursive_mutex> obj(recursive_mutex_);
    169   DisplayError error = kErrorNone;
    170   error = DisplayBase::SetDisplayState(state);
    171   if (error != kErrorNone) {
    172     return error;
    173   }
    174 
    175   // Set vsync enable state to false, as driver disables vsync during display power off.
    176   if (state == kStateOff) {
    177     vsync_enable_ = false;
    178   }
    179 
    180   return kErrorNone;
    181 }
    182 
    183 void DisplayPrimary::SetIdleTimeoutMs(uint32_t active_ms) {
    184   lock_guard<recursive_mutex> obj(recursive_mutex_);
    185 
    186   if (comp_manager_->SetIdleTimeoutMs(display_comp_ctx_, active_ms) == kErrorNone) {
    187     hw_intf_->SetIdleTimeoutMs(active_ms);
    188   }
    189 }
    190 
    191 DisplayError DisplayPrimary::SetDisplayMode(uint32_t mode) {
    192   DisplayError error = kErrorNone;
    193 
    194   // Limit scope of mutex to this block
    195   {
    196     lock_guard<recursive_mutex> obj(recursive_mutex_);
    197     HWDisplayMode hw_display_mode = static_cast<HWDisplayMode>(mode);
    198     uint32_t pending = 0;
    199 
    200     if (!active_) {
    201       DLOGW("Invalid display state = %d. Panel must be on.", state_);
    202       return kErrorNotSupported;
    203     }
    204 
    205     if (hw_display_mode != kModeCommand && hw_display_mode != kModeVideo) {
    206       DLOGW("Invalid panel mode parameters. Requested = %d", hw_display_mode);
    207       return kErrorParameters;
    208     }
    209 
    210     if (hw_display_mode == hw_panel_info_.mode) {
    211       DLOGW("Same display mode requested. Current = %d, Requested = %d", hw_panel_info_.mode,
    212             hw_display_mode);
    213       return kErrorNone;
    214     }
    215 
    216     error = hw_intf_->SetDisplayMode(hw_display_mode);
    217     if (error != kErrorNone) {
    218       DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
    219             hw_display_mode);
    220       return error;
    221     }
    222 
    223     if (mode == kModeVideo) {
    224       ControlPartialUpdate(false /* enable */, &pending);
    225     } else if (mode == kModeCommand) {
    226       // Flush idle timeout value currently set.
    227       hw_intf_->SetIdleTimeoutMs(0);
    228       switch_to_cmd_ = true;
    229     }
    230   }
    231 
    232   // Request for a new draw cycle. New display mode will get applied on next draw cycle.
    233   // New idle time will get configured as part of this.
    234   event_handler_->Refresh();
    235 
    236   return error;
    237 }
    238 
    239 DisplayError DisplayPrimary::SetPanelBrightness(int level) {
    240   lock_guard<recursive_mutex> obj(recursive_mutex_);
    241   return hw_intf_->SetPanelBrightness(level);
    242 }
    243 
    244 DisplayError DisplayPrimary::CachePanelBrightness(int level) {
    245   lock_guard<recursive_mutex> obj(recursive_mutex_);
    246   return hw_intf_->CachePanelBrightness(level);
    247 }
    248 
    249 DisplayError DisplayPrimary::GetRefreshRateRange(uint32_t *min_refresh_rate,
    250                                                  uint32_t *max_refresh_rate) {
    251   lock_guard<recursive_mutex> obj(recursive_mutex_);
    252   DisplayError error = kErrorNone;
    253 
    254   if (hw_panel_info_.min_fps && hw_panel_info_.max_fps) {
    255     *min_refresh_rate = hw_panel_info_.min_fps;
    256     *max_refresh_rate = hw_panel_info_.max_fps;
    257   } else {
    258     error = DisplayBase::GetRefreshRateRange(min_refresh_rate, max_refresh_rate);
    259   }
    260 
    261   return error;
    262 }
    263 
    264 DisplayError DisplayPrimary::SetRefreshRate(uint32_t refresh_rate) {
    265   lock_guard<recursive_mutex> obj(recursive_mutex_);
    266 
    267   if (!active_ || !hw_panel_info_.dynamic_fps) {
    268     return kErrorNotSupported;
    269   }
    270 
    271   if (refresh_rate < hw_panel_info_.min_fps || refresh_rate > hw_panel_info_.max_fps) {
    272     DLOGE("Invalid Fps = %d request", refresh_rate);
    273     return kErrorParameters;
    274   }
    275 
    276   DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
    277   if (error != kErrorNone) {
    278     return error;
    279   }
    280 
    281   return DisplayBase::ReconfigureDisplay();
    282 }
    283 
    284 DisplayError DisplayPrimary::VSync(int64_t timestamp) {
    285   if (vsync_enable_) {
    286     DisplayEventVSync vsync;
    287     vsync.timestamp = timestamp;
    288     event_handler_->VSync(vsync);
    289   }
    290 
    291   return kErrorNone;
    292 }
    293 
    294 void DisplayPrimary::IdleTimeout() {
    295   event_handler_->Refresh();
    296   comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
    297   needs_validate_.set();
    298 }
    299 
    300 void DisplayPrimary::PingPongTimeout() {
    301   lock_guard<recursive_mutex> obj(recursive_mutex_);
    302   hw_intf_->DumpDebugData();
    303 }
    304 
    305 void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
    306   lock_guard<recursive_mutex> obj(recursive_mutex_);
    307   comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
    308   if (thermal_level >= kMaxThermalLevel) {
    309     needs_validate_.set();
    310   }
    311 }
    312 
    313 void DisplayPrimary::IdlePowerCollapse() {
    314   lock_guard<recursive_mutex> obj(recursive_mutex_);
    315   comp_manager_->ProcessIdlePowerCollapse(display_comp_ctx_);
    316 }
    317 
    318 DisplayError DisplayPrimary::GetPanelBrightness(int *level) {
    319   lock_guard<recursive_mutex> obj(recursive_mutex_);
    320   return hw_intf_->GetPanelBrightness(level);
    321 }
    322 
    323 DisplayError DisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
    324   lock_guard<recursive_mutex> obj(recursive_mutex_);
    325   if (!pending) {
    326     return kErrorParameters;
    327   }
    328 
    329   if (!hw_panel_info_.partial_update) {
    330     // Nothing to be done.
    331     DLOGI("partial update is not applicable for display=%d", display_type_);
    332     return kErrorNotSupported;
    333   }
    334 
    335   *pending = 0;
    336   if (enable == partial_update_control_) {
    337     DLOGI("Same state transition is requested.");
    338     return kErrorNone;
    339   }
    340 
    341   partial_update_control_ = enable;
    342 
    343   if (!enable) {
    344     // If the request is to turn off feature, new draw call is required to have
    345     // the new setting into effect.
    346     *pending = 1;
    347   }
    348 
    349   return kErrorNone;
    350 }
    351 
    352 DisplayError DisplayPrimary::DisablePartialUpdateOneFrame() {
    353   lock_guard<recursive_mutex> obj(recursive_mutex_);
    354   disable_pu_one_frame_ = true;
    355 
    356   return kErrorNone;
    357 }
    358 
    359 bool DisplayPrimary::NeedsAVREnable() {
    360   if (avr_prop_disabled_) {
    361     return false;
    362   }
    363 
    364   return (hw_panel_info_.mode == kModeVideo && ((hw_panel_info_.dynamic_fps &&
    365           hw_panel_info_.dfps_porch_mode) || (!hw_panel_info_.dynamic_fps &&
    366           hw_panel_info_.min_fps != hw_panel_info_.max_fps)));
    367 }
    368 
    369 }  // namespace sdm
    370 
    371