/*
 * Copyright © 2016 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 */

#include "igt.h"
#include "drmtest.h"
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

IGT_TEST_DESCRIPTION("Test atomic mode setting with multiple planes ");

#define MAX_CRCS          2
#define SIZE_PLANE      256
#define SIZE_CURSOR     128
#define LOOP_FOREVER     -1

typedef struct {
	float red;
	float green;
	float blue;
} color_t;

typedef struct {
	int drm_fd;
	igt_display_t display;
	igt_pipe_crc_t *pipe_crc;
	igt_plane_t **plane;
	struct igt_fb *fb;
} data_t;

/* Command line parameters. */
struct {
	int iterations;
	bool user_seed;
	int seed;
} opt = {
	.iterations = 1,
	.user_seed = false,
	.seed = 1,
};

/*
 * Common code across all tests, acting on data_t
 */
static void test_init(data_t *data, enum pipe pipe, int n_planes)
{
	data->pipe_crc = igt_pipe_crc_new(data->drm_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);

	data->plane = calloc(n_planes, sizeof(data->plane));
	igt_assert_f(data->plane != NULL, "Failed to allocate memory for planes\n");

	data->fb = calloc(n_planes, sizeof(struct igt_fb));
	igt_assert_f(data->fb != NULL, "Failed to allocate memory for FBs\n");
}

static void test_fini(data_t *data, igt_output_t *output, int n_planes)
{
	for (int i = 0; i < n_planes; i++) {
		igt_plane_t *plane = data->plane[i];
		if (!plane)
			continue;
		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
			continue;
		igt_plane_set_fb(plane, NULL);
		data->plane[i] = NULL;
	}

	/* reset the constraint on the pipe */
	igt_output_set_pipe(output, PIPE_ANY);

	igt_pipe_crc_free(data->pipe_crc);

	free(data->plane);
	data->plane = NULL;
	free(data->fb);
	data->fb = NULL;
}

static void
test_grab_crc(data_t *data, igt_output_t *output, enum pipe pipe, bool atomic,
	      color_t *color, uint64_t tiling, igt_crc_t **crc /* out */)
{
	drmModeModeInfo *mode;
	igt_plane_t *primary;
	int ret, n;

	igt_output_set_pipe(output, pipe);

	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
	data->plane[primary->index] = primary;

	mode = igt_output_get_mode(output);

	igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
			    DRM_FORMAT_XRGB8888,
			    LOCAL_DRM_FORMAT_MOD_NONE,
			    color->red, color->green, color->blue,
			    &data->fb[primary->index]);

	igt_plane_set_fb(data->plane[primary->index], &data->fb[primary->index]);

	ret = igt_display_try_commit2(&data->display,
				      atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
	igt_skip_on(ret != 0);

	igt_pipe_crc_start(data->pipe_crc);
	n = igt_pipe_crc_get_crcs(data->pipe_crc, 1, crc);
	igt_assert_eq(n, 1);
}

/*
 * Multiple plane position test.
 *   - We start by grabbing a reference CRC of a full blue fb being scanned
 *     out on the primary plane
 *   - Then we scannout number of planes:
 *      * the primary plane uses a blue fb with a black rectangle hole
 *      * planes, on top of the primary plane, with a blue fb that is set-up
 *        to cover the black rectangles of the primary plane fb
 *     The resulting CRC should be identical to the reference CRC
 */

static void
create_fb_for_mode_position(data_t *data, igt_output_t *output, drmModeModeInfo *mode,
			    color_t *color, int *rect_x, int *rect_y,
			    int *rect_w, int *rect_h, uint64_t tiling,
			    int max_planes)
{
	unsigned int fb_id;
	cairo_t *cr;
	igt_plane_t *primary;

	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);

	fb_id = igt_create_fb(data->drm_fd,
			      mode->hdisplay, mode->vdisplay,
			      DRM_FORMAT_XRGB8888,
			      tiling,
			      &data->fb[primary->index]);
	igt_assert(fb_id);

	cr = igt_get_cairo_ctx(data->drm_fd, &data->fb[primary->index]);
	igt_paint_color(cr, rect_x[0], rect_y[0],
			mode->hdisplay, mode->vdisplay,
			color->red, color->green, color->blue);

	for (int i = 0; i < max_planes; i++) {
		if (data->plane[i]->type == DRM_PLANE_TYPE_PRIMARY)
			continue;
		igt_paint_color(cr, rect_x[i], rect_y[i],
				rect_w[i], rect_h[i], 0.0, 0.0, 0.0);
		}

	igt_put_cairo_ctx(data->drm_fd, &data->fb[primary->index], cr);
}


static void
prepare_planes(data_t *data, enum pipe pipe_id, color_t *color,
	       uint64_t tiling, int max_planes, igt_output_t *output)
{
	drmModeModeInfo *mode;
	igt_pipe_t *pipe;
	igt_plane_t *primary;
	int *x;
	int *y;
	int *size;
	int i;

	igt_output_set_pipe(output, pipe_id);
	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
	pipe = primary->pipe;

	x = malloc(pipe->n_planes * sizeof(*x));
	igt_assert_f(x, "Failed to allocate %ld bytes for variable x\n", (long int) (pipe->n_planes * sizeof(*x)));
	y = malloc(pipe->n_planes * sizeof(*y));
	igt_assert_f(y, "Failed to allocate %ld bytes for variable y\n", (long int) (pipe->n_planes * sizeof(*y)));
	size = malloc(pipe->n_planes * sizeof(*size));
	igt_assert_f(size, "Failed to allocate %ld bytes for variable size\n", (long int) (pipe->n_planes * sizeof(*size)));

	mode = igt_output_get_mode(output);

	/* planes with random positions */
	x[primary->index] = 0;
	y[primary->index] = 0;
	for (i = 0; i < max_planes; i++) {
		igt_plane_t *plane = igt_output_get_plane(output, i);

		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
			continue;
		else if (plane->type == DRM_PLANE_TYPE_CURSOR)
			size[i] = SIZE_CURSOR;
		else
			size[i] = SIZE_PLANE;

		x[i] = rand() % (mode->hdisplay - size[i]);
		y[i] = rand() % (mode->vdisplay - size[i]);

		data->plane[i] = plane;

		igt_create_color_fb(data->drm_fd,
				    size[i], size[i],
				    data->plane[i]->type == DRM_PLANE_TYPE_CURSOR ? DRM_FORMAT_ARGB8888 : DRM_FORMAT_XRGB8888,
				    data->plane[i]->type == DRM_PLANE_TYPE_CURSOR ? LOCAL_DRM_FORMAT_MOD_NONE : tiling,
				    color->red, color->green, color->blue,
				    &data->fb[i]);

		igt_plane_set_position(data->plane[i], x[i], y[i]);
		igt_plane_set_fb(data->plane[i], &data->fb[i]);
	}

	/* primary plane */
	data->plane[primary->index] = primary;
	create_fb_for_mode_position(data, output, mode, color, x, y,
				    size, size, tiling, max_planes);
	igt_plane_set_fb(data->plane[primary->index], &data->fb[primary->index]);
}

static void
test_atomic_plane_position_with_output(data_t *data, enum pipe pipe,
				       igt_output_t *output, int n_planes,
				       uint64_t tiling)
{
	char buf[256];
	struct drm_event *e = (void *)buf;
	color_t blue  = { 0.0f, 0.0f, 1.0f };
	igt_crc_t *ref = NULL;
	igt_crc_t *crc = NULL;
	unsigned int vblank_start, vblank_stop;
	int i, n, ret;
	int iterations = opt.iterations < 1 ? 1 : opt.iterations;
	bool loop_forever;
	char info[256];

	if (opt.iterations == LOOP_FOREVER) {
		loop_forever = true;
		sprintf(info, "forever");
	} else {
		loop_forever = false;
		sprintf(info, "for %d %s",
			iterations, iterations > 1 ? "iterations" : "iteration");
	}

	igt_info("Testing connector %s using pipe %s with %d planes %s with seed %d\n",
		 igt_output_name(output), kmstest_pipe_name(pipe), n_planes,
		 info, opt.seed);

	test_init(data, pipe, n_planes);

	test_grab_crc(data, output, pipe, true, &blue, tiling, &ref);

	i = 0;
	while (i < iterations || loop_forever) {
		prepare_planes(data, pipe, &blue, tiling, n_planes, output);

		vblank_start = kmstest_get_vblank(data->display.drm_fd, pipe,
						  DRM_VBLANK_NEXTONMISS);

		igt_display_commit_atomic(&data->display,
					  DRM_MODE_PAGE_FLIP_EVENT,
					  &data->display);

		igt_set_timeout(1, "Stuck on page flip");

		ret = read(data->display.drm_fd, buf, sizeof(buf));
		igt_assert(ret >= 0);

		vblank_stop = kmstest_get_vblank(data->display.drm_fd, pipe, 0);
		igt_assert_eq(e->type, DRM_EVENT_FLIP_COMPLETE);
		igt_reset_timeout();

		n = igt_pipe_crc_get_crcs(data->pipe_crc, vblank_stop - vblank_start, &crc);

		igt_assert(vblank_stop - vblank_start <= MAX_CRCS);
		igt_assert_eq(n, vblank_stop - vblank_start);

		igt_assert_crc_equal(ref, crc);

		i++;
	}

	igt_pipe_crc_stop(data->pipe_crc);

	test_fini(data, output, n_planes);
}

static void
test_legacy_plane_position_with_output(data_t *data, enum pipe pipe,
				       igt_output_t *output, int n_planes,
				       uint64_t tiling)
{
	color_t blue  = { 0.0f, 0.0f, 1.0f };
	igt_crc_t *ref = NULL;
	igt_crc_t *crc = NULL;
	int i, n;
	int iterations = opt.iterations < 1 ? 1 : opt.iterations;
	bool loop_forever;
	char info[256];

	if (opt.iterations == LOOP_FOREVER) {
		loop_forever = true;
		sprintf(info, "forever");
	} else {
		loop_forever = false;
		sprintf(info, "for %d %s",
			iterations, iterations > 1 ? "iterations" : "iteration");
	}

	igt_info("Testing connector %s using pipe %s with %d planes %s with seed %d\n",
		 igt_output_name(output), kmstest_pipe_name(pipe), n_planes,
		 info, opt.seed);

	test_init(data, pipe, n_planes);

	test_grab_crc(data, output, pipe, false, &blue, tiling, &ref);

	i = 0;
	while (i < iterations || loop_forever) {
		prepare_planes(data, pipe, &blue, tiling, n_planes, output);

		igt_display_commit2(&data->display, COMMIT_LEGACY);

		n = igt_pipe_crc_get_crcs(data->pipe_crc, MAX_CRCS, &crc);

		igt_assert_eq(n, MAX_CRCS);

		igt_assert_crc_equal(ref, crc);

		i++;
	}

	igt_pipe_crc_stop(data->pipe_crc);

	test_fini(data, output, n_planes);
}

static void
test_plane_position(data_t *data, enum pipe pipe, bool atomic, uint64_t tiling)
{
	igt_output_t *output;
	int connected_outs;
	int devid = intel_get_drm_devid(data->drm_fd);
	int n_planes = data->display.pipes[pipe].n_planes;

	if (atomic)
		igt_require(data->display.is_atomic);

	if ((tiling == LOCAL_I915_FORMAT_MOD_Y_TILED ||
	     tiling == LOCAL_I915_FORMAT_MOD_Yf_TILED))
		igt_require(AT_LEAST_GEN(devid, 9));

	if (!opt.user_seed)
		opt.seed = time(NULL);

	srand(opt.seed);

	connected_outs = 0;
	for_each_valid_output_on_pipe(&data->display, pipe, output) {
		if (atomic)
			test_atomic_plane_position_with_output(data, pipe,
							       output,
							       n_planes,
							       tiling);
		else
			test_legacy_plane_position_with_output(data, pipe,
							       output,
							       n_planes,
							       tiling);

		connected_outs++;
	}

	igt_skip_on(connected_outs == 0);

}

static void
run_tests_for_pipe(data_t *data, enum pipe pipe)
{
	igt_output_t *output;

	igt_fixture {
		int valid_tests = 0;

		igt_skip_on(pipe >= data->display.n_pipes);

		for_each_valid_output_on_pipe(&data->display, pipe, output)
			valid_tests++;

		igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
		igt_require(data->display.pipes[pipe].n_planes > 0);
	}


	igt_subtest_f("legacy-pipe-%s-tiling-none",
		      kmstest_pipe_name(pipe))
		for_each_valid_output_on_pipe(&data->display, pipe, output)
			test_plane_position(data, pipe, false, LOCAL_DRM_FORMAT_MOD_NONE);

	igt_subtest_f("atomic-pipe-%s-tiling-none",
		      kmstest_pipe_name(pipe))
		for_each_valid_output_on_pipe(&data->display, pipe, output)
			test_plane_position(data, pipe, true, LOCAL_I915_FORMAT_MOD_X_TILED);

	igt_subtest_f("legacy-pipe-%s-tiling-x",
		      kmstest_pipe_name(pipe))
		for_each_valid_output_on_pipe(&data->display, pipe, output)
			test_plane_position(data, pipe, false, LOCAL_I915_FORMAT_MOD_X_TILED);

	igt_subtest_f("atomic-pipe-%s-tiling-x",
		      kmstest_pipe_name(pipe))
		for_each_valid_output_on_pipe(&data->display, pipe, output)
			test_plane_position(data, pipe, true, LOCAL_I915_FORMAT_MOD_X_TILED);

	igt_subtest_f("legacy-pipe-%s-tiling-y",
		      kmstest_pipe_name(pipe))
		for_each_valid_output_on_pipe(&data->display, pipe, output)
			test_plane_position(data, pipe, false, LOCAL_I915_FORMAT_MOD_Y_TILED);

	igt_subtest_f("atomic-pipe-%s-tiling-y",
		      kmstest_pipe_name(pipe))
		for_each_valid_output_on_pipe(&data->display, pipe, output)
			test_plane_position(data, pipe, true, LOCAL_I915_FORMAT_MOD_Y_TILED);

	igt_subtest_f("legacy-pipe-%s-tiling-yf",
		      kmstest_pipe_name(pipe))
		for_each_valid_output_on_pipe(&data->display, pipe, output)
			test_plane_position(data, pipe, false, LOCAL_I915_FORMAT_MOD_Yf_TILED);

	igt_subtest_f("atomic-pipe-%s-tiling-yf",
		      kmstest_pipe_name(pipe))
		for_each_valid_output_on_pipe(&data->display, pipe, output)
			test_plane_position(data, pipe, true, LOCAL_I915_FORMAT_MOD_Yf_TILED);
}

static data_t data;

static int opt_handler(int option, int option_index, void *input)
{
	switch (option) {
	case 'i':
		opt.iterations = strtol(optarg, NULL, 0);

		if (opt.iterations < LOOP_FOREVER || opt.iterations == 0) {
			igt_info("incorrect number of iterations\n");
			igt_assert(false);
		}

		break;
	case 's':
		opt.user_seed = true;
		opt.seed = strtol(optarg, NULL, 0);
		break;
	default:
		igt_assert(false);
	}

	return 0;
}

const char *help_str =
	"  --iterations Number of iterations for test coverage. -1 loop forever, default 64 iterations\n"
	"  --seed       Seed for random number generator\n";

int main(int argc, char *argv[])
{
	struct option long_options[] = {
		{ "iterations", required_argument, NULL, 'i'},
		{ "seed",    required_argument, NULL, 's'},
		{ 0, 0, 0, 0 }
	};
	enum pipe pipe;

	igt_subtest_init_parse_opts(&argc, argv, "", long_options, help_str,
				    opt_handler, NULL);

	igt_skip_on_simulation();

	igt_fixture {
		data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
		kmstest_set_vt_graphics_mode();
		igt_require_pipe_crc(data.drm_fd);
		igt_display_init(&data.display, data.drm_fd);
		igt_require(data.display.n_pipes > 0);
	}

	for_each_pipe_static(pipe) {
		igt_subtest_group
			run_tests_for_pipe(&data, pipe);
	}

	igt_fixture {
		igt_display_fini(&data.display);
	}

	igt_exit();
}
