Commit 5313c8a8 by Shahbaz Youssefi Committed by Commit Bot

Implement EGL_KHR_fence_sync and EGL_KHR_wait_sync

EGL_KHR_fence_sync introduces the EGLSync object and associated create/destroy/clientWait functions. EGL_KHR_wait_sync adds the serverWait function on top of that. Bug: angleproject:2466 Change-Id: Iebb239a85c4471ea18b3c3a8a83b793af555e31d Reviewed-on: https://chromium-review.googlesource.com/c/1412261 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 828acb39
...@@ -84,10 +84,12 @@ supported_egl_extensions = [ ...@@ -84,10 +84,12 @@ supported_egl_extensions = [
"EGL_EXT_platform_base", "EGL_EXT_platform_base",
"EGL_EXT_platform_device", "EGL_EXT_platform_device",
"EGL_KHR_debug", "EGL_KHR_debug",
"EGL_KHR_fence_sync",
"EGL_KHR_image", "EGL_KHR_image",
"EGL_KHR_stream", "EGL_KHR_stream",
"EGL_KHR_stream_consumer_gltexture", "EGL_KHR_stream_consumer_gltexture",
"EGL_KHR_swap_buffers_with_damage", "EGL_KHR_swap_buffers_with_damage",
"EGL_KHR_wait_sync",
"EGL_NV_post_sub_buffer", "EGL_NV_post_sub_buffer",
"EGL_NV_stream_consumer_gltexture_yuv", "EGL_NV_stream_consumer_gltexture_yuv",
] ]
......
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
"GL/EGL entry points:scripts/gl_angle_ext.xml": "GL/EGL entry points:scripts/gl_angle_ext.xml":
"56fb2634ebb3d8240b1a92aeb5518f1a", "56fb2634ebb3d8240b1a92aeb5518f1a",
"GL/EGL entry points:scripts/registry_xml.py": "GL/EGL entry points:scripts/registry_xml.py":
"8490a27114ee420dbbe640f1b99edeec", "d9f9d394f3e71ac7dba84c203452d9e1",
"GL/EGL/WGL loader:scripts/egl.xml": "GL/EGL/WGL loader:scripts/egl.xml":
"842e24514c4cfe09fba703c17a0fd292", "842e24514c4cfe09fba703c17a0fd292",
"GL/EGL/WGL loader:scripts/egl_angle_ext.xml": "GL/EGL/WGL loader:scripts/egl_angle_ext.xml":
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
"GL/EGL/WGL loader:scripts/generate_loader.py": "GL/EGL/WGL loader:scripts/generate_loader.py":
"2d9be1d0f4f54905f3372411522133d1", "2d9be1d0f4f54905f3372411522133d1",
"GL/EGL/WGL loader:scripts/registry_xml.py": "GL/EGL/WGL loader:scripts/registry_xml.py":
"8490a27114ee420dbbe640f1b99edeec", "d9f9d394f3e71ac7dba84c203452d9e1",
"GL/EGL/WGL loader:scripts/wgl.xml": "GL/EGL/WGL loader:scripts/wgl.xml":
"aa96419c582af2f6673430e2847693f4", "aa96419c582af2f6673430e2847693f4",
"OpenGL dispatch table:scripts/gl.xml": "OpenGL dispatch table:scripts/gl.xml":
...@@ -120,7 +120,7 @@ ...@@ -120,7 +120,7 @@
"proc table:src/libGLESv2/gen_proc_table.py": "proc table:src/libGLESv2/gen_proc_table.py":
"ee265eada3dd238646010dd03874d242", "ee265eada3dd238646010dd03874d242",
"proc table:src/libGLESv2/proc_table_data.json": "proc table:src/libGLESv2/proc_table_data.json":
"77a69a0785c263381ef856b1d7d9c492", "81412cd66c53732e7e9d0cfc86b1ec92",
"uniform type:src/common/gen_uniform_type_table.py": "uniform type:src/common/gen_uniform_type_table.py":
"e185802e66950dfc5fc7a8fc19751206" "e185802e66950dfc5fc7a8fc19751206"
} }
\ No newline at end of file
...@@ -206,6 +206,7 @@ Extensions::Extensions() ...@@ -206,6 +206,7 @@ Extensions::Extensions()
eglImage(false), eglImage(false),
eglImageExternal(false), eglImageExternal(false),
eglImageExternalEssl3(false), eglImageExternalEssl3(false),
eglSync(false),
eglStreamConsumerExternal(false), eglStreamConsumerExternal(false),
unpackSubimage(false), unpackSubimage(false),
packSubimage(false), packSubimage(false),
...@@ -866,6 +867,7 @@ const ExtensionInfoMap &GetExtensionInfoMap() ...@@ -866,6 +867,7 @@ const ExtensionInfoMap &GetExtensionInfoMap()
map["GL_OES_EGL_image"] = enableableExtension(&Extensions::eglImage); map["GL_OES_EGL_image"] = enableableExtension(&Extensions::eglImage);
map["GL_OES_EGL_image_external"] = enableableExtension(&Extensions::eglImageExternal); map["GL_OES_EGL_image_external"] = enableableExtension(&Extensions::eglImageExternal);
map["GL_OES_EGL_image_external_essl3"] = enableableExtension(&Extensions::eglImageExternalEssl3); map["GL_OES_EGL_image_external_essl3"] = enableableExtension(&Extensions::eglImageExternalEssl3);
map["GL_OES_EGL_sync"] = esOnlyExtension(&Extensions::eglSync);
map["GL_NV_EGL_stream_consumer_external"] = enableableExtension(&Extensions::eglStreamConsumerExternal); map["GL_NV_EGL_stream_consumer_external"] = enableableExtension(&Extensions::eglStreamConsumerExternal);
map["GL_EXT_unpack_subimage"] = enableableExtension(&Extensions::unpackSubimage); map["GL_EXT_unpack_subimage"] = enableableExtension(&Extensions::unpackSubimage);
map["GL_NV_pack_subimage"] = enableableExtension(&Extensions::packSubimage); map["GL_NV_pack_subimage"] = enableableExtension(&Extensions::packSubimage);
...@@ -1356,6 +1358,8 @@ DisplayExtensions::DisplayExtensions() ...@@ -1356,6 +1358,8 @@ DisplayExtensions::DisplayExtensions()
streamConsumerGLTexture(false), streamConsumerGLTexture(false),
streamConsumerGLTextureYUV(false), streamConsumerGLTextureYUV(false),
streamProducerD3DTexture(false), streamProducerD3DTexture(false),
fenceSync(false),
waitSync(false),
createContextWebGLCompatibility(false), createContextWebGLCompatibility(false),
createContextBindGeneratesResource(false), createContextBindGeneratesResource(false),
getSyncValues(false), getSyncValues(false),
...@@ -1404,6 +1408,8 @@ std::vector<std::string> DisplayExtensions::getStrings() const ...@@ -1404,6 +1408,8 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_KHR_stream", stream, &extensionStrings); InsertExtensionString("EGL_KHR_stream", stream, &extensionStrings);
InsertExtensionString("EGL_KHR_stream_consumer_gltexture", streamConsumerGLTexture, &extensionStrings); InsertExtensionString("EGL_KHR_stream_consumer_gltexture", streamConsumerGLTexture, &extensionStrings);
InsertExtensionString("EGL_NV_stream_consumer_gltexture_yuv", streamConsumerGLTextureYUV, &extensionStrings); InsertExtensionString("EGL_NV_stream_consumer_gltexture_yuv", streamConsumerGLTextureYUV, &extensionStrings);
InsertExtensionString("EGL_KHR_fence_sync", fenceSync, &extensionStrings);
InsertExtensionString("EGL_KHR_wait_sync", waitSync, &extensionStrings);
InsertExtensionString("EGL_ANGLE_flexible_surface_compatibility", flexibleSurfaceCompatibility, &extensionStrings); InsertExtensionString("EGL_ANGLE_flexible_surface_compatibility", flexibleSurfaceCompatibility, &extensionStrings);
InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture", streamProducerD3DTexture, &extensionStrings); InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture", streamProducerD3DTexture, &extensionStrings);
InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility", createContextWebGLCompatibility, &extensionStrings); InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility", createContextWebGLCompatibility, &extensionStrings);
......
...@@ -326,6 +326,9 @@ struct Extensions ...@@ -326,6 +326,9 @@ struct Extensions
// GL_OES_EGL_image_external_essl3 // GL_OES_EGL_image_external_essl3
bool eglImageExternalEssl3; bool eglImageExternalEssl3;
// GL_OES_EGL_sync
bool eglSync;
// NV_EGL_stream_consumer_external // NV_EGL_stream_consumer_external
bool eglStreamConsumerExternal; bool eglStreamConsumerExternal;
...@@ -787,6 +790,12 @@ struct DisplayExtensions ...@@ -787,6 +790,12 @@ struct DisplayExtensions
// EGL_ANGLE_stream_producer_d3d_texture // EGL_ANGLE_stream_producer_d3d_texture
bool streamProducerD3DTexture; bool streamProducerD3DTexture;
// EGL_KHR_fence_sync
bool fenceSync;
// EGL_KHR_wait_sync
bool waitSync;
// EGL_ANGLE_create_context_webgl_compatibility // EGL_ANGLE_create_context_webgl_compatibility
bool createContextWebGLCompatibility; bool createContextWebGLCompatibility;
......
...@@ -3217,6 +3217,13 @@ Extensions Context::generateSupportedExtensions() const ...@@ -3217,6 +3217,13 @@ Extensions Context::generateSupportedExtensions() const
supportedExtensions.explicitContext = true; supportedExtensions.explicitContext = true;
} }
// If EGL_KHR_fence_sync is not enabled, don't expose GL_OES_EGL_sync.
ASSERT(mCurrentDisplay);
if (!mCurrentDisplay->getExtensions().fenceSync)
{
supportedExtensions.eglSync = false;
}
supportedExtensions.memorySize = true; supportedExtensions.memorySize = true;
return supportedExtensions; return supportedExtensions;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "common/utilities.h" #include "common/utilities.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Device.h" #include "libANGLE/Device.h"
#include "libANGLE/EGLSync.h"
#include "libANGLE/Image.h" #include "libANGLE/Image.h"
#include "libANGLE/ResourceManager.h" #include "libANGLE/ResourceManager.h"
#include "libANGLE/Stream.h" #include "libANGLE/Stream.h"
...@@ -566,6 +567,11 @@ Error Display::terminate(const Thread *thread) ...@@ -566,6 +567,11 @@ Error Display::terminate(const Thread *thread)
destroyStream(*mStreamSet.begin()); destroyStream(*mStreamSet.begin());
} }
while (!mSyncSet.empty())
{
destroySync(*mSyncSet.begin());
}
while (!mState.surfaceSet.empty()) while (!mState.surfaceSet.empty())
{ {
ANGLE_TRY(destroySurface(*mState.surfaceSet.begin())); ANGLE_TRY(destroySurface(*mState.surfaceSet.begin()));
...@@ -814,6 +820,29 @@ Error Display::createContext(const Config *configuration, ...@@ -814,6 +820,29 @@ Error Display::createContext(const Config *configuration,
return NoError(); return NoError();
} }
Error Display::createSync(EGLenum type, const AttributeMap &attribs, Sync **outSync)
{
ASSERT(isInitialized());
if (mImplementation->testDeviceLost())
{
ANGLE_TRY(restoreLostDevice());
}
angle::UniqueObjectPointer<egl::Sync, Display> syncPtr(new Sync(mImplementation, type, attribs),
this);
ANGLE_TRY(syncPtr->initialize(this));
Sync *sync = syncPtr.release();
sync->addRef();
mSyncSet.insert(sync);
*outSync = sync;
return NoError();
}
Error Display::makeCurrent(egl::Surface *drawSurface, Error Display::makeCurrent(egl::Surface *drawSurface,
egl::Surface *readSurface, egl::Surface *readSurface,
gl::Context *context) gl::Context *context)
...@@ -924,6 +953,14 @@ Error Display::destroyContext(const Thread *thread, gl::Context *context) ...@@ -924,6 +953,14 @@ Error Display::destroyContext(const Thread *thread, gl::Context *context)
return NoError(); return NoError();
} }
void Display::destroySync(egl::Sync *sync)
{
auto iter = mSyncSet.find(sync);
ASSERT(iter != mSyncSet.end());
(*iter)->release(this);
mSyncSet.erase(iter);
}
bool Display::isDeviceLost() const bool Display::isDeviceLost() const
{ {
ASSERT(isInitialized()); ASSERT(isInitialized());
...@@ -1009,6 +1046,11 @@ bool Display::isValidStream(const Stream *stream) const ...@@ -1009,6 +1046,11 @@ bool Display::isValidStream(const Stream *stream) const
return mStreamSet.find(const_cast<Stream *>(stream)) != mStreamSet.end(); return mStreamSet.find(const_cast<Stream *>(stream)) != mStreamSet.end();
} }
bool Display::isValidSync(const Sync *sync) const
{
return mSyncSet.find(const_cast<Sync *>(sync)) != mSyncSet.end();
}
bool Display::hasExistingWindowSurface(EGLNativeWindowType window) bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
{ {
WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); WindowSurfaceMap *windowSurfaces = GetWindowSurfaces();
...@@ -1056,8 +1098,8 @@ static ClientExtensions GenerateClientExtensions() ...@@ -1056,8 +1098,8 @@ static ClientExtensions GenerateClientExtensions()
#endif #endif
extensions.clientGetAllProcAddresses = true; extensions.clientGetAllProcAddresses = true;
extensions.explicitContext = true;
extensions.debug = true; extensions.debug = true;
extensions.explicitContext = true;
return extensions; return extensions;
} }
...@@ -1305,4 +1347,14 @@ EGLint Display::programCacheResize(EGLint limit, EGLenum mode) ...@@ -1305,4 +1347,14 @@ EGLint Display::programCacheResize(EGLint limit, EGLenum mode)
} }
} }
Error Display::clientWaitSync(Sync *sync, EGLint flags, EGLTime timeout, EGLint *outResult)
{
return sync->clientWait(this, flags, timeout, outResult);
}
Error Display::waitSync(Sync *sync, EGLint flags)
{
return sync->serverWait(this, flags);
}
} // namespace egl } // namespace egl
...@@ -39,8 +39,9 @@ namespace egl ...@@ -39,8 +39,9 @@ namespace egl
{ {
class Device; class Device;
class Image; class Image;
class Surface;
class Stream; class Stream;
class Surface;
class Sync;
class Thread; class Thread;
using SurfaceSet = std::set<Surface *>; using SurfaceSet = std::set<Surface *>;
...@@ -107,12 +108,15 @@ class Display final : public LabeledObject, angle::NonCopyable ...@@ -107,12 +108,15 @@ class Display final : public LabeledObject, angle::NonCopyable
const AttributeMap &attribs, const AttributeMap &attribs,
gl::Context **outContext); gl::Context **outContext);
Error createSync(EGLenum type, const AttributeMap &attribs, Sync **outSync);
Error makeCurrent(Surface *drawSurface, Surface *readSurface, gl::Context *context); Error makeCurrent(Surface *drawSurface, Surface *readSurface, gl::Context *context);
Error destroySurface(Surface *surface); Error destroySurface(Surface *surface);
void destroyImage(Image *image); void destroyImage(Image *image);
void destroyStream(Stream *stream); void destroyStream(Stream *stream);
Error destroyContext(const Thread *thread, gl::Context *context); Error destroyContext(const Thread *thread, gl::Context *context);
void destroySync(Sync *sync);
bool isInitialized() const; bool isInitialized() const;
bool isValidConfig(const Config *config) const; bool isValidConfig(const Config *config) const;
...@@ -120,6 +124,7 @@ class Display final : public LabeledObject, angle::NonCopyable ...@@ -120,6 +124,7 @@ class Display final : public LabeledObject, angle::NonCopyable
bool isValidSurface(const Surface *surface) const; bool isValidSurface(const Surface *surface) const;
bool isValidImage(const Image *image) const; bool isValidImage(const Image *image) const;
bool isValidStream(const Stream *stream) const; bool isValidStream(const Stream *stream) const;
bool isValidSync(const Sync *sync) const;
bool isValidNativeWindow(EGLNativeWindowType window) const; bool isValidNativeWindow(EGLNativeWindowType window) const;
Error validateClientBuffer(const Config *configuration, Error validateClientBuffer(const Config *configuration,
...@@ -164,6 +169,9 @@ class Display final : public LabeledObject, angle::NonCopyable ...@@ -164,6 +169,9 @@ class Display final : public LabeledObject, angle::NonCopyable
EGLint binarysize); EGLint binarysize);
EGLint programCacheResize(EGLint limit, EGLenum mode); EGLint programCacheResize(EGLint limit, EGLenum mode);
Error clientWaitSync(Sync *sync, EGLint flags, EGLTime timeout, EGLint *outResult);
Error waitSync(Sync *sync, EGLint flags);
const AttributeMap &getAttributeMap() const { return mAttributeMap; } const AttributeMap &getAttributeMap() const { return mAttributeMap; }
EGLNativeDisplayType getNativeDisplayId() const { return mDisplayId; } EGLNativeDisplayType getNativeDisplayId() const { return mDisplayId; }
...@@ -204,6 +212,9 @@ class Display final : public LabeledObject, angle::NonCopyable ...@@ -204,6 +212,9 @@ class Display final : public LabeledObject, angle::NonCopyable
typedef std::set<Stream *> StreamSet; typedef std::set<Stream *> StreamSet;
StreamSet mStreamSet; StreamSet mStreamSet;
typedef std::set<Sync *> SyncSet;
SyncSet mSyncSet;
bool mInitialized; bool mInitialized;
bool mDeviceLost; bool mDeviceLost;
......
//
// Copyright (c) 2002-2013 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.
//
// EGLSync.cpp: Implements the egl::Sync class.
#include "libANGLE/EGLSync.h"
#include "angle_gl.h"
#include "common/utilities.h"
#include "libANGLE/renderer/EGLImplFactory.h"
#include "libANGLE/renderer/EGLSyncImpl.h"
namespace egl
{
Sync::Sync(rx::EGLImplFactory *factory, EGLenum type, const AttributeMap &attribs)
: mFence(factory->createSync(attribs)), mType(type)
{}
void Sync::onDestroy(const Display *display)
{
ASSERT(mFence);
mFence->onDestroy(display);
mFence.reset();
}
Sync::~Sync() {}
Error Sync::initialize(const Display *display)
{
return mFence->initialize(display, mType);
}
Error Sync::clientWait(const Display *display, EGLint flags, EGLTime timeout, EGLint *outResult)
{
return mFence->clientWait(display, flags, timeout, outResult);
}
Error Sync::serverWait(const Display *display, EGLint flags)
{
return mFence->serverWait(display, flags);
}
Error Sync::getStatus(const Display *display, EGLint *outStatus) const
{
return mFence->getStatus(display, outStatus);
}
} // namespace egl
//
// Copyright 2019 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.
//
// EGLSync.h: Defines the egl::Sync classes, which support the EGL_KHR_fence_sync,
// EGL_KHR_wait_sync and EGL 1.5 sync objects.
#ifndef LIBANGLE_EGLSYNC_H_
#define LIBANGLE_EGLSYNC_H_
#include "libANGLE/Debug.h"
#include "libANGLE/Error.h"
#include "libANGLE/RefCountObject.h"
#include "common/angleutils.h"
namespace rx
{
class EGLImplFactory;
class EGLSyncImpl;
} // namespace rx
namespace egl
{
class Sync final : public angle::RefCountObject<Display, angle::Result>
{
public:
Sync(rx::EGLImplFactory *factory, EGLenum type, const AttributeMap &attribs);
~Sync() override;
void onDestroy(const Display *display) override;
Error initialize(const Display *display);
Error clientWait(const Display *display, EGLint flags, EGLTime timeout, EGLint *outResult);
Error serverWait(const Display *display, EGLint flags);
Error getStatus(const Display *display, EGLint *outStatus) const;
EGLenum getType() const { return mType; }
EGLint getCondition() const { return mCondition; }
private:
std::unique_ptr<rx::EGLSyncImpl> mFence;
EGLenum mType;
static constexpr EGLint mCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
};
} // namespace egl
#endif // LIBANGLE_FENCE_H_
...@@ -90,22 +90,22 @@ using ErrorStream = angle::ErrorStreamBase<Error, EGLint, EGL_SUCCESS, EGLint, E ...@@ -90,22 +90,22 @@ using ErrorStream = angle::ErrorStreamBase<Error, EGLint, EGL_SUCCESS, EGLint, E
} // namespace priv } // namespace priv
using EglNotInitialized = priv::ErrorStream<EGL_NOT_INITIALIZED>;
using EglBadAccess = priv::ErrorStream<EGL_BAD_ACCESS>; using EglBadAccess = priv::ErrorStream<EGL_BAD_ACCESS>;
using EglBadAlloc = priv::ErrorStream<EGL_BAD_ALLOC>; using EglBadAlloc = priv::ErrorStream<EGL_BAD_ALLOC>;
using EglBadAttribute = priv::ErrorStream<EGL_BAD_ATTRIBUTE>; using EglBadAttribute = priv::ErrorStream<EGL_BAD_ATTRIBUTE>;
using EglBadConfig = priv::ErrorStream<EGL_BAD_CONFIG>; using EglBadConfig = priv::ErrorStream<EGL_BAD_CONFIG>;
using EglBadContext = priv::ErrorStream<EGL_BAD_CONTEXT>; using EglBadContext = priv::ErrorStream<EGL_BAD_CONTEXT>;
using EglBadCurrentSurface = priv::ErrorStream<EGL_BAD_CURRENT_SURFACE>; using EglBadCurrentSurface = priv::ErrorStream<EGL_BAD_CURRENT_SURFACE>;
using EglBadDevice = priv::ErrorStream<EGL_BAD_DEVICE_EXT>;
using EglBadDisplay = priv::ErrorStream<EGL_BAD_DISPLAY>; using EglBadDisplay = priv::ErrorStream<EGL_BAD_DISPLAY>;
using EglBadMatch = priv::ErrorStream<EGL_BAD_MATCH>; using EglBadMatch = priv::ErrorStream<EGL_BAD_MATCH>;
using EglBadNativeWindow = priv::ErrorStream<EGL_BAD_NATIVE_WINDOW>; using EglBadNativeWindow = priv::ErrorStream<EGL_BAD_NATIVE_WINDOW>;
using EglBadParameter = priv::ErrorStream<EGL_BAD_PARAMETER>; using EglBadParameter = priv::ErrorStream<EGL_BAD_PARAMETER>;
using EglBadState = priv::ErrorStream<EGL_BAD_STATE_KHR>;
using EglBadStream = priv::ErrorStream<EGL_BAD_STREAM_KHR>;
using EglBadSurface = priv::ErrorStream<EGL_BAD_SURFACE>; using EglBadSurface = priv::ErrorStream<EGL_BAD_SURFACE>;
using EglContextLost = priv::ErrorStream<EGL_CONTEXT_LOST>; using EglContextLost = priv::ErrorStream<EGL_CONTEXT_LOST>;
using EglBadStream = priv::ErrorStream<EGL_BAD_STREAM_KHR>; using EglNotInitialized = priv::ErrorStream<EGL_NOT_INITIALIZED>;
using EglBadState = priv::ErrorStream<EGL_BAD_STATE_KHR>;
using EglBadDevice = priv::ErrorStream<EGL_BAD_DEVICE_EXT>;
inline Error NoError() inline Error NoError()
{ {
......
...@@ -4,8 +4,7 @@ ...@@ -4,8 +4,7 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
// Fence.cpp: Implements the gl::FenceNV and gl::Sync classes, which support the GL_NV_fence // Fence.cpp: Implements the gl::FenceNV and gl::Sync classes.
// extension and GLES3 sync objects.
#include "libANGLE/Fence.h" #include "libANGLE/Fence.h"
...@@ -66,7 +65,11 @@ Sync::Sync(rx::SyncImpl *impl, GLuint id) ...@@ -66,7 +65,11 @@ Sync::Sync(rx::SyncImpl *impl, GLuint id)
mFlags(0) mFlags(0)
{} {}
void Sync::onDestroy(const Context *context) {} void Sync::onDestroy(const Context *context)
{
ASSERT(mFence);
mFence->onDestroy(context);
}
Sync::~Sync() Sync::~Sync()
{ {
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#include "libANGLE/Buffer.h" #include "libANGLE/Buffer.h"
#include "libANGLE/Config.h" #include "libANGLE/Config.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/EGLSync.h"
#include "libANGLE/Fence.h" #include "libANGLE/Fence.h"
#include "libANGLE/Framebuffer.h" #include "libANGLE/Framebuffer.h"
#include "libANGLE/GLES1State.h" #include "libANGLE/GLES1State.h"
...@@ -3026,4 +3028,27 @@ void SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value) ...@@ -3026,4 +3028,27 @@ void SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value)
} }
} }
Error GetSyncAttrib(Display *display, Sync *sync, EGLint attribute, EGLint *value)
{
switch (attribute)
{
case EGL_SYNC_TYPE_KHR:
*value = sync->getType();
return NoError();
case EGL_SYNC_STATUS_KHR:
return sync->getStatus(display, value);
case EGL_SYNC_CONDITION_KHR:
*value = sync->getCondition();
return NoError();
default:
break;
}
UNREACHABLE();
return NoError();
}
} // namespace egl } // namespace egl
...@@ -231,7 +231,9 @@ unsigned int GetTexParameterCount(GLenum pname); ...@@ -231,7 +231,9 @@ unsigned int GetTexParameterCount(GLenum pname);
namespace egl namespace egl
{ {
struct Config; struct Config;
class Display;
class Surface; class Surface;
class Sync;
void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value); void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value);
...@@ -239,6 +241,7 @@ void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *va ...@@ -239,6 +241,7 @@ void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *va
void QuerySurfaceAttrib(const Surface *surface, EGLint attribute, EGLint *value); void QuerySurfaceAttrib(const Surface *surface, EGLint attribute, EGLint *value);
void SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value); void SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value);
Error GetSyncAttrib(Display *display, Sync *sync, EGLint attribute, EGLint *value);
} // namespace egl } // namespace egl
......
...@@ -31,6 +31,7 @@ class State; ...@@ -31,6 +31,7 @@ class State;
namespace rx namespace rx
{ {
class ContextImpl; class ContextImpl;
class EGLSyncImpl;
class ImageImpl; class ImageImpl;
class ExternalImageSiblingImpl; class ExternalImageSiblingImpl;
class SurfaceImpl; class SurfaceImpl;
...@@ -73,6 +74,8 @@ class EGLImplFactory : angle::NonCopyable ...@@ -73,6 +74,8 @@ class EGLImplFactory : angle::NonCopyable
EGLenum target, EGLenum target,
EGLClientBuffer buffer, EGLClientBuffer buffer,
const egl::AttributeMap &attribs); const egl::AttributeMap &attribs);
virtual EGLSyncImpl *createSync(const egl::AttributeMap &attribs);
}; };
inline ExternalImageSiblingImpl *EGLImplFactory::createExternalImageSibling( inline ExternalImageSiblingImpl *EGLImplFactory::createExternalImageSibling(
...@@ -85,6 +88,12 @@ inline ExternalImageSiblingImpl *EGLImplFactory::createExternalImageSibling( ...@@ -85,6 +88,12 @@ inline ExternalImageSiblingImpl *EGLImplFactory::createExternalImageSibling(
return nullptr; return nullptr;
} }
inline EGLSyncImpl *EGLImplFactory::createSync(const egl::AttributeMap &attribs)
{
UNREACHABLE();
return nullptr;
}
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_EGLIMPLFACTORY_H_ #endif // LIBANGLE_RENDERER_EGLIMPLFACTORY_H_
//
// Copyright 2019 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.
//
// EGLSyncImpl.h: Defines the rx::EGLSyncImpl class.
#ifndef LIBANGLE_RENDERER_EGLSYNCIMPL_H_
#define LIBANGLE_RENDERER_EGLSYNCIMPL_H_
#include "libANGLE/Error.h"
#include "common/angleutils.h"
#include "angle_gl.h"
namespace egl
{
class Display;
} // namespace egl
namespace rx
{
class EGLSyncImpl : angle::NonCopyable
{
public:
EGLSyncImpl(){};
virtual ~EGLSyncImpl(){};
virtual void onDestroy(const egl::Display *display) {}
virtual egl::Error initialize(const egl::Display *display, EGLenum type) = 0;
virtual egl::Error clientWait(const egl::Display *display,
EGLint flags,
EGLTime timeout,
EGLint *outResult) = 0;
virtual egl::Error serverWait(const egl::Display *display, EGLint flags) = 0;
virtual egl::Error getStatus(const egl::Display *display, EGLint *outStatus) = 0;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_EGLSYNCIMPL_H_
...@@ -28,6 +28,8 @@ class SyncImpl : angle::NonCopyable ...@@ -28,6 +28,8 @@ class SyncImpl : angle::NonCopyable
SyncImpl(){}; SyncImpl(){};
virtual ~SyncImpl(){}; virtual ~SyncImpl(){};
virtual void onDestroy(const gl::Context *context) {}
virtual angle::Result set(const gl::Context *context, GLenum condition, GLbitfield flags) = 0; virtual angle::Result set(const gl::Context *context, GLenum condition, GLbitfield flags) = 0;
virtual angle::Result clientWait(const gl::Context *context, virtual angle::Result clientWait(const gl::Context *context,
GLbitfield flags, GLbitfield flags,
......
...@@ -23,10 +23,14 @@ SyncGL::SyncGL(const FunctionsGL *functions) : SyncImpl(), mFunctions(functions) ...@@ -23,10 +23,14 @@ SyncGL::SyncGL(const FunctionsGL *functions) : SyncImpl(), mFunctions(functions)
SyncGL::~SyncGL() SyncGL::~SyncGL()
{ {
if (mSyncObject != 0) ASSERT(mSyncObject == 0);
{ }
mFunctions->deleteSync(mSyncObject);
} void SyncGL::onDestroy(const gl::Context *context)
{
ASSERT(mSyncObject != 0);
mFunctions->deleteSync(mSyncObject);
mSyncObject = 0;
} }
angle::Result SyncGL::set(const gl::Context *context, GLenum condition, GLbitfield flags) angle::Result SyncGL::set(const gl::Context *context, GLenum condition, GLbitfield flags)
......
...@@ -21,6 +21,8 @@ class SyncGL : public SyncImpl ...@@ -21,6 +21,8 @@ class SyncGL : public SyncImpl
explicit SyncGL(const FunctionsGL *functions); explicit SyncGL(const FunctionsGL *functions);
~SyncGL() override; ~SyncGL() override;
void onDestroy(const gl::Context *context) override;
angle::Result set(const gl::Context *context, GLenum condition, GLbitfield flags) override; angle::Result set(const gl::Context *context, GLenum condition, GLbitfield flags) override;
angle::Result clientWait(const gl::Context *context, angle::Result clientWait(const gl::Context *context,
GLbitfield flags, GLbitfield flags,
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "libANGLE/renderer/gl/egl/DisplayEGL.h" #include "libANGLE/renderer/gl/egl/DisplayEGL.h"
#include "libANGLE/renderer/gl/egl/ImageEGL.h" #include "libANGLE/renderer/gl/egl/ImageEGL.h"
#include "libANGLE/renderer/gl/egl/SyncEGL.h"
namespace rx namespace rx
{ {
...@@ -29,6 +30,11 @@ ImageImpl *DisplayEGL::createImage(const egl::ImageState &state, ...@@ -29,6 +30,11 @@ ImageImpl *DisplayEGL::createImage(const egl::ImageState &state,
return new ImageEGL(state, context, target, attribs, mEGL); return new ImageEGL(state, context, target, attribs, mEGL);
} }
EGLSyncImpl *DisplayEGL::createSync(const egl::AttributeMap &attribs)
{
return new SyncEGL(attribs, mEGL);
}
std::string DisplayEGL::getVendorString() const std::string DisplayEGL::getVendorString() const
{ {
const char *vendor = mEGL->queryString(EGL_VENDOR); const char *vendor = mEGL->queryString(EGL_VENDOR);
...@@ -107,6 +113,8 @@ egl::Error DisplayEGL::initializeContext(EGLContext shareContext, ...@@ -107,6 +113,8 @@ egl::Error DisplayEGL::initializeContext(EGLContext shareContext,
void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
{ {
gl::Version eglVersion(mEGL->majorVersion, mEGL->minorVersion);
outExtensions->createContextRobustness = outExtensions->createContextRobustness =
mEGL->hasExtension("EGL_EXT_create_context_robustness"); mEGL->hasExtension("EGL_EXT_create_context_robustness");
...@@ -133,6 +141,11 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -133,6 +141,11 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->getFrameTimestamps = mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps"); outExtensions->getFrameTimestamps = mEGL->hasExtension("EGL_ANDROID_get_frame_timestamps");
outExtensions->fenceSync =
eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_fence_sync");
outExtensions->waitSync =
eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_wait_sync");
DisplayGL::generateExtensions(outExtensions); DisplayGL::generateExtensions(outExtensions);
} }
......
...@@ -29,6 +29,8 @@ class DisplayEGL : public DisplayGL ...@@ -29,6 +29,8 @@ class DisplayEGL : public DisplayGL
EGLenum target, EGLenum target,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
EGLSyncImpl *createSync(const egl::AttributeMap &attribs) override;
std::string getVendorString() const override; std::string getVendorString() const override;
void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get) override; void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get) override;
......
...@@ -60,11 +60,13 @@ struct FunctionsEGL::EGLDispatchTable ...@@ -60,11 +60,13 @@ struct FunctionsEGL::EGLDispatchTable
createImageKHRPtr(nullptr), createImageKHRPtr(nullptr),
destroyImageKHRPtr(nullptr), destroyImageKHRPtr(nullptr),
clientWaitSyncKHRPtr(nullptr),
createSyncKHRPtr(nullptr), createSyncKHRPtr(nullptr),
destroySyncKHRPtr(nullptr), destroySyncKHRPtr(nullptr),
clientWaitSyncKHRPtr(nullptr),
getSyncAttribKHRPtr(nullptr), getSyncAttribKHRPtr(nullptr),
waitSyncKHRPtr(nullptr),
swapBuffersWithDamageKHRPtr(nullptr), swapBuffersWithDamageKHRPtr(nullptr),
presentationTimeANDROIDPtr(nullptr), presentationTimeANDROIDPtr(nullptr),
...@@ -107,11 +109,14 @@ struct FunctionsEGL::EGLDispatchTable ...@@ -107,11 +109,14 @@ struct FunctionsEGL::EGLDispatchTable
PFNEGLDESTROYIMAGEKHRPROC destroyImageKHRPtr; PFNEGLDESTROYIMAGEKHRPROC destroyImageKHRPtr;
// EGL_KHR_fence_sync // EGL_KHR_fence_sync
PFNEGLCLIENTWAITSYNCKHRPROC clientWaitSyncKHRPtr;
PFNEGLCREATESYNCKHRPROC createSyncKHRPtr; PFNEGLCREATESYNCKHRPROC createSyncKHRPtr;
PFNEGLDESTROYSYNCKHRPROC destroySyncKHRPtr; PFNEGLDESTROYSYNCKHRPROC destroySyncKHRPtr;
PFNEGLCLIENTWAITSYNCKHRPROC clientWaitSyncKHRPtr;
PFNEGLGETSYNCATTRIBKHRPROC getSyncAttribKHRPtr; PFNEGLGETSYNCATTRIBKHRPROC getSyncAttribKHRPtr;
// EGL_KHR_wait_sync
PFNEGLWAITSYNCKHRPROC waitSyncKHRPtr;
// EGL_KHR_swap_buffers_with_damage // EGL_KHR_swap_buffers_with_damage
PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC swapBuffersWithDamageKHRPtr; PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC swapBuffersWithDamageKHRPtr;
...@@ -200,11 +205,15 @@ egl::Error FunctionsEGL::initialize(EGLNativeDisplayType nativeDisplay) ...@@ -200,11 +205,15 @@ egl::Error FunctionsEGL::initialize(EGLNativeDisplayType nativeDisplay)
} }
if (hasExtension("EGL_KHR_fence_sync")) if (hasExtension("EGL_KHR_fence_sync"))
{ {
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->clientWaitSyncKHRPtr, eglClientWaitSyncKHR);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createSyncKHRPtr, eglCreateSyncKHR); ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createSyncKHRPtr, eglCreateSyncKHR);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->destroySyncKHRPtr, eglDestroySyncKHR); ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->destroySyncKHRPtr, eglDestroySyncKHR);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->clientWaitSyncKHRPtr, eglClientWaitSyncKHR);
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getSyncAttribKHRPtr, eglGetSyncAttribKHR); ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getSyncAttribKHRPtr, eglGetSyncAttribKHR);
} }
if (hasExtension("EGL_KHR_wait_sync"))
{
ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->waitSyncKHRPtr, eglWaitSyncKHR);
}
if (hasExtension("EGL_KHR_swap_buffers_with_damage")) if (hasExtension("EGL_KHR_swap_buffers_with_damage"))
{ {
...@@ -380,26 +389,31 @@ EGLBoolean FunctionsEGL::destroyImageKHR(EGLImageKHR image) const ...@@ -380,26 +389,31 @@ EGLBoolean FunctionsEGL::destroyImageKHR(EGLImageKHR image) const
return mFnPtrs->destroyImageKHRPtr(mEGLDisplay, image); return mFnPtrs->destroyImageKHRPtr(mEGLDisplay, image);
} }
EGLSyncKHR FunctionsEGL::createSyncKHR(EGLenum type, const EGLint *attrib_list) EGLSyncKHR FunctionsEGL::createSyncKHR(EGLenum type, const EGLint *attrib_list) const
{ {
return mFnPtrs->createSyncKHRPtr(mEGLDisplay, type, attrib_list); return mFnPtrs->createSyncKHRPtr(mEGLDisplay, type, attrib_list);
} }
EGLBoolean FunctionsEGL::destroySyncKHR(EGLSyncKHR sync) EGLBoolean FunctionsEGL::destroySyncKHR(EGLSyncKHR sync) const
{ {
return mFnPtrs->destroySyncKHRPtr(mEGLDisplay, sync); return mFnPtrs->destroySyncKHRPtr(mEGLDisplay, sync);
} }
EGLint FunctionsEGL::clientWaitSyncKHR(EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) EGLint FunctionsEGL::clientWaitSyncKHR(EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) const
{ {
return mFnPtrs->clientWaitSyncKHRPtr(mEGLDisplay, sync, flags, timeout); return mFnPtrs->clientWaitSyncKHRPtr(mEGLDisplay, sync, flags, timeout);
} }
EGLBoolean FunctionsEGL::getSyncAttribKHR(EGLSyncKHR sync, EGLint attribute, EGLint *value) EGLBoolean FunctionsEGL::getSyncAttribKHR(EGLSyncKHR sync, EGLint attribute, EGLint *value) const
{ {
return mFnPtrs->getSyncAttribKHRPtr(mEGLDisplay, sync, attribute, value); return mFnPtrs->getSyncAttribKHRPtr(mEGLDisplay, sync, attribute, value);
} }
EGLint FunctionsEGL::waitSyncKHR(EGLSyncKHR sync, EGLint flags) const
{
return mFnPtrs->waitSyncKHRPtr(mEGLDisplay, sync, flags);
}
EGLBoolean FunctionsEGL::swapBuffersWithDamageKHR(EGLSurface surface, EGLBoolean FunctionsEGL::swapBuffersWithDamageKHR(EGLSurface surface,
EGLint *rects, EGLint *rects,
EGLint n_rects) const EGLint n_rects) const
......
...@@ -71,10 +71,12 @@ class FunctionsEGL ...@@ -71,10 +71,12 @@ class FunctionsEGL
const EGLint *attrib_list) const; const EGLint *attrib_list) const;
EGLBoolean destroyImageKHR(EGLImageKHR image) const; EGLBoolean destroyImageKHR(EGLImageKHR image) const;
EGLSyncKHR createSyncKHR(EGLenum type, const EGLint *attrib_list); EGLSyncKHR createSyncKHR(EGLenum type, const EGLint *attrib_list) const;
EGLBoolean destroySyncKHR(EGLSyncKHR sync); EGLBoolean destroySyncKHR(EGLSyncKHR sync) const;
EGLint clientWaitSyncKHR(EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); EGLint clientWaitSyncKHR(EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) const;
EGLBoolean getSyncAttribKHR(EGLSyncKHR sync, EGLint attribute, EGLint *value); EGLBoolean getSyncAttribKHR(EGLSyncKHR sync, EGLint attribute, EGLint *value) const;
EGLint waitSyncKHR(EGLSyncKHR sync, EGLint flags) const;
EGLBoolean swapBuffersWithDamageKHR(EGLSurface surface, EGLint *rects, EGLint n_rects) const; EGLBoolean swapBuffersWithDamageKHR(EGLSurface surface, EGLint *rects, EGLint n_rects) const;
......
//
// Copyright 2019 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.
//
// SyncEGL.cpp: Implements the rx::SyncEGL class.
#include "libANGLE/renderer/gl/egl/SyncEGL.h"
#include "libANGLE/AttributeMap.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/gl/egl/FunctionsEGL.h"
namespace rx
{
SyncEGL::SyncEGL(const egl::AttributeMap &attribs, const FunctionsEGL *egl)
: mEGL(egl), mSync(EGL_NO_SYNC_KHR)
{}
SyncEGL::~SyncEGL()
{
ASSERT(mSync == EGL_NO_SYNC_KHR);
}
void SyncEGL::onDestroy(const egl::Display *display)
{
ASSERT(mSync != EGL_NO_SYNC_KHR);
mEGL->destroySyncKHR(mSync);
mSync = EGL_NO_SYNC_KHR;
}
egl::Error SyncEGL::initialize(const egl::Display *display, EGLenum type)
{
ASSERT(type == EGL_SYNC_FENCE_KHR);
mSync = mEGL->createSyncKHR(type, nullptr);
if (mSync == EGL_NO_SYNC_KHR)
{
return egl::Error(mEGL->getError(), "eglCreateSync failed to create sync object");
}
return egl::NoError();
}
egl::Error SyncEGL::clientWait(const egl::Display *display,
EGLint flags,
EGLTime timeout,
EGLint *outResult)
{
ASSERT(mSync != EGL_NO_SYNC_KHR);
EGLint result = mEGL->clientWaitSyncKHR(mSync, flags, timeout);
if (result == EGL_FALSE)
{
return egl::Error(mEGL->getError(), "eglClientWaitSync failed");
}
*outResult = result;
return egl::NoError();
}
egl::Error SyncEGL::serverWait(const egl::Display *display, EGLint flags)
{
ASSERT(mSync != EGL_NO_SYNC_KHR);
EGLint result = mEGL->waitSyncKHR(mSync, flags);
if (result == EGL_FALSE)
{
return egl::Error(mEGL->getError(), "eglWaitSync failed");
}
return egl::NoError();
}
egl::Error SyncEGL::getStatus(const egl::Display *display, EGLint *outStatus)
{
ASSERT(mSync != EGL_NO_SYNC_KHR);
EGLBoolean result = mEGL->getSyncAttribKHR(mSync, EGL_SYNC_STATUS_KHR, outStatus);
if (result == EGL_FALSE)
{
return egl::Error(mEGL->getError(), "eglGetSyncAttribKHR with EGL_SYNC_STATUS_KHR failed");
}
return egl::NoError();
}
} // namespace rx
//
// Copyright 2019 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.
//
// SyncEGL.h: Defines the rx::SyncEGL class, the EGL implementation of EGL sync objects.
#ifndef LIBANGLE_RENDERER_GL_EGL_SYNCEGL_H_
#define LIBANGLE_RENDERER_GL_EGL_SYNCEGL_H_
#include "libANGLE/renderer/EGLSyncImpl.h"
namespace egl
{
class AttributeMap;
}
namespace rx
{
class FunctionsEGL;
class SyncEGL final : public EGLSyncImpl
{
public:
SyncEGL(const egl::AttributeMap &attribs, const FunctionsEGL *egl);
~SyncEGL() override;
void onDestroy(const egl::Display *display) override;
egl::Error initialize(const egl::Display *display, EGLenum type) override;
egl::Error clientWait(const egl::Display *display,
EGLint flags,
EGLTime timeout,
EGLint *outResult) override;
egl::Error serverWait(const egl::Display *display, EGLint flags) override;
egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override;
private:
const FunctionsEGL *mEGL;
EGLSync mSync;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_GL_EGL_IMAGEEGL_H_
...@@ -1150,6 +1150,8 @@ void GenerateCaps(const FunctionsGL *functions, ...@@ -1150,6 +1150,8 @@ void GenerateCaps(const FunctionsGL *functions,
extensions->eglImageExternalEssl3 = extensions->eglImageExternalEssl3 =
functions->hasGLESExtension("GL_OES_EGL_image_external_essl3"); functions->hasGLESExtension("GL_OES_EGL_image_external_essl3");
extensions->eglSync = functions->hasGLESExtension("GL_OES_EGL_sync");
if (functions->isAtLeastGL(gl::Version(3, 3)) || if (functions->isAtLeastGL(gl::Version(3, 3)) ||
functions->hasGLExtension("GL_ARB_timer_query") || functions->hasGLExtension("GL_ARB_timer_query") ||
functions->hasGLESExtension("GL_EXT_disjoint_timer_query")) functions->hasGLESExtension("GL_EXT_disjoint_timer_query"))
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Device.h" #include "libANGLE/Device.h"
#include "libANGLE/Display.h" #include "libANGLE/Display.h"
#include "libANGLE/EGLSync.h"
#include "libANGLE/Image.h" #include "libANGLE/Image.h"
#include "libANGLE/Stream.h" #include "libANGLE/Stream.h"
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
...@@ -807,6 +808,18 @@ Error ValidateDevice(const Device *device) ...@@ -807,6 +808,18 @@ Error ValidateDevice(const Device *device)
return NoError(); return NoError();
} }
Error ValidateSync(const Display *display, const Sync *sync)
{
ANGLE_TRY(ValidateDisplay(display));
if (!display->isValidSync(sync))
{
return EglBadParameter() << "sync object is not valid.";
}
return NoError();
}
const Thread *GetThreadIfValid(const Thread *thread) const Thread *GetThreadIfValid(const Thread *thread)
{ {
// Threads should always be valid // Threads should always be valid
...@@ -873,6 +886,16 @@ const Device *GetDeviceIfValid(const Device *device) ...@@ -873,6 +886,16 @@ const Device *GetDeviceIfValid(const Device *device)
return device; return device;
} }
const Sync *GetSyncIfValid(const Display *display, const Sync *sync)
{
if (ValidateSync(display, sync).isError())
{
return nullptr;
}
return sync;
}
LabeledObject *GetLabeledObjectIfValid(Thread *thread, LabeledObject *GetLabeledObjectIfValid(Thread *thread,
const Display *display, const Display *display,
ObjectType objectType, ObjectType objectType,
...@@ -2084,6 +2107,172 @@ Error ValidateReleaseDeviceANGLE(Device *device) ...@@ -2084,6 +2107,172 @@ Error ValidateReleaseDeviceANGLE(Device *device)
return NoError(); return NoError();
} }
Error ValidateCreateSyncBase(const Display *display,
EGLenum type,
const AttributeMap &attribs,
const Display *currentDisplay,
const gl::Context *currentContext,
bool isExt)
{
ANGLE_TRY(ValidateDisplay(display));
switch (type)
{
case EGL_SYNC_FENCE_KHR:
if (!attribs.isEmpty())
{
return EglBadAttribute() << "Invalid attribute";
}
if (display != currentDisplay)
{
return EglBadMatch() << "CreateSync can only be called on the current display";
}
ANGLE_TRY(ValidateContext(currentDisplay, currentContext));
if (!currentContext->getExtensions().eglSync)
{
return EglBadMatch() << "EGL_SYNC_FENCE_KHR cannot be used without "
"GL_OES_EGL_sync support.";
}
break;
default:
if (isExt)
{
return EglBadAttribute() << "Invalid type parameter";
}
else
{
return EglBadParameter() << "Invalid type parameter";
}
}
return NoError();
}
Error ValidateGetSyncAttribBase(const Display *display, const Sync *sync, EGLint attribute)
{
ANGLE_TRY(ValidateSync(display, sync));
switch (attribute)
{
case EGL_SYNC_CONDITION_KHR:
if (sync->getType() != EGL_SYNC_FENCE_KHR)
{
return EglBadAttribute() << "EGL_SYNC_CONDITION_KHR is only valid for fence syncs";
}
break;
// The following attributes are accepted by all types
case EGL_SYNC_TYPE_KHR:
case EGL_SYNC_STATUS_KHR:
break;
default:
return EglBadAttribute() << "Invalid attribute";
}
return NoError();
}
Error ValidateCreateSyncKHR(const Display *display,
EGLenum type,
const AttributeMap &attribs,
const Display *currentDisplay,
const gl::Context *currentContext)
{
ANGLE_TRY(ValidateDisplay(display));
const DisplayExtensions &extensions = display->getExtensions();
if (!extensions.fenceSync)
{
return EglBadAccess() << "EGL_KHR_fence_sync extension is not available";
}
return ValidateCreateSyncBase(display, type, attribs, currentDisplay, currentContext, true);
}
Error ValidateCreateSync(const Display *display,
EGLenum type,
const AttributeMap &attribs,
const Display *currentDisplay,
const gl::Context *currentContext)
{
return ValidateCreateSyncBase(display, type, attribs, currentDisplay, currentContext, false);
}
Error ValidateDestroySync(const Display *display, const Sync *sync)
{
ANGLE_TRY(ValidateSync(display, sync));
return NoError();
}
Error ValidateClientWaitSync(const Display *display,
const Sync *sync,
EGLint flags,
EGLTime timeout)
{
ANGLE_TRY(ValidateSync(display, sync));
return NoError();
}
Error ValidateWaitSync(const Display *display,
const gl::Context *context,
const Sync *sync,
EGLint flags)
{
ANGLE_TRY(ValidateDisplay(display));
const DisplayExtensions &extensions = display->getExtensions();
if (!extensions.waitSync)
{
return EglBadAccess() << "EGL_KHR_wait_sync extension is not available";
}
ANGLE_TRY(ValidateSync(display, sync));
if (context == nullptr)
{
return EglBadMatch() << "No context is current.";
}
if (!context->getExtensions().eglSync)
{
return EglBadMatch() << "Server-side waits cannot be performed without "
"GL_OES_EGL_sync support.";
}
if (flags != 0)
{
return EglBadParameter() << "flags must be zero";
}
return NoError();
}
Error ValidateGetSyncAttribKHR(const Display *display,
const Sync *sync,
EGLint attribute,
EGLint *value)
{
if (value == nullptr)
{
return EglBadParameter() << "Invalid value parameter";
}
return ValidateGetSyncAttribBase(display, sync, attribute);
}
Error ValidateGetSyncAttrib(const Display *display,
const Sync *sync,
EGLint attribute,
EGLAttrib *value)
{
if (value == nullptr)
{
return EglBadParameter() << "Invalid value parameter";
}
return ValidateGetSyncAttribBase(display, sync, attribute);
}
Error ValidateCreateStreamKHR(const Display *display, const AttributeMap &attributes) Error ValidateCreateStreamKHR(const Display *display, const AttributeMap &attributes)
{ {
ANGLE_TRY(ValidateDisplay(display)); ANGLE_TRY(ValidateDisplay(display));
...@@ -2174,7 +2363,6 @@ Error ValidateStreamConsumerGLTextureExternalKHR(const Display *display, ...@@ -2174,7 +2363,6 @@ Error ValidateStreamConsumerGLTextureExternalKHR(const Display *display,
gl::Context *context, gl::Context *context,
const Stream *stream) const Stream *stream)
{ {
ANGLE_TRY(ValidateDisplay(display));
ANGLE_TRY(ValidateContext(display, context)); ANGLE_TRY(ValidateContext(display, context));
const DisplayExtensions &displayExtensions = display->getExtensions(); const DisplayExtensions &displayExtensions = display->getExtensions();
...@@ -3256,7 +3444,6 @@ Error ValidateQueryContext(const Display *display, ...@@ -3256,7 +3444,6 @@ Error ValidateQueryContext(const Display *display,
EGLint attribute, EGLint attribute,
EGLint *value) EGLint *value)
{ {
ANGLE_TRY(ValidateDisplay(display));
ANGLE_TRY(ValidateContext(display, context)); ANGLE_TRY(ValidateContext(display, context));
switch (attribute) switch (attribute)
......
...@@ -32,6 +32,7 @@ class Display; ...@@ -32,6 +32,7 @@ class Display;
class Image; class Image;
class Stream; class Stream;
class Surface; class Surface;
class Sync;
class Thread; class Thread;
class LabeledObject; class LabeledObject;
...@@ -42,6 +43,7 @@ Error ValidateConfig(const Display *display, const Config *config); ...@@ -42,6 +43,7 @@ Error ValidateConfig(const Display *display, const Config *config);
Error ValidateContext(const Display *display, const gl::Context *context); Error ValidateContext(const Display *display, const gl::Context *context);
Error ValidateImage(const Display *display, const Image *image); Error ValidateImage(const Display *display, const Image *image);
Error ValidateDevice(const Device *device); Error ValidateDevice(const Device *device);
Error ValidateSync(const Device *device, const Sync *sync);
// Return the requested object only if it is valid (otherwise nullptr) // Return the requested object only if it is valid (otherwise nullptr)
const Thread *GetThreadIfValid(const Thread *thread); const Thread *GetThreadIfValid(const Thread *thread);
...@@ -51,6 +53,7 @@ const Image *GetImageIfValid(const Display *display, const Image *image); ...@@ -51,6 +53,7 @@ const Image *GetImageIfValid(const Display *display, const Image *image);
const Stream *GetStreamIfValid(const Display *display, const Stream *stream); const Stream *GetStreamIfValid(const Display *display, const Stream *stream);
const gl::Context *GetContextIfValid(const Display *display, const gl::Context *context); const gl::Context *GetContextIfValid(const Display *display, const gl::Context *context);
const Device *GetDeviceIfValid(const Device *device); const Device *GetDeviceIfValid(const Device *device);
const Sync *GetSyncIfValid(const Display *display, const Sync *sync);
LabeledObject *GetLabeledObjectIfValid(Thread *thread, LabeledObject *GetLabeledObjectIfValid(Thread *thread,
const Display *display, const Display *display,
ObjectType objectType, ObjectType objectType,
...@@ -94,6 +97,42 @@ Error ValidateCreateDeviceANGLE(EGLint device_type, ...@@ -94,6 +97,42 @@ Error ValidateCreateDeviceANGLE(EGLint device_type,
const EGLAttrib *attrib_list); const EGLAttrib *attrib_list);
Error ValidateReleaseDeviceANGLE(Device *device); Error ValidateReleaseDeviceANGLE(Device *device);
Error ValidateCreateSyncBase(const Display *display,
EGLenum type,
const AttributeMap &attribs,
const Display *currentDisplay,
const gl::Context *currentContext,
bool isExt);
Error ValidateGetSyncAttribBase(const Display *display, const Sync *sync, EGLint attribute);
Error ValidateCreateSyncKHR(const Display *display,
EGLenum type,
const AttributeMap &attribs,
const Display *currentDisplay,
const gl::Context *currentContext);
Error ValidateCreateSync(const Display *display,
EGLenum type,
const AttributeMap &attribs,
const Display *currentDisplay,
const gl::Context *currentContext);
Error ValidateDestroySync(const Display *display, const Sync *sync);
Error ValidateClientWaitSync(const Display *display,
const Sync *sync,
EGLint flags,
EGLTime timeout);
Error ValidateWaitSync(const Display *display,
const gl::Context *context,
const Sync *sync,
EGLint flags);
Error ValidateGetSyncAttribKHR(const Display *display,
const Sync *sync,
EGLint attribute,
EGLint *value);
Error ValidateGetSyncAttrib(const Display *display,
const Sync *sync,
EGLint attribute,
EGLAttrib *value);
Error ValidateCreateStreamKHR(const Display *display, const AttributeMap &attributes); Error ValidateCreateStreamKHR(const Display *display, const AttributeMap &attributes);
Error ValidateDestroyStreamKHR(const Display *display, const Stream *stream); Error ValidateDestroyStreamKHR(const Display *display, const Stream *stream);
Error ValidateStreamAttribKHR(const Display *display, Error ValidateStreamAttribKHR(const Display *display,
......
...@@ -80,6 +80,10 @@ PFNEGLGETPLATFORMDISPLAYEXTPROC EGL_GetPlatformDisplayEXT; ...@@ -80,6 +80,10 @@ PFNEGLGETPLATFORMDISPLAYEXTPROC EGL_GetPlatformDisplayEXT;
PFNEGLDEBUGMESSAGECONTROLKHRPROC EGL_DebugMessageControlKHR; PFNEGLDEBUGMESSAGECONTROLKHRPROC EGL_DebugMessageControlKHR;
PFNEGLLABELOBJECTKHRPROC EGL_LabelObjectKHR; PFNEGLLABELOBJECTKHRPROC EGL_LabelObjectKHR;
PFNEGLQUERYDEBUGKHRPROC EGL_QueryDebugKHR; PFNEGLQUERYDEBUGKHRPROC EGL_QueryDebugKHR;
PFNEGLCLIENTWAITSYNCKHRPROC EGL_ClientWaitSyncKHR;
PFNEGLCREATESYNCKHRPROC EGL_CreateSyncKHR;
PFNEGLDESTROYSYNCKHRPROC EGL_DestroySyncKHR;
PFNEGLGETSYNCATTRIBKHRPROC EGL_GetSyncAttribKHR;
PFNEGLCREATEIMAGEKHRPROC EGL_CreateImageKHR; PFNEGLCREATEIMAGEKHRPROC EGL_CreateImageKHR;
PFNEGLDESTROYIMAGEKHRPROC EGL_DestroyImageKHR; PFNEGLDESTROYIMAGEKHRPROC EGL_DestroyImageKHR;
PFNEGLCREATESTREAMKHRPROC EGL_CreateStreamKHR; PFNEGLCREATESTREAMKHRPROC EGL_CreateStreamKHR;
...@@ -91,6 +95,7 @@ PFNEGLSTREAMCONSUMERACQUIREKHRPROC EGL_StreamConsumerAcquireKHR; ...@@ -91,6 +95,7 @@ PFNEGLSTREAMCONSUMERACQUIREKHRPROC EGL_StreamConsumerAcquireKHR;
PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC EGL_StreamConsumerGLTextureExternalKHR; PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC EGL_StreamConsumerGLTextureExternalKHR;
PFNEGLSTREAMCONSUMERRELEASEKHRPROC EGL_StreamConsumerReleaseKHR; PFNEGLSTREAMCONSUMERRELEASEKHRPROC EGL_StreamConsumerReleaseKHR;
PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC EGL_SwapBuffersWithDamageKHR; PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC EGL_SwapBuffersWithDamageKHR;
PFNEGLWAITSYNCKHRPROC EGL_WaitSyncKHR;
PFNEGLPOSTSUBBUFFERNVPROC EGL_PostSubBufferNV; PFNEGLPOSTSUBBUFFERNVPROC EGL_PostSubBufferNV;
PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC EGL_StreamConsumerGLTextureExternalAttribsNV; PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC EGL_StreamConsumerGLTextureExternalAttribsNV;
...@@ -207,6 +212,12 @@ void LoadEGL(LoadProc loadProc) ...@@ -207,6 +212,12 @@ void LoadEGL(LoadProc loadProc)
reinterpret_cast<PFNEGLDEBUGMESSAGECONTROLKHRPROC>(loadProc("EGL_DebugMessageControlKHR")); reinterpret_cast<PFNEGLDEBUGMESSAGECONTROLKHRPROC>(loadProc("EGL_DebugMessageControlKHR"));
EGL_LabelObjectKHR = reinterpret_cast<PFNEGLLABELOBJECTKHRPROC>(loadProc("EGL_LabelObjectKHR")); EGL_LabelObjectKHR = reinterpret_cast<PFNEGLLABELOBJECTKHRPROC>(loadProc("EGL_LabelObjectKHR"));
EGL_QueryDebugKHR = reinterpret_cast<PFNEGLQUERYDEBUGKHRPROC>(loadProc("EGL_QueryDebugKHR")); EGL_QueryDebugKHR = reinterpret_cast<PFNEGLQUERYDEBUGKHRPROC>(loadProc("EGL_QueryDebugKHR"));
EGL_ClientWaitSyncKHR =
reinterpret_cast<PFNEGLCLIENTWAITSYNCKHRPROC>(loadProc("EGL_ClientWaitSyncKHR"));
EGL_CreateSyncKHR = reinterpret_cast<PFNEGLCREATESYNCKHRPROC>(loadProc("EGL_CreateSyncKHR"));
EGL_DestroySyncKHR = reinterpret_cast<PFNEGLDESTROYSYNCKHRPROC>(loadProc("EGL_DestroySyncKHR"));
EGL_GetSyncAttribKHR =
reinterpret_cast<PFNEGLGETSYNCATTRIBKHRPROC>(loadProc("EGL_GetSyncAttribKHR"));
EGL_CreateImageKHR = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(loadProc("EGL_CreateImageKHR")); EGL_CreateImageKHR = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(loadProc("EGL_CreateImageKHR"));
EGL_DestroyImageKHR = EGL_DestroyImageKHR =
reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(loadProc("EGL_DestroyImageKHR")); reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(loadProc("EGL_DestroyImageKHR"));
...@@ -228,6 +239,7 @@ void LoadEGL(LoadProc loadProc) ...@@ -228,6 +239,7 @@ void LoadEGL(LoadProc loadProc)
loadProc("EGL_StreamConsumerReleaseKHR")); loadProc("EGL_StreamConsumerReleaseKHR"));
EGL_SwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC>( EGL_SwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC>(
loadProc("EGL_SwapBuffersWithDamageKHR")); loadProc("EGL_SwapBuffersWithDamageKHR"));
EGL_WaitSyncKHR = reinterpret_cast<PFNEGLWAITSYNCKHRPROC>(loadProc("EGL_WaitSyncKHR"));
EGL_PostSubBufferNV = EGL_PostSubBufferNV =
reinterpret_cast<PFNEGLPOSTSUBBUFFERNVPROC>(loadProc("EGL_PostSubBufferNV")); reinterpret_cast<PFNEGLPOSTSUBBUFFERNVPROC>(loadProc("EGL_PostSubBufferNV"));
EGL_StreamConsumerGLTextureExternalAttribsNV = EGL_StreamConsumerGLTextureExternalAttribsNV =
......
...@@ -84,6 +84,10 @@ extern PFNEGLGETPLATFORMDISPLAYEXTPROC EGL_GetPlatformDisplayEXT; ...@@ -84,6 +84,10 @@ extern PFNEGLGETPLATFORMDISPLAYEXTPROC EGL_GetPlatformDisplayEXT;
extern PFNEGLDEBUGMESSAGECONTROLKHRPROC EGL_DebugMessageControlKHR; extern PFNEGLDEBUGMESSAGECONTROLKHRPROC EGL_DebugMessageControlKHR;
extern PFNEGLLABELOBJECTKHRPROC EGL_LabelObjectKHR; extern PFNEGLLABELOBJECTKHRPROC EGL_LabelObjectKHR;
extern PFNEGLQUERYDEBUGKHRPROC EGL_QueryDebugKHR; extern PFNEGLQUERYDEBUGKHRPROC EGL_QueryDebugKHR;
extern PFNEGLCLIENTWAITSYNCKHRPROC EGL_ClientWaitSyncKHR;
extern PFNEGLCREATESYNCKHRPROC EGL_CreateSyncKHR;
extern PFNEGLDESTROYSYNCKHRPROC EGL_DestroySyncKHR;
extern PFNEGLGETSYNCATTRIBKHRPROC EGL_GetSyncAttribKHR;
extern PFNEGLCREATEIMAGEKHRPROC EGL_CreateImageKHR; extern PFNEGLCREATEIMAGEKHRPROC EGL_CreateImageKHR;
extern PFNEGLDESTROYIMAGEKHRPROC EGL_DestroyImageKHR; extern PFNEGLDESTROYIMAGEKHRPROC EGL_DestroyImageKHR;
extern PFNEGLCREATESTREAMKHRPROC EGL_CreateStreamKHR; extern PFNEGLCREATESTREAMKHRPROC EGL_CreateStreamKHR;
...@@ -95,6 +99,7 @@ extern PFNEGLSTREAMCONSUMERACQUIREKHRPROC EGL_StreamConsumerAcquireKHR; ...@@ -95,6 +99,7 @@ extern PFNEGLSTREAMCONSUMERACQUIREKHRPROC EGL_StreamConsumerAcquireKHR;
extern PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC EGL_StreamConsumerGLTextureExternalKHR; extern PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC EGL_StreamConsumerGLTextureExternalKHR;
extern PFNEGLSTREAMCONSUMERRELEASEKHRPROC EGL_StreamConsumerReleaseKHR; extern PFNEGLSTREAMCONSUMERRELEASEKHRPROC EGL_StreamConsumerReleaseKHR;
extern PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC EGL_SwapBuffersWithDamageKHR; extern PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC EGL_SwapBuffersWithDamageKHR;
extern PFNEGLWAITSYNCKHRPROC EGL_WaitSyncKHR;
extern PFNEGLPOSTSUBBUFFERNVPROC EGL_PostSubBufferNV; extern PFNEGLPOSTSUBBUFFERNVPROC EGL_PostSubBufferNV;
extern PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC extern PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC
EGL_StreamConsumerGLTextureExternalAttribsNV; EGL_StreamConsumerGLTextureExternalAttribsNV;
......
...@@ -174,6 +174,8 @@ libangle_sources = [ ...@@ -174,6 +174,8 @@ libangle_sources = [
"src/libANGLE/Device.h", "src/libANGLE/Device.h",
"src/libANGLE/Display.cpp", "src/libANGLE/Display.cpp",
"src/libANGLE/Display.h", "src/libANGLE/Display.h",
"src/libANGLE/EGLSync.cpp",
"src/libANGLE/EGLSync.h",
"src/libANGLE/Error.cpp", "src/libANGLE/Error.cpp",
"src/libANGLE/Error.h", "src/libANGLE/Error.h",
"src/libANGLE/Error.inl", "src/libANGLE/Error.inl",
...@@ -277,6 +279,7 @@ libangle_sources = [ ...@@ -277,6 +279,7 @@ libangle_sources = [
"src/libANGLE/renderer/DisplayImpl.cpp", "src/libANGLE/renderer/DisplayImpl.cpp",
"src/libANGLE/renderer/DisplayImpl.h", "src/libANGLE/renderer/DisplayImpl.h",
"src/libANGLE/renderer/EGLImplFactory.h", "src/libANGLE/renderer/EGLImplFactory.h",
"src/libANGLE/renderer/EGLSyncImpl.h",
"src/libANGLE/renderer/FenceNVImpl.h", "src/libANGLE/renderer/FenceNVImpl.h",
"src/libANGLE/renderer/FormatID_autogen.h", "src/libANGLE/renderer/FormatID_autogen.h",
"src/libANGLE/renderer/Format_table_autogen.cpp", "src/libANGLE/renderer/Format_table_autogen.cpp",
...@@ -705,6 +708,8 @@ libangle_gl_egl_sources = [ ...@@ -705,6 +708,8 @@ libangle_gl_egl_sources = [
"src/libANGLE/renderer/gl/egl/RendererEGL.h", "src/libANGLE/renderer/gl/egl/RendererEGL.h",
"src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp", "src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp",
"src/libANGLE/renderer/gl/egl/SurfaceEGL.h", "src/libANGLE/renderer/gl/egl/SurfaceEGL.h",
"src/libANGLE/renderer/gl/egl/SyncEGL.cpp",
"src/libANGLE/renderer/gl/egl/SyncEGL.h",
"src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.cpp", "src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.cpp",
"src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.h", "src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.h",
] ]
......
...@@ -821,14 +821,24 @@ EGLSync EGLAPIENTRY EGL_CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib ...@@ -821,14 +821,24 @@ EGLSync EGLAPIENTRY EGL_CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR
", EGLenum type = 0x%X, const EGLint* attrib_list = 0x%016" PRIxPTR ")", ", EGLenum type = 0x%X, const EGLint* attrib_list = 0x%016" PRIxPTR ")",
(uintptr_t)dpy, type, (uintptr_t)attrib_list); (uintptr_t)dpy, type, (uintptr_t)attrib_list);
Thread *thread = egl::GetCurrentThread(); Thread *thread = egl::GetCurrentThread();
egl::Display *display = static_cast<egl::Display *>(dpy); egl::Display *display = static_cast<egl::Display *>(dpy);
AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
UNIMPLEMENTED(); gl::Context *currentContext = thread->getContext();
// TODO(geofflang): Implement sync objects. http://anglebug.com/2466 egl::Display *currentDisplay = currentContext ? currentContext->getCurrentDisplay() : nullptr;
thread->setError(EglBadDisplay() << "eglCreateSync unimplemented.", GetDebug(), "eglCreateSync",
GetDisplayIfValid(display)); ANGLE_EGL_TRY_RETURN(
return EGL_NO_SYNC; thread, ValidateCreateSyncKHR(display, type, attributes, currentDisplay, currentContext),
"eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
egl::Sync *syncObject = nullptr;
ANGLE_EGL_TRY_RETURN(thread, display->createSync(type, attributes, &syncObject),
"eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
thread->setSuccess();
return static_cast<EGLSync>(syncObject);
} }
EGLBoolean EGLAPIENTRY EGL_DestroySync(EGLDisplay dpy, EGLSync sync) EGLBoolean EGLAPIENTRY EGL_DestroySync(EGLDisplay dpy, EGLSync sync)
...@@ -836,13 +846,18 @@ EGLBoolean EGLAPIENTRY EGL_DestroySync(EGLDisplay dpy, EGLSync sync) ...@@ -836,13 +846,18 @@ EGLBoolean EGLAPIENTRY EGL_DestroySync(EGLDisplay dpy, EGLSync sync)
ANGLE_SCOPED_GLOBAL_LOCK(); ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSync sync = 0x%016" PRIxPTR ")", (uintptr_t)dpy, EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSync sync = 0x%016" PRIxPTR ")", (uintptr_t)dpy,
(uintptr_t)sync); (uintptr_t)sync);
Thread *thread = egl::GetCurrentThread();
UNIMPLEMENTED(); Thread *thread = egl::GetCurrentThread();
// TODO(geofflang): Pass the EGL sync object to the setError function. http://anglebug.com/2466 egl::Display *display = static_cast<egl::Display *>(dpy);
thread->setError(EglBadDisplay() << "eglDestroySync unimplemented.", GetDebug(), egl::Sync *syncObject = static_cast<Sync *>(sync);
"eglDestroySync", nullptr);
return EGL_FALSE; ANGLE_EGL_TRY_RETURN(thread, ValidateDestroySync(display, syncObject), "eglDestroySync",
GetDisplayIfValid(display), EGL_FALSE);
display->destroySync(syncObject);
thread->setSuccess();
return EGL_TRUE;
} }
EGLint EGLAPIENTRY EGL_ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) EGLint EGLAPIENTRY EGL_ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
...@@ -852,13 +867,20 @@ EGLint EGLAPIENTRY EGL_ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags ...@@ -852,13 +867,20 @@ EGLint EGLAPIENTRY EGL_ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags
", EGLint flags = 0x%X, EGLTime timeout = " ", EGLint flags = 0x%X, EGLTime timeout = "
"%llu)", "%llu)",
(uintptr_t)dpy, (uintptr_t)sync, flags, static_cast<unsigned long long>(timeout)); (uintptr_t)dpy, (uintptr_t)sync, flags, static_cast<unsigned long long>(timeout));
Thread *thread = egl::GetCurrentThread();
UNIMPLEMENTED(); Thread *thread = egl::GetCurrentThread();
// TODO(geofflang): Pass the EGL sync object to the setError function. http://anglebug.com/2466 egl::Display *display = static_cast<egl::Display *>(dpy);
thread->setError(EglBadDisplay() << "eglClientWaitSync unimplemented.", GetDebug(), egl::Sync *syncObject = static_cast<Sync *>(sync);
"eglClientWaitSync", nullptr);
return 0; ANGLE_EGL_TRY_RETURN(thread, ValidateClientWaitSync(display, syncObject, flags, timeout),
"eglClientWaitSync", GetDisplayIfValid(display), EGL_FALSE);
EGLint syncStatus = EGL_FALSE;
ANGLE_EGL_TRY_RETURN(thread, display->clientWaitSync(syncObject, flags, timeout, &syncStatus),
"eglClientWaitSync", GetDisplayIfValid(display), EGL_FALSE);
thread->setSuccess();
return syncStatus;
} }
EGLBoolean EGLAPIENTRY EGL_GetSyncAttrib(EGLDisplay dpy, EGLBoolean EGLAPIENTRY EGL_GetSyncAttrib(EGLDisplay dpy,
...@@ -871,13 +893,21 @@ EGLBoolean EGLAPIENTRY EGL_GetSyncAttrib(EGLDisplay dpy, ...@@ -871,13 +893,21 @@ EGLBoolean EGLAPIENTRY EGL_GetSyncAttrib(EGLDisplay dpy,
", EGLint attribute = 0x%X, EGLAttrib " ", EGLint attribute = 0x%X, EGLAttrib "
"*value = 0x%016" PRIxPTR ")", "*value = 0x%016" PRIxPTR ")",
(uintptr_t)dpy, (uintptr_t)sync, attribute, (uintptr_t)value); (uintptr_t)dpy, (uintptr_t)sync, attribute, (uintptr_t)value);
Thread *thread = egl::GetCurrentThread();
UNIMPLEMENTED(); Thread *thread = egl::GetCurrentThread();
// TODO(geofflang): Pass the EGL sync object to the setError function. http://anglebug.com/2466 egl::Display *display = static_cast<egl::Display *>(dpy);
thread->setError(EglBadDisplay() << "eglSyncAttrib unimplemented.", GetDebug(), egl::Sync *syncObject = static_cast<Sync *>(sync);
"eglGetSyncAttrib", nullptr);
return EGL_FALSE; ANGLE_EGL_TRY_RETURN(thread, ValidateGetSyncAttrib(display, syncObject, attribute, value),
"eglGetSyncAttrib", GetDisplayIfValid(display), EGL_FALSE);
EGLint valueExt;
ANGLE_EGL_TRY_RETURN(thread, GetSyncAttrib(display, syncObject, attribute, &valueExt),
"eglGetSyncAttrib", GetDisplayIfValid(display), EGL_FALSE);
*value = valueExt;
thread->setSuccess();
return EGL_TRUE;
} }
EGLImage EGLAPIENTRY EGL_CreateImage(EGLDisplay dpy, EGLImage EGLAPIENTRY EGL_CreateImage(EGLDisplay dpy,
...@@ -994,13 +1024,20 @@ EGLBoolean EGLAPIENTRY EGL_WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) ...@@ -994,13 +1024,20 @@ EGLBoolean EGLAPIENTRY EGL_WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
EVENT("(EGLDisplay dpy =0x%016" PRIxPTR "p, EGLSync sync = 0x%016" PRIxPTR EVENT("(EGLDisplay dpy =0x%016" PRIxPTR "p, EGLSync sync = 0x%016" PRIxPTR
", EGLint flags = 0x%X)", ", EGLint flags = 0x%X)",
(uintptr_t)dpy, (uintptr_t)sync, flags); (uintptr_t)dpy, (uintptr_t)sync, flags);
Thread *thread = egl::GetCurrentThread(); Thread *thread = egl::GetCurrentThread();
egl::Display *display = static_cast<egl::Display *>(dpy); egl::Display *display = static_cast<egl::Display *>(dpy);
gl::Context *context = thread->getContext();
egl::Sync *syncObject = static_cast<Sync *>(sync);
UNIMPLEMENTED(); ANGLE_EGL_TRY_RETURN(thread, ValidateWaitSync(display, context, syncObject, flags),
thread->setError(EglBadDisplay() << "eglWaitSync unimplemented.", GetDebug(), "eglWaitSync", "eglWaitSync", GetDisplayIfValid(display), EGL_FALSE);
GetDisplayIfValid(display));
return EGL_FALSE; ANGLE_EGL_TRY_RETURN(thread, display->waitSync(syncObject, flags), "eglWaitSync",
GetDisplayIfValid(display), EGL_FALSE);
thread->setSuccess();
return EGL_TRUE;
} }
__eglMustCastToProperFunctionPointerType EGLAPIENTRY EGL_GetProcAddress(const char *procname) __eglMustCastToProperFunctionPointerType EGLAPIENTRY EGL_GetProcAddress(const char *procname)
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "libANGLE/Stream.h" #include "libANGLE/Stream.h"
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
#include "libANGLE/Thread.h" #include "libANGLE/Thread.h"
#include "libANGLE/queryutils.h"
#include "libANGLE/validationEGL.h" #include "libANGLE/validationEGL.h"
#include "libGLESv2/global_state.h" #include "libGLESv2/global_state.h"
...@@ -874,6 +875,128 @@ EGLBoolean EGLAPIENTRY EGL_StreamPostD3DTextureANGLE(EGLDisplay dpy, ...@@ -874,6 +875,128 @@ EGLBoolean EGLAPIENTRY EGL_StreamPostD3DTextureANGLE(EGLDisplay dpy,
return EGL_TRUE; return EGL_TRUE;
} }
// EGL_KHR_fence_sync
ANGLE_EXPORT EGLSync EGLAPIENTRY EGL_CreateSyncKHR(EGLDisplay dpy,
EGLenum type,
const EGLint *attrib_list)
{
ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR
", EGLenum type = 0x%X, const EGLint* attrib_list = 0x%016" PRIxPTR ")",
(uintptr_t)dpy, type, (uintptr_t)attrib_list);
Thread *thread = egl::GetCurrentThread();
egl::Display *display = static_cast<egl::Display *>(dpy);
AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
gl::Context *currentContext = thread->getContext();
egl::Display *currentDisplay = currentContext ? currentContext->getCurrentDisplay() : nullptr;
ANGLE_EGL_TRY_RETURN(
thread, ValidateCreateSyncKHR(display, type, attributes, currentDisplay, currentContext),
"eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
egl::Sync *syncObject = nullptr;
ANGLE_EGL_TRY_RETURN(thread, display->createSync(type, attributes, &syncObject),
"eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
thread->setSuccess();
return static_cast<EGLSync>(syncObject);
}
ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_DestroySyncKHR(EGLDisplay dpy, EGLSync sync)
{
ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSync sync = 0x%016" PRIxPTR ")", (uintptr_t)dpy,
(uintptr_t)sync);
Thread *thread = egl::GetCurrentThread();
egl::Display *display = static_cast<egl::Display *>(dpy);
egl::Sync *syncObject = static_cast<Sync *>(sync);
ANGLE_EGL_TRY_RETURN(thread, ValidateDestroySync(display, syncObject), "eglDestroySync",
GetDisplayIfValid(display), EGL_FALSE);
display->destroySync(syncObject);
thread->setSuccess();
return EGL_TRUE;
}
ANGLE_EXPORT EGLint EGLAPIENTRY EGL_ClientWaitSyncKHR(EGLDisplay dpy,
EGLSync sync,
EGLint flags,
EGLTime timeout)
{
ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSync sync = 0x%016" PRIxPTR
", EGLint flags = 0x%X, EGLTime timeout = "
"%llu)",
(uintptr_t)dpy, (uintptr_t)sync, flags, static_cast<unsigned long long>(timeout));
Thread *thread = egl::GetCurrentThread();
egl::Display *display = static_cast<egl::Display *>(dpy);
egl::Sync *syncObject = static_cast<Sync *>(sync);
ANGLE_EGL_TRY_RETURN(thread, ValidateClientWaitSync(display, syncObject, flags, timeout),
"eglClientWaitSync", GetDisplayIfValid(display), EGL_FALSE);
EGLint syncStatus = EGL_FALSE;
ANGLE_EGL_TRY_RETURN(thread, display->clientWaitSync(syncObject, flags, timeout, &syncStatus),
"eglClientWaitSync", GetDisplayIfValid(display), EGL_FALSE);
thread->setSuccess();
return syncStatus;
}
ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetSyncAttribKHR(EGLDisplay dpy,
EGLSync sync,
EGLint attribute,
EGLint *value)
{
ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSync sync = 0x%016" PRIxPTR
", EGLint attribute = 0x%X, EGLAttrib "
"*value = 0x%016" PRIxPTR ")",
(uintptr_t)dpy, (uintptr_t)sync, attribute, (uintptr_t)value);
Thread *thread = egl::GetCurrentThread();
egl::Display *display = static_cast<egl::Display *>(dpy);
egl::Sync *syncObject = static_cast<Sync *>(sync);
ANGLE_EGL_TRY_RETURN(thread, ValidateGetSyncAttribKHR(display, syncObject, attribute, value),
"eglGetSyncAttrib", GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, GetSyncAttrib(display, syncObject, attribute, value),
"eglGetSyncAttrib", GetDisplayIfValid(display), EGL_FALSE);
thread->setSuccess();
return EGL_TRUE;
}
// EGL_KHR_wait_sync
ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_WaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
{
ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy =0x%016" PRIxPTR "p, EGLSync sync = 0x%016" PRIxPTR
", EGLint flags = 0x%X)",
(uintptr_t)dpy, (uintptr_t)sync, flags);
Thread *thread = egl::GetCurrentThread();
egl::Display *display = static_cast<egl::Display *>(dpy);
gl::Context *context = thread->getContext();
egl::Sync *syncObject = static_cast<Sync *>(sync);
ANGLE_EGL_TRY_RETURN(thread, ValidateWaitSync(display, context, syncObject, flags),
"eglWaitSync", GetDisplayIfValid(display), EGL_FALSE);
ANGLE_EGL_TRY_RETURN(thread, display->waitSync(syncObject, flags), "eglWaitSync",
GetDisplayIfValid(display), EGL_FALSE);
thread->setSuccess();
return EGL_TRUE;
}
EGLBoolean EGLAPIENTRY EGL_GetSyncValuesCHROMIUM(EGLDisplay dpy, EGLBoolean EGLAPIENTRY EGL_GetSyncValuesCHROMIUM(EGLDisplay dpy,
EGLSurface surface, EGLSurface surface,
EGLuint64KHR *ust, EGLuint64KHR *ust,
......
...@@ -104,6 +104,23 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_StreamPostD3DTextureANGLE(EGLDisplay dpy ...@@ -104,6 +104,23 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_StreamPostD3DTextureANGLE(EGLDisplay dpy
void *texture, void *texture,
const EGLAttrib *attrib_list); const EGLAttrib *attrib_list);
// EGL_KHR_fence_sync
ANGLE_EXPORT EGLSync EGLAPIENTRY EGL_CreateSyncKHR(EGLDisplay dpy,
EGLenum type,
const EGLint *attrib_list);
ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_DestroySyncKHR(EGLDisplay dpy, EGLSync sync);
ANGLE_EXPORT EGLint EGLAPIENTRY EGL_ClientWaitSyncKHR(EGLDisplay dpy,
EGLSync sync,
EGLint flags,
EGLTime timeout);
ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetSyncAttribKHR(EGLDisplay dpy,
EGLSync sync,
EGLint attribute,
EGLint *value);
// EGL_KHR_wait_sync
ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_WaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags);
// EGL_CHROMIUM_get_sync_values // EGL_CHROMIUM_get_sync_values
ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetSyncValuesCHROMIUM(EGLDisplay dpy, ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetSyncValuesCHROMIUM(EGLDisplay dpy,
EGLSurface surface, EGLSurface surface,
......
...@@ -1445,6 +1445,12 @@ EXPORTS ...@@ -1445,6 +1445,12 @@ EXPORTS
EGL_LabelObjectKHR EGL_LabelObjectKHR
EGL_QueryDebugKHR EGL_QueryDebugKHR
; EGL_KHR_fence_sync
EGL_ClientWaitSyncKHR
EGL_CreateSyncKHR
EGL_DestroySyncKHR
EGL_GetSyncAttribKHR
; EGL_KHR_image ; EGL_KHR_image
EGL_CreateImageKHR EGL_CreateImageKHR
EGL_DestroyImageKHR EGL_DestroyImageKHR
...@@ -1464,6 +1470,9 @@ EXPORTS ...@@ -1464,6 +1470,9 @@ EXPORTS
; EGL_KHR_swap_buffers_with_damage ; EGL_KHR_swap_buffers_with_damage
EGL_SwapBuffersWithDamageKHR EGL_SwapBuffersWithDamageKHR
; EGL_KHR_wait_sync
EGL_WaitSyncKHR
; EGL_NV_post_sub_buffer ; EGL_NV_post_sub_buffer
EGL_PostSubBufferNV EGL_PostSubBufferNV
......
...@@ -31,6 +31,7 @@ ProcEntry g_procTable[] = { ...@@ -31,6 +31,7 @@ ProcEntry g_procTable[] = {
{"eglBindTexImage", P(EGL_BindTexImage)}, {"eglBindTexImage", P(EGL_BindTexImage)},
{"eglChooseConfig", P(EGL_ChooseConfig)}, {"eglChooseConfig", P(EGL_ChooseConfig)},
{"eglClientWaitSync", P(EGL_ClientWaitSync)}, {"eglClientWaitSync", P(EGL_ClientWaitSync)},
{"eglClientWaitSyncKHR", P(EGL_ClientWaitSyncKHR)},
{"eglCopyBuffers", P(EGL_CopyBuffers)}, {"eglCopyBuffers", P(EGL_CopyBuffers)},
{"eglCreateContext", P(EGL_CreateContext)}, {"eglCreateContext", P(EGL_CreateContext)},
{"eglCreateDeviceANGLE", P(EGL_CreateDeviceANGLE)}, {"eglCreateDeviceANGLE", P(EGL_CreateDeviceANGLE)},
...@@ -46,6 +47,7 @@ ProcEntry g_procTable[] = { ...@@ -46,6 +47,7 @@ ProcEntry g_procTable[] = {
{"eglCreateStreamKHR", P(EGL_CreateStreamKHR)}, {"eglCreateStreamKHR", P(EGL_CreateStreamKHR)},
{"eglCreateStreamProducerD3DTextureANGLE", P(EGL_CreateStreamProducerD3DTextureANGLE)}, {"eglCreateStreamProducerD3DTextureANGLE", P(EGL_CreateStreamProducerD3DTextureANGLE)},
{"eglCreateSync", P(EGL_CreateSync)}, {"eglCreateSync", P(EGL_CreateSync)},
{"eglCreateSyncKHR", P(EGL_CreateSyncKHR)},
{"eglCreateWindowSurface", P(EGL_CreateWindowSurface)}, {"eglCreateWindowSurface", P(EGL_CreateWindowSurface)},
{"eglDebugMessageControlKHR", P(EGL_DebugMessageControlKHR)}, {"eglDebugMessageControlKHR", P(EGL_DebugMessageControlKHR)},
{"eglDestroyContext", P(EGL_DestroyContext)}, {"eglDestroyContext", P(EGL_DestroyContext)},
...@@ -54,6 +56,7 @@ ProcEntry g_procTable[] = { ...@@ -54,6 +56,7 @@ ProcEntry g_procTable[] = {
{"eglDestroyStreamKHR", P(EGL_DestroyStreamKHR)}, {"eglDestroyStreamKHR", P(EGL_DestroyStreamKHR)},
{"eglDestroySurface", P(EGL_DestroySurface)}, {"eglDestroySurface", P(EGL_DestroySurface)},
{"eglDestroySync", P(EGL_DestroySync)}, {"eglDestroySync", P(EGL_DestroySync)},
{"eglDestroySyncKHR", P(EGL_DestroySyncKHR)},
{"eglGetCompositorTimingANDROID", P(EGL_GetCompositorTimingANDROID)}, {"eglGetCompositorTimingANDROID", P(EGL_GetCompositorTimingANDROID)},
{"eglGetCompositorTimingSupportedANDROID", P(EGL_GetCompositorTimingSupportedANDROID)}, {"eglGetCompositorTimingSupportedANDROID", P(EGL_GetCompositorTimingSupportedANDROID)},
{"eglGetConfigAttrib", P(EGL_GetConfigAttrib)}, {"eglGetConfigAttrib", P(EGL_GetConfigAttrib)},
...@@ -70,6 +73,7 @@ ProcEntry g_procTable[] = { ...@@ -70,6 +73,7 @@ ProcEntry g_procTable[] = {
{"eglGetPlatformDisplayEXT", P(EGL_GetPlatformDisplayEXT)}, {"eglGetPlatformDisplayEXT", P(EGL_GetPlatformDisplayEXT)},
{"eglGetProcAddress", P(EGL_GetProcAddress)}, {"eglGetProcAddress", P(EGL_GetProcAddress)},
{"eglGetSyncAttrib", P(EGL_GetSyncAttrib)}, {"eglGetSyncAttrib", P(EGL_GetSyncAttrib)},
{"eglGetSyncAttribKHR", P(EGL_GetSyncAttribKHR)},
{"eglGetSyncValuesCHROMIUM", P(EGL_GetSyncValuesCHROMIUM)}, {"eglGetSyncValuesCHROMIUM", P(EGL_GetSyncValuesCHROMIUM)},
{"eglInitialize", P(EGL_Initialize)}, {"eglInitialize", P(EGL_Initialize)},
{"eglLabelObjectKHR", P(EGL_LabelObjectKHR)}, {"eglLabelObjectKHR", P(EGL_LabelObjectKHR)},
...@@ -111,6 +115,7 @@ ProcEntry g_procTable[] = { ...@@ -111,6 +115,7 @@ ProcEntry g_procTable[] = {
{"eglWaitGL", P(EGL_WaitGL)}, {"eglWaitGL", P(EGL_WaitGL)},
{"eglWaitNative", P(EGL_WaitNative)}, {"eglWaitNative", P(EGL_WaitNative)},
{"eglWaitSync", P(EGL_WaitSync)}, {"eglWaitSync", P(EGL_WaitSync)},
{"eglWaitSyncKHR", P(EGL_WaitSyncKHR)},
{"glActiveShaderProgram", P(gl::ActiveShaderProgram)}, {"glActiveShaderProgram", P(gl::ActiveShaderProgram)},
{"glActiveShaderProgramContextANGLE", P(gl::ActiveShaderProgramContextANGLE)}, {"glActiveShaderProgramContextANGLE", P(gl::ActiveShaderProgramContextANGLE)},
{"glActiveTexture", P(gl::ActiveTexture)}, {"glActiveTexture", P(gl::ActiveTexture)},
...@@ -1363,5 +1368,5 @@ ProcEntry g_procTable[] = { ...@@ -1363,5 +1368,5 @@ ProcEntry g_procTable[] = {
{"glWeightPointerOES", P(gl::WeightPointerOES)}, {"glWeightPointerOES", P(gl::WeightPointerOES)},
{"glWeightPointerOESContextANGLE", P(gl::WeightPointerOESContextANGLE)}}; {"glWeightPointerOESContextANGLE", P(gl::WeightPointerOESContextANGLE)}};
size_t g_numProcs = 1279; size_t g_numProcs = 1284;
} // namespace egl } // namespace egl
...@@ -902,6 +902,15 @@ ...@@ -902,6 +902,15 @@
"eglStreamPostD3DTextureANGLE" "eglStreamPostD3DTextureANGLE"
], ],
"EGL_KHR_fence_sync": [
"eglCreateSyncKHR",
"eglDestroySyncKHR",
"eglClientWaitSyncKHR",
"eglGetSyncAttribKHR"
],
"EGL_KHR_wait_sync": [
"eglWaitSyncKHR"
],
"EGL_CHROMIUM_get_sync_values": [ "EGL_CHROMIUM_get_sync_values": [
"eglGetSyncValuesCHROMIUM" "eglGetSyncValuesCHROMIUM"
], ],
......
...@@ -134,6 +134,7 @@ angle_end2end_tests_sources = [ ...@@ -134,6 +134,7 @@ angle_end2end_tests_sources = [
"egl_tests/EGLSanityCheckTest.cpp", "egl_tests/EGLSanityCheckTest.cpp",
"egl_tests/EGLSurfacelessContextTest.cpp", "egl_tests/EGLSurfacelessContextTest.cpp",
"egl_tests/EGLSurfaceTest.cpp", "egl_tests/EGLSurfaceTest.cpp",
"egl_tests/EGLSyncTest.cpp",
"egl_tests/EGLThreadTest.cpp", "egl_tests/EGLThreadTest.cpp",
"test_utils/ANGLETest.cpp", "test_utils/ANGLETest.cpp",
"test_utils/ANGLETest.h", "test_utils/ANGLETest.h",
......
...@@ -155,7 +155,6 @@ ...@@ -155,7 +155,6 @@
1340 WIN : dEQP-EGL.functional.resize.pixel_density.* = SKIP 1340 WIN : dEQP-EGL.functional.resize.pixel_density.* = SKIP
// Windows OpenGL failures // Windows OpenGL failures
2546 WIN : dEQP-EGL.functional.fence_sync.invalid.* = SKIP
2546 WIN : dEQP-EGL.functional.resize.surface_size.shrink = SKIP 2546 WIN : dEQP-EGL.functional.resize.surface_size.shrink = SKIP
2546 WIN : dEQP-EGL.functional.reusable_sync.invalid.* = SKIP 2546 WIN : dEQP-EGL.functional.reusable_sync.invalid.* = SKIP
2546 WIN : dEQP-EGL.functional.color_clears.multi_thread.* = FAIL 2546 WIN : dEQP-EGL.functional.color_clears.multi_thread.* = FAIL
......
//
// Copyright 2019 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.
//
// EGLSyncTest.cpp:
// Tests of EGL_KHR_fence_sync and EGL_KHR_wait_sync extensions.
#include <gtest/gtest.h>
#include "test_utils/ANGLETest.h"
#include "test_utils/angle_test_configs.h"
#include "util/EGLWindow.h"
using namespace angle;
class EGLSyncTest : public ANGLETest
{
protected:
bool hasFenceSyncExtension() const
{
return eglDisplayExtensionEnabled(getEGLWindow()->getDisplay(), "EGL_KHR_fence_sync");
}
bool hasWaitSyncExtension() const
{
return hasFenceSyncExtension() &&
eglDisplayExtensionEnabled(getEGLWindow()->getDisplay(), "EGL_KHR_wait_sync");
}
bool hasGLSyncExtension() const { return extensionEnabled("GL_OES_EGL_sync"); }
};
// Test error cases for all EGL_KHR_fence_sync functions
TEST_P(EGLSyncTest, FenceSyncErrors)
{
ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
EGLDisplay display = getEGLWindow()->getDisplay();
// If the client API doesn't have the necessary extension, test that sync creation fails and
// ignore the rest of the tests.
if (!hasGLSyncExtension())
{
EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr));
EXPECT_EGL_ERROR(EGL_BAD_MATCH);
}
ANGLE_SKIP_TEST_IF(!hasGLSyncExtension());
EGLContext context = eglGetCurrentContext();
EGLSurface drawSurface = eglGetCurrentSurface(EGL_DRAW);
EGLSurface readSurface = eglGetCurrentSurface(EGL_READ);
EXPECT_NE(context, EGL_NO_CONTEXT);
EXPECT_NE(drawSurface, EGL_NO_SURFACE);
EXPECT_NE(readSurface, EGL_NO_SURFACE);
// CreateSync with no attribute shouldn't cause an error
EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
EXPECT_NE(sync, EGL_NO_SYNC_KHR);
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
// CreateSync with empty attribute shouldn't cause an error
const EGLint emptyAttributes[] = {EGL_NONE};
sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, emptyAttributes);
EXPECT_NE(sync, EGL_NO_SYNC_KHR);
// DestroySync generates BAD_PARAMETER if the sync is not valid
EXPECT_EGL_FALSE(eglDestroySyncKHR(display, reinterpret_cast<EGLSyncKHR>(20)));
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
// CreateSync generates BAD_DISPLAY if display is not valid
EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(EGL_NO_DISPLAY, EGL_SYNC_FENCE_KHR, nullptr));
EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
// CreateSync generates BAD_ATTRIBUTE if attribute is neither nullptr nor empty.
const EGLint nonEmptyAttributes[] = {
EGL_CL_EVENT_HANDLE,
0,
EGL_NONE,
};
EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nonEmptyAttributes));
EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
// CreateSync generates BAD_ATTRIBUTE if type is not valid
EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, 0, nullptr));
EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
// CreateSync generates BAD_MATCH if no context is current
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr));
EXPECT_EGL_ERROR(EGL_BAD_MATCH);
eglMakeCurrent(display, drawSurface, readSurface, context);
// ClientWaitSync generates EGL_BAD_PARAMETER if the sync object is not valid
EXPECT_EGL_FALSE(eglClientWaitSyncKHR(display, reinterpret_cast<EGLSyncKHR>(30), 0, 0));
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
// GetSyncAttrib generates EGL_BAD_PARAMETER if the sync object is not valid, and value is not
// modified
constexpr EGLint kSentinelAttribValue = 123456789;
EGLint attribValue = kSentinelAttribValue;
EXPECT_EGL_FALSE(eglGetSyncAttribKHR(display, reinterpret_cast<EGLSyncKHR>(40),
EGL_SYNC_TYPE_KHR, &attribValue));
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
EXPECT_EQ(attribValue, kSentinelAttribValue);
// GetSyncAttrib generates EGL_BAD_ATTRIBUTE if the attribute is not valid, and value is not
// modified
EXPECT_EGL_FALSE(eglGetSyncAttribKHR(display, sync, EGL_CL_EVENT_HANDLE, &attribValue));
EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
EXPECT_EQ(attribValue, kSentinelAttribValue);
// GetSyncAttrib generates EGL_BAD_MATCH if the attribute is valid for sync, but not the
// particular sync type. We don't have such a case at the moment.
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
}
// Test error cases for all EGL_KHR_wait_sync functions
TEST_P(EGLSyncTest, WaitSyncErrors)
{
// The client API that shows support for eglWaitSyncKHR is the same as the one required for
// eglCreateSyncKHR. As such, there is no way to create a sync and not be able to wait on it.
// This would have created an EGL_BAD_MATCH error.
ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension());
EGLDisplay display = getEGLWindow()->getDisplay();
EGLContext context = eglGetCurrentContext();
EGLSurface drawSurface = eglGetCurrentSurface(EGL_DRAW);
EGLSurface readSurface = eglGetCurrentSurface(EGL_READ);
EXPECT_NE(context, EGL_NO_CONTEXT);
EXPECT_NE(drawSurface, EGL_NO_SURFACE);
EXPECT_NE(readSurface, EGL_NO_SURFACE);
EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
EXPECT_NE(sync, EGL_NO_SYNC_KHR);
// WaitSync generates BAD_MATCH if no context is current
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
EXPECT_EGL_FALSE(eglWaitSyncKHR(display, sync, 0));
EXPECT_EGL_ERROR(EGL_BAD_MATCH);
eglMakeCurrent(display, drawSurface, readSurface, context);
// WaitSync generates BAD_PARAMETER if the sync is not valid
EXPECT_EGL_FALSE(eglWaitSyncKHR(display, reinterpret_cast<EGLSyncKHR>(20), 0));
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
// WaitSync generates BAD_PARAMETER if flags is non-zero
EXPECT_EGL_FALSE(eglWaitSyncKHR(display, sync, 1));
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
}
// Test usage of eglGetSyncAttribKHR
TEST_P(EGLSyncTest, GetSyncAttrib)
{
ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
EGLDisplay display = getEGLWindow()->getDisplay();
EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
EXPECT_NE(sync, EGL_NO_SYNC_KHR);
// Fence sync attributes are:
//
// EGL_SYNC_TYPE_KHR: EGL_SYNC_FENCE_KHR
// EGL_SYNC_STATUS_KHR: EGL_UNSIGNALED_KHR or EGL_SIGNALED_KHR
// EGL_SYNC_CONDITION_KHR: EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR
constexpr EGLint kSentinelAttribValue = 123456789;
EGLint attribValue = kSentinelAttribValue;
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_TYPE_KHR, &attribValue));
EXPECT_EQ(attribValue, EGL_SYNC_FENCE_KHR);
attribValue = kSentinelAttribValue;
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_CONDITION_KHR, &attribValue));
EXPECT_EQ(attribValue, EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR);
attribValue = kSentinelAttribValue;
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_STATUS_KHR, &attribValue));
// Hack around EXPECT_* not having an "either this or that" variant:
if (attribValue != EGL_SIGNALED_KHR)
{
EXPECT_EQ(attribValue, EGL_UNSIGNALED_KHR);
}
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
}
// Test that basic usage works and doesn't generate errors or crash
TEST_P(EGLSyncTest, BasicOperations)
{
ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
EGLDisplay display = getEGLWindow()->getDisplay();
EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
EXPECT_NE(sync, EGL_NO_SYNC_KHR);
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_EGL_TRUE(eglWaitSyncKHR(display, sync, 0));
glFlush();
EGLint value = 0;
unsigned int loopCount = 0;
// Use 'loopCount' to make sure the test doesn't get stuck in an infinite loop
while (value != EGL_SIGNALED_KHR && loopCount <= 1000000)
{
loopCount++;
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_STATUS_KHR, &value));
}
ASSERT_EQ(value, EGL_SIGNALED_KHR);
for (size_t i = 0; i < 20; i++)
{
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_EQ(
EGL_CONDITION_SATISFIED_KHR,
eglClientWaitSyncKHR(display, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR));
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_STATUS_KHR, &value));
EXPECT_EQ(value, EGL_SIGNALED_KHR);
}
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
}
ANGLE_INSTANTIATE_TEST(EGLSyncTest,
ES2_D3D9(),
ES2_D3D11(),
ES3_D3D11(),
ES2_OPENGL(),
ES3_OPENGL(),
ES2_OPENGLES(),
ES3_OPENGLES(),
ES2_VULKAN(),
ES3_VULKAN());
...@@ -82,6 +82,10 @@ ANGLE_UTIL_EXPORT PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT; ...@@ -82,6 +82,10 @@ ANGLE_UTIL_EXPORT PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
ANGLE_UTIL_EXPORT PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR; ANGLE_UTIL_EXPORT PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR;
ANGLE_UTIL_EXPORT PFNEGLLABELOBJECTKHRPROC eglLabelObjectKHR; ANGLE_UTIL_EXPORT PFNEGLLABELOBJECTKHRPROC eglLabelObjectKHR;
ANGLE_UTIL_EXPORT PFNEGLQUERYDEBUGKHRPROC eglQueryDebugKHR; ANGLE_UTIL_EXPORT PFNEGLQUERYDEBUGKHRPROC eglQueryDebugKHR;
ANGLE_UTIL_EXPORT PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncKHR;
ANGLE_UTIL_EXPORT PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR;
ANGLE_UTIL_EXPORT PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR;
ANGLE_UTIL_EXPORT PFNEGLGETSYNCATTRIBKHRPROC eglGetSyncAttribKHR;
ANGLE_UTIL_EXPORT PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; ANGLE_UTIL_EXPORT PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
ANGLE_UTIL_EXPORT PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR; ANGLE_UTIL_EXPORT PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
ANGLE_UTIL_EXPORT PFNEGLCREATESTREAMKHRPROC eglCreateStreamKHR; ANGLE_UTIL_EXPORT PFNEGLCREATESTREAMKHRPROC eglCreateStreamKHR;
...@@ -94,6 +98,7 @@ ANGLE_UTIL_EXPORT PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC ...@@ -94,6 +98,7 @@ ANGLE_UTIL_EXPORT PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC
eglStreamConsumerGLTextureExternalKHR; eglStreamConsumerGLTextureExternalKHR;
ANGLE_UTIL_EXPORT PFNEGLSTREAMCONSUMERRELEASEKHRPROC eglStreamConsumerReleaseKHR; ANGLE_UTIL_EXPORT PFNEGLSTREAMCONSUMERRELEASEKHRPROC eglStreamConsumerReleaseKHR;
ANGLE_UTIL_EXPORT PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC eglSwapBuffersWithDamageKHR; ANGLE_UTIL_EXPORT PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC eglSwapBuffersWithDamageKHR;
ANGLE_UTIL_EXPORT PFNEGLWAITSYNCKHRPROC eglWaitSyncKHR;
ANGLE_UTIL_EXPORT PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV; ANGLE_UTIL_EXPORT PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV;
ANGLE_UTIL_EXPORT PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC ANGLE_UTIL_EXPORT PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC
eglStreamConsumerGLTextureExternalAttribsNV; eglStreamConsumerGLTextureExternalAttribsNV;
...@@ -211,6 +216,12 @@ void LoadEGL(LoadProc loadProc) ...@@ -211,6 +216,12 @@ void LoadEGL(LoadProc loadProc)
reinterpret_cast<PFNEGLDEBUGMESSAGECONTROLKHRPROC>(loadProc("eglDebugMessageControlKHR")); reinterpret_cast<PFNEGLDEBUGMESSAGECONTROLKHRPROC>(loadProc("eglDebugMessageControlKHR"));
eglLabelObjectKHR = reinterpret_cast<PFNEGLLABELOBJECTKHRPROC>(loadProc("eglLabelObjectKHR")); eglLabelObjectKHR = reinterpret_cast<PFNEGLLABELOBJECTKHRPROC>(loadProc("eglLabelObjectKHR"));
eglQueryDebugKHR = reinterpret_cast<PFNEGLQUERYDEBUGKHRPROC>(loadProc("eglQueryDebugKHR")); eglQueryDebugKHR = reinterpret_cast<PFNEGLQUERYDEBUGKHRPROC>(loadProc("eglQueryDebugKHR"));
eglClientWaitSyncKHR =
reinterpret_cast<PFNEGLCLIENTWAITSYNCKHRPROC>(loadProc("eglClientWaitSyncKHR"));
eglCreateSyncKHR = reinterpret_cast<PFNEGLCREATESYNCKHRPROC>(loadProc("eglCreateSyncKHR"));
eglDestroySyncKHR = reinterpret_cast<PFNEGLDESTROYSYNCKHRPROC>(loadProc("eglDestroySyncKHR"));
eglGetSyncAttribKHR =
reinterpret_cast<PFNEGLGETSYNCATTRIBKHRPROC>(loadProc("eglGetSyncAttribKHR"));
eglCreateImageKHR = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(loadProc("eglCreateImageKHR")); eglCreateImageKHR = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(loadProc("eglCreateImageKHR"));
eglDestroyImageKHR = eglDestroyImageKHR =
reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(loadProc("eglDestroyImageKHR")); reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(loadProc("eglDestroyImageKHR"));
...@@ -232,6 +243,7 @@ void LoadEGL(LoadProc loadProc) ...@@ -232,6 +243,7 @@ void LoadEGL(LoadProc loadProc)
loadProc("eglStreamConsumerReleaseKHR")); loadProc("eglStreamConsumerReleaseKHR"));
eglSwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC>( eglSwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC>(
loadProc("eglSwapBuffersWithDamageKHR")); loadProc("eglSwapBuffersWithDamageKHR"));
eglWaitSyncKHR = reinterpret_cast<PFNEGLWAITSYNCKHRPROC>(loadProc("eglWaitSyncKHR"));
eglPostSubBufferNV = eglPostSubBufferNV =
reinterpret_cast<PFNEGLPOSTSUBBUFFERNVPROC>(loadProc("eglPostSubBufferNV")); reinterpret_cast<PFNEGLPOSTSUBBUFFERNVPROC>(loadProc("eglPostSubBufferNV"));
eglStreamConsumerGLTextureExternalAttribsNV = eglStreamConsumerGLTextureExternalAttribsNV =
......
...@@ -89,6 +89,10 @@ ANGLE_UTIL_EXPORT extern PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEX ...@@ -89,6 +89,10 @@ ANGLE_UTIL_EXPORT extern PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEX
ANGLE_UTIL_EXPORT extern PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR; ANGLE_UTIL_EXPORT extern PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR;
ANGLE_UTIL_EXPORT extern PFNEGLLABELOBJECTKHRPROC eglLabelObjectKHR; ANGLE_UTIL_EXPORT extern PFNEGLLABELOBJECTKHRPROC eglLabelObjectKHR;
ANGLE_UTIL_EXPORT extern PFNEGLQUERYDEBUGKHRPROC eglQueryDebugKHR; ANGLE_UTIL_EXPORT extern PFNEGLQUERYDEBUGKHRPROC eglQueryDebugKHR;
ANGLE_UTIL_EXPORT extern PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncKHR;
ANGLE_UTIL_EXPORT extern PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR;
ANGLE_UTIL_EXPORT extern PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR;
ANGLE_UTIL_EXPORT extern PFNEGLGETSYNCATTRIBKHRPROC eglGetSyncAttribKHR;
ANGLE_UTIL_EXPORT extern PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; ANGLE_UTIL_EXPORT extern PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
ANGLE_UTIL_EXPORT extern PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR; ANGLE_UTIL_EXPORT extern PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
ANGLE_UTIL_EXPORT extern PFNEGLCREATESTREAMKHRPROC eglCreateStreamKHR; ANGLE_UTIL_EXPORT extern PFNEGLCREATESTREAMKHRPROC eglCreateStreamKHR;
...@@ -101,6 +105,7 @@ ANGLE_UTIL_EXPORT extern PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC ...@@ -101,6 +105,7 @@ ANGLE_UTIL_EXPORT extern PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC
eglStreamConsumerGLTextureExternalKHR; eglStreamConsumerGLTextureExternalKHR;
ANGLE_UTIL_EXPORT extern PFNEGLSTREAMCONSUMERRELEASEKHRPROC eglStreamConsumerReleaseKHR; ANGLE_UTIL_EXPORT extern PFNEGLSTREAMCONSUMERRELEASEKHRPROC eglStreamConsumerReleaseKHR;
ANGLE_UTIL_EXPORT extern PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC eglSwapBuffersWithDamageKHR; ANGLE_UTIL_EXPORT extern PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC eglSwapBuffersWithDamageKHR;
ANGLE_UTIL_EXPORT extern PFNEGLWAITSYNCKHRPROC eglWaitSyncKHR;
ANGLE_UTIL_EXPORT extern PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV; ANGLE_UTIL_EXPORT extern PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV;
ANGLE_UTIL_EXPORT extern PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC ANGLE_UTIL_EXPORT extern PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC
eglStreamConsumerGLTextureExternalAttribsNV; eglStreamConsumerGLTextureExternalAttribsNV;
......
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