1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // Versions of hwcomposer we implement: 18 // JB: 0.3 19 // JB-MR1 to N : 1.1 20 // N-MR1 to ... : We report 1.1 but SurfaceFlinger has the option to use an 21 // adapter to treat our 1.1 hwcomposer as a 2.0. If SF stops using that adapter 22 // to support 1.1 implementations it can be copied into cuttlefish from 23 // frameworks/native/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.* 24 25 #define LOG_TAG "hwc.cf_x86" 26 27 #include <guest/libs/platform_support/api_level_fixes.h> 28 29 #include <errno.h> 30 #include <fcntl.h> 31 #include <math.h> 32 #include <poll.h> 33 #include <pthread.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 37 #include <sys/ioctl.h> 38 #include <sys/mman.h> 39 #include <sys/resource.h> 40 #include <sys/time.h> 41 42 #include <string> 43 44 #define HWC_REMOVE_DEPRECATED_VERSIONS 1 45 46 #include <cutils/compiler.h> 47 #include <log/log.h> 48 #include <cutils/properties.h> 49 #include <hardware/gralloc.h> 50 #include <hardware/hardware.h> 51 #include <hardware/hwcomposer.h> 52 #include <hardware/hwcomposer_defs.h> 53 #include <utils/String8.h> 54 #include <utils/Vector.h> 55 56 #include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h" 57 #include "guest/hals/hwcomposer/common/hwcomposer.h" 58 #include <sync/sync.h> 59 60 #include "base_composer.h" 61 #include "geometry_utils.h" 62 #include "hwcomposer.h" 63 #include "vsoc_composer.h" 64 65 #ifdef USE_OLD_HWCOMPOSER 66 typedef cvd::BaseComposer InnerComposerType; 67 #else 68 typedef cvd::VSoCComposer InnerComposerType; 69 #endif 70 71 typedef InnerComposerType ComposerType; 72 73 struct vsoc_hwc_composer_device_1_t { 74 vsoc_hwc_device base; 75 cvd::hwc_composer_device_data_t vsync_data; 76 ComposerType* composer; 77 }; 78 79 namespace { 80 81 std::string CompositionString(int type) { 82 switch (type) { 83 case HWC_FRAMEBUFFER: 84 return "Framebuffer"; 85 case HWC_OVERLAY: 86 return "Overlay"; 87 case HWC_BACKGROUND: 88 return "Background"; 89 case HWC_FRAMEBUFFER_TARGET: 90 return "FramebufferTarget"; 91 #if VSOC_PLATFORM_SDK_AFTER(K) 92 case HWC_SIDEBAND: 93 return "Sideband"; 94 case HWC_CURSOR_OVERLAY: 95 return "CursorOverlay"; 96 #endif 97 default: 98 return std::string("Unknown (") + std::to_string(type) + ")"; 99 } 100 } 101 102 void LogLayers(int num_layers, vsoc_hwc_layer* layers, int invalid) { 103 ALOGE("Layers:"); 104 for (int idx = 0; idx < num_layers; ++idx) { 105 std::string log_line; 106 if (idx == invalid) { 107 log_line = "Invalid layer: "; 108 } 109 log_line += 110 "Composition Type: " + CompositionString(layers[idx].compositionType); 111 ALOGE("%s", log_line.c_str()); 112 } 113 } 114 115 // Ensures that the layer does not include any inconsistencies 116 bool IsValidLayer(const vsoc_hwc_layer& layer) { 117 if (layer.flags & HWC_SKIP_LAYER) { 118 // A layer we are asked to skip validate should not be marked as skip 119 ALOGE("%s: Layer is marked as skip", __FUNCTION__); 120 return false; 121 } 122 // Check displayFrame 123 if (layer.displayFrame.left > layer.displayFrame.right || 124 layer.displayFrame.top > layer.displayFrame.bottom) { 125 ALOGE( 126 "%s: Malformed rectangle (displayFrame): [left = %d, right = %d, top = " 127 "%d, bottom = %d]", 128 __FUNCTION__, layer.displayFrame.left, layer.displayFrame.right, 129 layer.displayFrame.top, layer.displayFrame.bottom); 130 return false; 131 } 132 // Validate the handle 133 if (private_handle_t::validate(layer.handle) != 0) { 134 ALOGE("%s: Layer contains an invalid gralloc handle.", __FUNCTION__); 135 return false; 136 } 137 const private_handle_t* p_handle = 138 reinterpret_cast<const private_handle_t*>(layer.handle); 139 // Check sourceCrop 140 if (layer.sourceCrop.left > layer.sourceCrop.right || 141 layer.sourceCrop.top > layer.sourceCrop.bottom) { 142 ALOGE( 143 "%s: Malformed rectangle (sourceCrop): [left = %d, right = %d, top = " 144 "%d, bottom = %d]", 145 __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right, 146 layer.sourceCrop.top, layer.sourceCrop.bottom); 147 return false; 148 } 149 if (layer.sourceCrop.left < 0 || layer.sourceCrop.top < 0 || 150 layer.sourceCrop.right > p_handle->x_res || 151 layer.sourceCrop.bottom > p_handle->y_res) { 152 ALOGE( 153 "%s: Invalid sourceCrop for buffer handle: sourceCrop = [left = %d, " 154 "right = %d, top = %d, bottom = %d], handle = [width = %d, height = " 155 "%d]", 156 __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right, 157 layer.sourceCrop.top, layer.sourceCrop.bottom, p_handle->x_res, 158 p_handle->y_res); 159 return false; 160 } 161 return true; 162 } 163 164 bool IsValidComposition(int num_layers, vsoc_hwc_layer* layers, bool on_set) { 165 if (num_layers == 0) { 166 ALOGE("Composition requested with 0 layers"); 167 return false; 168 } 169 // Sometimes the hwcomposer receives a prepare and set calls with no other 170 // layer than the FRAMEBUFFER_TARGET with a null handler. We treat this case 171 // independently as a valid composition, but issue a warning about it. 172 if (num_layers == 1 && layers[0].compositionType == HWC_FRAMEBUFFER_TARGET && 173 layers[0].handle == NULL) { 174 ALOGW("Received request for empty composition, treating as valid noop"); 175 return true; 176 } 177 // The FRAMEBUFFER_TARGET layer needs to be sane only if 178 // there is at least one layer marked HWC_FRAMEBUFFER or if there is no layer 179 // marked HWC_OVERLAY (i.e some layers where composed with OpenGL, no layer 180 // marked overlay or framebuffer means that surfaceflinger decided to go for 181 // OpenGL without asking the hwcomposer first) 182 bool check_fb_target = true; 183 for (int idx = 0; idx < num_layers; ++idx) { 184 if (layers[idx].compositionType == HWC_FRAMEBUFFER) { 185 // There is at least one, so it needs to be checked. 186 // It may have been set to false before, so ensure it's set to true. 187 check_fb_target = true; 188 break; 189 } 190 if (layers[idx].compositionType == HWC_OVERLAY) { 191 // At least one overlay, we may not need to. 192 check_fb_target = false; 193 } 194 } 195 196 for (int idx = 0; idx < num_layers; ++idx) { 197 switch (layers[idx].compositionType) { 198 case HWC_FRAMEBUFFER_TARGET: 199 // In the call to prepare() the framebuffer target does not have a valid 200 // buffer_handle, so we don't validate it yet. 201 if (on_set && check_fb_target && !IsValidLayer(layers[idx])) { 202 ALOGE("%s: Invalid layer found", __FUNCTION__); 203 LogLayers(num_layers, layers, idx); 204 return false; 205 } 206 break; 207 case HWC_OVERLAY: 208 if (!(layers[idx].flags & HWC_SKIP_LAYER) && 209 !IsValidLayer(layers[idx])) { 210 ALOGE("%s: Invalid layer found", __FUNCTION__); 211 LogLayers(num_layers, layers, idx); 212 return false; 213 } 214 break; 215 } 216 } 217 return true; 218 } 219 220 } 221 222 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1) 223 static int vsoc_hwc_prepare(vsoc_hwc_device* dev, hwc_layer_list_t* list) { 224 #else 225 static int vsoc_hwc_prepare(vsoc_hwc_device* dev, size_t numDisplays, 226 hwc_display_contents_1_t** displays) { 227 if (!numDisplays || !displays) return 0; 228 229 hwc_display_contents_1_t* list = displays[HWC_DISPLAY_PRIMARY]; 230 231 if (!list) return 0; 232 #endif 233 if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], false)) { 234 LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__); 235 return -1; 236 } 237 reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->PrepareLayers( 238 list->numHwLayers, &list->hwLayers[0]); 239 return 0; 240 } 241 242 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1) 243 int vsoc_hwc_set(struct hwc_composer_device* dev, hwc_display_t dpy, 244 hwc_surface_t sur, hwc_layer_list_t* list) { 245 if (list->numHwLayers == 1 && 246 layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) { 247 ALOGW("Received request for empty composition, treating as valid noop"); 248 return 0; 249 } 250 if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], true)) { 251 LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__); 252 return -1; 253 } 254 return reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev) 255 ->composer->SetLayers(list->numHwLayers, &list->hwLayers[0]); 256 } 257 #else 258 static int vsoc_hwc_set(vsoc_hwc_device* dev, size_t numDisplays, 259 hwc_display_contents_1_t** displays) { 260 if (!numDisplays || !displays) return 0; 261 262 hwc_display_contents_1_t* contents = displays[HWC_DISPLAY_PRIMARY]; 263 if (!contents) return 0; 264 265 vsoc_hwc_layer* layers = &contents->hwLayers[0]; 266 if (contents->numHwLayers == 1 && 267 layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) { 268 ALOGW("Received request for empty composition, treating as valid noop"); 269 return 0; 270 } 271 if (!IsValidComposition(contents->numHwLayers, layers, true)) { 272 LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__); 273 return -1; 274 } 275 int retval = 276 reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->SetLayers( 277 contents->numHwLayers, layers); 278 279 int closedFds = 0; 280 for (size_t index = 0; index < contents->numHwLayers; ++index) { 281 if (layers[index].acquireFenceFd != -1) { 282 close(layers[index].acquireFenceFd); 283 layers[index].acquireFenceFd = -1; 284 ++closedFds; 285 } 286 } 287 if (closedFds) { 288 ALOGI("Saw %zu layers, closed=%d", contents->numHwLayers, closedFds); 289 } 290 291 // TODO(ghartman): This should be set before returning. On the next set it 292 // should be signalled when we load the new frame. 293 contents->retireFenceFd = -1; 294 return retval; 295 } 296 #endif 297 298 static void vsoc_hwc_register_procs(vsoc_hwc_device* dev, 299 const hwc_procs_t* procs) { 300 struct vsoc_hwc_composer_device_1_t* pdev = 301 (struct vsoc_hwc_composer_device_1_t*)dev; 302 pdev->vsync_data.procs = procs; 303 } 304 305 static int vsoc_hwc_query(vsoc_hwc_device* dev, int what, int* value) { 306 struct vsoc_hwc_composer_device_1_t* pdev = 307 (struct vsoc_hwc_composer_device_1_t*)dev; 308 309 switch (what) { 310 case HWC_BACKGROUND_LAYER_SUPPORTED: 311 // we support the background layer 312 value[0] = 0; 313 break; 314 case HWC_VSYNC_PERIOD: 315 value[0] = pdev->vsync_data.vsync_period_ns; 316 break; 317 default: 318 // unsupported query 319 ALOGE("%s badness unsupported query what=%d", __FUNCTION__, what); 320 return -EINVAL; 321 } 322 return 0; 323 } 324 325 static int vsoc_hwc_event_control( 326 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1) 327 vsoc_hwc_device* /*dev*/, int event, int /*enabled*/) { 328 #else 329 vsoc_hwc_device* /*dev*/, int /*dpy*/, int event, int /*enabled*/) { 330 #endif 331 332 if (event == HWC_EVENT_VSYNC) { 333 return 0; 334 } 335 return -EINVAL; 336 } 337 338 static int vsoc_hwc_blank(vsoc_hwc_device* /*dev*/, int disp, int /*blank*/) { 339 if (!IS_PRIMARY_DISPLAY(disp)) return -EINVAL; 340 return 0; 341 } 342 343 static void vsoc_hwc_dump(vsoc_hwc_device* dev, char* buff, int buff_len) { 344 reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->Dump( 345 buff, buff_len); 346 } 347 348 static int vsoc_hwc_get_display_configs(vsoc_hwc_device* /*dev*/, int disp, 349 uint32_t* configs, size_t* numConfigs) { 350 if (*numConfigs == 0) return 0; 351 352 if (IS_PRIMARY_DISPLAY(disp)) { 353 configs[0] = 0; 354 *numConfigs = 1; 355 return 0; 356 } 357 358 return -EINVAL; 359 } 360 361 #if VSOC_PLATFORM_SDK_AFTER(J) 362 static int32_t vsoc_hwc_attribute(struct vsoc_hwc_composer_device_1_t* pdev, 363 const uint32_t attribute) { 364 switch (attribute) { 365 case HWC_DISPLAY_VSYNC_PERIOD: 366 return pdev->vsync_data.vsync_period_ns; 367 case HWC_DISPLAY_WIDTH: 368 return pdev->composer->x_res(); 369 case HWC_DISPLAY_HEIGHT: 370 return pdev->composer->y_res(); 371 case HWC_DISPLAY_DPI_X: 372 ALOGI("Reporting DPI_X of %d", pdev->composer->dpi()); 373 // The number of pixels per thousand inches 374 return pdev->composer->dpi() * 1000; 375 case HWC_DISPLAY_DPI_Y: 376 ALOGI("Reporting DPI_Y of %d", pdev->composer->dpi()); 377 // The number of pixels per thousand inches 378 return pdev->composer->dpi() * 1000; 379 default: 380 ALOGE("unknown display attribute %u", attribute); 381 return -EINVAL; 382 } 383 } 384 385 static int vsoc_hwc_get_display_attributes(vsoc_hwc_device* dev, int disp, 386 uint32_t config __unused, 387 const uint32_t* attributes, 388 int32_t* values) { 389 struct vsoc_hwc_composer_device_1_t* pdev = 390 (struct vsoc_hwc_composer_device_1_t*)dev; 391 392 if (!IS_PRIMARY_DISPLAY(disp)) { 393 ALOGE("unknown display type %u", disp); 394 return -EINVAL; 395 } 396 397 for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) { 398 values[i] = vsoc_hwc_attribute(pdev, attributes[i]); 399 } 400 401 return 0; 402 } 403 #endif 404 405 static int vsoc_hwc_close(hw_device_t* device) { 406 struct vsoc_hwc_composer_device_1_t* dev = 407 (struct vsoc_hwc_composer_device_1_t*)device; 408 ALOGE("vsoc_hwc_close"); 409 pthread_kill(dev->vsync_data.vsync_thread, SIGTERM); 410 pthread_join(dev->vsync_data.vsync_thread, NULL); 411 delete dev->composer; 412 delete dev; 413 return 0; 414 } 415 416 static int vsoc_hwc_open(const struct hw_module_t* module, const char* name, 417 struct hw_device_t** device) { 418 ALOGI("%s", __FUNCTION__); 419 if (strcmp(name, HWC_HARDWARE_COMPOSER)) { 420 ALOGE("%s called with bad name %s", __FUNCTION__, name); 421 return -EINVAL; 422 } 423 424 vsoc_hwc_composer_device_1_t* dev = new vsoc_hwc_composer_device_1_t(); 425 if (!dev) { 426 ALOGE("%s failed to allocate dev", __FUNCTION__); 427 return -ENOMEM; 428 } 429 430 struct timespec rt; 431 if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) { 432 ALOGE("%s:%d error in vsync thread clock_gettime: %s", __FILE__, __LINE__, 433 strerror(errno)); 434 } 435 dev->vsync_data.vsync_base_timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec; 436 437 dev->base.common.tag = HARDWARE_DEVICE_TAG; 438 dev->base.common.version = VSOC_HWC_DEVICE_API_VERSION; 439 dev->base.common.module = const_cast<hw_module_t*>(module); 440 dev->base.common.close = vsoc_hwc_close; 441 442 dev->base.prepare = vsoc_hwc_prepare; 443 dev->base.set = vsoc_hwc_set; 444 dev->base.query = vsoc_hwc_query; 445 dev->base.registerProcs = vsoc_hwc_register_procs; 446 dev->base.dump = vsoc_hwc_dump; 447 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1) 448 static hwc_methods_t hwc_methods = {vsoc_hwc_event_control}; 449 dev->base.methods = &hwc_methods; 450 #else 451 dev->base.blank = vsoc_hwc_blank; 452 dev->base.eventControl = vsoc_hwc_event_control; 453 dev->base.getDisplayConfigs = vsoc_hwc_get_display_configs; 454 dev->base.getDisplayAttributes = vsoc_hwc_get_display_attributes; 455 #endif 456 dev->composer = new ComposerType(dev->vsync_data.vsync_base_timestamp); 457 dev->vsync_data.vsync_period_ns = 1000000000 / dev->composer->refresh_rate(); 458 int ret = pthread_create(&dev->vsync_data.vsync_thread, 459 NULL, cvd::hwc_vsync_thread, &dev->vsync_data); 460 if (ret) { 461 ALOGE("failed to start vsync thread: %s", strerror(ret)); 462 ret = -ret; 463 delete dev; 464 } else { 465 *device = &dev->base.common; 466 } 467 468 return ret; 469 } 470 471 static struct hw_module_methods_t vsoc_hwc_module_methods = { 472 vsoc_hwc_open, 473 }; 474 475 hwc_module_t HAL_MODULE_INFO_SYM = {{HARDWARE_MODULE_TAG, 476 HWC_MODULE_API_VERSION_0_1, 477 HARDWARE_HAL_API_VERSION, 478 HWC_HARDWARE_MODULE_ID, 479 "VSOC hwcomposer module", 480 "Google", 481 &vsoc_hwc_module_methods, 482 NULL, 483 {0}}}; 484