diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/platform/graphics/egl/GLContextEGL.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/platform/graphics/egl/GLContextEGL.cpp')
-rw-r--r-- | Source/WebCore/platform/graphics/egl/GLContextEGL.cpp | 198 |
1 files changed, 106 insertions, 92 deletions
diff --git a/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp b/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp index 329131601..a086efa98 100644 --- a/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp +++ b/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp @@ -22,7 +22,8 @@ #if USE(EGL) #include "GraphicsContext3D.h" -#include <wtf/OwnPtr.h> +#include "PlatformDisplay.h" +#include <EGL/egl.h> #if USE(CAIRO) #include <cairo.h> @@ -45,30 +46,6 @@ namespace WebCore { -static EGLDisplay gSharedEGLDisplay = EGL_NO_DISPLAY; - -#if USE(OPENGL_ES_2) -static const EGLenum gGLAPI = EGL_OPENGL_ES_API; -#else -static const EGLenum gGLAPI = EGL_OPENGL_API; -#endif - -static EGLDisplay sharedEGLDisplay() -{ - static bool initialized = false; - if (!initialized) { - initialized = true; -#if PLATFORM(X11) - gSharedEGLDisplay = eglGetDisplay(GLContext::sharedX11Display()); -#else - gSharedEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); -#endif - if (gSharedEGLDisplay != EGL_NO_DISPLAY && (!eglInitialize(gSharedEGLDisplay, 0, 0) || !eglBindAPI(gGLAPI))) - gSharedEGLDisplay = EGL_NO_DISPLAY; - } - return gSharedEGLDisplay; -} - static const EGLint gContextAttributes[] = { #if USE(OPENGL_ES_2) EGL_CONTEXT_CLIENT_VERSION, 2, @@ -76,7 +53,13 @@ static const EGLint gContextAttributes[] = { EGL_NONE }; -static bool getEGLConfig(EGLConfig* config, GLContextEGL::EGLSurfaceType surfaceType) +#if USE(OPENGL_ES_2) +static const EGLenum gEGLAPIVersion = EGL_OPENGL_ES_API; +#else +static const EGLenum gEGLAPIVersion = EGL_OPENGL_API; +#endif + +bool GLContextEGL::getEGLConfig(EGLDisplay display, EGLConfig* config, EGLSurfaceType surfaceType) { EGLint attributeList[] = { #if USE(OPENGL_ES_2) @@ -101,45 +84,52 @@ static bool getEGLConfig(EGLConfig* config, GLContextEGL::EGLSurfaceType surface attributeList[13] = EGL_PIXMAP_BIT; break; case GLContextEGL::WindowSurface: + case GLContextEGL::Surfaceless: attributeList[13] = EGL_WINDOW_BIT; break; } EGLint numberConfigsReturned; - return eglChooseConfig(sharedEGLDisplay(), attributeList, config, 1, &numberConfigsReturned) && numberConfigsReturned; + return eglChooseConfig(display, attributeList, config, 1, &numberConfigsReturned) && numberConfigsReturned; } -PassOwnPtr<GLContextEGL> GLContextEGL::createWindowContext(EGLNativeWindowType window, GLContext* sharingContext) +std::unique_ptr<GLContextEGL> GLContextEGL::createWindowContext(GLNativeWindowType window, PlatformDisplay& platformDisplay, EGLContext sharingContext) { - EGLContext eglSharingContext = sharingContext ? static_cast<GLContextEGL*>(sharingContext)->m_context : 0; - - EGLDisplay display = sharedEGLDisplay(); - if (display == EGL_NO_DISPLAY) - return nullptr; - + EGLDisplay display = platformDisplay.eglDisplay(); EGLConfig config; - if (!getEGLConfig(&config, WindowSurface)) + if (!getEGLConfig(display, &config, WindowSurface)) return nullptr; - EGLContext context = eglCreateContext(display, config, eglSharingContext, gContextAttributes); + EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes); if (context == EGL_NO_CONTEXT) return nullptr; - EGLSurface surface = eglCreateWindowSurface(display, config, window, 0); - if (surface == EGL_NO_SURFACE) + EGLSurface surface = EGL_NO_SURFACE; +#if PLATFORM(GTK) +#if PLATFORM(X11) + if (platformDisplay.type() == PlatformDisplay::Type::X11) + surface = createWindowSurfaceX11(display, config, window); +#endif +#if PLATFORM(WAYLAND) + if (platformDisplay.type() == PlatformDisplay::Type::Wayland) + surface = createWindowSurfaceWayland(display, config, window); +#endif +#else + surface = eglCreateWindowSurface(display, config, static_cast<EGLNativeWindowType>(window), nullptr); +#endif + if (surface == EGL_NO_SURFACE) { + eglDestroyContext(display, context); return nullptr; + } - return adoptPtr(new GLContextEGL(context, surface, WindowSurface)); + return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, surface, WindowSurface)); } -PassOwnPtr<GLContextEGL> GLContextEGL::createPbufferContext(EGLContext sharingContext) +std::unique_ptr<GLContextEGL> GLContextEGL::createPbufferContext(PlatformDisplay& platformDisplay, EGLContext sharingContext) { - EGLDisplay display = sharedEGLDisplay(); - if (display == EGL_NO_DISPLAY) - return nullptr; - + EGLDisplay display = platformDisplay.eglDisplay(); EGLConfig config; - if (!getEGLConfig(&config, PbufferSurface)) + if (!getEGLConfig(display, &config, PbufferSurface)) return nullptr; EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes); @@ -153,78 +143,91 @@ PassOwnPtr<GLContextEGL> GLContextEGL::createPbufferContext(EGLContext sharingCo return nullptr; } - return adoptPtr(new GLContextEGL(context, surface, PbufferSurface)); + return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, surface, PbufferSurface)); } -PassOwnPtr<GLContextEGL> GLContextEGL::createPixmapContext(EGLContext sharingContext) +std::unique_ptr<GLContextEGL> GLContextEGL::createSurfacelessContext(PlatformDisplay& platformDisplay, EGLContext sharingContext) { -#if PLATFORM(X11) - EGLDisplay display = sharedEGLDisplay(); + EGLDisplay display = platformDisplay.eglDisplay(); if (display == EGL_NO_DISPLAY) return nullptr; + const char* extensions = eglQueryString(display, EGL_EXTENSIONS); + if (!GLContext::isExtensionSupported(extensions, "EGL_KHR_surfaceless_context") && !GLContext::isExtensionSupported(extensions, "EGL_KHR_surfaceless_opengl")) + return nullptr; + EGLConfig config; - if (!getEGLConfig(&config, PixmapSurface)) + if (!getEGLConfig(display, &config, Surfaceless)) return nullptr; EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes); if (context == EGL_NO_CONTEXT) return nullptr; - EGLint depth; - if (!eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depth)) - return nullptr; + return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, EGL_NO_SURFACE, Surfaceless)); +} - Pixmap pixmap = XCreatePixmap(sharedX11Display(), DefaultRootWindow(sharedX11Display()), 1, 1, depth); - if (!pixmap) +std::unique_ptr<GLContextEGL> GLContextEGL::createContext(GLNativeWindowType window, PlatformDisplay& platformDisplay) +{ + if (platformDisplay.eglDisplay() == EGL_NO_DISPLAY) return nullptr; - EGLSurface surface = eglCreatePixmapSurface(display, config, pixmap, 0); - - if (surface == EGL_NO_SURFACE) + if (eglBindAPI(gEGLAPIVersion) == EGL_FALSE) return nullptr; - return adoptPtr(new GLContextEGL(context, surface, PixmapSurface)); -#else - return nullptr; + EGLContext eglSharingContext = platformDisplay.sharingGLContext() ? static_cast<GLContextEGL*>(platformDisplay.sharingGLContext())->m_context : EGL_NO_CONTEXT; + auto context = window ? createWindowContext(window, platformDisplay, eglSharingContext) : nullptr; + if (!context) + context = createSurfacelessContext(platformDisplay, eglSharingContext); + if (!context) { +#if PLATFORM(X11) + if (platformDisplay.type() == PlatformDisplay::Type::X11) + context = createPixmapContext(platformDisplay, eglSharingContext); +#endif +#if PLATFORM(WAYLAND) + if (platformDisplay.type() == PlatformDisplay::Type::Wayland) + context = createWaylandContext(platformDisplay, eglSharingContext); #endif + } + if (!context) + context = createPbufferContext(platformDisplay, eglSharingContext); + + return context; } -PassOwnPtr<GLContextEGL> GLContextEGL::createContext(EGLNativeWindowType window, GLContext* sharingContext) +std::unique_ptr<GLContextEGL> GLContextEGL::createSharingContext(PlatformDisplay& platformDisplay) { - if (!sharedEGLDisplay()) + if (platformDisplay.eglDisplay() == EGL_NO_DISPLAY) return nullptr; - static bool initialized = false; - static bool success = true; - if (!initialized) { -#if !USE(OPENGL_ES_2) - success = initializeOpenGLShims(); -#endif - initialized = true; - } - if (!success) + if (eglBindAPI(gEGLAPIVersion) == EGL_FALSE) return nullptr; - EGLContext eglSharingContext = sharingContext ? static_cast<GLContextEGL*>(sharingContext)->m_context : 0; - OwnPtr<GLContextEGL> context = window ? createWindowContext(window, sharingContext) : nullptr; + auto context = createSurfacelessContext(platformDisplay); + if (!context) { +#if PLATFORM(X11) + if (platformDisplay.type() == PlatformDisplay::Type::X11) + context = createPixmapContext(platformDisplay); +#endif +#if PLATFORM(WAYLAND) + if (platformDisplay.type() == PlatformDisplay::Type::Wayland) + context = createWaylandContext(platformDisplay); +#endif + } if (!context) - context = createPixmapContext(eglSharingContext); + context = createPbufferContext(platformDisplay); - if (!context) - context = createPbufferContext(eglSharingContext); - - return context.release(); + return context; } -GLContextEGL::GLContextEGL(EGLContext context, EGLSurface surface, EGLSurfaceType type) - : m_context(context) +GLContextEGL::GLContextEGL(PlatformDisplay& display, EGLContext context, EGLSurface surface, EGLSurfaceType type) + : GLContext(display) + , m_context(context) , m_surface(surface) , m_type(type) -#if USE(CAIRO) - , m_cairoDevice(0) -#endif { + ASSERT(type != PixmapSurface); + ASSERT(type == Surfaceless || surface != EGL_NO_SURFACE); } GLContextEGL::~GLContextEGL() @@ -234,7 +237,7 @@ GLContextEGL::~GLContextEGL() cairo_device_destroy(m_cairoDevice); #endif - EGLDisplay display = sharedEGLDisplay(); + EGLDisplay display = m_display.eglDisplay(); if (m_context) { glBindFramebuffer(GL_FRAMEBUFFER, 0); eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); @@ -243,6 +246,10 @@ GLContextEGL::~GLContextEGL() if (m_surface) eglDestroySurface(display, m_surface); + +#if PLATFORM(WAYLAND) + destroyWaylandWindow(); +#endif } bool GLContextEGL::canRenderToDefaultFramebuffer() @@ -255,9 +262,10 @@ IntSize GLContextEGL::defaultFrameBufferSize() if (!canRenderToDefaultFramebuffer()) return IntSize(); + EGLDisplay display = m_display.eglDisplay(); EGLint width, height; - if (!eglQuerySurface(sharedEGLDisplay(), m_surface, EGL_WIDTH, &width) - || !eglQuerySurface(sharedEGLDisplay(), m_surface, EGL_HEIGHT, &height)) + if (!eglQuerySurface(display, m_surface, EGL_WIDTH, &width) + || !eglQuerySurface(display, m_surface, EGL_HEIGHT, &height)) return IntSize(); return IntSize(width, height); @@ -265,19 +273,19 @@ IntSize GLContextEGL::defaultFrameBufferSize() bool GLContextEGL::makeContextCurrent() { - ASSERT(m_context && m_surface); + ASSERT(m_context); GLContext::makeContextCurrent(); if (eglGetCurrentContext() == m_context) return true; - return eglMakeCurrent(sharedEGLDisplay(), m_surface, m_surface, m_context); + return eglMakeCurrent(m_display.eglDisplay(), m_surface, m_surface, m_context); } void GLContextEGL::swapBuffers() { ASSERT(m_surface); - eglSwapBuffers(sharedEGLDisplay(), m_surface); + eglSwapBuffers(m_display.eglDisplay(), m_surface); } void GLContextEGL::waitNative() @@ -285,6 +293,12 @@ void GLContextEGL::waitNative() eglWaitNative(EGL_CORE_NATIVE_ENGINE); } +void GLContextEGL::swapInterval(int interval) +{ + ASSERT(m_surface); + eglSwapInterval(m_display.eglDisplay(), interval); +} + #if USE(CAIRO) cairo_device_t* GLContextEGL::cairoDevice() { @@ -292,14 +306,14 @@ cairo_device_t* GLContextEGL::cairoDevice() return m_cairoDevice; #if ENABLE(ACCELERATED_2D_CANVAS) - m_cairoDevice = cairo_egl_device_create(sharedEGLDisplay(), m_context); + m_cairoDevice = cairo_egl_device_create(m_display.eglDisplay(), m_context); #endif return m_cairoDevice; } #endif -#if ENABLE(WEBGL) +#if ENABLE(GRAPHICS_CONTEXT_3D) PlatformGraphicsContext3D GLContextEGL::platformContext() { return m_context; |