// SwiftShader Software Renderer
//
// Copyright(c) 2005-2013 TransGaming Inc.
//
// All rights reserved. No part of this software may be copied, distributed, transmitted,
// transcribed, stored in a retrieval system, translated into any human or computer
// language by any means, or disclosed to third parties without the explicit written
// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
// or implied, including but not limited to any patent rights, are granted to you.
//

// 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/Surface.h"
#include "libEGL/Context.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>

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());
    }
}

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 = 0;

	if(clientVersion == 1 && config->mRenderableType & EGL_OPENGL_ES_BIT)
	{
		if(libGLES_CM)
		{
			context = libGLES_CM->es1CreateContext(config, shareContext);
		}
	}
	else if((clientVersion == 2 && config->mRenderableType & EGL_OPENGL_ES2_BIT)
#ifndef __ANDROID__ // Do not allow GLES 3.0 on Android
	     || (clientVersion == 3 && config->mRenderableType & EGL_OPENGL_ES3_BIT)
#endif
	        )
	{
		if(libGLESv2)
		{
			context = libGLESv2->es2CreateContext(config, 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);
}

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);
	}
}

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

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

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;
        }
    #elif defined(__APPLE__)
        return sw::OSX::IsValidWindow(window);
    #else
        #error "Display::isValidWindow unimplemented for this platform"
    #endif

    return false;
}

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;
}

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

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

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

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;
}

}
