summaryrefslogtreecommitdiff
path: root/libhwc
diff options
context:
space:
mode:
authorBenoit Goby <benoit@android.com>2012-09-28 20:37:17 -0700
committerBenoit Goby <benoit@android.com>2012-10-01 20:57:23 -0700
commit93f9f5db1b8ed79cac5abb62544f59c04fd49252 (patch)
tree8a9ee021b4fcb16d17242836e03f006be7e7ef09 /libhwc
parent995bbd512ac29912894158067e3fc44d3ceb000a (diff)
downloadexynos5-93f9f5db1b8ed79cac5abb62544f59c04fd49252.tar.gz
hwc: Use graphic layer and no gscaler for FB TARGET
Bug: 7123196 Change-Id: I8fffd9c6896919b2d24192e90d5125d0976980d3
Diffstat (limited to 'libhwc')
-rw-r--r--libhwc/hwc.cpp372
1 files changed, 182 insertions, 190 deletions
diff --git a/libhwc/hwc.cpp b/libhwc/hwc.cpp
index 588b4df..e4ce96b 100644
--- a/libhwc/hwc.cpp
+++ b/libhwc/hwc.cpp
@@ -59,6 +59,7 @@ const int AVAILABLE_GSC_UNITS[] = { 0, 3 };
const size_t NUM_GSC_UNITS = sizeof(AVAILABLE_GSC_UNITS) /
sizeof(AVAILABLE_GSC_UNITS[0]);
const size_t BURSTLEN_BYTES = 16 * 8;
+const size_t NUM_HDMI_BUFFERS = 3;
struct exynos5_hwc_composer_device_1_t;
@@ -86,6 +87,17 @@ struct exynos5_gsc_data_t {
size_t current_buf;
};
+struct hdmi_layer_t {
+ int id;
+ int fd;
+ bool enabled;
+ exynos_gsc_img cfg;
+
+ bool streaming;
+ size_t current_buf;
+ size_t queued_buf;
+};
+
struct exynos5_hwc_composer_device_1_t {
hwc_composer_device_1_t base;
@@ -106,16 +118,12 @@ struct exynos5_hwc_composer_device_1_t {
int32_t vsync_period;
int hdmi_mixer0;
- int hdmi_layer0;
- int hdmi_layer1;
bool hdmi_hpd;
bool hdmi_enabled;
bool hdmi_blanked;
- void *hdmi_gsc;
int hdmi_w;
int hdmi_h;
- exynos_gsc_img hdmi_src;
- exynos_gsc_img hdmi_dst;
+ hdmi_layer_t hdmi_layers[2];
exynos5_gsc_data_t gsc[NUM_GSC_UNITS];
@@ -365,14 +373,14 @@ int hdmi_get_config(struct exynos5_hwc_composer_device_1_t *dev)
bool found = false;
int ret;
- if (ioctl(dev->hdmi_layer0, VIDIOC_G_DV_PRESET, &preset) < 0) {
+ if (ioctl(dev->hdmi_layers[0].fd, VIDIOC_G_DV_PRESET, &preset) < 0) {
ALOGE("%s: g_dv_preset error, %d", __func__, errno);
return -1;
}
while (true) {
enum_preset.index = index++;
- ret = ioctl(dev->hdmi_layer0, VIDIOC_ENUM_DV_PRESETS, &enum_preset);
+ ret = ioctl(dev->hdmi_layers[0].fd, VIDIOC_ENUM_DV_PRESETS, &enum_preset);
if (ret < 0) {
if (errno == EINVAL)
@@ -415,147 +423,58 @@ static bool exynos5_blending_is_supported(int32_t blending)
return exynos5_blending_to_s3c_blending(blending) < S3C_FB_BLENDING_MAX;
}
-static int hdmi_start_background(struct exynos5_hwc_composer_device_1_t *dev)
+
+static int hdmi_enable_layer(struct exynos5_hwc_composer_device_1_t *dev,
+ hdmi_layer_t &hl)
{
- struct v4l2_requestbuffers reqbuf;
- struct v4l2_subdev_format sd_fmt;
- struct v4l2_subdev_crop sd_crop;
- struct v4l2_format fmt;
- struct v4l2_buffer buffer;
- struct v4l2_plane planes[1];
+ if (hl.enabled)
+ return 0;
+ struct v4l2_requestbuffers reqbuf;
memset(&reqbuf, 0, sizeof(reqbuf));
- memset(&sd_fmt, 0, sizeof(sd_fmt));
- memset(&sd_crop, 0, sizeof(sd_crop));
- memset(&fmt, 0, sizeof(fmt));
- memset(&buffer, 0, sizeof(buffer));
- memset(planes, 0, sizeof(planes));
-
- sd_fmt.pad = MIXER_G1_SUBDEV_PAD_SINK;
- sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- sd_fmt.format.width = 1;
- sd_fmt.format.height = 1;
- sd_fmt.format.code = V4L2_MBUS_FMT_XRGB8888_4X8_LE;
- if (exynos_subdev_s_fmt(dev->hdmi_mixer0, &sd_fmt) < 0) {
- ALOGE("%s: s_fmt failed pad=%d", __func__, sd_fmt.pad);
- return -1;
- }
-
- sd_crop.pad = MIXER_G1_SUBDEV_PAD_SINK;
- sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- sd_crop.rect.left = 0;
- sd_crop.rect.top = 0;
- sd_crop.rect.width = 1;
- sd_crop.rect.height = 1;
- if (exynos_subdev_s_crop(dev->hdmi_mixer0, &sd_crop) < 0) {
- ALOGE("%s: set_crop failed pad=%d", __func__, sd_crop.pad);
- return -1;
- }
-
- sd_fmt.pad = MIXER_G1_SUBDEV_PAD_SOURCE;
- sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- sd_fmt.format.width = dev->hdmi_w;
- sd_fmt.format.height = dev->hdmi_h;
- sd_fmt.format.code = V4L2_MBUS_FMT_XRGB8888_4X8_LE;
- if (exynos_subdev_s_fmt(dev->hdmi_mixer0, &sd_fmt) < 0) {
- ALOGE("%s: s_fmt failed pad=%d", __func__, sd_fmt.pad);
- return -1;
- }
-
- sd_crop.pad = MIXER_G1_SUBDEV_PAD_SOURCE;
- sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- sd_crop.rect.left = 0;
- sd_crop.rect.top = 0;
- sd_crop.rect.width = 1;
- sd_crop.rect.height = 1;
- if (exynos_subdev_s_crop(dev->hdmi_mixer0, &sd_crop) < 0) {
- ALOGE("%s: s_crop failed pad=%d", __func__, sd_crop.pad);
- return -1;
- }
-
- fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- fmt.fmt.pix_mp.width = 1;
- fmt.fmt.pix_mp.height = 1;
- fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_BGR32;
- fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
- fmt.fmt.pix_mp.num_planes = 1;
- if (exynos_v4l2_s_fmt(dev->hdmi_layer1, &fmt) < 0) {
- ALOGE("%s::videodev set format failed", __func__);
- return -1;
- }
-
- reqbuf.count = 1;
+ reqbuf.count = NUM_HDMI_BUFFERS;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- reqbuf.memory = V4L2_MEMORY_MMAP;
-
- if (exynos_v4l2_reqbufs(dev->hdmi_layer1, &reqbuf) < 0) {
- ALOGE("%s: exynos_v4l2_reqbufs failed %d", __func__, errno);
- return -1;
- }
-
- if (reqbuf.count != 1) {
- ALOGE("%s: didn't get buffer", __func__);
- return -1;
- }
-
- memset(&buffer, 0, sizeof(buffer));
- buffer.type = reqbuf.type;
- buffer.memory = V4L2_MEMORY_MMAP;
- buffer.length = 1;
- buffer.m.planes = planes;
- if (exynos_v4l2_querybuf(dev->hdmi_layer1, &buffer) < 0) {
- ALOGE("%s: exynos_v4l2_querybuf failed %d", __func__, errno);
+ reqbuf.memory = V4L2_MEMORY_DMABUF;
+ if (exynos_v4l2_reqbufs(hl.fd, &reqbuf) < 0) {
+ ALOGE("%s: layer%d: reqbufs failed %d", __func__, hl.id, errno);
return -1;
}
- void *start = mmap(NULL, planes[0].length, PROT_READ | PROT_WRITE,
- MAP_SHARED, dev->hdmi_layer1, planes[0].m.mem_offset);
- if (start == MAP_FAILED) {
- ALOGE("%s: mmap failed %d", __func__, errno);
- return -1;
- }
-
- memset(start, 0, planes[0].length);
-
- munmap(start, planes[0].length);
-
- if (exynos_v4l2_qbuf(dev->hdmi_layer1, &buffer) < 0) {
- ALOGE("%s: exynos_v4l2_qbuf failed %d", __func__, errno);
- return -1;
- }
-
- if (exynos_v4l2_streamon(dev->hdmi_layer1, buffer.type) < 0) {
- ALOGE("%s:stream on failed", __func__);
- return -1;
- }
-
- if (exynos_v4l2_s_ctrl(dev->hdmi_layer1, V4L2_CID_TV_LAYER_PRIO, 0) < 0) {
- ALOGE("%s: s_ctrl LAYER_PRIO failed", __func__);
+ if (reqbuf.count != NUM_HDMI_BUFFERS) {
+ ALOGE("%s: layer%d: didn't get buffer", __func__, hl.id);
return -1;
}
+ ALOGV("%s: layer%d enabled", __func__, hl.id);
+ hl.enabled = true;
return 0;
}
-static int hdmi_stop_background(struct exynos5_hwc_composer_device_1_t *dev)
+static void hdmi_disable_layer(struct exynos5_hwc_composer_device_1_t *dev,
+ hdmi_layer_t &hl)
{
- struct v4l2_requestbuffers reqbuf;
+ if (!hl.enabled)
+ return;
- if (exynos_v4l2_streamoff(dev->hdmi_layer1, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) {
- ALOGE("%s:stream off failed", __func__);
- return -1;
+ if (hl.streaming) {
+ if (exynos_v4l2_streamoff(hl.fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0)
+ ALOGE("%s: layer%d: streamoff failed %d", __func__, hl.id, errno);
+ hl.streaming = false;
}
+ struct v4l2_requestbuffers reqbuf;
memset(&reqbuf, 0, sizeof(reqbuf));
- reqbuf.count = 0;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- reqbuf.memory = V4L2_MEMORY_MMAP;
- if (exynos_v4l2_reqbufs(dev->hdmi_layer1, &reqbuf) < 0) {
- ALOGE("%s: exynos_v4l2_reqbufs failed %d", __func__, errno);
- return -1;
- }
+ reqbuf.memory = V4L2_MEMORY_DMABUF;
+ if (exynos_v4l2_reqbufs(hl.fd, &reqbuf) < 0)
+ ALOGE("%s: layer%d: reqbufs failed %d", __func__, hl.id, errno);
- return 0;
+ memset(&hl.cfg, 0, sizeof(hl.cfg));
+ hl.current_buf = 0;
+ hl.queued_buf = 0;
+ hl.enabled = false;
+
+ ALOGV("%s: layer%d disabled", __func__, hl.id);
}
static int hdmi_enable(struct exynos5_hwc_composer_device_1_t *dev)
@@ -566,19 +485,52 @@ static int hdmi_enable(struct exynos5_hwc_composer_device_1_t *dev)
if (dev->hdmi_blanked)
return 0;
- dev->hdmi_gsc = exynos_gsc_create_exclusive(3, GSC_OUTPUT_MODE, GSC_OUT_TV);
- if (!dev->hdmi_gsc) {
- ALOGE("%s: exynos_gsc_create_exclusive failed", __func__);
- return -ENODEV;
+ struct v4l2_subdev_format sd_fmt;
+ memset(&sd_fmt, 0, sizeof(sd_fmt));
+ sd_fmt.pad = MIXER_G0_SUBDEV_PAD_SINK;
+ sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ sd_fmt.format.width = dev->hdmi_w;
+ sd_fmt.format.height = dev->hdmi_h;
+ sd_fmt.format.code = V4L2_MBUS_FMT_XRGB8888_4X8_LE;
+ if (exynos_subdev_s_fmt(dev->hdmi_mixer0, &sd_fmt) < 0) {
+ ALOGE("%s: s_fmt failed pad=%d", __func__, sd_fmt.pad);
+ return -1;
+ }
+
+ struct v4l2_subdev_crop sd_crop;
+ memset(&sd_crop, 0, sizeof(sd_crop));
+ sd_crop.pad = MIXER_G0_SUBDEV_PAD_SINK;
+ sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ sd_crop.rect.width = dev->hdmi_w;
+ sd_crop.rect.height = dev->hdmi_h;
+ if (exynos_subdev_s_crop(dev->hdmi_mixer0, &sd_crop) < 0) {
+ ALOGE("%s: s_crop failed pad=%d", __func__, sd_crop.pad);
+ return -1;
}
- memset(&dev->hdmi_src, 0, sizeof(dev->hdmi_src));
+ memset(&sd_fmt, 0, sizeof(sd_fmt));
+ sd_fmt.pad = MIXER_G0_SUBDEV_PAD_SOURCE;
+ sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ sd_fmt.format.width = dev->hdmi_w;
+ sd_fmt.format.height = dev->hdmi_h;
+ sd_fmt.format.code = V4L2_MBUS_FMT_XRGB8888_4X8_LE;
+ if (exynos_subdev_s_fmt(dev->hdmi_mixer0, &sd_fmt) < 0) {
+ ALOGE("%s: s_fmt failed pad=%d", __func__, sd_fmt.pad);
+ return -1;
+ }
- if (hdmi_start_background(dev) < 0) {
- ALOGE("%s: hdmi_start_background failed", __func__);
+ memset(&sd_crop, 0, sizeof(sd_crop));
+ sd_crop.pad = MIXER_G0_SUBDEV_PAD_SOURCE;
+ sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ sd_crop.rect.width = dev->hdmi_w;
+ sd_crop.rect.height = dev->hdmi_h;
+ if (exynos_subdev_s_crop(dev->hdmi_mixer0, &sd_crop) < 0) {
+ ALOGE("%s: s_crop failed pad=%d", __func__, sd_crop.pad);
return -1;
}
+ hdmi_enable_layer(dev, dev->hdmi_layers[0]);
+
dev->hdmi_enabled = true;
return 0;
}
@@ -587,69 +539,103 @@ static void hdmi_disable(struct exynos5_hwc_composer_device_1_t *dev)
{
if (!dev->hdmi_enabled)
return;
- exynos_gsc_destroy(dev->hdmi_gsc);
- hdmi_stop_background(dev);
- dev->hdmi_gsc = NULL;
+
+ hdmi_disable_layer(dev, dev->hdmi_layers[0]);
+
dev->hdmi_enabled = false;
}
-static int hdmi_configure_fblayer(struct exynos5_hwc_composer_device_1_t *dev,
- hwc_layer_1_t &layer)
+static int hdmi_output(struct exynos5_hwc_composer_device_1_t *dev,
+ hdmi_layer_t &hl,
+ hwc_layer_1_t &layer)
{
- int ret = 0;
- exynos_gsc_img src_cfg, dst_cfg;
- memset(&src_cfg, 0, sizeof(src_cfg));
- memset(&dst_cfg, 0, sizeof(dst_cfg));
private_handle_t *h = private_handle_t::dynamicCast(layer.handle);
+ int ret = 0;
- src_cfg.x = layer.sourceCrop.left;
- src_cfg.y = layer.sourceCrop.top;
- src_cfg.w = WIDTH(layer.sourceCrop);
- src_cfg.fw = h->stride;
- src_cfg.h = HEIGHT(layer.sourceCrop);
- src_cfg.fh = h->vstride;
- src_cfg.format = HAL_PIXEL_FORMAT_RGBX_8888;
- src_cfg.yaddr = h->fd;
- src_cfg.acquireFenceFd = layer.acquireFenceFd;
-
- dst_cfg.w = dev->hdmi_w;
- dst_cfg.fw = dev->hdmi_w;
- dst_cfg.h = dev->hdmi_h;
- dst_cfg.fh = dev->hdmi_h;
- dst_cfg.format = HAL_PIXEL_FORMAT_EXYNOS_YV12;
- dst_cfg.rot = layer.transform;
+ if (!hl.enabled) {
+ ret = -1;
+ goto err;
+ }
- if (gsc_src_cfg_changed(src_cfg, dev->hdmi_src)
- || gsc_dst_cfg_changed(dst_cfg, dev->hdmi_dst)) {
+ exynos_gsc_img cfg;
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.x = layer.displayFrame.left;
+ cfg.y = layer.displayFrame.top;
+ cfg.w = WIDTH(layer.displayFrame);
+ cfg.h = HEIGHT(layer.displayFrame);
+
+ if (gsc_src_cfg_changed(hl.cfg, cfg)) {
+ struct v4l2_format fmt;
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.width = cfg.w;
+ fmt.fmt.pix_mp.height = cfg.h;
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_BGR32;
+ fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
+ fmt.fmt.pix_mp.num_planes = 1;
+ ret = exynos_v4l2_s_fmt(hl.fd, &fmt);
+ if (ret < 0) {
+ ALOGE("%s: layer%d: s_fmt failed %d", __func__, hl.id, errno);
+ goto err;
+ }
- ALOGV("HDMI source config:");
- dump_gsc_img(src_cfg);
- ALOGV("HDMI dest config:");
- dump_gsc_img(dst_cfg);
+ ALOGV("HDMI layer%d configuration:", hl.id);
+ dump_gsc_img(cfg);
+ hl.cfg = cfg;
+ }
- exynos_gsc_stop_exclusive(dev->hdmi_gsc);
+ struct v4l2_buffer buffer;
+ struct v4l2_plane planes[1];
- ret = exynos_gsc_config_exclusive(dev->hdmi_gsc, &src_cfg, &dst_cfg);
+ if (hl.queued_buf == NUM_HDMI_BUFFERS) {
+ memset(&buffer, 0, sizeof(buffer));
+ memset(planes, 0, sizeof(planes));
+ buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ buffer.memory = V4L2_MEMORY_DMABUF;
+ buffer.length = 1;
+ buffer.m.planes = planes;
+ ret = exynos_v4l2_dqbuf(hl.fd, &buffer);
if (ret < 0) {
- ALOGE("%s: exynos_gsc_config_exclusive failed %d", __func__, ret);
+ ALOGE("%s: layer%d: dqbuf failed %d", __func__, hl.id, errno);
goto err;
}
-
- dev->hdmi_src = src_cfg;
- dev->hdmi_dst = dst_cfg;
+ hl.queued_buf--;
}
- ret = exynos_gsc_run_exclusive(dev->hdmi_gsc, &src_cfg, NULL);
- if (ret < 0) {
- ALOGE("%s: exynos_gsc_run_exclusive failed %d", __func__, ret);
+ memset(&buffer, 0, sizeof(buffer));
+ memset(planes, 0, sizeof(planes));
+ buffer.index = hl.current_buf;
+ buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ buffer.memory = V4L2_MEMORY_DMABUF;
+ buffer.flags = V4L2_BUF_FLAG_USE_SYNC;
+ buffer.reserved = layer.acquireFenceFd;
+ buffer.length = 1;
+ buffer.m.planes = planes;
+ buffer.m.planes[0].m.fd = h->fd;
+ if (exynos_v4l2_qbuf(hl.fd, &buffer) < 0) {
+ ALOGE("%s: layer%d: qbuf failed %d", __func__, hl.id, errno);
+ ret = -1;
goto err;
}
- layer.releaseFenceFd = src_cfg.releaseFenceFd;
+ layer.releaseFenceFd = buffer.reserved;
+
+ hl.queued_buf++;
+ hl.current_buf = (hl.current_buf + 1) % NUM_HDMI_BUFFERS;
+
+ if (!hl.streaming) {
+ if (exynos_v4l2_streamon(hl.fd, buffer.type) < 0) {
+ ALOGE("%s: layer%d: streamon failed %d", __func__, hl.id, errno);
+ ret = -1;
+ goto err;
+ }
+ hl.streaming = true;
+ }
err:
if (layer.acquireFenceFd >= 0)
close(layer.acquireFenceFd);
+
return ret;
}
@@ -948,7 +934,6 @@ static int exynos5_prepare_hdmi(exynos5_hwc_composer_device_1_t *pdev,
if (layer.compositionType == HWC_FRAMEBUFFER_TARGET) {
ALOGV("\tlayer %u: framebuffer target", i);
- dump_layer(&layer);
continue;
}
@@ -1359,6 +1344,11 @@ static int exynos5_set_hdmi(exynos5_hwc_composer_device_1_t *pdev,
for (size_t i = 0; i < contents->numHwLayers; i++) {
hwc_layer_1_t &layer = contents->hwLayers[i];
+ if (layer.flags & HWC_SKIP_LAYER) {
+ ALOGV("HDMI skipping layer %d", i);
+ continue;
+ }
+
if (layer.compositionType == HWC_FRAMEBUFFER_TARGET) {
if (!layer.handle)
continue;
@@ -1366,7 +1356,7 @@ static int exynos5_set_hdmi(exynos5_hwc_composer_device_1_t *pdev,
ALOGV("HDMI FB layer:");
dump_layer(&layer);
- hdmi_configure_fblayer(pdev, layer);
+ hdmi_output(pdev, pdev->hdmi_layers[0], layer);
}
}
@@ -1805,23 +1795,25 @@ static int exynos5_open(const struct hw_module_t *module, const char *name,
info.height, dev->ydpi / 1000.0, refreshRate);
dev->hdmi_mixer0 = open("/dev/v4l-subdev7", O_RDWR);
- if (dev->hdmi_layer0 < 0) {
+ if (dev->hdmi_mixer0 < 0) {
ALOGE("failed to open hdmi mixer0 subdev");
- ret = dev->hdmi_layer0;
+ ret = dev->hdmi_mixer0;
goto err_ioctl;
}
- dev->hdmi_layer0 = open("/dev/video16", O_RDWR);
- if (dev->hdmi_layer0 < 0) {
+ dev->hdmi_layers[0].id = 0;
+ dev->hdmi_layers[0].fd = open("/dev/video16", O_RDWR);
+ if (dev->hdmi_layers[0].fd < 0) {
ALOGE("failed to open hdmi layer0 device");
- ret = dev->hdmi_layer0;
+ ret = dev->hdmi_layers[0].fd;
goto err_mixer0;
}
- dev->hdmi_layer1 = open("/dev/video17", O_RDWR);
- if (dev->hdmi_layer1 < 0) {
+ dev->hdmi_layers[1].id = 1;
+ dev->hdmi_layers[1].fd = open("/dev/video17", O_RDWR);
+ if (dev->hdmi_layers[1].fd < 0) {
ALOGE("failed to open hdmi layer1 device");
- ret = dev->hdmi_layer1;
+ ret = dev->hdmi_layers[1].fd;
goto err_hdmi0;
}
@@ -1879,9 +1871,9 @@ err_vsync:
err_mixer0:
close(dev->hdmi_mixer0);
err_hdmi1:
- close(dev->hdmi_layer0);
+ close(dev->hdmi_layers[0].fd);
err_hdmi0:
- close(dev->hdmi_layer1);
+ close(dev->hdmi_layers[1].fd);
err_ioctl:
close(dev->fd);
err_open_fb:
@@ -1907,8 +1899,8 @@ static int exynos5_close(hw_device_t *device)
gralloc_close(dev->alloc_device);
close(dev->vsync_fd);
close(dev->hdmi_mixer0);
- close(dev->hdmi_layer0);
- close(dev->hdmi_layer1);
+ close(dev->hdmi_layers[0].fd);
+ close(dev->hdmi_layers[1].fd);
close(dev->fd);
return 0;
}