• 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
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *     * Redistributions of source code must retain the above copyright
8 *       notice, this list of conditions and the following disclaimer.
9 *     * Redistributions in binary form must reproduce the above
10 *       copyright notice, this list of conditions and the following
11 *       disclaimer in the documentation and/or other materials provided
12 *       with the distribution.
13 *     * Neither the name of The Linux Foundation nor the names of its
14 *       contributors may be used to endorse or promote products derived
15 *       from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 #include <cutils/properties.h>
31 #include <utils/constants.h>
32 #include <utils/debug.h>
33 #include <stdarg.h>
34 #include "hwc_display_primary.h"
35 #include "hwc_debugger.h"
36 
37 #define __CLASS__ "HWCDisplayPrimary"
38 
39 namespace sdm {
40 
Create(CoreInterface * core_intf,hwc_procs_t const ** hwc_procs,HWCDisplay ** hwc_display)41 int HWCDisplayPrimary::Create(CoreInterface *core_intf, hwc_procs_t const **hwc_procs,
42                               HWCDisplay **hwc_display) {
43   int status = 0;
44   uint32_t primary_width = 0;
45   uint32_t primary_height = 0;
46 
47   HWCDisplay *hwc_display_primary = new HWCDisplayPrimary(core_intf, hwc_procs);
48   status = hwc_display_primary->Init();
49   if (status) {
50     delete hwc_display_primary;
51     return status;
52   }
53 
54   hwc_display_primary->GetPanelResolution(&primary_width, &primary_height);
55   int width = 0, height = 0;
56   HWCDebugHandler::Get()->GetProperty("sdm.fb_size_width", &width);
57   HWCDebugHandler::Get()->GetProperty("sdm.fb_size_height", &height);
58   if (width > 0 && height > 0) {
59     primary_width = UINT32(width);
60     primary_height = UINT32(height);
61   }
62 
63   status = hwc_display_primary->SetFrameBufferResolution(primary_width, primary_height);
64   if (status) {
65     Destroy(hwc_display_primary);
66     return status;
67   }
68 
69   *hwc_display = hwc_display_primary;
70 
71   return status;
72 }
73 
Destroy(HWCDisplay * hwc_display)74 void HWCDisplayPrimary::Destroy(HWCDisplay *hwc_display) {
75   hwc_display->Deinit();
76   delete hwc_display;
77 }
78 
HWCDisplayPrimary(CoreInterface * core_intf,hwc_procs_t const ** hwc_procs)79 HWCDisplayPrimary::HWCDisplayPrimary(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
80   : HWCDisplay(core_intf, hwc_procs, kPrimary, HWC_DISPLAY_PRIMARY, true), cpu_hint_(NULL) {
81 }
82 
Init()83 int HWCDisplayPrimary::Init() {
84   cpu_hint_ = new CPUHint();
85   if (cpu_hint_->Init(static_cast<HWCDebugHandler*>(HWCDebugHandler::Get())) != kErrorNone) {
86     delete cpu_hint_;
87     cpu_hint_ = NULL;
88   }
89 
90   use_metadata_refresh_rate_ = true;
91   int disable_metadata_dynfps = 0;
92   HWCDebugHandler::Get()->GetProperty("persist.metadata_dynfps.disable", &disable_metadata_dynfps);
93   if (disable_metadata_dynfps) {
94     use_metadata_refresh_rate_ = false;
95   }
96 
97   return HWCDisplay::Init();
98 }
99 
ProcessBootAnimCompleted(hwc_display_contents_1_t * list)100 void HWCDisplayPrimary::ProcessBootAnimCompleted(hwc_display_contents_1_t *list) {
101   uint32_t numBootUpLayers = 0;
102 
103   numBootUpLayers = static_cast<uint32_t>(Debug::GetBootAnimLayerCount());
104 
105   if (numBootUpLayers == 0) {
106     numBootUpLayers = 2;
107   }
108   /* All other checks namely "init.svc.bootanim" or
109   * HWC_GEOMETRY_CHANGED fail in correctly identifying the
110   * exact bootup transition to homescreen
111   */
112   char cryptoState[PROPERTY_VALUE_MAX];
113   char voldDecryptState[PROPERTY_VALUE_MAX];
114   bool isEncrypted = false;
115   bool main_class_services_started = false;
116   if (property_get("ro.crypto.state", cryptoState, "unencrypted")) {
117     if (!strcmp(cryptoState, "encrypted")) {
118       isEncrypted = true;
119       if (property_get("vold.decrypt", voldDecryptState, "") &&
120             !strcmp(voldDecryptState, "trigger_restart_framework"))
121         main_class_services_started = true;
122     }
123   }
124   if ((!isEncrypted ||(isEncrypted && main_class_services_started)) &&
125     (list->numHwLayers > numBootUpLayers)) {
126     boot_animation_completed_ = true;
127     // Applying default mode after bootanimation is finished And
128     // If Data is Encrypted, it is ready for access.
129     if (display_intf_)
130       display_intf_->ApplyDefaultDisplayMode();
131   }
132 }
133 
Prepare(hwc_display_contents_1_t * content_list)134 int HWCDisplayPrimary::Prepare(hwc_display_contents_1_t *content_list) {
135   int status = 0;
136   DisplayError error = kErrorNone;
137 
138   if (!boot_animation_completed_)
139     ProcessBootAnimCompleted(content_list);
140 
141   if (display_paused_) {
142     MarkLayersForGPUBypass(content_list);
143     return status;
144   }
145 
146   status = AllocateLayerStack(content_list);
147   if (status) {
148     return status;
149   }
150 
151   status = PrePrepareLayerStack(content_list);
152   if (status) {
153     return status;
154   }
155 
156   bool one_updating_layer = SingleLayerUpdating(UINT32(content_list->numHwLayers - 1));
157   ToggleCPUHint(one_updating_layer);
158 
159   uint32_t refresh_rate = GetOptimalRefreshRate(one_updating_layer);
160   if (current_refresh_rate_ != refresh_rate) {
161     error = display_intf_->SetRefreshRate(refresh_rate);
162   }
163 
164   if (error == kErrorNone) {
165     // On success, set current refresh rate to new refresh rate
166     current_refresh_rate_ = refresh_rate;
167   }
168 
169   if (handle_idle_timeout_) {
170     handle_idle_timeout_ = false;
171   }
172 
173   if (content_list->numHwLayers <= 1) {
174     flush_ = true;
175     return 0;
176   }
177 
178   status = PrepareLayerStack(content_list);
179   if (status) {
180     return status;
181   }
182 
183   return 0;
184 }
185 
Commit(hwc_display_contents_1_t * content_list)186 int HWCDisplayPrimary::Commit(hwc_display_contents_1_t *content_list) {
187   int status = 0;
188   if (display_paused_) {
189     if (content_list->outbufAcquireFenceFd >= 0) {
190       // If we do not handle the frame set retireFenceFd to outbufAcquireFenceFd,
191       // which will make sure the framework waits on it and closes it.
192       content_list->retireFenceFd = dup(content_list->outbufAcquireFenceFd);
193       close(content_list->outbufAcquireFenceFd);
194       content_list->outbufAcquireFenceFd = -1;
195     }
196 
197     DisplayError error = display_intf_->Flush();
198     if (error != kErrorNone) {
199       DLOGE("Flush failed. Error = %d", error);
200     }
201     return status;
202   }
203 
204   status = HWCDisplay::CommitLayerStack(content_list);
205   if (status) {
206     return status;
207   }
208 
209   status = HWCDisplay::PostCommitLayerStack(content_list);
210   if (status) {
211     return status;
212   }
213 
214   return 0;
215 }
216 
Perform(uint32_t operation,...)217 int HWCDisplayPrimary::Perform(uint32_t operation, ...) {
218   va_list args;
219   va_start(args, operation);
220   int val = va_arg(args, int32_t);
221   va_end(args);
222   switch (operation) {
223     case SET_METADATA_DYN_REFRESH_RATE:
224       SetMetaDataRefreshRateFlag(val);
225       break;
226     case SET_BINDER_DYN_REFRESH_RATE:
227       ForceRefreshRate(UINT32(val));
228       break;
229     case SET_DISPLAY_MODE:
230       SetDisplayMode(UINT32(val));
231       break;
232     case SET_QDCM_SOLID_FILL_INFO:
233       SetQDCMSolidFillInfo(true, UINT32(val));
234       break;
235     case UNSET_QDCM_SOLID_FILL_INFO:
236       SetQDCMSolidFillInfo(false, UINT32(val));
237       break;
238     default:
239       DLOGW("Invalid operation %d", operation);
240       return -EINVAL;
241   }
242 
243   return 0;
244 }
245 
SetDisplayMode(uint32_t mode)246 DisplayError HWCDisplayPrimary::SetDisplayMode(uint32_t mode) {
247   DisplayError error = kErrorNone;
248 
249   if (display_intf_) {
250     error = display_intf_->SetDisplayMode(mode);
251   }
252 
253   return error;
254 }
255 
SetMetaDataRefreshRateFlag(bool enable)256 void HWCDisplayPrimary::SetMetaDataRefreshRateFlag(bool enable) {
257   int disable_metadata_dynfps = 0;
258 
259   HWCDebugHandler::Get()->GetProperty("persist.metadata_dynfps.disable", &disable_metadata_dynfps);
260   if (disable_metadata_dynfps) {
261     return;
262   }
263   use_metadata_refresh_rate_ = enable;
264 }
265 
SetQDCMSolidFillInfo(bool enable,uint32_t color)266 void HWCDisplayPrimary::SetQDCMSolidFillInfo(bool enable, uint32_t color) {
267   solid_fill_enable_ = enable;
268   solid_fill_color_  = color;
269 }
270 
ToggleCPUHint(bool set)271 void HWCDisplayPrimary::ToggleCPUHint(bool set) {
272   if (!cpu_hint_) {
273     return;
274   }
275 
276   if (set) {
277     cpu_hint_->Set();
278   } else {
279     cpu_hint_->Reset();
280   }
281 }
282 
SetSecureDisplay(bool secure_display_active)283 void HWCDisplayPrimary::SetSecureDisplay(bool secure_display_active) {
284   if (secure_display_active_ != secure_display_active) {
285     // Skip Prepare and call Flush for null commit
286     DLOGI("SecureDisplay state changed from %d to %d Needs Flush!!", secure_display_active_,
287            secure_display_active);
288     secure_display_active_ = secure_display_active;
289     skip_prepare_ = true;
290   }
291   return;
292 }
293 
ForceRefreshRate(uint32_t refresh_rate)294 void HWCDisplayPrimary::ForceRefreshRate(uint32_t refresh_rate) {
295   if ((refresh_rate && (refresh_rate < min_refresh_rate_ || refresh_rate > max_refresh_rate_)) ||
296        force_refresh_rate_ == refresh_rate) {
297     // Cannot honor force refresh rate, as its beyond the range or new request is same
298     return;
299   }
300 
301   const hwc_procs_t *hwc_procs = *hwc_procs_;
302   force_refresh_rate_ = refresh_rate;
303 
304   hwc_procs->invalidate(hwc_procs);
305 
306   return;
307 }
308 
GetOptimalRefreshRate(bool one_updating_layer)309 uint32_t HWCDisplayPrimary::GetOptimalRefreshRate(bool one_updating_layer) {
310   if (force_refresh_rate_) {
311     return force_refresh_rate_;
312   } else if (handle_idle_timeout_) {
313     return min_refresh_rate_;
314   } else if (use_metadata_refresh_rate_ && one_updating_layer && metadata_refresh_rate_) {
315     return metadata_refresh_rate_;
316   }
317 
318   return max_refresh_rate_;
319 }
320 
Refresh()321 DisplayError HWCDisplayPrimary::Refresh() {
322   const hwc_procs_t *hwc_procs = *hwc_procs_;
323   DisplayError error = kErrorNone;
324 
325   if (!hwc_procs) {
326     return kErrorParameters;
327   }
328 
329   hwc_procs->invalidate(hwc_procs);
330   handle_idle_timeout_ = true;
331 
332   return error;
333 }
334 
SetIdleTimeoutMs(uint32_t timeout_ms)335 void HWCDisplayPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
336   display_intf_->SetIdleTimeoutMs(timeout_ms);
337 }
338 
339 }  // namespace sdm
340 
341