/*
 * Copyright 2016 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 <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <xf86drm.h>

#ifdef __ANDROID__
#include <cutils/log.h>
#include <libgen.h>
#define MINIGBM_DEBUG "vendor.minigbm.debug"
#else
#define MINIGBM_DEBUG "MINIGBM_DEBUG"
#endif

#include "drv_helpers.h"
#include "drv_priv.h"
#include "util.h"

#ifdef DRV_AMDGPU
extern const struct backend backend_amdgpu;
#endif
#ifdef DRV_I915
extern const struct backend backend_i915;
#endif
#ifdef DRV_MSM
extern const struct backend backend_msm;
#endif
#ifdef DRV_VC4
extern const struct backend backend_vc4;
#endif

// Dumb / generic drivers
extern const struct backend backend_evdi;
extern const struct backend backend_marvell;
extern const struct backend backend_mediatek;
extern const struct backend backend_meson;
extern const struct backend backend_nouveau;
extern const struct backend backend_komeda;
extern const struct backend backend_radeon;
extern const struct backend backend_rockchip;
extern const struct backend backend_sun4i_drm;
extern const struct backend backend_synaptics;
extern const struct backend backend_virtgpu;
extern const struct backend backend_udl;
extern const struct backend backend_vkms;

extern const struct backend backend_mock;

static const struct backend *drv_backend_list[] = {
#ifdef DRV_AMDGPU
	&backend_amdgpu,
#endif
#ifdef DRV_I915
	&backend_i915,
#endif
#ifdef DRV_MSM
	&backend_msm,
#endif
#ifdef DRV_VC4
	&backend_vc4,
#endif
	&backend_evdi,	    &backend_komeda,	&backend_marvell, &backend_mediatek,
	&backend_meson,	    &backend_nouveau,	&backend_radeon,  &backend_rockchip,
	&backend_sun4i_drm, &backend_synaptics, &backend_udl,	  &backend_virtgpu,
	&backend_vkms,	    &backend_mock
};

void drv_preload(bool load)
{
	unsigned int i;
	for (i = 0; i < ARRAY_SIZE(drv_backend_list); i++) {
		const struct backend *b = drv_backend_list[i];
		if (b->preload)
			b->preload(load);
	}
}

static const struct backend *drv_get_backend(int fd)
{
	drmVersionPtr drm_version;
	unsigned int i;

	drm_version = drmGetVersion(fd);

	if (!drm_version)
		return NULL;

	for (i = 0; i < ARRAY_SIZE(drv_backend_list); i++) {
		const struct backend *b = drv_backend_list[i];
		if (!strcmp(drm_version->name, b->name)) {
			drmFreeVersion(drm_version);
			return b;
		}
	}

	drmFreeVersion(drm_version);
	return NULL;
}

struct driver *drv_create(int fd)
{
	struct driver *drv;
	int ret;

	drv = (struct driver *)calloc(1, sizeof(*drv));

	if (!drv)
		return NULL;

	const char *minigbm_debug;
	minigbm_debug = drv_get_os_option(MINIGBM_DEBUG);
	drv->compression = (minigbm_debug == NULL) || (strstr(minigbm_debug, "nocompression") == NULL);
	drv->log_bos = (minigbm_debug && strstr(minigbm_debug, "log_bos") != NULL);

	drv->fd = fd;
	drv->backend = drv_get_backend(fd);

	if (!drv->backend)
		goto free_driver;

	if (pthread_mutex_init(&drv->buffer_table_lock, NULL))
		goto free_driver;

	drv->buffer_table = drmHashCreate();
	if (!drv->buffer_table)
		goto free_buffer_table_lock;

	if (pthread_mutex_init(&drv->mappings_lock, NULL))
		goto free_buffer_table;

	drv->mappings = drv_array_init(sizeof(struct mapping));
	if (!drv->mappings)
		goto free_mappings_lock;

	drv->combos = drv_array_init(sizeof(struct combination));
	if (!drv->combos)
		goto free_mappings;

	if (drv->backend->init) {
		ret = drv->backend->init(drv);
		if (ret) {
			drv_array_destroy(drv->combos);
			goto free_mappings;
		}
	}

	return drv;

free_mappings:
	drv_array_destroy(drv->mappings);
free_mappings_lock:
	pthread_mutex_destroy(&drv->mappings_lock);
free_buffer_table:
	drmHashDestroy(drv->buffer_table);
free_buffer_table_lock:
	pthread_mutex_destroy(&drv->buffer_table_lock);
free_driver:
	free(drv);
	return NULL;
}

void drv_destroy(struct driver *drv)
{
	if (drv->backend->close)
		drv->backend->close(drv);

	drv_array_destroy(drv->combos);

	drv_array_destroy(drv->mappings);
	pthread_mutex_destroy(&drv->mappings_lock);

	drmHashDestroy(drv->buffer_table);
	pthread_mutex_destroy(&drv->buffer_table_lock);

	free(drv);
}

int drv_get_fd(struct driver *drv)
{
	return drv->fd;
}

const char *drv_get_name(struct driver *drv)
{
	return drv->backend->name;
}

struct combination *drv_get_combination(struct driver *drv, uint32_t format, uint64_t use_flags)
{
	struct combination *curr, *best;

	if (format == DRM_FORMAT_NONE || use_flags == BO_USE_NONE)
		return 0;

	best = NULL;
	uint32_t i;
	for (i = 0; i < drv_array_size(drv->combos); i++) {
		curr = drv_array_at_idx(drv->combos, i);
		if ((format == curr->format) && use_flags == (curr->use_flags & use_flags))
			if (!best || best->metadata.priority < curr->metadata.priority)
				best = curr;
	}

	return best;
}

struct bo *drv_bo_new(struct driver *drv, uint32_t width, uint32_t height, uint32_t format,
		      uint64_t use_flags, bool is_test_buffer)
{

	struct bo *bo;
	bo = (struct bo *)calloc(1, sizeof(*bo));

	if (!bo)
		return NULL;

	bo->drv = drv;
	bo->meta.width = width;
	bo->meta.height = height;
	bo->meta.format = format;
	bo->meta.use_flags = use_flags;
	bo->meta.num_planes = drv_num_planes_from_format(format);
	bo->is_test_buffer = is_test_buffer;

	if (!bo->meta.num_planes) {
		free(bo);
		errno = EINVAL;
		return NULL;
	}

	return bo;
}

static void drv_bo_mapping_destroy(struct bo *bo)
{
	struct driver *drv = bo->drv;
	uint32_t idx = 0;

	/*
	 * This function is called right before the buffer is destroyed. It will free any mappings
	 * associated with the buffer.
	 */
	pthread_mutex_lock(&drv->mappings_lock);
	for (size_t plane = 0; plane < bo->meta.num_planes; plane++) {
		while (idx < drv_array_size(drv->mappings)) {
			struct mapping *mapping =
			    (struct mapping *)drv_array_at_idx(drv->mappings, idx);
			if (mapping->vma->handle != bo->handle.u32) {
				idx++;
				continue;
			}

			if (!--mapping->vma->refcount) {
				int ret = drv->backend->bo_unmap(bo, mapping->vma);
				if (ret) {
					pthread_mutex_unlock(&drv->mappings_lock);
					assert(ret);
					drv_loge("munmap failed\n");
					return;
				}

				free(mapping->vma);
			}

			/* This shrinks and shifts the array, so don't increment idx. */
			drv_array_remove(drv->mappings, idx);
		}
	}
	pthread_mutex_unlock(&drv->mappings_lock);
}

/*
 * Acquire a reference on plane buffers of the bo.
 */
static void drv_bo_acquire(struct bo *bo)
{
	struct driver *drv = bo->drv;

	pthread_mutex_lock(&drv->buffer_table_lock);
	for (size_t plane = 0; plane < bo->meta.num_planes; plane++) {
		uintptr_t num = 0;

		if (!drmHashLookup(drv->buffer_table, bo->handle.u32, (void **)&num))
			drmHashDelete(drv->buffer_table, bo->handle.u32);

		drmHashInsert(drv->buffer_table, bo->handle.u32, (void *)(num + 1));
	}
	pthread_mutex_unlock(&drv->buffer_table_lock);
}

/*
 * Release a reference on plane buffers of the bo. Return true when the bo has lost all its
 * references. Otherwise, return false.
 */
static bool drv_bo_release(struct bo *bo)
{
	struct driver *drv = bo->drv;
	uintptr_t num;

	if (drv->backend->bo_release)
		drv->backend->bo_release(bo);

	pthread_mutex_lock(&drv->buffer_table_lock);
	for (size_t plane = 0; plane < bo->meta.num_planes; plane++) {
		if (!drmHashLookup(drv->buffer_table, bo->handle.u32, (void **)&num)) {
			drmHashDelete(drv->buffer_table, bo->handle.u32);

			if (num > 1) {
				drmHashInsert(drv->buffer_table, bo->handle.u32, (void *)(num - 1));
			}
		}
	}

	/* The same buffer can back multiple planes with different offsets. */
	for (size_t plane = 0; plane < bo->meta.num_planes; plane++) {
		if (!drmHashLookup(drv->buffer_table, bo->handle.u32, (void **)&num)) {
			/* num is positive if found in the hashmap. */
			pthread_mutex_unlock(&drv->buffer_table_lock);
			return false;
		}
	}
	pthread_mutex_unlock(&drv->buffer_table_lock);

	return true;
}

struct bo *drv_bo_create(struct driver *drv, uint32_t width, uint32_t height, uint32_t format,
			 uint64_t use_flags)
{
	int ret;
	struct bo *bo;
	bool is_test_alloc;

	is_test_alloc = use_flags & BO_USE_TEST_ALLOC;
	use_flags &= ~BO_USE_TEST_ALLOC;

	bo = drv_bo_new(drv, width, height, format, use_flags, is_test_alloc);

	if (!bo)
		return NULL;

	ret = -EINVAL;
	if (drv->backend->bo_compute_metadata) {
		ret = drv->backend->bo_compute_metadata(bo, width, height, format, use_flags, NULL,
							0);
		if (!is_test_alloc && ret == 0)
			ret = drv->backend->bo_create_from_metadata(bo);
	} else if (!is_test_alloc) {
		ret = drv->backend->bo_create(bo, width, height, format, use_flags);
	}

	if (ret) {
		errno = -ret;
		free(bo);
		return NULL;
	}

	drv_bo_acquire(bo);

	if (drv->log_bos)
		drv_bo_log_info(bo, "legacy created");

	return bo;
}

struct bo *drv_bo_create_with_modifiers(struct driver *drv, uint32_t width, uint32_t height,
					uint32_t format, const uint64_t *modifiers, uint32_t count)
{
	int ret;
	struct bo *bo;

	if (!drv->backend->bo_create_with_modifiers && !drv->backend->bo_compute_metadata) {
		errno = ENOENT;
		return NULL;
	}

	bo = drv_bo_new(drv, width, height, format, BO_USE_NONE, false);

	if (!bo)
		return NULL;

	ret = -EINVAL;
	if (drv->backend->bo_compute_metadata) {
		ret = drv->backend->bo_compute_metadata(bo, width, height, format, BO_USE_NONE,
							modifiers, count);
		if (ret == 0)
			ret = drv->backend->bo_create_from_metadata(bo);
	} else {
		ret = drv->backend->bo_create_with_modifiers(bo, width, height, format, modifiers,
							     count);
	}

	if (ret) {
		free(bo);
		return NULL;
	}

	drv_bo_acquire(bo);

	if (drv->log_bos)
		drv_bo_log_info(bo, "created");

	return bo;
}

void drv_bo_destroy(struct bo *bo)
{
	if (!bo->is_test_buffer && drv_bo_release(bo)) {
		drv_bo_mapping_destroy(bo);
		bo->drv->backend->bo_destroy(bo);
	}

	free(bo);
}

struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data)
{
	int ret;
	size_t plane;
	struct bo *bo;
	off_t seek_end;

	bo = drv_bo_new(drv, data->width, data->height, data->format, data->use_flags, false);

	if (!bo)
		return NULL;

	ret = drv->backend->bo_import(bo, data);
	if (ret) {
		free(bo);
		return NULL;
	}

	drv_bo_acquire(bo);

	bo->meta.format_modifier = data->format_modifier;
	for (plane = 0; plane < bo->meta.num_planes; plane++) {
		bo->meta.strides[plane] = data->strides[plane];
		bo->meta.offsets[plane] = data->offsets[plane];

		seek_end = lseek(data->fds[plane], 0, SEEK_END);
		if (seek_end == (off_t)(-1)) {
			drv_loge("lseek() failed with %s\n", strerror(errno));
			goto destroy_bo;
		}

		lseek(data->fds[plane], 0, SEEK_SET);
		if (plane == bo->meta.num_planes - 1 || data->offsets[plane + 1] == 0)
			bo->meta.sizes[plane] = seek_end - data->offsets[plane];
		else
			bo->meta.sizes[plane] = data->offsets[plane + 1] - data->offsets[plane];

		if ((int64_t)bo->meta.offsets[plane] + bo->meta.sizes[plane] > seek_end) {
			drv_loge("buffer size is too large.\n");
			goto destroy_bo;
		}

		bo->meta.total_size += bo->meta.sizes[plane];
	}

	if (drv->log_bos)
		drv_bo_log_info(bo, "imported");

	return bo;

destroy_bo:
	drv_bo_destroy(bo);
	return NULL;
}

void *drv_bo_map(struct bo *bo, const struct rectangle *rect, uint32_t map_flags,
		 struct mapping **map_data, size_t plane)
{
	struct driver *drv = bo->drv;
	uint32_t i;
	uint8_t *addr;
	struct mapping mapping = { 0 };

	assert(rect->width >= 0);
	assert(rect->height >= 0);
	assert(rect->x + rect->width <= drv_bo_get_width(bo));
	assert(rect->y + rect->height <= drv_bo_get_height(bo));
	assert(BO_MAP_READ_WRITE & map_flags);
	/* No CPU access for protected buffers. */
	assert(!(bo->meta.use_flags & BO_USE_PROTECTED));

	if (bo->is_test_buffer)
		return MAP_FAILED;

	mapping.rect = *rect;
	mapping.refcount = 1;

	pthread_mutex_lock(&drv->mappings_lock);

	for (i = 0; i < drv_array_size(drv->mappings); i++) {
		struct mapping *prior = (struct mapping *)drv_array_at_idx(drv->mappings, i);
		if (prior->vma->handle != bo->handle.u32 || prior->vma->map_flags != map_flags)
			continue;

		if (rect->x != prior->rect.x || rect->y != prior->rect.y ||
		    rect->width != prior->rect.width || rect->height != prior->rect.height)
			continue;

		prior->refcount++;
		*map_data = prior;
		goto exact_match;
	}

	for (i = 0; i < drv_array_size(drv->mappings); i++) {
		struct mapping *prior = (struct mapping *)drv_array_at_idx(drv->mappings, i);
		if (prior->vma->handle != bo->handle.u32 || prior->vma->map_flags != map_flags)
			continue;

		prior->vma->refcount++;
		mapping.vma = prior->vma;
		goto success;
	}

	mapping.vma = calloc(1, sizeof(*mapping.vma));
	if (!mapping.vma) {
		*map_data = NULL;
		pthread_mutex_unlock(&drv->mappings_lock);
		return MAP_FAILED;
	}

	memcpy(mapping.vma->map_strides, bo->meta.strides, sizeof(mapping.vma->map_strides));
	addr = drv->backend->bo_map(bo, mapping.vma, map_flags);
	if (addr == MAP_FAILED) {
		*map_data = NULL;
		free(mapping.vma);
		pthread_mutex_unlock(&drv->mappings_lock);
		return MAP_FAILED;
	}

	mapping.vma->refcount = 1;
	mapping.vma->addr = addr;
	mapping.vma->handle = bo->handle.u32;
	mapping.vma->map_flags = map_flags;

success:
	*map_data = drv_array_append(drv->mappings, &mapping);
exact_match:
	drv_bo_invalidate(bo, *map_data);
	addr = (uint8_t *)((*map_data)->vma->addr);
	addr += drv_bo_get_plane_offset(bo, plane);
	pthread_mutex_unlock(&drv->mappings_lock);
	return (void *)addr;
}

int drv_bo_unmap(struct bo *bo, struct mapping *mapping)
{
	struct driver *drv = bo->drv;
	uint32_t i;
	int ret = 0;

	pthread_mutex_lock(&drv->mappings_lock);

	if (--mapping->refcount)
		goto out;

	if (!--mapping->vma->refcount) {
		ret = drv->backend->bo_unmap(bo, mapping->vma);
		free(mapping->vma);
	}

	for (i = 0; i < drv_array_size(drv->mappings); i++) {
		if (mapping == (struct mapping *)drv_array_at_idx(drv->mappings, i)) {
			drv_array_remove(drv->mappings, i);
			break;
		}
	}

out:
	pthread_mutex_unlock(&drv->mappings_lock);
	return ret;
}

bool drv_bo_cached(struct bo *bo)
{
	return bo->meta.cached;
}

int drv_bo_invalidate(struct bo *bo, struct mapping *mapping)
{
	int ret = 0;

	assert(mapping);
	assert(mapping->vma);
	assert(mapping->refcount > 0);
	assert(mapping->vma->refcount > 0);

	if (bo->drv->backend->bo_invalidate)
		ret = bo->drv->backend->bo_invalidate(bo, mapping);

	return ret;
}

int drv_bo_flush(struct bo *bo, struct mapping *mapping)
{
	int ret = 0;

	assert(mapping);
	assert(mapping->vma);
	assert(mapping->refcount > 0);
	assert(mapping->vma->refcount > 0);

	if (bo->drv->backend->bo_flush)
		ret = bo->drv->backend->bo_flush(bo, mapping);

	return ret;
}

int drv_bo_flush_or_unmap(struct bo *bo, struct mapping *mapping)
{
	int ret = 0;

	assert(mapping);
	assert(mapping->vma);
	assert(mapping->refcount > 0);
	assert(mapping->vma->refcount > 0);
	assert(!(bo->meta.use_flags & BO_USE_PROTECTED));

	if (bo->drv->backend->bo_flush)
		ret = bo->drv->backend->bo_flush(bo, mapping);
	else
		ret = drv_bo_unmap(bo, mapping);

	return ret;
}

uint32_t drv_bo_get_width(struct bo *bo)
{
	return bo->meta.width;
}

uint32_t drv_bo_get_height(struct bo *bo)
{
	return bo->meta.height;
}

size_t drv_bo_get_num_planes(struct bo *bo)
{
	return bo->meta.num_planes;
}

union bo_handle drv_bo_get_plane_handle(struct bo *bo, size_t plane)
{
	return bo->handle;
}

#ifndef DRM_RDWR
#define DRM_RDWR O_RDWR
#endif

int drv_bo_get_plane_fd(struct bo *bo, size_t plane)
{

	int ret, fd;
	assert(plane < bo->meta.num_planes);

	if (bo->is_test_buffer)
		return -EINVAL;

	ret = drmPrimeHandleToFD(bo->drv->fd, bo->handle.u32, DRM_CLOEXEC | DRM_RDWR, &fd);

	// Older DRM implementations blocked DRM_RDWR, but gave a read/write mapping anyways
	if (ret)
		ret = drmPrimeHandleToFD(bo->drv->fd, bo->handle.u32, DRM_CLOEXEC, &fd);

	if (ret)
		drv_loge("Failed to get plane fd: %s\n", strerror(errno));

	return (ret) ? ret : fd;
}

uint32_t drv_bo_get_plane_offset(struct bo *bo, size_t plane)
{
	assert(plane < bo->meta.num_planes);
	return bo->meta.offsets[plane];
}

uint32_t drv_bo_get_plane_size(struct bo *bo, size_t plane)
{
	assert(plane < bo->meta.num_planes);
	return bo->meta.sizes[plane];
}

uint32_t drv_bo_get_plane_stride(struct bo *bo, size_t plane)
{
	assert(plane < bo->meta.num_planes);
	return bo->meta.strides[plane];
}

uint64_t drv_bo_get_format_modifier(struct bo *bo)
{
	return bo->meta.format_modifier;
}

uint32_t drv_bo_get_format(struct bo *bo)
{
	return bo->meta.format;
}

uint32_t drv_bo_get_tiling(struct bo *bo)
{
	return bo->meta.tiling;
}

uint64_t drv_bo_get_use_flags(struct bo *bo)
{
	return bo->meta.use_flags;
}

size_t drv_bo_get_total_size(struct bo *bo)
{
	return bo->meta.total_size;
}

void drv_bo_log_info(const struct bo *bo, const char *prefix)
{
	const struct bo_metadata *meta = &bo->meta;

	drv_logd("%s %s bo %p: %dx%d '%c%c%c%c' tiling %d plane %zu mod 0x%" PRIx64 " use 0x%" PRIx64 " size %zu\n",
		 prefix, bo->drv->backend->name, bo,
		 meta->width, meta->height,
		 meta->format & 0xff,
		 (meta->format >> 8) & 0xff,
		 (meta->format >> 16) & 0xff,
		 (meta->format >> 24) & 0xff,
		 meta->tiling, meta->num_planes, meta->format_modifier,
		 meta->use_flags, meta->total_size);
	for (uint32_t i = 0; i < meta->num_planes; i++) {
		drv_logd("  bo %p plane %d: offset %d size %d stride %d\n",
			 bo, i, meta->offsets[i], meta->sizes[i],
			 meta->strides[i]);
	}
}

/*
 * Map internal fourcc codes back to standard fourcc codes.
 */
uint32_t drv_get_standard_fourcc(uint32_t fourcc_internal)
{
	return (fourcc_internal == DRM_FORMAT_YVU420_ANDROID) ? DRM_FORMAT_YVU420 : fourcc_internal;
}

void drv_resolve_format_and_use_flags(struct driver *drv, uint32_t format, uint64_t use_flags,
				      uint32_t *out_format, uint64_t *out_use_flags)
{
	assert(drv->backend->resolve_format_and_use_flags);

	drv->backend->resolve_format_and_use_flags(drv, format, use_flags, out_format,
						   out_use_flags);
}

void drv_log_prefix(enum drv_log_level level, const char *prefix, const char *func, int line,
		    const char *format, ...)
{
	char buf[50];
	snprintf(buf, sizeof(buf), "[%s:%s(%d)]", prefix, func, line);

	va_list args;
	va_start(args, format);
#ifdef __ANDROID__
	int prio = ANDROID_LOG_ERROR;
	switch (level) {
	case DRV_LOGV:
		prio = ANDROID_LOG_VERBOSE;
		break;
	case DRV_LOGD:
		prio = ANDROID_LOG_DEBUG;
		break;
	case DRV_LOGI:
		prio = ANDROID_LOG_INFO;
		break;
	case DRV_LOGE:
	default:
		break;
	};
	__android_log_vprint(prio, buf, format, args);
#else
	fprintf(stderr, "%s ", buf);
	vfprintf(stderr, format, args);
#endif
	va_end(args);
}

int drv_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES],
		      uint32_t offsets[DRV_MAX_PLANES], uint64_t *format_modifier)
{
	for (uint32_t plane = 0; plane < bo->meta.num_planes; plane++) {
		strides[plane] = bo->meta.strides[plane];
		offsets[plane] = bo->meta.offsets[plane];
	}
	*format_modifier = bo->meta.format_modifier;

	if (bo->drv->backend->resource_info)
		return bo->drv->backend->resource_info(bo, strides, offsets, format_modifier);

	return 0;
}

uint32_t drv_get_max_texture_2d_size(struct driver *drv)
{
	if (drv->backend->get_max_texture_2d_size)
		return drv->backend->get_max_texture_2d_size(drv);

	return UINT32_MAX;
}
