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 <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 #include "fb/hw_primary.h"
     37 
     38 #define __CLASS__ "DisplayPrimary"
     39 
     40 namespace sdm {
     41 
     42 DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
     43                                BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
     44                                RotatorInterface *rotator_intf)
     45   : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, comp_manager,
     46                 rotator_intf, hw_info_intf) {
     47 }
     48 
     49 DisplayError DisplayPrimary::Init() {
     50   lock_guard<recursive_mutex> obj(recursive_mutex_);
     51 
     52   DisplayError error = HWPrimary::Create(&hw_intf_, hw_info_intf_,
     53                                          DisplayBase::buffer_sync_handler_);
     54 
     55   if (error != kErrorNone) {
     56     return error;
     57   }
     58 
     59   error = DisplayBase::Init();
     60   if (error != kErrorNone) {
     61     HWPrimary::Destroy(hw_intf_);
     62     return error;
     63   }
     64 
     65   idle_timeout_ms_ = Debug::GetIdleTimeoutMs();
     66 
     67   if (hw_panel_info_.mode == kModeCommand && Debug::IsVideoModeEnabled()) {
     68     error = hw_intf_->SetDisplayMode(kModeVideo);
     69     if (error != kErrorNone) {
     70       DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
     71             kModeVideo);
     72     }
     73   }
     74 
     75   error = HWEventsInterface::Create(INT(display_type_), this, &event_list_, &hw_events_intf_);
     76   if (error != kErrorNone) {
     77     DLOGE("Failed to create hardware events interface. Error = %d", error);
     78     DisplayBase::Deinit();
     79     HWPrimary::Destroy(hw_intf_);
     80   }
     81 
     82   return error;
     83 }
     84 
     85 DisplayError DisplayPrimary::Deinit() {
     86   lock_guard<recursive_mutex> obj(recursive_mutex_);
     87 
     88   DisplayError error = DisplayBase::Deinit();
     89   HWPrimary::Destroy(hw_intf_);
     90 
     91   return error;
     92 }
     93 
     94 DisplayError DisplayPrimary::Prepare(LayerStack *layer_stack) {
     95   lock_guard<recursive_mutex> obj(recursive_mutex_);
     96   DisplayError error = kErrorNone;
     97   uint32_t new_mixer_width = 0;
     98   uint32_t new_mixer_height = 0;
     99   uint32_t display_width = display_attributes_.x_pixels;
    100   uint32_t display_height = display_attributes_.y_pixels;
    101 
    102   if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
    103     error = ReconfigureMixer(new_mixer_width, new_mixer_height);
    104     if (error != kErrorNone) {
    105       ReconfigureMixer(display_width, display_height);
    106     }
    107   }
    108 
    109   return DisplayBase::Prepare(layer_stack);
    110 }
    111 
    112 DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) {
    113   lock_guard<recursive_mutex> obj(recursive_mutex_);
    114   DisplayError error = kErrorNone;
    115 
    116   // Enabling auto refresh is async and needs to happen before commit ioctl
    117   if (hw_panel_info_.mode == kModeCommand) {
    118     hw_intf_->SetAutoRefresh(layer_stack->flags.single_buffered_layer_present);
    119   }
    120 
    121   bool set_idle_timeout = comp_manager_->CanSetIdleTimeout(display_comp_ctx_);
    122 
    123   error = DisplayBase::Commit(layer_stack);
    124   if (error != kErrorNone) {
    125     return error;
    126   }
    127 
    128   DisplayBase::ReconfigureDisplay();
    129 
    130   if (hw_panel_info_.mode == kModeVideo) {
    131     if (set_idle_timeout && !layer_stack->flags.single_buffered_layer_present) {
    132       hw_intf_->SetIdleTimeoutMs(idle_timeout_ms_);
    133     } else {
    134       hw_intf_->SetIdleTimeoutMs(0);
    135     }
    136   }
    137 
    138   return error;
    139 }
    140 
    141 DisplayError DisplayPrimary::SetDisplayState(DisplayState state) {
    142   lock_guard<recursive_mutex> obj(recursive_mutex_);
    143   DisplayError error = kErrorNone;
    144   error = DisplayBase::SetDisplayState(state);
    145   if (error != kErrorNone) {
    146     return error;
    147   }
    148 
    149   // Set vsync enable state to false, as driver disables vsync during display power off.
    150   if (state == kStateOff) {
    151     vsync_enable_ = false;
    152   }
    153 
    154   return kErrorNone;
    155 }
    156 
    157 void DisplayPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
    158   lock_guard<recursive_mutex> obj(recursive_mutex_);
    159 
    160   // Idle fallback feature is supported only for video mode panel.
    161   if (hw_panel_info_.mode == kModeVideo) {
    162     hw_intf_->SetIdleTimeoutMs(timeout_ms);
    163   }
    164   idle_timeout_ms_ = timeout_ms;
    165 }
    166 
    167 DisplayError DisplayPrimary::SetDisplayMode(uint32_t mode) {
    168   lock_guard<recursive_mutex> obj(recursive_mutex_);
    169   DisplayError error = kErrorNone;
    170   HWDisplayMode hw_display_mode = static_cast<HWDisplayMode>(mode);
    171   uint32_t pending = 0;
    172 
    173   if (!active_) {
    174     DLOGW("Invalid display state = %d. Panel must be on.", state_);
    175     return kErrorNotSupported;
    176   }
    177 
    178   if (hw_display_mode != kModeCommand && hw_display_mode != kModeVideo) {
    179     DLOGW("Invalid panel mode parameters. Requested = %d", hw_display_mode);
    180     return kErrorParameters;
    181   }
    182 
    183   if (hw_display_mode == hw_panel_info_.mode) {
    184     DLOGW("Same display mode requested. Current = %d, Requested = %d", hw_panel_info_.mode,
    185           hw_display_mode);
    186     return kErrorNone;
    187   }
    188 
    189   error = hw_intf_->SetDisplayMode(hw_display_mode);
    190   if (error != kErrorNone) {
    191     DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
    192           hw_display_mode);
    193     return error;
    194   }
    195 
    196   if (mode == kModeVideo) {
    197     ControlPartialUpdate(false /* enable */, &pending);
    198     hw_intf_->SetIdleTimeoutMs(idle_timeout_ms_);
    199   } else if (mode == kModeCommand) {
    200     ControlPartialUpdate(true /* enable */, &pending);
    201     hw_intf_->SetIdleTimeoutMs(0);
    202   }
    203 
    204   return error;
    205 }
    206 
    207 DisplayError DisplayPrimary::SetPanelBrightness(int level) {
    208   lock_guard<recursive_mutex> obj(recursive_mutex_);
    209   return hw_intf_->SetPanelBrightness(level);
    210 }
    211 
    212 DisplayError DisplayPrimary::GetRefreshRateRange(uint32_t *min_refresh_rate,
    213                                                  uint32_t *max_refresh_rate) {
    214   lock_guard<recursive_mutex> obj(recursive_mutex_);
    215   DisplayError error = kErrorNone;
    216 
    217   if (hw_panel_info_.min_fps && hw_panel_info_.max_fps) {
    218     *min_refresh_rate = hw_panel_info_.min_fps;
    219     *max_refresh_rate = hw_panel_info_.max_fps;
    220   } else {
    221     error = DisplayBase::GetRefreshRateRange(min_refresh_rate, max_refresh_rate);
    222   }
    223 
    224   return error;
    225 }
    226 
    227 DisplayError DisplayPrimary::SetRefreshRate(uint32_t refresh_rate) {
    228   lock_guard<recursive_mutex> obj(recursive_mutex_);
    229 
    230   if (!active_ || !hw_panel_info_.dynamic_fps) {
    231     return kErrorNotSupported;
    232   }
    233 
    234   if (refresh_rate < hw_panel_info_.min_fps || refresh_rate > hw_panel_info_.max_fps) {
    235     DLOGE("Invalid Fps = %d request", refresh_rate);
    236     return kErrorParameters;
    237   }
    238 
    239   DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
    240   if (error != kErrorNone) {
    241     return error;
    242   }
    243 
    244   return DisplayBase::ReconfigureDisplay();
    245 }
    246 
    247 DisplayError DisplayPrimary::VSync(int64_t timestamp) {
    248   if (vsync_enable_) {
    249     DisplayEventVSync vsync;
    250     vsync.timestamp = timestamp;
    251     event_handler_->VSync(vsync);
    252   }
    253 
    254   return kErrorNone;
    255 }
    256 
    257 void DisplayPrimary::IdleTimeout() {
    258   event_handler_->Refresh();
    259   comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
    260   AllDisplaysNeedValidate();
    261 }
    262 
    263 void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
    264   lock_guard<recursive_mutex> obj(recursive_mutex_);
    265   comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
    266   if (thermal_level >= kMaxThermalLevel) {
    267     AllDisplaysNeedValidate();
    268   }
    269 }
    270 
    271 DisplayError DisplayPrimary::GetPanelBrightness(int *level) {
    272   lock_guard<recursive_mutex> obj(recursive_mutex_);
    273   return hw_intf_->GetPanelBrightness(level);
    274 }
    275 
    276 DisplayError DisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
    277   lock_guard<recursive_mutex> obj(recursive_mutex_);
    278   if (!pending) {
    279     return kErrorParameters;
    280   }
    281 
    282   if (!hw_panel_info_.partial_update) {
    283     // Nothing to be done.
    284     DLOGI("partial update is not applicable for display=%d", display_type_);
    285     return kErrorNotSupported;
    286   }
    287 
    288   *pending = 0;
    289   if (enable == partial_update_control_) {
    290     DLOGI("Same state transition is requested.");
    291     return kErrorNone;
    292   }
    293 
    294   partial_update_control_ = enable;
    295 
    296   if (!enable) {
    297     // If the request is to turn off feature, new draw call is required to have
    298     // the new setting into effect.
    299     *pending = 1;
    300   }
    301 
    302   return kErrorNone;
    303 }
    304 
    305 DisplayError DisplayPrimary::DisablePartialUpdateOneFrame() {
    306   lock_guard<recursive_mutex> obj(recursive_mutex_);
    307   disable_pu_one_frame_ = true;
    308 
    309   return kErrorNone;
    310 }
    311 
    312 }  // namespace sdm
    313 
    314