summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp')
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp340
1 files changed, 340 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp
new file mode 100755
index 000000000..c0b0f846f
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp
@@ -0,0 +1,340 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FunctionsEGL.cpp: Implements the FunctionsEGL class.
+
+#include "libANGLE/renderer/gl/egl/FunctionsEGL.h"
+
+#include <algorithm>
+
+#include "libANGLE/renderer/gl/FunctionsGL.h"
+#include "libANGLE/renderer/gl/egl/functionsegl_typedefs.h"
+#include "common/string_utils.h"
+
+namespace
+{
+
+template <typename T>
+bool SetPtr(T *dst, void *src)
+{
+ if (src)
+ {
+ *dst = reinterpret_cast<T>(src);
+ return true;
+ }
+ return false;
+}
+} // namespace
+
+namespace rx
+{
+
+struct FunctionsEGL::EGLDispatchTable
+{
+ EGLDispatchTable()
+ : bindAPIPtr(nullptr),
+ chooseConfigPtr(nullptr),
+ createContextPtr(nullptr),
+ createPbufferSurfacePtr(nullptr),
+ createWindowSurfacePtr(nullptr),
+ destroyContextPtr(nullptr),
+ destroySurfacePtr(nullptr),
+ getConfigAttribPtr(nullptr),
+ getDisplayPtr(nullptr),
+ getErrorPtr(nullptr),
+ initializePtr(nullptr),
+ makeCurrentPtr(nullptr),
+ queryStringPtr(nullptr),
+ querySurfacePtr(nullptr),
+ swapBuffersPtr(nullptr),
+ terminatePtr(nullptr),
+
+ bindTexImagePtr(nullptr),
+ releaseTexImagePtr(nullptr),
+ swapIntervalPtr(nullptr),
+
+ createImageKHRPtr(nullptr),
+ destroyImageKHRPtr(nullptr),
+
+ clientWaitSyncKHRPtr(nullptr),
+ createSyncKHRPtr(nullptr),
+ destroySyncKHRPtr(nullptr),
+ getSyncAttribKHRPtr(nullptr)
+ {
+ }
+
+ // 1.0
+ PFNEGLBINDAPIPROC bindAPIPtr;
+ PFNEGLCHOOSECONFIGPROC chooseConfigPtr;
+ PFNEGLCREATECONTEXTPROC createContextPtr;
+ PFNEGLCREATEPBUFFERSURFACEPROC createPbufferSurfacePtr;
+ PFNEGLCREATEWINDOWSURFACEPROC createWindowSurfacePtr;
+ PFNEGLDESTROYCONTEXTPROC destroyContextPtr;
+ PFNEGLDESTROYSURFACEPROC destroySurfacePtr;
+ PFNEGLGETCONFIGATTRIBPROC getConfigAttribPtr;
+ PFNEGLGETDISPLAYPROC getDisplayPtr;
+ PFNEGLGETERRORPROC getErrorPtr;
+ PFNEGLINITIALIZEPROC initializePtr;
+ PFNEGLMAKECURRENTPROC makeCurrentPtr;
+ PFNEGLQUERYSTRINGPROC queryStringPtr;
+ PFNEGLQUERYSURFACEPROC querySurfacePtr;
+ PFNEGLSWAPBUFFERSPROC swapBuffersPtr;
+ PFNEGLTERMINATEPROC terminatePtr;
+
+ // 1.1
+ PFNEGLBINDTEXIMAGEPROC bindTexImagePtr;
+ PFNEGLRELEASETEXIMAGEPROC releaseTexImagePtr;
+ PFNEGLSWAPINTERVALPROC swapIntervalPtr;
+
+ // EGL_KHR_image
+ PFNEGLCREATEIMAGEKHRPROC createImageKHRPtr;
+ PFNEGLDESTROYIMAGEKHRPROC destroyImageKHRPtr;
+
+ // EGL_KHR_fence_sync
+ PFNEGLCLIENTWAITSYNCKHRPROC clientWaitSyncKHRPtr;
+ PFNEGLCREATESYNCKHRPROC createSyncKHRPtr;
+ PFNEGLDESTROYSYNCKHRPROC destroySyncKHRPtr;
+ PFNEGLGETSYNCATTRIBKHRPROC getSyncAttribKHRPtr;
+};
+
+FunctionsEGL::FunctionsEGL()
+ : majorVersion(0), minorVersion(0), mFnPtrs(new EGLDispatchTable()), mEGLDisplay(EGL_NO_DISPLAY)
+{
+}
+
+FunctionsEGL::~FunctionsEGL()
+{
+ SafeDelete(mFnPtrs);
+}
+
+egl::Error FunctionsEGL::initialize(EGLNativeDisplayType nativeDisplay)
+{
+#define ANGLE_GET_PROC_OR_ERROR(MEMBER, NAME) \
+ if (!SetPtr(MEMBER, getProcAddress(#NAME))) \
+ { \
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not load EGL entry point " #NAME); \
+ }
+
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->bindAPIPtr, eglBindAPI);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->chooseConfigPtr, eglChooseConfig);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createContextPtr, eglCreateContext);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createPbufferSurfacePtr, eglCreatePbufferSurface);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createWindowSurfacePtr, eglCreateWindowSurface);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->destroyContextPtr, eglDestroyContext);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->destroySurfacePtr, eglDestroySurface);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getConfigAttribPtr, eglGetConfigAttrib);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getDisplayPtr, eglGetDisplay);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getErrorPtr, eglGetError);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->initializePtr, eglInitialize);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->makeCurrentPtr, eglMakeCurrent);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->queryStringPtr, eglQueryString);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->querySurfacePtr, eglQuerySurface);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->swapBuffersPtr, eglSwapBuffers);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->terminatePtr, eglTerminate);
+
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->bindTexImagePtr, eglBindTexImage);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->releaseTexImagePtr, eglReleaseTexImage);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalPtr, eglSwapInterval);
+
+ mEGLDisplay = mFnPtrs->getDisplayPtr(nativeDisplay);
+ if (mEGLDisplay == EGL_NO_DISPLAY)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Failed to get system egl display");
+ }
+ if (mFnPtrs->initializePtr(mEGLDisplay, &majorVersion, &minorVersion) != EGL_TRUE)
+ {
+ return egl::Error(mFnPtrs->getErrorPtr(), "Failed to initialize system egl");
+ }
+ if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 4))
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Unsupported EGL version (require at least 1.4).");
+ }
+ if (mFnPtrs->bindAPIPtr(EGL_OPENGL_ES_API) != EGL_TRUE)
+ {
+ return egl::Error(mFnPtrs->getErrorPtr(), "Failed to bind API in system egl");
+ }
+
+ const char *extensions = queryString(EGL_EXTENSIONS);
+ if (!extensions)
+ {
+ return egl::Error(mFnPtrs->getErrorPtr(), "Faild to query extensions in system egl");
+ }
+ angle::SplitStringAlongWhitespace(extensions, &mExtensions);
+
+ if (hasExtension("EGL_KHR_image_base"))
+ {
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->createImageKHRPtr, eglCreateImageKHR);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->destroyImageKHRPtr, eglDestroyImageKHR);
+ }
+ 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->destroySyncKHRPtr, eglDestroySyncKHR);
+ ANGLE_GET_PROC_OR_ERROR(&mFnPtrs->getSyncAttribKHRPtr, eglGetSyncAttribKHR);
+ }
+
+#undef ANGLE_GET_PROC_OR_ERROR
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error FunctionsEGL::terminate()
+{
+ if (mFnPtrs->terminatePtr(mEGLDisplay) == EGL_TRUE)
+ {
+ mEGLDisplay = nullptr;
+ return egl::Error(EGL_SUCCESS);
+ }
+ return egl::Error(mFnPtrs->getErrorPtr());
+}
+
+class FunctionsGLEGL : public FunctionsGL
+{
+ public:
+ FunctionsGLEGL(const FunctionsEGL &egl) : mEGL(egl) {}
+
+ ~FunctionsGLEGL() override {}
+
+ private:
+ void *loadProcAddress(const std::string &function) override
+ {
+ return mEGL.getProcAddress(function.c_str());
+ }
+
+ const FunctionsEGL &mEGL;
+};
+
+FunctionsGL *FunctionsEGL::makeFunctionsGL(void) const
+{
+ return new FunctionsGLEGL(*this);
+}
+
+bool FunctionsEGL::hasExtension(const char *extension) const
+{
+ return std::find(mExtensions.begin(), mExtensions.end(), extension) != mExtensions.end();
+}
+
+EGLDisplay FunctionsEGL::getDisplay() const
+{
+ return mEGLDisplay;
+}
+
+EGLint FunctionsEGL::getError() const
+{
+ return mFnPtrs->getErrorPtr();
+}
+
+EGLBoolean FunctionsEGL::chooseConfig(EGLint const *attribList,
+ EGLConfig *configs,
+ EGLint configSize,
+ EGLint *numConfig) const
+{
+ return mFnPtrs->chooseConfigPtr(mEGLDisplay, attribList, configs, configSize, numConfig);
+}
+
+EGLBoolean FunctionsEGL::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value) const
+{
+ return mFnPtrs->getConfigAttribPtr(mEGLDisplay, config, attribute, value);
+}
+
+EGLContext FunctionsEGL::createContext(EGLConfig config,
+ EGLContext share_context,
+ EGLint const *attrib_list) const
+{
+ return mFnPtrs->createContextPtr(mEGLDisplay, config, share_context, attrib_list);
+}
+
+EGLSurface FunctionsEGL::createPbufferSurface(EGLConfig config, const EGLint *attrib_list) const
+{
+ return mFnPtrs->createPbufferSurfacePtr(mEGLDisplay, config, attrib_list);
+}
+
+EGLSurface FunctionsEGL::createWindowSurface(EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list) const
+{
+ return mFnPtrs->createWindowSurfacePtr(mEGLDisplay, config, win, attrib_list);
+}
+
+EGLBoolean FunctionsEGL::destroyContext(EGLContext context) const
+{
+ return mFnPtrs->destroyContextPtr(mEGLDisplay, context);
+}
+
+EGLBoolean FunctionsEGL::destroySurface(EGLSurface surface) const
+{
+ return mFnPtrs->destroySurfacePtr(mEGLDisplay, surface);
+}
+
+EGLBoolean FunctionsEGL::makeCurrent(EGLSurface surface, EGLContext context) const
+{
+ return mFnPtrs->makeCurrentPtr(mEGLDisplay, surface, surface, context);
+}
+
+char const *FunctionsEGL::queryString(EGLint name) const
+{
+ return mFnPtrs->queryStringPtr(mEGLDisplay, name);
+}
+
+EGLBoolean FunctionsEGL::querySurface(EGLSurface surface, EGLint attribute, EGLint *value) const
+{
+ return mFnPtrs->querySurfacePtr(mEGLDisplay, surface, attribute, value);
+}
+
+EGLBoolean FunctionsEGL::swapBuffers(EGLSurface surface) const
+{
+ return mFnPtrs->swapBuffersPtr(mEGLDisplay, surface);
+}
+
+EGLBoolean FunctionsEGL::bindTexImage(EGLSurface surface, EGLint buffer) const
+{
+ return mFnPtrs->bindTexImagePtr(mEGLDisplay, surface, buffer);
+}
+
+EGLBoolean FunctionsEGL::releaseTexImage(EGLSurface surface, EGLint buffer) const
+{
+ return mFnPtrs->releaseTexImagePtr(mEGLDisplay, surface, buffer);
+}
+
+EGLBoolean FunctionsEGL::swapInterval(EGLint interval) const
+{
+ return mFnPtrs->swapIntervalPtr(mEGLDisplay, interval);
+}
+
+EGLImageKHR FunctionsEGL::createImageKHR(EGLContext context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLint *attrib_list) const
+{
+ return mFnPtrs->createImageKHRPtr(mEGLDisplay, context, target, buffer, attrib_list);
+}
+
+EGLBoolean FunctionsEGL::destroyImageKHR(EGLImageKHR image) const
+{
+ return mFnPtrs->destroyImageKHRPtr(mEGLDisplay, image);
+}
+
+EGLSyncKHR FunctionsEGL::createSyncKHR(EGLenum type, const EGLint *attrib_list)
+{
+ return mFnPtrs->createSyncKHRPtr(mEGLDisplay, type, attrib_list);
+}
+
+EGLBoolean FunctionsEGL::destroySyncKHR(EGLSyncKHR sync)
+{
+ return mFnPtrs->destroySyncKHRPtr(mEGLDisplay, sync);
+}
+
+EGLint FunctionsEGL::clientWaitSyncKHR(EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+ return mFnPtrs->clientWaitSyncKHRPtr(mEGLDisplay, sync, flags, timeout);
+}
+
+EGLBoolean FunctionsEGL::getSyncAttribKHR(EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+ return mFnPtrs->getSyncAttribKHRPtr(mEGLDisplay, sync, attribute, value);
+}
+} // namespace rx