// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// 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 "FrameBufferX11.hpp"

#include "libX11.hpp"
#include "Common/Timer.hpp"

#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>

namespace sw
{
	static int (*PreviousXErrorHandler)(Display *display, XErrorEvent *event) = 0;
	static bool shmBadAccess = false;

	// Catches BadAcces errors so we can fall back to not using MIT-SHM
	static int XShmErrorHandler(Display *display, XErrorEvent *event)
	{
		if(event->error_code == BadAccess)
		{
			shmBadAccess = true;
			return 0;
		}
		else
		{
			return PreviousXErrorHandler(display, event);
		}
	}

	FrameBufferX11::FrameBufferX11(Display *display, Window window, int width, int height) : FrameBuffer(width, height, false, false), ownX11(!display), x_display(display), x_window(window)
	{
		if(!x_display)
		{
			x_display = libX11->XOpenDisplay(0);
			assert(x_display);
		}

		XWindowAttributes attribs;
		Status status = libX11->XGetWindowAttributes(display, window, &attribs);
		assert(status == 0);
		int depth = attribs.depth;
		Visual *visual = attribs.visual;

		x_gc = libX11->XCreateGC(x_display, window, 0, nullptr);

		mit_shm = (libX11->XShmQueryExtension && libX11->XShmQueryExtension(x_display) == True);
		if(mit_shm)
		{
			x_image = libX11->XShmCreateImage(x_display, visual, depth, ZPixmap, 0, &shminfo, width, height);

			shminfo.shmid = shmget(IPC_PRIVATE, x_image->bytes_per_line * x_image->height, IPC_CREAT | SHM_R | SHM_W);
			shminfo.shmaddr = x_image->data = (char*)shmat(shminfo.shmid, 0, 0);
			shminfo.readOnly = False;

			PreviousXErrorHandler = libX11->XSetErrorHandler(XShmErrorHandler);
			libX11->XShmAttach(x_display, &shminfo);   // May produce a BadAccess error
			libX11->XSync(x_display, False);
			libX11->XSetErrorHandler(PreviousXErrorHandler);

			if(shmBadAccess)
			{
				mit_shm = false;

				XDestroyImage(x_image);
				shmdt(shminfo.shmaddr);
				shmctl(shminfo.shmid, IPC_RMID, 0);

				shmBadAccess = false;
			}
		}

		if(!mit_shm)
		{
			int bytes_per_line = width * 4;
			int bytes_per_image = height * bytes_per_line;
			char *buffer = (char*)malloc(bytes_per_image);
			memset(buffer, 0, bytes_per_image);

			x_image = libX11->XCreateImage(x_display, visual, depth, ZPixmap, 0, buffer, width, height, 32, bytes_per_line);
			assert(x_image);

			if(!x_image)
			{
				free(buffer);
			}
		}
	}

	FrameBufferX11::~FrameBufferX11()
	{
		if(x_gc)
		{
			libX11->XFreeGC(x_display, x_gc);
		}

		if(!mit_shm)
		{
			XDestroyImage(x_image);
		}
		else
		{
			libX11->XShmDetach(x_display, &shminfo);
			XDestroyImage(x_image);
			shmdt(shminfo.shmaddr);
			shmctl(shminfo.shmid, IPC_RMID, 0);
		}

		if(ownX11)
		{
			libX11->XCloseDisplay(x_display);
		}
	}

	void *FrameBufferX11::lock()
	{
		if(x_image)
		{
			stride = x_image->bytes_per_line;
			framebuffer = x_image->data;
		}

		return framebuffer;
	}

	void FrameBufferX11::unlock()
	{
		framebuffer = nullptr;
	}

	void FrameBufferX11::blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
	{
		copy(source);

		if(!mit_shm)
		{
			libX11->XPutImage(x_display, x_window, x_gc, x_image, 0, 0, 0, 0, width, height);
		}
		else
		{
			libX11->XShmPutImage(x_display, x_window, x_gc, x_image, 0, 0, 0, 0, width, height, False);
		}

		libX11->XSync(x_display, False);

		if(false)   // Draw the framerate on screen
		{
			static double fpsTime = sw::Timer::seconds();
			static int frames = -1;

			double time = sw::Timer::seconds();
			double delta = time - fpsTime;
			frames++;

			static double FPS = 0.0;
			static double maxFPS = 0.0;

			if(delta > 1.0)
			{
				FPS = frames / delta;

				fpsTime = time;
				frames = 0;

				if(FPS > maxFPS)
				{
					maxFPS = FPS;
				}
			}

			char string[256];
			sprintf(string, "FPS: %.2f (max: %.2f)", FPS, maxFPS);
			libX11->XDrawString(x_display, x_window, x_gc, 50, 50, string, strlen(string));
		}
	}
}

// Chromium can be built with USE_X11 && USE_OZONE. In case of pure USE_X11 builds, we can use this path.
// In another case, the decision what framebuffer to create will be done by the FrameBufferFactoryOzone.
#if !defined(USE_OZONE)
NO_SANITIZE_FUNCTION sw::FrameBuffer *createFrameBuffer(void *display, Window window, int width, int height)
{
	return new sw::FrameBufferX11((::Display*)display, window, width, height);
}
#endif
