display: Add display metadata in buffer handle
Allocate extra space for metadata in buffer handles
Provide api to map this space in client process and set the metadata
Change-Id: I8bca8448670d4aa88d439320faf402dae30458f8
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index f79841c..7b2c1d8 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -27,6 +27,7 @@
#include "gpu.h"
#include "memalloc.h"
#include "alloc_controller.h"
+#include <qdMetaData.h>
using namespace gralloc;
@@ -137,37 +138,52 @@
data.pHandle = (unsigned int) pHandle;
err = mAllocCtrl->allocate(data, usage);
- if (usage & GRALLOC_USAGE_PRIVATE_UNSYNCHRONIZED) {
- flags |= private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED;
- }
+ if (!err) {
+ /* allocate memory for enhancement data */
+ alloc_data eData;
+ eData.fd = -1;
+ eData.base = 0;
+ eData.offset = 0;
+ eData.size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+ eData.pHandle = data.pHandle;
+ eData.align = getpagesize();
+ int eDataUsage = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
+ int eDataErr = mAllocCtrl->allocate(eData, eDataUsage);
+ ALOGE_IF(eDataErr, "gralloc failed for eDataErr=%s",
+ strerror(-eDataErr));
- if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY) {
- flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
- //The EXTERNAL_BLOCK flag is always an add-on
- if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_BLOCK) {
- flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_BLOCK;
- }if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_CC) {
- flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_CC;
+ if (usage & GRALLOC_USAGE_PRIVATE_UNSYNCHRONIZED) {
+ flags |= private_handle_t::PRIV_FLAGS_UNSYNCHRONIZED;
}
- }
- if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER ) {
- flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
- }
+ if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY) {
+ flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
+ //The EXTERNAL_BLOCK flag is always an add-on
+ if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_BLOCK) {
+ flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_BLOCK;
+ }
+ if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_CC) {
+ flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_CC;
+ }
+ }
- if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
- flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
- }
+ if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER ) {
+ flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
+ }
- if (usage & GRALLOC_USAGE_HW_CAMERA_READ) {
- flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
- }
+ if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
+ flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
+ }
- if (err == 0) {
+ if (usage & GRALLOC_USAGE_HW_CAMERA_READ) {
+ flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
+ }
+
flags |= data.allocType;
- private_handle_t* hnd = new private_handle_t(data.fd, size, flags,
- bufferType, format, width,
- height);
+ int eBaseAddr = int(eData.base) + eData.offset;
+ private_handle_t *hnd = new private_handle_t(data.fd, size, flags,
+ bufferType, format, width, height, eData.fd, eData.offset,
+ eBaseAddr);
hnd->offset = data.offset;
hnd->base = int(data.base) + data.offset;
@@ -175,6 +191,7 @@
}
ALOGE_IF(err, "gralloc failed err=%s", strerror(-err));
+
return err;
}
@@ -261,6 +278,13 @@
hnd->offset, hnd->fd);
if(err)
return err;
+ // free the metadata space
+ unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+ err = memalloc->free_buffer((void*)hnd->base_metadata,
+ (size_t) size, hnd->offset_metadata,
+ hnd->fd_metadata);
+ if (err)
+ return err;
}
// Release the genlock
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index 4f6445d..6ccc7e0 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -30,6 +30,9 @@
#include <cutils/log.h>
+#define ROUND_UP_PAGESIZE(x) ( (((unsigned long)(x)) + PAGE_SIZE-1) & \
+ (~(PAGE_SIZE-1)) )
+
enum {
/* gralloc usage bits indicating the type
* of allocation that should be used */
@@ -167,6 +170,7 @@
int fd;
// genlock handle to be dup'd by the binder
int genlockHandle;
+ int fd_metadata; // fd for the meta-data
// ints
int magic;
int flags;
@@ -174,6 +178,7 @@
int offset;
int bufferType;
int base;
+ int offset_metadata;
// The gpu address mapped into the mmu.
// If using ashmem, set to 0, they don't care
int gpuaddr;
@@ -183,19 +188,21 @@
int height;
// local fd of the genlock device.
int genlockPrivFd;
+ int base_metadata;
#ifdef __cplusplus
- static const int sNumInts = 12;
- static const int sNumFds = 2;
+ static const int sNumInts = 14;
+ static const int sNumFds = 3;
static const int sMagic = 'gmsm';
private_handle_t(int fd, int size, int flags, int bufferType,
- int format,int width, int height) :
- fd(fd), genlockHandle(-1), magic(sMagic),
- flags(flags), size(size), offset(0),
- bufferType(bufferType), base(0), gpuaddr(0),
- pid(0), format(format),
- width(width), height(height), genlockPrivFd(-1)
+ int format,int width, int height, int eFd = -1,
+ int eOffset = 0, int eBase = 0) :
+ fd(fd), genlockHandle(-1), fd_metadata(eFd), magic(sMagic),
+ flags(flags), size(size), offset(0), bufferType(bufferType),
+ base(0), offset_metadata(eOffset), gpuaddr(0), pid(getpid()),
+ format(format), width(width), height(height), genlockPrivFd(-1),
+ base_metadata(eBase)
{
version = sizeof(native_handle);
numInts = sNumInts;
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 3088ecc..176a84e 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -42,6 +42,7 @@
#include "gr.h"
#include "alloc_controller.h"
#include "memalloc.h"
+#include <qdMetaData.h>
using namespace gralloc;
/*****************************************************************************/
@@ -68,22 +69,27 @@
IMemAlloc* memalloc = getAllocator(hnd->flags) ;
int err = memalloc->map_buffer(&mappedAddress, size,
hnd->offset, hnd->fd);
- if(err) {
+ if(err || mappedAddress == MAP_FAILED) {
ALOGE("Could not mmap handle %p, fd=%d (%s)",
handle, hnd->fd, strerror(errno));
hnd->base = 0;
return -errno;
}
- if (mappedAddress == MAP_FAILED) {
- ALOGE("Could not mmap handle %p, fd=%d (%s)",
- handle, hnd->fd, strerror(errno));
- hnd->base = 0;
- return -errno;
- }
hnd->base = intptr_t(mappedAddress) + hnd->offset;
//LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
// hnd->fd, hnd->offset, hnd->size, mappedAddress);
+ mappedAddress = MAP_FAILED;
+ size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+ err = memalloc->map_buffer(&mappedAddress, size,
+ hnd->offset_metadata, hnd->fd_metadata);
+ if(err || mappedAddress == MAP_FAILED) {
+ ALOGE("Could not mmap handle %p, fd=%d (%s)",
+ handle, hnd->fd_metadata, strerror(errno));
+ hnd->base_metadata = 0;
+ return -errno;
+ }
+ hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata;
}
*vaddr = (void*)hnd->base;
return 0;
@@ -98,10 +104,17 @@
void* base = (void*)hnd->base;
size_t size = hnd->size;
IMemAlloc* memalloc = getAllocator(hnd->flags) ;
- if(memalloc != NULL)
+ if(memalloc != NULL) {
err = memalloc->unmap_buffer(base, size, hnd->offset);
- if (err) {
- ALOGE("Could not unmap memory at address %p", base);
+ if (err) {
+ ALOGE("Could not unmap memory at address %p", base);
+ }
+ base = (void*)hnd->base_metadata;
+ size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+ err = memalloc->unmap_buffer(base, size, hnd->offset_metadata);
+ if (err) {
+ ALOGE("Could not unmap memory at address %p", base);
+ }
}
}
hnd->base = 0;
@@ -277,6 +290,12 @@
hnd->size, hnd->offset, hnd->fd);
ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x, flags = 0x%x) err=%s\n",
hnd, hnd->offset, hnd->size, hnd->flags, strerror(errno));
+ unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+ err = memalloc->clean_buffer((void*)hnd->base_metadata, size,
+ hnd->offset_metadata, hnd->fd_metadata);
+ ALOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%lu, "
+ "flags = 0x%x) err=%s\n", hnd, hnd->offset_metadata, size,
+ hnd->flags, strerror(errno));
hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
}
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 4200be9..3bca539 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -19,6 +19,7 @@
#include "hwc_mdpcomp.h"
#include <sys/ioctl.h>
#include "external.h"
+#include "qdMetaData.h"
namespace qhwc {
@@ -96,11 +97,15 @@
void MDPComp::setVidInfo(hwc_layer_1_t *layer, ovutils::eMdpFlags &mdpFlags) {
private_handle_t *hnd = (private_handle_t *)layer->handle;
+ MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
if(isSecureBuffer(hnd)) {
ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
sSecuredVid = true;
}
+ if((metadata->operation & PP_PARAM_INTERLACED) && metadata->interlaced) {
+ ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_DEINTERLACE);
+ }
}
/*
diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp
index 48cb165..1784593 100644
--- a/libhwcomposer/hwc_video.cpp
+++ b/libhwcomposer/hwc_video.cpp
@@ -19,6 +19,7 @@
#include <overlay.h>
#include "hwc_video.h"
#include "hwc_utils.h"
+#include "qdMetaData.h"
namespace qhwc {
@@ -106,6 +107,11 @@
ovutils::OV_MDP_BLEND_FG_PREMULT);
}
+ MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
+ if ((metadata->operation & PP_PARAM_INTERLACED) && metadata->interlaced) {
+ ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_DEINTERLACE);
+ }
+
ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
if (ctx->listStats[dpy].numAppLayers == 1) {
isFgFlag = ovutils::IS_FG_SET;
diff --git a/libqdutils/Android.mk b/libqdutils/Android.mk
index ed8bed0..ecae273 100644
--- a/libqdutils/Android.mk
+++ b/libqdutils/Android.mk
@@ -12,3 +12,19 @@
idle_invalidator.cpp
include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_COPY_HEADERS_TO := qcom/display
+LOCAL_COPY_HEADERS := qdMetaData.h
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
+LOCAL_SHARED_LIBRARIES := liblog libcutils
+LOCAL_C_INCLUDES := $(common_includes)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
+LOCAL_SRC_FILES := qdMetaData.cpp
+LOCAL_CFLAGS := $(common_flags)
+LOCAL_CFLAGS += -DLOG_TAG=\"DisplayMetaData\"
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libqdMetaData
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
new file mode 100644
index 0000000..a53ba07
--- /dev/null
+++ b/libqdutils/qdMetaData.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <sys/mman.h>
+#include <cutils/log.h>
+#include <gralloc_priv.h>
+#include "qdMetaData.h"
+
+int setMetaData(private_handle_t *handle, DispParamType paramType,
+ void *param) {
+ if (!handle) {
+ ALOGE("%s: Private handle is null!", __func__);
+ return -1;
+ }
+ if (handle->fd_metadata == -1) {
+ ALOGE("%s: Bad fd for extra data!", __func__);
+ return -1;
+ }
+ unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+ void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
+ handle->fd_metadata, 0);
+ if (!base) {
+ ALOGE("%s: mmap() failed: Base addr is NULL!", __func__);
+ return -1;
+ }
+ MetaData_t *data = reinterpret_cast <MetaData_t *>(base);
+ data->operation |= paramType;
+ switch (paramType) {
+ case PP_PARAM_HSIC:
+ memcpy((void *)&data->hsicData, param, sizeof(HSICData_t));
+ break;
+ case PP_PARAM_SHARPNESS:
+ data->sharpness = *((int32_t *)param);
+ break;
+ case PP_PARAM_VID_INTFC:
+ data->video_interface = *((int32_t *)param);
+ break;
+ case PP_PARAM_INTERLACED:
+ data->interlaced = *((int32_t *)param);
+ break;
+ default:
+ ALOGE("Unknown paramType %d", paramType);
+ break;
+ }
+ if(munmap(base, size))
+ ALOGE("%s: failed to unmap ptr 0x%x, err %d", __func__, (int)base,
+ errno);
+ return 0;
+}
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
new file mode 100644
index 0000000..e60daed
--- /dev/null
+++ b/libqdutils/qdMetaData.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _QDMETADATA_H
+#define _QDMETADATA_H
+
+
+typedef struct {
+ int32_t hue;
+ float saturation;
+ int32_t intensity;
+ float contrast;
+} HSICData_t;
+
+typedef struct {
+ int32_t operation;
+ int32_t interlaced;
+ HSICData_t hsicData;
+ int32_t sharpness;
+ int32_t video_interface;
+} MetaData_t;
+
+typedef enum {
+ PP_PARAM_HSIC = 0x0001,
+ PP_PARAM_SHARPNESS = 0x0002,
+ PP_PARAM_INTERLACED = 0x0004,
+ PP_PARAM_VID_INTFC = 0x0008
+} DispParamType;
+
+int setMetaData(private_handle_t *handle, DispParamType paramType, void *param);
+
+#endif /* _QDMETADATA_H */
+