• Home
  • 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 <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