diff options
Diffstat (limited to 'gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp')
-rwxr-xr-x | gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp | 340 |
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 |