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 55 uint32_t HWCColorManager::Get8BitsARGBColorValue(const PPColorFillParams ¶ms) { 56 uint32_t argb_color = ((params.color.r << 16) & 0xff0000) | ((params.color.g << 8) & 0xff00) | 57 ((params.color.b) & 0xff); 58 return argb_color; 59 } 60 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 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 91 HWCColorManager *HWCColorManager::CreateColorManager(HWCBufferAllocator * buffer_allocator) { 92 HWCColorManager *color_mgr = new HWCColorManager(buffer_allocator); 93 94 if (color_mgr) { 95 // Load display API interface library. And retrieve color API function tables. 96 DynLib &color_apis_lib = color_mgr->color_apis_lib_; 97 if (color_apis_lib.Open(DISPLAY_API_INTERFACE_LIBRARY_NAME)) { 98 if (!color_apis_lib.Sym(DISPLAY_API_FUNC_TABLES, &color_mgr->color_apis_)) { 99 DLOGE("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES, 100 DISPLAY_API_INTERFACE_LIBRARY_NAME); 101 delete color_mgr; 102 return NULL; 103 } 104 } else { 105 DLOGW("Unable to load = %s", DISPLAY_API_INTERFACE_LIBRARY_NAME); 106 delete color_mgr; 107 return NULL; 108 } 109 DLOGI("Successfully loaded %s", DISPLAY_API_INTERFACE_LIBRARY_NAME); 110 111 // Load diagclient library and invokes its entry point to pass in display APIs. 112 DynLib &diag_client_lib = color_mgr->diag_client_lib_; 113 if (diag_client_lib.Open(QDCM_DIAG_CLIENT_LIBRARY_NAME)) { 114 if (!diag_client_lib.Sym(INIT_QDCM_DIAG_CLIENT_NAME, 115 reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) || 116 !diag_client_lib.Sym(DEINIT_QDCM_DIAG_CLIENT_NAME, 117 reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_))) { 118 DLOGE("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME, 119 QDCM_DIAG_CLIENT_LIBRARY_NAME); 120 } else { 121 // invoke Diag Client entry point to initialize. 122 color_mgr->qdcm_diag_init_(color_mgr->color_apis_); 123 DLOGI("Successfully loaded %s and %s and diag_init'ed", DISPLAY_API_INTERFACE_LIBRARY_NAME, 124 QDCM_DIAG_CLIENT_LIBRARY_NAME); 125 } 126 } else { 127 DLOGW("Unable to load = %s", QDCM_DIAG_CLIENT_LIBRARY_NAME); 128 // only QDCM Diag client failed to be loaded and system still should function. 129 } 130 } else { 131 DLOGE("Unable to create HWCColorManager"); 132 return NULL; 133 } 134 135 return color_mgr; 136 } 137 138 HWCColorManager::HWCColorManager(HWCBufferAllocator *buffer_allocator) : 139 buffer_allocator_(buffer_allocator) { 140 } 141 142 HWCColorManager::~HWCColorManager() { 143 } 144 145 void HWCColorManager::DestroyColorManager() { 146 if (qdcm_mode_mgr_) { 147 delete qdcm_mode_mgr_; 148 } 149 if (qdcm_diag_deinit_) { 150 qdcm_diag_deinit_(); 151 } 152 delete this; 153 } 154 155 int HWCColorManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) { 156 int ret = 0; 157 158 if (!qdcm_mode_mgr_) { 159 qdcm_mode_mgr_ = HWCQDCMModeManager::CreateQDCMModeMgr(); 160 if (!qdcm_mode_mgr_) { 161 DLOGE("Unable to create QDCM operating mode manager."); 162 ret = -EFAULT; 163 } 164 } 165 166 if (qdcm_mode_mgr_) { 167 ret = qdcm_mode_mgr_->EnableQDCMMode(enable, hwc_display); 168 } 169 170 return ret; 171 } 172 173 int HWCColorManager::SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display) { 174 SCOPE_LOCK(locker_); 175 176 if (params) { 177 solid_fill_params_ = *reinterpret_cast<const PPColorFillParams *>(params); 178 } else { 179 solid_fill_params_ = PPColorFillParams(); 180 } 181 182 uint32_t solid_fill_color = Get8BitsARGBColorValue(solid_fill_params_); 183 if (enable) { 184 LayerRect solid_fill_rect = { 185 FLOAT(solid_fill_params_.rect.x), FLOAT(solid_fill_params_.rect.y), 186 FLOAT(solid_fill_params_.rect.x) + FLOAT(solid_fill_params_.rect.width), 187 FLOAT(solid_fill_params_.rect.y) + FLOAT(solid_fill_params_.rect.height), 188 }; 189 190 hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_INFO, solid_fill_color); 191 hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_RECT, &solid_fill_rect); 192 } else { 193 hwc_display->Perform(HWCDisplayPrimary::UNSET_QDCM_SOLID_FILL_INFO, 0); 194 } 195 196 return 0; 197 } 198 199 int HWCColorManager::SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_display) { 200 SCOPE_LOCK(locker_); 201 int ret = 0; 202 203 PPFrameCaptureData *frame_capture_data = reinterpret_cast<PPFrameCaptureData *>(params); 204 205 if (enable) { 206 std::memset(&buffer_info, 0x00, sizeof(buffer_info)); 207 hwc_display->GetPanelResolution(&buffer_info.buffer_config.width, 208 &buffer_info.buffer_config.height); 209 if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_888) { 210 buffer_info.buffer_config.format = kFormatRGB888; 211 } else if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_2101010) { 212 buffer_info.buffer_config.format = kFormatRGBA1010102; 213 } else { 214 DLOGE("Pixel-format: %d NOT support.", frame_capture_data->input_params.out_pix_format); 215 return -EFAULT; 216 } 217 218 buffer_info.buffer_config.buffer_count = 1; 219 buffer_info.alloc_buffer_info.fd = -1; 220 buffer_info.alloc_buffer_info.stride = 0; 221 buffer_info.alloc_buffer_info.size = 0; 222 223 ret = buffer_allocator_->AllocateBuffer(&buffer_info); 224 if (ret != 0) { 225 DLOGE("Buffer allocation failed. ret: %d", ret); 226 return -ENOMEM; 227 } else { 228 void *buffer = mmap(NULL, buffer_info.alloc_buffer_info.size, PROT_READ | PROT_WRITE, 229 MAP_SHARED, buffer_info.alloc_buffer_info.fd, 0); 230 231 if (buffer == MAP_FAILED) { 232 DLOGE("mmap failed. err = %d", errno); 233 frame_capture_data->buffer = NULL; 234 ret = buffer_allocator_->FreeBuffer(&buffer_info); 235 return -EFAULT; 236 } else { 237 frame_capture_data->buffer = reinterpret_cast<uint8_t *>(buffer); 238 frame_capture_data->buffer_stride = buffer_info.buffer_config.width; 239 frame_capture_data->buffer_size = buffer_info.alloc_buffer_info.size; 240 } 241 ret = hwc_display->FrameCaptureAsync(buffer_info, 1); 242 if (ret < 0) { 243 DLOGE("FrameCaptureAsync failed. ret = %d", ret); 244 } 245 } 246 } else { 247 ret = hwc_display->GetFrameCaptureStatus(); 248 if (!ret) { 249 if (frame_capture_data->buffer != NULL) { 250 if (munmap(frame_capture_data->buffer, buffer_info.alloc_buffer_info.size) != 0) { 251 DLOGE("munmap failed. err = %d", errno); 252 } 253 } 254 if (buffer_allocator_ != NULL) { 255 std::memset(frame_capture_data, 0x00, sizeof(PPFrameCaptureData)); 256 ret = buffer_allocator_->FreeBuffer(&buffer_info); 257 if (ret != 0) { 258 DLOGE("FreeBuffer failed. ret = %d", ret); 259 } 260 } 261 } else { 262 DLOGE("GetFrameCaptureStatus failed. ret = %d", ret); 263 } 264 } 265 return ret; 266 } 267 268 int HWCColorManager::SetHWDetailedEnhancerConfig(void *params, HWCDisplay *hwc_display) { 269 int err = -1; 270 DisplayDetailEnhancerData de_data; 271 272 PPDETuningCfgData *de_tuning_cfg_data = reinterpret_cast<PPDETuningCfgData*>(params); 273 if (de_tuning_cfg_data->cfg_pending == true) { 274 if (!de_tuning_cfg_data->cfg_en) { 275 de_data.override_flags = kOverrideDEEnable; 276 de_data.enable = 0; 277 } else { 278 de_data.override_flags = kOverrideDEEnable; 279 de_data.enable = 1; 280 281 if (de_tuning_cfg_data->params.flags & kDeTuningFlagSharpFactor) { 282 de_data.override_flags |= kOverrideDESharpen1; 283 de_data.sharp_factor = de_tuning_cfg_data->params.sharp_factor; 284 } 285 286 if (de_tuning_cfg_data->params.flags & kDeTuningFlagClip) { 287 de_data.override_flags |= kOverrideDEClip; 288 de_data.clip = de_tuning_cfg_data->params.clip; 289 } 290 291 if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrQuiet) { 292 de_data.override_flags |= kOverrideDEThrQuiet; 293 de_data.thr_quiet = de_tuning_cfg_data->params.thr_quiet; 294 } 295 296 if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrDieout) { 297 de_data.override_flags |= kOverrideDEThrDieout; 298 de_data.thr_dieout = de_tuning_cfg_data->params.thr_dieout; 299 } 300 301 if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrLow) { 302 de_data.override_flags |= kOverrideDEThrLow; 303 de_data.thr_low = de_tuning_cfg_data->params.thr_low; 304 } 305 306 if (de_tuning_cfg_data->params.flags & kDeTuningFlagThrHigh) { 307 de_data.override_flags |= kOverrideDEThrHigh; 308 de_data.thr_high = de_tuning_cfg_data->params.thr_high; 309 } 310 311 if (de_tuning_cfg_data->params.flags & kDeTuningFlagContentQualLevel) { 312 switch (de_tuning_cfg_data->params.quality) { 313 case kDeContentQualLow: 314 de_data.quality_level = kContentQualityLow; 315 break; 316 case kDeContentQualMedium: 317 de_data.quality_level = kContentQualityMedium; 318 break; 319 case kDeContentQualHigh: 320 de_data.quality_level = kContentQualityHigh; 321 break; 322 case kDeContentQualUnknown: 323 default: 324 de_data.quality_level = kContentQualityUnknown; 325 break; 326 } 327 } 328 } 329 err = hwc_display->SetDetailEnhancerConfig(de_data); 330 if (err) { 331 DLOGW("SetDetailEnhancerConfig failed. err = %d", err); 332 } 333 de_tuning_cfg_data->cfg_pending = false; 334 } 335 return err; 336 } 337 338 void HWCColorManager::SetColorModeDetailEnhancer(HWCDisplay *hwc_display) { 339 SCOPE_LOCK(locker_); 340 int err = -1; 341 PPPendingParams pending_action; 342 PPDisplayAPIPayload req_payload; 343 344 pending_action.action = kGetDetailedEnhancerData; 345 pending_action.params = NULL; 346 347 if (hwc_display) { 348 err = hwc_display->ColorSVCRequestRoute(req_payload, NULL, &pending_action); 349 if (!err && pending_action.action == kConfigureDetailedEnhancer) { 350 err = SetHWDetailedEnhancerConfig(pending_action.params, hwc_display); 351 } 352 } 353 return; 354 } 355 356 int HWCColorManager::SetDetailedEnhancer(void *params, HWCDisplay *hwc_display) { 357 SCOPE_LOCK(locker_); 358 int err = -1; 359 err = SetHWDetailedEnhancerConfig(params, hwc_display); 360 return err; 361 } 362 363 const HWCQDCMModeManager::ActiveFeatureCMD HWCQDCMModeManager::kActiveFeatureCMD[] = { 364 HWCQDCMModeManager::ActiveFeatureCMD("cabl:on", "cabl:off", "cabl:status", "running"), 365 HWCQDCMModeManager::ActiveFeatureCMD("ad:on", "ad:off", "ad:query:status", "running"), 366 HWCQDCMModeManager::ActiveFeatureCMD("svi:on", "svi:off", "svi:status", "running"), 367 }; 368 369 const char *const HWCQDCMModeManager::kSocketName = "pps"; 370 const char *const HWCQDCMModeManager::kTagName = "surfaceflinger"; 371 const char *const HWCQDCMModeManager::kPackageName = "colormanager"; 372 373 HWCQDCMModeManager *HWCQDCMModeManager::CreateQDCMModeMgr() { 374 HWCQDCMModeManager *mode_mgr = new HWCQDCMModeManager(); 375 376 if (!mode_mgr) { 377 DLOGW("No memory to create HWCQDCMModeManager."); 378 return NULL; 379 } else { 380 mode_mgr->socket_fd_ = 381 ::socket_local_client(kSocketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); 382 if (mode_mgr->socket_fd_ < 0) { 383 // it should not be disastrous and we still can grab wakelock in QDCM mode. 384 DLOGW("Unable to connect to dpps socket!"); 385 } 386 387 // retrieve system GPU idle timeout value for later to recover. 388 mode_mgr->entry_timeout_ = UINT32(HWCDebugHandler::GetIdleTimeoutMs()); 389 390 // acquire the binder handle to Android system PowerManager for later use. 391 android::sp<android::IBinder> binder = 392 android::defaultServiceManager()->checkService(android::String16("power")); 393 if (binder == NULL) { 394 DLOGW("Application can't connect to power manager service"); 395 delete mode_mgr; 396 mode_mgr = NULL; 397 } else { 398 mode_mgr->power_mgr_ = android::interface_cast<android::IPowerManager>(binder); 399 } 400 } 401 402 return mode_mgr; 403 } 404 405 HWCQDCMModeManager::~HWCQDCMModeManager() { 406 if (socket_fd_ >= 0) 407 ::close(socket_fd_); 408 } 409 410 int HWCQDCMModeManager::AcquireAndroidWakeLock(bool enable) { 411 int ret = 0; 412 413 if (enable) { 414 if (wakelock_token_ == NULL) { 415 android::sp<android::IBinder> binder = new android::BBinder(); 416 android::status_t status = power_mgr_->acquireWakeLock( 417 (kFullWakeLock | kAcquireCauseWakeup | kONAfterRelease), binder, 418 android::String16(kTagName), android::String16(kPackageName)); 419 if (status == android::NO_ERROR) { 420 wakelock_token_ = binder; 421 } 422 } 423 } else { 424 if (wakelock_token_ != NULL && power_mgr_ != NULL) { 425 power_mgr_->releaseWakeLock(wakelock_token_, 0); 426 wakelock_token_.clear(); 427 wakelock_token_ = NULL; 428 } 429 } 430 431 return ret; 432 } 433 434 int HWCQDCMModeManager::EnableActiveFeatures(bool enable, 435 const HWCQDCMModeManager::ActiveFeatureCMD &cmds, 436 bool *was_running) { 437 int ret = 0; 438 ssize_t size = 0; 439 char response[kSocketCMDMaxLength] = { 440 0, 441 }; 442 443 if (socket_fd_ < 0) { 444 DLOGW("No socket connection available!"); 445 return -EFAULT; 446 } 447 448 if (!enable) { // if client requesting to disable it. 449 // query CABL status, if off, no action. keep the status. 450 size = ::write(socket_fd_, cmds.cmd_query_status, strlen(cmds.cmd_query_status)); 451 if (size < 0) { 452 DLOGW("Unable to send data over socket %s", ::strerror(errno)); 453 ret = -EFAULT; 454 } else { 455 size = ::read(socket_fd_, response, kSocketCMDMaxLength); 456 if (size < 0) { 457 DLOGW("Unable to read data over socket %s", ::strerror(errno)); 458 ret = -EFAULT; 459 } else if (!strncmp(response, cmds.running, strlen(cmds.running))) { 460 *was_running = true; 461 } 462 } 463 464 if (*was_running) { // if was running, it's requested to disable it. 465 size = ::write(socket_fd_, cmds.cmd_off, strlen(cmds.cmd_off)); 466 if (size < 0) { 467 DLOGW("Unable to send data over socket %s", ::strerror(errno)); 468 ret = -EFAULT; 469 } 470 } 471 } else { // if was running, need enable it back. 472 if (*was_running) { 473 size = ::write(socket_fd_, cmds.cmd_on, strlen(cmds.cmd_on)); 474 if (size < 0) { 475 DLOGW("Unable to send data over socket %s", ::strerror(errno)); 476 ret = -EFAULT; 477 } 478 } 479 } 480 481 return ret; 482 } 483 484 int HWCQDCMModeManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) { 485 int ret = 0; 486 487 ret = EnableActiveFeatures((enable ? false : true), kActiveFeatureCMD[kCABLFeature], 488 &cabl_was_running_); 489 ret = AcquireAndroidWakeLock(enable); 490 491 // if enter QDCM mode, disable GPU fallback idle timeout. 492 if (hwc_display) { 493 uint32_t timeout = enable ? 0 : entry_timeout_; 494 hwc_display->SetIdleTimeoutMs(timeout); 495 } 496 497 return ret; 498 } 499 500 } // namespace sdm 501