717 lines
16 KiB
C
717 lines
16 KiB
C
/*
|
|
* Copyright (C) 2022-2023 ArtinChip Technology Co., Ltd.
|
|
* Authors: ZeQuan Liang <zequan.liang@artinchip.com>
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include <signal.h>
|
|
#include <sys/time.h>
|
|
#include <linux/fb.h>
|
|
#include <linux/dma-buf.h>
|
|
#include <linux/dma-heap.h>
|
|
|
|
#include "artinchip/sample_base.h"
|
|
#include "video/artinchip_fb.h"
|
|
#include "mpp_ge.h"
|
|
|
|
#define BYTE_ALIGN(x, byte) (((x) + ((byte) - 1))&(~((byte) - 1)))
|
|
|
|
#define FB_DEV "/dev/fb0"
|
|
#define DMA_HEAP_DEV "/dev/dma_heap/reserved"
|
|
#define SINGER_32BIT_IMAGE DATADIR"/singer_alpha.bmp"
|
|
|
|
#define SRC_DISP_REGION 0
|
|
#define DST_DISP_REGION 1
|
|
|
|
/* str to format table struct */
|
|
struct StrToFormat {
|
|
char *str;
|
|
int format;
|
|
};
|
|
|
|
/* bmp header format */
|
|
#pragma pack(push, 1)
|
|
struct BmpHeader {
|
|
unsigned short type;
|
|
unsigned int size;
|
|
unsigned short reserved1;
|
|
unsigned short reserved2;
|
|
unsigned int offset;
|
|
|
|
unsigned int dib_size;
|
|
int width;
|
|
int height;
|
|
unsigned short planes;
|
|
unsigned short bit_count;
|
|
unsigned int compression;
|
|
unsigned int size_image;
|
|
int x_meter;
|
|
int y_meter;
|
|
unsigned int clr_used;
|
|
unsigned int clr_important;
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
static int g_screen_w = 0;
|
|
static int g_screen_h = 0;
|
|
static int g_fb_fd = 0;
|
|
static int g_fb_len = 0;
|
|
static int g_fb_stride = 0;
|
|
static unsigned int g_fb_format = 0;
|
|
static unsigned int g_fb_phy = 0;
|
|
static unsigned char *g_fb_buf = NULL;
|
|
struct BmpHeader bmp_header = {0};
|
|
|
|
static void usage(char *app)
|
|
{
|
|
printf("Usage: %s [Options], built on %s %s\n", app, __DATE__, __TIME__);
|
|
printf("\t-o, --dither_on, Select open dither (default 0), 0 :close 1 :open\n");
|
|
printf("\t-s, --src_format, Select src format (default argb8888)\n");
|
|
printf("\t-d, --dst_format, Select dst format (default argb4444)\n");
|
|
|
|
printf("\t-u, --usage\n");
|
|
printf("\t-h, --help, list the supported format and the test instructions\n\n");
|
|
}
|
|
|
|
static void help(void)
|
|
{
|
|
printf("\r--This is ge bitblt operation using dither function.\n");
|
|
printf("\r--Dither supports input argb8888 and argb888 formats, and output argb4444, argb1555 and argb565 formats.\n");
|
|
printf("\r--In this example, the input layer is src, output layer is dst.\n");
|
|
printf("\r--In addition, the uppercase and lowercase letters of the src and dst parameters does not affect.\n");
|
|
|
|
printf("\r--Please use parameter -u or --usage to list other parameters.\n\n");
|
|
}
|
|
|
|
static int fb_open(void)
|
|
{
|
|
struct fb_fix_screeninfo fix;
|
|
struct fb_var_screeninfo var;
|
|
struct aicfb_layer_data layer;
|
|
|
|
g_fb_fd = open(FB_DEV, O_RDWR);
|
|
if (g_fb_fd == -1) {
|
|
ERR("open %s", FB_DEV);
|
|
return -1;
|
|
}
|
|
|
|
if (ioctl(g_fb_fd, FBIOGET_FSCREENINFO, &fix) < 0) {
|
|
ERR("ioctl FBIOGET_FSCREENINFO");
|
|
close(g_fb_fd);
|
|
return -1;
|
|
}
|
|
|
|
if (ioctl(g_fb_fd, FBIOGET_VSCREENINFO, &var) < 0) {
|
|
ERR("ioctl FBIOGET_VSCREENINFO");
|
|
close(g_fb_fd);
|
|
return -1;
|
|
}
|
|
|
|
if(ioctl(g_fb_fd, AICFB_GET_FB_LAYER_CONFIG, &layer) < 0) {
|
|
ERR("ioctl FBIOGET_VSCREENINFO");
|
|
close(g_fb_fd);
|
|
return -1;
|
|
}
|
|
|
|
g_screen_w = var.xres;
|
|
g_screen_h = var.yres;
|
|
g_fb_len = fix.smem_len;
|
|
g_fb_phy = fix.smem_start;
|
|
g_fb_stride = layer.buf.stride[0];
|
|
g_fb_format = layer.buf.format;
|
|
|
|
g_fb_buf = mmap(NULL, g_fb_len,
|
|
PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED,
|
|
g_fb_fd, 0);
|
|
if (g_fb_buf == MAP_FAILED) {
|
|
ERR("mmap framebuffer");
|
|
close(g_fb_fd);
|
|
g_fb_fd = -1;
|
|
g_fb_buf = NULL;
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void fb_close(void)
|
|
{
|
|
if (!g_fb_buf) {
|
|
munmap(g_fb_buf, g_fb_len);
|
|
}
|
|
|
|
if (g_fb_fd > 0) {
|
|
close(g_fb_fd);
|
|
}
|
|
}
|
|
|
|
static int ori_bmp_open(int *ori_fd)
|
|
{
|
|
*ori_fd = open(SINGER_32BIT_IMAGE, O_RDWR);
|
|
if (*ori_fd < 0) {
|
|
ERR("Failed to open %s, errno: %d[%s]\n",
|
|
SINGER_32BIT_IMAGE, errno, strerror(errno));
|
|
return -1;
|
|
}
|
|
|
|
if (read(*ori_fd, &bmp_header, sizeof(struct BmpHeader)) !=
|
|
sizeof(struct BmpHeader)) {
|
|
ERR("read bmp file error \n");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void ori_bmp_close(int ori_fd)
|
|
{
|
|
if (ori_fd > 0) {
|
|
close(ori_fd);
|
|
}
|
|
}
|
|
|
|
static int str_to_format(char *str)
|
|
{
|
|
int i = 0;
|
|
static struct StrToFormat table[] = {
|
|
{"argb8888", MPP_FMT_ARGB_8888},
|
|
{"argb888", MPP_FMT_RGB_888},
|
|
{"argb4444", MPP_FMT_ARGB_4444},
|
|
{"argb1555", MPP_FMT_ARGB_1555},
|
|
{"argb565", MPP_FMT_RGB_565},
|
|
};
|
|
|
|
const int table_size = sizeof(table) / sizeof(table[0]);
|
|
for (i = 0; i < table_size ; i++) {
|
|
if(!strncasecmp(str, table[i].str, strlen(table[i].str))) {
|
|
return table[i].format;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int format_to_stride(int format, int width)
|
|
{
|
|
int stride = -1;
|
|
|
|
switch (format) {
|
|
case MPP_FMT_ARGB_8888:
|
|
stride = BYTE_ALIGN((width * 4), 8);
|
|
break;
|
|
case MPP_FMT_ARGB_4444:
|
|
case MPP_FMT_ARGB_1555:
|
|
case MPP_FMT_RGB_565:
|
|
stride = BYTE_ALIGN((width * 2), 8);
|
|
break;
|
|
case MPP_FMT_RGB_888:
|
|
stride = BYTE_ALIGN((width * 3), 8);
|
|
break;
|
|
default:
|
|
ERR("Set stride error, format = %d\n", format);
|
|
break;
|
|
}
|
|
|
|
return stride;
|
|
}
|
|
|
|
static int format_to_hight(int format, int hight)
|
|
{
|
|
int t_hight = -1;
|
|
|
|
switch (format) {
|
|
case MPP_FMT_ARGB_8888:
|
|
case MPP_FMT_ARGB_4444:
|
|
case MPP_FMT_ARGB_1555:
|
|
case MPP_FMT_RGB_888:
|
|
case MPP_FMT_RGB_565:
|
|
t_hight = hight;
|
|
break;
|
|
default:
|
|
ERR("Set hight error, format = %d\n", format);
|
|
break;
|
|
}
|
|
|
|
return t_hight;
|
|
}
|
|
|
|
static int format_to_bmp_data_length(int format, int width)
|
|
{
|
|
int data_length = -1;
|
|
|
|
switch (format) {
|
|
case MPP_FMT_ARGB_8888:
|
|
data_length = BYTE_ALIGN((width * 4), 4);
|
|
break;
|
|
case MPP_FMT_ARGB_4444:
|
|
case MPP_FMT_ARGB_1555:
|
|
case MPP_FMT_RGB_565:
|
|
data_length = BYTE_ALIGN((width * 2), 4);
|
|
break;
|
|
case MPP_FMT_RGB_888:
|
|
data_length = BYTE_ALIGN((width * 3), 4);
|
|
break;
|
|
default:
|
|
ERR("Set data length error, format = %d\n",format);
|
|
break;
|
|
}
|
|
|
|
return data_length;
|
|
}
|
|
|
|
static int dmabuf_request_one(int fd, int format)
|
|
{
|
|
int ret = -1;
|
|
int stride = 0;
|
|
int hight = 0;
|
|
unsigned int ori_width = 0;
|
|
unsigned int ori_height = 0;
|
|
struct dma_heap_allocation_data data = {0};
|
|
|
|
ori_width = abs(bmp_header.width);
|
|
ori_height = abs(bmp_header.height);
|
|
|
|
stride = format_to_stride(format, ori_width);
|
|
if (stride < 0) {
|
|
ERR("format_to_stride execution error\n");
|
|
return -1;
|
|
}
|
|
|
|
hight = format_to_hight(format, ori_height);
|
|
if (hight < 0) {
|
|
ERR("format_to_hight execution error\n");
|
|
return -1;
|
|
}
|
|
|
|
data.fd = 0;
|
|
data.len = stride * hight;
|
|
data.fd_flags = O_RDWR | O_CLOEXEC;
|
|
data.heap_flags = 0;
|
|
|
|
ret = ioctl(fd, DMA_HEAP_IOCTL_ALLOC, &data);
|
|
if (ret < 0) {
|
|
ERR("ioctl() failed! errno: %d[%s]\n", errno, strerror(errno));
|
|
return -1;
|
|
}
|
|
|
|
return data.fd;
|
|
}
|
|
|
|
static int draw_ori_dmabuf(int dmabuf_fd, int ori_fd, int format)
|
|
{
|
|
int i = 0;
|
|
int len = 0;
|
|
int hight = 0;
|
|
int stride = 0;
|
|
unsigned char *dmabuf = NULL;
|
|
unsigned char *buf = NULL;
|
|
unsigned int ori_width = 0;
|
|
unsigned int ori_height = 0;
|
|
unsigned int line_length = 0;
|
|
unsigned int data_length = 0;
|
|
|
|
if (bmp_header.type != 0x4D42) {
|
|
ERR("not a Bmp file\n");
|
|
return -1;
|
|
}
|
|
|
|
ori_width = abs(bmp_header.width);
|
|
ori_height = abs(bmp_header.height);
|
|
|
|
stride = format_to_stride(format, ori_width);
|
|
if (stride < 0) {
|
|
ERR("format_to_stride execution error\n");
|
|
return -1;
|
|
}
|
|
|
|
hight = format_to_hight(format, ori_height);
|
|
if (hight < 0) {
|
|
ERR("format_to_hight execution error\n");
|
|
return -1;
|
|
}
|
|
|
|
len = stride * hight;
|
|
dmabuf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, dmabuf_fd, 0);
|
|
if (dmabuf == MAP_FAILED) {
|
|
ERR("mmap() failed! errno: %d[%s]\n", errno, strerror(errno));
|
|
return -1;
|
|
}
|
|
|
|
data_length = format_to_bmp_data_length(format, ori_width);
|
|
line_length = format_to_stride(format, ori_width);
|
|
|
|
/* read from bottom to top */
|
|
if (bmp_header.height < 0){
|
|
buf = dmabuf;
|
|
for (i = 0; i < ori_height; i++) {
|
|
if ((read(ori_fd, buf, data_length) != data_length)) {
|
|
ERR("read(%d) . errno: %d[%s]\n", data_length,
|
|
errno, strerror(errno));
|
|
return -1;
|
|
}
|
|
buf += line_length;
|
|
}
|
|
/* read from top to bottom */
|
|
} else {
|
|
for (i = ori_height -1; i >= 0; i--) {
|
|
buf = dmabuf + (i * line_length);
|
|
if ((read(ori_fd, buf, data_length) != data_length)) {
|
|
ERR("read(%d) . errno: %d[%s]\n", data_length,
|
|
errno, strerror(errno));
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
munmap(dmabuf, len);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* just do a format conversion */
|
|
static int ge_dither_set(struct ge_bitblt *blt, int src_dma_fd, int dst_dma_fd, int src_format, int dst_format, int dith_en)
|
|
{
|
|
int ori_width = 0;
|
|
int ori_height = 0;
|
|
int src_stride = 0;
|
|
int dst_stride = 0;
|
|
|
|
ori_width = abs(bmp_header.width);
|
|
ori_height = abs(bmp_header.height);
|
|
|
|
src_stride = format_to_stride(src_format, ori_width);
|
|
if(src_stride < 0) {
|
|
ERR("format_to_stride execution error\n");
|
|
return -1;
|
|
}
|
|
|
|
dst_stride = format_to_stride(dst_format, ori_width);
|
|
if(dst_stride < 0) {
|
|
ERR("format_to_stride execution error\n");
|
|
return -1;
|
|
}
|
|
|
|
/* src layer settings */
|
|
blt->src_buf.buf_type = MPP_DMA_BUF_FD;
|
|
blt->src_buf.fd[0] = src_dma_fd;
|
|
blt->src_buf.stride[0] = src_stride;
|
|
blt->src_buf.size.width = ori_width;
|
|
blt->src_buf.size.height = ori_height;
|
|
blt->src_buf.format = src_format;
|
|
blt->src_buf.crop_en = 0;
|
|
|
|
/* dst layer settings */
|
|
blt->dst_buf.buf_type = MPP_DMA_BUF_FD;
|
|
blt->dst_buf.fd[0] = dst_dma_fd;
|
|
blt->dst_buf.stride[0] = dst_stride;
|
|
blt->dst_buf.size.width = ori_width;
|
|
blt->dst_buf.size.height = ori_height;
|
|
blt->dst_buf.format = dst_format;
|
|
blt->dst_buf.crop_en = 0;
|
|
|
|
blt->ctrl.dither_en = dith_en;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ge_dither(struct mpp_ge *ge, struct ge_bitblt *blt, int src_dma_fd, int dst_dma_fd, int src_format, int dst_format, int dith_en)
|
|
{
|
|
int ret = -1;
|
|
|
|
ret = ge_dither_set(blt, src_dma_fd, dst_dma_fd, src_format, dst_format, dith_en);
|
|
if (ret < 0) {
|
|
ERR("ge_dither dither_set task failed: %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = mpp_ge_bitblt(ge, blt);
|
|
if (ret) {
|
|
ERR("ge_dither bitblt task failed: %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = mpp_ge_emit(ge);
|
|
if (ret) {
|
|
ERR("ge_dither emit task failed: %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ge_display_set(struct ge_bitblt *blt, int dma_fd, int format, int region)
|
|
{
|
|
int dstx = 0;
|
|
int dsty = 0;
|
|
int ori_width = 0;
|
|
int ori_height = 0;
|
|
int stride = 0;
|
|
|
|
ori_width = abs(bmp_header.width);
|
|
ori_height = abs(bmp_header.height);
|
|
|
|
stride = format_to_stride(format, ori_width);
|
|
if(stride < 0) {
|
|
ERR("format_to_stride execution error\n");
|
|
return -1;
|
|
}
|
|
|
|
if (region == SRC_DISP_REGION) {
|
|
dstx = 0;
|
|
dsty = 0;
|
|
} else {
|
|
dstx = g_screen_w / 2;
|
|
dsty = 0;
|
|
}
|
|
|
|
/* src layer settings */
|
|
blt->src_buf.buf_type = MPP_DMA_BUF_FD;
|
|
blt->src_buf.fd[0] = dma_fd;
|
|
blt->src_buf.stride[0] = stride;
|
|
blt->src_buf.size.width = ori_width;
|
|
blt->src_buf.size.height = ori_height;
|
|
blt->src_buf.format = format;
|
|
|
|
/* dst layer settings */
|
|
blt->dst_buf.buf_type = MPP_PHY_ADDR;
|
|
blt->dst_buf.phy_addr[0] = g_fb_phy;
|
|
blt->dst_buf.stride[0] = g_fb_stride;
|
|
blt->dst_buf.size.width = g_screen_w;
|
|
blt->dst_buf.size.height = g_screen_h;
|
|
blt->dst_buf.format = g_fb_format;
|
|
blt->dst_buf.crop_en = 1;
|
|
blt->dst_buf.crop.x = dstx;
|
|
blt->dst_buf.crop.y = dsty;
|
|
blt->dst_buf.crop.width = g_screen_w / 2;
|
|
blt->dst_buf.crop.height = g_screen_h;
|
|
|
|
blt->ctrl.dither_en = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ge_display(struct mpp_ge *ge, struct ge_bitblt *blt, int dma_fd, int format, int region)
|
|
{
|
|
int ret = -1;
|
|
|
|
ret = ge_display_set(blt, dma_fd, format, region);
|
|
if (ret < 0) {
|
|
ERR("ge_display set task failed: %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = mpp_ge_bitblt(ge, blt);
|
|
if (ret) {
|
|
ERR("ge_display bitblt task failed: %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = mpp_ge_emit(ge);
|
|
if (ret) {
|
|
ERR("ge_display emit task failed: %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ori_to_src(struct mpp_ge *ge, struct ge_bitblt *blt, int ori_dma_fd , int src_dma_fd, int src_format)
|
|
{
|
|
int ret = -1;
|
|
|
|
/* Run an bitlet operation without opening dither */
|
|
ret = ge_dither(ge, blt, ori_dma_fd, src_dma_fd, MPP_FMT_ARGB_8888, src_format, 0);
|
|
if (ret < 0) {
|
|
ERR("ori_to_src bitlet task failed\n");
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int ret = 0;
|
|
int ori_dmabuf_fd = -1;
|
|
int src_dmabuf_fd = -1;
|
|
int dst_dmabuf_fd = -1;
|
|
int heap_fd = -1;
|
|
int ori_fd = -1;
|
|
int src_format = 0;
|
|
int dst_format = 0;
|
|
int dither_on = 0;
|
|
struct mpp_ge *ge = NULL;
|
|
struct ge_bitblt blt = {0};
|
|
|
|
const char sopts[] = "uhs:d:o:";
|
|
const struct option lopts[] = {
|
|
{"usage", no_argument, NULL, 'u'},
|
|
{"help", no_argument, NULL, 'h'},
|
|
{"src_format", required_argument, NULL, 's'},
|
|
{"dst_format", required_argument, NULL, 'd'},
|
|
{"dither_on", required_argument, NULL, 'o'},
|
|
};
|
|
|
|
src_format = str_to_format("argb8888");
|
|
dst_format = str_to_format("argb4444");
|
|
while ((ret = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
|
|
switch (ret) {
|
|
case 's':
|
|
src_format = str_to_format(optarg);
|
|
if (src_format < 0) {
|
|
printf("src format set error, please set against\n");
|
|
goto EXIT;
|
|
}
|
|
|
|
break;
|
|
case 'd':
|
|
dst_format = str_to_format(optarg);
|
|
if (dst_format < 0) {
|
|
printf("dst format set error, please set against\n");
|
|
goto EXIT;
|
|
}
|
|
break;
|
|
case 'o':
|
|
dither_on = str2int(optarg);
|
|
if ((dither_on > 1) || (dither_on < 0)) {
|
|
printf("dither switch set error, please set against\n");
|
|
goto EXIT;
|
|
}
|
|
break;
|
|
case 'u':
|
|
usage(argv[0]);
|
|
goto EXIT;
|
|
case 'h':
|
|
help();
|
|
goto EXIT;
|
|
default:
|
|
ERR("Invalid parameter: %#x\n", ret);
|
|
goto EXIT;
|
|
}
|
|
}
|
|
|
|
ge = mpp_ge_open();
|
|
if (!ge) {
|
|
ERR("open ge device\n");
|
|
goto EXIT;
|
|
}
|
|
|
|
if (fb_open()) {
|
|
ERR("fb_open error\n");
|
|
goto EXIT;
|
|
}
|
|
|
|
heap_fd = open(DMA_HEAP_DEV, O_RDWR);
|
|
if (heap_fd < 0) {
|
|
ERR("Failed to open %s, errno: %d[%s]\n",
|
|
DMA_HEAP_DEV, errno, strerror(errno));
|
|
goto EXIT;
|
|
}
|
|
|
|
ret = ori_bmp_open(&ori_fd);
|
|
if (ret < 0) {
|
|
ERR("ori_bmp_open error \n");
|
|
goto EXIT;
|
|
}
|
|
|
|
ori_dmabuf_fd = dmabuf_request_one(heap_fd, MPP_FMT_ARGB_8888);
|
|
if (ori_dmabuf_fd < 0) {
|
|
ERR("ori_dmabuf_fd failed to request dmabuf\n");
|
|
goto EXIT;
|
|
}
|
|
|
|
src_dmabuf_fd = dmabuf_request_one(heap_fd, src_format);
|
|
if (src_dmabuf_fd < 0) {
|
|
ERR("src_dmabuf_fd failed to request dmabuf\n");
|
|
goto EXIT;
|
|
}
|
|
|
|
dst_dmabuf_fd = dmabuf_request_one(heap_fd, dst_format);
|
|
if (dst_dmabuf_fd < 0) {
|
|
ERR("dst_dmabuf_fd failed to request dmabuf\n");
|
|
goto EXIT;
|
|
}
|
|
|
|
/* read the original image data */
|
|
ret = draw_ori_dmabuf(ori_dmabuf_fd, ori_fd, MPP_FMT_ARGB_8888);
|
|
if (ret < 0) {
|
|
ERR("draw_src_dmabuf task failed\n");
|
|
goto EXIT;
|
|
}
|
|
|
|
mpp_ge_add_dmabuf(ge, ori_dmabuf_fd);
|
|
mpp_ge_add_dmabuf(ge, src_dmabuf_fd);
|
|
mpp_ge_add_dmabuf(ge, dst_dmabuf_fd);
|
|
|
|
ret = mpp_ge_emit(ge);
|
|
if (ret) {
|
|
ERR("emit task failed:%d\n", ret);
|
|
goto EXIT;
|
|
}
|
|
|
|
/* convert the original image format to input format */
|
|
ret = ori_to_src(ge, &blt, ori_dmabuf_fd, src_dmabuf_fd, src_format);
|
|
if (ret) {
|
|
ERR("ori_to_src task failed:%d\n", ret);
|
|
goto EXIT;
|
|
}
|
|
/* Display SRC layer data on the left side of the screen */
|
|
ret = ge_display(ge, &blt, src_dmabuf_fd, src_format, SRC_DISP_REGION);
|
|
if (ret) {
|
|
ERR("ge_display task failed:%d\n", ret);
|
|
goto EXIT;
|
|
}
|
|
|
|
/* Dither format conversion */
|
|
ret = ge_dither(ge, &blt, src_dmabuf_fd, dst_dmabuf_fd, src_format, dst_format, dither_on);
|
|
if (ret < 0) {
|
|
ERR("ge_dither task failed\n");
|
|
goto EXIT;
|
|
}
|
|
|
|
/* Display SRC layer data on the right side of the screen */
|
|
ret = ge_display(ge, &blt, dst_dmabuf_fd, dst_format, DST_DISP_REGION);
|
|
if (ret < 0) {
|
|
ERR("ge_display task failed\n");
|
|
goto EXIT;
|
|
}
|
|
|
|
ret = mpp_ge_sync(ge);
|
|
if (ret) {
|
|
ERR("sync task failed: %d\n", ret);
|
|
goto EXIT;
|
|
}
|
|
|
|
EXIT:
|
|
if (ori_dmabuf_fd > 0) {
|
|
mpp_ge_rm_dmabuf(ge, ori_dmabuf_fd);
|
|
close(ori_dmabuf_fd);
|
|
}
|
|
|
|
if (src_dmabuf_fd > 0) {
|
|
mpp_ge_rm_dmabuf(ge, src_dmabuf_fd);
|
|
close(src_dmabuf_fd);
|
|
}
|
|
|
|
if (dst_dmabuf_fd > 0) {
|
|
mpp_ge_rm_dmabuf(ge, dst_dmabuf_fd);
|
|
close(dst_dmabuf_fd);
|
|
}
|
|
|
|
if (heap_fd > 0) {
|
|
close(heap_fd);
|
|
}
|
|
|
|
if (ori_fd > 0) {
|
|
ori_bmp_close(ori_fd);
|
|
}
|
|
|
|
if (ge) {
|
|
mpp_ge_close(ge);
|
|
}
|
|
|
|
fb_close();
|
|
|
|
return 0;
|
|
}
|