Apply the Apache 2.0 license.

Change-Id: I4a7aeefedcd2d891093520d5a10ebefadcddb5be
Reviewed-on: https://swiftshader-review.googlesource.com/5320
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libEGL/Surface.cpp b/src/OpenGL/libEGL/Surface.cpp
index 345454f..b1e573b 100644
--- a/src/OpenGL/libEGL/Surface.cpp
+++ b/src/OpenGL/libEGL/Surface.cpp
@@ -1,373 +1,376 @@
-// 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.

-//

-

-// Surface.cpp: Implements the egl::Surface class, representing a drawing surface

-// such as the client area of a window, including any back buffers.

-// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.

-

-#include "Surface.h"

-

-#include "main.h"

-#include "Display.h"

-#include "Texture.hpp"

-#include "common/Image.hpp"

-#include "Context.hpp"

-#include "common/debug.h"

-#include "Main/FrameBuffer.hpp"

-

-#if defined(__linux__) && !defined(__ANDROID__)

-#include "Main/libX11.hpp"

-#elif defined(_WIN32)

-#include <tchar.h>

-#elif defined(__APPLE__)

-#include "OSXUtils.hpp"

-#endif

-

-#include <algorithm>

-

-namespace egl

-{

-

-Surface::Surface(const Display *display, const Config *config) : display(display), config(config)

-{

-	backBuffer = nullptr;

-    depthStencil = nullptr;

-    texture = nullptr;

-

-	width = 0;

-	height = 0;

-	largestPBuffer = EGL_FALSE;

-    pixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio

-    renderBuffer = EGL_BACK_BUFFER;

-    swapBehavior = EGL_BUFFER_PRESERVED;

-	textureFormat = EGL_NO_TEXTURE;

-    textureTarget = EGL_NO_TEXTURE;

-    swapInterval = -1;

-    setSwapInterval(1);

-}

-

-Surface::~Surface()

-{

-    Surface::deleteResources();

-}

-

-bool Surface::initialize()

-{

-	ASSERT(!backBuffer && !depthStencil);

-

-	if(libGLES_CM)

-	{

-		backBuffer = libGLES_CM->createBackBuffer(width, height, config);

-	}

-	else if(libGLESv2)

-	{

-		backBuffer = libGLESv2->createBackBuffer(width, height, config);

-	}

-

-    if(!backBuffer)

-    {

-        ERR("Could not create back buffer");

-        deleteResources();

-        return error(EGL_BAD_ALLOC, false);

-    }

-

-    if(config->mDepthStencilFormat != sw::FORMAT_NULL)

-    {

-		if(libGLES_CM)

-		{

-			depthStencil = libGLES_CM->createDepthStencil(width, height, config->mDepthStencilFormat, config->mSamples, false);

-		}

-		else if(libGLESv2)

-		{

-			depthStencil = libGLESv2->createDepthStencil(width, height, config->mDepthStencilFormat, config->mSamples, false);

-		}

-

-		if(!depthStencil)

-		{

-			ERR("Could not create depth/stencil buffer for surface");

-			deleteResources();

-			return error(EGL_BAD_ALLOC, false);

-		}

-    }

-

-	return true;

-}

-

-void Surface::deleteResources()

-{

-    if(depthStencil)

-    {

-        depthStencil->release();

-        depthStencil = nullptr;

-    }

-

-    if(texture)

-    {

-        texture->releaseTexImage();

-        texture = nullptr;

-    }

-

-	if(backBuffer)

-	{

-		backBuffer->release();

-		backBuffer = nullptr;

-	}

-}

-

-egl::Image *Surface::getRenderTarget()

-{

-    if(backBuffer)

-    {

-        backBuffer->addRef();

-    }

-

-    return backBuffer;

-}

-

-egl::Image *Surface::getDepthStencil()

-{

-    if(depthStencil)

-    {

-        depthStencil->addRef();

-    }

-

-    return depthStencil;

-}

-

-void Surface::setSwapBehavior(EGLenum swapBehavior)

-{

-	this->swapBehavior = swapBehavior;

-}

-

-void Surface::setSwapInterval(EGLint interval)

-{

-    if(swapInterval == interval)

-    {

-        return;

-    }

-

-    swapInterval = interval;

-    swapInterval = std::max(swapInterval, display->getMinSwapInterval());

-    swapInterval = std::min(swapInterval, display->getMaxSwapInterval());

-}

-

-EGLint Surface::getConfigID() const

-{

-    return config->mConfigID;

-}

-

-EGLenum Surface::getSurfaceType() const

-{

-    return config->mSurfaceType;

-}

-

-sw::Format Surface::getInternalFormat() const

-{

-    return config->mRenderTargetFormat;

-}

-

-EGLint Surface::getWidth() const

-{

-    return width;

-}

-

-EGLint Surface::getHeight() const

-{

-    return height;

-}

-

-EGLint Surface::getPixelAspectRatio() const

-{

-    return pixelAspectRatio;

-}

-

-EGLenum Surface::getRenderBuffer() const

-{

-    return renderBuffer;

-}

-

-EGLenum Surface::getSwapBehavior() const

-{

-    return swapBehavior;

-}

-

-EGLenum Surface::getTextureFormat() const

-{

-    return textureFormat;

-}

-

-EGLenum Surface::getTextureTarget() const

-{

-    return textureTarget;

-}

-

-EGLBoolean Surface::getLargestPBuffer() const

-{

-	return largestPBuffer;

-}

-

-void Surface::setBoundTexture(egl::Texture *texture)

-{

-    this->texture = texture;

-}

-

-egl::Texture *Surface::getBoundTexture() const

-{

-    return texture;

-}

-

-WindowSurface::WindowSurface(Display *display, const Config *config, EGLNativeWindowType window)

-    : Surface(display, config), window(window)

-{

-    frameBuffer = nullptr;

-}

-

-WindowSurface::~WindowSurface()

-{

-	WindowSurface::deleteResources();

-}

-

-bool WindowSurface::initialize()

-{

-    ASSERT(!frameBuffer && !backBuffer && !depthStencil);

-

-	return checkForResize();

-}

-

-void WindowSurface::swap()

-{

-	if(backBuffer && frameBuffer)

-    {

-		void *source = backBuffer->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);

-		frameBuffer->flip(source, backBuffer->sw::Surface::getInternalFormat(), backBuffer->getInternalPitchB());

-		backBuffer->unlockInternal();

-

-        checkForResize();

-	}

-}

-

-EGLNativeWindowType WindowSurface::getWindowHandle() const

-{

-    return window;

-}

-

-bool WindowSurface::checkForResize()

-{

-    #if defined(_WIN32)

-		RECT client;

-		if(!GetClientRect(window, &client))

-		{

-			ASSERT(false);

-			return false;

-		}

-

-		int windowWidth = client.right - client.left;

-		int windowHeight = client.bottom - client.top;

-	#elif defined(__ANDROID__)

-		int windowWidth;  window->query(window, NATIVE_WINDOW_WIDTH, &windowWidth);

-		int windowHeight; window->query(window, NATIVE_WINDOW_HEIGHT, &windowHeight);

-	#elif defined(__linux__)

-		XWindowAttributes windowAttributes;

-		libX11->XGetWindowAttributes((::Display*)display->getNativeDisplay(), window, &windowAttributes);

-

-		int windowWidth = windowAttributes.width;

-		int windowHeight = windowAttributes.height;

-	#elif defined(__APPLE__)

-		int windowWidth;

-		int windowHeight;

-		sw::OSX::GetNativeWindowSize(window, windowWidth, windowHeight);

-	#else

-		#error "WindowSurface::checkForResize unimplemented for this platform"

-	#endif

-

-    if((windowWidth != width) || (windowHeight != height))

-    {

-        bool success = reset(windowWidth, windowHeight);

-

-        if(getCurrentDrawSurface() == this)

-        {

-			getCurrentContext()->makeCurrent(this);

-        }

-

-        return success;

-    }

-

-    return true;   // Success

-}

-

-void WindowSurface::deleteResources()

-{

-	delete frameBuffer;

-	frameBuffer = nullptr;

-

-	Surface::deleteResources();

-}

-

-bool WindowSurface::reset(int backBufferWidth, int backBufferHeight)

-{

-	width = backBufferWidth;

-    height = backBufferHeight;

-

-    deleteResources();

-

-    if(window)

-    {

-		if(libGLES_CM)

-		{

-			frameBuffer = libGLES_CM->createFrameBuffer(display->getNativeDisplay(), window, width, height);

-		}

-		else if(libGLESv2)

-		{

-			frameBuffer = libGLESv2->createFrameBuffer(display->getNativeDisplay(), window, width, height);

-		}

-

-		if(!frameBuffer)

-		{

-			ERR("Could not create frame buffer");

-			deleteResources();

-			return error(EGL_BAD_ALLOC, false);

-		}

-    }

-

-	return Surface::initialize();

-}

-

-PBufferSurface::PBufferSurface(Display *display, const Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType, EGLBoolean largestPBuffer)

-    : Surface(display, config)

-{

-	this->width = width;

-	this->height = height;

-	this->largestPBuffer = largestPBuffer;

-}

-

-PBufferSurface::~PBufferSurface()

-{

-	PBufferSurface::deleteResources();

-}

-

-void PBufferSurface::swap()

-{

-	// No effect

-}

-

-EGLNativeWindowType PBufferSurface::getWindowHandle() const

-{

-	UNREACHABLE(-1);   // Should not be called. Only WindowSurface has a window handle.

-

-    return 0;

-}

-

-void PBufferSurface::deleteResources()

-{

-	Surface::deleteResources();

-}

-

-}

+// 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.
+
+// Surface.cpp: Implements the egl::Surface class, representing a drawing surface
+// such as the client area of a window, including any back buffers.
+// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
+
+#include "Surface.h"
+
+#include "main.h"
+#include "Display.h"
+#include "Texture.hpp"
+#include "common/Image.hpp"
+#include "Context.hpp"
+#include "common/debug.h"
+#include "Main/FrameBuffer.hpp"
+
+#if defined(__linux__) && !defined(__ANDROID__)
+#include "Main/libX11.hpp"
+#elif defined(_WIN32)
+#include <tchar.h>
+#elif defined(__APPLE__)
+#include "OSXUtils.hpp"
+#endif
+
+#include <algorithm>
+
+namespace egl
+{
+
+Surface::Surface(const Display *display, const Config *config) : display(display), config(config)
+{
+	backBuffer = nullptr;
+	depthStencil = nullptr;
+	texture = nullptr;
+
+	width = 0;
+	height = 0;
+	largestPBuffer = EGL_FALSE;
+	pixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING);   // FIXME: Determine actual pixel aspect ratio
+	renderBuffer = EGL_BACK_BUFFER;
+	swapBehavior = EGL_BUFFER_PRESERVED;
+	textureFormat = EGL_NO_TEXTURE;
+	textureTarget = EGL_NO_TEXTURE;
+	swapInterval = -1;
+	setSwapInterval(1);
+}
+
+Surface::~Surface()
+{
+	Surface::deleteResources();
+}
+
+bool Surface::initialize()
+{
+	ASSERT(!backBuffer && !depthStencil);
+
+	if(libGLES_CM)
+	{
+		backBuffer = libGLES_CM->createBackBuffer(width, height, config);
+	}
+	else if(libGLESv2)
+	{
+		backBuffer = libGLESv2->createBackBuffer(width, height, config);
+	}
+
+	if(!backBuffer)
+	{
+		ERR("Could not create back buffer");
+		deleteResources();
+		return error(EGL_BAD_ALLOC, false);
+	}
+
+	if(config->mDepthStencilFormat != sw::FORMAT_NULL)
+	{
+		if(libGLES_CM)
+		{
+			depthStencil = libGLES_CM->createDepthStencil(width, height, config->mDepthStencilFormat, config->mSamples, false);
+		}
+		else if(libGLESv2)
+		{
+			depthStencil = libGLESv2->createDepthStencil(width, height, config->mDepthStencilFormat, config->mSamples, false);
+		}
+
+		if(!depthStencil)
+		{
+			ERR("Could not create depth/stencil buffer for surface");
+			deleteResources();
+			return error(EGL_BAD_ALLOC, false);
+		}
+	}
+
+	return true;
+}
+
+void Surface::deleteResources()
+{
+	if(depthStencil)
+	{
+		depthStencil->release();
+		depthStencil = nullptr;
+	}
+
+	if(texture)
+	{
+		texture->releaseTexImage();
+		texture = nullptr;
+	}
+
+	if(backBuffer)
+	{
+		backBuffer->release();
+		backBuffer = nullptr;
+	}
+}
+
+egl::Image *Surface::getRenderTarget()
+{
+	if(backBuffer)
+	{
+		backBuffer->addRef();
+	}
+
+	return backBuffer;
+}
+
+egl::Image *Surface::getDepthStencil()
+{
+	if(depthStencil)
+	{
+		depthStencil->addRef();
+	}
+
+	return depthStencil;
+}
+
+void Surface::setSwapBehavior(EGLenum swapBehavior)
+{
+	this->swapBehavior = swapBehavior;
+}
+
+void Surface::setSwapInterval(EGLint interval)
+{
+	if(swapInterval == interval)
+	{
+		return;
+	}
+
+	swapInterval = interval;
+	swapInterval = std::max(swapInterval, display->getMinSwapInterval());
+	swapInterval = std::min(swapInterval, display->getMaxSwapInterval());
+}
+
+EGLint Surface::getConfigID() const
+{
+	return config->mConfigID;
+}
+
+EGLenum Surface::getSurfaceType() const
+{
+	return config->mSurfaceType;
+}
+
+sw::Format Surface::getInternalFormat() const
+{
+	return config->mRenderTargetFormat;
+}
+
+EGLint Surface::getWidth() const
+{
+	return width;
+}
+
+EGLint Surface::getHeight() const
+{
+	return height;
+}
+
+EGLint Surface::getPixelAspectRatio() const
+{
+	return pixelAspectRatio;
+}
+
+EGLenum Surface::getRenderBuffer() const
+{
+	return renderBuffer;
+}
+
+EGLenum Surface::getSwapBehavior() const
+{
+	return swapBehavior;
+}
+
+EGLenum Surface::getTextureFormat() const
+{
+	return textureFormat;
+}
+
+EGLenum Surface::getTextureTarget() const
+{
+	return textureTarget;
+}
+
+EGLBoolean Surface::getLargestPBuffer() const
+{
+	return largestPBuffer;
+}
+
+void Surface::setBoundTexture(egl::Texture *texture)
+{
+	this->texture = texture;
+}
+
+egl::Texture *Surface::getBoundTexture() const
+{
+	return texture;
+}
+
+WindowSurface::WindowSurface(Display *display, const Config *config, EGLNativeWindowType window)
+	: Surface(display, config), window(window)
+{
+	frameBuffer = nullptr;
+}
+
+WindowSurface::~WindowSurface()
+{
+	WindowSurface::deleteResources();
+}
+
+bool WindowSurface::initialize()
+{
+	ASSERT(!frameBuffer && !backBuffer && !depthStencil);
+
+	return checkForResize();
+}
+
+void WindowSurface::swap()
+{
+	if(backBuffer && frameBuffer)
+	{
+		void *source = backBuffer->lockInternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+		frameBuffer->flip(source, backBuffer->sw::Surface::getInternalFormat(), backBuffer->getInternalPitchB());
+		backBuffer->unlockInternal();
+
+		checkForResize();
+	}
+}
+
+EGLNativeWindowType WindowSurface::getWindowHandle() const
+{
+	return window;
+}
+
+bool WindowSurface::checkForResize()
+{
+	#if defined(_WIN32)
+		RECT client;
+		if(!GetClientRect(window, &client))
+		{
+			ASSERT(false);
+			return false;
+		}
+
+		int windowWidth = client.right - client.left;
+		int windowHeight = client.bottom - client.top;
+	#elif defined(__ANDROID__)
+		int windowWidth;  window->query(window, NATIVE_WINDOW_WIDTH, &windowWidth);
+		int windowHeight; window->query(window, NATIVE_WINDOW_HEIGHT, &windowHeight);
+	#elif defined(__linux__)
+		XWindowAttributes windowAttributes;
+		libX11->XGetWindowAttributes((::Display*)display->getNativeDisplay(), window, &windowAttributes);
+
+		int windowWidth = windowAttributes.width;
+		int windowHeight = windowAttributes.height;
+	#elif defined(__APPLE__)
+		int windowWidth;
+		int windowHeight;
+		sw::OSX::GetNativeWindowSize(window, windowWidth, windowHeight);
+	#else
+		#error "WindowSurface::checkForResize unimplemented for this platform"
+	#endif
+
+	if((windowWidth != width) || (windowHeight != height))
+	{
+		bool success = reset(windowWidth, windowHeight);
+
+		if(getCurrentDrawSurface() == this)
+		{
+			getCurrentContext()->makeCurrent(this);
+		}
+
+		return success;
+	}
+
+	return true;   // Success
+}
+
+void WindowSurface::deleteResources()
+{
+	delete frameBuffer;
+	frameBuffer = nullptr;
+
+	Surface::deleteResources();
+}
+
+bool WindowSurface::reset(int backBufferWidth, int backBufferHeight)
+{
+	width = backBufferWidth;
+	height = backBufferHeight;
+
+	deleteResources();
+
+	if(window)
+	{
+		if(libGLES_CM)
+		{
+			frameBuffer = libGLES_CM->createFrameBuffer(display->getNativeDisplay(), window, width, height);
+		}
+		else if(libGLESv2)
+		{
+			frameBuffer = libGLESv2->createFrameBuffer(display->getNativeDisplay(), window, width, height);
+		}
+
+		if(!frameBuffer)
+		{
+			ERR("Could not create frame buffer");
+			deleteResources();
+			return error(EGL_BAD_ALLOC, false);
+		}
+	}
+
+	return Surface::initialize();
+}
+
+PBufferSurface::PBufferSurface(Display *display, const Config *config, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType, EGLBoolean largestPBuffer)
+	: Surface(display, config)
+{
+	this->width = width;
+	this->height = height;
+	this->largestPBuffer = largestPBuffer;
+}
+
+PBufferSurface::~PBufferSurface()
+{
+	PBufferSurface::deleteResources();
+}
+
+void PBufferSurface::swap()
+{
+	// No effect
+}
+
+EGLNativeWindowType PBufferSurface::getWindowHandle() const
+{
+	UNREACHABLE(-1);   // Should not be called. Only WindowSurface has a window handle.
+
+	return 0;
+}
+
+void PBufferSurface::deleteResources()
+{
+	Surface::deleteResources();
+}
+
+}