Commit 69e46a18 by Geoff Lang Committed by Commit Bot

GL: Implement EGL_ANDROID_native_fence_sync

This extension allows Chrome to use ANGLE on newer Android devices. BUG=angleproject:3643 Change-Id: I5456d61749399ca2bbc11cc5e98b9120f8702406 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1687121Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 4e71b2bc
...@@ -90,6 +90,7 @@ supported_egl_extensions = [ ...@@ -90,6 +90,7 @@ supported_egl_extensions = [
"EGL_ANDROID_blob_cache", "EGL_ANDROID_blob_cache",
"EGL_ANDROID_get_frame_timestamps", "EGL_ANDROID_get_frame_timestamps",
"EGL_ANDROID_get_native_client_buffer", "EGL_ANDROID_get_native_client_buffer",
"EGL_ANDROID_native_fence_sync",
"EGL_ANDROID_presentation_time", "EGL_ANDROID_presentation_time",
"EGL_ANGLE_d3d_share_handle_client_buffer", "EGL_ANGLE_d3d_share_handle_client_buffer",
"EGL_ANGLE_device_creation", "EGL_ANGLE_device_creation",
......
...@@ -100,7 +100,7 @@ ...@@ -100,7 +100,7 @@
"GL/EGL entry points:scripts/gl_angle_ext.xml": "GL/EGL entry points:scripts/gl_angle_ext.xml":
"bed6b56a38621721e689ebc19601a556", "bed6b56a38621721e689ebc19601a556",
"GL/EGL entry points:scripts/registry_xml.py": "GL/EGL entry points:scripts/registry_xml.py":
"24fa69f5641ed09c8e8a2f9c64fd0260", "97cca309a0561f3bf54e0e2c1cf0708b",
"GL/EGL entry points:scripts/wgl.xml": "GL/EGL entry points:scripts/wgl.xml":
"aa96419c582af2f6673430e2847693f4", "aa96419c582af2f6673430e2847693f4",
"GL/EGL entry points:src/libANGLE/Context_gl_1_0_autogen.h": "GL/EGL entry points:src/libANGLE/Context_gl_1_0_autogen.h":
...@@ -256,9 +256,9 @@ ...@@ -256,9 +256,9 @@
"GL/EGL entry points:src/libGLESv2/libGLESv2_autogen.cpp": "GL/EGL entry points:src/libGLESv2/libGLESv2_autogen.cpp":
"229577015686414a6d094533c2210cea", "229577015686414a6d094533c2210cea",
"GL/EGL entry points:src/libGLESv2/libGLESv2_autogen.def": "GL/EGL entry points:src/libGLESv2/libGLESv2_autogen.def":
"fca8c7d5ec90a68a6ad062fc4edf67e4", "52ef9529c516e83d6a0d9e1a9ec0a493",
"GL/EGL entry points:src/libGLESv2/libGLESv2_with_capture_autogen.def": "GL/EGL entry points:src/libGLESv2/libGLESv2_with_capture_autogen.def":
"45eecb859db4e21d7591e5819ebd81dd", "25b108d7f235173041f7c92ffab9fb44",
"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":
...@@ -266,17 +266,17 @@ ...@@ -266,17 +266,17 @@
"GL/EGL/WGL loader:scripts/generate_loader.py": "GL/EGL/WGL loader:scripts/generate_loader.py":
"5a7cd014230fe04664d9613e65399d42", "5a7cd014230fe04664d9613e65399d42",
"GL/EGL/WGL loader:scripts/registry_xml.py": "GL/EGL/WGL loader:scripts/registry_xml.py":
"24fa69f5641ed09c8e8a2f9c64fd0260", "97cca309a0561f3bf54e0e2c1cf0708b",
"GL/EGL/WGL loader:scripts/wgl.xml": "GL/EGL/WGL loader:scripts/wgl.xml":
"aa96419c582af2f6673430e2847693f4", "aa96419c582af2f6673430e2847693f4",
"GL/EGL/WGL loader:src/libEGL/egl_loader_autogen.cpp": "GL/EGL/WGL loader:src/libEGL/egl_loader_autogen.cpp":
"84c8b518af7051faa89702a5d553e87e", "01d20878ff5644bb9ee9e22ec95c3587",
"GL/EGL/WGL loader:src/libEGL/egl_loader_autogen.h": "GL/EGL/WGL loader:src/libEGL/egl_loader_autogen.h":
"a8f0278a7dec5c9d6e1ca0854e9542e9", "fcaa495dbf4ad4841c60f669f5fabfb8",
"GL/EGL/WGL loader:util/egl_loader_autogen.cpp": "GL/EGL/WGL loader:util/egl_loader_autogen.cpp":
"4b23b703a6598a75ea753e9b4aa6ea0f", "b9a444da4142a12a9fe6b7a9d33a4ea8",
"GL/EGL/WGL loader:util/egl_loader_autogen.h": "GL/EGL/WGL loader:util/egl_loader_autogen.h":
"7ae6f818846fff1a734bc975c82319b2", "bc2c62ff42604977ac2240591ee8ba6a",
"GL/EGL/WGL loader:util/gles_loader_autogen.cpp": "GL/EGL/WGL loader:util/gles_loader_autogen.cpp":
"335463406e64c6dc9bf00502cb25d53c", "335463406e64c6dc9bf00502cb25d53c",
"GL/EGL/WGL loader:util/gles_loader_autogen.h": "GL/EGL/WGL loader:util/gles_loader_autogen.h":
...@@ -574,13 +574,13 @@ ...@@ -574,13 +574,13 @@
"proc table:scripts/gl_angle_ext.xml": "proc table:scripts/gl_angle_ext.xml":
"bed6b56a38621721e689ebc19601a556", "bed6b56a38621721e689ebc19601a556",
"proc table:scripts/registry_xml.py": "proc table:scripts/registry_xml.py":
"24fa69f5641ed09c8e8a2f9c64fd0260", "97cca309a0561f3bf54e0e2c1cf0708b",
"proc table:scripts/wgl.xml": "proc table:scripts/wgl.xml":
"aa96419c582af2f6673430e2847693f4", "aa96419c582af2f6673430e2847693f4",
"proc table:src/libGL/proc_table_wgl_autogen.cpp": "proc table:src/libGL/proc_table_wgl_autogen.cpp":
"62d8f224776d738d5ee259a5f84528e1", "62d8f224776d738d5ee259a5f84528e1",
"proc table:src/libGLESv2/proc_table_egl_autogen.cpp": "proc table:src/libGLESv2/proc_table_egl_autogen.cpp":
"35653e6a70519374b768c7240081fbd1", "73e54da783ff8d5058e9dadcc6e90322",
"uniform type:src/common/gen_uniform_type_table.py": "uniform type:src/common/gen_uniform_type_table.py":
"a741cc301b1617ab0e4d29b35f1d3b96", "a741cc301b1617ab0e4d29b35f1d3b96",
"uniform type:src/common/uniform_type_info_autogen.cpp": "uniform type:src/common/uniform_type_info_autogen.cpp":
......
...@@ -1160,6 +1160,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const ...@@ -1160,6 +1160,7 @@ std::vector<std::string> DisplayExtensions::getStrings() const
InsertExtensionString("EGL_ANGLE_power_preference", powerPreference, &extensionStrings); InsertExtensionString("EGL_ANGLE_power_preference", powerPreference, &extensionStrings);
InsertExtensionString("EGL_ANGLE_image_d3d11_texture", imageD3D11Texture, &extensionStrings); InsertExtensionString("EGL_ANGLE_image_d3d11_texture", imageD3D11Texture, &extensionStrings);
InsertExtensionString("EGL_ANDROID_get_native_client_buffer", getNativeClientBufferANDROID, &extensionStrings); InsertExtensionString("EGL_ANDROID_get_native_client_buffer", getNativeClientBufferANDROID, &extensionStrings);
InsertExtensionString("EGL_ANDROID_native_fence_sync", nativeFenceSyncANDROID, &extensionStrings);
// TODO(jmadill): Enable this when complete. // TODO(jmadill): Enable this when complete.
//InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings); //InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings);
// clang-format on // clang-format on
......
...@@ -902,6 +902,9 @@ struct DisplayExtensions ...@@ -902,6 +902,9 @@ struct DisplayExtensions
// EGL_ANDROID_get_native_client_buffer // EGL_ANDROID_get_native_client_buffer
bool getNativeClientBufferANDROID = false; bool getNativeClientBufferANDROID = false;
// EGL_ANDROID_native_fence_sync
bool nativeFenceSyncANDROID = false;
}; };
struct DeviceExtensions struct DeviceExtensions
......
...@@ -20,7 +20,9 @@ namespace egl ...@@ -20,7 +20,9 @@ namespace egl
Sync::Sync(rx::EGLImplFactory *factory, EGLenum type, const AttributeMap &attribs) Sync::Sync(rx::EGLImplFactory *factory, EGLenum type, const AttributeMap &attribs)
: mFence(factory->createSync(attribs)), : mFence(factory->createSync(attribs)),
mLabel(nullptr), mLabel(nullptr),
mType(type) mType(type),
mNativeFenceFD(
attribs.getAsInt(EGL_SYNC_NATIVE_FENCE_FD_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID))
{} {}
void Sync::onDestroy(const Display *display) void Sync::onDestroy(const Display *display)
...@@ -66,4 +68,9 @@ Error Sync::getStatus(const Display *display, EGLint *outStatus) const ...@@ -66,4 +68,9 @@ Error Sync::getStatus(const Display *display, EGLint *outStatus) const
return mFence->getStatus(display, outStatus); return mFence->getStatus(display, outStatus);
} }
Error Sync::dupNativeFenceFD(const Display *display, EGLint *result) const
{
return mFence->dupNativeFenceFD(display, result);
}
} // namespace egl } // namespace egl
...@@ -49,8 +49,11 @@ class Sync final : public angle::RefCountObject<Display, angle::Result>, public ...@@ -49,8 +49,11 @@ class Sync final : public angle::RefCountObject<Display, angle::Result>, public
Error serverWait(const Display *display, const gl::Context *context, EGLint flags); Error serverWait(const Display *display, const gl::Context *context, EGLint flags);
Error getStatus(const Display *display, EGLint *outStatus) const; Error getStatus(const Display *display, EGLint *outStatus) const;
Error dupNativeFenceFD(const Display *display, EGLint *result) const;
EGLenum getType() const { return mType; } EGLenum getType() const { return mType; }
EGLint getCondition() const { return mCondition; } EGLint getCondition() const { return mCondition; }
EGLint getNativeFenceFD() const { return mNativeFenceFD; }
private: private:
std::unique_ptr<rx::EGLSyncImpl> mFence; std::unique_ptr<rx::EGLSyncImpl> mFence;
...@@ -59,6 +62,7 @@ class Sync final : public angle::RefCountObject<Display, angle::Result>, public ...@@ -59,6 +62,7 @@ class Sync final : public angle::RefCountObject<Display, angle::Result>, public
EGLenum mType; EGLenum mType;
static constexpr EGLint mCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; static constexpr EGLint mCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
EGLint mNativeFenceFD;
}; };
} // namespace egl } // namespace egl
......
...@@ -47,6 +47,8 @@ class EGLSyncImpl : angle::NonCopyable ...@@ -47,6 +47,8 @@ class EGLSyncImpl : angle::NonCopyable
const gl::Context *context, const gl::Context *context,
EGLint flags) = 0; EGLint flags) = 0;
virtual egl::Error getStatus(const egl::Display *display, EGLint *outStatus) = 0; virtual egl::Error getStatus(const egl::Display *display, EGLint *outStatus) = 0;
virtual egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *result) const = 0;
}; };
} // namespace rx } // namespace rx
......
...@@ -10,6 +10,12 @@ ...@@ -10,6 +10,12 @@
#include "libANGLE/renderer/driver_utils.h" #include "libANGLE/renderer/driver_utils.h"
#include "common/platform.h"
#if defined(ANGLE_PLATFORM_ANDROID)
# include <sys/system_properties.h>
#endif
namespace rx namespace rx
{ {
// Intel // Intel
...@@ -136,4 +142,19 @@ const char *GetVendorString(uint32_t vendorId) ...@@ -136,4 +142,19 @@ const char *GetVendorString(uint32_t vendorId)
} }
} }
} // namespace rx int GetAndroidSDKVersion()
\ No newline at end of file {
#if defined(ANGLE_PLATFORM_ANDROID)
char apiVersion[PROP_VALUE_MAX];
int length = __system_property_get("ro.build.version.sdk", apiVersion);
if (length == 0)
{
return 0;
}
return atoi(apiVersion);
#else
return 0;
#endif
}
} // namespace rx
...@@ -138,5 +138,7 @@ inline bool IsAndroid() ...@@ -138,5 +138,7 @@ inline bool IsAndroid()
#endif #endif
} }
int GetAndroidSDKVersion();
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_DRIVER_UTILS_H_ #endif // LIBANGLE_RENDERER_DRIVER_UTILS_H_
...@@ -149,6 +149,8 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -149,6 +149,8 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->getNativeClientBufferANDROID = outExtensions->getNativeClientBufferANDROID =
mEGL->hasExtension("EGL_ANDROID_get_native_client_buffer"); mEGL->hasExtension("EGL_ANDROID_get_native_client_buffer");
outExtensions->nativeFenceSyncANDROID = mEGL->hasExtension("EGL_ANDROID_native_fence_sync");
DisplayGL::generateExtensions(outExtensions); DisplayGL::generateExtensions(outExtensions);
} }
......
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
#include <algorithm> #include <algorithm>
#include "common/platform.h"
#include "common/string_utils.h" #include "common/string_utils.h"
#include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/egl/functionsegl_typedefs.h" #include "libANGLE/renderer/gl/egl/functionsegl_typedefs.h"
...@@ -77,7 +79,9 @@ struct FunctionsEGL::EGLDispatchTable ...@@ -77,7 +79,9 @@ struct FunctionsEGL::EGLDispatchTable
getCompositorTimingANDROIDPtr(nullptr), getCompositorTimingANDROIDPtr(nullptr),
getNextFrameIdANDROIDPtr(nullptr), getNextFrameIdANDROIDPtr(nullptr),
getFrameTimestampSupportedANDROIDPtr(nullptr), getFrameTimestampSupportedANDROIDPtr(nullptr),
getFrameTimestampsANDROIDPtr(nullptr) getFrameTimestampsANDROIDPtr(nullptr),
dupNativeFenceFDANDROIDPtr(nullptr)
{} {}
// 1.0 // 1.0
...@@ -132,6 +136,9 @@ struct FunctionsEGL::EGLDispatchTable ...@@ -132,6 +136,9 @@ struct FunctionsEGL::EGLDispatchTable
PFNEGLGETNEXTFRAMEIDANDROIDPROC getNextFrameIdANDROIDPtr; PFNEGLGETNEXTFRAMEIDANDROIDPROC getNextFrameIdANDROIDPtr;
PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC getFrameTimestampSupportedANDROIDPtr; PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC getFrameTimestampSupportedANDROIDPtr;
PFNEGLGETFRAMETIMESTAMPSANDROIDPROC getFrameTimestampsANDROIDPtr; PFNEGLGETFRAMETIMESTAMPSANDROIDPROC getFrameTimestampsANDROIDPtr;
// EGL_ANDROID_native_fence_sync
PFNEGLDUPNATIVEFENCEFDANDROIDPROC dupNativeFenceFDANDROIDPtr;
}; };
FunctionsEGL::FunctionsEGL() FunctionsEGL::FunctionsEGL()
...@@ -246,6 +253,22 @@ egl::Error FunctionsEGL::initialize(EGLNativeDisplayType nativeDisplay) ...@@ -246,6 +253,22 @@ egl::Error FunctionsEGL::initialize(EGLNativeDisplayType nativeDisplay)
eglGetFrameTimestampsANDROID); eglGetFrameTimestampsANDROID);
} }
// The native fence sync extension is a bit complicated. It's reported as present for ChromeOS,
// but Android currently doesn't report this extension even when it's present, and older devices
// may export a useless wrapper function. See crbug.com/775707 for details. In short, if the
// symbol is present and we're on Android N or newer, assume that it's usable even if the
// extension wasn't reported.
if (hasExtension("EGL_ANDROID_native_fence_sync") || GetAndroidSDKVersion() >= 24)
{
// Don't error trying to load this entry point.
if (SetPtr(&mFnPtrs->dupNativeFenceFDANDROIDPtr,
getProcAddress("eglDupNativeFenceFDANDROID")) &&
!hasExtension("EGL_ANDROID_native_fence_sync"))
{
mExtensions.push_back("EGL_ANDROID_native_fence_sync");
}
}
#undef ANGLE_GET_PROC_OR_ERROR #undef ANGLE_GET_PROC_OR_ERROR
return egl::NoError(); return egl::NoError();
...@@ -470,4 +493,9 @@ EGLBoolean FunctionsEGL::getFrameTimestampsANDROID(EGLSurface surface, ...@@ -470,4 +493,9 @@ EGLBoolean FunctionsEGL::getFrameTimestampsANDROID(EGLSurface surface,
timestamps, values); timestamps, values);
} }
EGLint FunctionsEGL::dupNativeFenceFDANDROID(EGLSync sync) const
{
return mFnPtrs->dupNativeFenceFDANDROIDPtr(mEGLDisplay, sync);
}
} // namespace rx } // namespace rx
...@@ -97,6 +97,8 @@ class FunctionsEGL ...@@ -97,6 +97,8 @@ class FunctionsEGL
const EGLint *timestamps, const EGLint *timestamps,
EGLnsecsANDROID *values) const; EGLnsecsANDROID *values) const;
EGLint dupNativeFenceFDANDROID(EGLSync sync) const;
private: private:
// So as to isolate from angle we do not include angleutils.h and cannot // So as to isolate from angle we do not include angleutils.h and cannot
// use angle::NonCopyable so we replicated it here instead. // use angle::NonCopyable so we replicated it here instead.
......
...@@ -16,7 +16,10 @@ namespace rx ...@@ -16,7 +16,10 @@ namespace rx
{ {
SyncEGL::SyncEGL(const egl::AttributeMap &attribs, const FunctionsEGL *egl) SyncEGL::SyncEGL(const egl::AttributeMap &attribs, const FunctionsEGL *egl)
: mEGL(egl), mSync(EGL_NO_SYNC_KHR) : mEGL(egl),
mNativeFenceFD(
attribs.getAsInt(EGL_SYNC_NATIVE_FENCE_FD_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID)),
mSync(EGL_NO_SYNC_KHR)
{} {}
SyncEGL::~SyncEGL() SyncEGL::~SyncEGL()
...@@ -35,12 +38,22 @@ egl::Error SyncEGL::initialize(const egl::Display *display, ...@@ -35,12 +38,22 @@ egl::Error SyncEGL::initialize(const egl::Display *display,
const gl::Context *context, const gl::Context *context,
EGLenum type) EGLenum type)
{ {
ASSERT(type == EGL_SYNC_FENCE_KHR); ASSERT(type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID);
mSync = mEGL->createSyncKHR(type, nullptr);
std::vector<EGLint> attribs;
if (type == EGL_SYNC_NATIVE_FENCE_ANDROID)
{
attribs.push_back(EGL_SYNC_NATIVE_FENCE_FD_ANDROID);
attribs.push_back(mNativeFenceFD);
}
attribs.push_back(EGL_NONE);
mSync = mEGL->createSyncKHR(type, attribs.data());
if (mSync == EGL_NO_SYNC_KHR) if (mSync == EGL_NO_SYNC_KHR)
{ {
return egl::Error(mEGL->getError(), "eglCreateSync failed to create sync object"); return egl::Error(mEGL->getError(), "eglCreateSync failed to create sync object");
} }
return egl::NoError(); return egl::NoError();
} }
...@@ -90,4 +103,16 @@ egl::Error SyncEGL::getStatus(const egl::Display *display, EGLint *outStatus) ...@@ -90,4 +103,16 @@ egl::Error SyncEGL::getStatus(const egl::Display *display, EGLint *outStatus)
return egl::NoError(); return egl::NoError();
} }
egl::Error SyncEGL::dupNativeFenceFD(const egl::Display *display, EGLint *result) const
{
ASSERT(mSync != EGL_NO_SYNC_KHR);
*result = mEGL->dupNativeFenceFDANDROID(mSync);
if (*result == EGL_NO_NATIVE_FENCE_FD_ANDROID)
{
return egl::Error(mEGL->getError(), "eglDupNativeFenceFDANDROID failed");
}
return egl::NoError();
}
} // namespace rx } // namespace rx
...@@ -42,8 +42,11 @@ class SyncEGL final : public EGLSyncImpl ...@@ -42,8 +42,11 @@ class SyncEGL final : public EGLSyncImpl
EGLint flags) override; EGLint flags) override;
egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override; egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override;
egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *result) const override;
private: private:
const FunctionsEGL *mEGL; const FunctionsEGL *mEGL;
EGLint mNativeFenceFD;
EGLSync mSync; EGLSync mSync;
}; };
......
...@@ -55,7 +55,7 @@ angle::Result FenceSyncVk::initialize(ContextVk *contextVk) ...@@ -55,7 +55,7 @@ angle::Result FenceSyncVk::initialize(ContextVk *contextVk)
ANGLE_TRY(contextVk->getNextSubmitFence(&mFence)); ANGLE_TRY(contextVk->getNextSubmitFence(&mFence));
mEvent = event.release(); mEvent = event.release();
contextVk->getCommandGraph()->setFenceSync(mEvent); contextVk->getCommandGraph()->setFenceSync(mEvent);
return angle::Result::Continue; return angle::Result::Continue;
...@@ -285,4 +285,10 @@ egl::Error EGLSyncVk::getStatus(const egl::Display *display, EGLint *outStatus) ...@@ -285,4 +285,10 @@ egl::Error EGLSyncVk::getStatus(const egl::Display *display, EGLint *outStatus)
return egl::NoError(); return egl::NoError();
} }
egl::Error EGLSyncVk::dupNativeFenceFD(const egl::Display *display, EGLint *result) const
{
UNREACHABLE();
return egl::EglBadDisplay();
}
} // namespace rx } // namespace rx
...@@ -94,6 +94,8 @@ class EGLSyncVk final : public EGLSyncImpl ...@@ -94,6 +94,8 @@ class EGLSyncVk final : public EGLSyncImpl
EGLint flags) override; EGLint flags) override;
egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override; egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override;
egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *result) const override;
private: private:
FenceSyncVk mFenceSync; FenceSyncVk mFenceSync;
}; };
......
...@@ -2205,20 +2205,30 @@ Error ValidateCreateSyncBase(const Display *display, ...@@ -2205,20 +2205,30 @@ Error ValidateCreateSyncBase(const Display *display,
{ {
return EglBadAttribute() << "Invalid attribute"; return EglBadAttribute() << "Invalid attribute";
} }
break;
if (display != currentDisplay) case EGL_SYNC_NATIVE_FENCE_ANDROID:
if (!display->getExtensions().nativeFenceSyncANDROID)
{ {
return EglBadMatch() << "CreateSync can only be called on the current display"; return EglBadDisplay()
<< "EGL_ANDROID_native_fence_sync extension is not available.";
} }
ANGLE_TRY(ValidateContext(currentDisplay, currentContext)); for (const auto &attributeIter : attribs)
if (!currentContext->getExtensions().eglSync)
{ {
return EglBadMatch() << "EGL_SYNC_FENCE_KHR cannot be used without " EGLAttrib attribute = attributeIter.first;
"GL_OES_EGL_sync support.";
switch (attribute)
{
case EGL_SYNC_NATIVE_FENCE_FD_ANDROID:
break;
default:
return EglBadAttribute() << "Invalid attribute";
}
} }
break; break;
default: default:
if (isExt) if (isExt)
{ {
...@@ -2230,6 +2240,19 @@ Error ValidateCreateSyncBase(const Display *display, ...@@ -2230,6 +2240,19 @@ Error ValidateCreateSyncBase(const Display *display,
} }
} }
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.";
}
return NoError(); return NoError();
} }
...@@ -2240,15 +2263,23 @@ Error ValidateGetSyncAttribBase(const Display *display, const Sync *sync, EGLint ...@@ -2240,15 +2263,23 @@ Error ValidateGetSyncAttribBase(const Display *display, const Sync *sync, EGLint
switch (attribute) switch (attribute)
{ {
case EGL_SYNC_CONDITION_KHR: case EGL_SYNC_CONDITION_KHR:
if (sync->getType() != EGL_SYNC_FENCE_KHR) switch (sync->getType())
{ {
return EglBadAttribute() << "EGL_SYNC_CONDITION_KHR is only valid for fence syncs"; case EGL_SYNC_FENCE_KHR:
case EGL_SYNC_NATIVE_FENCE_ANDROID:
break;
default:
return EglBadAttribute()
<< "EGL_SYNC_CONDITION_KHR is not valid for this sync type.";
} }
break; break;
// The following attributes are accepted by all types // The following attributes are accepted by all types
case EGL_SYNC_TYPE_KHR: case EGL_SYNC_TYPE_KHR:
case EGL_SYNC_STATUS_KHR: case EGL_SYNC_STATUS_KHR:
break; break;
default: default:
return EglBadAttribute() << "Invalid attribute"; return EglBadAttribute() << "Invalid attribute";
} }
...@@ -3869,4 +3900,24 @@ Error ValidateGetNativeClientBufferANDROID(const AHardwareBuffer *buffer) ...@@ -3869,4 +3900,24 @@ Error ValidateGetNativeClientBufferANDROID(const AHardwareBuffer *buffer)
return NoError(); return NoError();
} }
Error ValidateDupNativeFenceFDANDROID(const Display *display, const Sync *sync)
{
ANGLE_TRY(ValidateDisplay(display));
if (!display->getExtensions().nativeFenceSyncANDROID)
{
return EglBadDisplay() << "EGL_ANDROID_native_fence_sync extension is not available.";
}
ANGLE_TRY(ValidateSync(display, sync));
if (sync->getNativeFenceFD() == EGL_NO_NATIVE_FENCE_FD_ANDROID)
{
return EglBadParameter() << "EGL_NATIVE_FENCE_FD_ANDROID attribute of sync is "
"EGL_NO_NATIVE_FENCE_FD_ANDROID";
}
return NoError();
}
} // namespace egl } // namespace egl
...@@ -329,6 +329,9 @@ Error ValidateQueryDisplayAttribANGLE(const Display *display, const EGLint attri ...@@ -329,6 +329,9 @@ Error ValidateQueryDisplayAttribANGLE(const Display *display, const EGLint attri
// EGL_ANDROID_get_native_client_buffer // EGL_ANDROID_get_native_client_buffer
Error ValidateGetNativeClientBufferANDROID(const struct AHardwareBuffer *buffer); Error ValidateGetNativeClientBufferANDROID(const struct AHardwareBuffer *buffer);
// EGL_ANDROID_native_fence_sync
Error ValidateDupNativeFenceFDANDROID(const Display *display, const Sync *sync);
} // namespace egl } // namespace egl
#define ANGLE_EGL_TRY(THREAD, EXPR, FUNCNAME, LABELOBJECT) \ #define ANGLE_EGL_TRY(THREAD, EXPR, FUNCNAME, LABELOBJECT) \
......
...@@ -61,6 +61,7 @@ PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC EGL_GetFrameTimestampSupportedANDROI ...@@ -61,6 +61,7 @@ PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC EGL_GetFrameTimestampSupportedANDROI
PFNEGLGETFRAMETIMESTAMPSANDROIDPROC EGL_GetFrameTimestampsANDROID; PFNEGLGETFRAMETIMESTAMPSANDROIDPROC EGL_GetFrameTimestampsANDROID;
PFNEGLGETNEXTFRAMEIDANDROIDPROC EGL_GetNextFrameIdANDROID; PFNEGLGETNEXTFRAMEIDANDROIDPROC EGL_GetNextFrameIdANDROID;
PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC EGL_GetNativeClientBufferANDROID; PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC EGL_GetNativeClientBufferANDROID;
PFNEGLDUPNATIVEFENCEFDANDROIDPROC EGL_DupNativeFenceFDANDROID;
PFNEGLPRESENTATIONTIMEANDROIDPROC EGL_PresentationTimeANDROID; PFNEGLPRESENTATIONTIMEANDROIDPROC EGL_PresentationTimeANDROID;
PFNEGLCREATEDEVICEANGLEPROC EGL_CreateDeviceANGLE; PFNEGLCREATEDEVICEANGLEPROC EGL_CreateDeviceANGLE;
PFNEGLRELEASEDEVICEANGLEPROC EGL_ReleaseDeviceANGLE; PFNEGLRELEASEDEVICEANGLEPROC EGL_ReleaseDeviceANGLE;
...@@ -178,6 +179,8 @@ void LoadEGL_EGL(LoadProc loadProc) ...@@ -178,6 +179,8 @@ void LoadEGL_EGL(LoadProc loadProc)
reinterpret_cast<PFNEGLGETNEXTFRAMEIDANDROIDPROC>(loadProc("EGL_GetNextFrameIdANDROID")); reinterpret_cast<PFNEGLGETNEXTFRAMEIDANDROIDPROC>(loadProc("EGL_GetNextFrameIdANDROID"));
EGL_GetNativeClientBufferANDROID = reinterpret_cast<PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC>( EGL_GetNativeClientBufferANDROID = reinterpret_cast<PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC>(
loadProc("EGL_GetNativeClientBufferANDROID")); loadProc("EGL_GetNativeClientBufferANDROID"));
EGL_DupNativeFenceFDANDROID = reinterpret_cast<PFNEGLDUPNATIVEFENCEFDANDROIDPROC>(
loadProc("EGL_DupNativeFenceFDANDROID"));
EGL_PresentationTimeANDROID = reinterpret_cast<PFNEGLPRESENTATIONTIMEANDROIDPROC>( EGL_PresentationTimeANDROID = reinterpret_cast<PFNEGLPRESENTATIONTIMEANDROIDPROC>(
loadProc("EGL_PresentationTimeANDROID")); loadProc("EGL_PresentationTimeANDROID"));
EGL_CreateDeviceANGLE = EGL_CreateDeviceANGLE =
......
...@@ -65,6 +65,7 @@ extern PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC EGL_GetFrameTimestampSupporte ...@@ -65,6 +65,7 @@ extern PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC EGL_GetFrameTimestampSupporte
extern PFNEGLGETFRAMETIMESTAMPSANDROIDPROC EGL_GetFrameTimestampsANDROID; extern PFNEGLGETFRAMETIMESTAMPSANDROIDPROC EGL_GetFrameTimestampsANDROID;
extern PFNEGLGETNEXTFRAMEIDANDROIDPROC EGL_GetNextFrameIdANDROID; extern PFNEGLGETNEXTFRAMEIDANDROIDPROC EGL_GetNextFrameIdANDROID;
extern PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC EGL_GetNativeClientBufferANDROID; extern PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC EGL_GetNativeClientBufferANDROID;
extern PFNEGLDUPNATIVEFENCEFDANDROIDPROC EGL_DupNativeFenceFDANDROID;
extern PFNEGLPRESENTATIONTIMEANDROIDPROC EGL_PresentationTimeANDROID; extern PFNEGLPRESENTATIONTIMEANDROIDPROC EGL_PresentationTimeANDROID;
extern PFNEGLCREATEDEVICEANGLEPROC EGL_CreateDeviceANGLE; extern PFNEGLCREATEDEVICEANGLEPROC EGL_CreateDeviceANGLE;
extern PFNEGLRELEASEDEVICEANGLEPROC EGL_ReleaseDeviceANGLE; extern PFNEGLRELEASEDEVICEANGLEPROC EGL_ReleaseDeviceANGLE;
......
...@@ -700,4 +700,10 @@ EGLClientBuffer EGLAPIENTRY eglGetNativeClientBufferANDROID(const struct AHardwa ...@@ -700,4 +700,10 @@ EGLClientBuffer EGLAPIENTRY eglGetNativeClientBufferANDROID(const struct AHardwa
return EGL_GetNativeClientBufferANDROID(buffer); return EGL_GetNativeClientBufferANDROID(buffer);
} }
EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync)
{
EnsureEGLLoaded();
return EGL_DupNativeFenceFDANDROID(dpy, sync);
}
} // extern "C" } // extern "C"
...@@ -73,6 +73,7 @@ EXPORTS ...@@ -73,6 +73,7 @@ EXPORTS
eglQueryDisplayAttribANGLE @79 eglQueryDisplayAttribANGLE @79
eglQueryStringiANGLE @80 eglQueryStringiANGLE @80
eglGetNativeClientBufferANDROID @81 eglGetNativeClientBufferANDROID @81
eglDupNativeFenceFDANDROID @82
; 1.5 entry points ; 1.5 entry points
eglCreateSync @38 eglCreateSync @38
......
...@@ -1454,4 +1454,27 @@ EGLClientBuffer EGLAPIENTRY EGL_GetNativeClientBufferANDROID(const struct AHardw ...@@ -1454,4 +1454,27 @@ EGLClientBuffer EGLAPIENTRY EGL_GetNativeClientBufferANDROID(const struct AHardw
return egl::Display::GetNativeClientBuffer(buffer); return egl::Display::GetNativeClientBuffer(buffer);
} }
EGLint EGLAPIENTRY EGL_DupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync)
{
ANGLE_SCOPED_GLOBAL_LOCK();
EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSyncKHR sync = 0x%016" PRIxPTR ")",
(uintptr_t)dpy, (uintptr_t)sync);
egl::Display *display = static_cast<egl::Display *>(dpy);
Sync *syncObject = static_cast<Sync *>(sync);
Thread *thread = egl::GetCurrentThread();
ANGLE_EGL_TRY_RETURN(thread, ValidateDupNativeFenceFDANDROID(display, syncObject),
"eglDupNativeFenceFDANDROID", GetSyncIfValid(display, syncObject),
EGL_NO_NATIVE_FENCE_FD_ANDROID);
EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
ANGLE_EGL_TRY_RETURN(thread, syncObject->dupNativeFenceFD(display, &result),
"eglDupNativeFenceFDANDROID", GetSyncIfValid(display, syncObject),
EGL_NO_NATIVE_FENCE_FD_ANDROID);
thread->setSuccess();
return result;
}
} // extern "C" } // extern "C"
...@@ -214,6 +214,9 @@ ANGLE_EXPORT const char *EGLAPIENTRY EGL_QueryStringiANGLE(EGLDisplay dpy, ...@@ -214,6 +214,9 @@ ANGLE_EXPORT const char *EGLAPIENTRY EGL_QueryStringiANGLE(EGLDisplay dpy,
ANGLE_EXPORT EGLClientBuffer EGLAPIENTRY ANGLE_EXPORT EGLClientBuffer EGLAPIENTRY
EGL_GetNativeClientBufferANDROID(const struct AHardwareBuffer *buffer); EGL_GetNativeClientBufferANDROID(const struct AHardwareBuffer *buffer);
// EGL_ANDROID_native_fence_sync
ANGLE_EXPORT EGLint EGLAPIENTRY EGL_DupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync);
} // extern "C" } // extern "C"
#endif // LIBGLESV2_ENTRYPOINTSEGLEXT_H_ #endif // LIBGLESV2_ENTRYPOINTSEGLEXT_H_
...@@ -1492,6 +1492,9 @@ EXPORTS ...@@ -1492,6 +1492,9 @@ EXPORTS
; EGL_ANDROID_get_native_client_buffer ; EGL_ANDROID_get_native_client_buffer
EGL_GetNativeClientBufferANDROID EGL_GetNativeClientBufferANDROID
; EGL_ANDROID_native_fence_sync
EGL_DupNativeFenceFDANDROID
; EGL_ANDROID_presentation_time ; EGL_ANDROID_presentation_time
EGL_PresentationTimeANDROID EGL_PresentationTimeANDROID
......
...@@ -1492,6 +1492,9 @@ EXPORTS ...@@ -1492,6 +1492,9 @@ EXPORTS
; EGL_ANDROID_get_native_client_buffer ; EGL_ANDROID_get_native_client_buffer
EGL_GetNativeClientBufferANDROID EGL_GetNativeClientBufferANDROID
; EGL_ANDROID_native_fence_sync
EGL_DupNativeFenceFDANDROID
; EGL_ANDROID_presentation_time ; EGL_ANDROID_presentation_time
EGL_PresentationTimeANDROID EGL_PresentationTimeANDROID
......
...@@ -58,6 +58,7 @@ ProcEntry g_procTable[] = { ...@@ -58,6 +58,7 @@ ProcEntry g_procTable[] = {
{"eglDestroySurface", P(EGL_DestroySurface)}, {"eglDestroySurface", P(EGL_DestroySurface)},
{"eglDestroySync", P(EGL_DestroySync)}, {"eglDestroySync", P(EGL_DestroySync)},
{"eglDestroySyncKHR", P(EGL_DestroySyncKHR)}, {"eglDestroySyncKHR", P(EGL_DestroySyncKHR)},
{"eglDupNativeFenceFDANDROID", P(EGL_DupNativeFenceFDANDROID)},
{"eglGetCompositorTimingANDROID", P(EGL_GetCompositorTimingANDROID)}, {"eglGetCompositorTimingANDROID", P(EGL_GetCompositorTimingANDROID)},
{"eglGetCompositorTimingSupportedANDROID", P(EGL_GetCompositorTimingSupportedANDROID)}, {"eglGetCompositorTimingSupportedANDROID", P(EGL_GetCompositorTimingSupportedANDROID)},
{"eglGetConfigAttrib", P(EGL_GetConfigAttrib)}, {"eglGetConfigAttrib", P(EGL_GetConfigAttrib)},
...@@ -1490,5 +1491,5 @@ ProcEntry g_procTable[] = { ...@@ -1490,5 +1491,5 @@ ProcEntry g_procTable[] = {
{"glWeightPointerOES", P(gl::WeightPointerOES)}, {"glWeightPointerOES", P(gl::WeightPointerOES)},
{"glWeightPointerOESContextANGLE", P(gl::WeightPointerOESContextANGLE)}}; {"glWeightPointerOESContextANGLE", P(gl::WeightPointerOESContextANGLE)}};
size_t g_numProcs = 1401; size_t g_numProcs = 1402;
} // namespace egl } // namespace egl
...@@ -62,6 +62,7 @@ ANGLE_UTIL_EXPORT PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC eglGetFrameTimesta ...@@ -62,6 +62,7 @@ ANGLE_UTIL_EXPORT PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC eglGetFrameTimesta
ANGLE_UTIL_EXPORT PFNEGLGETFRAMETIMESTAMPSANDROIDPROC eglGetFrameTimestampsANDROID; ANGLE_UTIL_EXPORT PFNEGLGETFRAMETIMESTAMPSANDROIDPROC eglGetFrameTimestampsANDROID;
ANGLE_UTIL_EXPORT PFNEGLGETNEXTFRAMEIDANDROIDPROC eglGetNextFrameIdANDROID; ANGLE_UTIL_EXPORT PFNEGLGETNEXTFRAMEIDANDROIDPROC eglGetNextFrameIdANDROID;
ANGLE_UTIL_EXPORT PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC eglGetNativeClientBufferANDROID; ANGLE_UTIL_EXPORT PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC eglGetNativeClientBufferANDROID;
ANGLE_UTIL_EXPORT PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID;
ANGLE_UTIL_EXPORT PFNEGLPRESENTATIONTIMEANDROIDPROC eglPresentationTimeANDROID; ANGLE_UTIL_EXPORT PFNEGLPRESENTATIONTIMEANDROIDPROC eglPresentationTimeANDROID;
ANGLE_UTIL_EXPORT PFNEGLCREATEDEVICEANGLEPROC eglCreateDeviceANGLE; ANGLE_UTIL_EXPORT PFNEGLCREATEDEVICEANGLEPROC eglCreateDeviceANGLE;
ANGLE_UTIL_EXPORT PFNEGLRELEASEDEVICEANGLEPROC eglReleaseDeviceANGLE; ANGLE_UTIL_EXPORT PFNEGLRELEASEDEVICEANGLEPROC eglReleaseDeviceANGLE;
...@@ -182,6 +183,8 @@ void LoadEGL(LoadProc loadProc) ...@@ -182,6 +183,8 @@ void LoadEGL(LoadProc loadProc)
reinterpret_cast<PFNEGLGETNEXTFRAMEIDANDROIDPROC>(loadProc("eglGetNextFrameIdANDROID")); reinterpret_cast<PFNEGLGETNEXTFRAMEIDANDROIDPROC>(loadProc("eglGetNextFrameIdANDROID"));
eglGetNativeClientBufferANDROID = reinterpret_cast<PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC>( eglGetNativeClientBufferANDROID = reinterpret_cast<PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC>(
loadProc("eglGetNativeClientBufferANDROID")); loadProc("eglGetNativeClientBufferANDROID"));
eglDupNativeFenceFDANDROID =
reinterpret_cast<PFNEGLDUPNATIVEFENCEFDANDROIDPROC>(loadProc("eglDupNativeFenceFDANDROID"));
eglPresentationTimeANDROID = eglPresentationTimeANDROID =
reinterpret_cast<PFNEGLPRESENTATIONTIMEANDROIDPROC>(loadProc("eglPresentationTimeANDROID")); reinterpret_cast<PFNEGLPRESENTATIONTIMEANDROIDPROC>(loadProc("eglPresentationTimeANDROID"));
eglCreateDeviceANGLE = eglCreateDeviceANGLE =
......
...@@ -69,6 +69,7 @@ ANGLE_UTIL_EXPORT extern PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC ...@@ -69,6 +69,7 @@ ANGLE_UTIL_EXPORT extern PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC
ANGLE_UTIL_EXPORT extern PFNEGLGETFRAMETIMESTAMPSANDROIDPROC eglGetFrameTimestampsANDROID; ANGLE_UTIL_EXPORT extern PFNEGLGETFRAMETIMESTAMPSANDROIDPROC eglGetFrameTimestampsANDROID;
ANGLE_UTIL_EXPORT extern PFNEGLGETNEXTFRAMEIDANDROIDPROC eglGetNextFrameIdANDROID; ANGLE_UTIL_EXPORT extern PFNEGLGETNEXTFRAMEIDANDROIDPROC eglGetNextFrameIdANDROID;
ANGLE_UTIL_EXPORT extern PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC eglGetNativeClientBufferANDROID; ANGLE_UTIL_EXPORT extern PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC eglGetNativeClientBufferANDROID;
ANGLE_UTIL_EXPORT extern PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceFDANDROID;
ANGLE_UTIL_EXPORT extern PFNEGLPRESENTATIONTIMEANDROIDPROC eglPresentationTimeANDROID; ANGLE_UTIL_EXPORT extern PFNEGLPRESENTATIONTIMEANDROIDPROC eglPresentationTimeANDROID;
ANGLE_UTIL_EXPORT extern PFNEGLCREATEDEVICEANGLEPROC eglCreateDeviceANGLE; ANGLE_UTIL_EXPORT extern PFNEGLCREATEDEVICEANGLEPROC eglCreateDeviceANGLE;
ANGLE_UTIL_EXPORT extern PFNEGLRELEASEDEVICEANGLEPROC eglReleaseDeviceANGLE; ANGLE_UTIL_EXPORT extern PFNEGLRELEASEDEVICEANGLEPROC eglReleaseDeviceANGLE;
......
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