WhyCan Forum(哇酷开发者社区)

我们习惯了"有问题百度一下", 感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信: whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn

您尚未登录。

#1 2018-06-30 11:36:57

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,188

2d绘图引擎 Cairo 在 V3s@Linux运行成功

参考链接1: 2d绘图引擎 Cairo 在 V3s@Linux运行成功
参考链接2: 2d绘图引擎 Cairo 在 SDL@Ubuntu 运行成功

Cairo 在 V3s@Linux运行成功

离线

#2 2018-06-30 11:38:03

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,188

Re: 2d绘图引擎 Cairo 在 V3s@Linux运行成功

参考cairo 绘图引擎和buildroot帖子:

https://whycan.cn/t_1006.html
https://whycan.cn/t_561.html

离线

#3 2018-06-30 11:39:27

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,188

Re: 2d绘图引擎 Cairo 在 V3s@Linux运行成功

打开buidroot根目录下 .config 文件,开启:

BR2_PACKAGE_CAIRO=y
BR2_PACKAGE_PIXMAN=y

接下来直接make即可.

打包部分 lib 文件:

cd /disk4/buildroot-2017.08.1/output/host/arm-buildroot-linux-gnueabi/sysroot
tar cvf /mnt/hgfs/E/libcairo.tar ./usr/lib/libcairo* ./usr/lib/engines/lib* ./usr/lib/libpixman-1.* ./usr/lib/libfontconfig.* ./usr/lib/libexpat.* ./usr/lib/libfreetype.* ./usr/lib/libatomic.*

下载解压缩到目标板子:

tftp 192.168.1.99 -g -r libcairo.tar;
tar xvf libcairo.tar -C /;

下载一个 cairo 应用源码 https://raw.githubusercontent.com/toradex/cairo-fb-examples/master/rectangles/rectangles.c:

/*
 * Demo application drawing rectangles on screen using fbdev
 *
 * This demo shows how to use the fbdev API to sync to vertical blank
 * on Colibri VF50/VF61
 *
 * Copyright (c) 2015, Toradex AG
 *
 * This project is licensed under the terms of the MIT license (see
 * LICENSE)
 */
#include <cairo/cairo.h>
#include <fcntl.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/fb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <stropts.h>
#include <sys/mman.h>
#include <tslib.h>
#include <time.h>

static volatile sig_atomic_t cancel = 0;

typedef struct _cairo_linuxfb_device {
	int fb_fd;
	unsigned char *fb_data;
	long fb_screensize;
	struct fb_var_screeninfo fb_vinfo;
	struct fb_fix_screeninfo fb_finfo;
} cairo_linuxfb_device_t;

void signal_handler(int signum)
{
	cancel = 1;
}

/*
 * Flip framebuffer, return the next buffer id which will be used
 */
int flip_buffer(cairo_linuxfb_device_t *device, int vsync, int bufid)
{
	int dummy = 0;

	/* Pan the framebuffer */
	device->fb_vinfo.yoffset = device->fb_vinfo.yres * bufid;
	if (ioctl(device->fb_fd, FBIOPAN_DISPLAY, &device->fb_vinfo)) {
		perror("Error panning display");
		return -1;
	}

	if (vsync) {
		if (ioctl(device->fb_fd, FBIO_WAITFORVSYNC, &dummy)) {
			perror("Error waiting for VSYNC");
			return -1;
		}
	}

	return 0;
}


/* Destroy a cairo surface */
void cairo_linuxfb_surface_destroy(void *device)
{
	cairo_linuxfb_device_t *dev = (cairo_linuxfb_device_t *)device;

	if (dev == NULL)
		return;

	munmap(dev->fb_data, dev->fb_screensize);
	close(dev->fb_fd);
	free(dev);
}

/* Create a cairo surface using the specified framebuffer */
cairo_surface_t *cairo_linuxfb_surface_create(cairo_linuxfb_device_t *device, const char *fb_name)
{
	cairo_surface_t *surface;

	// Open the file for reading and writing
	device->fb_fd = open(fb_name, O_RDWR);
	if (device->fb_fd == -1) {
		perror("Error: cannot open framebuffer device");
		goto handle_allocate_error;
	}

	// Get variable screen information
	if (ioctl(device->fb_fd, FBIOGET_VSCREENINFO, &device->fb_vinfo) == -1) {
		perror("Error: reading variable information");
		goto handle_ioctl_error;
	}

	/* Set virtual display size double the width for double buffering */
	device->fb_vinfo.yoffset = 0;
	device->fb_vinfo.yres_virtual = device->fb_vinfo.yres * 2;
	if (ioctl(device->fb_fd, FBIOPUT_VSCREENINFO, &device->fb_vinfo)) {
		perror("Error setting variable screen info from fb");
		goto handle_ioctl_error;
	}

	// Get fixed screen information
	if (ioctl(device->fb_fd, FBIOGET_FSCREENINFO, &device->fb_finfo) == -1) {
		perror("Error reading fixed information");
		goto handle_ioctl_error;
	}

	// Map the device to memory
	device->fb_data = (unsigned char *)mmap(0, device->fb_finfo.smem_len,
			PROT_READ | PROT_WRITE, MAP_SHARED,
			device->fb_fd, 0);
	if ((int)device->fb_data == -1) {
		perror("Error: failed to map framebuffer device to memory");
		goto handle_ioctl_error;
	}


	/* Create the cairo surface which will be used to draw to */
	surface = cairo_image_surface_create_for_data(device->fb_data,
			CAIRO_FORMAT_RGB16_565,
			device->fb_vinfo.xres,
			device->fb_vinfo.yres_virtual,
			cairo_format_stride_for_width(CAIRO_FORMAT_RGB16_565,
				device->fb_vinfo.xres));
	cairo_surface_set_user_data(surface, NULL, device,
			&cairo_linuxfb_surface_destroy);

	return surface;

handle_ioctl_error:
	close(device->fb_fd);
handle_allocate_error:
	free(device);
	exit(1);
}

void draw_rectangles(cairo_t *fbcr, struct tsdev *ts, cairo_linuxfb_device_t *device)
{
	int bufid = 1; /* start drawing into second buffer */
	float r, g, b;
	int fbsizex = device->fb_vinfo.xres;
	int fbsizey = device->fb_vinfo.yres;
	int startx, starty, sizex, sizey;
	struct ts_sample sample;
	cairo_surface_t *surface;
	cairo_t *cr;
	float scale = 1.0f;

	surface = cairo_image_surface_create(CAIRO_FORMAT_RGB16_565,
			fbsizex, fbsizey);
	cr = cairo_create(surface);

	/* 
	 * We clear the cairo surface here before drawing
	 * This is required in case something was drawn on this surface
	 * previously, the previous contents would not be cleared without this.
	 */
	cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
	cairo_paint(cr);

	cairo_set_operator(cr, CAIRO_OPERATOR_OVER);

	srand(time(NULL));

	while (!cancel) {
		r = (rand() % 100) / 100.0;
		g = (rand() % 100) / 100.0;
		b = (rand() % 100) / 100.0;
		startx = rand() % fbsizex;
		starty = rand() % fbsizey;
		sizex = rand() % (fbsizex - startx);
		sizey = rand() % (fbsizey - starty);

		cairo_identity_matrix(cr);
		if (ts) {
			int pressed = 0;

			/* Pressure is our identication whether we act on axis... */
			while (ts_read(ts, &sample, 1)) {
				if (sample.pressure > 0)
					pressed = 1;
			}

			if (pressed) {
				scale *= 1.05f;
				cairo_translate(cr, sample.x, sample.y);
				cairo_scale(cr, scale, scale);
				//r = g = b = 0;
				startx = -5;
				starty = -5;
				sizex = 10;
				sizey = 10;
			} else {
				scale = 1.0f;
			}
		}

		cairo_set_source_rgb(cr, r, g, b);
		cairo_rectangle(cr, startx, starty, sizex, sizey);
		cairo_stroke_preserve(cr);
		cairo_fill(cr);

		/* Draw to framebuffer at y offset according to current buffer.. */
		cairo_set_source_surface(fbcr, surface, 0, bufid * fbsizey);
		cairo_paint(fbcr);
		flip_buffer(device, 1, bufid);

		/* Switch buffer ID for next draw */
		bufid = !bufid;
		usleep(20000);
	}

	/* Make sure we leave with buffer 0 enabled */
	flip_buffer(device, 1, 0);

	/* Destroy and release all cairo related contexts */
	cairo_destroy(cr);
	cairo_surface_destroy(surface);
}

int main(int argc, char *argv[]) {
	char fb_node[16] = "/dev/fb0";
	char *tsdevice = NULL;
	struct tsdev *ts;
	struct sigaction action;
	cairo_linuxfb_device_t *device;
	cairo_surface_t *fbsurface;
	cairo_t *fbcr;

	if (argc > 1) {
		strcpy(fb_node, argv[1]);
	}

	printf("Frame buffer node is: %s\n", fb_node);

	if( (tsdevice = getenv("TSLIB_TSDEVICE")) != NULL )
		ts = ts_open(tsdevice, 1);
	else
		ts = ts_open("/dev/input/event0", 1);

	if (ts_config(ts)) {
		perror("ts_config");
		exit(1);
	}

	device = malloc(sizeof(*device));
	if (!device) {
		perror("Error: cannot allocate memory\n");
		exit(1);
	}

	memset(&action, 0, sizeof(struct sigaction));
	action.sa_handler = signal_handler;
	sigaction(SIGTERM, &action, NULL);
	sigaction(SIGINT, &action, NULL);

	fbsurface = cairo_linuxfb_surface_create(device, fb_node);
	fbcr = cairo_create(fbsurface);

	draw_rectangles(fbcr, ts, device);

	cairo_destroy(fbcr);
	cairo_surface_destroy(fbsurface);

	return 0;
}

编译应用程序:

/disk4/buildroot-2017.08.1/output/host/bin/arm-linux-gcc -o test rectangles.c  -lcairo -lts

可以运行,但是会抛出一个错误:

# ./test
Frame buffer node is: /dev/fb0
Error panning display: Invalid argument
Error panning display: Invalid argument
Error panning display: Invalid argument
Error panning display: Invalid argument
Error panning display: Invalid argument
Error panning display: Invalid argument
Error panning display: Invalid argument
Error panning display: Invalid argument
Error panning display: Invalid argument

运行结果:
QQ20180630114653.jpg

看起来这个画矩形的 cairo demo 有点问题。

离线

#4 2018-06-30 13:48:55

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,188

Re: 2d绘图引擎 Cairo 在 V3s@Linux运行成功

QQ20180630134644.jpeg

CAIRO_FORMAT_RGB16_565

代码改成这样,重新编译运行,基本正常了.

CAIRO_FORMAT_RGB24

/*
 * Demo application drawing rectangles on screen using fbdev
 *
 * This demo shows how to use the fbdev API to sync to vertical blank
 * on Colibri VF50/VF61
 *
 * Copyright (c) 2015, Toradex AG
 *
 * This project is licensed under the terms of the MIT license (see
 * LICENSE)
 */
#include <cairo/cairo.h>
#include <fcntl.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/fb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <stropts.h>
#include <sys/mman.h>
#include <tslib.h>
#include <time.h>

static volatile sig_atomic_t cancel = 0;

typedef struct _cairo_linuxfb_device {
	int fb_fd;
	unsigned char *fb_data;
	long fb_screensize;
	struct fb_var_screeninfo fb_vinfo;
	struct fb_fix_screeninfo fb_finfo;
} cairo_linuxfb_device_t;

void signal_handler(int signum)
{
	cancel = 1;
}

/*
 * Flip framebuffer, return the next buffer id which will be used
 */
int flip_buffer(cairo_linuxfb_device_t *device, int vsync, int bufid)
{
	int dummy = 0;

	/* Pan the framebuffer */
	device->fb_vinfo.yoffset = device->fb_vinfo.yres * bufid;
	if (ioctl(device->fb_fd, FBIOPAN_DISPLAY, &device->fb_vinfo)) {
		perror("Error panning display");
		return -1;
	}

	if (vsync) {
		if (ioctl(device->fb_fd, FBIO_WAITFORVSYNC, &dummy)) {
			perror("Error waiting for VSYNC");
			return -1;
		}
	}

	return 0;
}


/* Destroy a cairo surface */
void cairo_linuxfb_surface_destroy(void *device)
{
	cairo_linuxfb_device_t *dev = (cairo_linuxfb_device_t *)device;

	if (dev == NULL)
		return;

	munmap(dev->fb_data, dev->fb_screensize);
	close(dev->fb_fd);
	free(dev);
}

/* Create a cairo surface using the specified framebuffer */
cairo_surface_t *cairo_linuxfb_surface_create(cairo_linuxfb_device_t *device, const char *fb_name)
{
	cairo_surface_t *surface;

	// Open the file for reading and writing
	device->fb_fd = open(fb_name, O_RDWR);
	if (device->fb_fd == -1) {
		perror("Error: cannot open framebuffer device");
		goto handle_allocate_error;
	}

	// Get variable screen information
	if (ioctl(device->fb_fd, FBIOGET_VSCREENINFO, &device->fb_vinfo) == -1) {
		perror("Error: reading variable information");
		goto handle_ioctl_error;
	}

	/* Set virtual display size double the width for double buffering */
	device->fb_vinfo.yoffset = 0;
	device->fb_vinfo.yres_virtual = device->fb_vinfo.yres * 2;
	if (ioctl(device->fb_fd, FBIOPUT_VSCREENINFO, &device->fb_vinfo)) {
		perror("Error setting variable screen info from fb");
		goto handle_ioctl_error;
	}

	// Get fixed screen information
	if (ioctl(device->fb_fd, FBIOGET_FSCREENINFO, &device->fb_finfo) == -1) {
		perror("Error reading fixed information");
		goto handle_ioctl_error;
	}

	// Map the device to memory
	device->fb_data = (unsigned char *)mmap(0, device->fb_finfo.smem_len,
			PROT_READ | PROT_WRITE, MAP_SHARED,
			device->fb_fd, 0);
	if ((int)device->fb_data == -1) {
		perror("Error: failed to map framebuffer device to memory");
		goto handle_ioctl_error;
	}


	/* Create the cairo surface which will be used to draw to */
	surface = cairo_image_surface_create_for_data(device->fb_data,
			CAIRO_FORMAT_RGB24,
			device->fb_vinfo.xres,
			device->fb_vinfo.yres_virtual,
			cairo_format_stride_for_width(CAIRO_FORMAT_RGB24,
				device->fb_vinfo.xres));
	cairo_surface_set_user_data(surface, NULL, device,
			&cairo_linuxfb_surface_destroy);

	return surface;

handle_ioctl_error:
	close(device->fb_fd);
handle_allocate_error:
	free(device);
	exit(1);
}

void draw_rectangles(cairo_t *fbcr, struct tsdev *ts, cairo_linuxfb_device_t *device)
{
	int bufid = 1; /* start drawing into second buffer */
	float r, g, b;
	int fbsizex = device->fb_vinfo.xres;
	int fbsizey = device->fb_vinfo.yres;
	int startx, starty, sizex, sizey;
	struct ts_sample sample;
	cairo_surface_t *surface;
	cairo_t *cr;
	float scale = 1.0f;

	surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
			fbsizex, fbsizey);
	cr = cairo_create(surface);

	/* 
	 * We clear the cairo surface here before drawing
	 * This is required in case something was drawn on this surface
	 * previously, the previous contents would not be cleared without this.
	 */
	cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
	cairo_paint(cr);

	cairo_set_operator(cr, CAIRO_OPERATOR_OVER);

	srand(time(NULL));

	while (!cancel) {
		r = (rand() % 100) / 100.0;
		g = (rand() % 100) / 100.0;
		b = (rand() % 100) / 100.0;
		startx = rand() % fbsizex;
		starty = rand() % fbsizey;
		sizex = rand() % (fbsizex - startx);
		sizey = rand() % (fbsizey - starty);

		cairo_identity_matrix(cr);
		if (ts) {
			int pressed = 0;

			/* Pressure is our identication whether we act on axis... */
			while (ts_read(ts, &sample, 1)) {
				if (sample.pressure > 0)
					pressed = 1;
			}

			if (pressed) {
				scale *= 1.05f;
				cairo_translate(cr, sample.x, sample.y);
				cairo_scale(cr, scale, scale);
				//r = g = b = 0;
				startx = -5;
				starty = -5;
				sizex = 10;
				sizey = 10;
			} else {
				scale = 1.0f;
			}
		}

		cairo_set_source_rgb(cr, r, g, b);
		cairo_rectangle(cr, startx, starty, sizex, sizey);
		cairo_stroke_preserve(cr);
		cairo_fill(cr);

		/* Draw to framebuffer at y offset according to current buffer.. */
		cairo_set_source_surface(fbcr, surface, 0, bufid * fbsizey);
		cairo_paint(fbcr);
		flip_buffer(device, 1, bufid);

		/* Switch buffer ID for next draw */
		bufid = !bufid;
		usleep(20000);
	}

	/* Make sure we leave with buffer 0 enabled */
	flip_buffer(device, 1, 0);

	/* Destroy and release all cairo related contexts */
	cairo_destroy(cr);
	cairo_surface_destroy(surface);
}

int main(int argc, char *argv[]) {
	char fb_node[16] = "/dev/fb0";
	char *tsdevice = NULL;
	struct tsdev *ts;
	struct sigaction action;
	cairo_linuxfb_device_t *device;
	cairo_surface_t *fbsurface;
	cairo_t *fbcr;

	if (argc > 1) {
		strcpy(fb_node, argv[1]);
	}

	printf("Frame buffer node is: %s\n", fb_node);

	if( (tsdevice = getenv("TSLIB_TSDEVICE")) != NULL )
		ts = ts_open(tsdevice, 1);
	else
		ts = ts_open("/dev/input/event0", 1);

	if (ts_config(ts)) {
		perror("ts_config");
		exit(1);
	}

	device = malloc(sizeof(*device));
	if (!device) {
		perror("Error: cannot allocate memory\n");
		exit(1);
	}

	memset(&action, 0, sizeof(struct sigaction));
	action.sa_handler = signal_handler;
	sigaction(SIGTERM, &action, NULL);
	sigaction(SIGINT, &action, NULL);

	fbsurface = cairo_linuxfb_surface_create(device, fb_node);
	fbcr = cairo_create(fbsurface);

	draw_rectangles(fbcr, ts, device);

	cairo_destroy(fbcr);
	cairo_surface_destroy(fbsurface);

	return 0;
}

离线

#5 2018-06-30 18:50:47

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,188

Re: 2d绘图引擎 Cairo 在 V3s@Linux运行成功

/*
 * Demo application drawing rectangles on screen using fbdev
 *
 * This demo shows how to use the fbdev API to sync to vertical blank
 * on Colibri VF50/VF61
 *
 * Copyright (c) 2015, Toradex AG
 *
 * This project is licensed under the terms of the MIT license (see
 * LICENSE)
 */
#include <cairo/cairo.h>
#include <fcntl.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/fb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <stropts.h>
#include <sys/mman.h>
#include <tslib.h>
#include <time.h>
#include <math.h>

static volatile sig_atomic_t cancel = 0;

typedef struct _cairo_linuxfb_device {
	int fb_fd;
	unsigned char *fb_data;
	long fb_screensize;
	struct fb_var_screeninfo fb_vinfo;
	struct fb_fix_screeninfo fb_finfo;
} cairo_linuxfb_device_t;

void signal_handler(int signum)
{
	cancel = 1;
}

/*
 * Flip framebuffer, return the next buffer id which will be used
 */
int flip_buffer(cairo_linuxfb_device_t *device, int vsync, int bufid)
{
	int dummy = 0;

	/* Pan the framebuffer */
	device->fb_vinfo.yoffset = device->fb_vinfo.yres * bufid;
	if (ioctl(device->fb_fd, FBIOPAN_DISPLAY, &device->fb_vinfo)) {
		perror("Error panning display");
		return -1;
	}

	if (vsync) {
		if (ioctl(device->fb_fd, FBIO_WAITFORVSYNC, &dummy)) {
			perror("Error waiting for VSYNC");
			return -1;
		}
	}

	return 0;
}


/* Destroy a cairo surface */
void cairo_linuxfb_surface_destroy(void *device)
{
	cairo_linuxfb_device_t *dev = (cairo_linuxfb_device_t *)device;

	if (dev == NULL)
		return;

	munmap(dev->fb_data, dev->fb_screensize);
	close(dev->fb_fd);
	free(dev);
}

/* Create a cairo surface using the specified framebuffer */
cairo_surface_t *cairo_linuxfb_surface_create(cairo_linuxfb_device_t *device, const char *fb_name)
{
	cairo_surface_t *surface;

	// Open the file for reading and writing
	device->fb_fd = open(fb_name, O_RDWR);
	if (device->fb_fd == -1) {
		perror("Error: cannot open framebuffer device");
		goto handle_allocate_error;
	}

	// Get variable screen information
	if (ioctl(device->fb_fd, FBIOGET_VSCREENINFO, &device->fb_vinfo) == -1) {
		perror("Error: reading variable information");
		goto handle_ioctl_error;
	}

	/* Set virtual display size double the width for double buffering */
	device->fb_vinfo.yoffset = 0;
	device->fb_vinfo.yres_virtual = device->fb_vinfo.yres * 2;
	if (ioctl(device->fb_fd, FBIOPUT_VSCREENINFO, &device->fb_vinfo)) {
		perror("Error setting variable screen info from fb");
		goto handle_ioctl_error;
	}

	// Get fixed screen information
	if (ioctl(device->fb_fd, FBIOGET_FSCREENINFO, &device->fb_finfo) == -1) {
		perror("Error reading fixed information");
		goto handle_ioctl_error;
	}

	// Map the device to memory
	device->fb_data = (unsigned char *)mmap(0, device->fb_finfo.smem_len,
			PROT_READ | PROT_WRITE, MAP_SHARED,
			device->fb_fd, 0);
	if ((int)device->fb_data == -1) {
		perror("Error: failed to map framebuffer device to memory");
		goto handle_ioctl_error;
	}


	/* Create the cairo surface which will be used to draw to */
	surface = cairo_image_surface_create_for_data(device->fb_data,
			CAIRO_FORMAT_RGB24,
			device->fb_vinfo.xres,
			device->fb_vinfo.yres_virtual,
			cairo_format_stride_for_width(CAIRO_FORMAT_RGB24,
				device->fb_vinfo.xres));
	cairo_surface_set_user_data(surface, NULL, device,
			&cairo_linuxfb_surface_destroy);

	return surface;

handle_ioctl_error:
	close(device->fb_fd);
handle_allocate_error:
	free(device);
	exit(1);
}

void draw_rectangles(cairo_t *fbcr, struct tsdev *ts, cairo_linuxfb_device_t *device)
{
	int bufid = 1; /* start drawing into second buffer */
	float r, g, b;
	int fbsizex = device->fb_vinfo.xres;
	int fbsizey = device->fb_vinfo.yres;
	int startx, starty, sizex, sizey;
	struct ts_sample sample;
	cairo_surface_t *surface;
	cairo_t *cr;
	float scale = 1.0f;

	surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
			fbsizex, fbsizey);
	cr = cairo_create(surface);

	/* 
	 * We clear the cairo surface here before drawing
	 * This is required in case something was drawn on this surface
	 * previously, the previous contents would not be cleared without this.
	 */
	cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
	cairo_paint(cr);

	cairo_set_operator(cr, CAIRO_OPERATOR_OVER);

	srand(time(NULL));

	int k = 0;
	while (!cancel) 
	{
		k++;
		if(k>3) break;


		int width=800, height=480;

		cairo_set_line_width(cr, 9);  
		cairo_set_source_rgb(cr, 0.69, 0.19, 0);

		cairo_translate(cr, width/2, height/2);
		cairo_arc(cr, 0, 0, 50, 0, 2 * M_PI);
		cairo_stroke_preserve(cr);

		cairo_set_source_rgb(cr, 0.3, 0.4, 0.6); 
		cairo_fill(cr);  



		cairo_set_line_width(cr, 10);

		cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT); 
		cairo_move_to(cr, 30, 50); 
		cairo_line_to(cr, 150, 50);
		cairo_stroke(cr);

		cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); 
		cairo_move_to(cr, 30, 90); 
		cairo_line_to(cr, 150, 90);
		cairo_stroke(cr);

		cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE); 
		cairo_move_to(cr, 30, 130); 
		cairo_line_to(cr, 150, 130);
		cairo_stroke(cr);

		cairo_set_line_width(cr, 1.5);

		cairo_move_to(cr, 30, 40);  
		cairo_line_to(cr, 30, 140);
		cairo_stroke(cr);

		cairo_move_to(cr, 150, 40);  
		cairo_line_to(cr, 150, 140);
		cairo_stroke(cr);

		cairo_move_to(cr, 155, 40);  
		cairo_line_to(cr, 155, 140);
		cairo_stroke(cr);    


		/* Draw to framebuffer at y offset according to current buffer.. */
		cairo_set_source_surface(fbcr, surface, 0, bufid * fbsizey);
		cairo_paint(fbcr);
		flip_buffer(device, 1, bufid);

		/* Switch buffer ID for next draw */
		bufid = !bufid;
		usleep(20000);
	}

	/* Make sure we leave with buffer 0 enabled */
	flip_buffer(device, 1, 0);

	/* Destroy and release all cairo related contexts */
	cairo_destroy(cr);
	cairo_surface_destroy(surface);
}

int main(int argc, char *argv[]) {
	char fb_node[16] = "/dev/fb0";
	char *tsdevice = NULL;
	struct tsdev *ts;
	struct sigaction action;
	cairo_linuxfb_device_t *device;
	cairo_surface_t *fbsurface;
	cairo_t *fbcr;

	if (argc > 1) {
		strcpy(fb_node, argv[1]);
	}

	printf("Frame buffer node is: %s\n", fb_node);

	if( (tsdevice = getenv("TSLIB_TSDEVICE")) != NULL )
		ts = ts_open(tsdevice, 1);
	else
		ts = ts_open("/dev/input/event0", 1);

	if (ts_config(ts)) {
		perror("ts_config");
		exit(1);
	}

	device = malloc(sizeof(*device));
	if (!device) {
		perror("Error: cannot allocate memory\n");
		exit(1);
	}

	memset(&action, 0, sizeof(struct sigaction));
	action.sa_handler = signal_handler;
	sigaction(SIGTERM, &action, NULL);
	sigaction(SIGINT, &action, NULL);

	fbsurface = cairo_linuxfb_surface_create(device, fb_node);
	fbcr = cairo_create(fbsurface);

	draw_rectangles(fbcr, ts, device);

	cairo_destroy(fbcr);
	cairo_surface_destroy(fbsurface);

	return 0;
}

离线

#6 2018-06-30 23:29:25

Lvy
会员
注册时间: 2017-11-25
累计积分: 99

Re: 2d绘图引擎 Cairo 在 V3s@Linux运行成功

有V3S的板子,有空试试!谢谢晕哥!!!

离线

#7 2018-11-01 17:16:20

605364021
会员
注册时间: 2018-10-23
累计积分: 251

Re: 2d绘图引擎 Cairo 在 V3s@Linux运行成功

晕哥 说:

打开buidroot根目录下 .config 文件,开启:

BR2_PACKAGE_CAIRO=y
BR2_PACKAGE_PIXMAN=y

接下来直接make即可.

我在.config中加入后编译出现这样的错误

zhang@zhang-virtual-machine:~/buildroot-2017.08.1$ make
Makefile:539: *** fontconfig is in the dependency chain of cairo that has added it to its _DEPENDENCIES variable without selecting it or depending on it from Config.in。 停止。
Makefile:79: recipe for target '_all' failed
make: *** [_all] Error 2

是buildroot没配置好?

离线

#8 2018-11-01 17:19:38

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,188

Re: 2d绘图引擎 Cairo 在 V3s@Linux运行成功

605364021 说:
晕哥 说:

打开buidroot根目录下 .config 文件,开启:

BR2_PACKAGE_CAIRO=y
BR2_PACKAGE_PIXMAN=y

接下来直接make即可.

我在.config中加入后编译出现这样的错误

zhang@zhang-virtual-machine:~/buildroot-2017.08.1$ make
Makefile:539: *** fontconfig is in the dependency chain of cairo that has added it to its _DEPENDENCIES variable without selecting it or depending on it from Config.in。 停止。
Makefile:79: recipe for target '_all' failed
make: *** [_all] Error 2

是buildroot没配置好?

应该是缺 字体相关配置, 把 字体相关先全部勾上试一试。

离线

#9 2018-11-03 10:11:00

605364021
会员
注册时间: 2018-10-23
累计积分: 251

Re: 2d绘图引擎 Cairo 在 V3s@Linux运行成功

# ./arm_test 
Frame buffer node is: /dev/fb0
Couldn't open tslib config file: No such file or directory
ts_config: No such file or directory.

程序代码是帖子的应用源码。。。

离线

页脚

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