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