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,
     43                                BufferAllocator *buffer_allocator, CompManager *comp_manager)
     44   : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, buffer_allocator,
     45                 comp_manager, 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                                            buffer_allocator_, &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   if (hw_panel_info_.mode == kModeCommand && Debug::IsVideoModeEnabled()) {
     64     error = hw_intf_->SetDisplayMode(kModeVideo);
     65     if (error != kErrorNone) {
     66       DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
     67             kModeVideo);
     68     }
     69   }
     70 
     71   avr_prop_disabled_ = Debug::IsAVRDisabled();
     72 
     73   error = HWEventsInterface::Create(INT(display_type_), this, event_list_, &hw_events_intf_);
     74   if (error != kErrorNone) {
     75     DLOGE("Failed to create hardware events interface. Error = %d", error);
     76     DisplayBase::Deinit();
     77     HWInterface::Destroy(hw_intf_);
     78   }
     79 
     80   return error;
     81 }
     82 
     83 DisplayError DisplayPrimary::Prepare(LayerStack *layer_stack) {
     84   lock_guard<recursive_mutex> obj(recursive_mutex_);
     85   DisplayError error = kErrorNone;
     86   uint32_t new_mixer_width = 0;
     87   uint32_t new_mixer_height = 0;
     88   uint32_t display_width = display_attributes_.x_pixels;
     89   uint32_t display_height = display_attributes_.y_pixels;
     90 
     91   if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
     92     error = ReconfigureMixer(new_mixer_width, new_mixer_height);
     93     if (error != kErrorNone) {
     94       ReconfigureMixer(display_width, display_height);
     95     }
     96   }
     97 
     98   // Clean hw layers for reuse.
     99   hw_layers_ = HWLayers();
    100   hw_layers_.hw_avr_info.enable = NeedsAVREnable();
    101 
    102   return DisplayBase::Prepare(layer_stack);
    103 }
    104 
    105 DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) {
    106   lock_guard<recursive_mutex> obj(recursive_mutex_);
    107   DisplayError error = kErrorNone;
    108   uint32_t app_layer_count = hw_layers_.info.app_layer_count;
    109 
    110   // Enabling auto refresh is async and needs to happen before commit ioctl
    111   if (hw_panel_info_.mode == kModeCommand) {
    112     bool enable = (app_layer_count == 1) && layer_stack->flags.single_buffered_layer_present;
    113     bool need_refresh = layer_stack->flags.single_buffered_layer_present && (app_layer_count > 1);
    114 
    115     hw_intf_->SetAutoRefresh(enable);
    116     if (need_refresh) {
    117       event_handler_->Refresh();
    118     }
    119   }
    120 
    121   error = DisplayBase::Commit(layer_stack);
    122   if (error != kErrorNone) {
    123     return error;
    124   }
    125 
    126   DisplayBase::ReconfigureDisplay();
    127 
    128   int idle_time_ms = hw_layers_.info.set_idle_time_ms;
    129   if (idle_time_ms >= 0) {
    130     hw_intf_->SetIdleTimeoutMs(UINT32(idle_time_ms));
    131   }
    132 
    133   if (switch_to_cmd_) {
    134     uint32_t pending;
    135     switch_to_cmd_ = false;
    136     ControlPartialUpdate(true /* enable */, &pending);
    137   }
    138 
    139   return error;
    140 }
    141 
    142 DisplayError DisplayPrimary::SetDisplayState(DisplayState state) {
    143   lock_guard<recursive_mutex> obj(recursive_mutex_);
    144   DisplayError error = kErrorNone;
    145   error = DisplayBase::SetDisplayState(state);
    146   if (error != kErrorNone) {
    147     return error;
    148   }
    149 
    150   // Set vsync enable state to false, as driver disables vsync during display power off.
    151   if (state == kStateOff) {
    152     vsync_enable_ = false;
    153   }
    154 
    155   return kErrorNone;
    156 }
    157 
    158 void DisplayPrimary::SetIdleTimeoutMs(uint32_t active_ms) {
    159   lock_guard<recursive_mutex> obj(recursive_mutex_);
    160 
    161   if (comp_manager_->SetIdleTimeoutMs(display_comp_ctx_, active_ms) == kErrorNone) {
    162     hw_intf_->SetIdleTimeoutMs(active_ms);
    163   }
    164 }
    165 
    166 DisplayError DisplayPrimary::SetDisplayMode(uint32_t mode) {
    167   DisplayError error = kErrorNone;
    168 
    169   // Limit scope of mutex to this block
    170   {
    171     lock_guard<recursive_mutex> obj(recursive_mutex_);
    172     HWDisplayMode hw_display_mode = static_cast<HWDisplayMode>(mode);
    173     uint32_t pending = 0;
    174 
    175     if (!active_) {
    176       DLOGW("Invalid display state = %d. Panel must be on.", state_);
    177       return kErrorNotSupported;
    178     }
    179 
    180     if (hw_display_mode != kModeCommand && hw_display_mode != kModeVideo) {
    181       DLOGW("Invalid panel mode parameters. Requested = %d", hw_display_mode);
    182       return kErrorParameters;
    183     }
    184 
    185     if (hw_display_mode == hw_panel_info_.mode) {
    186       DLOGW("Same display mode requested. Current = %d, Requested = %d", hw_panel_info_.mode,
    187             hw_display_mode);
    188       return kErrorNone;
    189     }
    190 
    191     error = hw_intf_->SetDisplayMode(hw_display_mode);
    192     if (error != kErrorNone) {
    193       DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
    194             hw_display_mode);
    195       return error;
    196     }
    197 
    198     if (mode == kModeVideo) {
    199       ControlPartialUpdate(false /* enable */, &pending);
    200     } else if (mode == kModeCommand) {
    201       // Flush idle timeout value currently set.
    202       hw_intf_->SetIdleTimeoutMs(0);
    203       switch_to_cmd_ = true;
    204     }
    205   }
    206 
    207   // Request for a new draw cycle. New display mode will get applied on next draw cycle.
    208   // New idle time will get configured as part of this.
    209   event_handler_->Refresh();
    210 
    211   return error;
    212 }
    213 
    214 DisplayError DisplayPrimary::SetPanelBrightness(int level) {
    215   lock_guard<recursive_mutex> obj(recursive_mutex_);
    216   return hw_intf_->SetPanelBrightness(level);
    217 }
    218 
    219 DisplayError DisplayPrimary::CachePanelBrightness(int level) {
    220   lock_guard<recursive_mutex> obj(recursive_mutex_);
    221   return hw_intf_->CachePanelBrightness(level);
    222 }
    223 
    224 DisplayError DisplayPrimary::GetRefreshRateRange(uint32_t *min_refresh_rate,
    225                                                  uint32_t *max_refresh_rate) {
    226   lock_guard<recursive_mutex> obj(recursive_mutex_);
    227   DisplayError error = kErrorNone;
    228 
    229   if (hw_panel_info_.min_fps && hw_panel_info_.max_fps) {
    230     *min_refresh_rate = hw_panel_info_.min_fps;
    231     *max_refresh_rate = hw_panel_info_.max_fps;
    232   } else {
    233     error = DisplayBase::GetRefreshRateRange(min_refresh_rate, max_refresh_rate);
    234   }
    235 
    236   return error;
    237 }
    238 
    239 DisplayError DisplayPrimary::SetRefreshRate(uint32_t refresh_rate) {
    240   lock_guard<recursive_mutex> obj(recursive_mutex_);
    241 
    242   if (!active_ || !hw_panel_info_.dynamic_fps) {
    243     return kErrorNotSupported;
    244   }
    245 
    246   if (refresh_rate < hw_panel_info_.min_fps || refresh_rate > hw_panel_info_.max_fps) {
    247     DLOGE("Invalid Fps = %d request", refresh_rate);
    248     return kErrorParameters;
    249   }
    250 
    251   DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
    252   if (error != kErrorNone) {
    253     return error;
    254   }
    255 
    256   return DisplayBase::ReconfigureDisplay();
    257 }
    258 
    259 DisplayError DisplayPrimary::VSync(int64_t timestamp) {
    260   if (vsync_enable_) {
    261     DisplayEventVSync vsync;
    262     vsync.timestamp = timestamp;
    263     event_handler_->VSync(vsync);
    264   }
    265 
    266   return kErrorNone;
    267 }
    268 
    269 void DisplayPrimary::IdleTimeout() {
    270   event_handler_->Refresh();
    271   comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
    272   event_handler_->HandleEvent(kIdleTimeout);
    273 }
    274 
    275 void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
    276   lock_guard<recursive_mutex> obj(recursive_mutex_);
    277   comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
    278   event_handler_->HandleEvent(kThermalEvent);
    279 }
    280 
    281 void DisplayPrimary::IdlePowerCollapse() {
    282   lock_guard<recursive_mutex> obj(recursive_mutex_);
    283   comp_manager_->ProcessIdlePowerCollapse(display_comp_ctx_);
    284 }
    285 
    286 DisplayError DisplayPrimary::GetPanelBrightness(int *level) {
    287   lock_guard<recursive_mutex> obj(recursive_mutex_);
    288   return hw_intf_->GetPanelBrightness(level);
    289 }
    290 
    291 DisplayError DisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
    292   lock_guard<recursive_mutex> obj(recursive_mutex_);
    293   if (!pending) {
    294     return kErrorParameters;
    295   }
    296 
    297   if (!hw_panel_info_.partial_update) {
    298     // Nothing to be done.
    299     DLOGI("partial update is not applicable for display=%d", display_type_);
    300     return kErrorNotSupported;
    301   }
    302 
    303   *pending = 0;
    304   if (enable == partial_update_control_) {
    305     DLOGI("Same state transition is requested.");
    306     return kErrorNone;
    307   }
    308 
    309   partial_update_control_ = enable;
    310 
    311   if (!enable) {
    312     // If the request is to turn off feature, new draw call is required to have
    313     // the new setting into effect.
    314     *pending = 1;
    315   }
    316 
    317   return kErrorNone;
    318 }
    319 
    320 DisplayError DisplayPrimary::DisablePartialUpdateOneFrame() {
    321   lock_guard<recursive_mutex> obj(recursive_mutex_);
    322   disable_pu_one_frame_ = true;
    323 
    324   return kErrorNone;
    325 }
    326 
    327 bool DisplayPrimary::NeedsAVREnable() {
    328   if (avr_prop_disabled_) {
    329     return false;
    330   }
    331 
    332   return (hw_panel_info_.mode == kModeVideo && ((hw_panel_info_.dynamic_fps &&
    333           hw_panel_info_.dfps_porch_mode) || (!hw_panel_info_.dynamic_fps &&
    334           hw_panel_info_.min_fps != hw_panel_info_.max_fps)));
    335 }
    336 
    337 }  // namespace sdm
    338 
    339