/*
 * Copyright (c) 2014 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 <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <xf86drm.h>

#include "gbm_priv.h"
#include "util.h"

/*
gbm_buffer_base.cc:  gbm_bo_get_width(bo),
gbm_buffer_base.cc:  gbm_bo_get_height(bo),
gbm_buffer_base.cc:  gbm_bo_get_stride(bo),
gbm_buffer_base.cc:  gbm_bo_get_handle(bo).u32,
gbm_buffer_base.cc:  return gbm_bo_get_handle(bo_).u32;
gbm_buffer_base.cc:  return gfx::Size(gbm_bo_get_width(bo_), gbm_bo_get_height(bo_));
gbm_buffer.cc:    gbm_bo_destroy(bo());
gbm_buffer.cc:  gbm_bo* bo = gbm_bo_create(device,
gbm_surface.cc:    gbm_bo_set_user_data(bo, this, GbmSurfaceBuffer::Destroy);
gbm_surface.cc:      static_cast<GbmSurfaceBuffer*>(gbm_bo_get_user_data(buffer)));
gbm_surface.cc:    gbm_surface_release_buffer(native_surface_, current_buffer_);
gbm_surface.cc:    gbm_surface_destroy(native_surface_);
gbm_surface.cc:  native_surface_ = gbm_surface_create(
gbm_surface.cc:  gbm_bo* pending_buffer = gbm_surface_lock_front_buffer(native_surface_);
gbm_surface.cc:    gbm_surface_release_buffer(native_surface_, current_buffer_);
ozone_platform_gbm.cc:        device_(gbm_create_device(dri_->get_fd())) {}
ozone_platform_gbm.cc:    gbm_device_destroy(device_);
*/

extern struct gbm_driver gbm_driver_cirrus;
#ifdef GBM_EXYNOS
extern struct gbm_driver gbm_driver_exynos;
#endif
extern struct gbm_driver gbm_driver_gma500;
#ifdef GBM_I915
extern struct gbm_driver gbm_driver_i915;
#endif
#ifdef GBM_ROCKCHIP
extern struct gbm_driver gbm_driver_rockchip;
#endif
#ifdef GBM_TEGRA
extern struct gbm_driver gbm_driver_tegra;
#endif
extern struct gbm_driver gbm_driver_udl;

static struct gbm_driver *gbm_get_driver(int fd)
{
	drmVersionPtr drm_version;
	unsigned int i;

	drm_version = drmGetVersion(fd);

	if (!drm_version)
		return NULL;

	struct gbm_driver *driver_list[] = {
		&gbm_driver_cirrus,
#ifdef GBM_EXYNOS
		&gbm_driver_exynos,
#endif
		&gbm_driver_gma500,
#ifdef GBM_I915
		&gbm_driver_i915,
#endif
#ifdef GBM_ROCKCHIP
		&gbm_driver_rockchip,
#endif
#ifdef GBM_TEGRA
		&gbm_driver_tegra,
#endif
		&gbm_driver_udl,
	};

	for(i = 0; i < ARRAY_SIZE(driver_list); i++)
		if (!strcmp(drm_version->name, driver_list[i]->name))
		{
			drmFreeVersion(drm_version);
			return driver_list[i];
		}

	drmFreeVersion(drm_version);
	return NULL;
}

PUBLIC int
gbm_device_get_fd(struct gbm_device *gbm)
{
	return gbm->fd;
}

PUBLIC const char *
gbm_device_get_backend_name(struct gbm_device *gbm)
{
	return gbm->driver->name;
}

PUBLIC int
gbm_device_is_format_supported(struct gbm_device *gbm,
                             uint32_t format, uint32_t usage)
{
	unsigned i;

	if (format == GBM_BO_FORMAT_XRGB8888)
		format = GBM_FORMAT_XRGB8888;
	if (format == GBM_BO_FORMAT_ARGB8888)
		format = GBM_FORMAT_ARGB8888;

	if (usage & GBM_BO_USE_CURSOR &&
		usage & GBM_BO_USE_RENDERING)
		return 0;

	for(i = 0 ; i < ARRAY_SIZE(gbm->driver->format_list); i++)
	{
		if (!gbm->driver->format_list[i].format)
			break;

		if (gbm->driver->format_list[i].format == format &&
			(gbm->driver->format_list[i].usage & usage) == usage)
			return 1;
	}

	return 0;
}

PUBLIC struct gbm_device *gbm_create_device(int fd)
{
	struct gbm_device *gbm;
	int ret;

	gbm = (struct gbm_device*) malloc(sizeof(*gbm));
	if (!gbm)
		return NULL;

	gbm->fd = fd;

	gbm->driver = gbm_get_driver(fd);
	if (!gbm->driver) {
		free(gbm);
		return NULL;
	}

	if (gbm->driver->init) {
		ret = gbm->driver->init(gbm);
		if (ret) {
			free(gbm);
			return NULL;
		}
	}

	return gbm;
}

PUBLIC void gbm_device_destroy(struct gbm_device *gbm)
{
	if (gbm->driver->close)
		gbm->driver->close(gbm);
	free(gbm);
}

PUBLIC struct gbm_surface *gbm_surface_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags)
{
	struct gbm_surface *surface = (struct gbm_surface*) malloc(sizeof(*surface));
	if (!surface)
		return NULL;

	return surface;
}

PUBLIC void gbm_surface_destroy(struct gbm_surface *surface)
{
	free(surface);
}

PUBLIC struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface)
{
	return NULL;
}

PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_bo *bo)
{
}

PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags)
{
	struct gbm_bo *bo;
	int ret;

	bo = (struct gbm_bo*) malloc(sizeof(*bo));
	if (!bo)
		return NULL;

	bo->gbm = gbm;
	bo->width = width;
	bo->height = height;
	bo->stride = 0;
	bo->format = format;
	bo->handle.u32 = 0;
	bo->destroy_user_data = NULL;
	bo->user_data = NULL;

	ret = gbm->driver->bo_create(bo, width, height, format, flags);
	if (ret) {
		free(bo);
		return NULL;
	}

	return bo;
}

PUBLIC void gbm_bo_destroy(struct gbm_bo *bo)
{
	if (bo->destroy_user_data) {
		bo->destroy_user_data(bo, bo->user_data);
		bo->destroy_user_data = NULL;
		bo->user_data = NULL;
	}

	bo->gbm->driver->bo_destroy(bo);
	free(bo);
}

PUBLIC uint32_t
gbm_bo_get_width(struct gbm_bo *bo)
{
	return bo->width;
}

PUBLIC uint32_t
gbm_bo_get_height(struct gbm_bo *bo)
{
	return bo->height;
}

PUBLIC uint32_t
gbm_bo_get_stride(struct gbm_bo *bo)
{
	return bo->stride;
}

PUBLIC uint32_t
gbm_bo_get_format(struct gbm_bo *bo)
{
	return bo->format;
}

PUBLIC struct gbm_device *
gbm_bo_get_device(struct gbm_bo *bo)
{
	return bo->gbm;
}

PUBLIC union gbm_bo_handle
gbm_bo_get_handle(struct gbm_bo *bo)
{
	return bo->handle;
}

PUBLIC int
gbm_bo_get_fd(struct gbm_bo *bo)
{
	int fd;

	if (drmPrimeHandleToFD(dri->get_fd(),
				bo->handle,
				DRM_CLOEXEC,
				&fd))
		return fd;
	else
		return -1
}

PUBLIC void
gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
		     void (*destroy_user_data)(struct gbm_bo *, void *))
{
	bo->user_data = data;
	bo->destroy_user_data = destroy_user_data;
}

PUBLIC void *
gbm_bo_get_user_data(struct gbm_bo *bo)
{
	return bo->user_data;
}
