1 /*
2 * Copyright (c) 2014 - 2019, 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 <utils/utils.h>
29
30 #include <algorithm>
31 #include <functional>
32 #include <map>
33 #include <string>
34 #include <vector>
35
36 #include "display_builtin.h"
37 #include "hw_info_interface.h"
38 #include "hw_interface.h"
39 #include "drm_interface.h"
40 #include "drm_master.h"
41
42 #define __CLASS__ "DisplayBuiltIn"
43
44 namespace sdm {
45
DisplayBuiltIn(DisplayEventHandler * event_handler,HWInfoInterface * hw_info_intf,BufferSyncHandler * buffer_sync_handler,BufferAllocator * buffer_allocator,CompManager * comp_manager)46 DisplayBuiltIn::DisplayBuiltIn(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
47 BufferSyncHandler *buffer_sync_handler,
48 BufferAllocator *buffer_allocator, CompManager *comp_manager)
49 : DisplayBase(kBuiltIn, event_handler, kDeviceBuiltIn, buffer_sync_handler, buffer_allocator,
50 comp_manager, hw_info_intf) {}
51
DisplayBuiltIn(int32_t display_id,DisplayEventHandler * event_handler,HWInfoInterface * hw_info_intf,BufferSyncHandler * buffer_sync_handler,BufferAllocator * buffer_allocator,CompManager * comp_manager)52 DisplayBuiltIn::DisplayBuiltIn(int32_t display_id, DisplayEventHandler *event_handler,
53 HWInfoInterface *hw_info_intf,
54 BufferSyncHandler *buffer_sync_handler,
55 BufferAllocator *buffer_allocator, CompManager *comp_manager)
56 : DisplayBase(display_id, kBuiltIn, event_handler, kDeviceBuiltIn, buffer_sync_handler,
57 buffer_allocator, comp_manager, hw_info_intf) {}
58
~DisplayBuiltIn()59 DisplayBuiltIn::~DisplayBuiltIn() {
60 CloseFd(&previous_retire_fence_);
61 }
62
Init()63 DisplayError DisplayBuiltIn::Init() {
64 lock_guard<recursive_mutex> obj(recursive_mutex_);
65 int32_t disable_defer_power_state = 0;
66
67 DisplayError error = HWInterface::Create(display_id_, kBuiltIn, hw_info_intf_,
68 buffer_sync_handler_, buffer_allocator_, &hw_intf_);
69 if (error != kErrorNone) {
70 DLOGE("Failed to create hardware interface on. Error = %d", error);
71 return error;
72 }
73
74 if (-1 == display_id_) {
75 hw_intf_->GetDisplayId(&display_id_);
76 }
77
78 error = DisplayBase::Init();
79 if (error != kErrorNone) {
80 HWInterface::Destroy(hw_intf_);
81 return error;
82 }
83
84 if (hw_panel_info_.mode == kModeCommand && Debug::IsVideoModeEnabled()) {
85 error = hw_intf_->SetDisplayMode(kModeVideo);
86 if (error != kErrorNone) {
87 DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
88 kModeVideo);
89 }
90 }
91
92 if (hw_panel_info_.mode == kModeCommand) {
93 event_list_ = {HWEvent::VSYNC,
94 HWEvent::EXIT,
95 /* HWEvent::IDLE_NOTIFY, */
96 /* HWEvent::CEC_READ_MESSAGE, */
97 HWEvent::SHOW_BLANK_EVENT,
98 HWEvent::THERMAL_LEVEL,
99 HWEvent::IDLE_POWER_COLLAPSE,
100 HWEvent::PINGPONG_TIMEOUT,
101 HWEvent::PANEL_DEAD,
102 HWEvent::HW_RECOVERY,
103 HWEvent::HISTOGRAM};
104 } else {
105 event_list_ = {HWEvent::VSYNC,
106 HWEvent::EXIT,
107 HWEvent::IDLE_NOTIFY,
108 /* HWEvent::CEC_READ_MESSAGE, */
109 HWEvent::SHOW_BLANK_EVENT,
110 HWEvent::THERMAL_LEVEL,
111 HWEvent::PINGPONG_TIMEOUT,
112 HWEvent::PANEL_DEAD,
113 HWEvent::HW_RECOVERY,
114 HWEvent::HISTOGRAM};
115 }
116
117 avr_prop_disabled_ = Debug::IsAVRDisabled();
118
119 error = HWEventsInterface::Create(display_id_, kBuiltIn, this, event_list_, hw_intf_,
120 &hw_events_intf_);
121 if (error != kErrorNone) {
122 DisplayBase::Deinit();
123 HWInterface::Destroy(hw_intf_);
124 DLOGE("Failed to create hardware events interface on. Error = %d", error);
125 }
126
127 current_refresh_rate_ = hw_panel_info_.max_fps;
128
129 initColorSamplingState();
130
131 Debug::GetProperty(DISABLE_DEFER_POWER_STATE, &disable_defer_power_state);
132 defer_power_state_ = !disable_defer_power_state;
133 DLOGI("defer_power_state %d", defer_power_state_);
134
135 int value = 0;
136 Debug::Get()->GetProperty(DEFER_FPS_FRAME_COUNT, &value);
137 deferred_config_.frame_count = (value > 0) ? UINT32(value) : 0;
138
139 return error;
140 }
141
Deinit()142 DisplayError DisplayBuiltIn::Deinit() {
143 lock_guard<recursive_mutex> obj(recursive_mutex_);
144
145 dpps_info_.Deinit();
146 return DisplayBase::Deinit();
147 }
148
Prepare(LayerStack * layer_stack)149 DisplayError DisplayBuiltIn::Prepare(LayerStack *layer_stack) {
150 lock_guard<recursive_mutex> obj(recursive_mutex_);
151 DisplayError error = kErrorNone;
152 uint32_t new_mixer_width = 0;
153 uint32_t new_mixer_height = 0;
154 uint32_t display_width = display_attributes_.x_pixels;
155 uint32_t display_height = display_attributes_.y_pixels;
156
157 DTRACE_SCOPED();
158 if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
159 error = ReconfigureMixer(new_mixer_width, new_mixer_height);
160 if (error != kErrorNone) {
161 ReconfigureMixer(display_width, display_height);
162 }
163 } else {
164 if (CanSkipDisplayPrepare(layer_stack)) {
165 hw_layers_.hw_avr_info.update = needs_avr_update_;
166 hw_layers_.hw_avr_info.mode = GetAvrMode(qsync_mode_);
167 return kErrorNone;
168 }
169 }
170
171 // Clean hw layers for reuse.
172 DTRACE_BEGIN("PrepareHWLayers");
173 hw_layers_ = HWLayers();
174 DTRACE_END();
175
176 hw_layers_.hw_avr_info.update = needs_avr_update_;
177 hw_layers_.hw_avr_info.mode = GetAvrMode(qsync_mode_);
178
179 left_frame_roi_ = {};
180 right_frame_roi_ = {};
181
182 error = DisplayBase::Prepare(layer_stack);
183
184 // Cache the Frame ROI.
185 if (error == kErrorNone) {
186 if (hw_layers_.info.left_frame_roi.size() && hw_layers_.info.right_frame_roi.size()) {
187 left_frame_roi_ = hw_layers_.info.left_frame_roi.at(0);
188 right_frame_roi_ = hw_layers_.info.right_frame_roi.at(0);
189 }
190 }
191
192 return error;
193 }
194
initColorSamplingState()195 void DisplayBuiltIn::initColorSamplingState() {
196 samplingState = SamplingState::Off;
197 histogramCtrl.object_type = DRM_MODE_OBJECT_CRTC;
198 histogramCtrl.feature_id = sde_drm::DRMDPPSFeatureID::kFeatureAbaHistCtrl;
199 histogramCtrl.value = sde_drm::HistModes::kHistDisabled;
200
201 histogramIRQ.object_type = DRM_MODE_OBJECT_CRTC;
202 histogramIRQ.feature_id = sde_drm::DRMDPPSFeatureID::kFeatureAbaHistIRQ;
203 histogramIRQ.value = sde_drm::HistModes::kHistDisabled;
204 histogramSetup = true;
205 }
206
setColorSamplingState(SamplingState state)207 DisplayError DisplayBuiltIn::setColorSamplingState(SamplingState state) {
208 samplingState = state;
209 if (samplingState == SamplingState::On) {
210 histogramCtrl.value = sde_drm::HistModes::kHistEnabled;
211 histogramIRQ.value = sde_drm::HistModes::kHistEnabled;
212 } else {
213 histogramCtrl.value = sde_drm::HistModes::kHistDisabled;
214 histogramIRQ.value = sde_drm::HistModes::kHistDisabled;
215 }
216
217 //effectively drmModeAtomicAddProperty for the SDE_DSPP_HIST_CTRL_V1
218 return DppsProcessOps(kDppsSetFeature, &histogramCtrl, sizeof(histogramCtrl));
219 }
220
colorSamplingOn()221 DisplayError DisplayBuiltIn::colorSamplingOn() {
222 if (!histogramSetup) {
223 return kErrorParameters;
224 }
225 return setColorSamplingState(SamplingState::On);
226 }
227
colorSamplingOff()228 DisplayError DisplayBuiltIn::colorSamplingOff() {
229 if (!histogramSetup) {
230 return kErrorParameters;
231 }
232 return setColorSamplingState(SamplingState::Off);
233 }
234
GetAvrMode(QSyncMode mode)235 HWAVRModes DisplayBuiltIn::GetAvrMode(QSyncMode mode) {
236 switch (mode) {
237 case kQSyncModeNone:
238 return kQsyncNone;
239 case kQSyncModeContinuous:
240 return kContinuousMode;
241 case kQsyncModeOneShot:
242 case kQsyncModeOneShotContinuous:
243 return kOneShotMode;
244 default:
245 return kQsyncNone;
246 }
247 }
248
Commit(LayerStack * layer_stack)249 DisplayError DisplayBuiltIn::Commit(LayerStack *layer_stack) {
250 lock_guard<recursive_mutex> obj(recursive_mutex_);
251 DisplayError error = kErrorNone;
252 uint32_t app_layer_count = hw_layers_.info.app_layer_count;
253
254 DTRACE_SCOPED();
255
256 // Enabling auto refresh is async and needs to happen before commit ioctl
257 if (hw_panel_info_.mode == kModeCommand) {
258 bool enable = (app_layer_count == 1) && layer_stack->flags.single_buffered_layer_present;
259 bool need_refresh = layer_stack->flags.single_buffered_layer_present && (app_layer_count > 1);
260
261 hw_intf_->SetAutoRefresh(enable);
262 if (need_refresh) {
263 event_handler_->Refresh();
264 }
265 }
266
267 //effectively drmModeAtomicAddProperty for SDE_DSPP_HIST_IRQ_V1
268 if (histogramSetup) {
269 DppsProcessOps(kDppsSetFeature, &histogramIRQ, sizeof(histogramIRQ));
270 }
271
272 if (vsync_enable_) {
273 DTRACE_BEGIN("RegisterVsync");
274 // wait for previous frame's retire fence to signal.
275 buffer_sync_handler_->SyncWait(previous_retire_fence_);
276
277 // Register for vsync and then commit the frame.
278 hw_events_intf_->SetEventState(HWEvent::VSYNC, true);
279 DTRACE_END();
280 }
281
282 error = DisplayBase::Commit(layer_stack);
283 if (error != kErrorNone) {
284 return error;
285 }
286
287 if (commit_event_enabled_) {
288 dpps_info_.DppsNotifyOps(kDppsCommitEvent, &display_type_, sizeof(display_type_));
289 }
290
291 deferred_config_.UpdateDeferCount();
292
293 ReconfigureDisplay();
294
295 if (deferred_config_.CanApplyDeferredState()) {
296 event_handler_->HandleEvent(kInvalidateDisplay);
297 deferred_config_.Clear();
298 }
299
300 int idle_time_ms = hw_layers_.info.set_idle_time_ms;
301 if (idle_time_ms >= 0) {
302 hw_intf_->SetIdleTimeoutMs(UINT32(idle_time_ms));
303 }
304
305 if (switch_to_cmd_) {
306 uint32_t pending;
307 switch_to_cmd_ = false;
308 ControlPartialUpdate(true /* enable */, &pending);
309 }
310
311 dpps_info_.Init(this, hw_panel_info_.panel_name);
312
313 if (qsync_mode_ == kQsyncModeOneShot) {
314 // Reset qsync mode.
315 SetQSyncMode(kQSyncModeNone);
316 } else if (qsync_mode_ == kQsyncModeOneShotContinuous) {
317 // No action needed.
318 } else if (qsync_mode_ == kQSyncModeContinuous) {
319 needs_avr_update_ = false;
320 } else if (qsync_mode_ == kQSyncModeNone) {
321 needs_avr_update_ = false;
322 }
323
324 first_cycle_ = false;
325
326 CloseFd(&previous_retire_fence_);
327 previous_retire_fence_ = Sys::dup_(layer_stack->retire_fence_fd);
328
329 return error;
330 }
331
SetDisplayState(DisplayState state,bool teardown,int * release_fence)332 DisplayError DisplayBuiltIn::SetDisplayState(DisplayState state, bool teardown,
333 int *release_fence) {
334 lock_guard<recursive_mutex> obj(recursive_mutex_);
335 DisplayError error = kErrorNone;
336
337 if ((state == kStateOn) && deferred_config_.IsDeferredState()) {
338 SetDeferredFpsConfig();
339 }
340
341 error = DisplayBase::SetDisplayState(state, teardown, release_fence);
342 if (error != kErrorNone) {
343 return error;
344 }
345
346 // Set vsync enable state to false, as driver disables vsync during display power off.
347 if (state == kStateOff) {
348 vsync_enable_ = false;
349 } else if (state == kStateOn && pendingActiveConfig != UINT_MAX) {
350 deferred_config_.MarkDirty();
351 DisplayBase::SetActiveConfig(pendingActiveConfig);
352 pendingActiveConfig = UINT_MAX;
353 }
354
355 return kErrorNone;
356 }
357
SetActiveConfig(uint32_t index)358 DisplayError DisplayBuiltIn::SetActiveConfig(uint32_t index) {
359 lock_guard<recursive_mutex> obj(recursive_mutex_);
360 DisplayState state;
361
362 if (DisplayBase::GetDisplayState(&state) == kErrorNone) {
363 if (state != kStateOn) {
364 pendingActiveConfig = index;
365 return kErrorNone;
366 }
367 }
368
369 pendingActiveConfig = UINT_MAX;
370 deferred_config_.MarkDirty();
371 return DisplayBase::SetActiveConfig(index);
372 }
373
GetActiveConfig(uint32_t * index)374 DisplayError DisplayBuiltIn::GetActiveConfig(uint32_t *index) {
375 lock_guard<recursive_mutex> obj(recursive_mutex_);
376 if (index && pendingActiveConfig != UINT_MAX) {
377 *index = pendingActiveConfig;
378 return kErrorNone;
379 }
380 return DisplayBase::GetActiveConfig(index);
381 }
382
SetIdleTimeoutMs(uint32_t active_ms)383 void DisplayBuiltIn::SetIdleTimeoutMs(uint32_t active_ms) {
384 lock_guard<recursive_mutex> obj(recursive_mutex_);
385 comp_manager_->SetIdleTimeoutMs(display_comp_ctx_, active_ms);
386 }
387
SetDisplayMode(uint32_t mode)388 DisplayError DisplayBuiltIn::SetDisplayMode(uint32_t mode) {
389 DisplayError error = kErrorNone;
390
391 // Limit scope of mutex to this block
392 {
393 lock_guard<recursive_mutex> obj(recursive_mutex_);
394 HWDisplayMode hw_display_mode = static_cast<HWDisplayMode>(mode);
395 uint32_t pending = 0;
396
397 if (!active_) {
398 DLOGW("Invalid display state = %d. Panel must be on.", state_);
399 return kErrorNotSupported;
400 }
401
402 if (hw_display_mode != kModeCommand && hw_display_mode != kModeVideo) {
403 DLOGW("Invalid panel mode parameters. Requested = %d", hw_display_mode);
404 return kErrorParameters;
405 }
406
407 if (hw_display_mode == hw_panel_info_.mode) {
408 DLOGW("Same display mode requested. Current = %d, Requested = %d", hw_panel_info_.mode,
409 hw_display_mode);
410 return kErrorNone;
411 }
412
413 error = hw_intf_->SetDisplayMode(hw_display_mode);
414 if (error != kErrorNone) {
415 DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
416 hw_display_mode);
417 return error;
418 }
419
420 if (mode == kModeVideo) {
421 ControlPartialUpdate(false /* enable */, &pending);
422 } else if (mode == kModeCommand) {
423 // Flush idle timeout value currently set.
424 comp_manager_->SetIdleTimeoutMs(display_comp_ctx_, 0);
425 switch_to_cmd_ = true;
426 }
427 }
428
429 // Request for a new draw cycle. New display mode will get applied on next draw cycle.
430 // New idle time will get configured as part of this.
431 event_handler_->Refresh();
432
433 return error;
434 }
435
SetPanelBrightness(int32_t level)436 DisplayError DisplayBuiltIn::SetPanelBrightness(int32_t level) {
437 lock_guard<std::mutex> lock(brightness_lock_);
438
439 if (state_ == kStateOff) {
440 return kErrorNone;
441 }
442
443 DisplayError err = hw_intf_->SetPanelBrightness(level);
444
445 DLOGI_IF(kTagDisplay, "Setting brightness to level %d, error %d", level, err);
446
447 return err;
448 }
449
GetRefreshRateRange(uint32_t * min_refresh_rate,uint32_t * max_refresh_rate)450 DisplayError DisplayBuiltIn::GetRefreshRateRange(uint32_t *min_refresh_rate,
451 uint32_t *max_refresh_rate) {
452 lock_guard<recursive_mutex> obj(recursive_mutex_);
453 DisplayError error = kErrorNone;
454
455 if (hw_panel_info_.min_fps && hw_panel_info_.max_fps) {
456 *min_refresh_rate = hw_panel_info_.min_fps;
457 *max_refresh_rate = hw_panel_info_.max_fps;
458 } else {
459 error = DisplayBase::GetRefreshRateRange(min_refresh_rate, max_refresh_rate);
460 }
461
462 return error;
463 }
464
TeardownConcurrentWriteback(void)465 DisplayError DisplayBuiltIn::TeardownConcurrentWriteback(void) {
466 lock_guard<recursive_mutex> obj(recursive_mutex_);
467
468 return hw_intf_->TeardownConcurrentWriteback();
469 }
470
SetRefreshRate(uint32_t refresh_rate,bool final_rate)471 DisplayError DisplayBuiltIn::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
472 lock_guard<recursive_mutex> obj(recursive_mutex_);
473
474 if (!active_ || !hw_panel_info_.dynamic_fps || qsync_mode_ != kQSyncModeNone) {
475 return kErrorNotSupported;
476 }
477
478 if (refresh_rate < hw_panel_info_.min_fps || refresh_rate > hw_panel_info_.max_fps) {
479 DLOGE("Invalid Fps = %d request", refresh_rate);
480 return kErrorParameters;
481 }
482
483 if (handle_idle_timeout_ && !final_rate) {
484 refresh_rate = hw_panel_info_.min_fps;
485 }
486
487 if ((current_refresh_rate_ != refresh_rate) || handle_idle_timeout_) {
488 DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
489 if (error != kErrorNone) {
490 // Attempt to update refresh rate can fail if rf interfenence is detected.
491 // Just drop min fps settting for now.
492 handle_idle_timeout_ = false;
493 return error;
494 }
495
496 error = comp_manager_->CheckEnforceSplit(display_comp_ctx_, refresh_rate);
497 if (error != kErrorNone) {
498 return error;
499 }
500 }
501
502 // On success, set current refresh rate to new refresh rate
503 current_refresh_rate_ = refresh_rate;
504 handle_idle_timeout_ = false;
505 deferred_config_.MarkDirty();
506
507 return ReconfigureDisplay();
508 }
509
VSync(int64_t timestamp)510 DisplayError DisplayBuiltIn::VSync(int64_t timestamp) {
511 if (vsync_enable_ && !drop_hw_vsync_) {
512 DisplayEventVSync vsync;
513 vsync.timestamp = timestamp;
514 event_handler_->VSync(vsync);
515 }
516
517 return kErrorNone;
518 }
519
IdleTimeout()520 void DisplayBuiltIn::IdleTimeout() {
521 if (hw_panel_info_.mode == kModeVideo) {
522 if (event_handler_->HandleEvent(kIdleTimeout) != kErrorNone) {
523 return;
524 }
525 handle_idle_timeout_ = true;
526 event_handler_->Refresh();
527 lock_guard<recursive_mutex> obj(recursive_mutex_);
528 comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
529 }
530 }
531
PingPongTimeout()532 void DisplayBuiltIn::PingPongTimeout() {
533 lock_guard<recursive_mutex> obj(recursive_mutex_);
534 hw_intf_->DumpDebugData();
535 }
536
ThermalEvent(int64_t thermal_level)537 void DisplayBuiltIn::ThermalEvent(int64_t thermal_level) {
538 event_handler_->HandleEvent(kThermalEvent);
539 lock_guard<recursive_mutex> obj(recursive_mutex_);
540 comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
541 }
542
IdlePowerCollapse()543 void DisplayBuiltIn::IdlePowerCollapse() {
544 if (hw_panel_info_.mode == kModeCommand) {
545 event_handler_->HandleEvent(kIdlePowerCollapse);
546 lock_guard<recursive_mutex> obj(recursive_mutex_);
547 comp_manager_->ProcessIdlePowerCollapse(display_comp_ctx_);
548 }
549 }
550
PanelDead()551 void DisplayBuiltIn::PanelDead() {
552 event_handler_->HandleEvent(kPanelDeadEvent);
553 }
554
555 // HWEventHandler overload, not DisplayBase
HwRecovery(const HWRecoveryEvent sdm_event_code)556 void DisplayBuiltIn::HwRecovery(const HWRecoveryEvent sdm_event_code) {
557 DisplayBase::HwRecovery(sdm_event_code);
558 }
559
Histogram(int histogram_fd,uint32_t blob_id)560 void DisplayBuiltIn::Histogram(int histogram_fd, uint32_t blob_id) {
561 event_handler_->HistogramEvent(histogram_fd, blob_id);
562 }
563
GetPanelBrightness(int32_t & level) const564 DisplayError DisplayBuiltIn::GetPanelBrightness(int32_t &level) const {
565 lock_guard<std::mutex> lock(brightness_lock_);
566
567 DisplayError err = hw_intf_->GetPanelBrightness(level);
568
569 DLOGI_IF(kTagDisplay, "Getting brightness level %d, error %d", level, err);
570
571 return err;
572 }
573
GetPanelMaxBrightness(int32_t & max_brightness_level) const574 DisplayError DisplayBuiltIn::GetPanelMaxBrightness(int32_t &max_brightness_level) const {
575 lock_guard<std::mutex> lock(brightness_lock_);
576
577 max_brightness_level = static_cast<int32_t>(hw_panel_info_.panel_max_brightness);
578
579 DLOGI_IF(kTagDisplay, "Get panel max brightness %u", max_brightness_level);
580 return kErrorNone;
581 }
582
IsSupportPanelBrightnessControl()583 bool DisplayBuiltIn::IsSupportPanelBrightnessControl() {
584 lock_guard<recursive_mutex> obj(recursive_mutex_);
585
586 return hw_intf_->IsSupportPanelBrightnessControl();
587 }
588
ControlPartialUpdate(bool enable,uint32_t * pending)589 DisplayError DisplayBuiltIn::ControlPartialUpdate(bool enable, uint32_t *pending) {
590 lock_guard<recursive_mutex> obj(recursive_mutex_);
591 if (!pending) {
592 return kErrorParameters;
593 }
594
595 if (!hw_panel_info_.partial_update) {
596 // Nothing to be done.
597 DLOGI("partial update is not applicable for display id = %d", display_id_);
598 return kErrorNotSupported;
599 }
600
601 *pending = 0;
602 if (enable == partial_update_control_) {
603 DLOGI("Same state transition is requested.");
604 return kErrorNone;
605 }
606
607 partial_update_control_ = enable;
608
609 if (!enable) {
610 // If the request is to turn off feature, new draw call is required to have
611 // the new setting into effect.
612 *pending = 1;
613 }
614
615 return kErrorNone;
616 }
617
DisablePartialUpdateOneFrame()618 DisplayError DisplayBuiltIn::DisablePartialUpdateOneFrame() {
619 lock_guard<recursive_mutex> obj(recursive_mutex_);
620 disable_pu_one_frame_ = true;
621
622 return kErrorNone;
623 }
624
DppsProcessOps(enum DppsOps op,void * payload,size_t size)625 DisplayError DisplayBuiltIn::DppsProcessOps(enum DppsOps op, void *payload, size_t size) {
626 DisplayError error = kErrorNone;
627 uint32_t pending;
628 bool enable = false;
629
630 switch (op) {
631 case kDppsSetFeature:
632 if (!payload) {
633 DLOGE("Invalid payload parameter for op %d", op);
634 error = kErrorParameters;
635 break;
636 }
637 {
638 lock_guard<recursive_mutex> obj(recursive_mutex_);
639 error = hw_intf_->SetDppsFeature(payload, size);
640 }
641 break;
642 case kDppsGetFeatureInfo:
643 if (!payload) {
644 DLOGE("Invalid payload parameter for op %d", op);
645 error = kErrorParameters;
646 break;
647 }
648 error = hw_intf_->GetDppsFeatureInfo(payload, size);
649 break;
650 case kDppsScreenRefresh:
651 event_handler_->Refresh();
652 break;
653 case kDppsPartialUpdate:
654 if (!payload) {
655 DLOGE("Invalid payload parameter for op %d", op);
656 error = kErrorParameters;
657 break;
658 }
659 enable = *(reinterpret_cast<bool *>(payload));
660 ControlPartialUpdate(enable, &pending);
661 break;
662 case kDppsRequestCommit:
663 if (!payload) {
664 DLOGE("Invalid payload parameter for op %d", op);
665 error = kErrorParameters;
666 break;
667 }
668 {
669 lock_guard<recursive_mutex> obj(recursive_mutex_);
670 commit_event_enabled_ = *(reinterpret_cast<bool *>(payload));
671 }
672 break;
673 default:
674 DLOGE("Invalid input op %d", op);
675 error = kErrorParameters;
676 break;
677 }
678 return error;
679 }
680
SetDisplayDppsAdROI(void * payload)681 DisplayError DisplayBuiltIn::SetDisplayDppsAdROI(void *payload) {
682 lock_guard<recursive_mutex> obj(recursive_mutex_);
683 DisplayError err = kErrorNone;
684
685 err = hw_intf_->SetDisplayDppsAdROI(payload);
686 if (err != kErrorNone)
687 DLOGE("Failed to set ad roi config, err %d", err);
688
689 return err;
690 }
691
Init(DppsPropIntf * intf,const std::string & panel_name)692 void DppsInfo::Init(DppsPropIntf *intf, const std::string &panel_name) {
693 int error = 0;
694
695 if (dpps_initialized_) {
696 return;
697 }
698
699 if (!dpps_impl_lib.Open(kDppsLib)) {
700 DLOGW("Failed to load Dpps lib %s", kDppsLib);
701 goto exit;
702 }
703
704 if (!dpps_impl_lib.Sym("GetDppsInterface", reinterpret_cast<void **>(&GetDppsInterface))) {
705 DLOGE("GetDppsInterface not found!, err %s", dlerror());
706 goto exit;
707 }
708
709 dpps_intf = GetDppsInterface();
710 if (!dpps_intf) {
711 DLOGE("Failed to get Dpps Interface!");
712 goto exit;
713 }
714
715 error = dpps_intf->Init(intf, panel_name);
716 if (!error) {
717 DLOGI("DPPS Interface init successfully");
718 dpps_initialized_ = true;
719 return;
720 } else {
721 DLOGE("DPPS Interface init failure with err %d", error);
722 }
723
724 exit:
725 Deinit();
726 dpps_intf = new DppsDummyImpl();
727 dpps_initialized_ = true;
728 }
729
Deinit()730 void DppsInfo::Deinit() {
731 if (dpps_intf) {
732 dpps_intf->Deinit();
733 dpps_intf = NULL;
734 }
735 dpps_impl_lib.~DynLib();
736 }
737
DppsNotifyOps(enum DppsNotifyOps op,void * payload,size_t size)738 void DppsInfo::DppsNotifyOps(enum DppsNotifyOps op, void *payload, size_t size) {
739 int ret = 0;
740 ret = dpps_intf->DppsNotifyOps(op, payload, size);
741 if (ret)
742 DLOGE("DppsNotifyOps op %d error %d", op, ret);
743 }
744
HandleSecureEvent(SecureEvent secure_event,LayerStack * layer_stack)745 DisplayError DisplayBuiltIn::HandleSecureEvent(SecureEvent secure_event, LayerStack *layer_stack) {
746 hw_layers_.info.stack = layer_stack;
747 DisplayError err = hw_intf_->HandleSecureEvent(secure_event, &hw_layers_);
748 if (err != kErrorNone) {
749 return err;
750 }
751 comp_manager_->HandleSecureEvent(display_comp_ctx_, secure_event);
752
753 return kErrorNone;
754 }
755
SetQSyncMode(QSyncMode qsync_mode)756 DisplayError DisplayBuiltIn::SetQSyncMode(QSyncMode qsync_mode) {
757 lock_guard<recursive_mutex> obj(recursive_mutex_);
758 if (!hw_panel_info_.qsync_support || qsync_mode_ == qsync_mode || first_cycle_) {
759 DLOGE("Failed: qsync_support: %d first_cycle %d mode: %d -> %d", hw_panel_info_.qsync_support,
760 first_cycle_, qsync_mode_, qsync_mode);
761 return kErrorNotSupported;
762 }
763
764 qsync_mode_ = qsync_mode;
765 needs_avr_update_ = true;
766 event_handler_->Refresh();
767
768 return kErrorNone;
769 }
770
ControlIdlePowerCollapse(bool enable,bool synchronous)771 DisplayError DisplayBuiltIn::ControlIdlePowerCollapse(bool enable, bool synchronous) {
772 lock_guard<recursive_mutex> obj(recursive_mutex_);
773 if (!active_) {
774 DLOGW("Invalid display state = %d. Panel must be on.", state_);
775 return kErrorPermission;
776 }
777 if (hw_panel_info_.mode == kModeVideo) {
778 DLOGW("Idle power collapse not supported for video mode panel.");
779 return kErrorNotSupported;
780 }
781 return hw_intf_->ControlIdlePowerCollapse(enable, synchronous);
782 }
783
GetSupportedDSIClock(std::vector<uint64_t> * bitclk_rates)784 DisplayError DisplayBuiltIn::GetSupportedDSIClock(std::vector<uint64_t> *bitclk_rates) {
785 lock_guard<recursive_mutex> obj(recursive_mutex_);
786 if (!hw_panel_info_.dyn_bitclk_support) {
787 return kErrorNotSupported;
788 }
789
790 *bitclk_rates = hw_panel_info_.bitclk_rates;
791 return kErrorNone;
792 }
793
SetDynamicDSIClock(uint64_t bit_clk_rate)794 DisplayError DisplayBuiltIn::SetDynamicDSIClock(uint64_t bit_clk_rate) {
795 lock_guard<recursive_mutex> obj(recursive_mutex_);
796 if (!active_) {
797 DLOGW("Invalid display state = %d. Panel must be on.", state_);
798 return kErrorNotSupported;
799 }
800
801 if (!hw_panel_info_.dyn_bitclk_support) {
802 return kErrorNotSupported;
803 }
804
805 uint64_t current_clk = 0;
806 std::vector<uint64_t> &clk_rates = hw_panel_info_.bitclk_rates;
807 GetDynamicDSIClock(¤t_clk);
808 bool valid = std::find(clk_rates.begin(), clk_rates.end(), bit_clk_rate) != clk_rates.end();
809 if (current_clk == bit_clk_rate || !valid) {
810 DLOGI("Invalid setting %d, Clk. already set %d", !valid, (current_clk == bit_clk_rate));
811 return kErrorNone;
812 }
813
814 return hw_intf_->SetDynamicDSIClock(bit_clk_rate);
815 }
816
GetDynamicDSIClock(uint64_t * bit_clk_rate)817 DisplayError DisplayBuiltIn::GetDynamicDSIClock(uint64_t *bit_clk_rate) {
818 lock_guard<recursive_mutex> obj(recursive_mutex_);
819 if (!hw_panel_info_.dyn_bitclk_support) {
820 return kErrorNotSupported;
821 }
822
823 return hw_intf_->GetDynamicDSIClock(bit_clk_rate);
824 }
825
CanCompareFrameROI(LayerStack * layer_stack)826 bool DisplayBuiltIn::CanCompareFrameROI(LayerStack *layer_stack) {
827 // Check Display validation and safe-mode states.
828 if (needs_validate_ || comp_manager_->IsSafeMode()) {
829 return false;
830 }
831
832 // Check Panel and Layer Stack attributes.
833 if (!hw_panel_info_.partial_update || (hw_panel_info_.left_roi_count != 1) ||
834 layer_stack->flags.geometry_changed || layer_stack->flags.config_changed ||
835 (layer_stack->layers.size() != (hw_layers_.info.app_layer_count + 1))) {
836 return false;
837 }
838
839 // Check for Partial Update disable requests/scenarios.
840 if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) {
841 DisablePartialUpdateOneFrame();
842 }
843
844 if (!partial_update_control_ || disable_pu_one_frame_ || disable_pu_on_dest_scaler_) {
845 return false;
846 }
847
848 bool surface_damage = false;
849 uint32_t surface_damage_mask_value = (1 << kSurfaceDamage);
850 for (uint32_t i = 0; i < layer_stack->layers.size(); i++) {
851 Layer *layer = layer_stack->layers.at(i);
852 if (layer->update_mask.none()) {
853 continue;
854 }
855 // Only kSurfaceDamage bit should be set in layer's update-mask.
856 if (layer->update_mask.to_ulong() == surface_damage_mask_value) {
857 surface_damage = true;
858 } else {
859 return false;
860 }
861 }
862
863 return surface_damage;
864 }
865
CanSkipDisplayPrepare(LayerStack * layer_stack)866 bool DisplayBuiltIn::CanSkipDisplayPrepare(LayerStack *layer_stack) {
867 if (!CanCompareFrameROI(layer_stack)) {
868 return false;
869 }
870
871 DisplayError error = BuildLayerStackStats(layer_stack);
872 if (error != kErrorNone) {
873 return false;
874 }
875
876 hw_layers_.info.left_frame_roi.clear();
877 hw_layers_.info.right_frame_roi.clear();
878 hw_layers_.info.dest_scale_info_map.clear();
879 comp_manager_->GenerateROI(display_comp_ctx_, &hw_layers_);
880
881 if (!hw_layers_.info.left_frame_roi.size() || !hw_layers_.info.right_frame_roi.size()) {
882 return false;
883 }
884
885 // Compare the cached and calculated Frame ROIs.
886 bool same_roi = IsCongruent(left_frame_roi_, hw_layers_.info.left_frame_roi.at(0)) &&
887 IsCongruent(right_frame_roi_, hw_layers_.info.right_frame_roi.at(0));
888
889 if (same_roi) {
890 // Update Surface Damage rectangle(s) in HW layers.
891 uint32_t hw_layer_count = UINT32(hw_layers_.info.hw_layers.size());
892 for (uint32_t j = 0; j < hw_layer_count; j++) {
893 Layer &hw_layer = hw_layers_.info.hw_layers.at(j);
894 Layer *sdm_layer = layer_stack->layers.at(hw_layers_.info.index.at(j));
895 if (hw_layer.dirty_regions.size() != sdm_layer->dirty_regions.size()) {
896 return false;
897 }
898 for (uint32_t k = 0; k < hw_layer.dirty_regions.size(); k++) {
899 hw_layer.dirty_regions.at(k) = sdm_layer->dirty_regions.at(k);
900 }
901 }
902
903 // Set the composition type for SDM layers.
904 for (uint32_t i = 0; i < (layer_stack->layers.size() - 1); i++) {
905 layer_stack->layers.at(i)->composition = kCompositionSDE;
906 }
907 }
908
909 return same_roi;
910 }
911
ReconfigureDisplay()912 DisplayError DisplayBuiltIn::ReconfigureDisplay() {
913 lock_guard<recursive_mutex> obj(recursive_mutex_);
914 DisplayError error = kErrorNone;
915 HWDisplayAttributes display_attributes;
916 HWMixerAttributes mixer_attributes;
917 HWPanelInfo hw_panel_info;
918 uint32_t active_index = 0;
919
920 DTRACE_SCOPED();
921
922 error = hw_intf_->GetActiveConfig(&active_index);
923 if (error != kErrorNone) {
924 return error;
925 }
926
927 error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
928 if (error != kErrorNone) {
929 return error;
930 }
931
932 error = hw_intf_->GetMixerAttributes(&mixer_attributes);
933 if (error != kErrorNone) {
934 return error;
935 }
936
937 error = hw_intf_->GetHWPanelInfo(&hw_panel_info);
938 if (error != kErrorNone) {
939 return error;
940 }
941
942 const bool dirty = deferred_config_.IsDirty();
943 if (deferred_config_.IsDeferredState()) {
944 if (dirty) {
945 SetDeferredFpsConfig();
946 } else {
947 // In Deferred state, use current config for comparison.
948 GetFpsConfig(&display_attributes, &hw_panel_info);
949 }
950 }
951
952 const bool display_unchanged = (display_attributes == display_attributes_);
953 const bool mixer_unchanged = (mixer_attributes == mixer_attributes_);
954 const bool panel_unchanged = (hw_panel_info == hw_panel_info_);
955 if (!dirty && display_unchanged && mixer_unchanged && panel_unchanged) {
956 return kErrorNone;
957 }
958
959 if (CanDeferFpsConfig(display_attributes.fps)) {
960 deferred_config_.Init(display_attributes.fps, display_attributes.vsync_period_ns,
961 hw_panel_info.transfer_time_us);
962
963 // Apply current config until new Fps is deferred.
964 GetFpsConfig(&display_attributes, &hw_panel_info);
965 }
966
967 error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info,
968 mixer_attributes, fb_config_,
969 &(default_qos_data_.clock_hz));
970 if (error != kErrorNone) {
971 return error;
972 }
973
974 bool disble_pu = true;
975 if (mixer_unchanged && panel_unchanged) {
976 // Do not disable Partial Update for one frame, if only FPS has changed.
977 // Because if first frame after transition, has a partial Frame-ROI and
978 // is followed by Skip Validate frames, then it can benefit those frames.
979 disble_pu = !display_attributes_.OnlyFpsChanged(display_attributes);
980 }
981
982 if (disble_pu) {
983 DisablePartialUpdateOneFrame();
984 }
985
986 display_attributes_ = display_attributes;
987 mixer_attributes_ = mixer_attributes;
988 hw_panel_info_ = hw_panel_info;
989
990 // TODO(user): Temporary changes, to be removed when DRM driver supports
991 // Partial update with Destination scaler enabled.
992 SetPUonDestScaler();
993
994 return kErrorNone;
995 }
996
CanDeferFpsConfig(uint32_t fps)997 bool DisplayBuiltIn::CanDeferFpsConfig(uint32_t fps) {
998 if (deferred_config_.CanApplyDeferredState()) {
999 // Deferred Fps Config needs to be applied.
1000 return false;
1001 }
1002
1003 // In case of higher to lower Fps transition on a Builtin display, defer the Fps
1004 // (Transfer time) configuration, for the number of frames based on frame_count.
1005 return ((deferred_config_.frame_count != 0) && (display_attributes_.fps > fps));
1006 }
1007
SetDeferredFpsConfig()1008 void DisplayBuiltIn::SetDeferredFpsConfig() {
1009 // Update with the deferred Fps Config.
1010 display_attributes_.fps = deferred_config_.fps;
1011 display_attributes_.vsync_period_ns = deferred_config_.vsync_period_ns;
1012 hw_panel_info_.transfer_time_us = deferred_config_.transfer_time_us;
1013 deferred_config_.Clear();
1014 }
1015
GetFpsConfig(HWDisplayAttributes * display_attr,HWPanelInfo * panel_info)1016 void DisplayBuiltIn::GetFpsConfig(HWDisplayAttributes *display_attr, HWPanelInfo *panel_info) {
1017 display_attr->fps = display_attributes_.fps;
1018 display_attr->vsync_period_ns = display_attributes_.vsync_period_ns;
1019 panel_info->transfer_time_us = hw_panel_info_.transfer_time_us;
1020 }
1021
GetRefreshRate(uint32_t * refresh_rate)1022 DisplayError DisplayBuiltIn::GetRefreshRate(uint32_t *refresh_rate) {
1023 *refresh_rate = current_refresh_rate_;
1024 return kErrorNone;
1025 }
1026
1027 } // namespace sdm
1028