Commit 7b8f3c9b by Geoff Lang Committed by Commit Bot

Encapsulate the thread local storage into an egl::Thread class.

Instead of having separate GetGlobal* functions, interact with the global objects through a single Thread object. This reduces the number of TLS lookups in many EGL functions and allows the Thread object to be passed down to other objects if needed. BUG=angleproject:1618 Change-Id: I1f9a89e8899d637633f4e91fda0e38ac308dd020 Reviewed-on: https://chromium-review.googlesource.com/409637Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent d7490967
//
// Copyright(c) 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Thread.cpp : Defines the Thread class which represents a global EGL thread.
#include "libANGLE/Thread.h"
#include "libANGLE/Context.h"
#include "libANGLE/Error.h"
namespace egl
{
Thread::Thread()
: mError(EGL_SUCCESS),
mAPI(EGL_OPENGL_ES_API),
mDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
mDrawSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
mReadSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
mContext(static_cast<gl::Context *>(EGL_NO_CONTEXT))
{
}
void Thread::setError(const Error &error)
{
mError = error.getCode();
}
EGLint Thread::getError() const
{
return mError;
}
void Thread::setAPI(EGLenum api)
{
mAPI = api;
}
EGLenum Thread::getAPI() const
{
return mAPI;
}
void Thread::setCurrent(Display *display,
Surface *drawSurface,
Surface *readSurface,
gl::Context *context)
{
mDisplay = display;
mDrawSurface = drawSurface;
mReadSurface = readSurface;
mContext = context;
}
Display *Thread::getDisplay() const
{
return mDisplay;
}
Surface *Thread::getDrawSurface() const
{
return mDrawSurface;
}
Surface *Thread::getReadSurface() const
{
return mReadSurface;
}
gl::Context *Thread::getContext() const
{
return mContext;
}
gl::Context *Thread::getValidContext() const
{
if (mContext && mContext->isContextLost())
{
mContext->handleError(gl::Error(GL_OUT_OF_MEMORY, "Context has been lost."));
return nullptr;
}
return mContext;
}
} // namespace egl
//
// Copyright(c) 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Thread.h : Defines the Thread class which represents a global EGL thread.
#ifndef LIBANGLE_THREAD_H_
#define LIBANGLE_THREAD_H_
#include <EGL/egl.h>
namespace gl
{
class Context;
} // namespace gl
namespace egl
{
class Error;
class Display;
class Surface;
class Thread
{
public:
Thread();
void setError(const Error &error);
EGLint getError() const;
void setAPI(EGLenum api);
EGLenum getAPI() const;
void setCurrent(Display *display,
Surface *drawSurface,
Surface *readSurface,
gl::Context *context);
Display *getDisplay() const;
Surface *getDrawSurface() const;
Surface *getReadSurface() const;
gl::Context *getContext() const;
gl::Context *getValidContext() const;
private:
EGLint mError;
EGLenum mAPI;
egl::Display *mDisplay;
egl::Surface *mDrawSurface;
egl::Surface *mReadSurface;
gl::Context *mContext;
};
} // namespace egl
#endif // LIBANGLE_THREAD_H_
...@@ -138,6 +138,8 @@ ...@@ -138,6 +138,8 @@
'libANGLE/Surface.h', 'libANGLE/Surface.h',
'libANGLE/Texture.cpp', 'libANGLE/Texture.cpp',
'libANGLE/Texture.h', 'libANGLE/Texture.h',
'libANGLE/Thread.cpp',
'libANGLE/Thread.h',
'libANGLE/TransformFeedback.cpp', 'libANGLE/TransformFeedback.cpp',
'libANGLE/TransformFeedback.h', 'libANGLE/TransformFeedback.h',
'libANGLE/Uniform.cpp', 'libANGLE/Uniform.cpp',
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Display.h" #include "libANGLE/Display.h"
#include "libANGLE/Texture.h" #include "libANGLE/Texture.h"
#include "libANGLE/Thread.h"
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
#include "libANGLE/validationEGL.h" #include "libANGLE/validationEGL.h"
...@@ -32,9 +33,10 @@ namespace egl ...@@ -32,9 +33,10 @@ namespace egl
EGLint EGLAPIENTRY GetError(void) EGLint EGLAPIENTRY GetError(void)
{ {
EVENT("()"); EVENT("()");
Thread *thread = GetCurrentThread();
EGLint error = GetGlobalError(); EGLint error = thread->getError();
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return error; return error;
} }
...@@ -47,58 +49,58 @@ EGLDisplay EGLAPIENTRY GetDisplay(EGLNativeDisplayType display_id) ...@@ -47,58 +49,58 @@ EGLDisplay EGLAPIENTRY GetDisplay(EGLNativeDisplayType display_id)
EGLBoolean EGLAPIENTRY Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor) EGLBoolean EGLAPIENTRY Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", dpy,
dpy, major, minor); major, minor);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display))
{ {
SetGlobalError(Error(EGL_BAD_DISPLAY)); thread->setError(Error(EGL_BAD_DISPLAY));
return EGL_FALSE; return EGL_FALSE;
} }
Error error = display->initialize(); Error error = display->initialize();
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (major) *major = 1; if (major) *major = 1;
if (minor) *minor = 4; if (minor) *minor = 4;
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean EGLAPIENTRY Terminate(EGLDisplay dpy) EGLBoolean EGLAPIENTRY Terminate(EGLDisplay dpy)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy); EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display))
{ {
SetGlobalError(Error(EGL_BAD_DISPLAY)); thread->setError(Error(EGL_BAD_DISPLAY));
return EGL_FALSE; return EGL_FALSE;
} }
gl::Context *context = GetGlobalContext(); if (display->isValidContext(thread->getContext()))
if (display->isValidContext(context))
{ {
SetGlobalContext(NULL); thread->setCurrent(nullptr, nullptr, nullptr, nullptr);
SetGlobalDisplay(NULL);
} }
display->terminate(); display->terminate();
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
const char *EGLAPIENTRY QueryString(EGLDisplay dpy, EGLint name) const char *EGLAPIENTRY QueryString(EGLDisplay dpy, EGLint name)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
if (!(display == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)) if (!(display == EGL_NO_DISPLAY && name == EGL_EXTENSIONS))
...@@ -106,7 +108,7 @@ const char *EGLAPIENTRY QueryString(EGLDisplay dpy, EGLint name) ...@@ -106,7 +108,7 @@ const char *EGLAPIENTRY QueryString(EGLDisplay dpy, EGLint name)
Error error = ValidateDisplay(display); Error error = ValidateDisplay(display);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return NULL; return NULL;
} }
} }
...@@ -134,32 +136,34 @@ const char *EGLAPIENTRY QueryString(EGLDisplay dpy, EGLint name) ...@@ -134,32 +136,34 @@ const char *EGLAPIENTRY QueryString(EGLDisplay dpy, EGLint name)
result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")"; result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")";
break; break;
default: default:
SetGlobalError(Error(EGL_BAD_PARAMETER)); thread->setError(Error(EGL_BAD_PARAMETER));
return NULL; return NULL;
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return result; return result;
} }
EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, " EVENT(
"EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", "(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, "
dpy, configs, config_size, num_config); "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
dpy, configs, config_size, num_config);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Error error = ValidateDisplay(display); Error error = ValidateDisplay(display);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (!num_config) if (!num_config)
{ {
SetGlobalError(Error(EGL_BAD_PARAMETER)); thread->setError(Error(EGL_BAD_PARAMETER));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -174,28 +178,30 @@ EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint con ...@@ -174,28 +178,30 @@ EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint con
} }
*num_config = static_cast<EGLint>(filteredConfigs.size()); *num_config = static_cast<EGLint>(filteredConfigs.size());
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, " EVENT(
"EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", "(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, "
dpy, attrib_list, configs, config_size, num_config); "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
dpy, attrib_list, configs, config_size, num_config);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Error error = ValidateDisplay(display); Error error = ValidateDisplay(display);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (!num_config) if (!num_config)
{ {
SetGlobalError(Error(EGL_BAD_PARAMETER)); thread->setError(Error(EGL_BAD_PARAMETER));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -211,14 +217,17 @@ EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, E ...@@ -211,14 +217,17 @@ EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, E
} }
*num_config = static_cast<EGLint>(filteredConfigs.size()); *num_config = static_cast<EGLint>(filteredConfigs.size());
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", EVENT(
dpy, config, attribute, value); "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint "
"*value = 0x%0.8p)",
dpy, config, attribute, value);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Config *configuration = static_cast<Config*>(config); Config *configuration = static_cast<Config*>(config);
...@@ -226,24 +235,27 @@ EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint ...@@ -226,24 +235,27 @@ EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint
Error error = ValidateConfig(display, configuration); Error error = ValidateConfig(display, configuration);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (!display->getConfigAttrib(configuration, attribute, value)) if (!display->getConfigAttrib(configuration, attribute, value))
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, " EVENT(
"const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list); "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "
"const EGLint *attrib_list = 0x%0.8p)",
dpy, config, win, attrib_list);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Config *configuration = static_cast<Config*>(config); Config *configuration = static_cast<Config*>(config);
...@@ -252,7 +264,7 @@ EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGL ...@@ -252,7 +264,7 @@ EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGL
Error error = ValidateCreateWindowSurface(display, configuration, win, attributes); Error error = ValidateCreateWindowSurface(display, configuration, win, attributes);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
...@@ -260,7 +272,7 @@ EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGL ...@@ -260,7 +272,7 @@ EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGL
error = display->createWindowSurface(configuration, win, attributes, &surface); error = display->createWindowSurface(configuration, win, attributes, &surface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
...@@ -269,8 +281,11 @@ EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGL ...@@ -269,8 +281,11 @@ EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGL
EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", EVENT(
dpy, config, attrib_list); "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = "
"0x%0.8p)",
dpy, config, attrib_list);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Config *configuration = static_cast<Config*>(config); Config *configuration = static_cast<Config*>(config);
...@@ -279,7 +294,7 @@ EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, co ...@@ -279,7 +294,7 @@ EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, co
Error error = ValidateCreatePbufferSurface(display, configuration, attributes); Error error = ValidateCreatePbufferSurface(display, configuration, attributes);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
...@@ -287,7 +302,7 @@ EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, co ...@@ -287,7 +302,7 @@ EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, co
error = display->createPbufferSurface(configuration, attributes, &surface); error = display->createPbufferSurface(configuration, attributes, &surface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
...@@ -298,6 +313,7 @@ EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGL ...@@ -298,6 +313,7 @@ EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGL
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, " EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
"const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list); "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Config *configuration = static_cast<Config*>(config); Config *configuration = static_cast<Config*>(config);
...@@ -305,19 +321,20 @@ EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGL ...@@ -305,19 +321,20 @@ EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGL
Error error = ValidateConfig(display, configuration); Error error = ValidateConfig(display, configuration);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
UNIMPLEMENTED(); // FIXME UNIMPLEMENTED(); // FIXME
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
EGLBoolean EGLAPIENTRY DestroySurface(EGLDisplay dpy, EGLSurface surface) EGLBoolean EGLAPIENTRY DestroySurface(EGLDisplay dpy, EGLSurface surface)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Surface *eglSurface = static_cast<Surface*>(surface); Surface *eglSurface = static_cast<Surface*>(surface);
...@@ -325,19 +342,19 @@ EGLBoolean EGLAPIENTRY DestroySurface(EGLDisplay dpy, EGLSurface surface) ...@@ -325,19 +342,19 @@ EGLBoolean EGLAPIENTRY DestroySurface(EGLDisplay dpy, EGLSurface surface)
Error error = ValidateSurface(display, eglSurface); Error error = ValidateSurface(display, eglSurface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (surface == EGL_NO_SURFACE) if (surface == EGL_NO_SURFACE)
{ {
SetGlobalError(Error(EGL_BAD_SURFACE)); thread->setError(Error(EGL_BAD_SURFACE));
return EGL_FALSE; return EGL_FALSE;
} }
display->destroySurface((Surface*)surface); display->destroySurface((Surface*)surface);
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -345,6 +362,7 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a ...@@ -345,6 +362,7 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
dpy, surface, attribute, value); dpy, surface, attribute, value);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Surface *eglSurface = (Surface*)surface; Surface *eglSurface = (Surface*)surface;
...@@ -352,13 +370,13 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a ...@@ -352,13 +370,13 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a
Error error = ValidateSurface(display, eglSurface); Error error = ValidateSurface(display, eglSurface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (surface == EGL_NO_SURFACE) if (surface == EGL_NO_SURFACE)
{ {
SetGlobalError(Error(EGL_BAD_SURFACE)); thread->setError(Error(EGL_BAD_SURFACE));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -415,7 +433,7 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a ...@@ -415,7 +433,7 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a
case EGL_POST_SUB_BUFFER_SUPPORTED_NV: case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
if (!display->getExtensions().postSubBuffer) if (!display->getExtensions().postSubBuffer)
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE; return EGL_FALSE;
} }
*value = eglSurface->isPostSubBufferSupported(); *value = eglSurface->isPostSubBufferSupported();
...@@ -423,7 +441,7 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a ...@@ -423,7 +441,7 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a
case EGL_FIXED_SIZE_ANGLE: case EGL_FIXED_SIZE_ANGLE:
if (!display->getExtensions().windowFixedSize) if (!display->getExtensions().windowFixedSize)
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE; return EGL_FALSE;
} }
*value = eglSurface->isFixedSize(); *value = eglSurface->isFixedSize();
...@@ -431,7 +449,7 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a ...@@ -431,7 +449,7 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a
case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE: case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE:
if (!display->getExtensions().flexibleSurfaceCompatibility) if (!display->getExtensions().flexibleSurfaceCompatibility)
{ {
SetGlobalError( thread->setError(
Error(EGL_BAD_ATTRIBUTE, Error(EGL_BAD_ATTRIBUTE,
"EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used without " "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used without "
"EGL_ANGLE_flexible_surface_compatibility support.")); "EGL_ANGLE_flexible_surface_compatibility support."));
...@@ -442,9 +460,9 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a ...@@ -442,9 +460,9 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a
case EGL_SURFACE_ORIENTATION_ANGLE: case EGL_SURFACE_ORIENTATION_ANGLE:
if (!display->getExtensions().surfaceOrientation) if (!display->getExtensions().surfaceOrientation)
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE, thread->setError(Error(EGL_BAD_ATTRIBUTE,
"EGL_SURFACE_ORIENTATION_ANGLE cannot be queried without " "EGL_SURFACE_ORIENTATION_ANGLE cannot be queried without "
"EGL_ANGLE_surface_orientation support.")); "EGL_ANGLE_surface_orientation support."));
return EGL_FALSE; return EGL_FALSE;
} }
*value = eglSurface->getOrientation(); *value = eglSurface->getOrientation();
...@@ -452,19 +470,19 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a ...@@ -452,19 +470,19 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a
case EGL_DIRECT_COMPOSITION_ANGLE: case EGL_DIRECT_COMPOSITION_ANGLE:
if (!display->getExtensions().directComposition) if (!display->getExtensions().directComposition)
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE, thread->setError(Error(EGL_BAD_ATTRIBUTE,
"EGL_DIRECT_COMPOSITION_ANGLE cannot be used without " "EGL_DIRECT_COMPOSITION_ANGLE cannot be used without "
"EGL_ANGLE_direct_composition support.")); "EGL_ANGLE_direct_composition support."));
return EGL_FALSE; return EGL_FALSE;
} }
*value = eglSurface->directComposition(); *value = eglSurface->directComposition();
break; break;
default: default:
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -472,6 +490,7 @@ EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContex ...@@ -472,6 +490,7 @@ EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContex
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, " EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "
"const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list); "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Config *configuration = static_cast<Config*>(config); Config *configuration = static_cast<Config*>(config);
...@@ -481,7 +500,7 @@ EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContex ...@@ -481,7 +500,7 @@ EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContex
Error error = ValidateCreateContext(display, configuration, sharedGLContext, attributes); Error error = ValidateCreateContext(display, configuration, sharedGLContext, attributes);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_CONTEXT; return EGL_NO_CONTEXT;
} }
...@@ -489,17 +508,18 @@ EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContex ...@@ -489,17 +508,18 @@ EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContex
error = display->createContext(configuration, sharedGLContext, attributes, &context); error = display->createContext(configuration, sharedGLContext, attributes, &context);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_CONTEXT; return EGL_NO_CONTEXT;
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return static_cast<EGLContext>(context); return static_cast<EGLContext>(context);
} }
EGLBoolean EGLAPIENTRY DestroyContext(EGLDisplay dpy, EGLContext ctx) EGLBoolean EGLAPIENTRY DestroyContext(EGLDisplay dpy, EGLContext ctx)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
gl::Context *context = static_cast<gl::Context*>(ctx); gl::Context *context = static_cast<gl::Context*>(ctx);
...@@ -507,25 +527,24 @@ EGLBoolean EGLAPIENTRY DestroyContext(EGLDisplay dpy, EGLContext ctx) ...@@ -507,25 +527,24 @@ EGLBoolean EGLAPIENTRY DestroyContext(EGLDisplay dpy, EGLContext ctx)
Error error = ValidateContext(display, context); Error error = ValidateContext(display, context);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (ctx == EGL_NO_CONTEXT) if (ctx == EGL_NO_CONTEXT)
{ {
SetGlobalError(Error(EGL_BAD_CONTEXT)); thread->setError(Error(EGL_BAD_CONTEXT));
return EGL_FALSE; return EGL_FALSE;
} }
if (context == GetGlobalContext()) if (context == thread->getContext())
{ {
SetGlobalDisplay(NULL); thread->setCurrent(nullptr, thread->getDrawSurface(), thread->getReadSurface(), nullptr);
SetGlobalContext(NULL);
} }
display->destroyContext(context); display->destroyContext(context);
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -533,6 +552,7 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r ...@@ -533,6 +552,7 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)", EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
dpy, draw, read, ctx); dpy, draw, read, ctx);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
gl::Context *context = static_cast<gl::Context*>(ctx); gl::Context *context = static_cast<gl::Context*>(ctx);
...@@ -541,13 +561,13 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r ...@@ -541,13 +561,13 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
// error is generated. // error is generated.
if (ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) if (ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
{ {
SetGlobalError(Error(EGL_BAD_MATCH)); thread->setError(Error(EGL_BAD_MATCH));
return EGL_FALSE; return EGL_FALSE;
} }
if (ctx != EGL_NO_CONTEXT && draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE) if (ctx != EGL_NO_CONTEXT && draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE)
{ {
SetGlobalError(Error(EGL_BAD_MATCH)); thread->setError(Error(EGL_BAD_MATCH));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -555,21 +575,21 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r ...@@ -555,21 +575,21 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
// EGL_BAD_MATCH error is generated. // EGL_BAD_MATCH error is generated.
if ((read == EGL_NO_SURFACE) != (draw == EGL_NO_SURFACE)) if ((read == EGL_NO_SURFACE) != (draw == EGL_NO_SURFACE))
{ {
SetGlobalError(Error( thread->setError(Error(
EGL_BAD_MATCH, "read and draw must both be valid surfaces, or both be EGL_NO_SURFACE")); EGL_BAD_MATCH, "read and draw must both be valid surfaces, or both be EGL_NO_SURFACE"));
return EGL_FALSE; return EGL_FALSE;
} }
if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display))
{ {
SetGlobalError(Error(EGL_BAD_DISPLAY, "'dpy' not a valid EGLDisplay handle")); thread->setError(Error(EGL_BAD_DISPLAY, "'dpy' not a valid EGLDisplay handle"));
return EGL_FALSE; return EGL_FALSE;
} }
// EGL 1.5 spec: dpy can be uninitialized if all other parameters are null // EGL 1.5 spec: dpy can be uninitialized if all other parameters are null
if (!display->isInitialized() && (ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) if (!display->isInitialized() && (ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
{ {
SetGlobalError(Error(EGL_NOT_INITIALIZED, "'dpy' not initialized")); thread->setError(Error(EGL_NOT_INITIALIZED, "'dpy' not initialized"));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -578,14 +598,14 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r ...@@ -578,14 +598,14 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
Error error = ValidateContext(display, context); Error error = ValidateContext(display, context);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
} }
if (display->isInitialized() && display->testDeviceLost()) if (display->isInitialized() && display->testDeviceLost())
{ {
SetGlobalError(Error(EGL_CONTEXT_LOST)); thread->setError(Error(EGL_CONTEXT_LOST));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -595,7 +615,7 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r ...@@ -595,7 +615,7 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
Error error = ValidateSurface(display, drawSurface); Error error = ValidateSurface(display, drawSurface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
} }
...@@ -606,7 +626,7 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r ...@@ -606,7 +626,7 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
Error error = ValidateSurface(display, readSurface); Error error = ValidateSurface(display, readSurface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
} }
...@@ -618,7 +638,7 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r ...@@ -618,7 +638,7 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
context->getConfig(), readSurface->getType()); context->getConfig(), readSurface->getType());
if (readCompatError.isError()) if (readCompatError.isError())
{ {
SetGlobalError(readCompatError); thread->setError(readCompatError);
return EGL_FALSE; return EGL_FALSE;
} }
} }
...@@ -634,7 +654,7 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r ...@@ -634,7 +654,7 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
context->getConfig(), drawSurface->getType()); context->getConfig(), drawSurface->getType());
if (drawCompatError.isError()) if (drawCompatError.isError())
{ {
SetGlobalError(drawCompatError); thread->setError(drawCompatError);
return EGL_FALSE; return EGL_FALSE;
} }
} }
...@@ -643,16 +663,12 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r ...@@ -643,16 +663,12 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
Error makeCurrentError = display->makeCurrent(drawSurface, readSurface, context); Error makeCurrentError = display->makeCurrent(drawSurface, readSurface, context);
if (makeCurrentError.isError()) if (makeCurrentError.isError())
{ {
SetGlobalError(makeCurrentError); thread->setError(makeCurrentError);
return EGL_FALSE; return EGL_FALSE;
} }
gl::Context *previousContext = GetGlobalContext(); gl::Context *previousContext = thread->getContext();
thread->setCurrent(display, drawSurface, readSurface, context);
SetGlobalDisplay(display);
SetGlobalDrawSurface(drawSurface);
SetGlobalReadSurface(readSurface);
SetGlobalContext(context);
// Release the surface from the previously-current context, to allow // Release the surface from the previously-current context, to allow
// destroyed surfaces to delete themselves. // destroyed surfaces to delete themselves.
...@@ -661,27 +677,28 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r ...@@ -661,27 +677,28 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
previousContext->releaseSurface(); previousContext->releaseSurface();
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw) EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw)
{ {
EVENT("(EGLint readdraw = %d)", readdraw); EVENT("(EGLint readdraw = %d)", readdraw);
Thread *thread = GetCurrentThread();
if (readdraw == EGL_READ) if (readdraw == EGL_READ)
{ {
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return GetGlobalReadSurface(); return thread->getReadSurface();
} }
else if (readdraw == EGL_DRAW) else if (readdraw == EGL_DRAW)
{ {
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return GetGlobalDrawSurface(); return thread->getDrawSurface();
} }
else else
{ {
SetGlobalError(Error(EGL_BAD_PARAMETER)); thread->setError(Error(EGL_BAD_PARAMETER));
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
} }
...@@ -689,10 +706,11 @@ EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw) ...@@ -689,10 +706,11 @@ EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw)
EGLDisplay EGLAPIENTRY GetCurrentDisplay(void) EGLDisplay EGLAPIENTRY GetCurrentDisplay(void)
{ {
EVENT("()"); EVENT("()");
Thread *thread = GetCurrentThread();
EGLDisplay dpy = GetGlobalDisplay(); EGLDisplay dpy = thread->getDisplay();
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return dpy; return dpy;
} }
...@@ -700,6 +718,7 @@ EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attri ...@@ -700,6 +718,7 @@ EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attri
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
dpy, ctx, attribute, value); dpy, ctx, attribute, value);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
gl::Context *context = static_cast<gl::Context*>(ctx); gl::Context *context = static_cast<gl::Context*>(ctx);
...@@ -707,7 +726,7 @@ EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attri ...@@ -707,7 +726,7 @@ EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attri
Error error = ValidateContext(display, context); Error error = ValidateContext(display, context);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -726,24 +745,25 @@ EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attri ...@@ -726,24 +745,25 @@ EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attri
*value = context->getRenderBuffer(); *value = context->getRenderBuffer();
break; break;
default: default:
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean EGLAPIENTRY WaitGL(void) EGLBoolean EGLAPIENTRY WaitGL(void)
{ {
EVENT("()"); EVENT("()");
Thread *thread = GetCurrentThread();
Display *display = GetGlobalDisplay(); Display *display = thread->getDisplay();
Error error = ValidateDisplay(display); Error error = ValidateDisplay(display);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -752,47 +772,49 @@ EGLBoolean EGLAPIENTRY WaitGL(void) ...@@ -752,47 +772,49 @@ EGLBoolean EGLAPIENTRY WaitGL(void)
error = display->waitClient(); error = display->waitClient();
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean EGLAPIENTRY WaitNative(EGLint engine) EGLBoolean EGLAPIENTRY WaitNative(EGLint engine)
{ {
EVENT("(EGLint engine = %d)", engine); EVENT("(EGLint engine = %d)", engine);
Thread *thread = GetCurrentThread();
Display *display = GetGlobalDisplay(); Display *display = thread->getDisplay();
Error error = ValidateDisplay(display); Error error = ValidateDisplay(display);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (engine != EGL_CORE_NATIVE_ENGINE) if (engine != EGL_CORE_NATIVE_ENGINE)
{ {
SetGlobalError( thread->setError(
Error(EGL_BAD_PARAMETER, "the 'engine' parameter has an unrecognized value")); Error(EGL_BAD_PARAMETER, "the 'engine' parameter has an unrecognized value"));
} }
error = display->waitNative(engine, GetGlobalDrawSurface(), GetGlobalReadSurface()); error = display->waitNative(engine, thread->getDrawSurface(), thread->getReadSurface());
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface) EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Surface *eglSurface = (Surface*)surface; Surface *eglSurface = (Surface*)surface;
...@@ -800,36 +822,37 @@ EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface) ...@@ -800,36 +822,37 @@ EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface)
Error error = ValidateSurface(display, eglSurface); Error error = ValidateSurface(display, eglSurface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (display->testDeviceLost()) if (display->testDeviceLost())
{ {
SetGlobalError(Error(EGL_CONTEXT_LOST)); thread->setError(Error(EGL_CONTEXT_LOST));
return EGL_FALSE; return EGL_FALSE;
} }
if (surface == EGL_NO_SURFACE) if (surface == EGL_NO_SURFACE)
{ {
SetGlobalError(Error(EGL_BAD_SURFACE)); thread->setError(Error(EGL_BAD_SURFACE));
return EGL_FALSE; return EGL_FALSE;
} }
error = eglSurface->swap(); error = eglSurface->swap();
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Surface *eglSurface = static_cast<Surface*>(surface); Surface *eglSurface = static_cast<Surface*>(surface);
...@@ -837,19 +860,19 @@ EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNative ...@@ -837,19 +860,19 @@ EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNative
Error error = ValidateSurface(display, eglSurface); Error error = ValidateSurface(display, eglSurface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (display->testDeviceLost()) if (display->testDeviceLost())
{ {
SetGlobalError(Error(EGL_CONTEXT_LOST)); thread->setError(Error(EGL_CONTEXT_LOST));
return EGL_FALSE; return EGL_FALSE;
} }
UNIMPLEMENTED(); // FIXME UNIMPLEMENTED(); // FIXME
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return 0; return 0;
} }
...@@ -857,6 +880,7 @@ EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNative ...@@ -857,6 +880,7 @@ EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNative
EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Surface *eglSurface = static_cast<Surface*>(surface); Surface *eglSurface = static_cast<Surface*>(surface);
...@@ -864,35 +888,35 @@ EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint b ...@@ -864,35 +888,35 @@ EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint b
Error error = ValidateSurface(display, eglSurface); Error error = ValidateSurface(display, eglSurface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (buffer != EGL_BACK_BUFFER) if (buffer != EGL_BACK_BUFFER)
{ {
SetGlobalError(Error(EGL_BAD_PARAMETER)); thread->setError(Error(EGL_BAD_PARAMETER));
return EGL_FALSE; return EGL_FALSE;
} }
if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT) if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT)
{ {
SetGlobalError(Error(EGL_BAD_SURFACE)); thread->setError(Error(EGL_BAD_SURFACE));
return EGL_FALSE; return EGL_FALSE;
} }
if (eglSurface->getBoundTexture()) if (eglSurface->getBoundTexture())
{ {
SetGlobalError(Error(EGL_BAD_ACCESS)); thread->setError(Error(EGL_BAD_ACCESS));
return EGL_FALSE; return EGL_FALSE;
} }
if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
{ {
SetGlobalError(Error(EGL_BAD_MATCH)); thread->setError(Error(EGL_BAD_MATCH));
return EGL_FALSE; return EGL_FALSE;
} }
gl::Context *context = GetGlobalContext(); gl::Context *context = thread->getContext();
if (context) if (context)
{ {
gl::Texture *textureObject = context->getTargetTexture(GL_TEXTURE_2D); gl::Texture *textureObject = context->getTargetTexture(GL_TEXTURE_2D);
...@@ -900,19 +924,19 @@ EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint b ...@@ -900,19 +924,19 @@ EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint b
if (textureObject->getImmutableFormat()) if (textureObject->getImmutableFormat())
{ {
SetGlobalError(Error(EGL_BAD_MATCH)); thread->setError(Error(EGL_BAD_MATCH));
return EGL_FALSE; return EGL_FALSE;
} }
error = eglSurface->bindTexImage(textureObject, buffer); error = eglSurface->bindTexImage(textureObject, buffer);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -920,6 +944,7 @@ EGLBoolean EGLAPIENTRY SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint ...@@ -920,6 +944,7 @@ EGLBoolean EGLAPIENTRY SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)", EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
dpy, surface, attribute, value); dpy, surface, attribute, value);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Surface *eglSurface = static_cast<Surface*>(surface); Surface *eglSurface = static_cast<Surface*>(surface);
...@@ -927,19 +952,20 @@ EGLBoolean EGLAPIENTRY SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint ...@@ -927,19 +952,20 @@ EGLBoolean EGLAPIENTRY SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint
Error error = ValidateSurface(display, eglSurface); Error error = ValidateSurface(display, eglSurface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
UNIMPLEMENTED(); // FIXME UNIMPLEMENTED(); // FIXME
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Surface *eglSurface = static_cast<Surface*>(surface); Surface *eglSurface = static_cast<Surface*>(surface);
...@@ -947,25 +973,25 @@ EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLin ...@@ -947,25 +973,25 @@ EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLin
Error error = ValidateSurface(display, eglSurface); Error error = ValidateSurface(display, eglSurface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (buffer != EGL_BACK_BUFFER) if (buffer != EGL_BACK_BUFFER)
{ {
SetGlobalError(Error(EGL_BAD_PARAMETER)); thread->setError(Error(EGL_BAD_PARAMETER));
return EGL_FALSE; return EGL_FALSE;
} }
if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT) if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT)
{ {
SetGlobalError(Error(EGL_BAD_SURFACE)); thread->setError(Error(EGL_BAD_SURFACE));
return EGL_FALSE; return EGL_FALSE;
} }
if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
{ {
SetGlobalError(Error(EGL_BAD_MATCH)); thread->setError(Error(EGL_BAD_MATCH));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -976,33 +1002,34 @@ EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLin ...@@ -976,33 +1002,34 @@ EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLin
error = eglSurface->releaseTexImage(buffer); error = eglSurface->releaseTexImage(buffer);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval) EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Error error = ValidateDisplay(display); Error error = ValidateDisplay(display);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
Surface *draw_surface = static_cast<Surface*>(GetGlobalDrawSurface()); Surface *draw_surface = static_cast<Surface *>(thread->getDrawSurface());
if (draw_surface == NULL) if (draw_surface == NULL)
{ {
SetGlobalError(Error(EGL_BAD_SURFACE)); thread->setError(Error(EGL_BAD_SURFACE));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -1011,7 +1038,7 @@ EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval) ...@@ -1011,7 +1038,7 @@ EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval)
draw_surface->setSwapInterval(clampedInterval); draw_surface->setSwapInterval(clampedInterval);
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -1020,33 +1047,35 @@ EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval) ...@@ -1020,33 +1047,35 @@ EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval)
EGLBoolean EGLAPIENTRY BindAPI(EGLenum api) EGLBoolean EGLAPIENTRY BindAPI(EGLenum api)
{ {
EVENT("(EGLenum api = 0x%X)", api); EVENT("(EGLenum api = 0x%X)", api);
Thread *thread = GetCurrentThread();
switch (api) switch (api)
{ {
case EGL_OPENGL_API: case EGL_OPENGL_API:
case EGL_OPENVG_API: case EGL_OPENVG_API:
SetGlobalError(Error(EGL_BAD_PARAMETER)); thread->setError(Error(EGL_BAD_PARAMETER));
return EGL_FALSE; // Not supported by this implementation return EGL_FALSE; // Not supported by this implementation
case EGL_OPENGL_ES_API: case EGL_OPENGL_ES_API:
break; break;
default: default:
SetGlobalError(Error(EGL_BAD_PARAMETER)); thread->setError(Error(EGL_BAD_PARAMETER));
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalAPI(api); thread->setAPI(api);
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
EGLenum EGLAPIENTRY QueryAPI(void) EGLenum EGLAPIENTRY QueryAPI(void)
{ {
EVENT("()"); EVENT("()");
Thread *thread = GetCurrentThread();
EGLenum API = GetGlobalAPI(); EGLenum API = thread->getAPI();
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return API; return API;
} }
...@@ -1055,6 +1084,7 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf ...@@ -1055,6 +1084,7 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, " EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "
"EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
dpy, buftype, buffer, config, attrib_list); dpy, buftype, buffer, config, attrib_list);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Config *configuration = static_cast<Config*>(config); Config *configuration = static_cast<Config*>(config);
...@@ -1063,7 +1093,7 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf ...@@ -1063,7 +1093,7 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf
Error error = ValidateCreatePbufferFromClientBuffer(display, buftype, buffer, configuration, attributes); Error error = ValidateCreatePbufferFromClientBuffer(display, buftype, buffer, configuration, attributes);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
...@@ -1072,7 +1102,7 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf ...@@ -1072,7 +1102,7 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf
&surface); &surface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
...@@ -1082,34 +1112,36 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf ...@@ -1082,34 +1112,36 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf
EGLBoolean EGLAPIENTRY ReleaseThread(void) EGLBoolean EGLAPIENTRY ReleaseThread(void)
{ {
EVENT("()"); EVENT("()");
Thread *thread = GetCurrentThread();
MakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE); MakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean EGLAPIENTRY WaitClient(void) EGLBoolean EGLAPIENTRY WaitClient(void)
{ {
EVENT("()"); EVENT("()");
Thread *thread = GetCurrentThread();
Display *display = GetGlobalDisplay(); Display *display = thread->getDisplay();
Error error = ValidateDisplay(display); Error error = ValidateDisplay(display);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
error = display->waitClient(); error = display->waitClient();
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -1117,10 +1149,11 @@ EGLBoolean EGLAPIENTRY WaitClient(void) ...@@ -1117,10 +1149,11 @@ EGLBoolean EGLAPIENTRY WaitClient(void)
EGLContext EGLAPIENTRY GetCurrentContext(void) EGLContext EGLAPIENTRY GetCurrentContext(void)
{ {
EVENT("()"); EVENT("()");
Thread *thread = GetCurrentThread();
gl::Context *context = GetGlobalContext(); gl::Context *context = thread->getContext();
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return static_cast<EGLContext>(context); return static_cast<EGLContext>(context);
} }
...@@ -1128,32 +1161,40 @@ EGLContext EGLAPIENTRY GetCurrentContext(void) ...@@ -1128,32 +1161,40 @@ EGLContext EGLAPIENTRY GetCurrentContext(void)
EGLSync EGLAPIENTRY CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) EGLSync EGLAPIENTRY CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum type = 0x%X, const EGLint* attrib_list = 0x%0.8p)", dpy, type, attrib_list); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum type = 0x%X, const EGLint* attrib_list = 0x%0.8p)", dpy, type, attrib_list);
Thread *thread = GetCurrentThread();
UNIMPLEMENTED(); UNIMPLEMENTED();
thread->setError(Error(EGL_BAD_DISPLAY, "eglCreateSync unimplemented."));
return EGL_NO_SYNC; return EGL_NO_SYNC;
} }
EGLBoolean EGLAPIENTRY DestroySync(EGLDisplay dpy, EGLSync sync) EGLBoolean EGLAPIENTRY DestroySync(EGLDisplay dpy, EGLSync sync)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p)", dpy, sync); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p)", dpy, sync);
Thread *thread = GetCurrentThread();
UNIMPLEMENTED(); UNIMPLEMENTED();
thread->setError(Error(EGL_BAD_DISPLAY, "eglDestroySync unimplemented."));
return EGL_FALSE; return EGL_FALSE;
} }
EGLint EGLAPIENTRY ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) EGLint EGLAPIENTRY ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X, EGLTime timeout = %d)", dpy, sync, flags, timeout); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X, EGLTime timeout = %d)", dpy, sync, flags, timeout);
Thread *thread = GetCurrentThread();
UNIMPLEMENTED(); UNIMPLEMENTED();
thread->setError(Error(EGL_BAD_DISPLAY, "eglClientWaitSync unimplemented."));
return 0; return 0;
} }
EGLBoolean EGLAPIENTRY GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value) EGLBoolean EGLAPIENTRY GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint attribute = 0x%X, EGLAttrib *value = 0x%0.8p)", dpy, sync, attribute, value); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint attribute = 0x%X, EGLAttrib *value = 0x%0.8p)", dpy, sync, attribute, value);
Thread *thread = GetCurrentThread();
UNIMPLEMENTED(); UNIMPLEMENTED();
thread->setError(Error(EGL_BAD_DISPLAY, "eglSyncAttrib unimplemented."));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -1162,16 +1203,20 @@ EGLImage EGLAPIENTRY CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, ...@@ -1162,16 +1203,20 @@ EGLImage EGLAPIENTRY CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, " EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, "
"EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)", "EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)",
dpy, ctx, target, buffer, attrib_list); dpy, ctx, target, buffer, attrib_list);
Thread *thread = GetCurrentThread();
UNIMPLEMENTED(); UNIMPLEMENTED();
thread->setError(Error(EGL_BAD_DISPLAY, "eglCreateImage unimplemented."));
return EGL_NO_IMAGE; return EGL_NO_IMAGE;
} }
EGLBoolean EGLAPIENTRY DestroyImage(EGLDisplay dpy, EGLImage image) EGLBoolean EGLAPIENTRY DestroyImage(EGLDisplay dpy, EGLImage image)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLImage image = 0x%0.8p)", dpy, image); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLImage image = 0x%0.8p)", dpy, image);
Thread *thread = GetCurrentThread();
UNIMPLEMENTED(); UNIMPLEMENTED();
thread->setError(Error(EGL_BAD_DISPLAY, "eglDestroyImage unimplemented."));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -1179,8 +1224,10 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplay(EGLenum platform, void *native_display ...@@ -1179,8 +1224,10 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplay(EGLenum platform, void *native_display
{ {
EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)", EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
platform, native_display, attrib_list); platform, native_display, attrib_list);
Thread *thread = GetCurrentThread();
UNIMPLEMENTED(); UNIMPLEMENTED();
thread->setError(Error(EGL_BAD_DISPLAY, "eglGetPlatformDisplay unimplemented."));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
...@@ -1188,8 +1235,10 @@ EGLSurface EGLAPIENTRY CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig con ...@@ -1188,8 +1235,10 @@ EGLSurface EGLAPIENTRY CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig con
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_window = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)", EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_window = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
dpy, config, native_window, attrib_list); dpy, config, native_window, attrib_list);
Thread *thread = GetCurrentThread();
UNIMPLEMENTED(); UNIMPLEMENTED();
thread->setError(Error(EGL_BAD_DISPLAY, "eglCreatePlatformWindowSurface unimplemented."));
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
...@@ -1197,22 +1246,27 @@ EGLSurface EGLAPIENTRY CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig con ...@@ -1197,22 +1246,27 @@ EGLSurface EGLAPIENTRY CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig con
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_pixmap = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)", EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_pixmap = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
dpy, config, native_pixmap, attrib_list); dpy, config, native_pixmap, attrib_list);
Thread *thread = GetCurrentThread();
UNIMPLEMENTED(); UNIMPLEMENTED();
thread->setError(Error(EGL_BAD_DISPLAY, "eglCraetePlatformPixmaSurface unimplemented."));
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
EGLBoolean EGLAPIENTRY WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) EGLBoolean EGLAPIENTRY WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X)", dpy, sync, flags); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X)", dpy, sync, flags);
Thread *thread = GetCurrentThread();
UNIMPLEMENTED(); UNIMPLEMENTED();
thread->setError(Error(EGL_BAD_DISPLAY, "eglWaitSync unimplemented."));
return EGL_FALSE; return EGL_FALSE;
} }
__eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *procname) __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *procname)
{ {
EVENT("(const char *procname = \"%s\")", procname); EVENT("(const char *procname = \"%s\")", procname);
Thread *thread = GetCurrentThread();
typedef std::map<std::string, __eglMustCastToProperFunctionPointerType> ProcAddressMap; typedef std::map<std::string, __eglMustCastToProperFunctionPointerType> ProcAddressMap;
auto generateProcAddressMap = []() auto generateProcAddressMap = []()
...@@ -1822,15 +1876,9 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char * ...@@ -1822,15 +1876,9 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *
static const ProcAddressMap procAddressMap = generateProcAddressMap(); static const ProcAddressMap procAddressMap = generateProcAddressMap();
thread->setError(Error(EGL_SUCCESS));
auto iter = procAddressMap.find(procname); auto iter = procAddressMap.find(procname);
if (iter != procAddressMap.end()) return iter != procAddressMap.end() ? iter->second : nullptr;
{
return iter->second;
}
else
{
return nullptr;
}
} }
} }
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "libANGLE/Device.h" #include "libANGLE/Device.h"
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
#include "libANGLE/Stream.h" #include "libANGLE/Stream.h"
#include "libANGLE/Thread.h"
#include "libANGLE/validationEGL.h" #include "libANGLE/validationEGL.h"
#include "common/debug.h" #include "common/debug.h"
...@@ -26,6 +27,7 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa ...@@ -26,6 +27,7 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)", EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)",
dpy, surface, attribute, value); dpy, surface, attribute, value);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Surface *eglSurface = static_cast<Surface*>(surface); Surface *eglSurface = static_cast<Surface*>(surface);
...@@ -33,19 +35,19 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa ...@@ -33,19 +35,19 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa
Error error = ValidateSurface(display, eglSurface); Error error = ValidateSurface(display, eglSurface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (!display->getExtensions().querySurfacePointer) if (!display->getExtensions().querySurfacePointer)
{ {
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_FALSE; return EGL_FALSE;
} }
if (surface == EGL_NO_SURFACE) if (surface == EGL_NO_SURFACE)
{ {
SetGlobalError(Error(EGL_BAD_SURFACE)); thread->setError(Error(EGL_BAD_SURFACE));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -55,24 +57,24 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa ...@@ -55,24 +57,24 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa
case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
if (!display->getExtensions().surfaceD3DTexture2DShareHandle) if (!display->getExtensions().surfaceD3DTexture2DShareHandle)
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE; return EGL_FALSE;
} }
break; break;
case EGL_DXGI_KEYED_MUTEX_ANGLE: case EGL_DXGI_KEYED_MUTEX_ANGLE:
if (!display->getExtensions().keyedMutex) if (!display->getExtensions().keyedMutex)
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE; return EGL_FALSE;
} }
break; break;
default: default:
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE; return EGL_FALSE;
} }
error = eglSurface->querySurfacePointerANGLE(attribute, value); error = eglSurface->querySurfacePointerANGLE(attribute, value);
SetGlobalError(error); thread->setError(error);
return (error.isError() ? EGL_FALSE : EGL_TRUE); return (error.isError() ? EGL_FALSE : EGL_TRUE);
} }
...@@ -81,10 +83,11 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa ...@@ -81,10 +83,11 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa
EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height) EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint x = %d, EGLint y = %d, EGLint width = %d, EGLint height = %d)", dpy, surface, x, y, width, height); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint x = %d, EGLint y = %d, EGLint width = %d, EGLint height = %d)", dpy, surface, x, y, width, height);
Thread *thread = GetCurrentThread();
if (x < 0 || y < 0 || width < 0 || height < 0) if (x < 0 || y < 0 || width < 0 || height < 0)
{ {
SetGlobalError(Error(EGL_BAD_PARAMETER)); thread->setError(Error(EGL_BAD_PARAMETER));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -94,37 +97,37 @@ EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLin ...@@ -94,37 +97,37 @@ EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLin
Error error = ValidateSurface(display, eglSurface); Error error = ValidateSurface(display, eglSurface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (display->testDeviceLost()) if (display->testDeviceLost())
{ {
SetGlobalError(Error(EGL_CONTEXT_LOST)); thread->setError(Error(EGL_CONTEXT_LOST));
return EGL_FALSE; return EGL_FALSE;
} }
if (surface == EGL_NO_SURFACE) if (surface == EGL_NO_SURFACE)
{ {
SetGlobalError(Error(EGL_BAD_SURFACE)); thread->setError(Error(EGL_BAD_SURFACE));
return EGL_FALSE; return EGL_FALSE;
} }
if (!display->getExtensions().postSubBuffer) if (!display->getExtensions().postSubBuffer)
{ {
// Spec is not clear about how this should be handled. // Spec is not clear about how this should be handled.
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
error = eglSurface->postSubBuffer(x, y, width, height); error = eglSurface->postSubBuffer(x, y, width, height);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -133,6 +136,7 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -133,6 +136,7 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
{ {
EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)", EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
platform, native_display, attrib_list); platform, native_display, attrib_list);
Thread *thread = GetCurrentThread();
const ClientExtensions &clientExtensions = Display::getClientExtensions(); const ClientExtensions &clientExtensions = Display::getClientExtensions();
...@@ -141,20 +145,20 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -141,20 +145,20 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
case EGL_PLATFORM_ANGLE_ANGLE: case EGL_PLATFORM_ANGLE_ANGLE:
if (!clientExtensions.platformANGLE) if (!clientExtensions.platformANGLE)
{ {
SetGlobalError(Error(EGL_BAD_PARAMETER)); thread->setError(Error(EGL_BAD_PARAMETER));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
break; break;
case EGL_PLATFORM_DEVICE_EXT: case EGL_PLATFORM_DEVICE_EXT:
if (!clientExtensions.platformDevice) if (!clientExtensions.platformDevice)
{ {
SetGlobalError(Error(EGL_BAD_PARAMETER, "Platform Device extension is not active")); thread->setError(Error(EGL_BAD_PARAMETER, "Platform Device extension is not active"));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
break; break;
default: default:
SetGlobalError(Error(EGL_BAD_CONFIG)); thread->setError(Error(EGL_BAD_CONFIG));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
if (platform == EGL_PLATFORM_ANGLE_ANGLE) if (platform == EGL_PLATFORM_ANGLE_ANGLE)
...@@ -183,7 +187,7 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -183,7 +187,7 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
if (!clientExtensions.platformANGLED3D) if (!clientExtensions.platformANGLED3D)
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
break; break;
...@@ -192,7 +196,7 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -192,7 +196,7 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
if (!clientExtensions.platformANGLEOpenGL) if (!clientExtensions.platformANGLEOpenGL)
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
break; break;
...@@ -200,17 +204,17 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -200,17 +204,17 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE: case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:
if (!clientExtensions.platformANGLENULL) if (!clientExtensions.platformANGLENULL)
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE, thread->setError(Error(EGL_BAD_ATTRIBUTE,
"Display type " "Display type "
"EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE " "EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE "
"requires EGL_ANGLE_platform_angle_null.")); "requires EGL_ANGLE_platform_angle_null."));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
break; break;
default: default:
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
platformType = curAttrib[1]; platformType = curAttrib[1];
break; break;
...@@ -236,8 +240,8 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -236,8 +240,8 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
case EGL_FALSE: case EGL_FALSE:
break; break;
default: default:
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
enableAutoTrimSpecified = true; enableAutoTrimSpecified = true;
break; break;
...@@ -245,7 +249,7 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -245,7 +249,7 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
case EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE: case EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE:
if (!clientExtensions.experimentalPresentPath) if (!clientExtensions.experimentalPresentPath)
{ {
SetGlobalError( thread->setError(
Error(EGL_BAD_ATTRIBUTE, Error(EGL_BAD_ATTRIBUTE,
"EGL_ANGLE_experimental_present_path extension not active")); "EGL_ANGLE_experimental_present_path extension not active"));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
...@@ -257,7 +261,7 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -257,7 +261,7 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
case EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE: case EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE:
break; break;
default: default:
SetGlobalError( thread->setError(
Error(EGL_BAD_ATTRIBUTE, Error(EGL_BAD_ATTRIBUTE,
"Invalid value for EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE")); "Invalid value for EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE"));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
...@@ -279,10 +283,10 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -279,10 +283,10 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
break; break;
default: default:
SetGlobalError(Error(EGL_BAD_ATTRIBUTE, thread->setError(Error(EGL_BAD_ATTRIBUTE,
"Invalid value for " "Invalid value for "
"EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE " "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE "
"attrib")); "attrib"));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
deviceType = curAttrib[1]; deviceType = curAttrib[1];
...@@ -296,14 +300,14 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -296,14 +300,14 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
if (!majorVersionSpecified && minorVersionSpecified) if (!majorVersionSpecified && minorVersionSpecified)
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE && if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE &&
platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{ {
SetGlobalError( thread->setError(
Error(EGL_BAD_ATTRIBUTE, Error(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a device type of " "EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a device type of "
"EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."));
...@@ -312,7 +316,7 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -312,7 +316,7 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
if (enableAutoTrimSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) if (enableAutoTrimSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{ {
SetGlobalError( thread->setError(
Error(EGL_BAD_ATTRIBUTE, Error(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE requires a device type of " "EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE requires a device type of "
"EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."));
...@@ -321,23 +325,23 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -321,23 +325,23 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE, thread->setError(Error(EGL_BAD_ATTRIBUTE,
"EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a device type of " "EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a device type of "
"EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
if (deviceTypeSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE && if (deviceTypeSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE &&
platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
{ {
SetGlobalError( thread->setError(
Error(EGL_BAD_ATTRIBUTE, Error(EGL_BAD_ATTRIBUTE,
"EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE requires a device type of " "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE requires a device type of "
"EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE.")); "EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE."));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return Display::GetDisplayFromAttribs(native_display, return Display::GetDisplayFromAttribs(native_display,
AttributeMap::CreateFromIntArray(attrib_list)); AttributeMap::CreateFromIntArray(attrib_list));
} }
...@@ -346,13 +350,13 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp ...@@ -346,13 +350,13 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp
Device *eglDevice = reinterpret_cast<Device *>(native_display); Device *eglDevice = reinterpret_cast<Device *>(native_display);
if (eglDevice == nullptr || !Device::IsValidDevice(eglDevice)) if (eglDevice == nullptr || !Device::IsValidDevice(eglDevice))
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE, thread->setError(Error(EGL_BAD_ATTRIBUTE,
"native_display should be a valid EGL device if platform equals " "native_display should be a valid EGL device if platform equals "
"EGL_PLATFORM_DEVICE_EXT")); "EGL_PLATFORM_DEVICE_EXT"));
return EGL_NO_DISPLAY; return EGL_NO_DISPLAY;
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return Display::GetDisplayFromDevice(native_display); return Display::GetDisplayFromDevice(native_display);
} }
else else
...@@ -367,11 +371,12 @@ EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribut ...@@ -367,11 +371,12 @@ EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribut
{ {
EVENT("(EGLDeviceEXT device = 0x%0.8p, EGLint attribute = %d, EGLAttrib *value = 0x%0.8p)", EVENT("(EGLDeviceEXT device = 0x%0.8p, EGLint attribute = %d, EGLAttrib *value = 0x%0.8p)",
device, attribute, value); device, attribute, value);
Thread *thread = GetCurrentThread();
Device *dev = static_cast<Device*>(device); Device *dev = static_cast<Device*>(device);
if (dev == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(dev)) if (dev == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(dev))
{ {
SetGlobalError(Error(EGL_BAD_ACCESS)); thread->setError(Error(EGL_BAD_ACCESS));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -380,9 +385,9 @@ EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribut ...@@ -380,9 +385,9 @@ EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribut
Display *owningDisplay = dev->getOwningDisplay(); Display *owningDisplay = dev->getOwningDisplay();
if (owningDisplay != nullptr && !owningDisplay->getExtensions().deviceQuery) if (owningDisplay != nullptr && !owningDisplay->getExtensions().deviceQuery)
{ {
SetGlobalError(Error(EGL_BAD_ACCESS, thread->setError(Error(EGL_BAD_ACCESS,
"Device wasn't created using eglCreateDeviceANGLE, and the Display " "Device wasn't created using eglCreateDeviceANGLE, and the Display "
"that created it doesn't support device querying")); "that created it doesn't support device querying"));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -395,17 +400,17 @@ EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribut ...@@ -395,17 +400,17 @@ EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribut
case EGL_D3D9_DEVICE_ANGLE: case EGL_D3D9_DEVICE_ANGLE:
if (!dev->getExtensions().deviceD3D || dev->getType() != attribute) if (!dev->getExtensions().deviceD3D || dev->getType() != attribute)
{ {
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE; return EGL_FALSE;
} }
error = dev->getDevice(value); error = dev->getDevice(value);
break; break;
default: default:
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(error); thread->setError(error);
return (error.isError() ? EGL_FALSE : EGL_TRUE); return (error.isError() ? EGL_FALSE : EGL_TRUE);
} }
...@@ -414,11 +419,12 @@ const char * EGLAPIENTRY QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name) ...@@ -414,11 +419,12 @@ const char * EGLAPIENTRY QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name)
{ {
EVENT("(EGLDeviceEXT device = 0x%0.8p, EGLint name = %d)", EVENT("(EGLDeviceEXT device = 0x%0.8p, EGLint name = %d)",
device, name); device, name);
Thread *thread = GetCurrentThread();
Device *dev = static_cast<Device*>(device); Device *dev = static_cast<Device*>(device);
if (dev == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(dev)) if (dev == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(dev))
{ {
SetGlobalError(Error(EGL_BAD_DEVICE_EXT)); thread->setError(Error(EGL_BAD_DEVICE_EXT));
return nullptr; return nullptr;
} }
...@@ -429,11 +435,11 @@ const char * EGLAPIENTRY QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name) ...@@ -429,11 +435,11 @@ const char * EGLAPIENTRY QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name)
result = dev->getExtensionString().c_str(); result = dev->getExtensionString().c_str();
break; break;
default: default:
SetGlobalError(Error(EGL_BAD_DEVICE_EXT)); thread->setError(Error(EGL_BAD_DEVICE_EXT));
return nullptr; return nullptr;
} }
SetGlobalError(Error(EGL_SUCCESS)); thread->setError(Error(EGL_SUCCESS));
return result; return result;
} }
...@@ -442,19 +448,20 @@ EGLBoolean EGLAPIENTRY QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, E ...@@ -442,19 +448,20 @@ EGLBoolean EGLAPIENTRY QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, E
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint attribute = %d, EGLAttrib *value = 0x%0.8p)", EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint attribute = %d, EGLAttrib *value = 0x%0.8p)",
dpy, attribute, value); dpy, attribute, value);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Error error = ValidateDisplay(display); Error error = ValidateDisplay(display);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
if (!display->getExtensions().deviceQuery) if (!display->getExtensions().deviceQuery)
{ {
SetGlobalError(Error(EGL_BAD_ACCESS)); thread->setError(Error(EGL_BAD_ACCESS));
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -466,11 +473,11 @@ EGLBoolean EGLAPIENTRY QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, E ...@@ -466,11 +473,11 @@ EGLBoolean EGLAPIENTRY QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, E
break; break;
default: default:
SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); thread->setError(Error(EGL_BAD_ATTRIBUTE));
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(error); thread->setError(error);
return (error.isError() ? EGL_FALSE : EGL_TRUE); return (error.isError() ? EGL_FALSE : EGL_TRUE);
} }
...@@ -484,6 +491,7 @@ ANGLE_EXPORT EGLImageKHR EGLAPIENTRY CreateImageKHR(EGLDisplay dpy, ...@@ -484,6 +491,7 @@ ANGLE_EXPORT EGLImageKHR EGLAPIENTRY CreateImageKHR(EGLDisplay dpy,
"(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, " "(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, "
"EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)", "EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)",
dpy, ctx, target, buffer, attrib_list); dpy, ctx, target, buffer, attrib_list);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
gl::Context *context = static_cast<gl::Context *>(ctx); gl::Context *context = static_cast<gl::Context *>(ctx);
...@@ -492,7 +500,7 @@ ANGLE_EXPORT EGLImageKHR EGLAPIENTRY CreateImageKHR(EGLDisplay dpy, ...@@ -492,7 +500,7 @@ ANGLE_EXPORT EGLImageKHR EGLAPIENTRY CreateImageKHR(EGLDisplay dpy,
Error error = ValidateCreateImageKHR(display, context, target, buffer, attributes); Error error = ValidateCreateImageKHR(display, context, target, buffer, attributes);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_IMAGE; return EGL_NO_IMAGE;
} }
...@@ -500,7 +508,7 @@ ANGLE_EXPORT EGLImageKHR EGLAPIENTRY CreateImageKHR(EGLDisplay dpy, ...@@ -500,7 +508,7 @@ ANGLE_EXPORT EGLImageKHR EGLAPIENTRY CreateImageKHR(EGLDisplay dpy,
error = display->createImage(context, target, buffer, attributes, &image); error = display->createImage(context, target, buffer, attributes, &image);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_IMAGE; return EGL_NO_IMAGE;
} }
...@@ -510,6 +518,7 @@ ANGLE_EXPORT EGLImageKHR EGLAPIENTRY CreateImageKHR(EGLDisplay dpy, ...@@ -510,6 +518,7 @@ ANGLE_EXPORT EGLImageKHR EGLAPIENTRY CreateImageKHR(EGLDisplay dpy,
ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLImage image = 0x%0.8p)", dpy, image); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLImage image = 0x%0.8p)", dpy, image);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
Image *img = static_cast<Image *>(image); Image *img = static_cast<Image *>(image);
...@@ -517,7 +526,7 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroyImageKHR(EGLDisplay dpy, EGLImageKHR ...@@ -517,7 +526,7 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroyImageKHR(EGLDisplay dpy, EGLImageKHR
Error error = ValidateDestroyImageKHR(display, img); Error error = ValidateDestroyImageKHR(display, img);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -534,11 +543,12 @@ ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type, ...@@ -534,11 +543,12 @@ ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type,
"(EGLint device_type = %d, void* native_device = 0x%0.8p, const EGLAttrib* attrib_list = " "(EGLint device_type = %d, void* native_device = 0x%0.8p, const EGLAttrib* attrib_list = "
"0x%0.8p)", "0x%0.8p)",
device_type, native_device, attrib_list); device_type, native_device, attrib_list);
Thread *thread = GetCurrentThread();
Error error = ValidateCreateDeviceANGLE(device_type, native_device, attrib_list); Error error = ValidateCreateDeviceANGLE(device_type, native_device, attrib_list);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_DEVICE_EXT; return EGL_NO_DEVICE_EXT;
} }
...@@ -547,7 +557,7 @@ ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type, ...@@ -547,7 +557,7 @@ ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type,
if (error.isError()) if (error.isError())
{ {
ASSERT(device == nullptr); ASSERT(device == nullptr);
SetGlobalError(error); thread->setError(error);
return EGL_NO_DEVICE_EXT; return EGL_NO_DEVICE_EXT;
} }
...@@ -557,13 +567,14 @@ ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type, ...@@ -557,13 +567,14 @@ ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type,
ANGLE_EXPORT EGLBoolean EGLAPIENTRY ReleaseDeviceANGLE(EGLDeviceEXT device) ANGLE_EXPORT EGLBoolean EGLAPIENTRY ReleaseDeviceANGLE(EGLDeviceEXT device)
{ {
EVENT("(EGLDeviceEXT device = 0x%0.8p)", device); EVENT("(EGLDeviceEXT device = 0x%0.8p)", device);
Thread *thread = GetCurrentThread();
Device *dev = static_cast<Device *>(device); Device *dev = static_cast<Device *>(device);
Error error = ValidateReleaseDeviceANGLE(dev); Error error = ValidateReleaseDeviceANGLE(dev);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -576,6 +587,7 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY ReleaseDeviceANGLE(EGLDeviceEXT device) ...@@ -576,6 +587,7 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY ReleaseDeviceANGLE(EGLDeviceEXT device)
EGLStreamKHR EGLAPIENTRY CreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list) EGLStreamKHR EGLAPIENTRY CreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLAttrib* attrib_list = 0x%0.8p)", dpy, attrib_list); EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLAttrib* attrib_list = 0x%0.8p)", dpy, attrib_list);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list); AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
...@@ -583,7 +595,7 @@ EGLStreamKHR EGLAPIENTRY CreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_li ...@@ -583,7 +595,7 @@ EGLStreamKHR EGLAPIENTRY CreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_li
Error error = ValidateCreateStreamKHR(display, attributes); Error error = ValidateCreateStreamKHR(display, attributes);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_STREAM_KHR; return EGL_NO_STREAM_KHR;
} }
...@@ -591,17 +603,18 @@ EGLStreamKHR EGLAPIENTRY CreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_li ...@@ -591,17 +603,18 @@ EGLStreamKHR EGLAPIENTRY CreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_li
error = display->createStream(attributes, &stream); error = display->createStream(attributes, &stream);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_NO_STREAM_KHR; return EGL_NO_STREAM_KHR;
} }
SetGlobalError(error); thread->setError(error);
return static_cast<EGLStreamKHR>(stream); return static_cast<EGLStreamKHR>(stream);
} }
EGLBoolean EGLAPIENTRY DestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream) EGLBoolean EGLAPIENTRY DestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
Stream *streamObject = static_cast<Stream *>(stream); Stream *streamObject = static_cast<Stream *>(stream);
...@@ -609,12 +622,12 @@ EGLBoolean EGLAPIENTRY DestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream) ...@@ -609,12 +622,12 @@ EGLBoolean EGLAPIENTRY DestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
Error error = ValidateDestroyStreamKHR(display, streamObject); Error error = ValidateDestroyStreamKHR(display, streamObject);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
display->destroyStream(streamObject); display->destroyStream(streamObject);
SetGlobalError(error); thread->setError(error);
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -627,6 +640,7 @@ EGLBoolean EGLAPIENTRY StreamAttribKHR(EGLDisplay dpy, ...@@ -627,6 +640,7 @@ EGLBoolean EGLAPIENTRY StreamAttribKHR(EGLDisplay dpy,
"(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, " "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, "
"EGLint value = 0x%X)", "EGLint value = 0x%X)",
dpy, stream, attribute, value); dpy, stream, attribute, value);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
Stream *streamObject = static_cast<Stream *>(stream); Stream *streamObject = static_cast<Stream *>(stream);
...@@ -634,7 +648,7 @@ EGLBoolean EGLAPIENTRY StreamAttribKHR(EGLDisplay dpy, ...@@ -634,7 +648,7 @@ EGLBoolean EGLAPIENTRY StreamAttribKHR(EGLDisplay dpy,
Error error = ValidateStreamAttribKHR(display, streamObject, attribute, value); Error error = ValidateStreamAttribKHR(display, streamObject, attribute, value);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -650,7 +664,7 @@ EGLBoolean EGLAPIENTRY StreamAttribKHR(EGLDisplay dpy, ...@@ -650,7 +664,7 @@ EGLBoolean EGLAPIENTRY StreamAttribKHR(EGLDisplay dpy,
UNREACHABLE(); UNREACHABLE();
} }
SetGlobalError(error); thread->setError(error);
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -663,6 +677,7 @@ EGLBoolean EGLAPIENTRY QueryStreamKHR(EGLDisplay dpy, ...@@ -663,6 +677,7 @@ EGLBoolean EGLAPIENTRY QueryStreamKHR(EGLDisplay dpy,
"(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, " "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, "
"EGLint value = 0x%0.8p)", "EGLint value = 0x%0.8p)",
dpy, stream, attribute, value); dpy, stream, attribute, value);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
Stream *streamObject = static_cast<Stream *>(stream); Stream *streamObject = static_cast<Stream *>(stream);
...@@ -670,7 +685,7 @@ EGLBoolean EGLAPIENTRY QueryStreamKHR(EGLDisplay dpy, ...@@ -670,7 +685,7 @@ EGLBoolean EGLAPIENTRY QueryStreamKHR(EGLDisplay dpy,
Error error = ValidateQueryStreamKHR(display, streamObject, attribute, value); Error error = ValidateQueryStreamKHR(display, streamObject, attribute, value);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -689,7 +704,7 @@ EGLBoolean EGLAPIENTRY QueryStreamKHR(EGLDisplay dpy, ...@@ -689,7 +704,7 @@ EGLBoolean EGLAPIENTRY QueryStreamKHR(EGLDisplay dpy,
UNREACHABLE(); UNREACHABLE();
} }
SetGlobalError(error); thread->setError(error);
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -702,6 +717,7 @@ EGLBoolean EGLAPIENTRY QueryStreamu64KHR(EGLDisplay dpy, ...@@ -702,6 +717,7 @@ EGLBoolean EGLAPIENTRY QueryStreamu64KHR(EGLDisplay dpy,
"(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, " "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, "
"EGLuint64KHR value = 0x%0.8p)", "EGLuint64KHR value = 0x%0.8p)",
dpy, stream, attribute, value); dpy, stream, attribute, value);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
Stream *streamObject = static_cast<Stream *>(stream); Stream *streamObject = static_cast<Stream *>(stream);
...@@ -709,7 +725,7 @@ EGLBoolean EGLAPIENTRY QueryStreamu64KHR(EGLDisplay dpy, ...@@ -709,7 +725,7 @@ EGLBoolean EGLAPIENTRY QueryStreamu64KHR(EGLDisplay dpy,
Error error = ValidateQueryStreamu64KHR(display, streamObject, attribute, value); Error error = ValidateQueryStreamu64KHR(display, streamObject, attribute, value);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
...@@ -725,13 +741,15 @@ EGLBoolean EGLAPIENTRY QueryStreamu64KHR(EGLDisplay dpy, ...@@ -725,13 +741,15 @@ EGLBoolean EGLAPIENTRY QueryStreamu64KHR(EGLDisplay dpy,
UNREACHABLE(); UNREACHABLE();
} }
SetGlobalError(error); thread->setError(error);
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream) EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
Stream *streamObject = static_cast<Stream *>(stream); Stream *streamObject = static_cast<Stream *>(stream);
gl::Context *context = gl::GetValidGlobalContext(); gl::Context *context = gl::GetValidGlobalContext();
...@@ -739,24 +757,26 @@ EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStr ...@@ -739,24 +757,26 @@ EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStr
Error error = ValidateStreamConsumerGLTextureExternalKHR(display, context, streamObject); Error error = ValidateStreamConsumerGLTextureExternalKHR(display, context, streamObject);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
error = streamObject->createConsumerGLTextureExternal(AttributeMap(), context); error = streamObject->createConsumerGLTextureExternal(AttributeMap(), context);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(error); thread->setError(error);
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean EGLAPIENTRY StreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream) EGLBoolean EGLAPIENTRY StreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
Stream *streamObject = static_cast<Stream *>(stream); Stream *streamObject = static_cast<Stream *>(stream);
gl::Context *context = gl::GetValidGlobalContext(); gl::Context *context = gl::GetValidGlobalContext();
...@@ -764,24 +784,26 @@ EGLBoolean EGLAPIENTRY StreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR str ...@@ -764,24 +784,26 @@ EGLBoolean EGLAPIENTRY StreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR str
Error error = ValidateStreamConsumerAcquireKHR(display, context, streamObject); Error error = ValidateStreamConsumerAcquireKHR(display, context, streamObject);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
error = streamObject->consumerAcquire(); error = streamObject->consumerAcquire();
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(error); thread->setError(error);
return EGL_TRUE; return EGL_TRUE;
} }
EGLBoolean EGLAPIENTRY StreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream) EGLBoolean EGLAPIENTRY StreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream)
{ {
EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream); EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
Stream *streamObject = static_cast<Stream *>(stream); Stream *streamObject = static_cast<Stream *>(stream);
gl::Context *context = gl::GetValidGlobalContext(); gl::Context *context = gl::GetValidGlobalContext();
...@@ -789,18 +811,18 @@ EGLBoolean EGLAPIENTRY StreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR str ...@@ -789,18 +811,18 @@ EGLBoolean EGLAPIENTRY StreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR str
Error error = ValidateStreamConsumerReleaseKHR(display, context, streamObject); Error error = ValidateStreamConsumerReleaseKHR(display, context, streamObject);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
error = streamObject->consumerRelease(); error = streamObject->consumerRelease();
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(error); thread->setError(error);
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -811,6 +833,8 @@ EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy, ...@@ -811,6 +833,8 @@ EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy,
EVENT( EVENT(
"(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLAttrib attrib_list = 0x%0.8p", "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLAttrib attrib_list = 0x%0.8p",
dpy, stream, attrib_list); dpy, stream, attrib_list);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
Stream *streamObject = static_cast<Stream *>(stream); Stream *streamObject = static_cast<Stream *>(stream);
gl::Context *context = gl::GetValidGlobalContext(); gl::Context *context = gl::GetValidGlobalContext();
...@@ -820,18 +844,18 @@ EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy, ...@@ -820,18 +844,18 @@ EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy,
attributes); attributes);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
error = streamObject->createConsumerGLTextureExternal(attributes, context); error = streamObject->createConsumerGLTextureExternal(attributes, context);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(error); thread->setError(error);
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -842,6 +866,8 @@ EGLBoolean EGLAPIENTRY CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, ...@@ -842,6 +866,8 @@ EGLBoolean EGLAPIENTRY CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy,
EVENT( EVENT(
"(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLAttrib attrib_list = 0x%0.8p", "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLAttrib attrib_list = 0x%0.8p",
dpy, stream, attrib_list); dpy, stream, attrib_list);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
Stream *streamObject = static_cast<Stream *>(stream); Stream *streamObject = static_cast<Stream *>(stream);
AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list); AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
...@@ -850,18 +876,18 @@ EGLBoolean EGLAPIENTRY CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, ...@@ -850,18 +876,18 @@ EGLBoolean EGLAPIENTRY CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy,
ValidateCreateStreamProducerD3DTextureNV12ANGLE(display, streamObject, attributes); ValidateCreateStreamProducerD3DTextureNV12ANGLE(display, streamObject, attributes);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
error = streamObject->createProducerD3D11TextureNV12(attributes); error = streamObject->createProducerD3D11TextureNV12(attributes);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(error); thread->setError(error);
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -874,6 +900,8 @@ EGLBoolean EGLAPIENTRY StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, ...@@ -874,6 +900,8 @@ EGLBoolean EGLAPIENTRY StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy,
"(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, void* texture = 0x%0.8p, " "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, void* texture = 0x%0.8p, "
"EGLAttrib attrib_list = 0x%0.8p", "EGLAttrib attrib_list = 0x%0.8p",
dpy, stream, texture, attrib_list); dpy, stream, texture, attrib_list);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
Stream *streamObject = static_cast<Stream *>(stream); Stream *streamObject = static_cast<Stream *>(stream);
AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list); AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
...@@ -881,18 +909,18 @@ EGLBoolean EGLAPIENTRY StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, ...@@ -881,18 +909,18 @@ EGLBoolean EGLAPIENTRY StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy,
Error error = ValidateStreamPostD3DTextureNV12ANGLE(display, streamObject, texture, attributes); Error error = ValidateStreamPostD3DTextureNV12ANGLE(display, streamObject, texture, attributes);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
error = streamObject->postD3D11NV12Texture(texture, attributes); error = streamObject->postD3D11NV12Texture(texture, attributes);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
SetGlobalError(error); thread->setError(error);
return EGL_TRUE; return EGL_TRUE;
} }
...@@ -905,6 +933,7 @@ ANGLE_EXPORT EGLBoolean SwapBuffersWithDamageEXT(EGLDisplay dpy, ...@@ -905,6 +933,7 @@ ANGLE_EXPORT EGLBoolean SwapBuffersWithDamageEXT(EGLDisplay dpy,
"(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint *rects = 0x%0.8p, EGLint " "(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint *rects = 0x%0.8p, EGLint "
"n_rects = %d)", "n_rects = %d)",
dpy, surface, rects, n_rects); dpy, surface, rects, n_rects);
Thread *thread = GetCurrentThread();
Display *display = static_cast<Display *>(dpy); Display *display = static_cast<Display *>(dpy);
Surface *eglSurface = static_cast<Surface *>(surface); Surface *eglSurface = static_cast<Surface *>(surface);
...@@ -912,14 +941,14 @@ ANGLE_EXPORT EGLBoolean SwapBuffersWithDamageEXT(EGLDisplay dpy, ...@@ -912,14 +941,14 @@ ANGLE_EXPORT EGLBoolean SwapBuffersWithDamageEXT(EGLDisplay dpy,
Error error = ValidateSwapBuffersWithDamageEXT(display, eglSurface, rects, n_rects); Error error = ValidateSwapBuffersWithDamageEXT(display, eglSurface, rects, n_rects);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
error = eglSurface->swapWithDamage(rects, n_rects); error = eglSurface->swapWithDamage(rects, n_rects);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); thread->setError(error);
return EGL_FALSE; return EGL_FALSE;
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "libANGLE/Query.h" #include "libANGLE/Query.h"
#include "libANGLE/queryconversions.h" #include "libANGLE/queryconversions.h"
#include "libANGLE/queryutils.h" #include "libANGLE/queryutils.h"
#include "libANGLE/Thread.h"
#include "libANGLE/VertexArray.h" #include "libANGLE/VertexArray.h"
#include "libANGLE/validationES.h" #include "libANGLE/validationES.h"
...@@ -990,10 +991,11 @@ ANGLE_EXPORT void GL_APIENTRY EGLImageTargetTexture2DOES(GLenum target, GLeglIma ...@@ -990,10 +991,11 @@ ANGLE_EXPORT void GL_APIENTRY EGLImageTargetTexture2DOES(GLenum target, GLeglIma
{ {
EVENT("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image); EVENT("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);
Context *context = GetValidGlobalContext(); egl::Thread *thread = egl::GetCurrentThread();
Context *context = thread->getValidContext();
if (context) if (context)
{ {
egl::Display *display = egl::GetGlobalDisplay(); egl::Display *display = thread->getDisplay();
egl::Image *imageObject = reinterpret_cast<egl::Image *>(image); egl::Image *imageObject = reinterpret_cast<egl::Image *>(image);
if (!ValidateEGLImageTargetTexture2DOES(context, display, target, imageObject)) if (!ValidateEGLImageTargetTexture2DOES(context, display, target, imageObject))
{ {
...@@ -1015,10 +1017,11 @@ ANGLE_EXPORT void GL_APIENTRY EGLImageTargetRenderbufferStorageOES(GLenum target ...@@ -1015,10 +1017,11 @@ ANGLE_EXPORT void GL_APIENTRY EGLImageTargetRenderbufferStorageOES(GLenum target
{ {
EVENT("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image); EVENT("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);
Context *context = GetValidGlobalContext(); egl::Thread *thread = egl::GetCurrentThread();
Context *context = thread->getValidContext();
if (context) if (context)
{ {
egl::Display *display = egl::GetGlobalDisplay(); egl::Display *display = thread->getDisplay();
egl::Image *imageObject = reinterpret_cast<egl::Image *>(image); egl::Image *imageObject = reinterpret_cast<egl::Image *>(image);
if (!ValidateEGLImageTargetRenderbufferStorageOES(context, display, target, imageObject)) if (!ValidateEGLImageTargetRenderbufferStorageOES(context, display, target, imageObject))
{ {
......
...@@ -8,229 +8,141 @@ ...@@ -8,229 +8,141 @@
#include "libGLESv2/global_state.h" #include "libGLESv2/global_state.h"
#include "libANGLE/Context.h"
#include "libANGLE/Error.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/platform.h" #include "common/platform.h"
#include "common/tls.h" #include "common/tls.h"
namespace #include "libANGLE/Thread.h"
{
static TLSIndex currentTLS = TLS_INVALID_INDEX;
struct Current namespace gl
{
EGLint error;
EGLenum API;
egl::Display *display;
egl::Surface *drawSurface;
egl::Surface *readSurface;
gl::Context *context;
};
Current *AllocateCurrent()
{
ASSERT(currentTLS != TLS_INVALID_INDEX);
if (currentTLS == TLS_INVALID_INDEX)
{
return NULL;
}
Current *current = new Current();
current->error = EGL_SUCCESS;
current->API = EGL_OPENGL_ES_API;
current->display = reinterpret_cast<egl::Display*>(EGL_NO_DISPLAY);
current->drawSurface = reinterpret_cast<egl::Surface*>(EGL_NO_SURFACE);
current->readSurface = reinterpret_cast<egl::Surface*>(EGL_NO_SURFACE);
current->context = reinterpret_cast<gl::Context*>(EGL_NO_CONTEXT);
if (!SetTLSValue(currentTLS, current))
{
ERR("Could not set thread local storage.");
return NULL;
}
return current;
}
Current *GetCurrentData()
{ {
// Create a TLS index if one has not been created for this DLL
if (currentTLS == TLS_INVALID_INDEX)
{
currentTLS = CreateTLSIndex();
}
Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
// ANGLE issue 488: when the dll is loaded after thread initialization,
// thread local storage (current) might not exist yet.
return (current ? current : AllocateCurrent());
}
#ifdef ANGLE_PLATFORM_WINDOWS Context *GetGlobalContext()
void DeallocateCurrent()
{ {
Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS)); egl::Thread *thread = egl::GetCurrentThread();
SafeDelete(current); return thread->getContext();
SetTLSValue(currentTLS, NULL);
} }
extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID) Context *GetValidGlobalContext()
{ {
switch (reason) egl::Thread *thread = egl::GetCurrentThread();
{ return thread->getValidContext();
case DLL_PROCESS_ATTACH:
currentTLS = CreateTLSIndex();
if (currentTLS == TLS_INVALID_INDEX)
{
return FALSE;
}
AllocateCurrent();
break;
case DLL_THREAD_ATTACH:
AllocateCurrent();
break;
case DLL_THREAD_DETACH:
DeallocateCurrent();
break;
case DLL_PROCESS_DETACH:
DeallocateCurrent();
if (currentTLS != TLS_INVALID_INDEX)
{
DestroyTLSIndex(currentTLS);
currentTLS = TLS_INVALID_INDEX;
}
break;
}
return TRUE;
} }
#endif
} } // namespace gl
namespace gl namespace egl
{ {
Context *GetGlobalContext() namespace
{ {
Current *current = GetCurrentData();
return current->context; static TLSIndex threadTLS = TLS_INVALID_INDEX;
}
Context *GetValidGlobalContext() Thread *AllocateCurrentThread()
{ {
gl::Context *context = GetGlobalContext(); ASSERT(threadTLS != TLS_INVALID_INDEX);
if (context) if (threadTLS == TLS_INVALID_INDEX)
{ {
if (context->isContextLost()) return nullptr;
{
context->handleError(gl::Error(GL_OUT_OF_MEMORY, "Context has been lost."));
return nullptr;
}
else
{
return context;
}
} }
return nullptr;
}
Thread *thread = new Thread();
if (!SetTLSValue(threadTLS, thread))
{
ERR("Could not set thread local storage.");
return nullptr;
}
return thread;
} }
namespace egl } // anonymous namespace
{
void SetGlobalError(const Error &error) Thread *GetCurrentThread()
{ {
Current *current = GetCurrentData(); // Create a TLS index if one has not been created for this DLL
if (threadTLS == TLS_INVALID_INDEX)
current->error = error.getCode(); {
} threadTLS = CreateTLSIndex();
}
EGLint GetGlobalError() Thread *current = static_cast<Thread *>(GetTLSValue(threadTLS));
{
Current *current = GetCurrentData();
return current->error; // ANGLE issue 488: when the dll is loaded after thread initialization,
// thread local storage (current) might not exist yet.
return (current ? current : AllocateCurrentThread());
} }
EGLenum GetGlobalAPI() } // namespace egl
{
Current *current = GetCurrentData();
return current->API;
}
void SetGlobalAPI(EGLenum API) #ifdef ANGLE_PLATFORM_WINDOWS
namespace egl
{ {
Current *current = GetCurrentData();
current->API = API;
}
void SetGlobalDisplay(Display *dpy) namespace
{ {
Current *current = GetCurrentData();
current->display = dpy;
}
Display *GetGlobalDisplay() bool DeallocateCurrentThread()
{ {
Current *current = GetCurrentData(); Thread *thread = static_cast<Thread *>(GetTLSValue(threadTLS));
SafeDelete(thread);
return current->display; return SetTLSValue(threadTLS, nullptr);
} }
void SetGlobalDrawSurface(Surface *surface) bool InitializeProcess()
{ {
Current *current = GetCurrentData(); threadTLS = CreateTLSIndex();
if (threadTLS == TLS_INVALID_INDEX)
{
return false;
}
current->drawSurface = surface; return AllocateCurrentThread() != nullptr;
} }
Surface *GetGlobalDrawSurface() bool TerminateProcess()
{ {
Current *current = GetCurrentData(); if (!DeallocateCurrentThread())
{
return false;
}
return current->drawSurface; if (threadTLS != TLS_INVALID_INDEX)
} {
TLSIndex tlsCopy = threadTLS;
threadTLS = TLS_INVALID_INDEX;
void SetGlobalReadSurface(Surface *surface) if (!DestroyTLSIndex(tlsCopy))
{ {
Current *current = GetCurrentData(); return false;
}
}
current->readSurface = surface; return true;
} }
Surface *GetGlobalReadSurface() } // anonymous namespace
{
Current *current = GetCurrentData();
return current->readSurface; } // namespace egl
}
void SetGlobalContext(gl::Context *context) extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
{ {
Current *current = GetCurrentData(); switch (reason)
{
case DLL_PROCESS_ATTACH:
return static_cast<BOOL>(egl::InitializeProcess());
current->context = context; case DLL_THREAD_ATTACH:
} return static_cast<BOOL>(egl::AllocateCurrentThread() != nullptr);
gl::Context *GetGlobalContext() case DLL_THREAD_DETACH:
{ return static_cast<BOOL>(egl::DeallocateCurrentThread());
Current *current = GetCurrentData();
return current->context; case DLL_PROCESS_DETACH:
} return static_cast<BOOL>(egl::TerminateProcess());
}
return TRUE;
} }
#endif // ANGLE_PLATFORM_WINDOWS
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
#ifndef LIBGLESV2_GLOBALSTATE_H_ #ifndef LIBGLESV2_GLOBALSTATE_H_
#define LIBGLESV2_GLOBALSTATE_H_ #define LIBGLESV2_GLOBALSTATE_H_
#include <EGL/egl.h>
namespace gl namespace gl
{ {
class Context; class Context;
...@@ -18,32 +16,14 @@ class Context; ...@@ -18,32 +16,14 @@ class Context;
Context *GetGlobalContext(); Context *GetGlobalContext();
Context *GetValidGlobalContext(); Context *GetValidGlobalContext();
} } // namespace gl
namespace egl namespace egl
{ {
class Error; class Thread;
class Display;
class Surface;
void SetGlobalError(const Error &error);
EGLint GetGlobalError();
void SetGlobalAPI(EGLenum API);
EGLenum GetGlobalAPI();
void SetGlobalDisplay(Display *dpy);
Display *GetGlobalDisplay();
void SetGlobalDrawSurface(Surface *surface);
Surface *GetGlobalDrawSurface();
void SetGlobalReadSurface(Surface *surface);
Surface *GetGlobalReadSurface();
void SetGlobalContext(gl::Context *context); Thread *GetCurrentThread();
gl::Context *GetGlobalContext();
} } // namespace egl
#endif // LIBGLESV2_GLOBALSTATE_H_ #endif // LIBGLESV2_GLOBALSTATE_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment