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