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