1 /*
2 * Copyright (c) 2015 - 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 <dlfcn.h>
31 #include <powermanager/IPowerManager.h>
32 #include <cutils/sockets.h>
33 #include <cutils/native_handle.h>
34 #include <utils/String16.h>
35 #include <binder/Parcel.h>
36 #include <gralloc_priv.h>
37 #include <hardware/hwcomposer.h>
38 #include <hardware/hwcomposer_defs.h>
39 #include <QService.h>
40
41 #include <core/dump_interface.h>
42 #include <utils/constants.h>
43 #include <utils/debug.h>
44 #include <core/buffer_allocator.h>
45 #include <private/color_params.h>
46 #include "hwc_buffer_allocator.h"
47 #include "hwc_buffer_sync_handler.h"
48 #include "hwc_session.h"
49 #include "hwc_debugger.h"
50
51 #define __CLASS__ "HWCColorManager"
52
53 namespace sdm {
54
Get8BitsARGBColorValue(const PPColorFillParams & params)55 uint32_t HWCColorManager::Get8BitsARGBColorValue(const PPColorFillParams ¶ms) {
56 uint32_t argb_color = ((params.color.r << 16) & 0xff0000) | ((params.color.g) & 0xff)
57 | ((params.color.b << 8) & 0xff00);
58 return argb_color;
59 }
60
CreatePayloadFromParcel(const android::Parcel & in,uint32_t * disp_id,PPDisplayAPIPayload * sink)61 int HWCColorManager::CreatePayloadFromParcel(const android::Parcel &in, uint32_t *disp_id,
62 PPDisplayAPIPayload *sink) {
63 int ret = 0;
64 uint32_t id(0);
65 uint32_t size(0);
66
67 id = UINT32(in.readInt32());
68 size = UINT32(in.readInt32());
69 if (size > 0 && size == in.dataAvail()) {
70 const void *data = in.readInplace(size);
71 const uint8_t *temp = reinterpret_cast<const uint8_t *>(data);
72
73 sink->size = size;
74 sink->payload = const_cast<uint8_t *>(temp);
75 *disp_id = id;
76 } else {
77 DLOGW("Failing size checking, size = %d", size);
78 ret = -EINVAL;
79 }
80
81 return ret;
82 }
83
MarshallStructIntoParcel(const PPDisplayAPIPayload & data,android::Parcel * out_parcel)84 void HWCColorManager::MarshallStructIntoParcel(const PPDisplayAPIPayload &data,
85 android::Parcel *out_parcel) {
86 out_parcel->writeInt32(INT32(data.size));
87 if (data.payload)
88 out_parcel->write(data.payload, data.size);
89 }
90
CreateColorManager()91 HWCColorManager *HWCColorManager::CreateColorManager() {
92 HWCColorManager *color_mgr = new HWCColorManager();
93
94 if (color_mgr) {
95 void *&color_lib = color_mgr->color_apis_lib_;
96 // Load display API interface library. And retrieve color API function tables.
97 color_lib = ::dlopen(DISPLAY_API_INTERFACE_LIBRARY_NAME, RTLD_NOW);
98 if (color_lib) {
99 color_mgr->color_apis_ = ::dlsym(color_lib, DISPLAY_API_FUNC_TABLES);
100 if (!color_mgr->color_apis_) {
101 DLOGE("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES,
102 DISPLAY_API_INTERFACE_LIBRARY_NAME);
103 ::dlclose(color_lib);
104 delete color_mgr;
105 return NULL;
106 }
107 } else {
108 DLOGW("Unable to load = %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
109 delete color_mgr;
110 return NULL;
111 }
112 DLOGI("Successfully loaded %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
113
114 // Load diagclient library and invokes its entry point to pass in display APIs.
115 void *&diag_lib = color_mgr->diag_client_lib_;
116 diag_lib = ::dlopen(QDCM_DIAG_CLIENT_LIBRARY_NAME, RTLD_NOW);
117 if (diag_lib) {
118 *(reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) =
119 ::dlsym(diag_lib, INIT_QDCM_DIAG_CLIENT_NAME);
120 *(reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_)) =
121 ::dlsym(diag_lib, DEINIT_QDCM_DIAG_CLIENT_NAME);
122
123 if (!color_mgr->qdcm_diag_init_ || !color_mgr->qdcm_diag_deinit_) {
124 DLOGE("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME,
125 QDCM_DIAG_CLIENT_LIBRARY_NAME);
126 ::dlclose(diag_lib);
127 } else {
128 // invoke Diag Client entry point to initialize.
129 color_mgr->qdcm_diag_init_(color_mgr->color_apis_);
130 DLOGI("Successfully loaded %s and %s and diag_init'ed", DISPLAY_API_INTERFACE_LIBRARY_NAME,
131 QDCM_DIAG_CLIENT_LIBRARY_NAME);
132 }
133 } else {
134 DLOGW("Unable to load = %s", QDCM_DIAG_CLIENT_LIBRARY_NAME);
135 // only QDCM Diag client failed to be loaded and system still should function.
136 }
137 } else {
138 DLOGE("Unable to create HWCColorManager");
139 return NULL;
140 }
141
142 return color_mgr;
143 }
144
~HWCColorManager()145 HWCColorManager::~HWCColorManager() {
146 }
147
DestroyColorManager()148 void HWCColorManager::DestroyColorManager() {
149 if (qdcm_mode_mgr_) {
150 delete qdcm_mode_mgr_;
151 }
152 if (qdcm_diag_deinit_) {
153 qdcm_diag_deinit_();
154 }
155 if (diag_client_lib_) {
156 ::dlclose(diag_client_lib_);
157 }
158 if (color_apis_lib_) {
159 ::dlclose(color_apis_lib_);
160 }
161 delete this;
162 }
163
EnableQDCMMode(bool enable,HWCDisplay * hwc_display)164 int HWCColorManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
165 int ret = 0;
166
167 if (!qdcm_mode_mgr_) {
168 qdcm_mode_mgr_ = HWCQDCMModeManager::CreateQDCMModeMgr();
169 if (!qdcm_mode_mgr_) {
170 DLOGE("Unable to create QDCM operating mode manager.");
171 ret = -EFAULT;
172 }
173 }
174
175 if (qdcm_mode_mgr_) {
176 ret = qdcm_mode_mgr_->EnableQDCMMode(enable, hwc_display);
177 }
178
179 return ret;
180 }
181
SolidFillLayersPrepare(hwc_display_contents_1_t ** displays,HWCDisplay * hwc_display)182 bool HWCColorManager::SolidFillLayersPrepare(hwc_display_contents_1_t **displays,
183 HWCDisplay *hwc_display) {
184 SCOPE_LOCK(locker_);
185
186 // Query HWCColorManager if QDCM tool requesting SOLID_FILL mode.
187 uint32_t solid_fill_color = Get8BitsARGBColorValue(solid_fill_params_);
188 hwc_display_contents_1_t *layer_list = displays[HWC_DISPLAY_PRIMARY];
189
190 if (solid_fill_enable_ && solid_fill_layers_ && layer_list) {
191 // 1. shallow copy HWC_FRAMEBUFFER_TARGET layer info solid fill layer list.
192 solid_fill_layers_->hwLayers[1] = layer_list->hwLayers[layer_list->numHwLayers - 1];
193
194 // 2. continue the prepare<> on solid_fill_layers.
195 hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_INFO, solid_fill_color);
196 hwc_display->Prepare(solid_fill_layers_); // RECT info included.
197
198 // 3. Set HWC_OVERLAY to all SF layers before returning to framework.
199 for (size_t i = 0; i < (layer_list->numHwLayers - 1); i++) {
200 hwc_layer_1_t *layer = &layer_list->hwLayers[i];
201 layer->compositionType = HWC_OVERLAY;
202 }
203
204 return true;
205 } else if (!solid_fill_enable_) {
206 hwc_display->Perform(HWCDisplayPrimary::UNSET_QDCM_SOLID_FILL_INFO, 0);
207 }
208
209 return false;
210 }
211
SolidFillLayersSet(hwc_display_contents_1_t ** displays,HWCDisplay * hwc_display)212 bool HWCColorManager::SolidFillLayersSet(hwc_display_contents_1_t **displays,
213 HWCDisplay *hwc_display) {
214 // Query HWCColorManager if QDCM tool requesting SOLID_FILL mode.
215 SCOPE_LOCK(locker_);
216 hwc_display_contents_1_t *layer_list = displays[HWC_DISPLAY_PRIMARY];
217 if (solid_fill_enable_ && solid_fill_layers_ && layer_list) {
218 hwc_display->Commit(solid_fill_layers_);
219
220 // SurfaceFlinger layer stack is dropped in solid fill case and replaced with local layer stack
221 // Close acquire fence fds associated with SF layer stack
222 // Close release/retire fence fds returned along with local layer stack
223 for (size_t i = 0; i < (layer_list->numHwLayers - 1); i++) {
224 int &fence_fd = layer_list->hwLayers[i].acquireFenceFd;
225 if (fence_fd >= 0) {
226 close(fence_fd);
227 fence_fd = -1;
228 }
229 }
230
231 for (size_t i = 0; i < (solid_fill_layers_->numHwLayers - 1); i++) {
232 int &fence_fd = solid_fill_layers_->hwLayers[i].releaseFenceFd;
233 if (fence_fd >= 0) {
234 close(fence_fd);
235 fence_fd = -1;
236 }
237 }
238 if (solid_fill_layers_->retireFenceFd >= 0) {
239 close(solid_fill_layers_->retireFenceFd);
240 solid_fill_layers_->retireFenceFd = -1;
241 }
242
243 return true;
244 }
245
246 return false;
247 }
248
CreateSolidFillLayers(HWCDisplay * hwc_display)249 int HWCColorManager::CreateSolidFillLayers(HWCDisplay *hwc_display) {
250 int ret = 0;
251
252 if (!solid_fill_layers_) {
253 uint32_t size = sizeof(hwc_display_contents_1) + kNumSolidFillLayers * sizeof(hwc_layer_1_t);
254 uint32_t primary_width = 0;
255 uint32_t primary_height = 0;
256
257 hwc_display->GetPanelResolution(&primary_width, &primary_height);
258 uint8_t *buf = new uint8_t[size]();
259 // handle for solid fill layer with fd = -1.
260 private_handle_t *handle =
261 new private_handle_t(-1, 0, private_handle_t::PRIV_FLAGS_FRAMEBUFFER, BUFFER_TYPE_UI,
262 HAL_PIXEL_FORMAT_RGBA_8888, INT32(primary_width),
263 INT32(primary_height));
264
265 if (!buf || !handle) {
266 DLOGE("Failed to allocate memory.");
267 if (buf)
268 delete[] buf;
269 if (handle)
270 delete handle;
271
272 return -ENOMEM;
273 }
274
275 solid_fill_layers_ = reinterpret_cast<hwc_display_contents_1 *>(buf);
276 hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0];
277 layer.handle = handle;
278 }
279
280 solid_fill_layers_->flags = HWC_GEOMETRY_CHANGED;
281 solid_fill_layers_->numHwLayers = kNumSolidFillLayers;
282 solid_fill_layers_->retireFenceFd = -1;
283 solid_fill_layers_->outbuf = NULL;
284 solid_fill_layers_->outbufAcquireFenceFd = -1;
285
286 hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0];
287 hwc_rect_t solid_fill_rect = {
288 INT(solid_fill_params_.rect.x),
289 INT(solid_fill_params_.rect.y),
290 solid_fill_params_.rect.x + INT(solid_fill_params_.rect.width),
291 solid_fill_params_.rect.y + INT(solid_fill_params_.rect.height),
292 };
293
294 layer.compositionType = HWC_FRAMEBUFFER;
295 layer.blending = HWC_BLENDING_PREMULT;
296 layer.sourceCropf.left = solid_fill_params_.rect.x;
297 layer.sourceCropf.top = solid_fill_params_.rect.y;
298 layer.sourceCropf.right = UINT32(solid_fill_params_.rect.x) + solid_fill_params_.rect.width;
299 layer.sourceCropf.bottom = UINT32(solid_fill_params_.rect.y) + solid_fill_params_.rect.height;
300 layer.acquireFenceFd = -1;
301 layer.releaseFenceFd = -1;
302 layer.flags = 0;
303 layer.transform = 0;
304 layer.hints = 0;
305 layer.planeAlpha = 0xff;
306 layer.displayFrame = solid_fill_rect;
307 layer.visibleRegionScreen.numRects = 1;
308 layer.visibleRegionScreen.rects = &layer.displayFrame;
309 layer.surfaceDamage.numRects = 0;
310
311 return ret;
312 }
313
DestroySolidFillLayers()314 void HWCColorManager::DestroySolidFillLayers() {
315 if (solid_fill_layers_) {
316 hwc_layer_1_t &layer = solid_fill_layers_->hwLayers[0];
317 uint8_t *buf = reinterpret_cast<uint8_t *>(solid_fill_layers_);
318 private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(layer.handle);
319
320 if (hnd)
321 delete hnd;
322
323 if (buf)
324 delete[] buf;
325
326 solid_fill_layers_ = NULL;
327 }
328 }
329
SetSolidFill(const void * params,bool enable,HWCDisplay * hwc_display)330 int HWCColorManager::SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display) {
331 SCOPE_LOCK(locker_);
332 int ret = 0;
333
334 if (params) {
335 solid_fill_params_ = *reinterpret_cast<const PPColorFillParams *>(params);
336 } else {
337 solid_fill_params_ = PPColorFillParams();
338 }
339
340 if (enable) {
341 // will create solid fill layers for rendering if not present.
342 ret = CreateSolidFillLayers(hwc_display);
343 } else {
344 DestroySolidFillLayers();
345 }
346 solid_fill_enable_ = enable;
347
348 return ret;
349 }
350
351 const HWCQDCMModeManager::ActiveFeatureCMD HWCQDCMModeManager::kActiveFeatureCMD[] = {
352 HWCQDCMModeManager::ActiveFeatureCMD("cabl:on", "cabl:off", "cabl:status", "running"),
353 HWCQDCMModeManager::ActiveFeatureCMD("ad:on", "ad:off", "ad:query:status", "running"),
354 HWCQDCMModeManager::ActiveFeatureCMD("svi:on", "svi:off", "svi:status", "running"),
355 };
356
357 const char *const HWCQDCMModeManager::kSocketName = "pps";
358 const char *const HWCQDCMModeManager::kTagName = "surfaceflinger";
359 const char *const HWCQDCMModeManager::kPackageName = "colormanager";
360
CreateQDCMModeMgr()361 HWCQDCMModeManager *HWCQDCMModeManager::CreateQDCMModeMgr() {
362 HWCQDCMModeManager *mode_mgr = new HWCQDCMModeManager();
363
364 if (!mode_mgr) {
365 DLOGW("No memory to create HWCQDCMModeManager.");
366 return NULL;
367 } else {
368 mode_mgr->socket_fd_ =
369 ::socket_local_client(kSocketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
370 if (mode_mgr->socket_fd_ < 0) {
371 // it should not be disastrous and we still can grab wakelock in QDCM mode.
372 DLOGW("Unable to connect to dpps socket!");
373 }
374
375 // retrieve system GPU idle timeout value for later to recover.
376 mode_mgr->entry_timeout_ = UINT32(HWCDebugHandler::GetIdleTimeoutMs());
377
378 // acquire the binder handle to Android system PowerManager for later use.
379 android::sp<android::IBinder> binder =
380 android::defaultServiceManager()->checkService(android::String16("power"));
381 if (binder == NULL) {
382 DLOGW("Application can't connect to power manager service");
383 delete mode_mgr;
384 mode_mgr = NULL;
385 } else {
386 mode_mgr->power_mgr_ = android::interface_cast<android::IPowerManager>(binder);
387 }
388 }
389
390 return mode_mgr;
391 }
392
~HWCQDCMModeManager()393 HWCQDCMModeManager::~HWCQDCMModeManager() {
394 if (socket_fd_ >= 0)
395 ::close(socket_fd_);
396 }
397
AcquireAndroidWakeLock(bool enable)398 int HWCQDCMModeManager::AcquireAndroidWakeLock(bool enable) {
399 int ret = 0;
400
401 if (enable) {
402 if (wakelock_token_ == NULL) {
403 android::sp<android::IBinder> binder = new android::BBinder();
404 android::status_t status = power_mgr_->acquireWakeLock(
405 (kFullWakeLock | kAcquireCauseWakeup | kONAfterRelease), binder,
406 android::String16(kTagName), android::String16(kPackageName));
407 if (status == android::NO_ERROR) {
408 wakelock_token_ = binder;
409 }
410 }
411 } else {
412 if (wakelock_token_ != NULL && power_mgr_ != NULL) {
413 power_mgr_->releaseWakeLock(wakelock_token_, 0);
414 wakelock_token_.clear();
415 wakelock_token_ = NULL;
416 }
417 }
418
419 return ret;
420 }
421
EnableActiveFeatures(bool enable,const HWCQDCMModeManager::ActiveFeatureCMD & cmds,bool * was_running)422 int HWCQDCMModeManager::EnableActiveFeatures(bool enable,
423 const HWCQDCMModeManager::ActiveFeatureCMD &cmds,
424 bool *was_running) {
425 int ret = 0;
426 ssize_t size = 0;
427 char response[kSocketCMDMaxLength] = {
428 0,
429 };
430
431 if (socket_fd_ < 0) {
432 DLOGW("No socket connection available!");
433 return -EFAULT;
434 }
435
436 if (!enable) { // if client requesting to disable it.
437 // query CABL status, if off, no action. keep the status.
438 size = ::write(socket_fd_, cmds.cmd_query_status, strlen(cmds.cmd_query_status));
439 if (size < 0) {
440 DLOGW("Unable to send data over socket %s", ::strerror(errno));
441 ret = -EFAULT;
442 } else {
443 size = ::read(socket_fd_, response, kSocketCMDMaxLength);
444 if (size < 0) {
445 DLOGW("Unable to read data over socket %s", ::strerror(errno));
446 ret = -EFAULT;
447 } else if (!strncmp(response, cmds.running, strlen(cmds.running))) {
448 *was_running = true;
449 }
450 }
451
452 if (*was_running) { // if was running, it's requested to disable it.
453 size = ::write(socket_fd_, cmds.cmd_off, strlen(cmds.cmd_off));
454 if (size < 0) {
455 DLOGW("Unable to send data over socket %s", ::strerror(errno));
456 ret = -EFAULT;
457 }
458 }
459 } else { // if was running, need enable it back.
460 if (*was_running) {
461 size = ::write(socket_fd_, cmds.cmd_on, strlen(cmds.cmd_on));
462 if (size < 0) {
463 DLOGW("Unable to send data over socket %s", ::strerror(errno));
464 ret = -EFAULT;
465 }
466 }
467 }
468
469 return ret;
470 }
471
EnableQDCMMode(bool enable,HWCDisplay * hwc_display)472 int HWCQDCMModeManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) {
473 int ret = 0;
474
475 ret = EnableActiveFeatures((enable ? false : true), kActiveFeatureCMD[kCABLFeature],
476 &cabl_was_running_);
477 ret = AcquireAndroidWakeLock(enable);
478
479 // if enter QDCM mode, disable GPU fallback idle timeout.
480 if (hwc_display) {
481 uint32_t timeout = enable ? 0 : entry_timeout_;
482 hwc_display->SetIdleTimeoutMs(timeout);
483 }
484
485 return ret;
486 }
487
488 } // namespace sdm
489