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