• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
DisplayPrimary(DisplayEventHandler * event_handler,HWInfoInterface * hw_info_intf,BufferSyncHandler * buffer_sync_handler,CompManager * comp_manager,RotatorInterface * rotator_intf)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 
Init()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 
Deinit()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 
Prepare(LayerStack * layer_stack)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 
Commit(LayerStack * layer_stack)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 
SetDisplayState(DisplayState state)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 
SetIdleTimeoutMs(uint32_t timeout_ms)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 
SetDisplayMode(uint32_t mode)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 
SetPanelBrightness(int level)207 DisplayError DisplayPrimary::SetPanelBrightness(int level) {
208   lock_guard<recursive_mutex> obj(recursive_mutex_);
209   return hw_intf_->SetPanelBrightness(level);
210 }
211 
GetRefreshRateRange(uint32_t * min_refresh_rate,uint32_t * max_refresh_rate)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 
SetRefreshRate(uint32_t refresh_rate)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 
VSync(int64_t timestamp)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 
IdleTimeout()257 void DisplayPrimary::IdleTimeout() {
258   event_handler_->Refresh();
259   comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
260 }
261 
ThermalEvent(int64_t thermal_level)262 void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
263   lock_guard<recursive_mutex> obj(recursive_mutex_);
264   comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
265 }
266 
GetPanelBrightness(int * level)267 DisplayError DisplayPrimary::GetPanelBrightness(int *level) {
268   lock_guard<recursive_mutex> obj(recursive_mutex_);
269   return hw_intf_->GetPanelBrightness(level);
270 }
271 
ControlPartialUpdate(bool enable,uint32_t * pending)272 DisplayError DisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
273   lock_guard<recursive_mutex> obj(recursive_mutex_);
274   if (!pending) {
275     return kErrorParameters;
276   }
277 
278   if (!hw_panel_info_.partial_update) {
279     // Nothing to be done.
280     DLOGI("partial update is not applicable for display=%d", display_type_);
281     return kErrorNotSupported;
282   }
283 
284   *pending = 0;
285   if (enable == partial_update_control_) {
286     DLOGI("Same state transition is requested.");
287     return kErrorNone;
288   }
289 
290   partial_update_control_ = enable;
291 
292   if (!enable) {
293     // If the request is to turn off feature, new draw call is required to have
294     // the new setting into effect.
295     *pending = 1;
296   }
297 
298   return kErrorNone;
299 }
300 
DisablePartialUpdateOneFrame()301 DisplayError DisplayPrimary::DisablePartialUpdateOneFrame() {
302   lock_guard<recursive_mutex> obj(recursive_mutex_);
303   disable_pu_one_frame_ = true;
304 
305   return kErrorNone;
306 }
307 
308 }  // namespace sdm
309 
310