author | Pengcheng Chen <pengcheng.chen@amlogic.com> | 2016-12-26 11:26:01 (GMT) |
---|---|---|
committer | Pengcheng Chen <pengcheng.chen@amlogic.com> | 2017-01-06 05:23:33 (GMT) |
commit | 4fcdd6456d921911a6d1bd691bfdcd1153ed635d (patch) | |
tree | 0a3f887c5c73c7e7abcdd7f33b3659eeff22df25 | |
parent | cc84db0c1e001e32f3ad4214fafe00e34741462e (diff) | |
download | system-4fcdd6456d921911a6d1bd691bfdcd1153ed635d.zip system-4fcdd6456d921911a6d1bd691bfdcd1153ed635d.tar.gz system-4fcdd6456d921911a6d1bd691bfdcd1153ed635d.tar.bz2 |
PD#137623 ge2dlib:add ge2dlib interface
add ge2dlib interface and test code
Change-Id: Ib67d9f8162dee98439c22804f52c7fb02d96b877
Signed-off-by: Pengcheng Chen <pengcheng.chen@amlogic.com>
-rw-r--r-- | libge2d/Android.mk | 62 | ||||
-rw-r--r-- | libge2d/IONmem.c | 181 | ||||
-rw-r--r-- | libge2d/aml_ge2d.c | 239 | ||||
-rw-r--r-- | libge2d/ge2d_feature_test.c | 421 | ||||
-rw-r--r-- | libge2d/ge2d_load_test.c | 254 | ||||
-rw-r--r-- | libge2d/ge2d_port.c | 1224 | ||||
-rw-r--r-- | libge2d/include/IONmem.h | 49 | ||||
-rw-r--r-- | libge2d/include/aml_ge2d.h | 31 | ||||
-rw-r--r-- | libge2d/include/ge2d_com.h | 43 | ||||
-rw-r--r-- | libge2d/include/ge2d_port.h | 114 | ||||
-rw-r--r-- | libge2d/kernel-headers/linux/ge2d.h | 289 | ||||
-rw-r--r-- | libge2d/readme.txt | 80 |
12 files changed, 2987 insertions, 0 deletions
diff --git a/libge2d/Android.mk b/libge2d/Android.mk new file mode 100644 index 0000000..e862933 --- a/dev/null +++ b/libge2d/Android.mk @@ -0,0 +1,62 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES := ge2d_port.c +LOCAL_MODULE := libge2d +LOCAL_MODULE_TAGS := optional +LOCAL_SHARED_LIBRARIES := liblog +LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/kernel-headers +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include $(LOCAL_PATH)/kernel-headers +LOCAL_CFLAGS := -Werror +include $(BUILD_SHARED_LIBRARY) + + +include $(CLEAR_VARS) +LOCAL_PRELINK_MODULE:= false + +LOCAL_ARM_MODE := arm +LOCAL_MODULE_TAGS := ge2d_feature_test +LOCAL_SRC_FILES:= aml_ge2d.c IONmem.c ge2d_feature_test.c + +LOCAL_C_INCLUDES += $(LOCAL_PATH)/include \ + $(LOCAL_PATH)/kernel-headers \ + system/core/libion/include/ \ + system/core/libion/kernel-headers \ + system/core/include/ion + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libge2d \ + libion + +LOCAL_CFLAGS +=-g +LOCAL_CPPFLAGS := -g + +LOCAL_MODULE := ge2d_feature_test +include $(BUILD_EXECUTABLE) + + +include $(CLEAR_VARS) +LOCAL_PRELINK_MODULE:= false + + +LOCAL_ARM_MODE := arm +LOCAL_MODULE_TAGS := ge2d_load_test +LOCAL_SRC_FILES:= aml_ge2d.c IONmem.c ge2d_load_test.c + +LOCAL_C_INCLUDES += $(LOCAL_PATH)/include \ + $(LOCAL_PATH)/kernel-headers \ + system/core/libion/include/ \ + system/core/libion/kernel-headers \ + system/core/include/ion + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libge2d \ + libion + +LOCAL_CFLAGS +=-g +LOCAL_CPPFLAGS := -g + +LOCAL_MODULE := ge2d_load_test +include $(BUILD_EXECUTABLE) diff --git a/libge2d/IONmem.c b/libge2d/IONmem.c new file mode 100644 index 0000000..70c36f6 --- a/dev/null +++ b/libge2d/IONmem.c @@ -0,0 +1,181 @@ +#include <stdio.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <ion/ion.h> +#include "IONmem.h" + +static int cmem_fd = -2; +static int ref_count = 0; + +static int validate_init() +{ + switch (cmem_fd) { + case -3: + __E("CMEM_exit() already called, check stderr output for earlier " + "CMEM failure messages (possibly version mismatch).\n"); + + return 0; + + case -2: + __E("CMEM_init() not called, you must initialize CMEM before " + "making API calls.\n"); + + return 0; + + case -1: + __E("CMEM file descriptor -1 (failed 'open()'), ensure CMEMK " + "kernel module cmemk.ko has been installed with 'insmod'"); + + return 0; + + default: + return 1; + } +} + +int CMEM_init(void) +{ + int flags; + + __D("init: entered - ref_count %d, cmem_fd %d\n", ref_count, cmem_fd); + + if (cmem_fd >= 0) { + ref_count++; + __D("init: /dev/ion already opened, incremented ref_count %d\n", + ref_count); + return 0; + } + + cmem_fd = ion_open(); + + if (cmem_fd < 0) { + __E("init: Failed to open /dev/ion: '%s'\n", strerror(errno)); + return -1; + } + + ref_count++; + + __D("init: successfully opened /dev/ion...\n"); + + __D("init: exiting, returning success\n"); + + return 0; +} + + +unsigned long CMEM_alloc(size_t size, IONMEM_AllocParams *params) +{ + int ret = 0; + unsigned long PhyAdrr = 0; + struct meson_phys_data phy_data; + struct ion_custom_data custom_data; + + if (!validate_init()) { + return 0; + } + + ret = ion_alloc(cmem_fd, size, 0, ION_HEAP_CARVEOUT_MASK, 0, ¶ms->mIonHnd); + if (ret < 0) { + ion_close(cmem_fd); + __E("ion_alloc failed, errno=%d", errno); + cmem_fd = -1; + return -ENOMEM; + } + ret = ion_share(cmem_fd, params->mIonHnd, ¶ms->mImageFd); + if (ret < 0) { + __E("ion_share failed, errno=%d", errno); + ion_free(cmem_fd, params->mIonHnd); + ion_close(cmem_fd); + cmem_fd = -1; + return -EINVAL; + } + + phy_data.handle = params->mImageFd; + phy_data.phys_addr = 0; + phy_data.size = 0; + + custom_data.cmd = ION_IOC_MESON_PHYS_ADDR; + custom_data.arg = (unsigned long)&phy_data; + + ret = ioctl(cmem_fd, ION_IOC_CUSTOM, (unsigned long)&custom_data); + if (ret < 0) { + __D("ion custom ioctl %x failed with code %d: %s\n", + ION_IOC_MESON_PHYS_ADDR, ret, strerror(errno)); + } else { + PhyAdrr = phy_data.phys_addr; + } + __D("allocate ion buffer for capture, ret=%d, bytes=%d, PysAdrr=%ld .\n", + ret, size, PhyAdrr); + return PhyAdrr; +} + +#if 0 +void* CMEM_getUsrPtr(unsigned long PhyAdr, int size) +{ + void *userp = NULL; + /* Map the physical address to user space */ + userp = mmap(0, // Preferred start address + size, // Length to be mapped + PROT_WRITE | PROT_READ, // Read and write access + MAP_SHARED, // Shared memory + cmem_fd, // File descriptor + PhyAdr); // The byte offset from fd + + if (userp == MAP_FAILED) { + __E("registerAlloc: Failed to mmap buffer at physical address %#lx\n", + PhyAdr); + return NULL; + } + __D("mmap succeeded, returning virt buffer %p\n", userp); + + return userp; +} +#endif + +int CMEM_free(IONMEM_AllocParams *params) +{ + if (!validate_init()) { + return -1; + } + __D("CMEM_free,mIonHnd=%x free\n", params->mIonHnd); + + ion_free(cmem_fd, params->mIonHnd); + + return 0; +} + + +int CMEM_exit(void) +{ + int result = 0; + + __D("exit: entered - ref_count %d, cmem_fd %d\n", ref_count, cmem_fd); + + if (!validate_init()) { + return -1; + } + + __D("exit: decrementing ref_count\n"); + + ref_count--; + if (ref_count == 0) { + result = ion_close(cmem_fd); + + __D("exit: ref_count == 0, closed /dev/ion (%s)\n", + result == -1 ? strerror(errno) : "succeeded"); + + /* setting -3 allows to distinguish CMEM exit from CMEM failed */ + cmem_fd = -3; + } + + __D("exit: exiting, returning %d\n", result); + + return result; +} + diff --git a/libge2d/aml_ge2d.c b/libge2d/aml_ge2d.c new file mode 100644 index 0000000..2857fe3 --- a/dev/null +++ b/libge2d/aml_ge2d.c @@ -0,0 +1,239 @@ +#include <stdio.h> +#include <unistd.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <string.h> +#include <malloc.h> +#include "ge2d_port.h" +#include "ge2d_com.h" +#include <IONmem.h> +#include "aml_ge2d.h" + + +IONMEM_AllocParams cmemParm_src; +IONMEM_AllocParams cmemParm_src2; +IONMEM_AllocParams cmemParm_dst; + +#define CANVAS_ALIGNED(x) (((x) + 31) & ~31) + +aml_ge2d_t amlge2d; +static int fd_ge2d = -1; + +static void fill_data(buffer_info_t *pinfo,unsigned int color) +{ + unsigned int i = 0; + memset(pinfo->vaddr,0x00,amlge2d.src_size); + for (i=0;i<amlge2d.src_size;) { + pinfo->vaddr[i] = color & 0xff; + pinfo->vaddr[i+1] = (color & 0xff00)>>8; + pinfo->vaddr[i+2] = (color & 0xff0000)>>16; + pinfo->vaddr[i+3] = (color & 0xff000000)>>24; + i+=4; + } +} +int aml_ge2d_init(void) +{ + int ret = -1; + fd_ge2d = ge2d_open(); + if (fd_ge2d < 0) + return ge2d_fail; + ret = CMEM_init(); + if (ret < 0) + return ge2d_fail; + return ge2d_success; +} + + +void aml_ge2d_exit(void) +{ + if (fd_ge2d >= 0) + ge2d_close(fd_ge2d); + CMEM_exit(); +} + + + +void aml_ge2d_mem_free(aml_ge2d_info_t *pge2dinfo) +{ + if (pge2dinfo->src_info[0].paddr) + CMEM_free(&cmemParm_src); + if (pge2dinfo->src_info[1].paddr) + CMEM_free(&cmemParm_src2); + if (pge2dinfo->dst_info.paddr) + CMEM_free(&cmemParm_dst); + + if (pge2dinfo->src_info[0].vaddr) + munmap(pge2dinfo->src_info[0].vaddr, amlge2d.src_size); + if (pge2dinfo->src_info[1].vaddr) + munmap(pge2dinfo->src_info[1].vaddr, amlge2d.src2_size); + if (pge2dinfo->dst_info.vaddr) + munmap(pge2dinfo->dst_info.vaddr, amlge2d.dst_size); + + D_GE2D("aml_ge2d_mem_free!\n"); +} + +int aml_ge2d_mem_alloc(aml_ge2d_info_t *pge2dinfo) +{ + int ret = -1; + unsigned int input_image_width = 0, input2_image_width = 0, output_image_width = 0; + unsigned int nbytes = 0; + + if (GE2D_CANVAS_ALLOC == pge2dinfo->src_info[0].memtype) { + input_image_width = pge2dinfo->src_info[0].canvas_w; + if ((pge2dinfo->src_info[0].format == PIXEL_FORMAT_RGBA_8888) || + (pge2dinfo->src_info[0].format == PIXEL_FORMAT_BGRA_8888) || + (pge2dinfo->src_info[0].format == PIXEL_FORMAT_RGBX_8888)) + amlge2d.src_size = CANVAS_ALIGNED(input_image_width * pge2dinfo->src_info[0].canvas_h * 4); + else if (pge2dinfo->src_info[0].format == PIXEL_FORMAT_RGB_565) + amlge2d.src_size = CANVAS_ALIGNED(input_image_width * pge2dinfo->src_info[0].canvas_h * 2); + else if (pge2dinfo->src_info[0].format == PIXEL_FORMAT_RGB_888) + amlge2d.src_size = CANVAS_ALIGNED(input_image_width * pge2dinfo->src_info[0].canvas_h * 4/3); + else if ((pge2dinfo->src_info[0].format == PIXEL_FORMAT_YCrCb_420_SP) || + (pge2dinfo->src_info[0].format == PIXEL_FORMAT_YV12)) + amlge2d.src_size = CANVAS_ALIGNED(input_image_width * pge2dinfo->src_info[0].canvas_h * 3 / 2); + else if ((pge2dinfo->src_info[0].format == PIXEL_FORMAT_YCbCr_422_SP) || + (pge2dinfo->src_info[0].format == PIXEL_FORMAT_YCbCr_422_I)) + amlge2d.src_size = CANVAS_ALIGNED(input_image_width * pge2dinfo->src_info[0].canvas_h * 2); + else if (pge2dinfo->src_info[0].format == PIXEL_FORMAT_Y8) + amlge2d.src_size = CANVAS_ALIGNED(input_image_width * pge2dinfo->src_info[0].canvas_h); + else { + E_GE2D("format not support now\n"); + goto exit; + } + } + + if (GE2D_CANVAS_ALLOC == pge2dinfo->src_info[1].memtype) { + input2_image_width = pge2dinfo->src_info[1].canvas_w; + if ((pge2dinfo->src_info[1].format == PIXEL_FORMAT_RGBA_8888) || + (pge2dinfo->src_info[1].format == PIXEL_FORMAT_BGRA_8888) || + (pge2dinfo->src_info[1].format == PIXEL_FORMAT_RGBX_8888)) + amlge2d.src2_size = CANVAS_ALIGNED(input2_image_width * pge2dinfo->src_info[1].canvas_h * 4); + else if (pge2dinfo->src_info[1].format == PIXEL_FORMAT_RGB_565) + amlge2d.src2_size = CANVAS_ALIGNED(input2_image_width * pge2dinfo->src_info[1].canvas_h * 2); + else if (pge2dinfo->src_info[1].format == PIXEL_FORMAT_RGB_888) + amlge2d.src2_size = CANVAS_ALIGNED(input2_image_width * pge2dinfo->src_info[1].canvas_h * 4/3); + else if ((pge2dinfo->src_info[1].format == PIXEL_FORMAT_YCrCb_420_SP) || + (pge2dinfo->src_info[1].format == PIXEL_FORMAT_YV12)) + amlge2d.src2_size = CANVAS_ALIGNED(input2_image_width * pge2dinfo->src_info[1].canvas_h * 3 / 2); + else if ((pge2dinfo->src_info[1].format == PIXEL_FORMAT_YCbCr_422_SP) || + (pge2dinfo->src_info[1].format == PIXEL_FORMAT_YCbCr_422_I)) + amlge2d.src2_size = CANVAS_ALIGNED(input2_image_width * pge2dinfo->src_info[1].canvas_h * 2); + else if (pge2dinfo->src_info[1].format == PIXEL_FORMAT_Y8) + amlge2d.src2_size = CANVAS_ALIGNED(input2_image_width * pge2dinfo->src_info[1].canvas_h); + else { + E_GE2D("format not support now\n"); + goto exit; + } + } + + if (GE2D_CANVAS_ALLOC == pge2dinfo->dst_info.memtype) { + output_image_width = pge2dinfo->dst_info.canvas_w; + if ((pge2dinfo->dst_info.format == PIXEL_FORMAT_RGBA_8888) || + (pge2dinfo->dst_info.format == PIXEL_FORMAT_BGRA_8888) || + (pge2dinfo->dst_info.format == PIXEL_FORMAT_RGBX_8888)) + amlge2d.dst_size = CANVAS_ALIGNED(output_image_width * pge2dinfo->dst_info.canvas_h * 4); + else if (pge2dinfo->dst_info.format == PIXEL_FORMAT_RGB_565) + amlge2d.dst_size = CANVAS_ALIGNED(output_image_width * pge2dinfo->dst_info.canvas_h * 2); + else if (pge2dinfo->dst_info.format == PIXEL_FORMAT_RGB_888) + amlge2d.dst_size = CANVAS_ALIGNED(output_image_width * pge2dinfo->dst_info.canvas_h * 4/3); + else if ((pge2dinfo->dst_info.format == PIXEL_FORMAT_YCrCb_420_SP) || + (pge2dinfo->dst_info.format == PIXEL_FORMAT_YV12)) + amlge2d.dst_size = CANVAS_ALIGNED(output_image_width * pge2dinfo->dst_info.canvas_h * 3 / 2); + else if ((pge2dinfo->dst_info.format == PIXEL_FORMAT_YCbCr_422_SP) || + (pge2dinfo->dst_info.format == PIXEL_FORMAT_YCbCr_422_I)) + amlge2d.dst_size = CANVAS_ALIGNED(output_image_width * pge2dinfo->dst_info.canvas_h * 2); + else if (pge2dinfo->dst_info.format == PIXEL_FORMAT_Y8) + amlge2d.dst_size = CANVAS_ALIGNED(output_image_width * pge2dinfo->dst_info.canvas_h); + + else { + E_GE2D("format not support now\n"); + goto exit; + } + } + if (amlge2d.src_size) { + pge2dinfo->src_info[0].paddr = (unsigned long)CMEM_alloc(amlge2d.src_size, &cmemParm_src); + if (!pge2dinfo->src_info[0].paddr) { + E_GE2D("Not enough memory\n"); + if (pge2dinfo->src_info[0].paddr) + CMEM_free(&cmemParm_src); + return ge2d_fail; + } + pge2dinfo->src_info[0].vaddr = (char*)mmap( NULL, amlge2d.src_size, + PROT_READ | PROT_WRITE, MAP_SHARED, cmemParm_src.mImageFd, 0); + + if (!pge2dinfo->src_info[0].vaddr) { + E_GE2D("mmap failed,Not enough memory\n"); + goto exit; + } + fill_data(&pge2dinfo->src_info[0],0x00000000); + } + + if (amlge2d.src2_size) { + pge2dinfo->src_info[1].paddr = (unsigned long)CMEM_alloc(amlge2d.src2_size, &cmemParm_src2); + if (!pge2dinfo->src_info[1].paddr) { + E_GE2D("Not enough memory\n"); + if (pge2dinfo->src_info[1].paddr) + CMEM_free(&cmemParm_src2); + return ge2d_fail; + } + pge2dinfo->src_info[1].vaddr = (char*)mmap( NULL, amlge2d.src2_size, + PROT_READ | PROT_WRITE, MAP_SHARED, cmemParm_src2.mImageFd, 0); + if (!pge2dinfo->src_info[1].vaddr) { + E_GE2D("mmap failed,Not enough memory\n"); + goto exit; + } + } + + + if (amlge2d.dst_size) { + pge2dinfo->dst_info.paddr = (unsigned long)CMEM_alloc(amlge2d.dst_size, &cmemParm_dst); + if (!pge2dinfo->dst_info.paddr) { + E_GE2D("Not enough memory\n"); + goto exit; + } + pge2dinfo->dst_info.vaddr = (char*)mmap( NULL, amlge2d.dst_size, + PROT_READ | PROT_WRITE, MAP_SHARED, cmemParm_dst.mImageFd, 0); + + if (!pge2dinfo->dst_info.vaddr) { + E_GE2D("mmap failed,Not enough memory\n"); + goto exit; + } + } + + D_GE2D("aml_ge2d_mem_alloc: src_info[0].w=%d,src_info[1].w=%d,dst_info.w=%d\n", + input_image_width,input2_image_width,output_image_width); + D_GE2D("aml_ge2d_mem_alloc: src_info[0].h=%d,dst_info.h=%d\n", + pge2dinfo->src_info[0].canvas_h,pge2dinfo->dst_info.canvas_h); + D_GE2D("aml_ge2d_mem_alloc: src_info[0].format=%d,dst_info.format=%d\n", + pge2dinfo->src_info[0].format,pge2dinfo->dst_info.format); + D_GE2D("src_info[0].size=%d,src_info[1].size=%d,dst_info.size=%d\n", + amlge2d.src_size,amlge2d.src2_size,amlge2d.dst_size); + return ge2d_success; +exit: + if (pge2dinfo->src_info[0].paddr) + CMEM_free(&cmemParm_src); + if (pge2dinfo->src_info[1].paddr) + CMEM_free(&cmemParm_src2); + + if (pge2dinfo->src_info[0].vaddr) + munmap(pge2dinfo->src_info[0].vaddr, amlge2d.src_size); + if (pge2dinfo->src_info[1].vaddr) + munmap(pge2dinfo->src_info[1].vaddr, amlge2d.src2_size); + if (pge2dinfo->dst_info.paddr) + CMEM_free(&cmemParm_dst); + if (pge2dinfo->dst_info.vaddr) + munmap(pge2dinfo->dst_info.vaddr, amlge2d.dst_size); + return ret; +} + + +int aml_ge2d_process(aml_ge2d_info_t *pge2dinfo) +{ + int ret = -1; + if (fd_ge2d > 0) + ret = ge2d_process(fd_ge2d,pge2dinfo); + return ret; +} + diff --git a/libge2d/ge2d_feature_test.c b/libge2d/ge2d_feature_test.c new file mode 100644 index 0000000..23a197d --- a/dev/null +++ b/libge2d/ge2d_feature_test.c @@ -0,0 +1,421 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <malloc.h> +#include <string.h> +#include <sys/time.h> /* for gettimeofday() */ +#include "ge2d_port.h" +#include "ge2d_com.h" +#include "aml_ge2d.h" + + +/* #define FILE_DATA */ +#define SRC1_FILE_NAME ("/system/bin/infocus.yuv") +#define SRC_FILE_NAME ("/system/bin/fb0.rgb32") +#define DST_FILE_NAME ("/system/bin/out1.rgb32") + +static int SX_SRC1 = 1920; +static int SY_SRC1 = 1080; +static int SX_SRC2 = 1920; +static int SY_SRC2 = 1080; +static int SX_DST = 1920; +static int SY_DST = 1080; + +static int DEMOTIME = 3000; /* milliseconds */ +static int SRC1_PIXFORMAT = PIXEL_FORMAT_RGBA_8888; +static int SRC2_PIXFORMAT = PIXEL_FORMAT_YCrCb_420_SP; +static int DST_PIXFORMAT = PIXEL_FORMAT_RGBA_8888; + +static int OP = AML_GE2D_STRETCHBLIT; + +extern aml_ge2d_t amlge2d; + +static void set_ge2dinfo(aml_ge2d_info_t *pge2dinfo) +{ + pge2dinfo->src_info[0].memtype = GE2D_CANVAS_ALLOC; + pge2dinfo->src_info[0].canvas_w = SX_SRC1; + pge2dinfo->src_info[0].canvas_h = SY_SRC1; + pge2dinfo->src_info[0].format = SRC1_PIXFORMAT; + pge2dinfo->src_info[1].memtype = GE2D_CANVAS_ALLOC; + pge2dinfo->src_info[1].canvas_w = SX_SRC2; + pge2dinfo->src_info[1].canvas_h = SY_SRC2; + pge2dinfo->src_info[1].format = SRC2_PIXFORMAT; + + pge2dinfo->dst_info.memtype = GE2D_CANVAS_ALLOC; + pge2dinfo->dst_info.canvas_w = SX_DST; + pge2dinfo->dst_info.canvas_h = SY_DST; + pge2dinfo->dst_info.format = DST_PIXFORMAT; + pge2dinfo->dst_info.rotation = GE2D_ROTATION_0; + pge2dinfo->offset = 0; + pge2dinfo->ge2d_op = OP; + pge2dinfo->blend_mode = BLEND_MODE_PREMULTIPLIED; +} + +static void print_usage(void) +{ + int i; + printf ("Usage: ge2d_feature_test [options]\n\n"); + printf ("Options:\n\n"); + printf (" --op <0:fillrect, 1:blend, 2:strechblit, 3:blit> ge2d operation case.\n"); + printf (" --duration <milliseconds> Duration of each ge2d operation case.\n"); + printf (" --size <width>x<height> Set ge2d size.\n"); + printf (" --pixelformat <0:ARGB, 1:ABGR, 2:NV21> Set ge2d pixelformat.\n"); + printf (" --help Print usage information.\n"); + printf ("\n"); +} + +static int parse_command_line(int argc, char *argv[]) +{ + int i; + /* parse command line */ + for (i = 1; i < argc; i++) { + if (strncmp (argv[i], "--", 2) == 0) { + if (strcmp (argv[i] + 2, "help") == 0) { + print_usage(); + return ge2d_fail; + } + else if (strcmp (argv[i] + 2, "op") == 0 && ++i < argc && + sscanf (argv[i], "%d", &OP) == 1) { + continue; + } + } + } + return ge2d_success; +} + + +int aml_read_file_src1(const char* url , aml_ge2d_info_t *pge2dinfo) +{ + int fd = -1; + int length = 0; + int read_num = 0; + if (amlge2d.src_size == 0) + return 0; + + fd = open(url,O_RDONLY ); + if (fd < 0) { + E_GE2D("read source file:%s open error\n",url); + return ge2d_fail; + } + + amlge2d.src_data = (char*)malloc(amlge2d.src_size); + if (!amlge2d.src_data) { + E_GE2D("malloc for src_data failed\n"); + return ge2d_fail; + } + + read_num = read(fd,amlge2d.src_data,amlge2d.src_size); + if (read_num <= 0) { + E_GE2D("read file read_num=%d error\n",read_num); + return ge2d_fail; + } + + memcpy(pge2dinfo->src_info[0].vaddr, amlge2d.src_data, amlge2d.src_size); + close(fd); + return ge2d_success; +} + +int aml_read_file_src2(const char* url , aml_ge2d_info_t *pge2dinfo) +{ + int fd = -1; + int length = 0; + int read_num = 0; + if (amlge2d.src2_size == 0) + return 0; + + fd = open(url,O_RDONLY ); + if (fd < 0) { + E_GE2D("read source file:%s open error\n",url); + return ge2d_fail; + } + + amlge2d.src2_data = (char*)malloc(amlge2d.src2_size); + if (!amlge2d.src2_data) { + E_GE2D("malloc for src_data failed\n"); + return ge2d_fail; + } + + read_num = read(fd,amlge2d.src2_data,amlge2d.src2_size); + if (read_num <= 0) { + E_GE2D("read file read_num=%d error\n",read_num); + return ge2d_fail; + } + + memcpy(pge2dinfo->src_info[1].vaddr, amlge2d.src2_data, amlge2d.src2_size); + close(fd); + return ge2d_success; +} + +int aml_write_file(const char* url , aml_ge2d_info_t *pge2dinfo) +{ + int fd = -1; + int length = 0; + int write_num = 0; + if (amlge2d.dst_size == 0) + return 0; + if ((GE2D_CANVAS_OSD0 == pge2dinfo->dst_info.memtype) + || (GE2D_CANVAS_OSD1 == pge2dinfo->dst_info.memtype)) + return 0; + + fd = open(url,O_RDWR | O_CREAT,0660); + if (fd < 0) { + E_GE2D("write file:%s open error\n",url); + return ge2d_fail; + } + + amlge2d.dst_data = (char*)malloc(amlge2d.dst_size); + if (!amlge2d.dst_data) { + E_GE2D("malloc for dst_data failed\n"); + return ge2d_fail; + } + + memcpy(amlge2d.dst_data,pge2dinfo->dst_info.vaddr,amlge2d.dst_size); + + write_num = write(fd,amlge2d.dst_data,amlge2d.dst_size); + if (write_num <= 0) { + E_GE2D("read file read_num=%d error\n",write_num); + } + close(fd); + return ge2d_success; +} + + +static int do_fill_rectangle(aml_ge2d_info_t *pge2dinfo) +{ + int ret = -1; + char code; + printf("do_fill_rectangle test case:\n"); + pge2dinfo->src_info[0].memtype = GE2D_CANVAS_ALLOC; + pge2dinfo->dst_info.memtype = GE2D_CANVAS_OSD0; + pge2dinfo->src_info[0].canvas_w = SX_DST; + pge2dinfo->src_info[0].canvas_h = SY_DST; + pge2dinfo->src_info[0].format = SRC1_PIXFORMAT; + pge2dinfo->dst_info.canvas_w = 0; + pge2dinfo->dst_info.canvas_h = 0; + pge2dinfo->dst_info.format = 0; + #if 0 + int x,y,w,h; + printf("please input fill color:[RGBA]\n"); + scanf("%x",&pge2dinfo->color); + printf("please input fill rect:x,y,w,h]\n"); + scanf("%d,%d,%d,%d",&x,&y,&w,&h); + if ((x > SX)|| (x > SY) || (w > SX) || (h > SY)) + E_GE2D("do_fill_rectangle:input parameter error!\n"); + + pge2dinfo->dst_info.rect.x = x; + pge2dinfo->dst_info.rect.y = y; + pge2dinfo->dst_info.rect.w = w; + pge2dinfo->dst_info.rect.h = h; + #else + pge2dinfo->color = 0xffffffff; + pge2dinfo->dst_info.rect.x = 0; + pge2dinfo->dst_info.rect.y = 0; + pge2dinfo->dst_info.rect.w = pge2dinfo->src_info[0].canvas_w/2; + pge2dinfo->dst_info.rect.h = pge2dinfo->src_info[0].canvas_h/2; + #endif + ret = aml_ge2d_process(pge2dinfo); + sleep(5); + + printf("please enter any key do rotation test[90]\n"); + code = getc(stdin); + pge2dinfo->dst_info.rotation = GE2D_ROTATION_180; + ret = aml_ge2d_process(pge2dinfo); + + return ret; +} + + +static int do_blend(aml_ge2d_info_t *pge2dinfo) +{ + int ret = -1; + char code = 0; + printf("do_blend test case:\n"); + pge2dinfo->src_info[0].memtype = GE2D_CANVAS_ALLOC; + pge2dinfo->src_info[1].memtype = GE2D_CANVAS_ALLOC; + pge2dinfo->dst_info.memtype = GE2D_CANVAS_ALLOC; + pge2dinfo->src_info[0].canvas_w = SX_SRC1; + pge2dinfo->src_info[0].canvas_h = SY_SRC1; + pge2dinfo->src_info[0].format = SRC1_PIXFORMAT; + pge2dinfo->src_info[1].canvas_w = SX_SRC2; + pge2dinfo->src_info[1].canvas_h = SY_SRC2; + pge2dinfo->src_info[1].format = SRC2_PIXFORMAT; + pge2dinfo->dst_info.canvas_w = SX_DST; + pge2dinfo->dst_info.canvas_h = SY_DST; + pge2dinfo->dst_info.format = DST_PIXFORMAT; + + pge2dinfo->src_info[0].rect.x = 0; + pge2dinfo->src_info[0].rect.y = 0; + pge2dinfo->src_info[0].rect.w = pge2dinfo->src_info[0].canvas_w; + pge2dinfo->src_info[0].rect.h = pge2dinfo->src_info[0].canvas_h; + pge2dinfo->src_info[1].rect.x = 0; + pge2dinfo->src_info[1].rect.y = 0; + pge2dinfo->src_info[1].rect.w = pge2dinfo->src_info[0].canvas_w; + pge2dinfo->src_info[1].rect.h = pge2dinfo->src_info[0].canvas_h; + pge2dinfo->dst_info.rect.x = 0; + pge2dinfo->dst_info.rect.y = 0; + pge2dinfo->dst_info.rect.w = pge2dinfo->src_info[0].canvas_w; + pge2dinfo->dst_info.rect.h = pge2dinfo->src_info[0].canvas_h; + pge2dinfo->dst_info.rotation = GE2D_ROTATION_0; + ret = aml_ge2d_process(pge2dinfo); + + sleep(5); + printf("please enter any key do rotation test[90]\n"); + code = getc(stdin); + pge2dinfo->dst_info.rotation = GE2D_ROTATION_90; + pge2dinfo->dst_info.rect.w = pge2dinfo->src_info[0].canvas_w/2; + pge2dinfo->dst_info.rect.h = pge2dinfo->src_info[0].canvas_h/2; + ret = aml_ge2d_process(pge2dinfo); + return ret; +} + + +static int do_strechblit(aml_ge2d_info_t *pge2dinfo) +{ + int ret = -1; + char code = 0; + printf("do_strechblit test case:\n"); + pge2dinfo->src_info[0].memtype = GE2D_CANVAS_ALLOC; + pge2dinfo->dst_info.memtype = GE2D_CANVAS_OSD0; + pge2dinfo->src_info[0].canvas_w = SX_SRC1; + pge2dinfo->src_info[0].canvas_h = SY_SRC1; + pge2dinfo->src_info[0].format = SRC1_PIXFORMAT; + pge2dinfo->dst_info.canvas_w = SX_DST; + pge2dinfo->dst_info.canvas_h = SY_DST; + pge2dinfo->dst_info.format = DST_PIXFORMAT; + + pge2dinfo->src_info[0].rect.x = 0; + pge2dinfo->src_info[0].rect.y = 0; + pge2dinfo->src_info[0].rect.w = SX_SRC1; + pge2dinfo->src_info[0].rect.h = SY_SRC1; + pge2dinfo->dst_info.rect.x = 0; + pge2dinfo->dst_info.rect.y = 0; + pge2dinfo->dst_info.rect.w = SX_DST; + pge2dinfo->dst_info.rect.h = SY_DST; + pge2dinfo->dst_info.rotation = GE2D_ROTATION_0; + ret = aml_ge2d_process(pge2dinfo); + sleep(5); + + printf("please enter any key do rotation test[90]\n"); + code = getc(stdin); + pge2dinfo->dst_info.rotation = GE2D_ROTATION_90; + ret = aml_ge2d_process(pge2dinfo); + + return ret; + +} + +static int do_blit(aml_ge2d_info_t *pge2dinfo) +{ + int ret = -1; + char code = 0; + printf("do_blit test case:\n"); + pge2dinfo->src_info[0].memtype = GE2D_CANVAS_ALLOC; + pge2dinfo->dst_info.memtype = GE2D_CANVAS_ALLOC; + pge2dinfo->src_info[0].canvas_w = SX_SRC1; + pge2dinfo->src_info[0].canvas_h = SY_SRC1; + pge2dinfo->src_info[0].format = SRC1_PIXFORMAT; + pge2dinfo->dst_info.canvas_w = SX_DST; + pge2dinfo->dst_info.canvas_h = SY_DST; + pge2dinfo->dst_info.format = DST_PIXFORMAT; + + pge2dinfo->src_info[0].rect.x = 0; + pge2dinfo->src_info[0].rect.y = 0; + pge2dinfo->src_info[0].rect.w = pge2dinfo->src_info[0].canvas_w; + pge2dinfo->src_info[0].rect.h = pge2dinfo->src_info[0].canvas_h; + pge2dinfo->dst_info.rect.x = 0; + pge2dinfo->dst_info.rect.y = 0; + + pge2dinfo->dst_info.rotation = GE2D_ROTATION_0; + ret = aml_ge2d_process(pge2dinfo); + sleep(5); + + printf("please enter any key do rotation test[90]\n"); + code = getc(stdin); + pge2dinfo->dst_info.rotation = GE2D_ROTATION_90; + pge2dinfo->src_info[0].rect.x = 0; + pge2dinfo->src_info[0].rect.y = 0; + pge2dinfo->src_info[0].rect.w = pge2dinfo->src_info[0].canvas_w; + pge2dinfo->src_info[0].rect.h = pge2dinfo->src_info[0].canvas_h; + pge2dinfo->dst_info.rect.x = 0; + pge2dinfo->dst_info.rect.y = 0; + + ret = aml_ge2d_process(pge2dinfo); + + return ret; +} + +int main(int argc, char **argv) +{ + int ret = -1; + int i = 0; + unsigned long stime; + aml_ge2d_info_t ge2dinfo; + memset(&amlge2d,0x0,sizeof(aml_ge2d_t)); + amlge2d.pge2d_info = &ge2dinfo; + memset(&ge2dinfo, 0, sizeof(aml_ge2d_info_t)); + memset(&(ge2dinfo.src_info[0]), 0, sizeof(buffer_info_t)); + memset(&(ge2dinfo.src_info[1]), 0, sizeof(buffer_info_t)); + memset(&(ge2dinfo.dst_info), 0, sizeof(buffer_info_t)); + ret = parse_command_line(argc,argv); + if (ret == ge2d_fail) + return ge2d_success; + + set_ge2dinfo(&ge2dinfo); + + ret = aml_ge2d_init(); + if (ret < 0) + return ge2d_fail; + + ret = aml_ge2d_mem_alloc(&ge2dinfo); + if (ret < 0) + goto exit; + + + ret = aml_read_file_src1(SRC_FILE_NAME,&ge2dinfo); + if (ret < 0) + goto exit; + + ret = aml_read_file_src2(SRC1_FILE_NAME,&ge2dinfo); + if (ret < 0) + goto exit; + + switch (ge2dinfo.ge2d_op) + { + case AML_GE2D_FILLRECTANGLE: + do_fill_rectangle(&ge2dinfo); + break; + case AML_GE2D_BLEND: + do_blend(&ge2dinfo); + break; + case AML_GE2D_STRETCHBLIT: + do_strechblit(&ge2dinfo); + break; + case AML_GE2D_BLIT: + do_blit(&ge2dinfo); + break; + default: + E_GE2D("not support ge2d op,exit test!\n"); + break; + } + + aml_write_file(DST_FILE_NAME,&ge2dinfo); + +exit: + if (amlge2d.src_data) { + free(amlge2d.src_data); + amlge2d.src_data = NULL; + } + if (amlge2d.src2_data) { + free(amlge2d.src2_data); + amlge2d.src2_data = NULL; + } + if (amlge2d.dst_data) { + free(amlge2d.dst_data); + amlge2d.dst_data = NULL; + } + aml_ge2d_mem_free(&ge2dinfo); + aml_ge2d_exit(); + printf("ge2d feature_test exit!!!\n"); + return ge2d_success; +} diff --git a/libge2d/ge2d_load_test.c b/libge2d/ge2d_load_test.c new file mode 100644 index 0000000..e3baec7 --- a/dev/null +++ b/libge2d/ge2d_load_test.c @@ -0,0 +1,254 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <malloc.h> +#include <string.h> +#include <sys/time.h> +#include "ge2d_port.h" +#include "ge2d_com.h" +#include "aml_ge2d.h" + + +/* #define FILE_DATA */ +#define SRC_FILE_NAME ("/system/bin/fb0.dump") + +static int SX = 1920; +static int SY = 1080; +static int DEMOTIME = 3000; /* milliseconds */ +static int PIXFORMAT = PIXEL_FORMAT_RGBA_8888; +static int OP = AML_GE2D_STRETCHBLIT; + +extern aml_ge2d_t amlge2d; + +static void set_ge2dinfo(aml_ge2d_info_t *pge2dinfo) +{ + pge2dinfo->src_info[0].memtype = GE2D_CANVAS_ALLOC; + pge2dinfo->src_info[0].canvas_w = SX; + pge2dinfo->src_info[0].canvas_h = SY; + pge2dinfo->src_info[0].format = PIXFORMAT; + + pge2dinfo->src_info[1].memtype = GE2D_CANVAS_OSD0; + pge2dinfo->src_info[1].canvas_w = SX; + pge2dinfo->src_info[1].canvas_h = SY; + pge2dinfo->src_info[1].format = PIXFORMAT; + + pge2dinfo->dst_info.memtype = GE2D_CANVAS_OSD0; + pge2dinfo->dst_info.canvas_w = SX; + pge2dinfo->dst_info.canvas_h = SY; + pge2dinfo->dst_info.format = PIXFORMAT; + pge2dinfo->dst_info.rotation = 0; + pge2dinfo->offset = 0; + pge2dinfo->ge2d_op = OP; + pge2dinfo->blend_mode = BLEND_MODE_PREMULTIPLIED; + D_GE2D("OP=%d,w=%d,h=%d,format=%x,duration=%d \n",OP,SX,SY,PIXFORMAT,DEMOTIME); +} + +static void print_usage(void) +{ + int i; + printf ("Usage: ge2d_load_test [options]\n\n"); + printf ("Options:\n\n"); + printf (" --op <0:fillrect, 1:blend, 2:strechblit, 3:blit> ge2d operation case.\n"); + printf (" --duration <milliseconds> Duration of each ge2d operation case.\n"); + printf (" --size <width>x<height> Set ge2d size.\n"); + printf (" --pixelformat <0:ARGB, 1:ABGR, 2:NV21> Set ge2d pixelformat.\n"); + printf (" --help Print usage information.\n"); + printf ("\n"); +} + +static int parse_command_line(int argc, char *argv[]) +{ + int i; + /* parse command line */ + for (i = 1; i < argc; i++) { + if (strncmp (argv[i], "--", 2) == 0) { + if (strcmp (argv[i] + 2, "help") == 0) { + print_usage(); + return ge2d_fail; + } + else if (strcmp (argv[i] + 2, "op") == 0 && ++i < argc && + sscanf (argv[i], "%d", &OP) == 1) { + continue; + } + + else if (strcmp (argv[i] + 2, "size") == 0 && ++i < argc && + sscanf (argv[i], "%dx%d", &SX, &SY) == 2) { + continue; + } + else if (strcmp (argv[i] + 2, "duration") == 0 && ++i < argc && + sscanf (argv[i], "%d", &DEMOTIME) == 1) { + continue; + } + else if (strcmp (argv[i] + 2, "pixelformat") == 0 && ++i < argc && + sscanf (argv[i], "%d", &PIXFORMAT) == 1) { + continue; + } + } + } + return ge2d_success; +} + + +static int ge2d_info_set(aml_ge2d_info_t *pge2dinfo) +{ + switch (pge2dinfo->ge2d_op) { + case AML_GE2D_FILLRECTANGLE: + pge2dinfo->color = 0xffffffff; + pge2dinfo->src_info[0].rect.x = 0; + pge2dinfo->src_info[0].rect.y = 0; + pge2dinfo->src_info[0].rect.w = pge2dinfo->src_info[0].canvas_w; + pge2dinfo->src_info[0].rect.h = pge2dinfo->src_info[0].canvas_h; + pge2dinfo->dst_info.rect.x = 0; + pge2dinfo->dst_info.rect.y = 0; + pge2dinfo->dst_info.rect.w = pge2dinfo->src_info[0].canvas_w; + pge2dinfo->dst_info.rect.h = pge2dinfo->src_info[0].canvas_h; + break; + case AML_GE2D_BLIT: + pge2dinfo->src_info[0].rect.x = 0; + pge2dinfo->src_info[0].rect.y = 0; + pge2dinfo->src_info[0].rect.w = pge2dinfo->src_info[0].canvas_w/2; + pge2dinfo->src_info[0].rect.h = pge2dinfo->src_info[0].canvas_h/2; + pge2dinfo->dst_info.rect.x = 0; + pge2dinfo->dst_info.rect.y = 0; + pge2dinfo->dst_info.rect.w = pge2dinfo->src_info[0].canvas_w/2; + pge2dinfo->dst_info.rect.h = pge2dinfo->src_info[0].canvas_h/2; + break; + case AML_GE2D_STRETCHBLIT: + pge2dinfo->src_info[0].rect.x = 0; + pge2dinfo->src_info[0].rect.y = 0; + pge2dinfo->src_info[0].rect.w = pge2dinfo->src_info[0].canvas_w; + pge2dinfo->src_info[0].rect.h = pge2dinfo->src_info[0].canvas_h; + pge2dinfo->dst_info.rect.x = 0; + pge2dinfo->dst_info.rect.y = 0; + pge2dinfo->dst_info.rect.w = pge2dinfo->src_info[0].canvas_w/2; + pge2dinfo->dst_info.rect.h = pge2dinfo->src_info[0].canvas_h/2; + break; + case AML_GE2D_BLEND: + pge2dinfo->src_info[0].rect.x = 0; + pge2dinfo->src_info[0].rect.y = 0; + pge2dinfo->src_info[0].rect.w = pge2dinfo->src_info[0].canvas_w; + pge2dinfo->src_info[0].rect.h = pge2dinfo->src_info[0].canvas_h; + pge2dinfo->src_info[1].rect.x = 0; + pge2dinfo->src_info[1].rect.y = 0; + pge2dinfo->src_info[1].rect.w = pge2dinfo->src_info[1].canvas_w; + pge2dinfo->src_info[1].rect.h = pge2dinfo->src_info[1].canvas_h; + pge2dinfo->dst_info.rect.x = 0; + pge2dinfo->dst_info.rect.y = 0; + pge2dinfo->dst_info.rect.w = pge2dinfo->src_info[1].canvas_w; + pge2dinfo->dst_info.rect.h = pge2dinfo->src_info[1].canvas_h; + + break; + default: + E_GE2D("ge2d(%d) opration not support!\n",pge2dinfo->ge2d_op); + return ge2d_fail; + } + return ge2d_success; +} + + +static inline unsigned long myclock() +{ + struct timeval tv; + + gettimeofday (&tv, NULL); + + return (tv.tv_sec * 1000 + tv.tv_usec / 1000); +} + + +int aml_read_file(const char* url , aml_ge2d_info_t *pge2dinfo) +{ + int fd = -1; + int length = 0; + int read_num = 0; + if (amlge2d.src_size == 0) + return 0; + + fd = open(url,O_RDONLY ); + if (fd < 0) { + E_GE2D("read source file:%s open error\n",url); + return -1; + } + + amlge2d.src_data = (char*)malloc(amlge2d.src_size); + if (!amlge2d.src_data) { + E_GE2D("malloc for src_data failed\n"); + return -1; + } + + read_num = read(fd,amlge2d.src_data,amlge2d.src_size); + if (read_num <= 0) { + E_GE2D("read file read_num=%d error\n",read_num); + return -1; + } + + memcpy(pge2dinfo->src_info[0].vaddr, amlge2d.src_data, amlge2d.src_size); + close(fd); + return 0; +} + +int main(int argc, char **argv) +{ + int ret = -1; + int i = 0; + unsigned long stime; + aml_ge2d_info_t ge2dinfo; + memset(&amlge2d,0x0,sizeof(aml_ge2d_t)); + amlge2d.pge2d_info = &ge2dinfo; + memset(&ge2dinfo, 0, sizeof(aml_ge2d_info_t)); + memset(&(ge2dinfo.src_info[0]), 0, sizeof(buffer_info_t)); + memset(&(ge2dinfo.src_info[1]), 0, sizeof(buffer_info_t)); + memset(&(ge2dinfo.dst_info), 0, sizeof(buffer_info_t)); + ret = parse_command_line(argc,argv); + if (ret == ge2d_fail) + return ge2d_success; + + set_ge2dinfo(&ge2dinfo); + + ret = ge2d_info_set(&ge2dinfo); + if (ret < 0) + goto exit; + + + ret = aml_ge2d_init(); + if (ret < 0) + return ge2d_fail; + + ret = aml_ge2d_mem_alloc(&ge2dinfo); + if (ret < 0) + goto exit; + + + ret = aml_read_file(SRC_FILE_NAME,&ge2dinfo); + if (ret < 0) + goto exit; + + stime = myclock(); + for ( i = 0;i%100 || myclock()<(stime+DEMOTIME); i++) { + ret = aml_ge2d_process(&ge2dinfo); + if (ret < 0) + goto exit; + D_GE2D("stime=%lx, myclock()=%lx,i=%d\n",(stime+DEMOTIME), myclock(),i); + } + printf("Total %d time run!\n",i); + + +exit: + if (amlge2d.src_data) { + free(amlge2d.src_data); + amlge2d.src_data = NULL; + } + if (amlge2d.src2_data) { + free(amlge2d.src2_data); + amlge2d.src2_data = NULL; + } + if (amlge2d.dst_data) { + free(amlge2d.dst_data); + amlge2d.dst_data = NULL; + } + aml_ge2d_mem_free(&ge2dinfo); + aml_ge2d_exit(); + printf("ge2d example exit!!!\n"); + return ge2d_success; +} diff --git a/libge2d/ge2d_port.c b/libge2d/ge2d_port.c new file mode 100644 index 0000000..50a781d --- a/dev/null +++ b/libge2d/ge2d_port.c @@ -0,0 +1,1224 @@ +#include <stdio.h> +#include <unistd.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <string.h> +#include <linux/ge2d.h> +#include "ge2d_port.h" +#include "ge2d_com.h" + + +#define FILE_NAME_GE2D "/dev/ge2d" + +#define CANVAS_ALIGNED(x) (((x) + 31) & ~31) + + +#define GE2D_BPP_32 32 +#define GE2D_BPP_24 24 +#define GE2D_BPP_16 16 +#define GE2D_BPP_12 12 +#define GE2D_BPP_8 8 + +static int b_src_swap = 0; +static int pixel_to_ge2d_format(int img_format, int *pge2d_format,int *p_bpp) +{ + int is_rgb = -1; + + switch (img_format) { + case PIXEL_FORMAT_RGBA_8888: + case PIXEL_FORMAT_RGBX_8888: + *pge2d_format = GE2D_FORMAT_S32_ABGR; + *p_bpp = GE2D_BPP_32; + is_rgb = 1; + break; + case PIXEL_FORMAT_BGRA_8888: + *pge2d_format = GE2D_FORMAT_S32_ARGB; + *p_bpp = GE2D_BPP_32; + is_rgb = 1; + break; + case PIXEL_FORMAT_RGB_888: + *pge2d_format = GE2D_FORMAT_S24_RGB; + *p_bpp = GE2D_BPP_24; + is_rgb = 1; + break; + case PIXEL_FORMAT_RGB_565: + *pge2d_format = GE2D_FORMAT_S16_RGB_565; + *p_bpp = GE2D_BPP_16; + is_rgb = 1; + break; + case PIXEL_FORMAT_YCrCb_420_SP: + *pge2d_format = GE2D_FORMAT_M24_NV21; + *p_bpp = GE2D_BPP_8; + is_rgb = 0; + break; + case PIXEL_FORMAT_YV12: + *pge2d_format = GE2D_FORMAT_M24_YUV420; + *p_bpp = GE2D_BPP_8; + is_rgb = 0; + break; + case PIXEL_FORMAT_Y8: + *pge2d_format = GE2D_FORMAT_S8_Y; + *p_bpp = GE2D_BPP_8; + is_rgb = 0; + break; + case PIXEL_FORMAT_YCbCr_422_I: + *pge2d_format = GE2D_FORMAT_S16_YUV422; + *p_bpp = GE2D_BPP_8; + is_rgb = 0; + break; + default: + E_GE2D("Image format %d not supported!", img_format); + *pge2d_format = 0xffffffff; + *p_bpp = GE2D_BPP_32; + break; + } + return is_rgb; +} + + + + +static void ge2d_set_canvas(int bpp, int w,int h, int *canvas_w, int *canvas_h) +{ + *canvas_w = (CANVAS_ALIGNED(w * bpp >> 3))/(bpp >> 3); + *canvas_h = h; +} + + +static inline unsigned blendop(unsigned color_blending_mode, + unsigned color_blending_src_factor, + unsigned color_blending_dst_factor, + unsigned alpha_blending_mode, + unsigned alpha_blending_src_factor, + unsigned alpha_blending_dst_factor) +{ + return (color_blending_mode << 24) | + (color_blending_src_factor << 20) | + (color_blending_dst_factor << 16) | + (alpha_blending_mode << 8) | + (alpha_blending_src_factor << 4) | (alpha_blending_dst_factor << 0); +} + + +static int is_no_alpha(int format) +{ + if ((format == PIXEL_FORMAT_RGBX_8888) || + (format == PIXEL_FORMAT_RGB_565) || + (format == PIXEL_FORMAT_RGB_888) || + (format == PIXEL_FORMAT_YCrCb_420_SP)|| + (format == PIXEL_FORMAT_Y8)|| + (format == PIXEL_FORMAT_YV12) || + (format == PIXEL_FORMAT_YCbCr_422_I)|| + (format == PIXEL_FORMAT_YCbCr_422_SP)) + return 1; + else + return 0; +} + +static int is_nv21(int format) +{ + if ((format == PIXEL_FORMAT_YCrCb_420_SP)|| + (format == PIXEL_FORMAT_YV12)) + return 1; + else + return 0; +} + + +static int is_rect_valid(buffer_info_t *pbuffer_info) +{ + int ret = 1; + if (CANVAS_ALLOC == pbuffer_info->memtype) + if (((unsigned int)pbuffer_info->rect.w > pbuffer_info->canvas_w) || + ((unsigned int)pbuffer_info->rect.h > pbuffer_info->canvas_h)) { + E_GE2D("rect.w,h:[%d,%d] out of range!\n",pbuffer_info->rect.w, + pbuffer_info->rect.h); + ret = 0; + } + return ret; +} + + +static int ge2d_fillrectangle_config_ex(int fd,aml_ge2d_info_t *pge2dinfo) +{ + int ret = -1; + struct config_para_ex_s ge2d_config_ex; + int src_format = 0xffffffff,dst_format = 0xffffffff; + int s_canvas_w = 0; + int s_canvas_h = 0; + int d_canvas_w = 0; + int d_canvas_h = 0; + int bpp = 0; + int is_rgb = -1; + buffer_info_t* input_buffer_info = &(pge2dinfo->src_info[0]); + buffer_info_t* output_buffer_info = &(pge2dinfo->dst_info); + + memset(&ge2d_config_ex, 0, sizeof(struct config_para_ex_s )); + + if ((CANVAS_ALLOC == output_buffer_info->memtype)) { + is_rgb = pixel_to_ge2d_format(output_buffer_info->format,&dst_format,&bpp); + dst_format |= GE2D_LITTLE_ENDIAN; + if ((int)0xffffffff == dst_format) { + E_GE2D("can't get proper ge2d format\n" ); + return ge2d_fail; + } + ge2d_set_canvas(bpp,output_buffer_info->canvas_w,output_buffer_info->canvas_h,&d_canvas_w,&d_canvas_h); + + pixel_to_ge2d_format(input_buffer_info->format,&src_format,&bpp); + src_format |= GE2D_LITTLE_ENDIAN; + ge2d_set_canvas(bpp,input_buffer_info->canvas_w,input_buffer_info->canvas_h,&s_canvas_w,&s_canvas_h); + }else { + is_rgb = pixel_to_ge2d_format(output_buffer_info->format,&dst_format,&bpp); + dst_format |= GE2D_LITTLE_ENDIAN; + ge2d_set_canvas(bpp,output_buffer_info->canvas_w,output_buffer_info->canvas_h,&d_canvas_w,&d_canvas_h); + + pixel_to_ge2d_format(input_buffer_info->format,&src_format,&bpp); + src_format |= GE2D_LITTLE_ENDIAN; + ge2d_set_canvas(bpp,input_buffer_info->canvas_w,input_buffer_info->canvas_h,&s_canvas_w,&s_canvas_h); + } + D_GE2D("ge2d_fillrectangle_config_ex,memtype=%x,src_format=%x,s_canvas_w=%d,s_canvas_h=%d,rotation=%d\n", + input_buffer_info->memtype,src_format,s_canvas_w,s_canvas_h,input_buffer_info->rotation); + + D_GE2D("ge2d_fillrectangle_config_ex,memtype=%x,dst_format=%x,d_canvas_w=%d,d_canvas_h=%d,rotation=%d\n", + output_buffer_info->memtype,dst_format,d_canvas_w,d_canvas_h,output_buffer_info->rotation); + + ge2d_config_ex.src_para.mem_type = CANVAS_OSD0; + ge2d_config_ex.src_para.format = src_format; + ge2d_config_ex.src_para.left = 0; + ge2d_config_ex.src_para.top = 0; + ge2d_config_ex.src_para.width = s_canvas_w; + ge2d_config_ex.src_para.height = s_canvas_h; + + ge2d_config_ex.dst_para.mem_type = output_buffer_info->memtype; + ge2d_config_ex.dst_para.format = dst_format; + ge2d_config_ex.dst_para.left = 0; + ge2d_config_ex.dst_para.top = 0; + ge2d_config_ex.dst_para.width = d_canvas_w; + ge2d_config_ex.dst_para.height = d_canvas_h; + + ge2d_config_ex.src2_para.mem_type = CANVAS_TYPE_INVALID; + + switch (pge2dinfo->dst_info.rotation) { + case GE2D_ROTATION_0: + break; + case GE2D_ROTATION_90: + ge2d_config_ex.dst_xy_swap = 1; + ge2d_config_ex.dst_para.x_rev = 1; + break; + case GE2D_ROTATION_180: + ge2d_config_ex.dst_para.x_rev = 1; + ge2d_config_ex.dst_para.y_rev = 1; + break; + case GE2D_ROTATION_270: + ge2d_config_ex.dst_xy_swap = 1; + ge2d_config_ex.dst_para.y_rev = 1; + break; + default: + break; + } + + + if (CANVAS_ALLOC == output_buffer_info->memtype) { + if (is_rgb == 1) { + ge2d_config_ex.dst_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + } else if (output_buffer_info->format == PIXEL_FORMAT_YCrCb_420_SP) { + ge2d_config_ex.dst_planes[0].addr = output_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + ge2d_config_ex.dst_planes[1].addr = output_buffer_info->paddr + (d_canvas_w * d_canvas_h); + ge2d_config_ex.dst_planes[1].w = d_canvas_w; + ge2d_config_ex.dst_planes[1].h = d_canvas_h/2; + } else if (output_buffer_info->format == PIXEL_FORMAT_Y8) { + ge2d_config_ex.dst_planes[0].addr = output_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + } else if (output_buffer_info->format == PIXEL_FORMAT_YV12) { + ge2d_config_ex.dst_planes[0].addr = output_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + ge2d_config_ex.dst_planes[1].addr = output_buffer_info->paddr + (d_canvas_w * d_canvas_h); + ge2d_config_ex.dst_planes[1].w = d_canvas_w; + ge2d_config_ex.dst_planes[1].h = d_canvas_h/4; + ge2d_config_ex.dst_planes[2].addr = output_buffer_info->paddr + (d_canvas_w * d_canvas_h)*5/4; + ge2d_config_ex.dst_planes[2].w = d_canvas_w; + ge2d_config_ex.dst_planes[2].h = d_canvas_h/4; + } else if (input_buffer_info->format == PIXEL_FORMAT_YCbCr_422_SP) { + ge2d_config_ex.dst_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + ge2d_config_ex.dst_planes[1].addr = input_buffer_info->paddr + (d_canvas_w * d_canvas_h); + ge2d_config_ex.dst_planes[1].w = d_canvas_w; + ge2d_config_ex.dst_planes[1].h = d_canvas_h; + } else if (input_buffer_info->format == PIXEL_FORMAT_YCbCr_422_I) { + ge2d_config_ex.dst_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w*2; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + } + else { + E_GE2D("format is not match, should config dst_planes correct.\n"); + return ge2d_fail; + } + } + + ge2d_config_ex.alu_const_color = 0x00000000; + ge2d_config_ex.src1_gb_alpha = 0xff; + + ret = ioctl(fd, GE2D_CONFIG_EX, &ge2d_config_ex); + if (ret < 0) { + E_GE2D("ge2d config failed. \n"); + return ge2d_fail; + } + return ge2d_success; +} + +static int ge2d_blit_config_ex(int fd,aml_ge2d_info_t *pge2dinfo) +{ + int ret = -1; + struct config_para_ex_s ge2d_config_ex; + int src_format = 0xffffffff,dst_format = 0xffffffff; + int s_canvas_w = 0; + int s_canvas_h = 0; + int d_canvas_w = 0; + int d_canvas_h = 0; + int bpp = 0; + int is_rgb_input = -1; + int is_rgb_output = -1; + buffer_info_t* input_buffer_info = &(pge2dinfo->src_info[0]); + buffer_info_t* output_buffer_info = &(pge2dinfo->dst_info); + + memset(&ge2d_config_ex, 0, sizeof(struct config_para_ex_s )); + + if ((CANVAS_ALLOC == input_buffer_info->memtype)) { + is_rgb_input = pixel_to_ge2d_format(input_buffer_info->format,&src_format,&bpp); + src_format |= GE2D_LITTLE_ENDIAN; + if ((int)0xffffffff == src_format) { + E_GE2D("can't get proper ge2d format\n" ); + return ge2d_fail; + } + ge2d_set_canvas(bpp,input_buffer_info->canvas_w,input_buffer_info->canvas_h,&s_canvas_w,&s_canvas_h); + } + + if ((CANVAS_ALLOC == output_buffer_info->memtype)) { + is_rgb_output = pixel_to_ge2d_format(output_buffer_info->format,&dst_format,&bpp); + dst_format |= GE2D_LITTLE_ENDIAN; + if ((int)0xffffffff == dst_format) { + E_GE2D("can't get proper ge2d format\n" ); + return ge2d_fail; + } + ge2d_set_canvas(bpp,output_buffer_info->canvas_w,output_buffer_info->canvas_h,&d_canvas_w,&d_canvas_h); + } + D_GE2D("ge2d_blit_config_ex,memtype=%x,src_format=%x,s_canvas_w=%d,s_canvas_h=%d,rotation=%d\n", + input_buffer_info->memtype,src_format,s_canvas_w,s_canvas_h,input_buffer_info->rotation); + + D_GE2D("ge2d_blit_config_ex,memtype=%x,dst_format=%x,d_canvas_w=%d,d_canvas_h=%d,rotation=%d\n", + output_buffer_info->memtype,dst_format,d_canvas_w,d_canvas_h,output_buffer_info->rotation); + + ge2d_config_ex.src_para.mem_type = input_buffer_info->memtype; + ge2d_config_ex.src_para.format = src_format; + ge2d_config_ex.src_para.left = 0; + ge2d_config_ex.src_para.top = 0; + ge2d_config_ex.src_para.width = s_canvas_w; + ge2d_config_ex.src_para.height = s_canvas_h; + + ge2d_config_ex.src2_para.mem_type = CANVAS_TYPE_INVALID; + + ge2d_config_ex.dst_para.mem_type = output_buffer_info->memtype; + ge2d_config_ex.dst_para.format = dst_format; + ge2d_config_ex.dst_para.left = 0; + ge2d_config_ex.dst_para.top = 0; + ge2d_config_ex.dst_para.width = d_canvas_w; + ge2d_config_ex.dst_para.height = d_canvas_h; + + switch (pge2dinfo->src_info[0].rotation) { + case GE2D_ROTATION_0: + break; + case GE2D_ROTATION_90: + ge2d_config_ex.dst_xy_swap = 1; + ge2d_config_ex.src_para.y_rev = 1; + break; + case GE2D_ROTATION_180: + ge2d_config_ex.src_para.x_rev = 1; + ge2d_config_ex.src_para.y_rev = 1; + break; + case GE2D_ROTATION_270: + ge2d_config_ex.dst_xy_swap = 1; + ge2d_config_ex.src_para.x_rev = 1; + break; + default: + break; + } + + switch (pge2dinfo->dst_info.rotation) { + case GE2D_ROTATION_0: + break; + case GE2D_ROTATION_90: + ge2d_config_ex.dst_xy_swap = 1; + ge2d_config_ex.dst_para.x_rev = 1; + break; + case GE2D_ROTATION_180: + ge2d_config_ex.dst_para.x_rev = 1; + ge2d_config_ex.dst_para.y_rev = 1; + break; + case GE2D_ROTATION_270: + ge2d_config_ex.dst_xy_swap = 1; + ge2d_config_ex.dst_para.y_rev = 1; + break; + default: + break; + } + + if (CANVAS_ALLOC == input_buffer_info->memtype) { + if (is_rgb_input) { + ge2d_config_ex.src_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.src_planes[0].w = s_canvas_w; + ge2d_config_ex.src_planes[0].h = s_canvas_h; + } else if (input_buffer_info->format == PIXEL_FORMAT_YCrCb_420_SP) { + ge2d_config_ex.src_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.src_planes[0].w = s_canvas_w; + ge2d_config_ex.src_planes[0].h = s_canvas_h; + ge2d_config_ex.src_planes[1].addr = input_buffer_info->paddr + (s_canvas_w * s_canvas_h); + ge2d_config_ex.src_planes[1].w = s_canvas_w; + ge2d_config_ex.src_planes[1].h = s_canvas_h/2; + } else if (input_buffer_info->format == PIXEL_FORMAT_Y8) { + ge2d_config_ex.src_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.src_planes[0].w = s_canvas_w; + ge2d_config_ex.src_planes[0].h = s_canvas_h; + } else if (input_buffer_info->format == PIXEL_FORMAT_YV12) { + ge2d_config_ex.src_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.src_planes[0].w = s_canvas_w; + ge2d_config_ex.src_planes[0].h = s_canvas_h; + ge2d_config_ex.src_planes[1].addr = input_buffer_info->paddr + (s_canvas_w * s_canvas_h); + ge2d_config_ex.src_planes[1].w = s_canvas_w; + ge2d_config_ex.src_planes[1].h = s_canvas_h/4; + ge2d_config_ex.src_planes[2].addr = input_buffer_info->paddr + (s_canvas_w * s_canvas_h)*5/4; + ge2d_config_ex.src_planes[2].w = s_canvas_w; + ge2d_config_ex.src_planes[2].h = s_canvas_h/4; + } else if (input_buffer_info->format == PIXEL_FORMAT_YCbCr_422_SP) { + ge2d_config_ex.src_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.src_planes[0].w = s_canvas_w; + ge2d_config_ex.src_planes[0].h = s_canvas_h; + ge2d_config_ex.src_planes[1].addr = input_buffer_info->paddr + (s_canvas_w * s_canvas_h); + ge2d_config_ex.src_planes[1].w = s_canvas_w; + ge2d_config_ex.src_planes[1].h = s_canvas_h; + } else if (input_buffer_info->format == PIXEL_FORMAT_YCbCr_422_I) { + ge2d_config_ex.src_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.src_planes[0].w = s_canvas_w*2; + ge2d_config_ex.src_planes[0].h = s_canvas_h; + } + else { + E_GE2D("format is not match, should config src_planes correct.\n"); + return ge2d_fail; + } + } + + if (CANVAS_ALLOC == output_buffer_info->memtype) { + if (is_rgb_output) { + ge2d_config_ex.dst_planes[0].addr = output_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + } else if (output_buffer_info->format == PIXEL_FORMAT_YCrCb_420_SP) { + ge2d_config_ex.dst_planes[0].addr = output_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + ge2d_config_ex.dst_planes[1].addr = output_buffer_info->paddr + (d_canvas_w * d_canvas_h); + ge2d_config_ex.dst_planes[1].w = d_canvas_w; + ge2d_config_ex.dst_planes[1].h = d_canvas_h/2; + } else if (output_buffer_info->format == PIXEL_FORMAT_Y8) { + ge2d_config_ex.dst_planes[0].addr = output_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + } else if (output_buffer_info->format == PIXEL_FORMAT_YV12) { + ge2d_config_ex.dst_planes[0].addr = output_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + ge2d_config_ex.dst_planes[1].addr = output_buffer_info->paddr + (d_canvas_w * d_canvas_h); + ge2d_config_ex.dst_planes[1].w = d_canvas_w; + ge2d_config_ex.dst_planes[1].h = d_canvas_h/4; + ge2d_config_ex.dst_planes[2].addr = output_buffer_info->paddr + (d_canvas_w * d_canvas_h)*5/4; + ge2d_config_ex.dst_planes[2].w = d_canvas_w; + ge2d_config_ex.dst_planes[2].h = d_canvas_h/4; + } else if (input_buffer_info->format == PIXEL_FORMAT_YCbCr_422_SP) { + ge2d_config_ex.dst_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + ge2d_config_ex.dst_planes[1].addr = input_buffer_info->paddr + (d_canvas_w * d_canvas_h); + ge2d_config_ex.dst_planes[1].w = d_canvas_w; + ge2d_config_ex.dst_planes[1].h = d_canvas_h; + } else if (input_buffer_info->format == PIXEL_FORMAT_YCbCr_422_I) { + ge2d_config_ex.dst_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w*2; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + } + else { + E_GE2D("format is not match, should config dst_planes correct.\n"); + return ge2d_fail; + } + } + + ge2d_config_ex.alu_const_color = 0x00000000; + ge2d_config_ex.src1_gb_alpha = 0xff; + ret = ioctl(fd, GE2D_CONFIG_EX, &ge2d_config_ex); + if (ret < 0) { + E_GE2D("ge2d config failed. \n"); + return ge2d_fail; + } + return ge2d_success; +} + + +static int ge2d_blend_config_ex(int fd,aml_ge2d_info_t *pge2dinfo) +{ + int ret = -1; + struct config_para_ex_s ge2d_config_ex; + int src_format = 0xffffffff,src2_format = 0xffffffff,dst_format = 0xffffffff; + int s_canvas_w = 0; + int s_canvas_h = 0; + int s2_canvas_w = 0; + int s2_canvas_h = 0; + int d_canvas_w = 0; + int d_canvas_h = 0; + int is_rgb_input = -1; + int is_rgb_input2 = -1; + int is_rgb_output = -1; + int bpp = 0; + buffer_info_t* input_buffer_info = &pge2dinfo->src_info[0]; + buffer_info_t* input2_buffer_info = &pge2dinfo->src_info[1]; + buffer_info_t* output_buffer_info = &pge2dinfo->dst_info; + /* src2 not support nv21/nv12, swap src1 and src2 */ + if (is_nv21(input2_buffer_info->format)) { + input_buffer_info = &pge2dinfo->src_info[1]; + input2_buffer_info = &pge2dinfo->src_info[0]; + b_src_swap = 1; + D_GE2D("NOTE:src2 not support nv21/nv12, swap src1 and src2!\n"); + } + else + b_src_swap = 0; + + memset(&ge2d_config_ex, 0, sizeof(struct config_para_ex_s )); + + if (CANVAS_ALLOC == input_buffer_info->memtype) { + is_rgb_input = pixel_to_ge2d_format(input_buffer_info->format,&src_format,&bpp); + src_format |= GE2D_LITTLE_ENDIAN; + if ((int)0xffffffff == src_format) { + E_GE2D("can't get proper ge2d format\n" ); + return ge2d_fail; + } + ge2d_set_canvas(bpp,input_buffer_info->canvas_w,input_buffer_info->canvas_h,&s_canvas_w,&s_canvas_h); + } + if ((CANVAS_ALLOC == input2_buffer_info->memtype)) { + is_rgb_input2 = pixel_to_ge2d_format(input2_buffer_info->format,&src2_format,&bpp); + src2_format |= GE2D_LITTLE_ENDIAN; + if ((int)0xffffffff == src2_format) { + E_GE2D("can't get proper ge2d format\n" ); + return ge2d_fail; + } + ge2d_set_canvas(bpp,input2_buffer_info->canvas_w,input2_buffer_info->canvas_h,&s2_canvas_w,&s2_canvas_h); + } + + if ((CANVAS_ALLOC == output_buffer_info->memtype)) { + is_rgb_output = pixel_to_ge2d_format(output_buffer_info->format,&dst_format,&bpp); + dst_format |= GE2D_LITTLE_ENDIAN; + if ((int)0xffffffff == dst_format) { + E_GE2D("can't get proper ge2d format\n" ); + return ge2d_fail; + } + ge2d_set_canvas(bpp,output_buffer_info->canvas_w,output_buffer_info->canvas_h,&d_canvas_w,&d_canvas_h); + + } + D_GE2D("ge2d_blit_config_ex,memtype=%x,src_format=%x,s_canvas_w=%d,s_canvas_h=%d,rotation=%d\n", + input_buffer_info->memtype,src_format,s_canvas_w,s_canvas_h,input_buffer_info->rotation); + + D_GE2D("ge2d_blit_config_ex,memtype=%x,src2_format=%x,s2_canvas_w=%d,s2_canvas_h=%d,rotation=%d\n", + input2_buffer_info->memtype,src2_format,s2_canvas_w,s2_canvas_h,input2_buffer_info->rotation); + + D_GE2D("ge2d_blit_config_ex,memtype=%x,dst_format=%x,d_canvas_w=%d,d_canvas_h=%d,rotation=%d\n", + output_buffer_info->memtype,dst_format,d_canvas_w,d_canvas_h,output_buffer_info->rotation); + + ge2d_config_ex.src_para.mem_type = input_buffer_info->memtype; + ge2d_config_ex.src_para.format = src_format; + ge2d_config_ex.src_para.left = 0; + ge2d_config_ex.src_para.top = 0; + ge2d_config_ex.src_para.width = s_canvas_w; + ge2d_config_ex.src_para.height = s_canvas_h; + + ge2d_config_ex.src2_para.mem_type = input2_buffer_info->memtype; + ge2d_config_ex.src2_para.format = src2_format; + ge2d_config_ex.src2_para.left = 0; + ge2d_config_ex.src2_para.top = 0; + ge2d_config_ex.src2_para.width = s2_canvas_w; + ge2d_config_ex.src2_para.height = s2_canvas_h; + + ge2d_config_ex.dst_para.mem_type = output_buffer_info->memtype; + ge2d_config_ex.dst_para.format = dst_format; + ge2d_config_ex.dst_para.left = 0; + ge2d_config_ex.dst_para.top = 0; + ge2d_config_ex.dst_para.width = d_canvas_w; + ge2d_config_ex.dst_para.height = d_canvas_h; + switch (pge2dinfo->src_info[0].rotation) { + case GE2D_ROTATION_0: + break; + case GE2D_ROTATION_90: + ge2d_config_ex.dst_xy_swap = 1; + ge2d_config_ex.src_para.y_rev = 1; + break; + case GE2D_ROTATION_180: + ge2d_config_ex.src_para.x_rev = 1; + ge2d_config_ex.src_para.y_rev = 1; + break; + case GE2D_ROTATION_270: + ge2d_config_ex.dst_xy_swap = 1; + ge2d_config_ex.src_para.x_rev = 1; + break; + default: + break; + } + + switch (pge2dinfo->src_info[1].rotation) { + case GE2D_ROTATION_0: + break; + case GE2D_ROTATION_90: + ge2d_config_ex.dst_xy_swap = 1; + ge2d_config_ex.src2_para.y_rev = 1; + break; + case GE2D_ROTATION_180: + ge2d_config_ex.src2_para.x_rev = 1; + ge2d_config_ex.src2_para.y_rev = 1; + break; + case GE2D_ROTATION_270: + ge2d_config_ex.dst_xy_swap = 1; + ge2d_config_ex.src2_para.x_rev = 1; + break; + default: + break; + } + + switch (pge2dinfo->dst_info.rotation) { + case GE2D_ROTATION_0: + break; + case GE2D_ROTATION_90: + ge2d_config_ex.dst_xy_swap = 1; + ge2d_config_ex.dst_para.x_rev = 1; + break; + case GE2D_ROTATION_180: + ge2d_config_ex.dst_para.x_rev = 1; + ge2d_config_ex.dst_para.y_rev = 1; + break; + case GE2D_ROTATION_270: + ge2d_config_ex.dst_xy_swap = 1; + ge2d_config_ex.dst_para.y_rev = 1; + break; + default: + break; + } + + if (CANVAS_ALLOC == input_buffer_info->memtype) { + if (is_rgb_input) { + ge2d_config_ex.src_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.src_planes[0].w = s_canvas_w; + ge2d_config_ex.src_planes[0].h = s_canvas_h; + } else if (input_buffer_info->format == PIXEL_FORMAT_YCrCb_420_SP) { + ge2d_config_ex.src_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.src_planes[0].w = s_canvas_w; + ge2d_config_ex.src_planes[0].h = s_canvas_h; + ge2d_config_ex.src_planes[1].addr = input_buffer_info->paddr + (s_canvas_w * s_canvas_h); + ge2d_config_ex.src_planes[1].w = s_canvas_w; + ge2d_config_ex.src_planes[1].h = s_canvas_h/2; + } else if (input_buffer_info->format == PIXEL_FORMAT_Y8) { + ge2d_config_ex.src_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.src_planes[0].w = s_canvas_w; + ge2d_config_ex.src_planes[0].h = s_canvas_h; + } else if (input_buffer_info->format == PIXEL_FORMAT_YV12) { + ge2d_config_ex.src_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.src_planes[0].w = s_canvas_w; + ge2d_config_ex.src_planes[0].h = s_canvas_h; + ge2d_config_ex.src_planes[1].addr = input_buffer_info->paddr + (s_canvas_w * s_canvas_h); + ge2d_config_ex.src_planes[1].w = s_canvas_w; + ge2d_config_ex.src_planes[1].h = s_canvas_h/4; + ge2d_config_ex.src_planes[2].addr = input_buffer_info->paddr + (s_canvas_w * s_canvas_h)*5/4; + ge2d_config_ex.src_planes[2].w = s_canvas_w; + ge2d_config_ex.src_planes[2].h = s_canvas_h/4; + } else if (input_buffer_info->format == PIXEL_FORMAT_YCbCr_422_SP) { + ge2d_config_ex.src_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.src_planes[0].w = s_canvas_w; + ge2d_config_ex.src_planes[0].h = s_canvas_h; + ge2d_config_ex.src_planes[1].addr = input_buffer_info->paddr + (s_canvas_w * s_canvas_h); + ge2d_config_ex.src_planes[1].w = s_canvas_w; + ge2d_config_ex.src_planes[1].h = s_canvas_h; + } else if (input_buffer_info->format == PIXEL_FORMAT_YCbCr_422_I) { + ge2d_config_ex.src_planes[0].addr = input_buffer_info->paddr; + ge2d_config_ex.src_planes[0].w = s_canvas_w*2; + ge2d_config_ex.src_planes[0].h = s_canvas_h; + } + else { + E_GE2D("format is not match, should config src_planes correct.\n"); + return ge2d_fail; + } + } + + + if (CANVAS_ALLOC == input2_buffer_info->memtype) { + if (is_rgb_input2) { + ge2d_config_ex.src2_planes[0].addr = input2_buffer_info->paddr; + ge2d_config_ex.src2_planes[0].w = s2_canvas_w; + ge2d_config_ex.src2_planes[0].h = s2_canvas_h; + } else if (input2_buffer_info->format == PIXEL_FORMAT_YCrCb_420_SP) { + ge2d_config_ex.src2_planes[0].addr = input2_buffer_info->paddr; + ge2d_config_ex.src2_planes[0].w = s2_canvas_w; + ge2d_config_ex.src2_planes[0].h = s2_canvas_h; + ge2d_config_ex.src2_planes[1].addr = input2_buffer_info->paddr + (s2_canvas_w * s2_canvas_h); + ge2d_config_ex.src2_planes[1].w = s2_canvas_w; + ge2d_config_ex.src2_planes[1].h = s2_canvas_h/2; + } else if (input2_buffer_info->format == PIXEL_FORMAT_Y8) { + ge2d_config_ex.src2_planes[0].addr = input2_buffer_info->paddr; + ge2d_config_ex.src2_planes[0].w = s2_canvas_w; + ge2d_config_ex.src2_planes[0].h = s2_canvas_h; + } else if (input2_buffer_info->format == PIXEL_FORMAT_YV12) { + ge2d_config_ex.src2_planes[0].addr = input2_buffer_info->paddr; + ge2d_config_ex.src2_planes[0].w = s2_canvas_w; + ge2d_config_ex.src2_planes[0].h = s2_canvas_h; + ge2d_config_ex.src2_planes[1].addr = input2_buffer_info->paddr + (s2_canvas_w * s2_canvas_h); + ge2d_config_ex.src2_planes[1].w = s2_canvas_w; + ge2d_config_ex.src2_planes[1].h = s2_canvas_h/4; + ge2d_config_ex.src2_planes[2].addr = input2_buffer_info->paddr + (s2_canvas_w * s2_canvas_h)*5/4; + ge2d_config_ex.src2_planes[2].w = s2_canvas_w; + ge2d_config_ex.src2_planes[2].h = s2_canvas_h/4; + } else if (input2_buffer_info->format == PIXEL_FORMAT_YCbCr_422_SP) { + ge2d_config_ex.src2_planes[0].addr = input2_buffer_info->paddr; + ge2d_config_ex.src2_planes[0].w = s2_canvas_w; + ge2d_config_ex.src2_planes[0].h = s2_canvas_h; + ge2d_config_ex.src2_planes[1].addr = input2_buffer_info->paddr + (s2_canvas_w * s2_canvas_h); + ge2d_config_ex.src2_planes[1].w = s2_canvas_w; + ge2d_config_ex.src2_planes[1].h = s2_canvas_h; + } else if (input2_buffer_info->format == PIXEL_FORMAT_YCbCr_422_I) { + ge2d_config_ex.src2_planes[0].addr = input2_buffer_info->paddr; + ge2d_config_ex.src2_planes[0].w = s2_canvas_w*2; + ge2d_config_ex.src2_planes[0].h = s2_canvas_h; + } + else { + E_GE2D("format is not match, should config src2_planes correct.\n"); + return ge2d_fail; + } + } + + if (CANVAS_ALLOC == output_buffer_info->memtype) { + if (is_rgb_output) { + ge2d_config_ex.dst_planes[0].addr = output_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + } else if (output_buffer_info->format == PIXEL_FORMAT_YCrCb_420_SP) { + ge2d_config_ex.dst_planes[0].addr = output_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + ge2d_config_ex.dst_planes[1].addr = output_buffer_info->paddr + (d_canvas_w * d_canvas_h); + ge2d_config_ex.dst_planes[1].w = d_canvas_w; + ge2d_config_ex.dst_planes[1].h = d_canvas_h/2; + } else if (output_buffer_info->format == PIXEL_FORMAT_Y8) { + ge2d_config_ex.dst_planes[0].addr = output_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + } else if (output_buffer_info->format == PIXEL_FORMAT_YV12) { + ge2d_config_ex.dst_planes[0].addr = output_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + ge2d_config_ex.dst_planes[1].addr = output_buffer_info->paddr + (d_canvas_w * d_canvas_h); + ge2d_config_ex.dst_planes[1].w = d_canvas_w; + ge2d_config_ex.dst_planes[1].h = d_canvas_h/4; + ge2d_config_ex.dst_planes[2].addr = output_buffer_info->paddr + (d_canvas_w * d_canvas_h)*5/4; + ge2d_config_ex.dst_planes[2].w = d_canvas_w; + ge2d_config_ex.dst_planes[2].h = d_canvas_h/4; + } else if (output_buffer_info->format == PIXEL_FORMAT_YCbCr_422_SP) { + ge2d_config_ex.dst_planes[0].addr = output_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + ge2d_config_ex.dst_planes[1].addr = output_buffer_info->paddr + (d_canvas_w * d_canvas_h); + ge2d_config_ex.dst_planes[1].w = d_canvas_w; + ge2d_config_ex.dst_planes[1].h = d_canvas_h; + } else if (output_buffer_info->format == PIXEL_FORMAT_YCbCr_422_I) { + ge2d_config_ex.dst_planes[0].addr = output_buffer_info->paddr; + ge2d_config_ex.dst_planes[0].w = d_canvas_w*2; + ge2d_config_ex.dst_planes[0].h = d_canvas_h; + } + else { + E_GE2D("format is not match, should config dst_planes correct.\n"); + return ge2d_fail; + } + } + ge2d_config_ex.alu_const_color = 0x00000000; + ge2d_config_ex.src1_gb_alpha = 0xff; + ret = ioctl(fd, GE2D_CONFIG_EX, &ge2d_config_ex); + if (ret < 0) { + E_GE2D("ge2d config ex failed. \n"); + return ge2d_fail; + } + return ge2d_success; +} + +static int ge2d_fillrectangle(int fd,rectangle_t *rect,unsigned int color) +{ + int ret; + ge2d_op_para_t op_ge2d_info; + memset(&op_ge2d_info, 0, sizeof(ge2d_op_para_t)); + D_GE2D("ge2d_fillrectangle:rect x is %d, y is %d, w is %d, h is %d\n", + rect->x, rect->y, rect->w, rect->h); + D_GE2D("color is %d\n", color); + + op_ge2d_info.src1_rect.x = rect->x; + op_ge2d_info.src1_rect.y = rect->y; + op_ge2d_info.src1_rect.w = rect->w; + op_ge2d_info.src1_rect.h = rect->h; + + op_ge2d_info.dst_rect.x = rect->x; + op_ge2d_info.dst_rect.y = rect->y; + op_ge2d_info.dst_rect.w = rect->w; + op_ge2d_info.dst_rect.h = rect->h; + op_ge2d_info.color = color; + + ret = ioctl(fd, GE2D_FILLRECTANGLE, &op_ge2d_info); + if (ret != 0) { + E_GE2D("%s,%d,ret %d,ioctl failed!\n",__FUNCTION__,__LINE__, ret); + return ge2d_fail; + } + return ge2d_success; +} + + + +static int ge2d_blit(int fd,rectangle_t *rect,unsigned int dx,unsigned int dy) +{ + int ret; + ge2d_op_para_t op_ge2d_info; + memset(&op_ge2d_info, 0, sizeof(ge2d_op_para_t)); + D_GE2D("ge2d_blit:rect x is %d, y is %d, w is %d, h is %d\n", + rect->x, rect->y, rect->w, rect->h); + D_GE2D("dx is %d, dy is %d\n", dx, dy); + + op_ge2d_info.src1_rect.x = rect->x; + op_ge2d_info.src1_rect.y = rect->y; + op_ge2d_info.src1_rect.w = rect->w; + op_ge2d_info.src1_rect.h = rect->h; + + op_ge2d_info.dst_rect.x = dx; + op_ge2d_info.dst_rect.y = dy; + op_ge2d_info.dst_rect.w = rect->w; + op_ge2d_info.dst_rect.h = rect->h; + + ret = ioctl(fd, GE2D_BLIT, &op_ge2d_info); + if (ret != 0) { + E_GE2D("%s,%d,ret %d,ioctl failed!\n",__FUNCTION__,__LINE__, ret); + return ge2d_fail; + } + return ge2d_success; +} + +static int ge2d_blit_noalpha(int fd,rectangle_t *rect,unsigned int dx,unsigned int dy) +{ + int ret; + ge2d_op_para_t op_ge2d_info; + memset(&op_ge2d_info, 0, sizeof(ge2d_op_para_t)); + D_GE2D("ge2d_blit_noalpha:rect x is %d, y is %d, w is %d, h is %d\n", + rect->x, rect->y, rect->w, rect->h); + + D_GE2D("dx is %d, dy is %d\n", dx, dy); + + op_ge2d_info.src1_rect.x = rect->x; + op_ge2d_info.src1_rect.y = rect->y; + op_ge2d_info.src1_rect.w = rect->w; + op_ge2d_info.src1_rect.h = rect->h; + + op_ge2d_info.dst_rect.x = dx; + op_ge2d_info.dst_rect.y = dy; + op_ge2d_info.dst_rect.w = rect->w; + op_ge2d_info.dst_rect.h = rect->h; + + ret = ioctl(fd, GE2D_BLIT_NOALPHA, &op_ge2d_info); + if ( ret != 0) { + E_GE2D("%s,%d,ret %d,ioctl failed!\n",__FUNCTION__,__LINE__, ret); + return ge2d_fail; + } + return ge2d_success; +} + +static int ge2d_strechblit(int fd,rectangle_t *srect,rectangle_t *drect) +{ + int ret; + ge2d_op_para_t op_ge2d_info; + memset(&op_ge2d_info, 0, sizeof(ge2d_op_para_t)); + D_GE2D("stretchblit srect[%d %d %d %d] drect[%d %d %d %d]\n", + srect->x,srect->y,srect->w,srect->h,drect->x,drect->y,drect->w,drect->h); + + op_ge2d_info.src1_rect.x = srect->x; + op_ge2d_info.src1_rect.y = srect->y; + op_ge2d_info.src1_rect.w = srect->w; + op_ge2d_info.src1_rect.h = srect->h; + + op_ge2d_info.dst_rect.x = drect->x; + op_ge2d_info.dst_rect.y = drect->y; + op_ge2d_info.dst_rect.w = drect->w; + op_ge2d_info.dst_rect.h = drect->h; + + ret = ioctl(fd, GE2D_STRETCHBLIT, &op_ge2d_info); + if (ret != 0) { + E_GE2D("%s,%d,ret %d,ioctl failed!\n",__FUNCTION__,__LINE__, ret); + return ge2d_fail; + } + return ge2d_success; +} + + +static int ge2d_strechblit_noalpha(int fd,rectangle_t *srect,rectangle_t *drect) +{ + int ret; + ge2d_op_para_t op_ge2d_info; + memset(&op_ge2d_info, 0, sizeof(ge2d_op_para_t)); + D_GE2D("stretchblit srect[%d %d %d %d] drect[%d %d %d %d]\n", + srect->x,srect->y,srect->w,srect->h,drect->x,drect->y,drect->w,drect->h); + + op_ge2d_info.src1_rect.x = srect->x; + op_ge2d_info.src1_rect.y = srect->y; + op_ge2d_info.src1_rect.w = srect->w; + op_ge2d_info.src1_rect.h = srect->h; + + op_ge2d_info.dst_rect.x = drect->x; + op_ge2d_info.dst_rect.y = drect->y; + op_ge2d_info.dst_rect.w = drect->w; + op_ge2d_info.dst_rect.h = drect->h; + + ret = ioctl(fd, GE2D_STRETCHBLIT_NOALPHA, &op_ge2d_info); + if (ret != 0) { + E_GE2D("%s,%d,ret %d,ioctl failed!\n",__FUNCTION__,__LINE__, ret); + return ge2d_fail; + } + return ge2d_success; +} + + +static int ge2d_blend(int fd,rectangle_t *srect,rectangle_t *srect2,rectangle_t *drect, unsigned int op) +{ + int ret; + ge2d_op_para_t op_ge2d_info; + ge2d_blend_op blend_op; + int max_d_w, max_d_h; + D_GE2D("ge2d_blend srect[%d %d %d %d], s2rect[%d %d %d %d],drect[%d %d %d %d]\n", + srect->x,srect->y,srect->w,srect->h, + srect2->x,srect2->y,srect2->w,srect2->h, + drect->x,drect->y,drect->w,drect->h); + memset(&blend_op,0,sizeof(ge2d_blend_op)); + max_d_w = (srect->w > srect2->w) ? srect2->w : srect->w; + max_d_h = (srect->h > srect2->h) ? srect2->h : srect->h; + if ((drect->w > max_d_w) || (drect->h > max_d_h)) { + /* dst rect must be min(srect,srect2),otherwise ge2d will timeout */ + E_GE2D("dst rect w=%d,h=%d out of range\n",drect->w,drect->h); + return ge2d_fail; + } + + op_ge2d_info.src1_rect.x = srect->x; + op_ge2d_info.src1_rect.y = srect->y; + op_ge2d_info.src1_rect.w = srect->w; + op_ge2d_info.src1_rect.h = srect->h; + + op_ge2d_info.src2_rect.x = srect2->x; + op_ge2d_info.src2_rect.y = srect2->y; + op_ge2d_info.src2_rect.w = srect2->w; + op_ge2d_info.src2_rect.h = srect2->h; + + op_ge2d_info.dst_rect.x = drect->x; + op_ge2d_info.dst_rect.y = drect->y; + op_ge2d_info.dst_rect.w = drect->w; + op_ge2d_info.dst_rect.h = drect->h; + + blend_op.color_blending_mode = OPERATION_ADD; + blend_op.alpha_blending_mode = OPERATION_ADD; + /* b_src_swap = 1:src1 & src2 swap, so blend factor used dst instead src */ + switch (op) { + case BLEND_MODE_NONE: + if (b_src_swap) { + blend_op.color_blending_src_factor = COLOR_FACTOR_ZERO; + blend_op.color_blending_dst_factor = COLOR_FACTOR_ONE; + blend_op.alpha_blending_src_factor = COLOR_FACTOR_ZERO; + blend_op.alpha_blending_dst_factor = COLOR_FACTOR_ONE; + } + else { + blend_op.color_blending_src_factor = COLOR_FACTOR_ONE; + blend_op.color_blending_dst_factor = COLOR_FACTOR_ZERO; + blend_op.alpha_blending_src_factor = COLOR_FACTOR_ONE; + blend_op.alpha_blending_dst_factor = COLOR_FACTOR_ZERO; + } + break; + case BLEND_MODE_PREMULTIPLIED: + if (b_src_swap) { + blend_op.color_blending_src_factor = COLOR_FACTOR_ONE_MINUS_DST_ALPHA; + blend_op.color_blending_dst_factor = COLOR_FACTOR_ONE; + blend_op.alpha_blending_src_factor = COLOR_FACTOR_ONE_MINUS_DST_ALPHA; + blend_op.alpha_blending_dst_factor = COLOR_FACTOR_ONE; + } + else { + blend_op.color_blending_src_factor = COLOR_FACTOR_ONE; + blend_op.color_blending_dst_factor = COLOR_FACTOR_ONE_MINUS_SRC_ALPHA; + blend_op.alpha_blending_src_factor = COLOR_FACTOR_ONE; + blend_op.alpha_blending_dst_factor = COLOR_FACTOR_ONE_MINUS_SRC_ALPHA; + } + break; + case BLEND_MODE_COVERAGE: + if (b_src_swap) { + blend_op.color_blending_src_factor = COLOR_FACTOR_ONE_MINUS_DST_ALPHA; + blend_op.color_blending_dst_factor = ALPHA_FACTOR_DST_ALPHA; + blend_op.alpha_blending_src_factor = ALPHA_FACTOR_ONE_MINUS_SRC_ALPHA; + blend_op.alpha_blending_dst_factor = ALPHA_FACTOR_DST_ALPHA; + } + else { + blend_op.color_blending_src_factor = COLOR_FACTOR_SRC_ALPHA; + blend_op.color_blending_dst_factor = COLOR_FACTOR_ONE_MINUS_SRC_ALPHA; + blend_op.alpha_blending_src_factor = ALPHA_FACTOR_SRC_ALPHA; + blend_op.alpha_blending_dst_factor = ALPHA_FACTOR_ONE_MINUS_SRC_ALPHA; + } + break; + case BLEND_MODE_INVALID: + return ge2d_fail; + } + + op_ge2d_info.op = blendop( + blend_op.color_blending_mode, + blend_op.color_blending_src_factor, + blend_op.color_blending_dst_factor, + blend_op.alpha_blending_mode, + blend_op.alpha_blending_src_factor, + blend_op.alpha_blending_dst_factor); + + D_GE2D("ge2d_blend op_ge2d_info.op=%x\n",op_ge2d_info.op); + ret = ioctl(fd, GE2D_BLEND, &op_ge2d_info); + if (ret != 0) { + E_GE2D("%s,%d,ret %d,ioctl failed!\n",__FUNCTION__,__LINE__, ret); + return ge2d_fail; + } + return ge2d_success; +} + + +static int ge2d_blend_noalpha(int fd,rectangle_t *srect,rectangle_t *srect2,rectangle_t *drect, unsigned int op) +{ + int ret; + ge2d_op_para_t op_ge2d_info; + ge2d_blend_op blend_op; + int max_d_w, max_d_h; + + D_GE2D("ge2d_blend srect[%d %d %d %d], s2rect[%d %d %d %d],drect[%d %d %d %d]\n", + srect->x,srect->y,srect->w,srect->h, + srect2->x,srect2->y,srect2->w,srect2->h, + drect->x,drect->y,drect->w,drect->h); + memset(&blend_op,0,sizeof(ge2d_blend_op)); + max_d_w = (srect->w > srect2->w) ? srect2->w : srect->w; + max_d_h = (srect->h > srect2->h) ? srect2->h : srect->h; + if ((drect->w > max_d_w) || (drect->h > max_d_h)) { + /* dst rect must be min(srect,srect2),otherwise ge2d will timeout */ + E_GE2D("dst rect w=%d,h=%d out of range\n",drect->w,drect->h); + return ge2d_fail; + } + + op_ge2d_info.src1_rect.x = srect->x; + op_ge2d_info.src1_rect.y = srect->y; + op_ge2d_info.src1_rect.w = srect->w; + op_ge2d_info.src1_rect.h = srect->h; + + op_ge2d_info.src2_rect.x = srect2->x; + op_ge2d_info.src2_rect.y = srect2->y; + op_ge2d_info.src2_rect.w = srect2->w; + op_ge2d_info.src2_rect.h = srect2->h; + + op_ge2d_info.dst_rect.x = drect->x; + op_ge2d_info.dst_rect.y = drect->y; + op_ge2d_info.dst_rect.w = drect->w; + op_ge2d_info.dst_rect.h = drect->h; + + blend_op.color_blending_mode = OPERATION_ADD; + blend_op.alpha_blending_mode = OPERATION_ADD; + /* b_src_swap = 1:src1 & src2 swap, so blend factor used dst instead src */ + switch (op) { + case BLEND_MODE_NONE: + if (b_src_swap) { + blend_op.color_blending_src_factor = COLOR_FACTOR_ZERO; + blend_op.color_blending_dst_factor = COLOR_FACTOR_ONE; + blend_op.alpha_blending_src_factor = COLOR_FACTOR_ZERO; + blend_op.alpha_blending_dst_factor = COLOR_FACTOR_ONE; + } + else { + blend_op.color_blending_src_factor = COLOR_FACTOR_ONE; + blend_op.color_blending_dst_factor = COLOR_FACTOR_ZERO; + blend_op.alpha_blending_src_factor = COLOR_FACTOR_ONE; + blend_op.alpha_blending_dst_factor = COLOR_FACTOR_ZERO; + } + break; + case BLEND_MODE_PREMULTIPLIED: + if (b_src_swap) { + blend_op.color_blending_src_factor = COLOR_FACTOR_ONE_MINUS_DST_ALPHA; + blend_op.color_blending_dst_factor = COLOR_FACTOR_ONE; + blend_op.alpha_blending_src_factor = COLOR_FACTOR_ONE_MINUS_DST_ALPHA; + blend_op.alpha_blending_dst_factor = COLOR_FACTOR_ONE; + } + else { + blend_op.color_blending_src_factor = COLOR_FACTOR_ONE; + blend_op.color_blending_dst_factor = COLOR_FACTOR_ONE_MINUS_SRC_ALPHA; + blend_op.alpha_blending_src_factor = COLOR_FACTOR_ONE; + blend_op.alpha_blending_dst_factor = COLOR_FACTOR_ONE_MINUS_SRC_ALPHA; + } + break; + case BLEND_MODE_COVERAGE: + if (b_src_swap) { + blend_op.color_blending_src_factor = COLOR_FACTOR_ONE_MINUS_DST_ALPHA; + blend_op.color_blending_dst_factor = ALPHA_FACTOR_DST_ALPHA; + blend_op.alpha_blending_src_factor = ALPHA_FACTOR_ONE_MINUS_SRC_ALPHA; + blend_op.alpha_blending_dst_factor = ALPHA_FACTOR_DST_ALPHA; + } + else { + blend_op.color_blending_src_factor = COLOR_FACTOR_SRC_ALPHA; + blend_op.color_blending_dst_factor = COLOR_FACTOR_ONE_MINUS_SRC_ALPHA; + blend_op.alpha_blending_src_factor = ALPHA_FACTOR_SRC_ALPHA; + blend_op.alpha_blending_dst_factor = ALPHA_FACTOR_ONE_MINUS_SRC_ALPHA; + } + break; + case BLEND_MODE_INVALID: + return ge2d_fail; + } + + + op_ge2d_info.op = blendop( + blend_op.color_blending_mode, + blend_op.color_blending_src_factor, + blend_op.color_blending_dst_factor, + blend_op.alpha_blending_mode, + blend_op.alpha_blending_src_factor, + blend_op.alpha_blending_dst_factor); + + D_GE2D("ge2d_blend op_ge2d_info.op=%x\n",op_ge2d_info.op); + ret = ioctl(fd, GE2D_BLEND_NOALPHA, &op_ge2d_info); + if (ret != 0) { + E_GE2D("%s,%d,ret %d,ioctl failed!\n",__FUNCTION__,__LINE__, ret); + return ge2d_fail; + } + return ge2d_success; +} + + + + + +int ge2d_open(void) +{ + int fd = -1; + fd = open(FILE_NAME_GE2D, O_RDWR); + if (fd < 0) { + E_GE2D("open %s failed!error no %d\n",FILE_NAME_GE2D,errno); + } + return fd; +} + + + +int ge2d_close(int fd) +{ + int ret = -1; + ret = close(fd); + if (ret < 0) + return -errno; + return ret; +} + +int ge2d_process(int fd,aml_ge2d_info_t *pge2dinfo) +{ + rectangle_t src_rect[2]; + rectangle_t dst_rect; + int dx = 0, dy = 0; + if (!pge2dinfo) { + E_GE2D("pge2dinfo is NULL!\n"); + return ge2d_fail; + } + + switch (pge2dinfo->ge2d_op) { + case AML_GE2D_FILLRECTANGLE: + dst_rect.w = pge2dinfo->dst_info.rect.w; + dst_rect.h = pge2dinfo->dst_info.rect.h; + dst_rect.x = pge2dinfo->dst_info.rect.x; + dst_rect.y = pge2dinfo->offset + pge2dinfo->dst_info.rect.y; + + ge2d_fillrectangle_config_ex(fd,pge2dinfo); + ge2d_fillrectangle(fd,&dst_rect,pge2dinfo->color); + break; + case AML_GE2D_BLIT: + if (!is_rect_valid(&pge2dinfo->src_info[0])) + return ge2d_fail; + if (!is_rect_valid(&pge2dinfo->dst_info)) + return ge2d_fail; + + dx = pge2dinfo->dst_info.rect.x; + dy = pge2dinfo->offset + pge2dinfo->dst_info.rect.y; + ge2d_blit_config_ex(fd,pge2dinfo); + if (is_no_alpha(pge2dinfo->src_info[0].format)) + ge2d_blit_noalpha(fd,&pge2dinfo->src_info[0].rect,dx,dy); + else + ge2d_blit(fd,&pge2dinfo->src_info[0].rect,dx,dy); + break; + case AML_GE2D_STRETCHBLIT: + if (!is_rect_valid(&pge2dinfo->src_info[0])) + return ge2d_fail; + if (!is_rect_valid(&pge2dinfo->dst_info)) + return ge2d_fail; + + dst_rect.w = pge2dinfo->dst_info.rect.w; + dst_rect.h = pge2dinfo->dst_info.rect.h; + dst_rect.x = pge2dinfo->dst_info.rect.x; + dst_rect.y = pge2dinfo->offset + pge2dinfo->dst_info.rect.y; + ge2d_blit_config_ex(fd,pge2dinfo); + if (is_no_alpha(pge2dinfo->src_info[0].format)) + ge2d_strechblit_noalpha(fd,&pge2dinfo->src_info[0].rect,&dst_rect); + else + ge2d_strechblit(fd,&pge2dinfo->src_info[0].rect,&dst_rect); + break; + case AML_GE2D_BLEND: + if ((pge2dinfo->dst_info.memtype == CANVAS_OSD0) && (pge2dinfo->src_info[1].memtype == CANVAS_OSD0)) { + memcpy(&pge2dinfo->src_info[1],&pge2dinfo->dst_info,sizeof(buffer_info_t)); + pge2dinfo->src_info[1].rect.y = pge2dinfo->offset + pge2dinfo->src_info[1].rect.y; + } + if (!is_rect_valid(&pge2dinfo->src_info[0])) + return ge2d_fail; + if (!is_rect_valid(&pge2dinfo->src_info[1])) + return ge2d_fail; + if (!is_rect_valid(&pge2dinfo->dst_info)) + return ge2d_fail; + + dst_rect.w = pge2dinfo->dst_info.rect.w; + dst_rect.h = pge2dinfo->dst_info.rect.h; + dst_rect.x = pge2dinfo->dst_info.rect.x; + dst_rect.y = pge2dinfo->offset + pge2dinfo->dst_info.rect.y; + ge2d_blend_config_ex(fd,pge2dinfo); + if ((is_no_alpha(pge2dinfo->src_info[0].format)) || (is_no_alpha(pge2dinfo->src_info[1].format))) { + if (b_src_swap) + ge2d_blend_noalpha(fd,&(pge2dinfo->src_info[1].rect), + &(pge2dinfo->src_info[0].rect), + &dst_rect,pge2dinfo->blend_mode); + else + ge2d_blend_noalpha(fd,&(pge2dinfo->src_info[0].rect), + &(pge2dinfo->src_info[1].rect), + &dst_rect,pge2dinfo->blend_mode); + } + else { + if (b_src_swap) + ge2d_blend(fd,&(pge2dinfo->src_info[1].rect), + &(pge2dinfo->src_info[0].rect), + &dst_rect,pge2dinfo->blend_mode); + else + ge2d_blend(fd,&(pge2dinfo->src_info[0].rect), + &(pge2dinfo->src_info[1].rect), + &dst_rect,pge2dinfo->blend_mode); + } + break; + default: + E_GE2D("ge2d(%d) opration not support!\n",pge2dinfo->ge2d_op); + return ge2d_fail; + } + return ge2d_success; +} + + diff --git a/libge2d/include/IONmem.h b/libge2d/include/IONmem.h new file mode 100644 index 0000000..c14d957 --- a/dev/null +++ b/libge2d/include/IONmem.h @@ -0,0 +1,49 @@ +#ifndef IONMEM_H +#define IONMEM_H +#include <ion/ion.h> +#if defined (__cplusplus) +extern "C" { +#endif + +#define ION_IOC_MESON_PHYS_ADDR 8 + + +struct meson_phys_data{ + int handle; + unsigned int phys_addr; + unsigned int size; +}; + +typedef struct IONMEM_AllocParams { + ion_user_handle_t mIonHnd; + int mImageFd; + size_t size; + unsigned char *usr_ptr; +} IONMEM_AllocParams; + + +#define ION_IOC_MAGIC 'I' + +#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data) + +#ifdef __DEBUG +#define __D(fmt, args...) fprintf(stderr, "CMEM Debug: " fmt, ## args) +#else +#define __D(fmt, args...) +#endif + +#define __E(fmt, args...) fprintf(stderr, "CMEM Error: " fmt, ## args) + + +int CMEM_init(void); +unsigned long CMEM_alloc(size_t size, IONMEM_AllocParams *params); +/*void* CMEM_getUsrPtr(unsigned long PhyAdr, int size);*/ +int CMEM_free(IONMEM_AllocParams *params); +int CMEM_exit(void); + +#if defined (__cplusplus) +} +#endif + +#endif + diff --git a/libge2d/include/aml_ge2d.h b/libge2d/include/aml_ge2d.h new file mode 100644 index 0000000..796ce2f --- a/dev/null +++ b/libge2d/include/aml_ge2d.h @@ -0,0 +1,31 @@ +#ifndef AML_GE2D_H_ +#define AML_GE2D_H_ + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef struct aml_ge2d { + aml_ge2d_info_t *pge2d_info; + char *src_data; + char *src2_data; + char *dst_data; + unsigned int src_size; + unsigned int src2_size; + unsigned int dst_size; +} aml_ge2d_t; + +int aml_ge2d_init(void); +void aml_ge2d_exit(void); + +int aml_ge2d_mem_alloc(aml_ge2d_info_t *pge2dinfo); +void aml_ge2d_mem_free(aml_ge2d_info_t *pge2dinfo); +int aml_ge2d_process(aml_ge2d_info_t *pge2dinfo); + +#if defined (__cplusplus) +} +#endif + + +#endif + diff --git a/libge2d/include/ge2d_com.h b/libge2d/include/ge2d_com.h new file mode 100644 index 0000000..1e18764 --- a/dev/null +++ b/libge2d/include/ge2d_com.h @@ -0,0 +1,43 @@ +#ifndef GE2D_COM_H_ +#define GE2D_COM_H_ + +#include <stdio.h> +#include <stdlib.h> +#include <malloc.h> +#include <string.h> + +#define LOG_TAG "ge2d" + +#include <cutils/log.h> + + +#define __DEBUG + +#ifdef __DEBUG +#define D_GE2D(fmt, args...) ALOGD("GE2D Debug: " fmt, ## args) +#else +#define D_GE2D(fmt, args...) +#endif +#define E_GE2D(fmt, args...) ALOGE("GE2D Error: " fmt, ## args) + +typedef struct{ + unsigned int color; + rectangle_t src1_rect; + rectangle_t src2_rect; + rectangle_t dst_rect; + int op; +}ge2d_op_para_t; + + + +typedef struct{ + unsigned int color_blending_mode; + unsigned int color_blending_src_factor; + unsigned int color_blending_dst_factor; + unsigned int alpha_blending_mode; + unsigned int alpha_blending_src_factor; + unsigned int alpha_blending_dst_factor; +}ge2d_blend_op; + + +#endif diff --git a/libge2d/include/ge2d_port.h b/libge2d/include/ge2d_port.h new file mode 100644 index 0000000..1a16a38 --- a/dev/null +++ b/libge2d/include/ge2d_port.h @@ -0,0 +1,114 @@ +#ifndef GE2D_PORT_H_ +#define GE2D_PORT_H_ + +#define ge2d_fail -1 +#define ge2d_success 0 + +#define OSD0 0 +#define OSD1 1 + + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef enum { + GE2D_CANVAS_OSD0 = 0, + GE2D_CANVAS_OSD1, + GE2D_CANVAS_ALLOC, + GE2D_CANVAS_TYPE_INVALID, +}ge2d_canvas_t; + + +/* Blend modes, settable per layer */ +typedef enum { + BLEND_MODE_INVALID = 0, + + /* colorOut = colorSrc */ + BLEND_MODE_NONE = 1, + + /* colorOut = colorSrc + colorDst * (1 - alphaSrc) */ + BLEND_MODE_PREMULTIPLIED = 2, + + /* colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc) */ + BLEND_MODE_COVERAGE = 3, +} blend_mode_t; + + + + +/** + * pixel format definitions + */ + +typedef enum { + PIXEL_FORMAT_RGBA_8888 = 1, + PIXEL_FORMAT_RGBX_8888 = 2, + PIXEL_FORMAT_RGB_888 = 3, + PIXEL_FORMAT_RGB_565 = 4, + PIXEL_FORMAT_BGRA_8888 = 5, + PIXEL_FORMAT_YV12 = 0x32315659, // YCrCb 4:2:0 Planar YYYY...... U......V...... + PIXEL_FORMAT_Y8 = 0x20203859, // YYYY + PIXEL_FORMAT_YCbCr_422_SP = 0x10, // NV16 YYYY.....UVUV.... + PIXEL_FORMAT_YCrCb_420_SP = 0x11, // NV21 YYYY.....UV.... + PIXEL_FORMAT_YCbCr_422_I = 0x14, // YUY2 Y0 U0 Y1 V0 +}pixel_format_t; + +typedef enum { + GE2D_ROTATION_0, + GE2D_ROTATION_90, + GE2D_ROTATION_180, + GE2D_ROTATION_270, +} GE2D_ROTATION; + + +typedef enum { + AML_GE2D_FILLRECTANGLE, + AML_GE2D_BLEND, + AML_GE2D_STRETCHBLIT, + AML_GE2D_BLIT, + AML_GE2D_NONE, +} GE2DOP; + + +typedef struct{ + int x; + int y; + int w; + int h; +}rectangle_t; + + +typedef struct buffer_info { + unsigned int memtype; + char* vaddr; + unsigned long paddr; + unsigned int canvas_w; + unsigned int canvas_h; + rectangle_t rect; + int format; + unsigned int rotation; +} buffer_info_t; + + + +typedef struct aml_ge2d_info { + unsigned int offset; + unsigned int blend_mode; + GE2DOP ge2d_op; + buffer_info_t src_info[2]; + buffer_info_t dst_info; + unsigned int color; + unsigned int gl_alpha; +} aml_ge2d_info_t; + + +int ge2d_open(void); +int ge2d_close(int fd); +int ge2d_process(int fd,aml_ge2d_info_t *pge2dinfo); + +#if defined (__cplusplus) +} +#endif + +#endif diff --git a/libge2d/kernel-headers/linux/ge2d.h b/libge2d/kernel-headers/linux/ge2d.h new file mode 100644 index 0000000..e3e5dc0 --- a/dev/null +++ b/libge2d/kernel-headers/linux/ge2d.h @@ -0,0 +1,289 @@ +/**************************************************************************** +** +** Copyright (C) 2010 AMLOGIC, INC. +** All rights reserved. +****************************************************************************/ + +#ifndef GE2D_H +#define GE2D_H + + +#define OPERATION_ADD 0 /* Cd = Cs*Fs+Cd*Fd */ +#define OPERATION_SUB 1 /* Cd = Cs*Fs-Cd*Fd */ +#define OPERATION_REVERSE_SUB 2 /* Cd = Cd*Fd-Cs*Fs */ +#define OPERATION_MIN 3 /* Cd = Min(Cd*Fd,Cs*Fs) */ +#define OPERATION_MAX 4 /* Cd = Max(Cd*Fd,Cs*Fs) */ +#define OPERATION_LOGIC 5 + +#define COLOR_FACTOR_ZERO 0 +#define COLOR_FACTOR_ONE 1 +#define COLOR_FACTOR_SRC_COLOR 2 +#define COLOR_FACTOR_ONE_MINUS_SRC_COLOR 3 +#define COLOR_FACTOR_DST_COLOR 4 +#define COLOR_FACTOR_ONE_MINUS_DST_COLOR 5 +#define COLOR_FACTOR_SRC_ALPHA 6 +#define COLOR_FACTOR_ONE_MINUS_SRC_ALPHA 7 +#define COLOR_FACTOR_DST_ALPHA 8 +#define COLOR_FACTOR_ONE_MINUS_DST_ALPHA 9 +#define COLOR_FACTOR_CONST_COLOR 10 +#define COLOR_FACTOR_ONE_MINUS_CONST_COLOR 11 +#define COLOR_FACTOR_CONST_ALPHA 12 +#define COLOR_FACTOR_ONE_MINUS_CONST_ALPHA 13 +#define COLOR_FACTOR_SRC_ALPHA_SATURATE 14 + +#define ALPHA_FACTOR_ZERO 0 +#define ALPHA_FACTOR_ONE 1 +#define ALPHA_FACTOR_SRC_ALPHA 2 +#define ALPHA_FACTOR_ONE_MINUS_SRC_ALPHA 3 +#define ALPHA_FACTOR_DST_ALPHA 4 +#define ALPHA_FACTOR_ONE_MINUS_DST_ALPHA 5 +#define ALPHA_FACTOR_CONST_ALPHA 6 +#define ALPHA_FACTOR_ONE_MINUS_CONST_ALPHA 7 + + +#define GE2D_BLEND_NOALPHA_NOBLOCK 0x470a +#define GE2D_BLEND_NOALPHA 0x4709 +#define GE2D_STRETCHBLIT_NOALPHA 0x4702 +#define GE2D_BLIT_NOALPHA 0x4701 +#define GE2D_BLEND 0x4700 +#define GE2D_BLIT 0x46ff +#define GE2D_STRETCHBLIT 0x46fe +#define GE2D_FILLRECTANGLE 0x46fd +#define GE2D_SET_COEF 0x46fb +#define GE2D_ANTIFLICKER_ENABLE 0x46f8 + +typedef enum { + OSD0_OSD0 = 0, + OSD0_OSD1, + OSD1_OSD1, + OSD1_OSD0, + ALLOC_OSD0, + ALLOC_OSD1, + ALLOC_ALLOC, + TYPE_INVALID, +} ge2d_src_dst_t; + +enum ge2d_src_canvas_type_e { + CANVAS_OSD0 = 0, + CANVAS_OSD1, + CANVAS_ALLOC, + CANVAS_TYPE_INVALID, +}; + +struct config_planes_s { + unsigned long addr; + unsigned int w; + unsigned int h; +}; + +struct src_key_ctrl_s { + int key_enable; + int key_color; + int key_mask; + int key_mode; +}; + +struct config_para_s { + int src_dst_type; + int alu_const_color; + unsigned int src_format; + unsigned int dst_format ; //add for src&dst all in user space. + struct config_planes_s src_planes[4]; + struct config_planes_s dst_planes[4]; + struct src_key_ctrl_s src_key; +}; + + + +struct rectangle_s { + int x; /* X coordinate of its top-left point */ + int y; /* Y coordinate of its top-left point */ + int w; /* width of it */ + int h; /* height of it */ +}; + +struct ge2d_para_s { + unsigned int color ; + struct rectangle_s src1_rect; + struct rectangle_s src2_rect; + struct rectangle_s dst_rect; + int op; +}; + +struct src_dst_para_ex_s { + int canvas_index; + int top; + int left; + int width; + int height; + int format; + int mem_type; + int color; + unsigned char x_rev; + unsigned char y_rev; + unsigned char fill_color_en; + unsigned char fill_mode; +}; + +struct config_para_ex_s { + struct src_dst_para_ex_s src_para; + struct src_dst_para_ex_s src2_para; + struct src_dst_para_ex_s dst_para; + + /* key mask */ + struct src_key_ctrl_s src_key; + struct src_key_ctrl_s src2_key; + + int alu_const_color; + unsigned src1_gb_alpha; + unsigned op_mode; + unsigned char bitmask_en; + unsigned char bytemask_only; + unsigned int bitmask; + unsigned char dst_xy_swap; + + /* scaler and phase releated */ + unsigned hf_init_phase; + int hf_rpt_num; + unsigned hsc_start_phase_step; + int hsc_phase_slope; + unsigned vf_init_phase; + int vf_rpt_num; + unsigned vsc_start_phase_step; + int vsc_phase_slope; + unsigned char src1_vsc_phase0_always_en; + unsigned char src1_hsc_phase0_always_en; + /* 1bit, 0: using minus, 1: using repeat data */ + unsigned char src1_hsc_rpt_ctrl; + /* 1bit, 0: using minus 1: using repeat data */ + unsigned char src1_vsc_rpt_ctrl; + + /* canvas info */ + struct config_planes_s src_planes[4]; + struct config_planes_s src2_planes[4]; + struct config_planes_s dst_planes[4]; +}; + +#define GE2D_ENDIAN_SHIFT 24 +#define GE2D_ENDIAN_MASK (0x1 << GE2D_ENDIAN_SHIFT) +#define GE2D_BIG_ENDIAN (0 << GE2D_ENDIAN_SHIFT) +#define GE2D_LITTLE_ENDIAN (1 << GE2D_ENDIAN_SHIFT) + +#define GE2D_COLOR_MAP_SHIFT 20 +#define GE2D_COLOR_MAP_MASK (0xf << GE2D_COLOR_MAP_SHIFT) +/* 16 bit */ +#define GE2D_COLOR_MAP_YUV422 (0 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_RGB655 (1 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_YUV655 (1 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_RGB844 (2 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_YUV844 (2 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_RGBA6442 (3 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_YUVA6442 (3 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_RGBA4444 (4 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_YUVA4444 (4 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_RGB565 (5 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_YUV565 (5 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_ARGB4444 (6 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_AYUV4444 (6 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_ARGB1555 (7 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_AYUV1555 (7 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_RGBA4642 (8 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_YUVA4642 (8 << GE2D_COLOR_MAP_SHIFT) +/* 24 bit */ +#define GE2D_COLOR_MAP_RGB888 (0 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_YUV444 (0 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_RGBA5658 (1 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_YUVA5658 (1 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_ARGB8565 (2 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_AYUV8565 (2 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_RGBA6666 (3 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_YUVA6666 (3 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_ARGB6666 (4 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_AYUV6666 (4 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_BGR888 (5 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_VUY888 (5 << GE2D_COLOR_MAP_SHIFT) +/* 32 bit */ +#define GE2D_COLOR_MAP_RGBA8888 (0 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_YUVA8888 (0 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_ARGB8888 (1 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_AYUV8888 (1 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_ABGR8888 (2 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_AVUY8888 (2 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_BGRA8888 (3 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_VUYA8888 (3 << GE2D_COLOR_MAP_SHIFT) +#define GE2D_COLOR_MAP_NV21 (14 << GE2D_COLOR_MAP_SHIFT) + +#define GE2D_FMT_S8_Y 0x00000 /* 00_00_0_00_0_00 */ +#define GE2D_FMT_S8_CB 0x00040 /* 00_01_0_00_0_00 */ +#define GE2D_FMT_S8_CR 0x00080 /* 00_10_0_00_0_00 */ +#define GE2D_FMT_S8_R 0x00000 /* 00_00_0_00_0_00 */ +#define GE2D_FMT_S8_G 0x00040 /* 00_01_0_00_0_00 */ +#define GE2D_FMT_S8_B 0x00080 /* 00_10_0_00_0_00 */ +#define GE2D_FMT_S8_A 0x000c0 /* 00_11_0_00_0_00 */ +#define GE2D_FMT_S8_LUT 0x00020 /* 00_00_1_00_0_00 */ +#define GE2D_FMT_S16_YUV422 0x20100 /* 01_00_0_00_0_00 */ +#define GE2D_FMT_S16_RGB (GE2D_LITTLE_ENDIAN|0x00100) /* 01_00_0_00_0_00 */ +#define GE2D_FMT_S24_YUV444 0x20200 /* 10_00_0_00_0_00 */ +#define GE2D_FMT_S24_RGB (GE2D_LITTLE_ENDIAN|0x00200) /* 10_00_0_00_0_00 */ +#define GE2D_FMT_S32_YUVA444 0x20300 /* 11_00_0_00_0_00 */ +#define GE2D_FMT_S32_RGBA (GE2D_LITTLE_ENDIAN|0x00300) /* 11_00_0_00_0_00 */ +#define GE2D_FMT_M24_YUV420 0x20007 /* 00_00_0_00_1_11 */ +#define GE2D_FMT_M24_YUV422 0x20006 /* 00_00_0_00_1_10 */ +#define GE2D_FMT_M24_YUV444 0x20004 /* 00_00_0_00_1_00 */ +#define GE2D_FMT_M24_RGB 0x00004 /* 00_00_0_00_1_00 */ +#define GE2D_FMT_M24_YUV420T 0x20017 /* 00_00_0_10_1_11 */ +#define GE2D_FMT_M24_YUV420B 0x2001f /* 00_00_0_11_1_11 */ +#define GE2D_FMT_S16_YUV422T 0x20110 /* 01_00_0_10_0_00 */ +#define GE2D_FMT_S16_YUV422B 0x20138 /* 01_00_0_11_0_00 */ +#define GE2D_FMT_S24_YUV444T 0x20210 /* 10_00_0_10_0_00 */ +#define GE2D_FMT_S24_YUV444B 0x20218 /* 10_00_0_11_0_00 */ +#define GE2D_FMT_M24_YUV420SP 0x20207 + +#define GE2D_FORMAT_S8_Y (GE2D_FMT_S8_Y) +#define GE2D_FORMAT_S8_CB (GE2D_FMT_S8_CB) +#define GE2D_FORMAT_S8_CR (GE2D_FMT_S8_CR) +#define GE2D_FORMAT_S8_R (GE2D_FMT_S8_R) +#define GE2D_FORMAT_S8_G (GE2D_FMT_S8_G) +#define GE2D_FORMAT_S8_B (GE2D_FMT_S8_B) +#define GE2D_FORMAT_S8_A (GE2D_FMT_S8_A) +#define GE2D_FORMAT_S8_LUT (GE2D_FMT_S8_LUT) +#define GE2D_FORMAT_S16_YUV422 (GE2D_FMT_S16_YUV422 | GE2D_COLOR_MAP_YUV422) +#define GE2D_FORMAT_S16_RGB_655 (GE2D_FMT_S16_RGB | GE2D_COLOR_MAP_RGB655) +#define GE2D_FORMAT_S16_RGB_565 (GE2D_FMT_S16_RGB | GE2D_COLOR_MAP_RGB565) +#define GE2D_FORMAT_S16_RGB_844 (GE2D_FMT_S16_RGB | GE2D_COLOR_MAP_RGB844) +#define GE2D_FORMAT_S16_RGBA_6442 (GE2D_FMT_S16_RGB | GE2D_COLOR_MAP_RGBA6442) +#define GE2D_FORMAT_S16_RGBA_4444 (GE2D_FMT_S16_RGB | GE2D_COLOR_MAP_RGBA4444) +#define GE2D_FORMAT_S16_ARGB_4444 (GE2D_FMT_S16_RGB | GE2D_COLOR_MAP_ARGB4444) +#define GE2D_FORMAT_S16_ARGB_1555 (GE2D_FMT_S16_RGB | GE2D_COLOR_MAP_ARGB1555) +#define GE2D_FORMAT_S16_RGBA_4642 (GE2D_FMT_S16_RGB | GE2D_COLOR_MAP_RGBA4642) +#define GE2D_FORMAT_S24_YUV444 (GE2D_FMT_S24_YUV444 | GE2D_COLOR_MAP_YUV444) +#define GE2D_FORMAT_S24_RGB (GE2D_FMT_S24_RGB | GE2D_COLOR_MAP_RGB888) +#define GE2D_FORMAT_S32_YUVA444 (GE2D_FMT_S32_YUVA444 | GE2D_COLOR_MAP_YUVA4444) +#define GE2D_FORMAT_S32_RGBA (GE2D_FMT_S32_RGBA | GE2D_COLOR_MAP_RGBA8888) +#define GE2D_FORMAT_S32_ARGB (GE2D_FMT_S32_RGBA | GE2D_COLOR_MAP_ARGB8888) +#define GE2D_FORMAT_S32_ABGR (GE2D_FMT_S32_RGBA | GE2D_COLOR_MAP_ABGR8888) +#define GE2D_FORMAT_S32_BGRA (GE2D_FMT_S32_RGBA | GE2D_COLOR_MAP_BGRA8888) +#define GE2D_FORMAT_S24_RGBA_5658 (GE2D_FMT_S24_RGB | GE2D_COLOR_MAP_RGBA5658) +#define GE2D_FORMAT_S24_ARGB_8565 (GE2D_FMT_S24_RGB | GE2D_COLOR_MAP_ARGB8565) +#define GE2D_FORMAT_S24_RGBA_6666 (GE2D_FMT_S24_RGB | GE2D_COLOR_MAP_RGBA6666) +#define GE2D_FORMAT_S24_ARGB_6666 (GE2D_FMT_S24_RGB | GE2D_COLOR_MAP_ARGB6666) +#define GE2D_FORMAT_S24_BGR (GE2D_FMT_S24_RGB | GE2D_COLOR_MAP_BGR888) +#define GE2D_FORMAT_M24_YUV420 (GE2D_FMT_M24_YUV420) +#define GE2D_FORMAT_M24_YUV422 (GE2D_FMT_M24_YUV422) +#define GE2D_FORMAT_M24_YUV444 (GE2D_FMT_M24_YUV444) +#define GE2D_FORMAT_M24_RGB (GE2D_FMT_M24_RGB) +#define GE2D_FORMAT_M24_YUV420T (GE2D_FMT_M24_YUV420T) +#define GE2D_FORMAT_M24_YUV420B (GE2D_FMT_M24_YUV420B) +#define GE2D_FORMAT_S16_YUV422T (GE2D_FMT_S16_YUV422T | GE2D_COLOR_MAP_YUV422) +#define GE2D_FORMAT_S16_YUV422B (GE2D_FMT_S16_YUV422B | GE2D_COLOR_MAP_YUV422) +#define GE2D_FORMAT_S24_YUV444T (GE2D_FMT_S24_YUV444T | GE2D_COLOR_MAP_YUV444) +#define GE2D_FORMAT_S24_YUV444B (GE2D_FMT_S24_YUV444B | GE2D_COLOR_MAP_YUV444) +#define GE2D_FORMAT_M24_NV21 (GE2D_FMT_M24_YUV420SP | GE2D_COLOR_MAP_NV21) + +#define GE2D_IOC_MAGIC 'G' + +#define GE2D_CONFIG _IOW(GE2D_IOC_MAGIC, 0x00, struct config_para_s) +#define GE2D_CONFIG_EX _IOW(GE2D_IOC_MAGIC, 0x01, struct config_para_ex_s) +#define GE2D_SRCCOLORKEY _IOW(GE2D_IOC_MAGIC, 0x02, struct config_para_s) + +#endif /* GE2D_H */ diff --git a/libge2d/readme.txt b/libge2d/readme.txt new file mode 100644 index 0000000..b2aab2c --- a/dev/null +++ b/libge2d/readme.txt @@ -0,0 +1,80 @@ +libge2d user guide
+API:
+int ge2d_open(void);
+int ge2d_close(int fd);
+int ge2d_process(int fd,aml_ge2d_info_t *pge2dinfo);
+
+
+typedef struct aml_ge2d_info {
+ unsigned int offset;
+ unsigned int blend_mode;
+ GE2DOP ge2d_op;
+ buffer_info_t src_info[2];
+ buffer_info_t dst_info;
+ unsigned int color;
+ unsigned int gl_alpha;
+} aml_ge2d_info_t;
+其数据结构含义如下:
+unsigned int offset: osd的y_offset;
+unsigned int blend_mode: blend_mode 只对blend操作有效;
+unsigned int color: 目前只对fillrectangle有效;
+GE2DOP ge2d_op: ge2d支持的操作
+ge2d支持的操作:
+ AML_GE2D_FILLRECTANGLE,
+ AML_GE2D_BLEND,
+ AML_GE2D_STRETCHBLIT,
+ AML_GE2D_BLIT,
+
+typedef struct buffer_info {
+ unsigned int memtype;
+ char* vaddr;
+ unsigned long paddr;
+ unsigned int canvas_w;
+ unsigned int canvas_h;
+ rectangle_t rect;
+ int format;
+ unsigned int rotation;
+} buffer_info_t;
+其数据结构含义如下:
+memtype: 如果由mem alloc,则设为:CANVAS_ALLOC
+ 如果使用osd,则设为:CANVAS_OSD0/CANVAS_OSD1
+char* vaddr: 不填,for debug
+unsigned long paddr; 如果由mem alloc,则填写mem phy addr
+ 如果使用osd,则不设,kernel会自行获取;
+unsigned int canvas_w;
+unsigned int canvas_h; 如果由mem alloc,则填写canvas width,height, related to mem size.
+ 如果使用osd,则不设,kernel会自行获取;
+int format; 如果由mem alloc,则填写pixel format
+ 如果使用osd,则不设,kernel会自行获取;
+rectangle_t rect; 根据实际情况填写rect,必须填;
+unsigned int rotation; 可设为0/90/180/270;
+
+1. AML_GE2D_FILLRECTANGLE 需要设置的数据结构内容如下:
+需要设置:
+src_info[0];
+dst_info;
+color;
+offset;
+
+2.AML_GE2D_BLEND需要设置的数据结构内容如下:
+需要设置:
+src_info[0];
+src_info[1];
+dst_info;
+blend_mode;
+offset;
+
+3.AML_GE2D_STRETCHBLIT 需要设置的数据结构内容如下:
+需要设置:
+src_info[0];
+dst_info;
+offset;
+
+3.AML_GE2D_BLIT 需要设置的数据结构内容如下:
+需要设置:
+src_info[0];
+dst_info;
+offset;
+
+
+
|