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
CompositionString(int type)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
LogLayers(int num_layers,vsoc_hwc_layer * layers,int invalid)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
IsValidLayer(const vsoc_hwc_layer & layer)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
IsValidComposition(int num_layers,vsoc_hwc_layer * layers,bool on_set)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)
vsoc_hwc_prepare(vsoc_hwc_device * dev,hwc_layer_list_t * list)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