• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cutils/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 "common/vsoc/lib/screen_region_view.h"
57 #include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h"
58 #include <sync/sync.h>
59 
60 #include "base_composer.h"
61 #include "geometry_utils.h"
62 #include "hwcomposer_common.h"
63 #include "stats_keeper.h"
64 #include "vsoc_composer.h"
65 
66 using vsoc::screen::ScreenRegionView;
67 
68 #ifdef USE_OLD_HWCOMPOSER
69 typedef cvd::BaseComposer InnerComposerType;
70 #else
71 typedef cvd::VSoCComposer InnerComposerType;
72 #endif
73 
74 #ifdef GATHER_STATS
75 typedef cvd::StatsKeepingComposer<InnerComposerType> ComposerType;
76 #else
77 typedef InnerComposerType ComposerType;
78 #endif
79 
80 struct vsoc_hwc_composer_device_1_t {
81   vsoc_hwc_device base;
82   const hwc_procs_t* procs;
83   pthread_t vsync_thread;
84   int64_t vsync_base_timestamp;
85   int32_t vsync_period_ns;
86   ComposerType* composer;
87 };
88 
89 namespace {
90 
91 std::string CompositionString(int type) {
92   switch (type) {
93     case HWC_FRAMEBUFFER:
94       return "Framebuffer";
95     case HWC_OVERLAY:
96       return "Overlay";
97     case HWC_BACKGROUND:
98       return "Background";
99     case HWC_FRAMEBUFFER_TARGET:
100       return "FramebufferTarget";
101 #if VSOC_PLATFORM_SDK_AFTER(K)
102     case HWC_SIDEBAND:
103       return "Sideband";
104     case HWC_CURSOR_OVERLAY:
105       return "CursorOverlay";
106 #endif
107     default:
108       return std::string("Unknown (") + std::to_string(type) + ")";
109   }
110 }
111 
112 void LogLayers(int num_layers, vsoc_hwc_layer* layers, int invalid) {
113   ALOGE("Layers:");
114   for (int idx = 0; idx < num_layers; ++idx) {
115     std::string log_line;
116     if (idx == invalid) {
117       log_line = "Invalid layer: ";
118     }
119     log_line +=
120         "Composition Type: " + CompositionString(layers[idx].compositionType);
121     ALOGE("%s", log_line.c_str());
122   }
123 }
124 
125 // Ensures that the layer does not include any inconsistencies
126 bool IsValidLayer(const vsoc_hwc_layer& layer) {
127   if (layer.flags & HWC_SKIP_LAYER) {
128     // A layer we are asked to skip validate should not be marked as skip
129     ALOGE("%s: Layer is marked as skip", __FUNCTION__);
130     return false;
131   }
132   // Check displayFrame
133   if (layer.displayFrame.left > layer.displayFrame.right ||
134       layer.displayFrame.top > layer.displayFrame.bottom) {
135     ALOGE(
136         "%s: Malformed rectangle (displayFrame): [left = %d, right = %d, top = "
137         "%d, bottom = %d]",
138         __FUNCTION__, layer.displayFrame.left, layer.displayFrame.right,
139         layer.displayFrame.top, layer.displayFrame.bottom);
140     return false;
141   }
142   // Validate the handle
143   if (private_handle_t::validate(layer.handle) != 0) {
144     ALOGE("%s: Layer contains an invalid gralloc handle.", __FUNCTION__);
145     return false;
146   }
147   const private_handle_t* p_handle =
148       reinterpret_cast<const private_handle_t*>(layer.handle);
149   // Check sourceCrop
150   if (layer.sourceCrop.left > layer.sourceCrop.right ||
151       layer.sourceCrop.top > layer.sourceCrop.bottom) {
152     ALOGE(
153         "%s: Malformed rectangle (sourceCrop): [left = %d, right = %d, top = "
154         "%d, bottom = %d]",
155         __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right,
156         layer.sourceCrop.top, layer.sourceCrop.bottom);
157     return false;
158   }
159   if (layer.sourceCrop.left < 0 || layer.sourceCrop.top < 0 ||
160       layer.sourceCrop.right > p_handle->x_res ||
161       layer.sourceCrop.bottom > p_handle->y_res) {
162     ALOGE(
163         "%s: Invalid sourceCrop for buffer handle: sourceCrop = [left = %d, "
164         "right = %d, top = %d, bottom = %d], handle = [width = %d, height = "
165         "%d]",
166         __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right,
167         layer.sourceCrop.top, layer.sourceCrop.bottom, p_handle->x_res,
168         p_handle->y_res);
169     return false;
170   }
171   return true;
172 }
173 
174 bool IsValidComposition(int num_layers, vsoc_hwc_layer* layers, bool on_set) {
175   if (num_layers == 0) {
176     ALOGE("Composition requested with 0 layers");
177     return false;
178   }
179   // Sometimes the hwcomposer receives a prepare and set calls with no other
180   // layer than the FRAMEBUFFER_TARGET with a null handler. We treat this case
181   // independently as a valid composition, but issue a warning about it.
182   if (num_layers == 1 && layers[0].compositionType == HWC_FRAMEBUFFER_TARGET &&
183       layers[0].handle == NULL) {
184     ALOGW("Received request for empty composition, treating as valid noop");
185     return true;
186   }
187   // The FRAMEBUFFER_TARGET layer needs to be sane only if
188   // there is at least one layer marked HWC_FRAMEBUFFER or if there is no layer
189   // marked HWC_OVERLAY (i.e some layers where composed with OpenGL, no layer
190   // marked overlay or framebuffer means that surfaceflinger decided to go for
191   // OpenGL without asking the hwcomposer first)
192   bool check_fb_target = true;
193   for (int idx = 0; idx < num_layers; ++idx) {
194     if (layers[idx].compositionType == HWC_FRAMEBUFFER) {
195       // There is at least one, so it needs to be checked.
196       // It may have been set to false before, so ensure it's set to true.
197       check_fb_target = true;
198       break;
199     }
200     if (layers[idx].compositionType == HWC_OVERLAY) {
201       // At least one overlay, we may not need to.
202       check_fb_target = false;
203     }
204   }
205 
206   for (int idx = 0; idx < num_layers; ++idx) {
207     switch (layers[idx].compositionType) {
208     case HWC_FRAMEBUFFER_TARGET:
209       // In the call to prepare() the framebuffer target does not have a valid
210       // buffer_handle, so we don't validate it yet.
211       if (on_set && check_fb_target && !IsValidLayer(layers[idx])) {
212         ALOGE("%s: Invalid layer found", __FUNCTION__);
213         LogLayers(num_layers, layers, idx);
214         return false;
215       }
216       break;
217     case HWC_OVERLAY:
218       if (!(layers[idx].flags & HWC_SKIP_LAYER) &&
219           !IsValidLayer(layers[idx])) {
220         ALOGE("%s: Invalid layer found", __FUNCTION__);
221         LogLayers(num_layers, layers, idx);
222         return false;
223       }
224       break;
225     }
226   }
227   return true;
228 }
229 
230 }
231 
232 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
233 static int vsoc_hwc_prepare(vsoc_hwc_device* dev, hwc_layer_list_t* list) {
234 #else
235 static int vsoc_hwc_prepare(vsoc_hwc_device* dev, size_t numDisplays,
236                             hwc_display_contents_1_t** displays) {
237   if (!numDisplays || !displays) return 0;
238 
239   hwc_display_contents_1_t* list = displays[HWC_DISPLAY_PRIMARY];
240 
241   if (!list) return 0;
242 #endif
243   if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], false)) {
244     LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
245     return -1;
246   }
247   reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->PrepareLayers(
248       list->numHwLayers, &list->hwLayers[0]);
249   return 0;
250 }
251 
252 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
253 int vsoc_hwc_set(struct hwc_composer_device* dev, hwc_display_t dpy,
254                  hwc_surface_t sur, hwc_layer_list_t* list) {
255   if (list->numHwLayers == 1 &&
256       layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) {
257     ALOGW("Received request for empty composition, treating as valid noop");
258     return 0;
259   }
260   if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], true)) {
261     LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
262     return -1;
263   }
264   return reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)
265       ->composer->SetLayers(list->numHwLayers, &list->hwLayers[0]);
266 }
267 #else
268 static int vsoc_hwc_set(vsoc_hwc_device* dev, size_t numDisplays,
269                         hwc_display_contents_1_t** displays) {
270   if (!numDisplays || !displays) return 0;
271 
272   hwc_display_contents_1_t* contents = displays[HWC_DISPLAY_PRIMARY];
273   if (!contents) return 0;
274 
275   vsoc_hwc_layer* layers = &contents->hwLayers[0];
276   if (contents->numHwLayers == 1 &&
277       layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) {
278     ALOGW("Received request for empty composition, treating as valid noop");
279     return 0;
280   }
281   if (!IsValidComposition(contents->numHwLayers, layers, true)) {
282     LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
283     return -1;
284   }
285   int retval =
286       reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->SetLayers(
287           contents->numHwLayers, layers);
288 
289   int closedFds = 0;
290   for (size_t index = 0; index < contents->numHwLayers; ++index) {
291     if (layers[index].acquireFenceFd != -1) {
292       close(layers[index].acquireFenceFd);
293       layers[index].acquireFenceFd = -1;
294       ++closedFds;
295     }
296   }
297   if (closedFds) {
298     ALOGI("Saw %zu layers, closed=%d", contents->numHwLayers, closedFds);
299   }
300 
301   // TODO(ghartman): This should be set before returning. On the next set it
302   // should be signalled when we load the new frame.
303   contents->retireFenceFd = -1;
304   return retval;
305 }
306 #endif
307 
308 static void vsoc_hwc_register_procs(vsoc_hwc_device* dev,
309                                     const hwc_procs_t* procs) {
310   struct vsoc_hwc_composer_device_1_t* pdev =
311       (struct vsoc_hwc_composer_device_1_t*)dev;
312   pdev->procs = procs;
313 }
314 
315 static int vsoc_hwc_query(vsoc_hwc_device* dev, int what, int* value) {
316   struct vsoc_hwc_composer_device_1_t* pdev =
317       (struct vsoc_hwc_composer_device_1_t*)dev;
318 
319   switch (what) {
320     case HWC_BACKGROUND_LAYER_SUPPORTED:
321       // we support the background layer
322       value[0] = 0;
323       break;
324     case HWC_VSYNC_PERIOD:
325       value[0] = pdev->vsync_period_ns;
326       break;
327     default:
328       // unsupported query
329       ALOGE("%s badness unsupported query what=%d", __FUNCTION__, what);
330       return -EINVAL;
331   }
332   return 0;
333 }
334 
335 static int vsoc_hwc_event_control(
336 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
337     vsoc_hwc_device* /*dev*/, int event, int /*enabled*/) {
338 #else
339     vsoc_hwc_device* /*dev*/, int /*dpy*/, int event, int /*enabled*/) {
340 #endif
341 
342   if (event == HWC_EVENT_VSYNC) {
343     return 0;
344   }
345   return -EINVAL;
346 }
347 
348 static void* hwc_vsync_thread(void* data) {
349   struct vsoc_hwc_composer_device_1_t* pdev =
350       (struct vsoc_hwc_composer_device_1_t*)data;
351   setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
352 
353   int64_t base_timestamp = pdev->vsync_base_timestamp;
354   int64_t last_logged = base_timestamp / 1e9;
355   int sent = 0;
356   int last_sent = 0;
357   static const int log_interval = 60;
358   void (*vsync_proc)(const struct hwc_procs*, int, int64_t) = nullptr;
359   bool log_no_procs = true, log_no_vsync = true;
360   while (true) {
361     struct timespec rt;
362     if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
363       ALOGE("%s:%d error in vsync thread clock_gettime: %s", __FILE__, __LINE__,
364             strerror(errno));
365     }
366     int64_t timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec;
367     // Given now's timestamp calculate the time of the next timestamp.
368     timestamp += pdev->vsync_period_ns -
369                  (timestamp - base_timestamp) % pdev->vsync_period_ns;
370 
371     rt.tv_sec = timestamp / 1e9;
372     rt.tv_nsec = timestamp % static_cast<int32_t>(1e9);
373     int err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &rt, NULL);
374     if (err == -1) {
375       ALOGE("error in vsync thread: %s", strerror(errno));
376       if (errno == EINTR) {
377         continue;
378       }
379     }
380 
381     // The vsync thread is started on device open, it may run before the
382     // registerProcs callback has a chance to be called, so we need to make sure
383     // procs is not NULL before dereferencing it.
384     if (pdev && pdev->procs) {
385       vsync_proc = pdev->procs->vsync;
386     } else if (log_no_procs) {
387       log_no_procs = false;
388       ALOGI("procs is not set yet, unable to deliver vsync event");
389     }
390     if (vsync_proc) {
391       vsync_proc(const_cast<hwc_procs_t*>(pdev->procs), 0, timestamp);
392       ++sent;
393     } else if (log_no_vsync) {
394       log_no_vsync = false;
395       ALOGE("vsync callback is null (but procs was already set)");
396     }
397     if (rt.tv_sec - last_logged > log_interval) {
398       ALOGI("Sent %d syncs in %ds", sent - last_sent, log_interval);
399       last_logged = rt.tv_sec;
400       last_sent = sent;
401     }
402   }
403 
404   return NULL;
405 }
406 
407 static int vsoc_hwc_blank(vsoc_hwc_device* /*dev*/, int disp, int /*blank*/) {
408   if (!IS_PRIMARY_DISPLAY(disp)) return -EINVAL;
409   return 0;
410 }
411 
412 static void vsoc_hwc_dump(vsoc_hwc_device* dev, char* buff, int buff_len) {
413   reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->Dump(
414       buff, buff_len);
415 }
416 
417 static int vsoc_hwc_get_display_configs(vsoc_hwc_device* /*dev*/, int disp,
418                                         uint32_t* configs, size_t* numConfigs) {
419   if (*numConfigs == 0) return 0;
420 
421   if (IS_PRIMARY_DISPLAY(disp)) {
422     configs[0] = 0;
423     *numConfigs = 1;
424     return 0;
425   }
426 
427   return -EINVAL;
428 }
429 
430 #if VSOC_PLATFORM_SDK_AFTER(J)
431 static int32_t vsoc_hwc_attribute(struct vsoc_hwc_composer_device_1_t* pdev,
432                                   const uint32_t attribute) {
433   auto screen_view = ScreenRegionView::GetInstance();
434   switch (attribute) {
435     case HWC_DISPLAY_VSYNC_PERIOD:
436       return pdev->vsync_period_ns;
437     case HWC_DISPLAY_WIDTH:
438       return screen_view->x_res();
439     case HWC_DISPLAY_HEIGHT:
440       return screen_view->y_res();
441     case HWC_DISPLAY_DPI_X:
442       ALOGI("Reporting DPI_X of %d", screen_view->dpi());
443       // The number of pixels per thousand inches
444       return screen_view->dpi() * 1000;
445     case HWC_DISPLAY_DPI_Y:
446       ALOGI("Reporting DPI_Y of %d", screen_view->dpi());
447       // The number of pixels per thousand inches
448       return screen_view->dpi() * 1000;
449     default:
450       ALOGE("unknown display attribute %u", attribute);
451       return -EINVAL;
452   }
453 }
454 
455 static int vsoc_hwc_get_display_attributes(vsoc_hwc_device* dev, int disp,
456                                            uint32_t config __unused,
457                                            const uint32_t* attributes,
458                                            int32_t* values) {
459   struct vsoc_hwc_composer_device_1_t* pdev =
460       (struct vsoc_hwc_composer_device_1_t*)dev;
461 
462   if (!IS_PRIMARY_DISPLAY(disp)) {
463     ALOGE("unknown display type %u", disp);
464     return -EINVAL;
465   }
466 
467   for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
468     values[i] = vsoc_hwc_attribute(pdev, attributes[i]);
469   }
470 
471   return 0;
472 }
473 #endif
474 
475 static int vsoc_hwc_close(hw_device_t* device) {
476   struct vsoc_hwc_composer_device_1_t* dev =
477       (struct vsoc_hwc_composer_device_1_t*)device;
478   ALOGE("vsoc_hwc_close");
479   pthread_kill(dev->vsync_thread, SIGTERM);
480   pthread_join(dev->vsync_thread, NULL);
481   delete dev->composer;
482   delete dev;
483   return 0;
484 }
485 
486 static int vsoc_hwc_open(const struct hw_module_t* module, const char* name,
487                          struct hw_device_t** device) {
488   ALOGI("%s", __FUNCTION__);
489   if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
490     ALOGE("%s called with bad name %s", __FUNCTION__, name);
491     return -EINVAL;
492   }
493 
494   vsoc_hwc_composer_device_1_t* dev = new vsoc_hwc_composer_device_1_t();
495   if (!dev) {
496     ALOGE("%s failed to allocate dev", __FUNCTION__);
497     return -ENOMEM;
498   }
499 
500   int refreshRate = ScreenRegionView::GetInstance()->refresh_rate_hz();
501   dev->vsync_period_ns = 1000000000 / refreshRate;
502   struct timespec rt;
503   if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
504     ALOGE("%s:%d error in vsync thread clock_gettime: %s", __FILE__, __LINE__,
505           strerror(errno));
506   }
507   dev->vsync_base_timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec;
508 
509   dev->base.common.tag = HARDWARE_DEVICE_TAG;
510   dev->base.common.version = VSOC_HWC_DEVICE_API_VERSION;
511   dev->base.common.module = const_cast<hw_module_t*>(module);
512   dev->base.common.close = vsoc_hwc_close;
513 
514   dev->base.prepare = vsoc_hwc_prepare;
515   dev->base.set = vsoc_hwc_set;
516   dev->base.query = vsoc_hwc_query;
517   dev->base.registerProcs = vsoc_hwc_register_procs;
518   dev->base.dump = vsoc_hwc_dump;
519 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
520   static hwc_methods_t hwc_methods = {vsoc_hwc_event_control};
521   dev->base.methods = &hwc_methods;
522 #else
523   dev->base.blank = vsoc_hwc_blank;
524   dev->base.eventControl = vsoc_hwc_event_control;
525   dev->base.getDisplayConfigs = vsoc_hwc_get_display_configs;
526   dev->base.getDisplayAttributes = vsoc_hwc_get_display_attributes;
527 #endif
528   dev->composer =
529       new ComposerType(dev->vsync_base_timestamp, dev->vsync_period_ns);
530 
531   int ret = pthread_create(&dev->vsync_thread, NULL, hwc_vsync_thread, dev);
532   if (ret) {
533     ALOGE("failed to start vsync thread: %s", strerror(ret));
534     ret = -ret;
535     delete dev;
536   } else {
537     *device = &dev->base.common;
538   }
539 
540   return ret;
541 }
542 
543 static struct hw_module_methods_t vsoc_hwc_module_methods = {
544     vsoc_hwc_open,
545 };
546 
547 hwc_module_t HAL_MODULE_INFO_SYM = {{HARDWARE_MODULE_TAG,
548                                      HWC_MODULE_API_VERSION_0_1,
549                                      HARDWARE_HAL_API_VERSION,
550                                      HWC_HARDWARE_MODULE_ID,
551                                      "VSOC hwcomposer module",
552                                      "Google",
553                                      &vsoc_hwc_module_methods,
554                                      NULL,
555                                      {0}}};
556