/*
 * Copyright 2015 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "bs_drm.h"

#include <getopt.h>
#include <math.h>

#define TABLE_LINEAR 0
#define TABLE_NEGATIVE 1
#define TABLE_POW 2
#define TABLE_STEP 3
// TABLE_PIECEWISE_HDR mimics Chrome's PIECEWISE_HDR gfx::ColorSpace::TranferID,
// basically an sRGB up to a given elbow or joint, and linear after.
#define TABLE_PIECEWISE_HDR 4

#define FLAG_INTERNAL 'i'
#define FLAG_EXTERNAL 'e'
#define FLAG_GAMMA 'g'
#define FLAG_LINEAR 'l'
#define FLAG_NEGATIVE 'n'
#define FLAG_TIME 't'
#define FLAG_CRTCS 'c'
#define FLAG_PERSIST 'p'
#define FLAG_STEP 's'
#define FLAG_HDR 'x'
#define FLAG_HELP 'h'

static struct option command_options[] = { { "internal", no_argument, NULL, FLAG_INTERNAL },
					   { "external", no_argument, NULL, FLAG_EXTERNAL },
					   { "gamma", required_argument, NULL, FLAG_GAMMA },
					   { "linear", no_argument, NULL, FLAG_LINEAR },
					   { "negative", no_argument, NULL, FLAG_NEGATIVE },
					   { "time", required_argument, NULL, FLAG_TIME },
					   { "crtcs", required_argument, NULL, FLAG_CRTCS },
					   { "persist", no_argument, NULL, FLAG_PERSIST },
					   { "step", no_argument, NULL, FLAG_STEP },
					   { "hdr", required_argument, NULL, FLAG_HDR },
					   { "help", no_argument, NULL, FLAG_HELP },
					   { NULL, 0, NULL, 0 } };

static void gamma_linear(uint16_t *table, int size)
{
	int i;
	for (i = 0; i < size; i++) {
		float v = (float)(i) / (float)(size - 1);
		v *= 65535.0f;
		table[i] = (uint16_t)v;
	}
}

static void gamma_inv(uint16_t *table, int size)
{
	int i;
	for (i = 0; i < size; i++) {
		float v = (float)(size - 1 - i) / (float)(size - 1);
		v *= 65535.0f;
		table[i] = (uint16_t)v;
	}
}

static void gamma_pow(uint16_t *table, int size, float p)
{
	int i;
	for (i = 0; i < size; i++) {
		float v = (float)(i) / (float)(size - 1);
		v = pow(v, p);
		v *= 65535.0f;
		table[i] = (uint16_t)v;
	}
}

static void gamma_step(uint16_t *table, int size)
{
	int i;
	for (i = 0; i < size; i++) {
		table[i] = (i < size / 2) ? 0 : 65535;
	}
}

static void gamma_piecewise_linear(uint16_t *table, int size, float joint)
{
	const float gamma = 1 / 2.2f;
	// |joint_i| is the index in [0, size) where sRGB and linear curves meet.
	const size_t joint_i = joint * size;
	// |joint_v| is the gamma output value where sRGB and linear curves meet.
	const float joint_v = pow(joint, gamma);
	// |slope| is the slope of the linear part.
	const float slope = (1 - joint_v) / (1 - joint);
	int i;
	for (i = 0; i < size; i++) {
		float v = (float)(i) / (float)(size - 1);

		if (i < joint_i)
			v = pow(v, gamma);
		else
			v = joint_v + slope * (v - joint);

		v *= 65535.0f;
		table[i] = (uint16_t)v;
	}
}

static const char* gamma_name(int gamma_table_id)
{
	const char *table_names[] = { "TABLE_LINEAR", "TABLE_NEGATIVE", "TABLE_POW", "TABLE_STEP",
				      "TABLE_PIECEWISE_HDR" };
	const size_t max_gamma_table_id = sizeof(table_names)/sizeof(table_names[0]);
	if (gamma_table_id >= max_gamma_table_id)
		return NULL;
	return table_names[gamma_table_id];
}

static void fsleep(double secs)
{
	usleep((useconds_t)(1000000.0f * secs));
}

static drmModeModeInfoPtr find_best_mode(int mode_count, drmModeModeInfoPtr modes)
{
	assert(mode_count >= 0);
	if (mode_count == 0)
		return NULL;

	assert(modes);

	for (int m = 0; m < mode_count; m++)
		if (modes[m].type & DRM_MODE_TYPE_PREFERRED)
			return &modes[m];

	return &modes[0];
}

static bool draw_pattern(struct bs_mapper *mapper, struct gbm_bo *bo, int gbm_format)
{
	uint32_t stride;
	const uint32_t height = gbm_bo_get_height(bo);
	const uint32_t stripw = gbm_bo_get_width(bo) / 256;
	const uint32_t striph = height / 4;

	if (gbm_format != GBM_FORMAT_XRGB8888 && gbm_format != GBM_FORMAT_XRGB2101010)
		return false;

	void *map_data;
	uint8_t *bo_ptr = bs_mapper_map(mapper, bo, 0, &map_data, &stride);
	if (bo_ptr == MAP_FAILED) {
		bs_debug_error("failed to mmap buffer while drawing pattern");
		return false;
	}
	const uint32_t bo_size = stride * height;

	bool success = true;

	memset(bo_ptr, 0, bo_size);
	for (uint32_t s = 0; s < 4; s++) {
		uint8_t r = 0, g = 0, b = 0;
		switch (s) {
			case 0:
				r = g = b = 1;
				break;
			case 1:
				r = 1;
				break;
			case 2:
				g = 1;
				break;
			case 3:
				b = 1;
				break;
			default:
				assert("invalid strip" && false);
				success = false;
				goto out;
		}
		for (uint32_t y = s * striph; y < (s + 1) * striph; y++) {
			uint8_t *row_ptr = &bo_ptr[y * stride];
			for (uint32_t i = 0; i < 256; i++) {
				for (uint32_t x = i * stripw; x < (i + 1) * stripw; x++) {
					if (gbm_format == GBM_FORMAT_XRGB8888) {
						row_ptr[x * 4 + 0] = b * i;
						row_ptr[x * 4 + 1] = g * i;
						row_ptr[x * 4 + 2] = r * i;
						row_ptr[x * 4 + 3] = 0;
					} else {
						*(uint32_t *)(&row_ptr[x * 4]) =
						    (((r * i) << 2) | ((r * i) >> 6)) << 20 |
						    (((g * i) << 2) | ((g * i) >> 6)) << 10 |
						    (((b * i) << 2) | ((b * i) >> 6));
					}
				}
			}
		}
	}

out:
	bs_mapper_unmap(mapper, bo, map_data);
	return success;
}

// |parameter| is passed to the appropriate |gamma_table| generation function.
static int set_gamma(int fd, uint32_t crtc_id, int gamma_size, int gamma_table, float parameter)
{
	int res;
	uint16_t *r, *g, *b;
	r = calloc(gamma_size, sizeof(*r));
	g = calloc(gamma_size, sizeof(*g));
	b = calloc(gamma_size, sizeof(*b));

	printf("Setting gamma table index %d (%s)\n", gamma_table, gamma_name(gamma_table));
	switch (gamma_table) {
		case TABLE_LINEAR:
			gamma_linear(r, gamma_size);
			gamma_linear(g, gamma_size);
			gamma_linear(b, gamma_size);
			break;
		case TABLE_NEGATIVE:
			gamma_inv(r, gamma_size);
			gamma_inv(g, gamma_size);
			gamma_inv(b, gamma_size);
			break;
		case TABLE_POW:
			gamma_pow(r, gamma_size, parameter);
			gamma_pow(g, gamma_size, parameter);
			gamma_pow(b, gamma_size, parameter);
			break;
		case TABLE_STEP:
			gamma_step(r, gamma_size);
			gamma_step(g, gamma_size);
			gamma_step(b, gamma_size);
			break;
		case TABLE_PIECEWISE_HDR:
			gamma_piecewise_linear(r, gamma_size, parameter);
			gamma_piecewise_linear(g, gamma_size, parameter);
			gamma_piecewise_linear(b, gamma_size, parameter);
			break;
	}

	res = drmModeCrtcSetGamma(fd, crtc_id, gamma_size, r, g, b);
	if (res)
		bs_debug_error("drmModeCrtcSetGamma(%d) failed: %s", crtc_id, strerror(errno));
	free(r);
	free(g);
	free(b);
	return res;
}

void help(void)
{
	printf(
	    "\
gamma test\n\
command line options:\
\n\
--help - this\n\
--linear - set linear gamma table\n\
--negative - set negative linear gamma table\n\
--step - set step gamma table\n\
--gamma=f - set pow(gamma) gamma table with gamma=f\n\
--time=f - set test time\n\
--crtcs=n - set mask of crtcs to test\n\
--persist - do not reset gamma table at the end of the test\n\
--internal - display tests on internal display\n\
--external - display tests on external display\n\
--hdr=x - sets piecewise HDR gamma table with SDR-HDR joint at x (usually 0.5)\n\
");
}

int main(int argc, char **argv)
{
	int internal = 1;
	int persist = 0;
	float time = 5.0;
	float gamma = 2.2f;
	float srgb_joint = 0.0f;
	int table = TABLE_LINEAR;
	uint32_t crtcs = 0xFFFF;

	for (;;) {
		int c = getopt_long(argc, argv, "", command_options, NULL);

		if (c == -1)
			break;

		switch (c) {
			case FLAG_HELP:
				help();
				return 0;

			case FLAG_INTERNAL:
				internal = 1;
				break;

			case FLAG_EXTERNAL:
				internal = 0;
				break;

			case FLAG_GAMMA:
				gamma = strtof(optarg, NULL);
				table = TABLE_POW;
				break;

			case FLAG_LINEAR:
				table = TABLE_LINEAR;
				break;

			case FLAG_NEGATIVE:
				table = TABLE_NEGATIVE;
				break;

			case FLAG_STEP:
				table = TABLE_STEP;
				break;

			case FLAG_HDR:
				srgb_joint = strtof(optarg, NULL);
				table = TABLE_PIECEWISE_HDR;
				break;

			case FLAG_TIME:
				time = strtof(optarg, NULL);
				break;

			case FLAG_CRTCS:
				crtcs = strtoul(optarg, NULL, 0);
				break;

			case FLAG_PERSIST:
				persist = 1;
				break;
		}
	}

	drmModeConnector *connector = NULL;
	struct bs_drm_pipe pipe = { 0 };
	struct bs_drm_pipe_plumber *plumber = bs_drm_pipe_plumber_new();
	bs_drm_pipe_plumber_connector_ptr(plumber, &connector);
	bs_drm_pipe_plumber_crtc_mask(plumber, crtcs);
	if (!internal)
		bs_drm_pipe_plumber_connector_ranks(plumber, bs_drm_connectors_external_rank);
	if (!bs_drm_pipe_plumber_make(plumber, &pipe)) {
		bs_debug_error("failed to make pipe");
		return 1;
	}

	int fd = pipe.fd;
	bs_drm_pipe_plumber_fd(plumber, fd);
	drmModeRes *resources = drmModeGetResources(fd);
	if (!resources) {
		bs_debug_error("failed to get drm resources");
		return 1;
	}

	struct gbm_device *gbm = gbm_create_device(fd);
	if (!gbm) {
		bs_debug_error("failed to create gbm");
		return 1;
	}

	struct bs_mapper *mapper = bs_mapper_gem_new();
	if (mapper == NULL) {
		bs_debug_error("failed to create mapper object");
		return 1;
	}

	uint32_t num_success = 0;
	for (int c = 0; c < resources->count_crtcs && (crtcs >> c); c++) {
		int ret;
		drmModeCrtc *crtc;
		uint32_t crtc_mask = 1u << c;

		if (!(crtcs & crtc_mask))
			continue;

		if (c > 0)
			printf("\n");

		if (connector != NULL) {
			drmModeFreeConnector(connector);
			connector = NULL;
		}

		bs_drm_pipe_plumber_crtc_mask(plumber, crtc_mask);
		if (!bs_drm_pipe_plumber_make(plumber, &pipe)) {
			printf("unable to make pipe with crtc mask: %x\n", crtc_mask);
			continue;
		}

		crtc = drmModeGetCrtc(fd, pipe.crtc_id);
		if (!crtc) {
			bs_debug_error("drmModeGetCrtc(%d) failed: %s\n", pipe.crtc_id,
				       strerror(errno));
			return 1;
		}
		int gamma_size = crtc->gamma_size;
		drmModeFreeCrtc(crtc);

		if (!gamma_size) {
			bs_debug_error("CRTC %d has no gamma table", crtc->crtc_id);
			continue;
		}

		printf("CRTC:%d gamma table size:%d\n", pipe.crtc_id, gamma_size);

		printf("Using CRTC:%u ENCODER:%u CONNECTOR:%u\n", pipe.crtc_id, pipe.encoder_id,
		       pipe.connector_id);

		drmModeModeInfoPtr mode = find_best_mode(connector->count_modes, connector->modes);
		if (!mode) {
			bs_debug_error("Could not find mode for CRTC %d", pipe.crtc_id);
			continue;
		}

		printf("Using mode %s\n", mode->name);

		const bool is_hdr = table == TABLE_PIECEWISE_HDR;
		const int gbm_format = is_hdr ? GBM_FORMAT_XRGB2101010 : GBM_FORMAT_XRGB8888;

		printf("Creating buffer %ux%u (%s)\n", mode->hdisplay, mode->vdisplay,
		       (is_hdr ? "XR30" : "XR24"));
		struct gbm_bo *bo = gbm_bo_create(gbm, mode->hdisplay, mode->vdisplay, gbm_format,
						  GBM_BO_USE_SCANOUT | GBM_BO_USE_SW_WRITE_RARELY);
		if (!bo) {
			bs_debug_error("failed to create buffer object");
			return 1;
		}

		uint32_t fb_id = bs_drm_fb_create_gbm(bo);
		if (!fb_id) {
			bs_debug_error("failed to create frame buffer for buffer object");
			return 1;
		}

		if (!draw_pattern(mapper, bo, gbm_format)) {
			bs_debug_error("failed to draw pattern on buffer object");
			return 1;
		}

		ret = drmModeSetCrtc(fd, pipe.crtc_id, fb_id, 0, 0, &pipe.connector_id, 1, mode);
		if (ret < 0) {
			bs_debug_error("Could not set mode on CRTC %d %s", pipe.crtc_id,
				       strerror(errno));
			return 1;
		}

		ret = set_gamma(fd, pipe.crtc_id, gamma_size, table, is_hdr ? srgb_joint : gamma);
		if (ret)
			return ret;

		fsleep(time);

		if (!persist) {
			ret = set_gamma(fd, pipe.crtc_id, gamma_size, TABLE_LINEAR, 0.0f);
			if (ret)
				return ret;
		}

		ret = drmModeSetCrtc(fd, pipe.crtc_id, 0, 0, 0, NULL, 0, NULL);
		if (ret < 0) {
			bs_debug_error("Could disable CRTC %d %s\n", pipe.crtc_id, strerror(errno));
			return 1;
		}

		drmModeRmFB(fd, fb_id);
		gbm_bo_destroy(bo);
		num_success++;
	}
	bs_mapper_destroy(mapper);

	if (connector != NULL) {
		drmModeFreeConnector(connector);
		connector = NULL;
	}

	drmModeFreeResources(resources);
	bs_drm_pipe_plumber_destroy(&plumber);

	if (!num_success) {
		bs_debug_error("unable to set gamma table on any CRTC");
		return 1;
	}

	return 0;
}
