您尚未登录。

楼主 # 2024-06-29 21:19:22

memory
会员
注册时间: 2021-08-11
已发帖子: 487
积分: 464

全志T113 Linux G2D学习

g2d_fill_dmabuf.c

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <string.h>
#include <signal.h>
#include <signal.h>
#include <time.h>
#include <linux/fb.h>
#include <linux/kernel.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "include/g2d_driver_enh.h"
#include "include/ion_head.h"

struct test_info_t
{
	g2d_fillrect_h info;
	int fd;
	int ion_fd;
	char filename[64];
	char out_filename[64];
	FILE *fp;
	struct ion_info dst_ion;
};

struct test_info_t test_info;

/* Signal handler */
static void terminate(int sig_no)
{
	int val[6];
	memset(val,0,sizeof(val));
	printf("Got signal %d, exiting ...\n", sig_no);
	if(test_info.fd == -1)
	{
			printf("EXIT:");
			exit(1);
	}

	close(test_info.fd);
	printf("EXIT:");
	exit(1);
}

int parse_cmdline(int argc, char **argv, struct test_info_t *p)
{
	int err = 0;
	int i = 0;

	while(i<argc) {
		printf("%s ",argv[i]);
		i++;
	}
	printf("\n");

	i = 0;
	while(i < argc) {
		if ( ! strcmp(argv[i], "-out_fb")) {
			if (argc > i+4) {
				i++;
				p->info.dst_image_h.format = atoi(argv[i]);
				i++;
				p->info.dst_image_h.width = atoi(argv[i]);
				i++;
				p->info.dst_image_h.height = atoi(argv[i]);
			}	else {
				printf("-out_fb para err!\n\n");
				err ++;
			}
		}

		if ( ! strcmp(argv[i], "-dst_rect")) {
			if (argc > i+4) {
				i++;
				p->info.dst_image_h.clip_rect.x = atoi(argv[i]);
				i++;
				p->info.dst_image_h.clip_rect.y = atoi(argv[i]);
				i++;
				p->info.dst_image_h.clip_rect.w = atoi(argv[i]);
				i++;
				p->info.dst_image_h.clip_rect.h = atoi(argv[i]);
			}	else {
				printf("-out_fb para err!\n\n");
				err ++;
			}
		}

		if ( ! strcmp(argv[i], "-out_file")) {
			if (argc > i+1) {
				i++;
				p->out_filename[0] = '\0';
				sprintf(p->out_filename,"%s",argv[i]);
				printf("out_file=%s\n", argv[i]);
			}	else {
				printf("no file described!!\n");
				err ++;
			}
		}

		if ( ! strcmp(argv[i], "-color")) {
			if (argc > i+1) {
				i+=1;
				p->info.dst_image_h.color = atoll(argv[i]);
			}
		}

		if ( ! strcmp(argv[i], "-alpha_mode")) {
			if (argc > i+1) {
				i+=1;
				p->info.dst_image_h.mode = atoi(argv[i]);
			}
		}

		if ( ! strcmp(argv[i], "-alpha")) {
			if (argc > i+1) {
				i+=1;
				p->info.dst_image_h.alpha = atoi(argv[i]);
			}
		}

		i++;
	}

	if(err > 0) {
		printf("example : --------\n");
		return -1;
	} else
		 return 0;
}

static void install_sig_handler(void)
{
	signal(SIGBUS, terminate);
	signal(SIGFPE, terminate);
	signal(SIGHUP, terminate);
	signal(SIGILL, terminate);
	signal(SIGINT, terminate);
	signal(SIGIOT, terminate);
	signal(SIGPIPE, terminate);
	signal(SIGQUIT, terminate);
	signal(SIGSEGV, terminate);
	signal(SIGSYS, terminate);
	signal(SIGTERM, terminate);
	signal(SIGTRAP, terminate);
	signal(SIGUSR1, terminate);
	signal(SIGUSR2, terminate);
}

#define DISP_MEM_REQUEST 0x2c0
#define DISP_MEM_RELEASE 0x2c1
#define DISP_MEM_GETADR 0x2c2

#define DISPALIGN(value, align) ((align==0)?(unsigned long)value:((((unsigned long)value) + ((align) - 1)) & ~((align) - 1)))

int ion_open(void)
{
	int fd = open("/dev/ion", O_RDONLY | O_CLOEXEC);
	if (fd < 0)
		printf("open ion device failed!%s\n", strerror(errno));
	printf("[%s]: success fd = %d\n", __func__, fd);
	return fd;
}
/**
 * @name       :disp_layer_is_iommu_enabled
 * @brief      :judge whether iommu is enabled
 * @return     :1 if iommu enabled or 0 if iommu disable
 */
static int is_iommu_enabled(void)
{
	struct stat iommu_sysfs;
	if (stat("/sys/class/iommu", &iommu_sysfs) == 0 &&
	    S_ISDIR(iommu_sysfs.st_mode))
		return 1;
	else
		return 0;
}

int ion_memory_request(struct ion_info *ion, int mem_size)
{
	struct ion_allocation_data data;
	int ret = -1;
	int ion_fd = 0;;

	if (test_info.ion_fd <= 0) {
		test_info.ion_fd = ion_open();
		if (test_info.ion_fd < 0) {
			return -1;
		}
	}
	ion_fd = test_info.ion_fd;

	printf("%s(%d): ion_fd %d\n", __func__, __LINE__, ion_fd);

	/* alloc buffer */
	if (is_iommu_enabled())
	{
		printf("---> is_iommu_enabled \n");
		data.heap_id_mask = ION_SYSTEM_HEAP_MASK;
	}
	else
	{
		printf("---> is_iommu_enabled fail\n");
		data.heap_id_mask = ION_DMA_HEAP_MASK;
	}

	data.len = mem_size;
	data.flags = ION_FLAG_CACHED;

	printf("%s(%d): ION_HEAP_TYPE 0x%x\n", __func__, __LINE__, data.heap_id_mask);

	ret = ioctl(ion_fd, ION_IOC_ALLOC, &data);
	if(ret < 0) {
		printf("%s(%d): ION_IOC_ALLOC err, ret = %d\n", __func__, __LINE__, ret);
		data.fd = -1;
		goto out;
	}
	printf("%s(%d): ION_IOC_ALLOC succes, dmabuf-fd = %d, size = %d\n",
				__func__, __LINE__, ret, data.len);
	printf("\n");

	ion->virt_addr = mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, data.fd, 0);

	if (ion->virt_addr == MAP_FAILED) {
		printf("%s(%d): mmap err, ret %p\n", __func__, __LINE__, ion->virt_addr);
		data.fd = -1;
	}

	ion->alloc_data = data;
out:
	return data.fd;
}

void ion_memory_release(int fd)
{
	close(fd);
	return;
}


int main(int argc, char **argv)
{
	unsigned long arg[6];
	int rv;
	int i,n;
	int ret;
	int out_size;
	int dst_fd = 0;
	int fb_width, fb_height;

	install_sig_handler();
	memset(&test_info, 0, sizeof(struct test_info_t));
	rv = parse_cmdline(argc,argv, &test_info);
	if(rv < 0) {
		printf("parse_command fail");
		return -1;
	}

	if((test_info.fd = open("/dev/g2d",O_RDWR)) == -1) {
		printf("open g2d device fail!\n");
		close(test_info.fd);
		return -1;
	}

	out_size = test_info.info.dst_image_h.width * test_info.info.dst_image_h.height * 4;
	printf("out_size=%d\n", out_size);

	printf("ready to open dst file %s \n", test_info.filename);
	dst_fd = ion_memory_request(&test_info.dst_ion, out_size);
	if(dst_fd <= 0)
		printf("request dst_mem failed! \n");

	test_info.info.dst_image_h.fd = dst_fd;

	fb_width = test_info.info.dst_image_h.width;
	fb_height = test_info.info.dst_image_h.height;

	printf("dst:format=0x%x,color=0x%x \n img w=%d, h=%d, \n rect x=%d, y=%d, w=%d, h=%d, align=%d\n\n",
		test_info.info.dst_image_h.format, test_info.info.dst_image_h.color,
		test_info.info.dst_image_h.width, test_info.info.dst_image_h.height,
		test_info.info.dst_image_h.clip_rect.x, test_info.info.dst_image_h.clip_rect.y,
		test_info.info.dst_image_h.clip_rect.w, test_info.info.dst_image_h.clip_rect.h,
		test_info.info.dst_image_h.align[0]);

	sleep(1);
	/* fill color */
	if(ioctl(test_info.fd , G2D_CMD_FILLRECT_H ,(unsigned long)(&test_info.info)) < 0)
	{
		printf("[%d][%s][%s]G2D_CMD_FILLRECT_H failure!\n",__LINE__, __FILE__,__FUNCTION__);
		ion_memory_release(dst_fd);
		close(test_info.fd);

		return -1;
	}
		printf("[%d][%s][%s]G2D_CMD_FILLRECT_H Successful!\n",__LINE__, __FILE__,__FUNCTION__);

	/* save result data to file */
	printf("save result data to file %s \n", test_info.out_filename);
	/* save result data to file */
	if((test_info.fp = fopen(test_info.out_filename, "wb+")) == NULL) {
		printf("open file %s fail. \n", test_info.out_filename);
		ion_memory_release(dst_fd);
		return -1;
	} else {
		printf("open file %s ok. \n", test_info.out_filename);
	}
	printf("==out_size=%d, addr=%p==\n", out_size, test_info.dst_ion.virt_addr);
	ret = fwrite(test_info.dst_ion.virt_addr, out_size, 1, test_info.fp);
	printf("fwrite,ret=%d\n", ret);
	munmap(test_info.dst_ion.virt_addr, out_size);
	fclose(test_info.fp);

	ion_memory_release(dst_fd);
	close(test_info.fd);

	return 0;
}

编译指令:

STAGING_DIR="" /opt/T113_Tina5.0/prebuilt/rootfsbuilt/arm/toolchain-sunxi-glibc-gcc-830/toolchain/bin/arm-openwrt-linux-gcc -o g2d_fill_dmabuf src/g2d_fill_dmabuf.c

运行指令:

chmod +x /tmp/g2d_fill_dmabuf && /tmp/g2d_fill_dmabuf -out_fb 2 1920 1200 -dst_rect 0 0 1920 1200 -out_file /tmp/fill_dmabuf_0_1920x1200_abgr8888_2.bin -color 570460160 -alpha_mode 2 -alpha 128

运行日志:

#chmod +x /tmp/g2d_fill_dmabuf && /tmp/g2d_fill_dmabuf -out_fb 2 1920 1
200 -dst_rect 0 0 1920 1200 -out_file /tmp/fill_dmabuf_0_1920x1200_abgr8888_2.bi
n -color 570460160 -alpha_mode 2 -alpha 128
/tmp/g2d_fill_dmabuf -out_fb 2 1920 1200 -dst_rect 0 0 1920 1200 -out_file /tmp/fill_dmabuf_0_1920x1200_abgr8888_2.bin -color 570460160 -alpha_mode 2 -alpha 128
out_file=/tmp/fill_dmabuf_0_1920x1200_abgr8888_2.bin
out_size=9216000
ready to open dst file
[ion_open]: success fd = 4
ion_memory_request(197): ion_fd 4
---> is_iommu_enabled
ion_memory_request(214): ION_HEAP_TYPE 0x1
ion_memory_request(223): ION_IOC_ALLOC succes, dmabuf-fd = 0, size = -1097396703

dst:format=0x2,color=0x22008800
 img w=1920, h=1200,
 rect x=0, y=0, w=1920, h=1200, align=0

[309][g2d_fill_dmabuf.c][main]G2D_CMD_FILLRECT_H Successful!
save result data to file /tmp/fill_dmabuf_0_1920x1200_abgr8888_2.bin
open file /tmp/fill_dmabuf_0_1920x1200_abgr8888_2.bin ok.
==out_size=9216000, addr=0xb6549000==
fwrite,ret=1

离线

楼主 #1 2024-06-29 21:23:33

memory
会员
注册时间: 2021-08-11
已发帖子: 487
积分: 464

Re: 全志T113 Linux G2D学习

连续测试10000次 1920*1200 填充:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <string.h>
#include <signal.h>
#include <signal.h>
#include <time.h>
#include <linux/fb.h>
#include <linux/kernel.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "include/g2d_driver_enh.h"
#include "include/ion_head.h"

struct test_info_t
{
	g2d_fillrect_h info;
	int fd;
	int ion_fd;
	char filename[64];
	char out_filename[64];
	FILE *fp;
	struct ion_info dst_ion;
};

struct test_info_t test_info;

/* Signal handler */
static void terminate(int sig_no)
{
	int val[6];
	memset(val,0,sizeof(val));
	printf("Got signal %d, exiting ...\n", sig_no);
	if(test_info.fd == -1)
	{
			printf("EXIT:");
			exit(1);
	}

	close(test_info.fd);
	printf("EXIT:");
	exit(1);
}

int parse_cmdline(int argc, char **argv, struct test_info_t *p)
{
	int err = 0;
	int i = 0;

	while(i<argc) {
		printf("%s ",argv[i]);
		i++;
	}
	printf("\n");

	i = 0;
	while(i < argc) {
		if ( ! strcmp(argv[i], "-out_fb")) {
			if (argc > i+4) {
				i++;
				p->info.dst_image_h.format = atoi(argv[i]);
				i++;
				p->info.dst_image_h.width = atoi(argv[i]);
				i++;
				p->info.dst_image_h.height = atoi(argv[i]);
			}	else {
				printf("-out_fb para err!\n\n");
				err ++;
			}
		}

		if ( ! strcmp(argv[i], "-dst_rect")) {
			if (argc > i+4) {
				i++;
				p->info.dst_image_h.clip_rect.x = atoi(argv[i]);
				i++;
				p->info.dst_image_h.clip_rect.y = atoi(argv[i]);
				i++;
				p->info.dst_image_h.clip_rect.w = atoi(argv[i]);
				i++;
				p->info.dst_image_h.clip_rect.h = atoi(argv[i]);
			}	else {
				printf("-out_fb para err!\n\n");
				err ++;
			}
		}

		if ( ! strcmp(argv[i], "-out_file")) {
			if (argc > i+1) {
				i++;
				p->out_filename[0] = '\0';
				sprintf(p->out_filename,"%s",argv[i]);
				printf("out_file=%s\n", argv[i]);
			}	else {
				printf("no file described!!\n");
				err ++;
			}
		}

		if ( ! strcmp(argv[i], "-color")) {
			if (argc > i+1) {
				i+=1;
				p->info.dst_image_h.color = atoll(argv[i]);
			}
		}

		if ( ! strcmp(argv[i], "-alpha_mode")) {
			if (argc > i+1) {
				i+=1;
				p->info.dst_image_h.mode = atoi(argv[i]);
			}
		}

		if ( ! strcmp(argv[i], "-alpha")) {
			if (argc > i+1) {
				i+=1;
				p->info.dst_image_h.alpha = atoi(argv[i]);
			}
		}

		i++;
	}

	if(err > 0) {
		printf("example : --------\n");
		return -1;
	} else
		 return 0;
}

static void install_sig_handler(void)
{
	signal(SIGBUS, terminate);
	signal(SIGFPE, terminate);
	signal(SIGHUP, terminate);
	signal(SIGILL, terminate);
	signal(SIGINT, terminate);
	signal(SIGIOT, terminate);
	signal(SIGPIPE, terminate);
	signal(SIGQUIT, terminate);
	signal(SIGSEGV, terminate);
	signal(SIGSYS, terminate);
	signal(SIGTERM, terminate);
	signal(SIGTRAP, terminate);
	signal(SIGUSR1, terminate);
	signal(SIGUSR2, terminate);
}

#define DISP_MEM_REQUEST 0x2c0
#define DISP_MEM_RELEASE 0x2c1
#define DISP_MEM_GETADR 0x2c2

#define DISPALIGN(value, align) ((align==0)?(unsigned long)value:((((unsigned long)value) + ((align) - 1)) & ~((align) - 1)))

int ion_open(void)
{
	int fd = open("/dev/ion", O_RDONLY | O_CLOEXEC);
	if (fd < 0)
		printf("open ion device failed!%s\n", strerror(errno));
	printf("[%s]: success fd = %d\n", __func__, fd);
	return fd;
}
/**
 * @name       :disp_layer_is_iommu_enabled
 * @brief      :judge whether iommu is enabled
 * @return     :1 if iommu enabled or 0 if iommu disable
 */
static int is_iommu_enabled(void)
{
	struct stat iommu_sysfs;
	if (stat("/sys/class/iommu", &iommu_sysfs) == 0 &&
	    S_ISDIR(iommu_sysfs.st_mode))
		return 1;
	else
		return 0;
}

int ion_memory_request(struct ion_info *ion, int mem_size)
{
	struct ion_allocation_data data;
	int ret = -1;
	int ion_fd = 0;;

	if (test_info.ion_fd <= 0) {
		test_info.ion_fd = ion_open();
		if (test_info.ion_fd < 0) {
			return -1;
		}
	}
	ion_fd = test_info.ion_fd;

	printf("%s(%d): ion_fd %d\n", __func__, __LINE__, ion_fd);

	/* alloc buffer */
	if (is_iommu_enabled())
	{
		printf("---> is_iommu_enabled \n");
		data.heap_id_mask = ION_SYSTEM_HEAP_MASK;
	}
	else
	{
		printf("---> is_iommu_enabled fail\n");
		data.heap_id_mask = ION_DMA_HEAP_MASK;
	}

	data.len = mem_size;
	data.flags = ION_FLAG_CACHED;

	printf("%s(%d): ION_HEAP_TYPE 0x%x\n", __func__, __LINE__, data.heap_id_mask);

	ret = ioctl(ion_fd, ION_IOC_ALLOC, &data);
	if(ret < 0) {
		printf("%s(%d): ION_IOC_ALLOC err, ret = %d\n", __func__, __LINE__, ret);
		data.fd = -1;
		goto out;
	}
	printf("%s(%d): ION_IOC_ALLOC succes, dmabuf-fd = %d, size = %d\n",
				__func__, __LINE__, ret, data.len);
	printf("\n");

	ion->virt_addr = mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, data.fd, 0);

	if (ion->virt_addr == MAP_FAILED) {
		printf("%s(%d): mmap err, ret %p\n", __func__, __LINE__, ion->virt_addr);
		data.fd = -1;
	}

	ion->alloc_data = data;
out:
	return data.fd;
}

void ion_memory_release(int fd)
{
	close(fd);
	return;
}


int main(int argc, char **argv)
{
	unsigned long arg[6];
	int rv;
	int i,n;
	int ret;
	int out_size;
	int dst_fd = 0;
	int fb_width, fb_height;

	install_sig_handler();
	memset(&test_info, 0, sizeof(struct test_info_t));
	rv = parse_cmdline(argc,argv, &test_info);
	if(rv < 0) {
		printf("parse_command fail");
		return -1;
	}

	if((test_info.fd = open("/dev/g2d",O_RDWR)) == -1) {
		printf("open g2d device fail!\n");
		close(test_info.fd);
		return -1;
	}

	out_size = test_info.info.dst_image_h.width * test_info.info.dst_image_h.height * 4;
	printf("out_size=%d\n", out_size);

	printf("ready to open dst file %s \n", test_info.filename);
	dst_fd = ion_memory_request(&test_info.dst_ion, out_size);
	if(dst_fd <= 0)
		printf("request dst_mem failed! \n");

	test_info.info.dst_image_h.fd = dst_fd;

	fb_width = test_info.info.dst_image_h.width;
	fb_height = test_info.info.dst_image_h.height;

	printf("dst:format=0x%x,color=0x%x \n img w=%d, h=%d, \n rect x=%d, y=%d, w=%d, h=%d, align=%d\n\n",
		test_info.info.dst_image_h.format, test_info.info.dst_image_h.color,
		test_info.info.dst_image_h.width, test_info.info.dst_image_h.height,
		test_info.info.dst_image_h.clip_rect.x, test_info.info.dst_image_h.clip_rect.y,
		test_info.info.dst_image_h.clip_rect.w, test_info.info.dst_image_h.clip_rect.h,
		test_info.info.dst_image_h.align[0]);

	sleep(1);
	
	while(1) {
	    static int i = 0;
	    
	    if(i > 10000) break;
	    

        /* fill color */
        if(ioctl(test_info.fd , G2D_CMD_FILLRECT_H ,(unsigned long)(&test_info.info)) < 0)
        {
	        printf("[%d][%s][%s]G2D_CMD_FILLRECT_H failure!\n",__LINE__, __FILE__,__FUNCTION__);
	        ion_memory_release(dst_fd);
	        close(test_info.fd);

	        return -1;
        }

	    i++;
	}
		printf("[%d][%s][%s]G2D_CMD_FILLRECT_H Successful!\n",__LINE__, __FILE__,__FUNCTION__);

	/* save result data to file */
	printf("save result data to file %s \n", test_info.out_filename);
	/* save result data to file */
	if((test_info.fp = fopen(test_info.out_filename, "wb+")) == NULL) {
		printf("open file %s fail. \n", test_info.out_filename);
		ion_memory_release(dst_fd);
		return -1;
	} else {
		printf("open file %s ok. \n", test_info.out_filename);
	}
	printf("==out_size=%d, addr=%p==\n", out_size, test_info.dst_ion.virt_addr);
	ret = fwrite(test_info.dst_ion.virt_addr, out_size, 1, test_info.fp);
	printf("fwrite,ret=%d\n", ret);
	munmap(test_info.dst_ion.virt_addr, out_size);
	fclose(test_info.fp);

	ion_memory_release(dst_fd);
	close(test_info.fd);

	return 0;
}
chmod +x /tmp/g2d_fill_dmabuf && /tmp/g2d_fill_dmabuf -out_fb 2 1920 1200 -dst_rect 0 0 1920 1200 -out_file tmp/fill_dmabuf_0_1920x1200_abgr8888_2.bin -color 570460160 -alpha_mode 2 -alpha 128
# date && chmod +x /tmp/g2d_fill_dmabuf && /tmp/g2d_fill_dmabuf -out_fb 2 1920 1
200 -dst_rect 0 0 1920 1200 -out_file /tmp/fill_dmabuf_0_1920x1200_abgr8888_2.bi
n -color 570460160 -alpha_mode 2 -alpha 128 && date
Sat Jun 29 20:59:03 CST 2024
/tmp/g2d_fill_dmabuf -out_fb 2 1920 1200 -dst_rect 0 0 1920 1200 -out_file /tmp/fill_dmabuf_0_1920x1200_abgr8888_2.bin -color 570460160 -alpha_mode 2 -alpha 128
out_file=/tmp/fill_dmabuf_0_1920x1200_abgr8888_2.bin
out_size=9216000
ready to open dst file
[ion_open]: success fd = 4
ion_memory_request(197): ion_fd 4
---> is_iommu_enabled
ion_memory_request(214): ION_HEAP_TYPE 0x1
ion_memory_request(223): ION_IOC_ALLOC succes, dmabuf-fd = 0, size = -1097396703

dst:format=0x2,color=0x22008800
 img w=1920, h=1200,
 rect x=0, y=0, w=1920, h=1200, align=0

[309][g2d_fill_dmabuf.c][main]G2D_CMD_FILLRECT_H Successful!
save result data to file /tmp/fill_dmabuf_0_1920x1200_abgr8888_2.bin
open file /tmp/fill_dmabuf_0_1920x1200_abgr8888_2.bin ok.
==out_size=9216000, addr=0xb6549000==
fwrite,ret=1
Sat Jun 29 21:01:19 CST 2024

处理速度 73fps

# echo $((10000/(120+16)))
73
#

离线

楼主 #2 2024-06-30 11:24:53

memory
会员
注册时间: 2021-08-11
已发帖子: 487
积分: 464

Re: 全志T113 Linux G2D学习

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <string.h>
#include <signal.h>
#include <signal.h>
#include <time.h>
#include <linux/fb.h>
#include <linux/kernel.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "include/g2d_driver_enh.h"
#include "include/ion_head.h"

struct test_info_t
{
	g2d_fillrect_h info;
	int fd;
	int ion_fd;
	char filename[64];
	char out_filename[64];
	FILE *fp;
	struct ion_info dst_ion;
};

struct test_info_t test_info;

/* Signal handler */
static void terminate(int sig_no)
{
	int val[6];
	memset(val,0,sizeof(val));
	printf("Got signal %d, exiting ...\n", sig_no);
	if(test_info.fd == -1)
	{
			printf("EXIT:");
			exit(1);
	}

	close(test_info.fd);
	printf("EXIT:");
	exit(1);
}

static void install_sig_handler(void)
{
	signal(SIGBUS, terminate);
	signal(SIGFPE, terminate);
	signal(SIGHUP, terminate);
	signal(SIGILL, terminate);
	signal(SIGINT, terminate);
	signal(SIGIOT, terminate);
	signal(SIGPIPE, terminate);
	signal(SIGQUIT, terminate);
	signal(SIGSEGV, terminate);
	signal(SIGSYS, terminate);
	signal(SIGTERM, terminate);
	signal(SIGTRAP, terminate);
	signal(SIGUSR1, terminate);
	signal(SIGUSR2, terminate);
}



int ion_open(void)
{
	int fd = open("/dev/ion", O_RDONLY | O_CLOEXEC);
	if (fd < 0)
		printf("open ion device failed!%s\n", strerror(errno));
	printf("[%s]: success fd = %d\n", __func__, fd);
	return fd;
}
/**
 * @name       :disp_layer_is_iommu_enabled
 * @brief      :judge whether iommu is enabled
 * @return     :1 if iommu enabled or 0 if iommu disable
 */
static int is_iommu_enabled(void)
{
	struct stat iommu_sysfs;
	if (stat("/sys/class/iommu", &iommu_sysfs) == 0 &&
	    S_ISDIR(iommu_sysfs.st_mode))
		return 1;
	else
		return 0;
}

int ion_memory_request(struct ion_info *ion, int mem_size)
{
	struct ion_allocation_data data;
	int ret = -1;
	int ion_fd = 0;;

	if (test_info.ion_fd <= 0) {
		test_info.ion_fd = ion_open();
		if (test_info.ion_fd < 0) {
			return -1;
		}
	}
	ion_fd = test_info.ion_fd;

	printf("%s(%d): ion_fd %d\n", __func__, __LINE__, ion_fd);

	/* alloc buffer */
	if (is_iommu_enabled())
	{
		printf("---> is_iommu_enabled \n");
		data.heap_id_mask = ION_SYSTEM_HEAP_MASK;
	}
	else
	{
		printf("---> is_iommu_enabled fail\n");
		data.heap_id_mask = ION_DMA_HEAP_MASK;
	}

	data.len = mem_size;
	data.flags = ION_FLAG_CACHED;

	printf("%s(%d): ION_HEAP_TYPE 0x%x\n", __func__, __LINE__, data.heap_id_mask);

	ret = ioctl(ion_fd, ION_IOC_ALLOC, &data);
	if(ret < 0) {
		printf("%s(%d): ION_IOC_ALLOC err, ret = %d\n", __func__, __LINE__, ret);
		data.fd = -1;
		goto out;
	}
	printf("%s(%d): ION_IOC_ALLOC succes, dmabuf-fd = %d, size = %d\n",
				__func__, __LINE__, ret, data.len);
	printf("\n");

	ion->virt_addr = mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, data.fd, 0);

	if (ion->virt_addr == MAP_FAILED) {
		printf("%s(%d): mmap err, ret %p\n", __func__, __LINE__, ion->virt_addr);
		data.fd = -1;
	}

	ion->alloc_data = data;
out:
	return data.fd;
}

void ion_memory_release(int fd)
{
	close(fd);
	return;
}


int main(int argc, char **argv)
{
	unsigned long arg[6];
	int rv;
	int i,n;
	int ret;
	int out_size;
	int dst_fd = 0;
	int fb_width, fb_height;

	install_sig_handler();
	memset(&test_info, 0, sizeof(struct test_info_t));

	if((test_info.fd = open("/dev/g2d",O_RDWR)) == -1) {
		printf("open g2d device fail!\n");
		close(test_info.fd);
		return -1;
	}

    strcpy(test_info.out_filename, "/tmp/fill_dmabuf_1920x1200_bgra8888.bin"); //pixelviewer的解析格式和g2d format刚好反过来
	test_info.info.dst_image_h.width = 1920;
	test_info.info.dst_image_h.height = 1200;
	
	out_size = test_info.info.dst_image_h.width * test_info.info.dst_image_h.height * 4;
	printf("out_size=%d\n", out_size);


	dst_fd = ion_memory_request(&test_info.dst_ion, out_size);
	if(dst_fd <= 0)
		printf("request dst_mem failed! \n");

	test_info.info.dst_image_h.fd = dst_fd;

	fb_width = test_info.info.dst_image_h.width;
	fb_height = test_info.info.dst_image_h.height;

    //Red
    test_info.info.dst_image_h.format = G2D_FORMAT_ARGB8888;
    test_info.info.dst_image_h.width = 1920;
    test_info.info.dst_image_h.height = 1200;
    test_info.info.dst_image_h.clip_rect.x = 0;
    test_info.info.dst_image_h.clip_rect.y = 0;
    test_info.info.dst_image_h.clip_rect.w = 300;
    test_info.info.dst_image_h.clip_rect.h = 1200;
    test_info.info.dst_image_h.color = 0xFFFF0000; //A,R,G,B
    test_info.info.dst_image_h.mode = G2D_MIXER_ALPHA; //G2D_PIXEL_ALPHA,G2D_GLOBAL_ALPHA,G2D_MIXER_ALPHA
    test_info.info.dst_image_h.alpha = 0x30;

    if(ioctl(test_info.fd , G2D_CMD_FILLRECT_H ,(unsigned long)(&test_info.info)) < 0)
    {
        printf("[%d][%s][%s]G2D_CMD_FILLRECT_H failure!\n",__LINE__, __FILE__,__FUNCTION__);
        ion_memory_release(dst_fd);
        close(test_info.fd);

        return -1;
    }

    if(ioctl(test_info.fd , G2D_CMD_FILLRECT_H ,(unsigned long)(&test_info.info)) < 0)
    {
        printf("[%d][%s][%s]G2D_CMD_FILLRECT_H failure!\n",__LINE__, __FILE__,__FUNCTION__);
        ion_memory_release(dst_fd);
        close(test_info.fd);

        return -1;
    }
    
    
            
        
    //Green
    test_info.info.dst_image_h.format = G2D_FORMAT_ARGB8888;
    test_info.info.dst_image_h.width = 1920;
    test_info.info.dst_image_h.height = 1200;
    test_info.info.dst_image_h.clip_rect.x = 400;
    test_info.info.dst_image_h.clip_rect.y = 0;
    test_info.info.dst_image_h.clip_rect.w = 300;
    test_info.info.dst_image_h.clip_rect.h = 1200;
    test_info.info.dst_image_h.color = 0xFF00FF00;//A,R,G,B
    test_info.info.dst_image_h.mode = 1;
    test_info.info.dst_image_h.alpha = 0xFF;
    
    if(ioctl(test_info.fd , G2D_CMD_FILLRECT_H ,(unsigned long)(&test_info.info)) < 0)
    {
        printf("[%d][%s][%s]G2D_CMD_FILLRECT_H failure!\n",__LINE__, __FILE__,__FUNCTION__);
        ion_memory_release(dst_fd);
        close(test_info.fd);

        return -1;
    }
    
    
            

    //Blue
	test_info.info.dst_image_h.format = G2D_FORMAT_ARGB8888;
	test_info.info.dst_image_h.width = 1920;
	test_info.info.dst_image_h.height = 1200;
	test_info.info.dst_image_h.clip_rect.x = 800;
	test_info.info.dst_image_h.clip_rect.y = 0;
	test_info.info.dst_image_h.clip_rect.w = 300;
	test_info.info.dst_image_h.clip_rect.h = 1200;
	test_info.info.dst_image_h.color = 0xFF0000FF;//A,R,G,B
	test_info.info.dst_image_h.mode = 1;
	test_info.info.dst_image_h.alpha = 0xFF;


    /* fill color */
    if(ioctl(test_info.fd , G2D_CMD_FILLRECT_H ,(unsigned long)(&test_info.info)) < 0)
    {
        printf("[%d][%s][%s]G2D_CMD_FILLRECT_H failure!\n",__LINE__, __FILE__,__FUNCTION__);
        ion_memory_release(dst_fd);
        close(test_info.fd);

        return -1;
    }
    
        
        
        
                
        
	/* save result data to file */
	printf("save result data to file %s \n", test_info.out_filename);
	/* save result data to file */
	if((test_info.fp = fopen(test_info.out_filename, "wb+")) == NULL) {
		printf("open file %s fail. \n", test_info.out_filename);
		ion_memory_release(dst_fd);
		return -1;
	} else {
		printf("open file %s ok. \n", test_info.out_filename);
	}
	printf("==out_size=%d, addr=%p==\n", out_size, test_info.dst_ion.virt_addr);
	ret = fwrite(test_info.dst_ion.virt_addr, out_size, 1, test_info.fp);
	printf("fwrite,ret=%d\n", ret);
	munmap(test_info.dst_ion.virt_addr, out_size);
	fclose(test_info.fp);

	ion_memory_release(dst_fd);
	close(test_info.fd);

	return 0;
}
STAGING_DIR="" /opt/T113_Tina5.0/prebuilt/rootfsbuilt/arm/toolchain-sunxi-glibc-gcc-830/toolchain/bin/arm-openwrt-linux-gcc -o /mnt/hgfs/D/g2d_fill_dmabuf src/g2d_fill_dmabuf.c
# chmod +x /tmp/g2d_fill_dmabuf && /tmp/g2d_fill_dmabuf
out_size=9216000
[ion_open]: success fd = 4
ion_memory_request(107): ion_fd 4
---> is_iommu_enabled
ion_memory_request(124): ION_HEAP_TYPE 0x1
ion_memory_request(133): ION_IOC_ALLOC succes, dmabuf-fd = 0, size = 9216000

save result data to file /tmp/fill_dmabuf_1920x1200_bgra8888.bin
open file /tmp/fill_dmabuf_1920x1200_bgra8888.bin ok.
==out_size=9216000, addr=0xb6500000==
fwrite,ret=1
#
#
adb pull /tmp/fill_dmabuf_1920x1200_bgra8888.bin

QQ截图20240630112430.png

离线

楼主 #5 2024-07-01 15:41:40

memory
会员
注册时间: 2021-08-11
已发帖子: 487
积分: 464

Re: 全志T113 Linux G2D学习

旋转测试:

chmod +x /tmp/g2d_lbc_rot && /tmp/g2d_lbc_rot -flag 256 -in_fb 0 800 480 -src_rect 0 0 800 480 -out_fb 0 480 800 -dst_rect 0 0 480 800 -src_file /tmp/src_800x480_rgb.bin -dst_file /tmp/en_src_480x800_bgra888_rotate_90.bin

原图:
QQ截图20240701153922.png

旋转90°:
QQ截图20240701153827.png

离线

楼主 #6 2024-07-01 15:53:43

memory
会员
注册时间: 2021-08-11
已发帖子: 487
积分: 464

Re: 全志T113 Linux G2D学习

测试水平镜像:

chmod +x /tmp/g2d_lbc_rot && /tmp/g2d_lbc_rot -flag 4096 -in_fb 0 800 480 -src_rect 0 0 800 480 -out_fb 0 800 480 -dst_rect 0 0 800 480 -src_file /tmp/src_800x480_rgb.bin -dst_file /tmp/en_dst_800x480_bgra888_flip_h.bin

QQ截图20240701155316.png

离线

楼主 #7 2024-07-01 16:16:08

memory
会员
注册时间: 2021-08-11
已发帖子: 487
积分: 464

Re: 全志T113 Linux G2D学习

但是开启lbc失败:

chmod +x /tmp/g2d_lbc_rot && /tmp/g2d_lbc_rot -flag 4096 -in_fb 0 800 480 -src_rect 0 0 800 480 -out_fb 0 800 480 -dst_rect 0 0 800 480 -src_file /tmp/src_800x480_rgb.bin -dst_file /tmp/en_dst_800x480_bgra888_flip_h.bin -lbc 1 -cmp_ratio 400 -enc_lossy 1 -dec_lossy 1

# chmod +x /tmp/g2d_lbc_rot && /tmp/g2d_lbc_rot -flag 4096 -in_fb 0 800 480 -src
_rect 0 0 800 480 -out_fb 0 800 480 -dst_rect 0 0 800 480 -src_file /tmp/src_800
x480_rgb.bin -dst_file /tmp/en_dst_800x480_bgra888_flip_h.bin -lbc 1 -cmp_ratio
400 -enc_lossy 1 -dec_lossy 1
/tmp/g2d_lbc_rot -flag 4096 -in_fb 0 800 480 -src_rect 0 0 800 480 -out_fb 0 800 480 -dst_rect 0 0 800 480 -src_file /tmp/src_800x480_rgb.bin -dst_file /tmp/en_dst_800x480_bgra888_flip_h.bin -lbc 1 -cmp_ratio 400 -enc_lossy 1 -dec_lossy 1
src_file=/tmp/src_800x480_rgb.bin
dst_file=/tmp/en_dst_800x480_bgra888_flip_h.bin
in_size:1536000, out_size=1536000
ready to open src file /tmp/src_800x480_rgb.bin
[ion_open]: success fd = 4
ion_memory_request(295): ion_fd 4
ion_memory_request(306): ION_HEAP_TYPE 0x1
ion_memory_request(315): ION_IOC_ALLOC succes, dmabuf-fd = 0, size = 1536000

+++src_fd = 5
open file /tmp/src_800x480_rgb.bin ok.
read file /tmp/src_800x480_rgb.bin ,ret = 1
ready to open dst file /tmp/en_dst_800x480_bgra888_flip_h.bin
ion_memory_request(295): ion_fd 4
ion_memory_request(306): ION_HEAP_TYPE 0x1
ion_memory_request(315): ION_IOC_ALLOC succes, dmabuf-fd = 0, size = 1536000

+++dst_fd = 7
open file /tmp/en_dst_800x480_bgra888_flip_h.bin ok.
src:format=0x0, w=800, h=480, x=0, y=0, image_w=800, image_h=480, align=0

dst:format=0x0, img w=800, h=480, rect x=0, y=0, w=800, h=480, align=0

[G2D] LBC=1
[460][src/g2d_lbc_rot.c][main]G2D_CMD_LBC_ROT failure!
#
#
#
#

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn