2 * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include <hardware/hardware.h>
19 #include <hardware/hwcomposer.h>
27 #include <cutils/log.h>
29 #include "HostConnection.h"
30 #include "gralloc_cb.h"
32 #define DEFINE_HOST_CONNECTION() \
33 HostConnection *hostCon = HostConnection::get(); \
34 renderControl_encoder_context_t *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL)
36 #define DEFINE_AND_VALIDATE_HOST_CONNECTION() \
37 HostConnection *hostCon = HostConnection::get(); \
39 ALOGE("hwcomposer.anbox: Failed to get host connection\n"); \
42 renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \
44 ALOGE("hwcomposer.anbox: Failed to get renderControl encoder context\n"); \
49 hwc_composer_device_1_t device;
51 // These 3 variables could be reduced to first_overlay only, however it makes
52 // the conditions in the code more complicated. In order to keep things as
53 // simple as possible, there are 3 major ways to display a frame.
54 // 1. Show only the framebuffer.
55 // 2. Show the framebuffer with some overlays above it.
56 // 3. Show all overlays and hide the framebuffer.
58 // Since the framebuffer has no alpha channel and is opaque, it can only ever
59 // be the rearmost layer that we end up putting on screen, otherwise it will
60 // cover up all layers behind it, since its display frame is the whole window.
62 // Without framebuffer_visible, the condition of whether to display the
63 // frambuffer becomes more complex and possibly if (numHwLayers == 0 ||
64 // hwLayers[0]->compositionType != HWC_OVERLAY) but that might not be correct.
66 // The range [first_overlay, first_overlay+num_overlay) is a natural way to
67 // structure the loop and prevents requiring state and iterating through all
68 // the non-OVERLAY layers in hwc_set.
69 bool framebuffer_visible;
74 static void dump_layer(hwc_layer_1_t const* l) {
75 ALOGD("\tname='%s', type=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}",
76 l->name, l->compositionType, l->flags, l->handle, l->transform, l->blending,
83 l->displayFrame.right,
84 l->displayFrame.bottom);
87 static int hwc_prepare(hwc_composer_device_1_t* dev, size_t numDisplays,
88 hwc_display_contents_1_t** displays) {
89 auto context = reinterpret_cast<HwcContext*>(dev);
91 if (displays == NULL || displays[0] == NULL)
94 // Anbox only supports the primary display.
95 if (displays[0]->flags & HWC_GEOMETRY_CHANGED) {
96 const size_t& num_hw_layers = displays[0]->numHwLayers;
98 bool visible = (num_hw_layers == 1);
100 // Iterate backwards and skip the first (end) layer, which is the
101 // framebuffer target layer. According to the SurfaceFlinger folks, the
102 // actual location of this layer is up to the HWC implementation to
103 // decide, but is in the well know last slot of the list. This does not
104 // imply that the framebuffer target layer must be topmost.
105 for (; i < num_hw_layers; i++) {
106 hwc_layer_1_t* layer = &displays[0]->hwLayers[num_hw_layers - 1 - i];
112 if (layer->flags & HWC_SKIP_LAYER) {
113 // All layers below and including this one will be drawn into the
114 // framebuffer. Stop marking further layers as HWC_OVERLAY.
119 switch (layer->compositionType) {
121 case HWC_FRAMEBUFFER:
122 layer->compositionType = HWC_OVERLAY;
127 ALOGE("hwcomposor: Invalid compositionType %d",
128 layer->compositionType);
132 context->first_overlay = num_hw_layers - i;
133 context->num_overlays = i - 1;
134 context->framebuffer_visible = visible;
141 * We're using "implicit" synchronization, so make sure we aren't passing any
142 * sync object descriptors around.
144 static void check_sync_fds(size_t numDisplays, hwc_display_contents_1_t** displays)
147 for (i = 0; i < numDisplays; i++) {
148 hwc_display_contents_1_t* list = displays[i];
149 if (list->retireFenceFd >= 0) {
150 ALOGW("retireFenceFd[%u] was %d", i, list->retireFenceFd);
151 list->retireFenceFd = -1;
154 for (j = 0; j < list->numHwLayers; j++) {
155 hwc_layer_1_t* layer = &list->hwLayers[j];
156 if (layer->acquireFenceFd >= 0) {
157 ALOGW("acquireFenceFd[%u][%u] was %d, closing", i, j, layer->acquireFenceFd);
158 close(layer->acquireFenceFd);
159 layer->acquireFenceFd = -1;
161 if (layer->releaseFenceFd >= 0) {
162 ALOGW("releaseFenceFd[%u][%u] was %d", i, j, layer->releaseFenceFd);
163 layer->releaseFenceFd = -1;
169 static int hwc_set(hwc_composer_device_1_t* dev, size_t numDisplays,
170 hwc_display_contents_1_t** displays) {
171 auto context = reinterpret_cast<HwcContext*>(dev);
173 if (displays == NULL || displays[0] == NULL)
176 DEFINE_AND_VALIDATE_HOST_CONNECTION();
178 for (size_t i = 0 ; i < displays[0]->numHwLayers ; i++) {
179 const auto layer = &displays[0]->hwLayers[i];
181 if (layer->flags & HWC_SKIP_LAYER ||
182 layer->flags & HWC_IS_CURSOR_LAYER)
189 // FIXME this is just dirty ... but layer->handle is a const native_handle_t and canBePosted
190 // can't be called with a const.
191 auto cb = const_cast<cb_handle_t*>(reinterpret_cast<const cb_handle_t*>(layer->handle));
192 if (!cb_handle_t::validate(cb)) {
193 ALOGE("Buffer handle is invalid\n");
197 rcEnc->rcPostLayer(rcEnc,
200 layer->planeAlpha / 255,
201 layer->sourceCrop.left,
202 layer->sourceCrop.top,
203 layer->sourceCrop.right,
204 layer->sourceCrop.bottom,
205 layer->displayFrame.left,
206 layer->displayFrame.top,
207 layer->displayFrame.right,
208 layer->displayFrame.bottom);
212 rcEnc->rcPostAllLayersDone(rcEnc);
214 check_sync_fds(numDisplays, displays);
219 static int hwc_event_control(hwc_composer_device_1* dev, int disp,
220 int event, int enabled) {
224 static void hwc_register_procs(hwc_composer_device_1* dev,
225 hwc_procs_t const* procs) {
228 static int hwc_blank(hwc_composer_device_1* dev, int disp, int blank) {
232 static int hwc_query(hwc_composer_device_1* dev, int what, int* value) {
236 static int hwc_device_close(hw_device_t* dev) {
237 auto context = reinterpret_cast<HwcContext*>(dev);
242 static int hwc_get_display_configs(hwc_composer_device_1* dev, int disp,
243 uint32_t* configs, size_t* numConfigs) {
248 if (*numConfigs > 0) {
249 // Config[0] will be passed in to getDisplayAttributes as the disp
250 // parameter. The ARC display supports only 1 configuration.
257 static int hwc_get_display_attributes(hwc_composer_device_1* dev,
258 int disp, uint32_t config,
259 const uint32_t* attributes,
261 if (disp != 0 || config != 0) {
265 DEFINE_AND_VALIDATE_HOST_CONNECTION();
267 while (*attributes != HWC_DISPLAY_NO_ATTRIBUTE) {
268 switch (*attributes) {
269 case HWC_DISPLAY_VSYNC_PERIOD:
270 *values = rcEnc->rcGetDisplayVsyncPeriod(rcEnc, disp);
272 case HWC_DISPLAY_WIDTH:
273 *values = rcEnc->rcGetDisplayWidth(rcEnc, disp);
275 case HWC_DISPLAY_HEIGHT:
276 *values = rcEnc->rcGetDisplayHeight(rcEnc, disp);
278 case HWC_DISPLAY_DPI_X:
279 *values = 1000 * rcEnc->rcGetDisplayDpiX(rcEnc, disp);
281 case HWC_DISPLAY_DPI_Y:
282 *values = 1000 * rcEnc->rcGetDisplayDpiY(rcEnc, disp);
285 ALOGE("Unknown attribute value 0x%02x", *attributes);
293 static int hwc_device_open(const hw_module_t* module, const char* name, hw_device_t** device) {
294 ALOGD("%s", __PRETTY_FUNCTION__);
296 if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0)
299 auto dev = new HwcContext;
300 dev->device.common.tag = HARDWARE_DEVICE_TAG;
301 dev->device.common.version = HWC_DEVICE_API_VERSION_1_0;
302 dev->device.common.module = const_cast<hw_module_t*>(module);
303 dev->device.common.close = hwc_device_close;
304 dev->device.prepare = hwc_prepare;
305 dev->device.set = hwc_set;
306 dev->device.eventControl = hwc_event_control;
307 dev->device.blank = hwc_blank;
308 dev->device.query = hwc_query;
309 dev->device.getDisplayConfigs = hwc_get_display_configs;
310 dev->device.getDisplayAttributes = hwc_get_display_attributes;
311 dev->device.registerProcs = hwc_register_procs;
312 dev->device.dump = nullptr;
314 *device = &dev->device.common;
319 static hw_module_methods_t hwc_module_methods = {
320 .open = hwc_device_open
323 hwc_module_t HAL_MODULE_INFO_SYM = {
325 .tag = HARDWARE_MODULE_TAG,
328 .id = HWC_HARDWARE_MODULE_ID,
329 .name = "Hardware Composer Module",
330 .author = "Anbox Developers",
331 .methods = &hwc_module_methods,