/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>

#include <pthread.h>

#include <hardware/hardware.h>
#include <hardware/gralloc.h>
#include <hardware/hwcomposer.h>

#include <system/window.h>
#include <cutils/native_handle.h>

// normalize and shorten type names
typedef struct android_native_base_t aBase;
typedef struct ANativeWindowBuffer aBuffer;
typedef struct ANativeWindow aWindow;

static int trace_level = 1;

#define _TRACE(n,fmt...) \
	do { if (trace_level >= (n)) fprintf(stderr, "CNW: " fmt); } while (0)

#define ERROR(fmt...) _TRACE(0, fmt)
#define INFO(fmt...) _TRACE(1, fmt)
#define LOG(fmt...) _TRACE(2, fmt)
#define TRACE(fmt...) _TRACE(3, fmt)

#define QCT_WORKAROUND 1

typedef struct CNativeBuffer {
	aBuffer base;
	struct CNativeBuffer *next;
	struct CNativeBuffer *prev;
	int ffd;
} CNativeBuffer;

typedef struct CNativeWindow {
	aWindow base;

	hwc_composer_device_1_t *hwc;
	framebuffer_device_t *fb;
	alloc_device_t *gr;

	pthread_mutex_t lock;
	pthread_cond_t cvar;

	aBuffer *front;
	aBuffer *spare;

	CNativeBuffer free_buffer_queue;

	unsigned width;
	unsigned height;
	unsigned xdpi;
	unsigned ydpi;
	unsigned format;

	hwc_display_contents_1_t *dclist[HWC_NUM_PHYSICAL_DISPLAY_TYPES];

	hwc_display_contents_1_t dc;
	hwc_layer_1_t layer[4];
} CNativeWindow;

static inline CNativeBuffer *from_abuffer(aBuffer *buf) {
	return (CNativeBuffer*) buf;
}

static CNativeBuffer *get_front(struct CNativeBuffer *queue) {
	CNativeBuffer *buf = queue->next;
	if (buf == queue)
		return 0;
	buf->next->prev = queue;
	queue->next = buf->next;
	buf->next = buf->prev = 0;
	return buf;
}

static void put_front(struct CNativeBuffer *queue, aBuffer *_buf) {
	struct CNativeBuffer *buf = (struct CNativeBuffer *) _buf;
	buf->prev = queue;
	buf->next = queue->next;
	queue->next->prev = buf;
	queue->next = buf;
}

static void put_back(struct CNativeBuffer *queue, aBuffer *_buf) {
	struct CNativeBuffer *buf = (struct CNativeBuffer *) _buf;
	buf->next = queue;
	buf->prev = queue->prev;
	queue->prev->next = buf;
	queue->prev = buf;
}

static void cnw_inc_ref(aBase *base) { TRACE("buf %p ref++\n",base); }
static void cnw_dec_ref(aBase *base) { TRACE("buf %p ref--\n",base); }

static inline CNativeWindow *from_base(aWindow *base) {
	return (CNativeWindow *) base;
}

static inline CNativeWindow *from_base_const(const aWindow *base) {
	return (CNativeWindow *) base;
}

static int cnw_set_swap_interval(aWindow *base, int interval) {
	CNativeWindow *win = from_base(base);
	if (win->fb && win->fb->setSwapInterval)
		return win->fb->setSwapInterval(win->fb, interval);
	return 0;
}

static int cnw_dequeue_buffer1(aWindow *base, aBuffer **buf, int *ffd) {
	CNativeWindow *win = from_base(base);
	CNativeBuffer *cnb;

	pthread_mutex_lock(&win->lock);

	while ((cnb = get_front(&win->free_buffer_queue)) == 0) {
		pthread_cond_wait(&win->cvar, &win->lock);
	}

	*ffd = cnb->ffd;
	*buf = &cnb->base;
	cnb->ffd = -1;
	LOG("<< dequeue buffer %p %d\n", *buf, *ffd);

	pthread_mutex_unlock(&win->lock);
	return 0;
}

static int cnw_lock_buffer0(aWindow *base, aBuffer *buffer) {
	return 0;
}

static void set_layer(hwc_layer_1_t *dl, aBuffer *buf, int ffd) {
	int right = buf->width;
	int bottom = buf->height;

	dl->compositionType = HWC_FRAMEBUFFER;
	dl->hints = 0;
	dl->flags = 0;

	dl->handle = buf->handle;
	dl->transform = 0;
	dl->blending = HWC_BLENDING_NONE;
	dl->sourceCrop.left = 0;
	dl->sourceCrop.top = 0;
	dl->sourceCrop.right = right;
	dl->sourceCrop.bottom = bottom;
	dl->displayFrame.left = 0;
	dl->displayFrame.top = 0;
	dl->displayFrame.right = right;
	dl->displayFrame.bottom = bottom;
	dl->visibleRegionScreen.numRects = 1;
	dl->visibleRegionScreen.rects = &dl->displayFrame;

	dl->acquireFenceFd = ffd;
	dl->releaseFenceFd = -1;
}

static void hwc_post(CNativeWindow *win, aBuffer *buf, int ffd) {
	hwc_composer_device_1_t *hwc = win->hwc;
	hwc_display_contents_1_t *dc = &(win->dc);
	hwc_layer_1_t *dl = win->dc.hwLayers;
	int r;

	dc->retireFenceFd = -1;
	dc->outbufAcquireFenceFd = -1;
	dc->flags = HWC_GEOMETRY_CHANGED;
	dc->numHwLayers = 1;

	// some hwcomposers fail if these are NULL
	dc->dpy = (void*) 0xdeadbeef;
	dc->sur = (void*) 0xdeadbeef;

	set_layer(&dl[0], buf, ffd);

	if (QCT_WORKAROUND) {
		set_layer(&dl[1], win->spare, -1);
		dl[1].compositionType = HWC_FRAMEBUFFER_TARGET;
		dc->numHwLayers++;
	}

	r = hwc->prepare(hwc, HWC_NUM_PHYSICAL_DISPLAY_TYPES, win->dclist);
	if (r) {
		ERROR("hwc->prepare failed r=%d\n",r);
		return;
	}

//	for (i = 0; i < dc->numHwLayers; i++)
//		LOG("dl[%d] ctype=0x%08x hints=0x%08x flags=0x%08x\n", i,
//			dl[i].compositionType, dl[0].hints, dl[0].flags);

	r = hwc->set(hwc, HWC_NUM_PHYSICAL_DISPLAY_TYPES, win->dclist);
	if (r) {
		ERROR("hwc->set failed, r=%d\n", r);
		return;
	}

	if (dc->retireFenceFd != -1)
		close(dc->retireFenceFd);
	if (dl->releaseFenceFd != -1) {
		CNativeBuffer *cnb = from_abuffer(buf);
		cnb->ffd = dl->releaseFenceFd;
	}
	if (QCT_WORKAROUND)
		if (dl[1].releaseFenceFd != -1)
			close(dl[1].releaseFenceFd);
}

static int cnw_queue_buffer1(aWindow *base, aBuffer *buffer, int ffd) {
	CNativeWindow *win = from_base(base);
	int res;
	LOG(">> queue buffer %p %d\n", buffer, ffd);
	if (win->fb) {
		res = win->fb->post(win->fb, buffer->handle);
		if (ffd != -1)
			close(ffd);
	} else {
		hwc_post(win, buffer, ffd);
		res = 0;
	}
	pthread_mutex_lock(&win->lock);
	if (win->front)
		put_back(&win->free_buffer_queue, win->front);
	win->front = buffer;
	pthread_cond_signal(&win->cvar);
	pthread_mutex_unlock(&win->lock);

	return res;
}

static int cnw_cancel_buffer1(aWindow *base, aBuffer *buf, int ffd) {
	CNativeWindow *win = from_base(base);
	CNativeBuffer *cnb = from_abuffer(buf);
	LOG("<< cancel buffer %p %d\n", buf, ffd);
	cnb->ffd = ffd;
	pthread_mutex_lock(&win->lock);
	put_front(&win->free_buffer_queue, buf);
	pthread_mutex_unlock(&win->lock);
	return 0;
}

static int cnw_dequeue_buffer0(aWindow *base, aBuffer **buf) {
	int ffd = -1;
	int r;
	r = cnw_dequeue_buffer1(base, buf, &ffd);
	if (ffd != -1)
		close(ffd);
	return r;
}

static int cnw_queue_buffer0(aWindow *base, aBuffer *buf) {
	return cnw_queue_buffer1(base, buf, -1);
}

static int cnw_cancel_buffer0(aWindow *base, aBuffer *buf) {
	return cnw_cancel_buffer1(base, buf, -1);
}

static int cnw_query(const aWindow *base, int what, int *value) {
	CNativeWindow *win = from_base_const(base);

	switch (what) {
	case NATIVE_WINDOW_WIDTH:
	case NATIVE_WINDOW_DEFAULT_WIDTH:
		*value = win->width;
		TRACE("query window width: %d\n", *value);
		return 0;
	case NATIVE_WINDOW_HEIGHT:
	case NATIVE_WINDOW_DEFAULT_HEIGHT:
		*value = win->height;
		TRACE("query window height: %d\n", *value);
		return 0;
	case NATIVE_WINDOW_FORMAT:
		*value = win->format;
		TRACE("query window format: %d\n", *value);
		return 0;
	case NATIVE_WINDOW_TRANSFORM_HINT:
		TRACE("query transform hint: 0\n");
		*value = 0;
		return 0;
	case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
		TRACE("query min undequeued buffers: 1\n");
		*value = 1;
		return 0;
	default:
		*value = 0;
		ERROR("query %d unknown!\n", what);
		return -EINVAL;
	}
}

static int cnw_perform(aWindow *base, int op, ...) {
	CNativeWindow *win = from_base(base);
	va_list ap;
	va_start(ap, op);

	switch (op) {
	case NATIVE_WINDOW_SET_USAGE:
		TRACE("set usage %d\n", va_arg(ap,int));
		return 0;
	case NATIVE_WINDOW_CONNECT:
	case NATIVE_WINDOW_DISCONNECT:
	case NATIVE_WINDOW_API_CONNECT:
	case NATIVE_WINDOW_API_DISCONNECT:
		return 0;
	case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
		TRACE("set buffers format %d\n", va_arg(ap,int));
		return 0;
	case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
		TRACE("set buffers transform %d\n", va_arg(ap,int));
		return 0;
	case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
		TRACE("set buffers timestamp %lld\n", va_arg(ap,long long));
		return 0;
	case NATIVE_WINDOW_SET_SCALING_MODE:
		TRACE("set scaling mode %d\n", va_arg(ap,int));
		return 0;
	case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: {
		unsigned int w = va_arg(ap,unsigned int);
		unsigned int h = va_arg(ap,unsigned int);
		if ((w == win->width) && (h == win->height)) {
			TRACE("set buffers dimensions %d x %d\n", w, h);
			return 0;
		}
		ERROR("cannot resize buffers to %d x %d\n", w, h);
		return -1;
	}
	default:
		ERROR("perform %d unknown!\n", op);
		return -ENODEV;
	}
}

static void hwc_invalidate(const struct hwc_procs *procs) {}
static void hwc_vsync(const struct hwc_procs *procs, int disp, int64_t ts) {}
static void hwc_hotplug(const struct hwc_procs *procs, int disp, int conn) {}

struct hwc_procs hprocs = {
	.invalidate = hwc_invalidate,
	.vsync = hwc_vsync,
	.hotplug = hwc_hotplug,
};

uint32_t attrs[] = {
	HWC_DISPLAY_WIDTH,
	HWC_DISPLAY_HEIGHT,
	HWC_DISPLAY_VSYNC_PERIOD,
	HWC_DISPLAY_DPI_X,
	HWC_DISPLAY_DPI_Y,
	HWC_DISPLAY_NO_ATTRIBUTE,
};

static int hwc_init(CNativeWindow *win) {
	hw_module_t const* module;
	hwc_composer_device_1_t *hwc;
	unsigned i;
	int r;
	uint32_t configs[32];
	size_t numconfigs = 32;
	int32_t values[8];

	if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
		ERROR("cannot open hw composer module\n");
		return -ENODEV;
	}

	if (hwc_open_1(module, &hwc)) {
		ERROR("cannot open hwc device\n");
		return -ENODEV;
	}
	win->hwc = hwc;

	LOG("hwc version 0x%08x\n", hwc->common.version);

	if ((hwc->common.version & 0xFFFF0000) < 0x01010000) {
		ERROR("hwc version less than 1.1\n");
		hwc_close_1(hwc);
		return -ENODEV;
	}

	hwc->registerProcs(hwc, &hprocs);

	if (hwc->getDisplayConfigs(hwc, 0, configs, &numconfigs)) {
		ERROR("cannot get configs\n");
		return -ENODEV;
	}
	for (i = 0; i < numconfigs; i++)
		LOG("cfg[%d] = 0x%08x\n", i, configs[i]);

	if ((r = hwc->getDisplayAttributes(hwc, 0, configs[0], attrs, values))) {
		ERROR("cannot get attributes %d\n", r);
		return -ENODEV;
	}

	win->width = values[0];
	win->height = values[1];
	win->xdpi = values[3];
	win->ydpi = values[4];
	win->format = HAL_PIXEL_FORMAT_RGBA_8888;

	hwc->blank(hwc, 0, 0);

	win->dclist[0] = &(win->dc);
	return 0;
}

static aBuffer *cnw_alloc(CNativeWindow *win, unsigned format, unsigned usage) {
	CNativeBuffer *cnb;
	aBuffer *buf;
	int err;

	if (!(cnb = malloc(sizeof(CNativeBuffer))))
		return 0;

	buf = &cnb->base;
	cnb->ffd = -1;

	buf->common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
	buf->common.version = sizeof(aBuffer);
	buf->common.incRef = cnw_inc_ref;
	buf->common.decRef = cnw_dec_ref;

	buf->width = win->width;
	buf->height = win->height;
	buf->format = format;
	buf->usage = usage;

	err = win->gr->alloc(win->gr, win->width, win->height,
		format, usage, &buf->handle, &buf->stride);
	if (err) {
		ERROR("gralloc of %d x %d failed: err=%d\n",
			win->width, win->height, err);
		free(buf);
		return 0;
	}
	INFO("alloc buffer %p %d x %d\n", buf, win->width, win->height);
	return buf;
}

static int cnw_init(CNativeWindow *win) {
	hw_module_t const* module;
	framebuffer_device_t *fb = NULL;
	alloc_device_t *gr;
	int err, i;
	unsigned usage;

	memset(win, 0, sizeof(CNativeWindow));

	win->free_buffer_queue.next = &(win->free_buffer_queue);
	win->free_buffer_queue.prev = &(win->free_buffer_queue);

	if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) != 0) {
		ERROR("cannot open gralloc module\n");
		return -ENODEV;
	}

	if (hwc_init(win)) {
		ERROR("cannot open hwcomposer, trying legacy fb HAL\n");
		err = framebuffer_open(module, &fb);
		if (err) {
			ERROR("cannot open fb HAL (%s)", strerror(-err));
			return -ENODEV;
		}
		win->width = fb->width;
		win->height = fb->height;
		win->format = fb->format;
		win->xdpi = fb->xdpi;
		win->ydpi = fb->ydpi;
		win->fb = fb;
	}

	INFO("display %d x %d fmt=%d\n",
		win->width, win->height, win->format);

	err = gralloc_open(module, &gr);
	if (err) {
		ERROR("couldn't open gralloc HAL (%s)", strerror(-err));
		return -ENODEV;
	}
	win->gr = gr;

	usage = GRALLOC_USAGE_HW_FB |
		GRALLOC_USAGE_HW_COMPOSER |
		GRALLOC_USAGE_HW_RENDER;

	for (i = 0; i < 2; i++) {
		aBuffer *buf = cnw_alloc(win, win->format, usage);
		if (!buf)
			return -ENOMEM;
		put_back(&win->free_buffer_queue, buf);
	}

	if (!win->fb && QCT_WORKAROUND) {
		win->spare = cnw_alloc(win, win->format, usage);
		if (!win->spare)
			return -ENOMEM;
	}

	// Disgusting, but we need to init these "const" fields
	// and unlike C++ we can't use const_cast<>
	*((float*) &win->base.xdpi) = win->xdpi;
	*((float*) &win->base.ydpi) = win->ydpi;
	*((int*) &win->base.minSwapInterval) = 1;
	*((int*) &win->base.maxSwapInterval) = 1;

	win->base.common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
	win->base.common.version = sizeof(aWindow);
	win->base.common.incRef = cnw_inc_ref;
	win->base.common.decRef = cnw_dec_ref;

	win->base.setSwapInterval = cnw_set_swap_interval;
	win->base.dequeueBuffer_DEPRECATED = cnw_dequeue_buffer0;
	win->base.lockBuffer_DEPRECATED = cnw_lock_buffer0;
	win->base.queueBuffer_DEPRECATED = cnw_queue_buffer0;
	win->base.query = cnw_query;
	win->base.perform = cnw_perform;
	win->base.cancelBuffer_DEPRECATED = cnw_cancel_buffer0;
	win->base.dequeueBuffer = cnw_dequeue_buffer1;
	win->base.queueBuffer = cnw_queue_buffer1;
	win->base.cancelBuffer = cnw_cancel_buffer1;

	pthread_mutex_init(&win->lock, NULL);
	pthread_cond_init(&win->cvar, NULL);

	return 0;
}

void cnw_destroy(CNativeWindow *win) {
	if (win->fb)
		framebuffer_close(win->fb);
	if (win->hwc)
		hwc_close_1(win->hwc);
	if (win->gr)
		gralloc_close(win->gr);
	free(win);
}

CNativeWindow *cnw_create(void) {
	CNativeWindow *win;
	char *x;
	if ((x = getenv("CNWDEBUG")))
		trace_level = atoi(x);
	if (!(win = malloc(sizeof(CNativeWindow))))
		return NULL;
	if (cnw_init(win)) {
		cnw_destroy(win);
		return NULL;
	}
	return win;
}

void cnw_info(CNativeWindow *win, unsigned *w, unsigned *h, unsigned *fmt) {
	*w = win->width;
	*h = win->height;
	*fmt = win->format;
}

