Commit e70f6aa6 by James Darpinian Committed by Commit Bot

ANGLE_platform_angle_device_context_volatile_* extensions

Change from Kimmo Kinnunen downstream: https://bugs.webkit.org/show_bug.cgi?id=216106 Add two extensions for EAGL and CGL backends to declare the underlying platform context being "volatile". It means that the thread-global current context is being modified behind ANGLE. If ANGLE context is marked volatile for a particular API, it will sync the underlying context for every EGL function that needs the context. Most intuitive use is for the client to call eglMakeCurrent before calling any gl function if the client knowns the platform state might be dirty. Implement eglReleaseThread for EAGL and CGL backends. Releasing thread will unset the platform current context. Fix a bug of omitting EGL_ANGLE_device_eagl from being advertised. Bug: angleproject:5104 Change-Id: I1ec98ad35bc0caada23556ae8697fdef20f65b1a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2486548 Commit-Queue: James Darpinian <jdarpinian@chromium.org> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 45881ab3
Name
ANGLE_platform_angle_device_context_volatile_cgl
Name Strings
EGL_ANGLE_platform_angle_device_context_volatile_cgl
Contributors
Kimmo Kinnunen, Apple
Kenneth Russell, Google
Contacts
Kimmo Kinnunen, Apple (kkinnunen 'at' apple 'dot' org)
Kenneth Russell, Google (kbr 'at' chromium 'dot' org)
Status
Draft
Version
Version 1, 2020-09-30
Number
EGL Extension XXX
Extension Type
EGL client extension
Dependencies
Requires ANGLE_platform_angle.
Overview
This extension allows the client to request a Display that internally
is able to function even if client changes current CGL context of the
thread. Requesting a volatile device context contexts may impact performance.
The extension is useful for using EGL in a library that cannot guarantee
which platform APIs its clients will use.
New Types
None
New Procedures and Functions
None
New Tokens
Accepted as an attribute name in the <attrib_list> argument of
eglGetPlatformDisplayEXT:
EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_CGL_ANGLE 0x34A3
Additions to the EGL Specification
None.
New Behavior
To request a display that internally supports the feature,
use the attribute EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_CGL_ANGLE.
EGL_TRUE enables volatile CGL device context and EGL_FALSE disables it.
Any value other than these will result in an error.
The default value for EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_CGL_ANGLE
is EGL_FALSE.
When the device context of the display is set as volatile CGL, then
each EGL function will change the current CGL context state accordingly
to use the internal device context, if needed. If the internal device context
is not using CGL, the property has no effect.
Calls to OpenGL or OpenGL ES functions will not ensure the underlying device
context is correct. If the state of the current CGL context is unknown,
clients should call MakeCurrent to ensure that the internal device
context is made current.
Issues
None
Revision History
Version 1, 2020-09-30 (Kimmo Kinnunen)
- Initial draft
Name
ANGLE_platform_angle_device_context_volatile_eagl
Name Strings
EGL_ANGLE_platform_angle_device_context_volatile_eagl
Contributors
Kimmo Kinnunen, Apple
Kenneth Russell, Google
Contacts
Kimmo Kinnunen, Apple (kkinnunen 'at' apple 'dot' org)
Kenneth Russell, Google (kbr 'at' chromium 'dot' org)
Status
Draft
Version
Version 1, 2020-09-30
Number
EGL Extension XXX
Extension Type
EGL client extension
Dependencies
Requires ANGLE_platform_angle.
Overview
This extension allows the client to request a Display that internally
is able to function even if client changes current EAGL context of the
thread. Requesting a volatile device context contexts may impact performance.
The extension is useful for using EGL in a library that cannot guarantee
which platform APIs its clients will use.
New Types
None
New Procedures and Functions
None
New Tokens
Accepted as an attribute name in the <attrib_list> argument of
eglGetPlatformDisplayEXT:
EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_EAGL_ANGLE 0x34A2
Additions to the EGL Specification
None.
New Behavior
To request a display that internally supports the feature,
use the attribute EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_EAGL_ANGLE.
EGL_TRUE enables volatile EAGL device context and EGL_FALSE disables it.
Any value other than these will result in an error.
The default value for EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_EAGL_ANGLE
is EGL_FALSE.
When the device context of the display is set as volatile EAGL, then
each EGL function will change the current EAGL context state accordingly
to use the internal device context, if needed. If the internal device context
is not using EAGL, the property has no effect.
Calls to OpenGL or OpenGL ES functions will not ensure the underlying device
context is correct. If the state of the current EAGL context is unknown,
clients should call MakeCurrent to ensure that the internal device
context is made current.
Issues
None
Revision History
Version 1, 2020-09-30 (Kimmo Kinnunen)
- Initial draft
......@@ -116,6 +116,16 @@
#define EGL_PLATFORM_ANGLE_CONTEXT_VIRTUALIZATION_ANGLE 0x3481
#endif /* EGL_ANGLE_platform_angle_context_virtualization */
#ifndef EGL_ANGLE_platform_angle_device_context_volatile_eagl
#define EGL_ANGLE_platform_angle_device_context_volatile_eagl 1
#define EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_EAGL_ANGLE 0x34A2
#endif /* EGL_ANGLE_platform_angle_device_context_volatile_eagl */
#ifndef EGL_ANGLE_platform_angle_device_context_volatile_cgl
#define EGL_ANGLE_platform_angle_device_context_volatile_cgl 1
#define EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_CGL_ANGLE 0x34A3
#endif /* EGL_ANGLE_platform_angle_device_context_volatile_cgl */
#ifndef EGL_ANGLE_x11_visual
#define EGL_ANGLE_x11_visual
#define EGL_X11_VISUAL_ID_ANGLE 0x33A3
......
......@@ -1439,6 +1439,8 @@ std::vector<std::string> DeviceExtensions::getStrings() const
// | Extension name | Supported flag | Output vector |
InsertExtensionString("EGL_ANGLE_device_d3d", deviceD3D, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_cgl", deviceCGL, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_eagl", deviceEAGL, &extensionStrings);
// clang-format on
return extensionStrings;
......@@ -1466,6 +1468,8 @@ std::vector<std::string> ClientExtensions::getStrings() const
InsertExtensionString("EGL_ANGLE_platform_angle_vulkan", platformANGLEVulkan, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_metal", platformANGLEMetal, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_angle_context_virtualization", platformANGLEContextVirtualization, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_device_context_volatile_eagl", platformANGLEDeviceContextVolatileEagl, &extensionStrings);
InsertExtensionString("EGL_ANGLE_platform_device_context_volatile_cgl", platformANGLEDeviceContextVolatileCgl, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_creation", deviceCreation, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_creation_d3d11", deviceCreationD3D11, &extensionStrings);
InsertExtensionString("EGL_ANGLE_x11_visual", x11Visual, &extensionStrings);
......
......@@ -1202,6 +1202,12 @@ struct ClientExtensions
// EGL_ANGLE_platform_angle_context_virtualization
bool platformANGLEContextVirtualization = false;
// EGL_ANGLE_platform_angle_device_context_volatile_eagl
bool platformANGLEDeviceContextVolatileEagl = false;
// EGL_ANGLE_platform_angle_device_context_volatile_cgl
bool platformANGLEDeviceContextVolatileCgl = false;
// EGL_ANGLE_device_creation
bool deviceCreation = false;
......
......@@ -938,6 +938,16 @@ Error Display::terminate(const Thread *thread)
return NoError();
}
Error Display::prepareForCall()
{
return mImplementation->prepareForCall();
}
Error Display::releaseThread()
{
return mImplementation->releaseThread();
}
std::vector<const Config *> Display::getConfigs(const egl::AttributeMap &attribs) const
{
return mConfigSet.filter(attribs);
......@@ -1619,6 +1629,15 @@ static ClientExtensions GenerateClientExtensions()
extensions.platformANGLEDeviceTypeEGLANGLE = true;
#endif
#if (defined(ANGLE_PLATFORM_IOS) && !defined(ANGLE_PLATFORM_MACCATALYST)) || \
(defined(ANGLE_PLATFORM_MACCATALYST) && defined(ANGLE_CPU_ARM64))
extensions.platformANGLEDeviceContextVolatileEagl = true;
#endif
#if defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_MACCATALYST)
extensions.platformANGLEDeviceContextVolatileCgl = true;
#endif
extensions.clientGetAllProcAddresses = true;
extensions.debug = true;
extensions.explicitContext = true;
......
......@@ -116,6 +116,13 @@ class Display final : public LabeledObject,
Error initialize();
Error terminate(const Thread *thread);
// Called before all display state dependent EGL functions. Backends can set up, for example,
// thread-specific backend state through this function. Not called for functions that do not
// need the state.
Error prepareForCall();
// Called on eglReleaseThread. Backends can tear down thread-specific backend state through
// this function.
Error releaseThread();
static Display *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap);
static Display *GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay,
......
......@@ -23,6 +23,16 @@ DisplayImpl::~DisplayImpl()
ASSERT(mState.surfaceSet.empty());
}
egl::Error DisplayImpl::prepareForCall()
{
return egl::NoError();
}
egl::Error DisplayImpl::releaseThread()
{
return egl::NoError();
}
const egl::DisplayExtensions &DisplayImpl::getExtensions() const
{
if (!mExtensionsInitialized)
......
......@@ -68,6 +68,8 @@ class DisplayImpl : public EGLImplFactory, public angle::Subject
virtual egl::Error initialize(egl::Display *display) = 0;
virtual void terminate() = 0;
virtual egl::Error prepareForCall();
virtual egl::Error releaseThread();
virtual egl::Error makeCurrent(egl::Display *display,
egl::Surface *drawSurface,
......
......@@ -10,6 +10,7 @@
#define LIBANGLE_RENDERER_GL_CGL_DISPLAYCGL_H_
#include <thread>
#include <unordered_set>
#include "libANGLE/renderer/gl/DisplayGL.h"
......@@ -43,6 +44,8 @@ class DisplayCGL : public DisplayGL
egl::Error initialize(egl::Display *display) override;
void terminate() override;
egl::Error prepareForCall() override;
egl::Error releaseThread() override;
egl::Error makeCurrent(egl::Display *display,
egl::Surface *drawSurface,
......@@ -115,7 +118,7 @@ class DisplayCGL : public DisplayGL
egl::Display *mEGLDisplay;
CGLContextObj mContext;
std::unordered_map<std::thread::id, CGLContextObj> mCurrentContexts;
std::unordered_set<std::thread::id> mThreadsWithCurrentContext;
CGLPixelFormatObj mPixelFormat;
bool mSupportsGPUSwitching;
uint64_t mCurrentGPUID;
......@@ -125,6 +128,7 @@ class DisplayCGL : public DisplayGL
// is unref'd for the last time, this is set to the time of that last unref. If it isn't
// activated again in 10 seconds, the discrete GPU pixel format is deleted.
double mLastDiscreteGPUUnrefTime;
bool mDeviceContextIsVolatile = false;
};
} // namespace rx
......
......@@ -198,9 +198,11 @@ egl::Error DisplayCGL::initialize(egl::Display *display)
mCurrentGPUID = angle::GetGpuIDFromDisplayID(kCGDirectMainDisplay);
}
CGLSetCurrentContext(mContext);
mCurrentContexts[std::this_thread::get_id()] = mContext;
if (CGLSetCurrentContext(mContext) != kCGLNoError)
{
return egl::EglNotInitialized() << "Could not make the CGL context current.";
}
mThreadsWithCurrentContext.insert(std::this_thread::get_id());
// There is no equivalent getProcAddress in CGL so we open the dylib directly
void *handle = dlopen(kDefaultOpenGLDylibName, RTLD_NOW);
......@@ -224,6 +226,10 @@ egl::Error DisplayCGL::initialize(egl::Display *display)
return egl::EglNotInitialized() << "OpenGL ES 2.0 is not supportable.";
}
auto &attributes = display->getAttributeMap();
mDeviceContextIsVolatile =
attributes.get(EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_CGL_ANGLE, GL_FALSE);
return DisplayGL::initialize(display);
}
......@@ -237,12 +243,12 @@ void DisplayCGL::terminate()
CGLDestroyPixelFormat(mPixelFormat);
mPixelFormat = nullptr;
}
mCurrentContexts.clear();
if (mContext != nullptr)
{
CGLSetCurrentContext(nullptr);
CGLDestroyContext(mContext);
mContext = nullptr;
mThreadsWithCurrentContext.clear();
}
if (mDiscreteGPUPixelFormat != nullptr)
{
......@@ -252,24 +258,43 @@ void DisplayCGL::terminate()
}
}
egl::Error DisplayCGL::prepareForCall()
{
ASSERT(mContext);
auto threadId = std::this_thread::get_id();
if (mDeviceContextIsVolatile ||
mThreadsWithCurrentContext.find(threadId) == mThreadsWithCurrentContext.end())
{
if (CGLSetCurrentContext(mContext) != kCGLNoError)
{
return egl::EglBadAlloc() << "Could not make device CGL context current.";
}
mThreadsWithCurrentContext.insert(threadId);
}
return egl::NoError();
}
egl::Error DisplayCGL::releaseThread()
{
ASSERT(mContext);
auto threadId = std::this_thread::get_id();
if (mThreadsWithCurrentContext.find(threadId) != mThreadsWithCurrentContext.end())
{
if (CGLSetCurrentContext(nullptr) != kCGLNoError)
{
return egl::EglBadAlloc() << "Could not release device CGL context.";
}
mThreadsWithCurrentContext.erase(threadId);
}
return egl::NoError();
}
egl::Error DisplayCGL::makeCurrent(egl::Display *display,
egl::Surface *drawSurface,
egl::Surface *readSurface,
gl::Context *context)
{
checkDiscreteGPUStatus();
// If the thread that's calling makeCurrent does not have the correct
// context current (either mContext or 0), we need to set it current.
CGLContextObj newContext = 0;
if (context)
{
newContext = mContext;
}
if (newContext != mCurrentContexts[std::this_thread::get_id()])
{
CGLSetCurrentContext(newContext);
mCurrentContexts[std::this_thread::get_id()] = newContext;
}
return DisplayGL::makeCurrent(display, drawSurface, readSurface, context);
}
......
......@@ -9,6 +9,9 @@
#ifndef LIBANGLE_RENDERER_GL_EAGL_DISPLAYEAGL_H_
#define LIBANGLE_RENDERER_GL_EAGL_DISPLAYEAGL_H_
#include <thread>
#include <unordered_set>
#import "common/platform.h"
#if defined(ANGLE_PLATFORM_IOS) && !defined(ANGLE_PLATFORM_MACCATALYST)
......@@ -35,6 +38,8 @@ class DisplayEAGL : public DisplayGL
egl::Error initialize(egl::Display *display) override;
void terminate() override;
egl::Error prepareForCall() override;
egl::Error releaseThread() override;
SurfaceImpl *createWindowSurface(const egl::SurfaceState &state,
EGLNativeWindowType window,
......@@ -93,6 +98,8 @@ class DisplayEAGL : public DisplayGL
egl::Display *mEGLDisplay;
EAGLContextObj mContext;
std::unordered_set<std::thread::id> mThreadsWithContextCurrent;
bool mDeviceContextIsVolatile = false;
};
} // namespace rx
......
......@@ -75,7 +75,12 @@ egl::Error DisplayEAGL::initialize(egl::Display *display)
{
return egl::EglNotInitialized() << "Could not create the EAGL context.";
}
[EAGLContext setCurrentContext:mContext];
if (![EAGLContext setCurrentContext:mContext])
{
return egl::EglNotInitialized() << "Could set the EAGL context current.";
}
mThreadsWithContextCurrent.insert(std::this_thread::get_id());
// There is no equivalent getProcAddress in EAGL so we open the dylib directly
void *handle = dlopen(kOpenGLESDylibName, RTLD_NOW);
......@@ -95,6 +100,10 @@ egl::Error DisplayEAGL::initialize(egl::Display *display)
return egl::EglNotInitialized() << "OpenGL ES 2.0 is not supportable.";
}
auto &attributes = display->getAttributeMap();
mDeviceContextIsVolatile =
attributes.get(EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_EAGL_ANGLE, GL_FALSE);
return DisplayGL::initialize(display);
}
......@@ -107,7 +116,37 @@ void DisplayEAGL::terminate()
{
[EAGLContext setCurrentContext:nil];
mContext = nullptr;
mThreadsWithContextCurrent.clear();
}
}
egl::Error DisplayEAGL::prepareForCall()
{
auto threadId = std::this_thread::get_id();
if (mDeviceContextIsVolatile ||
mThreadsWithContextCurrent.find(threadId) == mThreadsWithContextCurrent.end())
{
if (![getEAGLContextClass() setCurrentContext:mContext])
{
return egl::EglBadAlloc() << "Could not make device EAGL context current.";
}
mThreadsWithContextCurrent.insert(threadId);
}
return egl::NoError();
}
egl::Error DisplayEAGL::releaseThread()
{
auto threadId = std::this_thread::get_id();
if (mThreadsWithContextCurrent.find(threadId) != mThreadsWithContextCurrent.end())
{
if (![getEAGLContextClass() setCurrentContext:nil])
{
return egl::EglBadAlloc() << "Could not release device EAGL context.";
}
mThreadsWithContextCurrent.erase(threadId);
}
return egl::NoError();
}
SurfaceImpl *DisplayEAGL::createWindowSurface(const egl::SurfaceState &state,
......
......@@ -643,6 +643,36 @@ Error ValidateGetPlatformDisplayCommon(EGLenum platform,
case EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE:
luidSpecified = true;
break;
case EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_EAGL_ANGLE:
// The property does not have an effect if it's not active, so do not check
// for non-support.
switch (value)
{
case EGL_FALSE:
case EGL_TRUE:
break;
default:
return EglBadAttribute()
<< "Invalid value for "
"EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_"
"EAGL_ANGLE attrib";
}
break;
case EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_CGL_ANGLE:
// The property does not have an effect if it's not active, so do not check
// for non-support.
switch (value)
{
case EGL_FALSE:
case EGL_TRUE:
break;
default:
return EglBadAttribute()
<< "Invalid value for "
"EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_"
"CGL_ANGLE attrib";
}
break;
default:
break;
}
......
......@@ -105,7 +105,8 @@ EGLBoolean EGLAPIENTRY EGL_Terminate(EGLDisplay dpy)
egl::Display *display = static_cast<egl::Display *>(dpy);
ANGLE_EGL_TRY_RETURN(thread, ValidateTerminate(display), "eglTerminate",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglTerminate",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread,
display->makeCurrent(thread->getContext(), nullptr, nullptr, nullptr),
"eglTerminate", GetDisplayIfValid(display), EGL_FALSE);
......@@ -128,6 +129,8 @@ const char *EGLAPIENTRY EGL_QueryString(EGLDisplay dpy, EGLint name)
{
ANGLE_EGL_TRY_RETURN(thread, ValidateDisplay(display), "eglQueryString",
GetDisplayIfValid(display), nullptr);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryString",
GetDisplayIfValid(display), nullptr);
}
const char *result;
......@@ -256,6 +259,8 @@ EGLSurface EGLAPIENTRY EGL_CreateWindowSurface(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread,
ValidateCreateWindowSurface(display, configuration, win, attributes),
"eglCreateWindowSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateWindowSurface",
GetDisplayIfValid(display), EGL_NO_SURFACE);
egl::Surface *surface = nullptr;
ANGLE_EGL_TRY_RETURN(thread,
......@@ -282,7 +287,8 @@ EGLSurface EGLAPIENTRY EGL_CreatePbufferSurface(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread, ValidateCreatePbufferSurface(display, configuration, attributes),
"eglCreatePbufferSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePbufferSurface",
GetDisplayIfValid(display), EGL_NO_SURFACE);
egl::Surface *surface = nullptr;
ANGLE_EGL_TRY_RETURN(thread, display->createPbufferSurface(configuration, attributes, &surface),
"eglCreatePbufferSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
......@@ -311,7 +317,8 @@ EGLSurface EGLAPIENTRY EGL_CreatePixmapSurface(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread,
ValidateCreatePixmapSurface(display, configuration, pixmap, attributes),
"eglCreatePixmapSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePixmapSurface",
GetDisplayIfValid(display), EGL_NO_SURFACE);
egl::Surface *surface = nullptr;
ANGLE_EGL_TRY_RETURN(thread,
display->createPixmapSurface(configuration, pixmap, attributes, &surface),
......@@ -333,7 +340,8 @@ EGLBoolean EGLAPIENTRY EGL_DestroySurface(EGLDisplay dpy, EGLSurface surface)
ANGLE_EGL_TRY_RETURN(thread, ValidateDestroySurface(display, eglSurface, surface),
"eglDestroySurface", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroySurface",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->destroySurface(eglSurface), "eglDestroySurface",
GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
......@@ -353,12 +361,13 @@ EGLBoolean EGLAPIENTRY EGL_QuerySurface(EGLDisplay dpy,
(uintptr_t)dpy, (uintptr_t)surface, attribute, (uintptr_t)value);
Thread *thread = egl::GetCurrentThread();
const egl::Display *display = static_cast<const egl::Display *>(dpy);
egl::Display *display = static_cast<egl::Display *>(dpy);
const Surface *eglSurface = static_cast<const Surface *>(surface);
ANGLE_EGL_TRY_RETURN(thread, ValidateQuerySurface(display, eglSurface, attribute, value),
"eglQuerySurface", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQuerySurface",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, QuerySurfaceAttrib(display, eglSurface, attribute, value),
"eglQuerySurface", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
......@@ -386,7 +395,8 @@ EGLContext EGLAPIENTRY EGL_CreateContext(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread,
ValidateCreateContext(display, configuration, sharedGLContext, attributes),
"eglCreateContext", GetDisplayIfValid(display), EGL_NO_CONTEXT);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateContext",
GetDisplayIfValid(display), EGL_NO_CONTEXT);
gl::Context *context = nullptr;
ANGLE_EGL_TRY_RETURN(thread,
display->createContext(configuration, sharedGLContext, thread->getAPI(),
......@@ -409,7 +419,8 @@ EGLBoolean EGLAPIENTRY EGL_DestroyContext(EGLDisplay dpy, EGLContext ctx)
ANGLE_EGL_TRY_RETURN(thread, ValidateDestroyContext(display, context, ctx), "eglDestroyContext",
GetContextIfValid(display, context), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroyContext",
GetDisplayIfValid(display), EGL_FALSE);
bool contextWasCurrent = context == thread->getContext();
ANGLE_EGL_TRY_RETURN(thread, display->destroyContext(thread, context), "eglDestroyContext",
......@@ -446,7 +457,8 @@ EGLBoolean EGLAPIENTRY EGL_MakeCurrent(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread, ValidateMakeCurrent(display, drawSurface, readSurface, context),
"eglMakeCurrent", GetContextIfValid(display, context), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglMakeCurrent",
GetDisplayIfValid(display), EGL_FALSE);
Surface *previousDraw = thread->getCurrentDrawSurface();
Surface *previousRead = thread->getCurrentReadSurface();
gl::Context *previousContext = thread->getContext();
......@@ -520,7 +532,8 @@ EGLBoolean EGLAPIENTRY EGL_QueryContext(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread, ValidateQueryContext(display, context, attribute, value),
"eglQueryContext", GetContextIfValid(display, context), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryContext",
GetDisplayIfValid(display), EGL_FALSE);
QueryContextAttrib(context, attribute, value);
thread->setSuccess();
......@@ -537,6 +550,8 @@ EGLBoolean EGLAPIENTRY EGL_WaitGL(void)
ANGLE_EGL_TRY_RETURN(thread, ValidateDisplay(display), "eglWaitGL", GetDisplayIfValid(display),
EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitGL", GetDisplayIfValid(display),
EGL_FALSE);
// eglWaitGL like calling eglWaitClient with the OpenGL ES API bound. Since we only implement
// OpenGL ES we can do the call directly.
......@@ -557,6 +572,8 @@ EGLBoolean EGLAPIENTRY EGL_WaitNative(EGLint engine)
ANGLE_EGL_TRY_RETURN(thread, ValidateWaitNative(display, engine), "eglWaitNative",
GetThreadIfValid(thread), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitNative",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->waitNative(thread->getContext(), engine), "eglWaitNative",
GetThreadIfValid(thread), EGL_FALSE);
......@@ -577,6 +594,8 @@ EGLBoolean EGLAPIENTRY EGL_SwapBuffers(EGLDisplay dpy, EGLSurface surface)
ANGLE_EGL_TRY_RETURN(thread, ValidateSwapBuffers(thread, display, eglSurface), "eglSwapBuffers",
GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSwapBuffers",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, eglSurface->swap(thread->getContext()), "eglSwapBuffers",
GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
......@@ -601,7 +620,8 @@ EGLBoolean EGLAPIENTRY EGL_CopyBuffers(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread, ValidateCopyBuffers(display, eglSurface), "eglCopyBuffers",
GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCopyBuffers",
GetDisplayIfValid(display), EGL_FALSE);
UNIMPLEMENTED(); // FIXME
thread->setSuccess();
......@@ -625,7 +645,8 @@ EGLBoolean EGLAPIENTRY EGL_BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
ANGLE_EGL_TRY_RETURN(
thread, ValidateBindTexImage(display, eglSurface, surface, buffer, context, &textureObject),
"eglBindTexImage", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglBindTexImage",
GetDisplayIfValid(display), EGL_FALSE);
if (context)
{
ANGLE_EGL_TRY_RETURN(thread, eglSurface->bindTexImage(context, textureObject, buffer),
......@@ -653,7 +674,8 @@ EGLBoolean EGLAPIENTRY EGL_SurfaceAttrib(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread, ValidateSurfaceAttrib(display, eglSurface, attribute, value),
"eglSurfaceAttrib", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSurfaceAttrib",
GetDisplayIfValid(display), EGL_FALSE);
SetSurfaceAttrib(eglSurface, attribute, value);
thread->setSuccess();
......@@ -674,6 +696,8 @@ EGLBoolean EGLAPIENTRY EGL_ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, E
ANGLE_EGL_TRY_RETURN(thread, ValidateReleaseTexImage(display, eglSurface, surface, buffer),
"eglReleaseTexImage", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglReleaseTexImage",
GetDisplayIfValid(display), EGL_FALSE);
gl::Texture *texture = eglSurface->getBoundTexture();
if (texture)
......@@ -700,7 +724,8 @@ EGLBoolean EGLAPIENTRY EGL_SwapInterval(EGLDisplay dpy, EGLint interval)
ANGLE_EGL_TRY_RETURN(thread, ValidateSwapInterval(display, draw_surface, context),
"eglSwapInterval", GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSwapInterval",
GetDisplayIfValid(display), EGL_FALSE);
const egl::Config *surfaceConfig = draw_surface->getConfig();
EGLint clampedInterval = std::min(std::max(interval, surfaceConfig->minSwapInterval),
surfaceConfig->maxSwapInterval);
......@@ -762,7 +787,8 @@ EGLSurface EGLAPIENTRY EGL_CreatePbufferFromClientBuffer(EGLDisplay dpy,
thread,
ValidateCreatePbufferFromClientBuffer(display, buftype, buffer, configuration, attributes),
"eglCreatePbufferFromClientBuffer", GetDisplayIfValid(display), EGL_NO_SURFACE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePbufferFromClientBuffer",
GetDisplayIfValid(display), EGL_NO_SURFACE);
egl::Surface *surface = nullptr;
ANGLE_EGL_TRY_RETURN(thread,
display->createPbufferFromClientBuffer(configuration, buftype, buffer,
......@@ -784,17 +810,20 @@ EGLBoolean EGLAPIENTRY EGL_ReleaseThread(void)
gl::Context *previousContext = thread->getContext();
egl::Display *previousDisplay = thread->getDisplay();
if (previousDisplay != EGL_NO_DISPLAY)
{
ANGLE_EGL_TRY_RETURN(thread, previousDisplay->prepareForCall(), "eglReleaseThread",
GetDisplayIfValid(previousDisplay), EGL_FALSE);
// Only call makeCurrent if the context or surfaces have changed.
if (previousDraw != EGL_NO_SURFACE || previousRead != EGL_NO_SURFACE ||
previousContext != EGL_NO_CONTEXT)
{
if (previousDisplay != EGL_NO_DISPLAY)
{
ANGLE_EGL_TRY_RETURN(
thread, previousDisplay->makeCurrent(previousContext, nullptr, nullptr, nullptr),
"eglReleaseThread", nullptr, EGL_FALSE);
}
ANGLE_EGL_TRY_RETURN(thread, previousDisplay->releaseThread(), "eglReleaseThread",
GetDisplayIfValid(previousDisplay), EGL_FALSE);
SetContextCurrent(thread, nullptr);
}
......@@ -813,7 +842,8 @@ EGLBoolean EGLAPIENTRY EGL_WaitClient(void)
ANGLE_EGL_TRY_RETURN(thread, ValidateDisplay(display), "eglWaitClient",
GetContextIfValid(display, context), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitClient",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->waitClient(context), "eglWaitClient",
GetContextIfValid(display, context), EGL_FALSE);
......@@ -852,7 +882,8 @@ EGLSync EGLAPIENTRY EGL_CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib
ANGLE_EGL_TRY_RETURN(
thread, ValidateCreateSync(display, type, attributes, currentDisplay, currentContext),
"eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateSync",
GetDisplayIfValid(display), EGL_FALSE);
egl::Sync *syncObject = nullptr;
ANGLE_EGL_TRY_RETURN(thread, display->createSync(currentContext, type, attributes, &syncObject),
"eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
......@@ -873,7 +904,8 @@ EGLBoolean EGLAPIENTRY EGL_DestroySync(EGLDisplay dpy, EGLSync sync)
ANGLE_EGL_TRY_RETURN(thread, ValidateDestroySync(display, syncObject), "eglDestroySync",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroySync",
GetDisplayIfValid(display), EGL_FALSE);
display->destroySync(syncObject);
thread->setSuccess();
......@@ -894,7 +926,8 @@ EGLint EGLAPIENTRY EGL_ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags
ANGLE_EGL_TRY_RETURN(thread, ValidateClientWaitSync(display, syncObject, flags, timeout),
"eglClientWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglClientWaitSync",
GetDisplayIfValid(display), EGL_FALSE);
gl::Context *currentContext = thread->getContext();
EGLint syncStatus = EGL_FALSE;
ANGLE_EGL_TRY_RETURN(
......@@ -957,6 +990,8 @@ EGLImage EGLAPIENTRY EGL_CreateImage(EGLDisplay dpy,
thread->setError(error, GetDebug(), "eglCreateImage", GetDisplayIfValid(display));
return EGL_NO_IMAGE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateImage",
GetDisplayIfValid(display), EGL_FALSE);
Image *image = nullptr;
error = display->createImage(context, target, buffer, attributes, &image);
......@@ -985,7 +1020,8 @@ EGLBoolean EGLAPIENTRY EGL_DestroyImage(EGLDisplay dpy, EGLImage image)
thread->setError(error, GetDebug(), "eglDestroyImage", GetImageIfValid(display, img));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroyImage",
GetDisplayIfValid(display), EGL_FALSE);
display->destroyImage(img);
thread->setSuccess();
......@@ -1044,14 +1080,15 @@ EGLSurface EGLAPIENTRY EGL_CreatePlatformWindowSurface(EGLDisplay dpy,
EGLNativeWindowType win = reinterpret_cast<EGLNativeWindowType>(native_window);
AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
ANGLE_EGL_TRY_RETURN(thread,
ValidateCreateWindowSurface(display, configuration, win, attributes),
"eglCreateWindowSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
ANGLE_EGL_TRY_RETURN(
thread, ValidateCreateWindowSurface(display, configuration, win, attributes),
"eglPlatformCreateWindowSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateWindowSurface",
GetDisplayIfValid(display), EGL_NO_SURFACE);
egl::Surface *surface = nullptr;
ANGLE_EGL_TRY_RETURN(thread,
display->createWindowSurface(configuration, win, attributes, &surface),
"eglCreateWindowSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
ANGLE_EGL_TRY_RETURN(
thread, display->createWindowSurface(configuration, win, attributes, &surface),
"eglPlatformCreateWindowSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
return static_cast<EGLSurface>(surface);
}
......@@ -1078,7 +1115,8 @@ EGLSurface EGLAPIENTRY EGL_CreatePlatformPixmapSurface(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(
thread, ValidateCreatePixmapSurface(display, configuration, pixmap, attributes),
"eglCreatePlatformPixmapSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePlatformPixmapSurface",
GetDisplayIfValid(display), EGL_NO_SURFACE);
egl::Surface *surface = nullptr;
ANGLE_EGL_TRY_RETURN(
thread, display->createPixmapSurface(configuration, pixmap, attributes, &surface),
......@@ -1102,7 +1140,8 @@ EGLBoolean EGLAPIENTRY EGL_WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
ANGLE_EGL_TRY_RETURN(thread, ValidateWaitSync(display, context, syncObject, flags),
"eglWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitSync",
GetDisplayIfValid(display), EGL_FALSE);
gl::Context *currentContext = thread->getContext();
ANGLE_EGL_TRY_RETURN(thread, syncObject->serverWait(display, currentContext, flags),
"eglWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
......
......@@ -86,7 +86,8 @@ EGLBoolean EGLAPIENTRY EGL_QuerySurfacePointerANGLE(EGLDisplay dpy,
GetSurfaceIfValid(display, eglSurface));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQuerySurfacePointerANGLE",
GetDisplayIfValid(display), EGL_FALSE);
error = eglSurface->querySurfacePointerANGLE(attribute, value);
if (error.isError())
{
......@@ -151,7 +152,8 @@ EGLBoolean EGLAPIENTRY EGL_PostSubBufferNV(EGLDisplay dpy,
thread->setSuccess();
return EGL_TRUE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglPostSubBufferNV",
GetDisplayIfValid(display), EGL_FALSE);
// TODO(jmadill): Validate Surface is bound to the thread.
error = eglSurface->postSubBuffer(thread->getContext(), x, y, width, height);
if (error.isError())
......@@ -223,7 +225,8 @@ EGLSurface EGLAPIENTRY EGL_CreatePlatformWindowSurfaceEXT(EGLDisplay dpy,
thread,
ValidateCreatePlatformWindowSurfaceEXT(display, configuration, native_window, attributes),
"eglCreatePlatformWindowSurfaceEXT", GetDisplayIfValid(display), EGL_NO_SURFACE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePlatformWindowSurfaceEXT",
GetDisplayIfValid(display), EGL_NO_SURFACE);
thread->setError(EglBadDisplay() << "CreatePlatformWindowSurfaceEXT unimplemented.", GetDebug(),
"eglCreatePlatformWindowSurfaceEXT", GetDisplayIfValid(display));
return EGL_NO_SURFACE;
......@@ -250,7 +253,8 @@ EGLSurface EGLAPIENTRY EGL_CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy,
thread,
ValidateCreatePlatformPixmapSurfaceEXT(display, configuration, native_pixmap, attributes),
"eglCreatePlatformPixmapSurfaceEXT", GetDisplayIfValid(display), EGL_NO_SURFACE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePlatformPixmapSurfaceEXT",
GetDisplayIfValid(display), EGL_NO_SURFACE);
thread->setError(EglBadDisplay() << "CreatePlatformPixmapSurfaceEXT unimplemented.", GetDebug(),
"eglCreatePlatformPixmapSurfaceEXT", GetDisplayIfValid(display));
return EGL_NO_SURFACE;
......@@ -275,10 +279,14 @@ EGLBoolean EGLAPIENTRY EGL_QueryDeviceAttribEXT(EGLDeviceEXT device,
thread->setError(error, GetDebug(), "eglQueryDeviceAttribEXT", GetDeviceIfValid(dev));
return EGL_FALSE;
}
egl::Display *owningDisplay = dev->getOwningDisplay();
if (owningDisplay)
{
ANGLE_EGL_TRY_RETURN(thread, owningDisplay->prepareForCall(), "eglQueryDeviceAttribEXT",
GetDisplayIfValid(owningDisplay), EGL_FALSE);
}
// If the device was created by (and is owned by) a display, and that display doesn't support
// device querying, then this call should fail
egl::Display *owningDisplay = dev->getOwningDisplay();
if (owningDisplay != nullptr && !owningDisplay->getExtensions().deviceQuery)
{
thread->setError(EglBadAccess() << "Device wasn't created using eglCreateDeviceANGLE, "
......@@ -351,7 +359,9 @@ const char *EGLAPIENTRY EGL_QueryDeviceStringEXT(EGLDeviceEXT device, EGLint nam
thread->setError(error, GetDebug(), "eglQueryDeviceStringEXT", GetDeviceIfValid(dev));
return EGL_FALSE;
}
egl::Display *owningDisplay = dev->getOwningDisplay();
ANGLE_EGL_TRY_RETURN(thread, owningDisplay->prepareForCall(), "eglQueryDeviceStringEXT",
GetDisplayIfValid(owningDisplay), EGL_FALSE);
const char *result;
switch (name)
{
......@@ -381,7 +391,8 @@ EGLBoolean EGLAPIENTRY EGL_QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribut
ANGLE_EGL_TRY_RETURN(thread, ValidateQueryDisplayAttribEXT(display, attribute),
"eglQueryDisplayAttribEXT", GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryDisplayAttribEXT",
GetDisplayIfValid(display), EGL_FALSE);
*value = display->queryAttrib(attribute);
thread->setSuccess();
return EGL_TRUE;
......@@ -402,7 +413,8 @@ EGLBoolean EGLAPIENTRY EGL_QueryDisplayAttribANGLE(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread, ValidateQueryDisplayAttribANGLE(display, attribute),
"eglQueryDisplayAttribANGLE", GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryDisplayAttribANGLE",
GetDisplayIfValid(display), EGL_FALSE);
*value = display->queryAttrib(attribute);
thread->setSuccess();
return EGL_TRUE;
......@@ -433,7 +445,8 @@ ANGLE_EXPORT EGLImageKHR EGLAPIENTRY EGL_CreateImageKHR(EGLDisplay dpy,
thread->setError(error, GetDebug(), "eglCreateImageKHR", GetDisplayIfValid(display));
return EGL_NO_IMAGE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateImageKHR",
GetDisplayIfValid(display), EGL_NO_IMAGE);
Image *image = nullptr;
error = display->createImage(context, target, buffer, attributes, &image);
if (error.isError())
......@@ -462,7 +475,8 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_DestroyImageKHR(EGLDisplay dpy, EGLImage
thread->setError(error, GetDebug(), "eglDestroyImageKHR", GetImageIfValid(display, img));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroyImageKHR",
GetDisplayIfValid(display), EGL_FALSE);
display->destroyImage(img);
thread->setSuccess();
......@@ -538,7 +552,8 @@ EGLStreamKHR EGLAPIENTRY EGL_CreateStreamKHR(EGLDisplay dpy, const EGLint *attri
thread->setError(error, GetDebug(), "eglCreateStreamKHR", GetDisplayIfValid(display));
return EGL_NO_STREAM_KHR;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateStreamKHR",
GetDisplayIfValid(display), EGL_NO_STREAM_KHR);
Stream *stream;
error = display->createStream(attributes, &stream);
if (error.isError())
......@@ -568,7 +583,8 @@ EGLBoolean EGLAPIENTRY EGL_DestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
GetStreamIfValid(display, streamObject));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroyStreamKHR",
GetDisplayIfValid(display), EGL_FALSE);
display->destroyStream(streamObject);
thread->setSuccess();
......@@ -597,7 +613,8 @@ EGLBoolean EGLAPIENTRY EGL_StreamAttribKHR(EGLDisplay dpy,
GetStreamIfValid(display, streamObject));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamAttribKHR",
GetDisplayIfValid(display), EGL_FALSE);
switch (attribute)
{
case EGL_CONSUMER_LATENCY_USEC_KHR:
......@@ -636,7 +653,8 @@ EGLBoolean EGLAPIENTRY EGL_QueryStreamKHR(EGLDisplay dpy,
GetStreamIfValid(display, streamObject));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryStreamKHR",
GetDisplayIfValid(display), EGL_FALSE);
switch (attribute)
{
case EGL_STREAM_STATE_KHR:
......@@ -678,7 +696,8 @@ EGLBoolean EGLAPIENTRY EGL_QueryStreamu64KHR(EGLDisplay dpy,
GetStreamIfValid(display, streamObject));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryStreamu64KHR",
GetDisplayIfValid(display), EGL_FALSE);
switch (attribute)
{
case EGL_PRODUCER_FRAME_KHR:
......@@ -713,7 +732,8 @@ EGLBoolean EGLAPIENTRY EGL_StreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EG
GetStreamIfValid(display, streamObject));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamConsumerGLTextureExternalKHR",
GetDisplayIfValid(display), EGL_FALSE);
error = streamObject->createConsumerGLTextureExternal(AttributeMap(), context);
if (error.isError())
{
......@@ -744,7 +764,8 @@ EGLBoolean EGLAPIENTRY EGL_StreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR
GetStreamIfValid(display, streamObject));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamConsumerAcquireKHR",
GetDisplayIfValid(display), EGL_FALSE);
error = streamObject->consumerAcquire(context);
if (error.isError())
{
......@@ -775,7 +796,8 @@ EGLBoolean EGLAPIENTRY EGL_StreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR
GetStreamIfValid(display, streamObject));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamConsumerReleaseKHR",
GetDisplayIfValid(display), EGL_FALSE);
error = streamObject->consumerRelease(context);
if (error.isError())
{
......@@ -811,7 +833,9 @@ EGLBoolean EGLAPIENTRY EGL_StreamConsumerGLTextureExternalAttribsNV(EGLDisplay d
GetStreamIfValid(display, streamObject));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(),
"eglStreamConsumerGLTextureExternalAttribsNV", GetDisplayIfValid(display),
EGL_FALSE);
error = streamObject->createConsumerGLTextureExternal(attributes, context);
if (error.isError())
{
......@@ -845,7 +869,9 @@ EGLBoolean EGLAPIENTRY EGL_CreateStreamProducerD3DTextureANGLE(EGLDisplay dpy,
GetStreamIfValid(display, streamObject));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(),
"eglCreateStreamProducerD3DTextureANGLE", GetDisplayIfValid(display),
EGL_FALSE);
error = streamObject->createProducerD3D11Texture(attributes);
if (error.isError())
{
......@@ -882,7 +908,8 @@ EGLBoolean EGLAPIENTRY EGL_StreamPostD3DTextureANGLE(EGLDisplay dpy,
GetStreamIfValid(display, streamObject));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamPostD3DTextureANGLE",
GetDisplayIfValid(display), EGL_FALSE);
error = streamObject->postD3D11Texture(texture, attributes);
if (error.isError())
{
......@@ -915,7 +942,8 @@ ANGLE_EXPORT EGLSync EGLAPIENTRY EGL_CreateSyncKHR(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(
thread, ValidateCreateSyncKHR(display, type, attributes, currentDisplay, currentContext),
"eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateSync",
GetDisplayIfValid(display), EGL_NO_SYNC);
egl::Sync *syncObject = nullptr;
ANGLE_EGL_TRY_RETURN(thread, display->createSync(currentContext, type, attributes, &syncObject),
"eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
......@@ -936,7 +964,8 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_DestroySyncKHR(EGLDisplay dpy, EGLSync s
ANGLE_EGL_TRY_RETURN(thread, ValidateDestroySync(display, syncObject), "eglDestroySync",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroySync",
GetDisplayIfValid(display), EGL_FALSE);
display->destroySync(syncObject);
thread->setSuccess();
......@@ -960,7 +989,8 @@ ANGLE_EXPORT EGLint EGLAPIENTRY EGL_ClientWaitSyncKHR(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread, ValidateClientWaitSync(display, syncObject, flags, timeout),
"eglClientWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglClientWaitSync",
GetDisplayIfValid(display), EGL_FALSE);
gl::Context *currentContext = thread->getContext();
EGLint syncStatus = EGL_FALSE;
ANGLE_EGL_TRY_RETURN(
......@@ -988,7 +1018,8 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetSyncAttribKHR(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread, ValidateGetSyncAttribKHR(display, syncObject, attribute, value),
"eglGetSyncAttrib", GetSyncIfValid(display, syncObject), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetSyncAttrib",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, GetSyncAttrib(display, syncObject, attribute, value),
"eglGetSyncAttrib", GetSyncIfValid(display, syncObject), EGL_FALSE);
......@@ -1011,7 +1042,8 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_WaitSyncKHR(EGLDisplay dpy, EGLSync sync
ANGLE_EGL_TRY_RETURN(thread, ValidateWaitSync(display, context, syncObject, flags),
"eglWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitSync",
GetDisplayIfValid(display), EGL_FALSE);
gl::Context *currentContext = thread->getContext();
ANGLE_EGL_TRY_RETURN(thread, syncObject->serverWait(display, currentContext, flags),
"eglWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
......@@ -1043,7 +1075,8 @@ EGLBoolean EGLAPIENTRY EGL_GetMscRateANGLE(EGLDisplay dpy,
GetSurfaceIfValid(display, eglSurface));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetMscRateANGLE",
GetDisplayIfValid(display), EGL_FALSE);
error = eglSurface->getMscRate(numerator, denominator);
if (error.isError())
{
......@@ -1080,7 +1113,8 @@ EGLBoolean EGLAPIENTRY EGL_GetSyncValuesCHROMIUM(EGLDisplay dpy,
GetSurfaceIfValid(display, eglSurface));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetSyncValuesCHROMIUM",
GetDisplayIfValid(display), EGL_FALSE);
error = eglSurface->getSyncValues(ust, msc, sbc);
if (error.isError())
{
......@@ -1116,7 +1150,8 @@ EGLBoolean EGLAPIENTRY EGL_SwapBuffersWithDamageKHR(EGLDisplay dpy,
GetSurfaceIfValid(display, eglSurface));
return EGL_FALSE;
}
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSwapBuffersWithDamageEXT",
GetDisplayIfValid(display), EGL_FALSE);
error = eglSurface->swapWithDamage(thread->getContext(), rects, n_rects);
if (error.isError())
{
......@@ -1145,6 +1180,8 @@ EGLBoolean EGLAPIENTRY EGL_PresentationTimeANDROID(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread, ValidatePresentationTimeANDROID(display, eglSurface, time),
"eglPresentationTimeANDROID", GetSurfaceIfValid(display, eglSurface),
EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglPresentationTimeANDROID",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, eglSurface->setPresentationTime(time),
"eglPresentationTimeANDROID", GetSurfaceIfValid(display, eglSurface),
EGL_FALSE);
......@@ -1166,7 +1203,8 @@ ANGLE_EXPORT void EGLAPIENTRY EGL_SetBlobCacheFuncsANDROID(EGLDisplay dpy,
ANGLE_EGL_TRY(thread, ValidateSetBlobCacheANDROID(display, set, get),
"eglSetBlobCacheFuncsANDROID", GetDisplayIfValid(display));
ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglSetBlobCacheFuncsANDROID",
GetDisplayIfValid(display));
thread->setSuccess();
display->setBlobCacheFuncs(set, get);
}
......@@ -1181,7 +1219,8 @@ EGLint EGLAPIENTRY EGL_ProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib
ANGLE_EGL_TRY_RETURN(thread, ValidateProgramCacheGetAttribANGLE(display, attrib),
"eglProgramCacheGetAttribANGLE", GetDisplayIfValid(display), 0);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglProgramCacheGetAttribANGLE",
GetDisplayIfValid(display), 0);
thread->setSuccess();
return display->programCacheGetAttrib(attrib);
}
......@@ -1206,7 +1245,8 @@ void EGLAPIENTRY EGL_ProgramCacheQueryANGLE(EGLDisplay dpy,
ANGLE_EGL_TRY(thread,
ValidateProgramCacheQueryANGLE(display, index, key, keysize, binary, binarysize),
"eglProgramCacheQueryANGLE", GetDisplayIfValid(display));
ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglProgramCacheQueryANGLE",
GetDisplayIfValid(display));
ANGLE_EGL_TRY(thread, display->programCacheQuery(index, key, keysize, binary, binarysize),
"eglProgramCacheQueryANGLE", GetDisplayIfValid(display));
......@@ -1231,7 +1271,8 @@ void EGLAPIENTRY EGL_ProgramCachePopulateANGLE(EGLDisplay dpy,
ANGLE_EGL_TRY(thread,
ValidateProgramCachePopulateANGLE(display, key, keysize, binary, binarysize),
"eglProgramCachePopulateANGLE", GetDisplayIfValid(display));
ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglProgramCachePopulateANGLE",
GetDisplayIfValid(display));
ANGLE_EGL_TRY(thread, display->programCachePopulate(key, keysize, binary, binarysize),
"eglProgramCachePopulateANGLE", GetDisplayIfValid(display));
......@@ -1249,7 +1290,8 @@ EGLint EGLAPIENTRY EGL_ProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limit, EGL
ANGLE_EGL_TRY_RETURN(thread, ValidateProgramCacheResizeANGLE(display, limit, mode),
"eglProgramCacheResizeANGLE", GetDisplayIfValid(display), 0);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglProgramCacheResizeANGLE",
GetDisplayIfValid(display), 0);
thread->setSuccess();
return display->programCacheResize(limit, mode);
}
......@@ -1340,7 +1382,15 @@ EGLint EGLAPIENTRY EGL_LabelObjectKHR(EGLDisplay dpy,
GetLabeledObjectIfValid(thread, display, objectTypePacked, object));
return error.getCode();
}
if (display)
{
error = display->prepareForCall();
if (error.isError())
{
thread->setError(error, GetDebug(), "eglLabelObjectKHR", GetDisplayIfValid(display));
return error.getCode();
}
}
LabeledObject *labeledObject =
GetLabeledObjectIfValid(thread, display, objectTypePacked, object);
ASSERT(labeledObject != nullptr);
......@@ -1394,6 +1444,8 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetCompositorTimingANDROID(EGLDisplay dp
thread,
ValidateGetCompositorTimingANDROID(display, eglSurface, numTimestamps, names, values),
"eglGetCompositorTimingANDROIDD", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetCompositorTimingANDROIDD",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, eglSurface->getCompositorTiming(numTimestamps, names, values),
"eglGetCompositorTimingANDROIDD", GetSurfaceIfValid(display, eglSurface),
EGL_FALSE);
......@@ -1418,6 +1470,8 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetNextFrameIdANDROID(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread, ValidateGetNextFrameIdANDROID(display, eglSurface, frameId),
"eglGetNextFrameIdANDROID", GetSurfaceIfValid(display, eglSurface),
EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetNextFrameIdANDROID",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, eglSurface->getNextFrameId(frameId), "eglGetNextFrameIdANDROID",
GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
......@@ -1443,7 +1497,8 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetFrameTimestampSupportedANDROID(EGLDis
ANGLE_EGL_TRY_RETURN(
thread, ValidateGetFrameTimestampSupportedANDROID(display, eglSurface, timestampInternal),
"eglQueryTimestampSupportedANDROID", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryTimestampSupportedANDROID",
GetDisplayIfValid(display), EGL_FALSE);
thread->setSuccess();
return eglSurface->getSupportedTimestamps().test(timestampInternal);
}
......@@ -1472,6 +1527,8 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetFrameTimestampsANDROID(EGLDisplay dpy
numTimestamps, timestamps, values),
"eglGetFrameTimestampsANDROID", GetSurfaceIfValid(display, eglSurface),
EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetFrameTimestampsANDROID",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(
thread, eglSurface->getFrameTimestamps(frameId, numTimestamps, timestamps, values),
"eglGetFrameTimestampsANDROID", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
......@@ -1494,7 +1551,8 @@ ANGLE_EXPORT const char *EGLAPIENTRY EGL_QueryStringiANGLE(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(thread, ValidateQueryStringiANGLE(display, name, index),
"eglQueryStringiANGLE", GetDisplayIfValid(display), nullptr);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryStringiANGLE",
GetDisplayIfValid(display), nullptr);
thread->setSuccess();
return display->queryStringi(name, index);
}
......@@ -1551,7 +1609,8 @@ EGLint EGLAPIENTRY EGL_DupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync)
ANGLE_EGL_TRY_RETURN(thread, ValidateDupNativeFenceFDANDROID(display, syncObject),
"eglDupNativeFenceFDANDROID", GetSyncIfValid(display, syncObject),
EGL_NO_NATIVE_FENCE_FD_ANDROID);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDupNativeFenceFDANDROID",
GetDisplayIfValid(display), EGL_NO_NATIVE_FENCE_FD_ANDROID);
EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
ANGLE_EGL_TRY_RETURN(thread, syncObject->dupNativeFenceFD(display, &result),
"eglDupNativeFenceFDANDROID", GetSyncIfValid(display, syncObject),
......@@ -1577,7 +1636,8 @@ EGLBoolean EGLAPIENTRY EGL_SwapBuffersWithFrameTokenANGLE(EGLDisplay dpy,
ANGLE_EGL_TRY_RETURN(
thread, ValidateSwapBuffersWithFrameTokenANGLE(display, eglSurface, frametoken),
"eglSwapBuffersWithFrameTokenANGLE", GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSwapBuffersWithFrameTokenANGLE",
GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, eglSurface->swapWithFrameToken(thread->getContext(), frametoken),
"eglSwapBuffersWithFrameTokenANGLE", GetDisplayIfValid(display),
EGL_FALSE);
......@@ -1598,6 +1658,8 @@ void EGLAPIENTRY EGL_ReleaseHighPowerGPUANGLE(EGLDisplay dpy, EGLContext ctx)
ANGLE_EGL_TRY(thread, ValidateContext(display, context), "eglReleaseHighPowerGPUANGLE",
GetDisplayIfValid(display));
ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglReleaseHighPowerGPUANGLE",
GetDisplayIfValid(display));
ANGLE_EGL_TRY(thread, context->releaseHighPowerGPU(), "eglReleaseHighPowerGPUANGLE",
GetDisplayIfValid(display));
......@@ -1616,6 +1678,8 @@ void EGLAPIENTRY EGL_ReacquireHighPowerGPUANGLE(EGLDisplay dpy, EGLContext ctx)
ANGLE_EGL_TRY(thread, ValidateContext(display, context), "eglReacquireHighPowerGPUANGLE",
GetDisplayIfValid(display));
ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglReacquireHighPowerGPUANGLE",
GetDisplayIfValid(display));
ANGLE_EGL_TRY(thread, context->reacquireHighPowerGPU(), "eglReacquireHighPowerGPUANGLE",
GetDisplayIfValid(display));
......@@ -1632,6 +1696,8 @@ void EGLAPIENTRY EGL_HandleGPUSwitchANGLE(EGLDisplay dpy)
ANGLE_EGL_TRY(thread, ValidateDisplay(display), "eglHandleGPUSwitchANGLE",
GetDisplayIfValid(display));
ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglHandleGPUSwitchANGLE",
GetDisplayIfValid(display));
ANGLE_EGL_TRY(thread, display->handleGPUSwitch(), "eglHandleGPUSwitchANGLE",
GetDisplayIfValid(display));
......
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