// 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.

// Display.cpp: Implements the egl::Display class, representing the abstract
// display on which graphics are drawn. Implements EGLDisplay.
// [EGL 1.4] section 2.1.2 page 3.

#include "Display.h"

#include "main.h"
#include "libEGL/EGLSurface.h"
#include "libEGL/Context.hpp"
#include "common/Image.hpp"
#include "common/debug.h"
#include "Common/MutexLock.hpp"

#ifdef __ANDROID__
#include <system/window.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <fcntl.h>
#elif defined(__linux__)
#include "Main/libX11.hpp"
#elif defined(__APPLE__)
#include "OSXUtils.hpp"
#endif

#include <algorithm>
#include <vector>
#include <map>

class Guard
{
public:
	explicit Guard(sw::BackoffLock* in) : mMutex(in)
	{
		mMutex->lock();
	}

	~Guard()
	{
		mMutex->unlock();
	}
protected:
	sw::BackoffLock* mMutex;
};

namespace egl
{

Display *Display::get(EGLDisplay dpy)
{
	if(dpy != PRIMARY_DISPLAY && dpy != HEADLESS_DISPLAY)   // We only support the default display
	{
		return nullptr;
	}

	static void *nativeDisplay = nullptr;

	#if defined(__linux__) && !defined(__ANDROID__)
		// Even if the application provides a native display handle, we open (and close) our own connection
		if(!nativeDisplay && dpy != HEADLESS_DISPLAY && libX11 && libX11->XOpenDisplay)
		{
			nativeDisplay = libX11->XOpenDisplay(NULL);
		}
	#endif

	static Display display(nativeDisplay);

	return &display;
}

Display::Display(void *nativeDisplay) : nativeDisplay(nativeDisplay)
{
	mMinSwapInterval = 1;
	mMaxSwapInterval = 1;
}

Display::~Display()
{
	terminate();

	#if defined(__linux__) && !defined(__ANDROID__)
		if(nativeDisplay && libX11->XCloseDisplay)
		{
			libX11->XCloseDisplay((::Display*)nativeDisplay);
		}
	#endif
}

static void cpuid(int registers[4], int info)
{
	#if defined(_WIN32)
		__cpuid(registers, info);
	#else
		__asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
	#endif
}

static bool detectSSE()
{
	int registers[4];
	cpuid(registers, 1);
	return (registers[3] & 0x02000000) != 0;
}

bool Display::initialize()
{
	if(isInitialized())
	{
		return true;
	}

	if(!detectSSE())
	{
		return false;
	}

	mMinSwapInterval = 0;
	mMaxSwapInterval = 4;

	const int samples[] =
	{
		0,
		2,
		4
	};

	const sw::Format renderTargetFormats[] =
	{
	//	sw::FORMAT_A1R5G5B5,
	//  sw::FORMAT_A2R10G10B10,   // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
		sw::FORMAT_A8R8G8B8,
		sw::FORMAT_A8B8G8R8,
		sw::FORMAT_R5G6B5,
	//  sw::FORMAT_X1R5G5B5,      // Has no compatible OpenGL ES renderbuffer format
		sw::FORMAT_X8R8G8B8,
		sw::FORMAT_X8B8G8R8
	};

	const sw::Format depthStencilFormats[] =
	{
		sw::FORMAT_NULL,
	//  sw::FORMAT_D16_LOCKABLE,
		sw::FORMAT_D32,
	//  sw::FORMAT_D15S1,
		sw::FORMAT_D24S8,
		sw::FORMAT_D24X8,
	//  sw::FORMAT_D24X4S4,
		sw::FORMAT_D16,
	//  sw::FORMAT_D32F_LOCKABLE,
	//  sw::FORMAT_D24FS8
	};

	sw::Format currentDisplayFormat = getDisplayFormat();
	ConfigSet configSet;

	for(unsigned int samplesIndex = 0; samplesIndex < sizeof(samples) / sizeof(int); samplesIndex++)
	{
		for(unsigned int formatIndex = 0; formatIndex < sizeof(renderTargetFormats) / sizeof(sw::Format); formatIndex++)
		{
			sw::Format renderTargetFormat = renderTargetFormats[formatIndex];

			for(unsigned int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(sw::Format); depthStencilIndex++)
			{
				sw::Format depthStencilFormat = depthStencilFormats[depthStencilIndex];

				configSet.add(currentDisplayFormat, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, samples[samplesIndex]);
			}
		}
	}

	// Give the sorted configs a unique ID and store them internally
	EGLint index = 1;
	for(ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
	{
		Config configuration = *config;
		configuration.mConfigID = index;
		index++;

		mConfigSet.mSet.insert(configuration);
	}

	if(!isInitialized())
	{
		terminate();

		return false;
	}

	return true;
}

void Display::terminate()
{
	while(!mSurfaceSet.empty())
	{
		destroySurface(*mSurfaceSet.begin());
	}

	while(!mContextSet.empty())
	{
		destroyContext(*mContextSet.begin());
	}

	while(!mSharedImageNameSpace.empty())
	{
		destroySharedImage(reinterpret_cast<EGLImageKHR>((intptr_t)mSharedImageNameSpace.firstName()));
	}
}

bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
{
	return mConfigSet.getConfigs(configs, attribList, configSize, numConfig);
}

bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
{
	const egl::Config *configuration = mConfigSet.get(config);

	switch(attribute)
	{
	case EGL_BUFFER_SIZE:                *value = configuration->mBufferSize;               break;
	case EGL_ALPHA_SIZE:                 *value = configuration->mAlphaSize;                break;
	case EGL_BLUE_SIZE:                  *value = configuration->mBlueSize;                 break;
	case EGL_GREEN_SIZE:                 *value = configuration->mGreenSize;                break;
	case EGL_RED_SIZE:                   *value = configuration->mRedSize;                  break;
	case EGL_DEPTH_SIZE:                 *value = configuration->mDepthSize;                break;
	case EGL_STENCIL_SIZE:               *value = configuration->mStencilSize;              break;
	case EGL_CONFIG_CAVEAT:              *value = configuration->mConfigCaveat;             break;
	case EGL_CONFIG_ID:                  *value = configuration->mConfigID;                 break;
	case EGL_LEVEL:                      *value = configuration->mLevel;                    break;
	case EGL_NATIVE_RENDERABLE:          *value = configuration->mNativeRenderable;         break;
	case EGL_NATIVE_VISUAL_ID:           *value = configuration->mNativeVisualID;           break;
	case EGL_NATIVE_VISUAL_TYPE:         *value = configuration->mNativeVisualType;         break;
	case EGL_SAMPLES:                    *value = configuration->mSamples;                  break;
	case EGL_SAMPLE_BUFFERS:             *value = configuration->mSampleBuffers;            break;
	case EGL_SURFACE_TYPE:               *value = configuration->mSurfaceType;              break;
	case EGL_TRANSPARENT_TYPE:           *value = configuration->mTransparentType;          break;
	case EGL_TRANSPARENT_BLUE_VALUE:     *value = configuration->mTransparentBlueValue;     break;
	case EGL_TRANSPARENT_GREEN_VALUE:    *value = configuration->mTransparentGreenValue;    break;
	case EGL_TRANSPARENT_RED_VALUE:      *value = configuration->mTransparentRedValue;      break;
	case EGL_BIND_TO_TEXTURE_RGB:        *value = configuration->mBindToTextureRGB;         break;
	case EGL_BIND_TO_TEXTURE_RGBA:       *value = configuration->mBindToTextureRGBA;        break;
	case EGL_MIN_SWAP_INTERVAL:          *value = configuration->mMinSwapInterval;          break;
	case EGL_MAX_SWAP_INTERVAL:          *value = configuration->mMaxSwapInterval;          break;
	case EGL_LUMINANCE_SIZE:             *value = configuration->mLuminanceSize;            break;
	case EGL_ALPHA_MASK_SIZE:            *value = configuration->mAlphaMaskSize;            break;
	case EGL_COLOR_BUFFER_TYPE:          *value = configuration->mColorBufferType;          break;
	case EGL_RENDERABLE_TYPE:            *value = configuration->mRenderableType;           break;
	case EGL_MATCH_NATIVE_PIXMAP:        *value = EGL_FALSE; UNIMPLEMENTED();               break;
	case EGL_CONFORMANT:                 *value = configuration->mConformant;               break;
	case EGL_MAX_PBUFFER_WIDTH:          *value = configuration->mMaxPBufferWidth;          break;
	case EGL_MAX_PBUFFER_HEIGHT:         *value = configuration->mMaxPBufferHeight;         break;
	case EGL_MAX_PBUFFER_PIXELS:         *value = configuration->mMaxPBufferPixels;         break;
	case EGL_RECORDABLE_ANDROID:         *value = configuration->mRecordableAndroid;        break;
	case EGL_FRAMEBUFFER_TARGET_ANDROID: *value = configuration->mFramebufferTargetAndroid; break;
	default:
		return false;
	}

	return true;
}

EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList)
{
	const Config *configuration = mConfigSet.get(config);

	if(attribList)
	{
		while(*attribList != EGL_NONE)
		{
			switch(attribList[0])
			{
			case EGL_RENDER_BUFFER:
				switch(attribList[1])
				{
				case EGL_BACK_BUFFER:
					break;
				case EGL_SINGLE_BUFFER:
					return error(EGL_BAD_MATCH, EGL_NO_SURFACE);   // Rendering directly to front buffer not supported
				default:
					return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
				}
				break;
			case EGL_VG_COLORSPACE:
				return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
			case EGL_VG_ALPHA_FORMAT:
				return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
			default:
				return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
			}

			attribList += 2;
		}
	}

	if(hasExistingWindowSurface(window))
	{
		return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
	}

	Surface *surface = new WindowSurface(this, configuration, window);

	if(!surface->initialize())
	{
		surface->release();
		return EGL_NO_SURFACE;
	}

	surface->addRef();
	mSurfaceSet.insert(surface);

	return success(surface);
}

EGLSurface Display::createPBufferSurface(EGLConfig config, const EGLint *attribList)
{
	EGLint width = 0, height = 0;
	EGLenum textureFormat = EGL_NO_TEXTURE;
	EGLenum textureTarget = EGL_NO_TEXTURE;
	EGLBoolean largestPBuffer = EGL_FALSE;
	const Config *configuration = mConfigSet.get(config);

	if(attribList)
	{
		while(*attribList != EGL_NONE)
		{
			switch(attribList[0])
			{
			case EGL_WIDTH:
				width = attribList[1];
				break;
			case EGL_HEIGHT:
				height = attribList[1];
				break;
			case EGL_LARGEST_PBUFFER:
				largestPBuffer = attribList[1];
				break;
			case EGL_TEXTURE_FORMAT:
				switch(attribList[1])
				{
				case EGL_NO_TEXTURE:
				case EGL_TEXTURE_RGB:
				case EGL_TEXTURE_RGBA:
					textureFormat = attribList[1];
					break;
				default:
					return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
				}
				break;
			case EGL_TEXTURE_TARGET:
				switch(attribList[1])
				{
				case EGL_NO_TEXTURE:
				case EGL_TEXTURE_2D:
					textureTarget = attribList[1];
					break;
				default:
					return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
				}
				break;
			case EGL_MIPMAP_TEXTURE:
				if(attribList[1] != EGL_FALSE)
				{
					return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
				}
				break;
			case EGL_VG_COLORSPACE:
				return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
			case EGL_VG_ALPHA_FORMAT:
				return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
			default:
				return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
			}

			attribList += 2;
		}
	}

	if(width < 0 || height < 0)
	{
		return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
	}

	if(width == 0 || height == 0)
	{
		return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
	}

	if((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
	   (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
	{
		return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
	}

	if(!(configuration->mSurfaceType & EGL_PBUFFER_BIT))
	{
		return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
	}

	if((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) ||
	   (textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE))
	{
		return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
	}

	Surface *surface = new PBufferSurface(this, configuration, width, height, textureFormat, textureTarget, largestPBuffer);

	if(!surface->initialize())
	{
		surface->release();
		return EGL_NO_SURFACE;
	}

	surface->addRef();
	mSurfaceSet.insert(surface);

	return success(surface);
}

EGLContext Display::createContext(EGLConfig configHandle, const egl::Context *shareContext, EGLint clientVersion)
{
	const egl::Config *config = mConfigSet.get(configHandle);
	egl::Context *context = nullptr;

	if(clientVersion == 1 && config->mRenderableType & EGL_OPENGL_ES_BIT)
	{
		if(libGLES_CM)
		{
			context = libGLES_CM->es1CreateContext(this, shareContext);
		}
	}
	else if((clientVersion == 2 && config->mRenderableType & EGL_OPENGL_ES2_BIT) ||
	        (clientVersion == 3 && config->mRenderableType & EGL_OPENGL_ES3_BIT))
	{
		if(libGLESv2)
		{
			context = libGLESv2->es2CreateContext(this, shareContext, clientVersion);
		}
	}
	else
	{
		return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
	}

	if(!context)
	{
		return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
	}

	context->addRef();
	mContextSet.insert(context);

	return success(context);
}

EGLSyncKHR Display::createSync(Context *context)
{
	FenceSync *fenceSync = new egl::FenceSync(context);
	Guard lk(&mSyncSetMutex);
	mSyncSet.insert(fenceSync);
	return fenceSync;
}

void Display::destroySurface(egl::Surface *surface)
{
	surface->release();
	mSurfaceSet.erase(surface);

	if(surface == getCurrentDrawSurface())
	{
		setCurrentDrawSurface(nullptr);
	}

	if(surface == getCurrentReadSurface())
	{
		setCurrentReadSurface(nullptr);
	}
}

void Display::destroyContext(egl::Context *context)
{
	context->release();
	mContextSet.erase(context);

	if(context == getCurrentContext())
	{
		setCurrentContext(nullptr);
		setCurrentDrawSurface(nullptr);
		setCurrentReadSurface(nullptr);
	}
}

void Display::destroySync(FenceSync *sync)
{
	{
		Guard lk(&mSyncSetMutex);
		mSyncSet.erase(sync);
	}
	delete sync;
}

bool Display::isInitialized() const
{
	return mConfigSet.size() > 0;
}

bool Display::isValidConfig(EGLConfig config)
{
	return mConfigSet.get(config) != nullptr;
}

bool Display::isValidContext(egl::Context *context)
{
	return mContextSet.find(context) != mContextSet.end();
}

bool Display::isValidSurface(egl::Surface *surface)
{
	return mSurfaceSet.find(surface) != mSurfaceSet.end();
}

bool Display::isValidWindow(EGLNativeWindowType window)
{
	#if defined(_WIN32)
		return IsWindow(window) == TRUE;
	#elif defined(__ANDROID__)
		if(!window)
		{
			ALOGE("%s called with window==NULL %s:%d", __FUNCTION__, __FILE__, __LINE__);
			return false;
		}
		if(static_cast<ANativeWindow*>(window)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC)
		{
			ALOGE("%s called with window==%p bad magic %s:%d", __FUNCTION__, window, __FILE__, __LINE__);
			return false;
		}
		return true;
	#elif defined(__linux__)
		if(nativeDisplay)
		{
			XWindowAttributes windowAttributes;
			Status status = libX11->XGetWindowAttributes((::Display*)nativeDisplay, window, &windowAttributes);

			return status == True;
		}
		return false;
	#elif defined(__APPLE__)
		return sw::OSX::IsValidWindow(window);
	#else
		#error "Display::isValidWindow unimplemented for this platform"
		return false;
	#endif
}

bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
{
	for(SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
	{
		if((*surface)->isWindowSurface())
		{
			if((*surface)->getWindowHandle() == window)
			{
				return true;
			}
		}
	}

	return false;
}

bool Display::isValidSync(FenceSync *sync)
{
	Guard lk(&mSyncSetMutex);
	return mSyncSet.find(sync) != mSyncSet.end();
}

EGLint Display::getMinSwapInterval() const
{
	return mMinSwapInterval;
}

EGLint Display::getMaxSwapInterval() const
{
	return mMaxSwapInterval;
}

void *Display::getNativeDisplay() const
{
	return nativeDisplay;
}

EGLImageKHR Display::createSharedImage(Image *image)
{
	return reinterpret_cast<EGLImageKHR>((intptr_t)mSharedImageNameSpace.allocate(image));
}

bool Display::destroySharedImage(EGLImageKHR image)
{
	GLuint name = (GLuint)reinterpret_cast<intptr_t>(image);
	Image *eglImage = mSharedImageNameSpace.find(name);

	if(!eglImage)
	{
		return false;
	}

	eglImage->destroyShared();
	mSharedImageNameSpace.remove(name);

	return true;
}

Image *Display::getSharedImage(EGLImageKHR image)
{
	GLuint name = (GLuint)reinterpret_cast<intptr_t>(image);
	return mSharedImageNameSpace.find(name);
}

sw::Format Display::getDisplayFormat() const
{
	#if defined(_WIN32)
		HDC deviceContext = GetDC(0);
		unsigned int bpp = ::GetDeviceCaps(deviceContext, BITSPIXEL);
		ReleaseDC(0, deviceContext);

		switch(bpp)
		{
		case 32: return sw::FORMAT_X8R8G8B8;
		case 24: return sw::FORMAT_R8G8B8;
		case 16: return sw::FORMAT_R5G6B5;
		default: UNREACHABLE(bpp);   // Unexpected display mode color depth
		}
	#elif defined(__ANDROID__)
		static const char *const framebuffer[] =
		{
			"/dev/graphics/fb0",
			"/dev/fb0",
			0
		};

		for(int i = 0; framebuffer[i]; i++)
		{
			int fd = open(framebuffer[i], O_RDONLY, 0);

			if(fd != -1)
			{
				struct fb_var_screeninfo info;
				if(ioctl(fd, FBIOGET_VSCREENINFO, &info) >= 0)
				{
					switch(info.bits_per_pixel)
					{
					case 16:
						return sw::FORMAT_R5G6B5;
					case 32:
						if(info.red.length    == 8 && info.red.offset    == 16 &&
						   info.green.length  == 8 && info.green.offset  == 8  &&
						   info.blue.length   == 8 && info.blue.offset   == 0  &&
						   info.transp.length == 0)
						{
							return sw::FORMAT_X8R8G8B8;
						}
						if(info.red.length    == 8 && info.red.offset    == 0  &&
						   info.green.length  == 8 && info.green.offset  == 8  &&
						   info.blue.length   == 8 && info.blue.offset   == 16 &&
						   info.transp.length == 0)
						{
							return sw::FORMAT_X8B8G8R8;
						}
						if(info.red.length    == 8 && info.red.offset    == 16 &&
						   info.green.length  == 8 && info.green.offset  == 8  &&
						   info.blue.length   == 8 && info.blue.offset   == 0  &&
						   info.transp.length == 8 && info.transp.offset == 24)
						{
							return sw::FORMAT_A8R8G8B8;
						}
						if(info.red.length    == 8 && info.red.offset    == 0  &&
						   info.green.length  == 8 && info.green.offset  == 8  &&
						   info.blue.length   == 8 && info.blue.offset   == 16 &&
						   info.transp.length == 8 && info.transp.offset == 24)
						{
							return sw::FORMAT_A8B8G8R8;
						}
						else UNIMPLEMENTED();
					default:
						UNIMPLEMENTED();
					}
				}

				close(fd);
			}
		}

		// No framebuffer device found, or we're in user space
		return sw::FORMAT_X8B8G8R8;
	#elif defined(__linux__)
		if(nativeDisplay)
		{
			Screen *screen = libX11->XDefaultScreenOfDisplay((::Display*)nativeDisplay);
			unsigned int bpp = libX11->XPlanesOfScreen(screen);

			switch(bpp)
			{
			case 32: return sw::FORMAT_X8R8G8B8;
			case 24: return sw::FORMAT_R8G8B8;
			case 16: return sw::FORMAT_R5G6B5;
			default: UNREACHABLE(bpp);   // Unexpected display mode color depth
			}
		}
		else
		{
			return sw::FORMAT_X8R8G8B8;
		}
	#elif defined(__APPLE__)
		return sw::FORMAT_A8B8G8R8;
	#else
		#error "Display::isValidWindow unimplemented for this platform"
	#endif

	return sw::FORMAT_X8R8G8B8;
}

}
