std::unique_ptr<GLContextEGL> GLContextEGL::createWindowContext(GLNativeWindowType window, PlatformDisplay& platformDisplay, EGLContext sharingContext) { EGLDisplay display = platformDisplay.eglDisplay(); EGLConfig config; if (!getEGLConfig(display, &config, WindowSurface)) return nullptr; EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes); if (context == EGL_NO_CONTEXT) return nullptr; 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 std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, surface, WindowSurface)); }
std::unique_ptr<GLContextEGL> GLContextEGL::createContext(GLNativeWindowType window, PlatformDisplay& platformDisplay) { if (platformDisplay.eglDisplay() == EGL_NO_DISPLAY) return nullptr; if (eglBindAPI(gEGLAPIVersion) == EGL_FALSE) 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; }
std::unique_ptr<GLContextEGL> GLContextEGL::createWaylandContext(PlatformDisplay& platformDisplay, EGLContext sharingContext) { EGLDisplay display = platformDisplay.eglDisplay(); EGLConfig config; if (!getEGLConfig(display, &config, WindowSurface)) return nullptr; EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes); if (context == EGL_NO_CONTEXT) return nullptr; WlUniquePtr<struct wl_surface> wlSurface(downcast<PlatformDisplayWayland>(platformDisplay).createSurface()); if (!wlSurface) { eglDestroyContext(display, context); return nullptr; } EGLNativeWindowType window = wl_egl_window_create(wlSurface.get(), 1, 1); EGLSurface surface = eglCreateWindowSurface(display, config, window, 0); if (surface == EGL_NO_SURFACE) { eglDestroyContext(display, context); wl_egl_window_destroy(window); return nullptr; } return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, surface, WTFMove(wlSurface), window)); }
std::unique_ptr<GLContextEGL> GLContextEGL::createPixmapContext(PlatformDisplay& platformDisplay, EGLContext sharingContext) { EGLDisplay display = platformDisplay.eglDisplay(); EGLConfig config; if (!getEGLConfig(display, &config, PixmapSurface)) 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)) { eglDestroyContext(display, context); return nullptr; } Display* x11Display = downcast<PlatformDisplayX11>(platformDisplay).native(); XUniquePixmap pixmap = XCreatePixmap(x11Display, DefaultRootWindow(x11Display), 1, 1, depth); if (!pixmap) { eglDestroyContext(display, context); return nullptr; } EGLSurface surface = eglCreatePixmapSurface(display, config, reinterpret_cast<EGLNativePixmapType>(pixmap.get()), 0); if (surface == EGL_NO_SURFACE) { eglDestroyContext(display, context); return nullptr; } return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, surface, WTFMove(pixmap))); }
std::unique_ptr<GLContextGLX> GLContextGLX::createContext(XID window, PlatformDisplay& platformDisplay) { GLXContext glxSharingContext = platformDisplay.sharingGLContext() ? static_cast<GLContextGLX*>(platformDisplay.sharingGLContext())->m_context.get() : nullptr; auto context = window ? createWindowContext(window, platformDisplay, glxSharingContext) : nullptr; if (!context) context = createPbufferContext(platformDisplay, glxSharingContext); if (!context) context = createPixmapContext(platformDisplay, glxSharingContext); return context; }
std::unique_ptr<GLContextEGL> GLContextEGL::createSharingContext(PlatformDisplay& platformDisplay) { if (platformDisplay.eglDisplay() == EGL_NO_DISPLAY) return nullptr; if (eglBindAPI(gEGLAPIVersion) == EGL_FALSE) return 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 = createPbufferContext(platformDisplay); return context; }
std::unique_ptr<GLContextEGL> GLContextEGL::createWindowContext(EGLNativeWindowType window, PlatformDisplay& platformDisplay, EGLContext sharingContext) { EGLDisplay display = platformDisplay.eglDisplay(); EGLConfig config; if (!getEGLConfig(display, &config, WindowSurface)) return nullptr; 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) { eglDestroyContext(display, context); return nullptr; } return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, surface, WindowSurface)); }
std::unique_ptr<GLContext> GLContext::createSharingContext(PlatformDisplay& display) { if (!initializeOpenGLShimsIfNeeded()) return nullptr; #if USE(GLX) if (display.type() == PlatformDisplay::Type::X11) { if (auto glxContext = GLContextGLX::createSharingContext(display)) return WTFMove(glxContext); } #endif #if USE(EGL) || PLATFORM(WAYLAND) if (auto eglContext = GLContextEGL::createSharingContext(display)) return WTFMove(eglContext); #endif return nullptr; }
std::unique_ptr<GLContextEGL> GLContextEGL::createSurfacelessContext(PlatformDisplay& platformDisplay, EGLContext sharingContext) { 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(display, &config, Surfaceless)) return nullptr; EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes); if (context == EGL_NO_CONTEXT) return nullptr; return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, EGL_NO_SURFACE, Surfaceless)); }
std::unique_ptr<GLContextEGL> GLContextEGL::createPbufferContext(PlatformDisplay& platformDisplay, EGLContext sharingContext) { EGLDisplay display = platformDisplay.eglDisplay(); EGLConfig config; if (!getEGLConfig(display, &config, PbufferSurface)) return nullptr; EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes); if (context == EGL_NO_CONTEXT) return nullptr; static const int pbufferAttributes[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; EGLSurface surface = eglCreatePbufferSurface(display, config, pbufferAttributes); if (surface == EGL_NO_SURFACE) { eglDestroyContext(display, context); return nullptr; } return std::unique_ptr<GLContextEGL>(new GLContextEGL(platformDisplay, context, surface, PbufferSurface)); }