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