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 <cutils/sockets.h> 32 #include <cutils/native_handle.h> 33 #include <utils/String16.h> 34 #include <binder/Parcel.h> 35 #include <gralloc_priv.h> 36 #include <hardware/hwcomposer.h> 37 #include <hardware/hwcomposer_defs.h> 38 #include <QService.h> 39 40 #include <core/dump_interface.h> 41 #include <utils/constants.h> 42 #include <utils/debug.h> 43 #include <core/buffer_allocator.h> 44 #include <private/color_params.h> 45 #include "hwc_buffer_allocator.h" 46 #include "hwc_buffer_sync_handler.h" 47 #include "hwc_session.h" 48 #include "hwc_debugger.h" 49 50 #define __CLASS__ "HWCColorManager" 51 52 namespace sdm { 53 54 uint32_t HWCColorManager::Get8BitsARGBColorValue(const PPColorFillParams ¶ms) { 55 uint32_t argb_color = ((params.color.r << 16) & 0xff0000) | ((params.color.g << 8) & 0xff00) | 56 ((params.color.b) & 0xff); 57 return argb_color; 58 } 59 60 int HWCColorManager::CreatePayloadFromParcel(const android::Parcel &in, uint32_t *disp_id, 61 PPDisplayAPIPayload *sink) { 62 int ret = 0; 63 uint32_t id(0); 64 uint32_t size(0); 65 66 id = UINT32(in.readInt32()); 67 size = UINT32(in.readInt32()); 68 if (size > 0 && size == in.dataAvail()) { 69 const void *data = in.readInplace(size); 70 const uint8_t *temp = reinterpret_cast<const uint8_t *>(data); 71 72 sink->size = size; 73 sink->payload = const_cast<uint8_t *>(temp); 74 *disp_id = id; 75 } else { 76 DLOGW("Failing size checking, size = %d", size); 77 ret = -EINVAL; 78 } 79 80 return ret; 81 } 82 83 void HWCColorManager::MarshallStructIntoParcel(const PPDisplayAPIPayload &data, 84 android::Parcel *out_parcel) { 85 out_parcel->writeInt32(INT32(data.size)); 86 if (data.payload) 87 out_parcel->write(data.payload, data.size); 88 } 89 90 HWCColorManager *HWCColorManager::CreateColorManager(HWCBufferAllocator * buffer_allocator) { 91 HWCColorManager *color_mgr = new HWCColorManager(buffer_allocator); 92 93 if (color_mgr) { 94 // Load display API interface library. And retrieve color API function tables. 95 DynLib &color_apis_lib = color_mgr->color_apis_lib_; 96 if (color_apis_lib.Open(DISPLAY_API_INTERFACE_LIBRARY_NAME)) { 97 if (!color_apis_lib.Sym(DISPLAY_API_FUNC_TABLES, &color_mgr->color_apis_)) { 98 DLOGE("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES, 99 DISPLAY_API_INTERFACE_LIBRARY_NAME); 100 delete color_mgr; 101 return NULL; 102 } 103 } else { 104 DLOGW("Unable to load = %s", DISPLAY_API_INTERFACE_LIBRARY_NAME); 105 delete color_mgr; 106 return NULL; 107 } 108 DLOGI("Successfully loaded %s", DISPLAY_API_INTERFACE_LIBRARY_NAME); 109 110 // Load diagclient library and invokes its entry point to pass in display APIs. 111 DynLib &diag_client_lib = color_mgr->diag_client_lib_; 112 if (diag_client_lib.Open(QDCM_DIAG_CLIENT_LIBRARY_NAME)) { 113 if (!diag_client_lib.Sym(INIT_QDCM_DIAG_CLIENT_NAME, 114 reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) || 115 !diag_client_lib.Sym(DEINIT_QDCM_DIAG_CLIENT_NAME, 116 reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_))) { 117 DLOGE("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME, 118 QDCM_DIAG_CLIENT_LIBRARY_NAME); 119 } else { 120 // invoke Diag Client entry point to initialize. 121 color_mgr->qdcm_diag_init_(color_mgr->color_apis_); 122 DLOGI("Successfully loaded %s and %s and diag_init'ed", DISPLAY_API_INTERFACE_LIBRARY_NAME, 123 QDCM_DIAG_CLIENT_LIBRARY_NAME); 124 } 125 } else { 126 DLOGW("Unable to load = %s", QDCM_DIAG_CLIENT_LIBRARY_NAME); 127 // only QDCM Diag client failed to be loaded and system still should function. 128 } 129 } else { 130 DLOGE("Unable to create HWCColorManager"); 131 return NULL; 132 } 133 134 return color_mgr; 135 } 136 137 HWCColorManager::HWCColorManager(HWCBufferAllocator *buffer_allocator) : 138 buffer_allocator_(buffer_allocator) { 139 } 140 141 HWCColorManager::~HWCColorManager() { 142 } 143 144 void HWCColorManager::DestroyColorManager() { 145 if (qdcm_mode_mgr_) { 146 delete qdcm_mode_mgr_; 147 } 148 if (qdcm_diag_deinit_) { 149 qdcm_diag_deinit_(); 150 } 151 delete this; 152 } 153 154 int HWCColorManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) { 155 int ret = 0; 156 157 if (!qdcm_mode_mgr_) { 158 qdcm_mode_mgr_ = HWCQDCMModeManager::CreateQDCMModeMgr(); 159 if (!qdcm_mode_mgr_) { 160 DLOGE("Unable to create QDCM operating mode manager."); 161 ret = -EFAULT; 162 } 163 } 164 165 if (qdcm_mode_mgr_) { 166 ret = qdcm_mode_mgr_->EnableQDCMMode(enable, hwc_display); 167 } 168 169 return ret; 170 } 171 172 int HWCColorManager::SetSolidFill(const void *params, bool enable, HWCDisplay *hwc_display) { 173 SCOPE_LOCK(locker_); 174 175 if (params) { 176 solid_fill_params_ = *reinterpret_cast<const PPColorFillParams *>(params); 177 } else { 178 solid_fill_params_ = PPColorFillParams(); 179 } 180 181 uint32_t solid_fill_color = Get8BitsARGBColorValue(solid_fill_params_); 182 if (enable) { 183 LayerRect solid_fill_rect = { 184 FLOAT(solid_fill_params_.rect.x), FLOAT(solid_fill_params_.rect.y), 185 FLOAT(solid_fill_params_.rect.x) + FLOAT(solid_fill_params_.rect.width), 186 FLOAT(solid_fill_params_.rect.y) + FLOAT(solid_fill_params_.rect.height), 187 }; 188 189 hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_INFO, solid_fill_color); 190 hwc_display->Perform(HWCDisplayPrimary::SET_QDCM_SOLID_FILL_RECT, &solid_fill_rect); 191 } else { 192 hwc_display->Perform(HWCDisplayPrimary::UNSET_QDCM_SOLID_FILL_INFO, 0); 193 } 194 195 return 0; 196 } 197 198 int HWCColorManager::SetFrameCapture(void *params, bool enable, HWCDisplay *hwc_display) { 199 SCOPE_LOCK(locker_); 200 int ret = 0; 201 202 PPFrameCaptureData *frame_capture_data = reinterpret_cast<PPFrameCaptureData *>(params); 203 204 if (enable) { 205 std::memset(&buffer_info, 0x00, sizeof(buffer_info)); 206 hwc_display->GetFrameBufferResolution(&buffer_info.buffer_config.width, 207 &buffer_info.buffer_config.height); 208 if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_888) { 209 buffer_info.buffer_config.format = kFormatRGB888; 210 } else if (frame_capture_data->input_params.out_pix_format == PP_PIXEL_FORMAT_RGB_2101010) { 211 // TODO(user): Complete the implementation 212 DLOGE("RGB 10-bit format NOT supported"); 213 return -EFAULT; 214 } else { 215 DLOGE("Pixel-format: %d NOT support.", frame_capture_data->input_params.out_pix_format); 216 return -EFAULT; 217 } 218 219 buffer_info.buffer_config.buffer_count = 1; 220 buffer_info.alloc_buffer_info.fd = -1; 221 buffer_info.alloc_buffer_info.stride = 0; 222 buffer_info.alloc_buffer_info.size = 0; 223 224 ret = buffer_allocator_->AllocateBuffer(&buffer_info); 225 if (ret != 0) { 226 DLOGE("Buffer allocation failed. ret: %d", ret); 227 return -ENOMEM; 228 } else { 229 void *buffer = mmap(NULL, buffer_info.alloc_buffer_info.size, PROT_READ | PROT_WRITE, 230 MAP_SHARED, buffer_info.alloc_buffer_info.fd, 0); 231 232 if (buffer == MAP_FAILED) { 233 DLOGE("mmap failed. err = %d", errno); 234 frame_capture_data->buffer = NULL; 235 ret = buffer_allocator_->FreeBuffer(&buffer_info); 236 return -EFAULT; 237 } else { 238 frame_capture_data->buffer = reinterpret_cast<uint8_t *>(buffer); 239 frame_capture_data->buffer_stride = buffer_info.alloc_buffer_info.stride; 240 frame_capture_data->buffer_size = buffer_info.alloc_buffer_info.size; 241 } 242 // TODO(user): Call HWC interface to provide the buffer and rectangle information 243 } 244 } else { 245 if (frame_capture_data->buffer != NULL) { 246 if (munmap(frame_capture_data->buffer, buffer_info.alloc_buffer_info.size) != 0) { 247 DLOGE("munmap failed. err = %d", errno); 248 } 249 } 250 if (buffer_allocator_ != NULL) { 251 std::memset(frame_capture_data, 0x00, sizeof(PPFrameCaptureData)); 252 ret = buffer_allocator_->FreeBuffer(&buffer_info); 253 if (ret != 0) { 254 DLOGE("FreeBuffer failed. ret = %d", ret); 255 } 256 } 257 } 258 return ret; 259 } 260 261 const HWCQDCMModeManager::ActiveFeatureCMD HWCQDCMModeManager::kActiveFeatureCMD[] = { 262 HWCQDCMModeManager::ActiveFeatureCMD("cabl:on", "cabl:off", "cabl:status", "running"), 263 HWCQDCMModeManager::ActiveFeatureCMD("ad:on", "ad:off", "ad:query:status", "running"), 264 HWCQDCMModeManager::ActiveFeatureCMD("svi:on", "svi:off", "svi:status", "running"), 265 }; 266 267 const char *const HWCQDCMModeManager::kSocketName = "pps"; 268 const char *const HWCQDCMModeManager::kTagName = "surfaceflinger"; 269 const char *const HWCQDCMModeManager::kPackageName = "colormanager"; 270 271 HWCQDCMModeManager *HWCQDCMModeManager::CreateQDCMModeMgr() { 272 HWCQDCMModeManager *mode_mgr = new HWCQDCMModeManager(); 273 274 if (!mode_mgr) { 275 DLOGW("No memory to create HWCQDCMModeManager."); 276 return NULL; 277 } else { 278 mode_mgr->socket_fd_ = 279 ::socket_local_client(kSocketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); 280 if (mode_mgr->socket_fd_ < 0) { 281 // it should not be disastrous and we still can grab wakelock in QDCM mode. 282 DLOGW("Unable to connect to dpps socket!"); 283 } 284 285 // retrieve system GPU idle timeout value for later to recover. 286 mode_mgr->entry_timeout_ = UINT32(HWCDebugHandler::GetIdleTimeoutMs()); 287 } 288 289 return mode_mgr; 290 } 291 292 HWCQDCMModeManager::~HWCQDCMModeManager() { 293 if (socket_fd_ >= 0) 294 ::close(socket_fd_); 295 } 296 297 int HWCQDCMModeManager::EnableActiveFeatures(bool enable, 298 const HWCQDCMModeManager::ActiveFeatureCMD &cmds, 299 bool *was_running) { 300 int ret = 0; 301 ssize_t size = 0; 302 char response[kSocketCMDMaxLength] = { 303 0, 304 }; 305 306 if (socket_fd_ < 0) { 307 DLOGW("No socket connection available!"); 308 return -EFAULT; 309 } 310 311 if (!enable) { // if client requesting to disable it. 312 // query CABL status, if off, no action. keep the status. 313 size = ::write(socket_fd_, cmds.cmd_query_status, strlen(cmds.cmd_query_status)); 314 if (size < 0) { 315 DLOGW("Unable to send data over socket %s", ::strerror(errno)); 316 ret = -EFAULT; 317 } else { 318 size = ::read(socket_fd_, response, kSocketCMDMaxLength); 319 if (size < 0) { 320 DLOGW("Unable to read data over socket %s", ::strerror(errno)); 321 ret = -EFAULT; 322 } else if (!strncmp(response, cmds.running, strlen(cmds.running))) { 323 *was_running = true; 324 } 325 } 326 327 if (*was_running) { // if was running, it's requested to disable it. 328 size = ::write(socket_fd_, cmds.cmd_off, strlen(cmds.cmd_off)); 329 if (size < 0) { 330 DLOGW("Unable to send data over socket %s", ::strerror(errno)); 331 ret = -EFAULT; 332 } 333 } 334 } else { // if was running, need enable it back. 335 if (*was_running) { 336 size = ::write(socket_fd_, cmds.cmd_on, strlen(cmds.cmd_on)); 337 if (size < 0) { 338 DLOGW("Unable to send data over socket %s", ::strerror(errno)); 339 ret = -EFAULT; 340 } 341 } 342 } 343 344 return ret; 345 } 346 347 int HWCQDCMModeManager::EnableQDCMMode(bool enable, HWCDisplay *hwc_display) { 348 int ret = 0; 349 350 ret = EnableActiveFeatures((enable ? false : true), kActiveFeatureCMD[kCABLFeature], 351 &cabl_was_running_); 352 353 // if enter QDCM mode, disable GPU fallback idle timeout. 354 if (hwc_display) { 355 uint32_t timeout = enable ? 0 : entry_timeout_; 356 hwc_display->SetIdleTimeoutMs(timeout); 357 } 358 359 return ret; 360 } 361 362 } // namespace sdm 363