/*
 * Copyright (C) 2013 Samsung Electronics Co.Ltd
 * Authors:
 *	Inki Dae <inki.dae@samsung.com>
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>

#include <sys/mman.h>
#include <linux/stddef.h>

#include <xf86drm.h>
#include <xf86drmMode.h>
#include <libkms.h>
#include <drm_fourcc.h>

#include "exynos_drm.h"
#include "exynos_drmif.h"
#include "exynos_fimg2d.h"

#define DRM_MODULE_NAME		"exynos"

static unsigned int screen_width, screen_height;

struct connector {
	uint32_t id;
	char mode_str[64];
	drmModeModeInfo *mode;
	drmModeEncoder *encoder;
	int crtc;
};

static void connector_find_mode(int fd, struct connector *c,
				drmModeRes *resources)
{
	drmModeConnector *connector;
	int i, j;

	/* First, find the connector & mode */
	c->mode = NULL;
	for (i = 0; i < resources->count_connectors; i++) {
		connector = drmModeGetConnector(fd, resources->connectors[i]);

		if (!connector) {
			fprintf(stderr, "could not get connector %i: %s\n",
				resources->connectors[i], strerror(errno));
			drmModeFreeConnector(connector);
			continue;
		}

		if (!connector->count_modes) {
			drmModeFreeConnector(connector);
			continue;
		}

		if (connector->connector_id != c->id) {
			drmModeFreeConnector(connector);
			continue;
		}

		for (j = 0; j < connector->count_modes; j++) {
			c->mode = &connector->modes[j];
			if (!strcmp(c->mode->name, c->mode_str))
				break;
		}

		/* Found it, break out */
		if (c->mode)
			break;

		drmModeFreeConnector(connector);
	}

	if (!c->mode) {
		fprintf(stderr, "failed to find mode \"%s\"\n", c->mode_str);
		return;
	}

	/* Now get the encoder */
	for (i = 0; i < resources->count_encoders; i++) {
		c->encoder = drmModeGetEncoder(fd, resources->encoders[i]);

		if (!c->encoder) {
			fprintf(stderr, "could not get encoder %i: %s\n",
				resources->encoders[i], strerror(errno));
			drmModeFreeEncoder(c->encoder);
			continue;
		}

		if (c->encoder->encoder_id  == connector->encoder_id)
			break;

		drmModeFreeEncoder(c->encoder);
	}

	if (c->crtc == -1)
		c->crtc = c->encoder->crtc_id;
}

static int drm_set_crtc(struct exynos_device *dev, struct connector *c,
			unsigned int fb_id)
{
	int ret;

	ret = drmModeSetCrtc(dev->fd, c->crtc,
			fb_id, 0, 0, &c->id, 1, c->mode);
	if (ret)
		drmMsg("failed to set mode: %s\n", strerror(errno));

	return ret;
}

static struct exynos_bo *exynos_create_buffer(struct exynos_device *dev,
						unsigned long size,
						unsigned int flags)
{
	struct exynos_bo *bo;

	bo = exynos_bo_create(dev, size, flags);
	if (!bo)
		return bo;

	if (!exynos_bo_map(bo)) {
		exynos_bo_destroy(bo);
		return NULL;
	}

	return bo;
}

/* Allocate buffer and fill it with checkerboard pattern, where the tiles *
 * have a random color. The caller has to free the buffer.                */
static void *create_checkerboard_pattern(unsigned int num_tiles_x,
						unsigned int num_tiles_y, unsigned int tile_size)
{
	unsigned int *buf;
	unsigned int x, y, i, j;
	const unsigned int stride = num_tiles_x * tile_size;

	if (posix_memalign((void*)&buf, 64, num_tiles_y * tile_size * stride * 4) != 0)
		return NULL;

	for (x = 0; x < num_tiles_x; ++x) {
		for (y = 0; y < num_tiles_y; ++y) {
			const unsigned int color = 0xff000000 + (random() & 0xffffff);

			for (i = 0; i < tile_size; ++i) {
				for (j = 0; j < tile_size; ++j) {
					buf[x * tile_size + y * stride * tile_size + i + j * stride] = color;
				}
			}
		}
	}

	return buf;
}

static void exynos_destroy_buffer(struct exynos_bo *bo)
{
	exynos_bo_destroy(bo);
}

static void wait_for_user_input(int last)
{
	printf("press <ENTER> to %s\n", last ? "exit test application" :
			"skip to next test");

	getchar();
}

static int g2d_solid_fill_test(struct exynos_device *dev, struct exynos_bo *dst)
{
	struct g2d_context *ctx;
	struct g2d_image img = {0};
	unsigned int count, img_w, img_h;
	int ret = 0;

	ctx = g2d_init(dev->fd);
	if (!ctx)
		return -EFAULT;

	img.bo[0] = dst->handle;

	printf("solid fill test.\n");

	srand(time(NULL));
	img_w = screen_width;
	img_h = screen_height;

	for (count = 0; count < 2; count++) {
		unsigned int x, y, w, h;

		x = rand() % (img_w / 2);
		y = rand() % (img_h / 2);
		w = rand() % (img_w - x);
		h = rand() % (img_h - y);

		img.width = img_w;
		img.height = img_h;
		img.stride = img.width * 4;
		img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
		img.color = 0xff000000 + (random() & 0xffffff);

		ret = g2d_solid_fill(ctx, &img, x, y, w, h);
		if (ret < 0)
			goto err_fini;

		ret = g2d_exec(ctx);
		if (ret < 0)
			break;
	}

err_fini:
	g2d_fini(ctx);

	return ret;
}

static int g2d_copy_test(struct exynos_device *dev, struct exynos_bo *src,
				struct exynos_bo *dst,
				enum e_g2d_buf_type type)
{
	struct g2d_context *ctx;
	struct g2d_image src_img = {0}, dst_img = {0};
	unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h;
	unsigned long userptr, size;
	int ret;

	ctx = g2d_init(dev->fd);
	if (!ctx)
		return -EFAULT;

	dst_img.bo[0] = dst->handle;

	src_x = 0;
	src_y = 0;
	dst_x = 0;
	dst_y = 0;
	img_w = screen_width;
	img_h = screen_height;

	switch (type) {
	case G2D_IMGBUF_GEM:
		src_img.bo[0] = src->handle;
		break;
	case G2D_IMGBUF_USERPTR:
		size = img_w * img_h * 4;

		userptr = (unsigned long)malloc(size);
		if (!userptr) {
			fprintf(stderr, "failed to allocate userptr.\n");
			return -EFAULT;
		}

		src_img.user_ptr[0].userptr = userptr;
		src_img.user_ptr[0].size = size;
		break;
	case G2D_IMGBUF_COLOR:
	default:
		ret = -EFAULT;
		goto fail;
	}

	printf("copy test with %s.\n",
			type == G2D_IMGBUF_GEM ? "gem" : "userptr");

	src_img.width = img_w;
	src_img.height = img_h;
	src_img.stride = src_img.width * 4;
	src_img.buf_type = type;
	src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
	src_img.color = 0xffff0000;
	ret = g2d_solid_fill(ctx, &src_img, src_x, src_y, img_w, img_h);
	if (ret < 0)
		goto err_free_userptr;

	dst_img.width = img_w;
	dst_img.height = img_h;
	dst_img.stride = dst_img.width * 4;
	dst_img.buf_type = G2D_IMGBUF_GEM;
	dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;

	ret = g2d_copy(ctx, &src_img, &dst_img, src_x, src_y, dst_x, dst_y,
			img_w - 4, img_h - 4);
	if (ret < 0)
		goto err_free_userptr;

	g2d_exec(ctx);

err_free_userptr:
	if (type == G2D_IMGBUF_USERPTR)
		if (userptr)
			free((void *)userptr);

fail:
	g2d_fini(ctx);

	return ret;
}

static int g2d_move_test(struct exynos_device *dev,
				struct exynos_bo *tmp,
				struct exynos_bo *buf,
				enum e_g2d_buf_type type)
{
	struct g2d_context *ctx;
	struct g2d_image img = {0}, tmp_img = {0};
	unsigned int img_w, img_h, count;
	int cur_x, cur_y;
	void *checkerboard;
	int ret;

	static const struct g2d_step {
		int x, y;
	} steps[] = {
		{ 1,  0}, { 0,  1},
		{-1,  0}, { 0, -1},
		{ 1,  1}, {-1, -1},
		{ 1, -1}, {-1,  1},
		{ 2,  1}, { 1,  2},
		{-2, -1}, {-1, -2},
		{ 2, -1}, { 1, -2},
		{-2,  1}, {-1,  2}
	};
	static const unsigned int num_steps =
		sizeof(steps) / sizeof(struct g2d_step);

	ctx = g2d_init(dev->fd);
	if (!ctx)
		return -EFAULT;

	img.bo[0] = buf->handle;

	/* create pattern of half the screen size */
	checkerboard = create_checkerboard_pattern(screen_width / 64, screen_height / 64, 32);
	if (!checkerboard) {
		ret = -EFAULT;
		goto fail;
	}

	img_w = (screen_width / 64) * 32;
	img_h = (screen_height / 64) * 32;

	switch (type) {
	case G2D_IMGBUF_GEM:
		memcpy(tmp->vaddr, checkerboard, img_w * img_h * 4);
		tmp_img.bo[0] = tmp->handle;
		break;
	case G2D_IMGBUF_USERPTR:
		tmp_img.user_ptr[0].userptr = (unsigned long)checkerboard;
		tmp_img.user_ptr[0].size = img_w * img_h * 4;
		break;
	case G2D_IMGBUF_COLOR:
	default:
		ret = -EFAULT;
		goto fail;
	}

	/* solid fill framebuffer with white color */
	img.width = screen_width;
	img.height = screen_height;
	img.stride = screen_width * 4;
	img.buf_type = G2D_IMGBUF_GEM;
	img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
	img.color = 0xffffffff;

	/* put checkerboard pattern in the center of the framebuffer */
	cur_x = (screen_width - img_w) / 2;
	cur_y = (screen_height - img_h) / 2;
	tmp_img.width = img_w;
	tmp_img.height = img_h;
	tmp_img.stride = img_w * 4;
	tmp_img.buf_type = type;
	tmp_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;

	ret = g2d_solid_fill(ctx, &img, 0, 0, screen_width, screen_height) ||
		g2d_copy(ctx, &tmp_img, &img, 0, 0, cur_x, cur_y, img_w, img_h);

	if (!ret)
		ret = g2d_exec(ctx);
	if (ret < 0)
			goto fail;

	printf("move test with %s.\n",
			type == G2D_IMGBUF_GEM ? "gem" : "userptr");

	srand(time(NULL));
	for (count = 0; count < 256; ++count) {
		const struct g2d_step *s;

		/* select step and validate it */
		while (1) {
			s = &steps[random() % num_steps];

			if (cur_x + s->x < 0 || cur_y + s->y < 0 ||
				cur_x + img_w + s->x >= screen_width ||
				cur_y + img_h + s->y >= screen_height)
				continue;
			else
				break;
		}

		ret = g2d_move(ctx, &img, cur_x, cur_y, cur_x + s->x, cur_y + s->y,
			img_w, img_h);
		if (!ret)
			ret = g2d_exec(ctx);

		if (ret < 0)
			goto fail;

		cur_x += s->x;
		cur_y += s->y;

		usleep(100000);
	}

fail:
	g2d_fini(ctx);

	free(checkerboard);

	return ret;
}

static int g2d_copy_with_scale_test(struct exynos_device *dev,
					struct exynos_bo *src,
					struct exynos_bo *dst,
					enum e_g2d_buf_type type)
{
	struct g2d_context *ctx;
	struct g2d_image src_img = {0}, dst_img = {0};
	unsigned int src_x, src_y, img_w, img_h;
	unsigned long userptr, size;
	int ret;

	ctx = g2d_init(dev->fd);
	if (!ctx)
		return -EFAULT;

	dst_img.bo[0] = dst->handle;

	src_x = 0;
	src_y = 0;
	img_w = screen_width;
	img_h = screen_height;

	switch (type) {
	case G2D_IMGBUF_GEM:
		src_img.bo[0] = src->handle;
		break;
	case G2D_IMGBUF_USERPTR:
		size = img_w * img_h * 4;

		userptr = (unsigned long)malloc(size);
		if (!userptr) {
			fprintf(stderr, "failed to allocate userptr.\n");
			return -EFAULT;
		}

		src_img.user_ptr[0].userptr = userptr;
		src_img.user_ptr[0].size = size;
		break;
	case G2D_IMGBUF_COLOR:
	default:
		ret = -EFAULT;
		goto fail;
	}

	printf("copy and scale test with %s.\n",
			type == G2D_IMGBUF_GEM ? "gem" : "userptr");

	src_img.width = img_w;
	src_img.height = img_h;
	src_img.stride = src_img.width * 4;
	src_img.buf_type = type;
	src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
	src_img.color = 0xffffffff;
	ret = g2d_solid_fill(ctx, &src_img, src_x, src_y, img_w ,  img_h);
	if (ret < 0)
		goto err_free_userptr;

	src_img.color = 0xff00ff00;
	ret = g2d_solid_fill(ctx, &src_img, 5, 5, 100, 100);
	if (ret < 0)
		goto err_free_userptr;

	dst_img.width = img_w;
	dst_img.height = img_h;
	dst_img.buf_type = G2D_IMGBUF_GEM;
	dst_img.stride = dst_img.width * 4;
	dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;

	ret = g2d_copy_with_scale(ctx, &src_img, &dst_img, 5, 5, 100, 100,
					100, 100, 200, 200, 0);
	if (ret < 0)
		goto err_free_userptr;

	g2d_exec(ctx);

err_free_userptr:
	if (type == G2D_IMGBUF_USERPTR)
		if (userptr)
			free((void *)userptr);

fail:
	g2d_fini(ctx);

	return 0;
}

static int g2d_blend_test(struct exynos_device *dev,
					struct exynos_bo *src,
					struct exynos_bo *dst,
					enum e_g2d_buf_type type)
{
	struct g2d_context *ctx;
	struct g2d_image src_img = {0}, dst_img = {0};
	unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h;
	unsigned long userptr, size;
	int ret;

	ctx = g2d_init(dev->fd);
	if (!ctx)
		return -EFAULT;

	dst_img.bo[0] = dst->handle;

	src_x = 0;
	src_y = 0;
	dst_x = 0;
	dst_y = 0;
	img_w = screen_width;
	img_h = screen_height;

	switch (type) {
	case G2D_IMGBUF_GEM:
		src_img.bo[0] = src->handle;
		break;
	case G2D_IMGBUF_USERPTR:
		size = img_w * img_h * 4;

		userptr = (unsigned long)malloc(size);
		if (!userptr) {
			fprintf(stderr, "failed to allocate userptr.\n");
			return -EFAULT;
		}

		src_img.user_ptr[0].userptr = userptr;
		src_img.user_ptr[0].size = size;
		break;
	case G2D_IMGBUF_COLOR:
	default:
		ret = -EFAULT;
		goto fail;
	}

	printf("blend test with %s.\n",
			type == G2D_IMGBUF_GEM ? "gem" : "userptr");

	src_img.width = img_w;
	src_img.height = img_h;
	src_img.stride = src_img.width * 4;
	src_img.buf_type = type;
	src_img.select_mode = G2D_SELECT_MODE_NORMAL;
	src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
	src_img.color = 0xffffffff;
	ret = g2d_solid_fill(ctx, &src_img, src_x, src_y, img_w, img_h);
	if (ret < 0)
		goto err_free_userptr;

	src_img.color = 0x770000ff;
	ret = g2d_solid_fill(ctx, &src_img, 5, 5, 200, 200);
	if (ret < 0)
		goto err_free_userptr;

	dst_img.width = img_w;
	dst_img.height = img_h;
	dst_img.stride = dst_img.width * 4;
	dst_img.buf_type = G2D_IMGBUF_GEM;
	dst_img.select_mode = G2D_SELECT_MODE_NORMAL;
	dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
	dst_img.color = 0xffffffff;
	ret = g2d_solid_fill(ctx, &dst_img, dst_x, dst_y, img_w, img_h);
	if (ret < 0)
		goto err_free_userptr;

	dst_img.color = 0x77ff0000;
	ret = g2d_solid_fill(ctx, &dst_img, 105, 105, 200, 200);
	if (ret < 0)
		goto err_free_userptr;

	ret = g2d_blend(ctx, &src_img, &dst_img, 5, 5, 105, 105, 200, 200,
			G2D_OP_OVER);
	if (ret < 0)
		goto err_free_userptr;

	g2d_exec(ctx);

err_free_userptr:
	if (type == G2D_IMGBUF_USERPTR)
		if (userptr)
			free((void *)userptr);

fail:
	g2d_fini(ctx);

	return 0;
}

static int g2d_checkerboard_test(struct exynos_device *dev,
					struct exynos_bo *src,
					struct exynos_bo *dst,
					enum e_g2d_buf_type type)
{
	struct g2d_context *ctx;
	struct g2d_image src_img = {0}, dst_img = {0};
	unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h;
	void *checkerboard = NULL;
	int ret;

	ctx = g2d_init(dev->fd);
	if (!ctx)
		return -EFAULT;

	dst_img.bo[0] = dst->handle;

	src_x = 0;
	src_y = 0;
	dst_x = 0;
	dst_y = 0;

	checkerboard = create_checkerboard_pattern(screen_width / 32, screen_height / 32, 32);
	if (checkerboard == NULL) {
		ret = -1;
		goto fail;
	}

	img_w = screen_width - (screen_width % 32);
	img_h = screen_height - (screen_height % 32);

	switch (type) {
	case G2D_IMGBUF_GEM:
		memcpy(src->vaddr, checkerboard, img_w * img_h * 4);
		src_img.bo[0] = src->handle;
		break;
	case G2D_IMGBUF_USERPTR:
		src_img.user_ptr[0].userptr = (unsigned long)checkerboard;
		src_img.user_ptr[0].size = img_w * img_h * 4;
		break;
	case G2D_IMGBUF_COLOR:
	default:
		ret = -EFAULT;
		goto fail;
	}

	printf("checkerboard test with %s.\n",
			type == G2D_IMGBUF_GEM ? "gem" : "userptr");

	src_img.width = img_w;
	src_img.height = img_h;
	src_img.stride = src_img.width * 4;
	src_img.buf_type = type;
	src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;

	dst_img.width = screen_width;
	dst_img.height = screen_height;
	dst_img.stride = dst_img.width * 4;
	dst_img.buf_type = G2D_IMGBUF_GEM;
	dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
	src_img.color = 0xff000000;
	ret = g2d_solid_fill(ctx, &dst_img, src_x, src_y, screen_width, screen_height);
	if (ret < 0)
		goto fail;

	ret = g2d_copy(ctx, &src_img, &dst_img, src_x, src_y, dst_x, dst_y,
			img_w, img_h);
	if (ret < 0)
		goto fail;

	g2d_exec(ctx);

fail:
	free(checkerboard);
	g2d_fini(ctx);

	return ret;
}

static void usage(char *name)
{
	fprintf(stderr, "usage: %s [-s]\n", name);
	fprintf(stderr, "-s <connector_id>@<crtc_id>:<mode>\n");
	exit(0);
}

extern char *optarg;
static const char optstr[] = "s:";

int main(int argc, char **argv)
{
	struct exynos_device *dev;
	struct exynos_bo *bo, *src;
	struct connector con;
	unsigned int fb_id;
	uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
	drmModeRes *resources;
	int ret, fd, c;

	memset(&con, 0, sizeof(struct connector));

	if (argc != 3) {
		usage(argv[0]);
		return -EINVAL;
	}

	while ((c = getopt(argc, argv, optstr)) != -1) {
		switch (c) {
		case 's':
			con.crtc = -1;
			if (sscanf(optarg, "%d:0x%64s",
						&con.id,
						con.mode_str) != 2 &&
					sscanf(optarg, "%d@%d:%64s",
						&con.id,
						&con.crtc,
						con.mode_str) != 3)
				usage(argv[0]);
			break;
		default:
			usage(argv[0]);
			break;
		}
	}

	fd = drmOpen(DRM_MODULE_NAME, NULL);
	if (fd < 0) {
		fprintf(stderr, "failed to open.\n");
		return fd;
	}

	dev = exynos_device_create(fd);
	if (!dev) {
		drmClose(dev->fd);
		return -EFAULT;
	}

	resources = drmModeGetResources(dev->fd);
	if (!resources) {
		fprintf(stderr, "drmModeGetResources failed: %s\n",
				strerror(errno));
		ret = -EFAULT;
		goto err_drm_close;
	}

	connector_find_mode(dev->fd, &con, resources);
	drmModeFreeResources(resources);

	if (!con.mode) {
		fprintf(stderr, "failed to find usable connector\n");
		ret = -EFAULT;
		goto err_drm_close;
	}

	screen_width = con.mode->hdisplay;
	screen_height = con.mode->vdisplay;

	if (screen_width == 0 || screen_height == 0) {
		fprintf(stderr, "failed to find sane resolution on connector\n");
		ret = -EFAULT;
		goto err_drm_close;
	}

	printf("screen width = %d, screen height = %d\n", screen_width,
			screen_height);

	bo = exynos_create_buffer(dev, screen_width * screen_height * 4, 0);
	if (!bo) {
		ret = -EFAULT;
		goto err_drm_close;
	}

	handles[0] = bo->handle;
	pitches[0] = screen_width * 4;
	offsets[0] = 0;

	ret = drmModeAddFB2(dev->fd, screen_width, screen_height,
				DRM_FORMAT_XRGB8888, handles,
				pitches, offsets, &fb_id, 0);
	if (ret < 0)
		goto err_destroy_buffer;

	memset(bo->vaddr, 0xff, screen_width * screen_height * 4);

	ret = drm_set_crtc(dev, &con, fb_id);
	if (ret < 0)
		goto err_rm_fb;

	ret = g2d_solid_fill_test(dev, bo);
	if (ret < 0) {
		fprintf(stderr, "failed to solid fill operation.\n");
		goto err_rm_fb;
	}

	wait_for_user_input(0);

	src = exynos_create_buffer(dev, screen_width * screen_height * 4, 0);
	if (!src) {
		ret = -EFAULT;
		goto err_rm_fb;
	}

	ret = g2d_copy_test(dev, src, bo, G2D_IMGBUF_GEM);
	if (ret < 0) {
		fprintf(stderr, "failed to test copy operation.\n");
		goto err_free_src;
	}

	wait_for_user_input(0);

	ret = g2d_move_test(dev, src, bo, G2D_IMGBUF_GEM);
	if (ret < 0) {
		fprintf(stderr, "failed to test move operation.\n");
		goto err_free_src;
	}

	wait_for_user_input(0);

	ret = g2d_copy_with_scale_test(dev, src, bo, G2D_IMGBUF_GEM);
	if (ret < 0) {
		fprintf(stderr, "failed to test copy and scale operation.\n");
		goto err_free_src;
	}

	wait_for_user_input(0);

	ret = g2d_checkerboard_test(dev, src, bo, G2D_IMGBUF_GEM);
	if (ret < 0) {
		fprintf(stderr, "failed to issue checkerboard test.\n");
		goto err_free_src;
	}

	wait_for_user_input(1);

	/*
	 * The blend test uses the userptr functionality of exynos-drm, which
	 * is currently not safe to use. If the kernel hasn't been build with
	 * exynos-iommu support, then the blend test is going to produce (kernel)
	 * memory corruption, eventually leading to a system crash.
	 *
	 * Disable the test for now, until the kernel code has been sanitized.
	 */
#if 0
	ret  = g2d_blend_test(dev, src, bo, G2D_IMGBUF_USERPTR);
	if (ret < 0)
		fprintf(stderr, "failed to test blend operation.\n");

	getchar();
#endif

err_free_src:
	if (src)
		exynos_destroy_buffer(src);

err_rm_fb:
	drmModeRmFB(dev->fd, fb_id);

err_destroy_buffer:
	exynos_destroy_buffer(bo);

err_drm_close:
	drmClose(dev->fd);
	exynos_device_destroy(dev);

	return 0;
}
