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::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)); }
PassOwnPtr<GLContextEGL> GLContextEGL::createPixmapContext(EGLContext sharingContext) { #if PLATFORM(X11) EGLDisplay display = sharedEGLDisplay(); if (display == EGL_NO_DISPLAY) return nullptr; EGLConfig config; if (!getEGLConfig(&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)) return nullptr; Pixmap pixmap = XCreatePixmap(sharedX11Display(), DefaultRootWindow(sharedX11Display()), 1, 1, depth); if (!pixmap) return nullptr; EGLSurface surface = eglCreatePixmapSurface(display, config, pixmap, 0); if (surface == EGL_NO_SURFACE) return nullptr; return adoptPtr(new GLContextEGL(context, surface, PixmapSurface)); #else return nullptr; #endif }
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))); }
PassOwnPtr<GLContextEGL> GLContextEGL::createPbufferContext(EGLContext sharingContext) { #if !PLATFORM(JS) EGLDisplay display = sharedEGLDisplay(); if (display == EGL_NO_DISPLAY) return nullptr; EGLConfig config; if (!getEGLConfig(&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 adoptPtr(new GLContextEGL(context, surface, PbufferSurface)); #else return nullptr; #endif }
SurfaceGL2D::SurfaceGL2D(QPainter* painter) { m_qpainter = painter; eglBindAPI(EGL_OPENGL_ES_API); ASSERT_EGL_NO_ERROR(); m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(m_eglDisplay, 0, 0); ASSERT_EGL_NO_ERROR(); getEGLConfig(&m_eglConfig, PbufferSurface); const EGLint attribList[] = { EGL_WIDTH, m_qpainter->device()->width(), EGL_HEIGHT, m_qpainter->device()->height(), EGL_NONE }; ASSERT_EGL_NO_ERROR(); m_eglSurface = eglCreatePbufferSurface(m_eglDisplay, m_eglConfig, attribList); ASSERT_EGL_NO_ERROR(); }
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)); }
bool CWinSystemX11::IsSuitableVisual(XVisualInfo *vInfo) { #if defined(HAS_GLX) int value; if (glXGetConfig(m_dpy, vInfo, GLX_RGBA, &value) || !value) return false; if (glXGetConfig(m_dpy, vInfo, GLX_DOUBLEBUFFER, &value) || !value) return false; if (glXGetConfig(m_dpy, vInfo, GLX_RED_SIZE, &value) || value < 8) return false; if (glXGetConfig(m_dpy, vInfo, GLX_GREEN_SIZE, &value) || value < 8) return false; if (glXGetConfig(m_dpy, vInfo, GLX_BLUE_SIZE, &value) || value < 8) return false; if (glXGetConfig(m_dpy, vInfo, GLX_ALPHA_SIZE, &value) || value < 8) return false; if (glXGetConfig(m_dpy, vInfo, GLX_DEPTH_SIZE, &value) || value < 8) return false; #endif #if defined(HAS_EGL) EGLConfig config = getEGLConfig(m_eglDisplay, vInfo); if (config == EGL_NO_CONFIG) { CLog::Log(LOGERROR, "Failed to determine egl config for visual info"); return false; } EGLint value; if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_RED_SIZE, &value) || value < 8) return false; if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_GREEN_SIZE, &value) || value < 8) return false; if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_BLUE_SIZE, &value) || value < 8) return false; if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_ALPHA_SIZE, &value) || value < 8) return false; if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_DEPTH_SIZE, &value) || value < 24) return false; #endif return true; }
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)); }
PassOwnPtr<GLContextEGL> GLContextEGL::createWindowContext(EGLNativeWindowType window, GLContext* sharingContext) { EGLContext eglSharingContext = sharingContext ? static_cast<GLContextEGL*>(sharingContext)->m_context : 0; EGLDisplay display = sharedEGLDisplay(); if (display == EGL_NO_DISPLAY) return nullptr; EGLConfig config; if (!getEGLConfig(&config, WindowSurface)) return nullptr; EGLContext context = eglCreateContext(display, config, eglSharingContext, gContextAttributes); if (context == EGL_NO_CONTEXT) return nullptr; EGLSurface surface = eglCreateWindowSurface(display, config, window, 0); if (surface == EGL_NO_SURFACE) return nullptr; return adoptPtr(new GLContextEGL(context, surface, WindowSurface)); }
bool CGLContextEGL::IsSuitableVisual(XVisualInfo *vInfo) { EGLConfig config = getEGLConfig(m_eglDisplay, vInfo); if (config == EGL_NO_CONFIG) { CLog::Log(LOGERROR, "Failed to determine egl config for visual info"); return false; } EGLint value; if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_RED_SIZE, &value) || value < 8) return false; if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_GREEN_SIZE, &value) || value < 8) return false; if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_BLUE_SIZE, &value) || value < 8) return false; if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_ALPHA_SIZE, &value) || value < 8) return false; if (!eglGetConfigAttrib(m_eglDisplay, config, EGL_DEPTH_SIZE, &value) || value < 24) return false; return true; }
bool CGLContextEGL::Refresh(bool force, int screen, Window glWindow, bool &newContext) { // refresh context if (m_eglContext && !force) { if (m_eglSurface == EGL_NO_SURFACE) { m_eglSurface = eglCreateWindowSurface(m_eglDisplay, m_eglConfig, glWindow, NULL); if (m_eglSurface == EGL_NO_SURFACE) { CLog::Log(LOGERROR, "failed to create EGL window surface %d\n", eglGetError()); return false; } } CLog::Log(LOGDEBUG, "CWinSystemX11::RefreshEGLContext: refreshing context"); eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext); return true; } // create context bool retVal = false; if (m_eglDisplay == EGL_NO_DISPLAY) { m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)m_dpy); if (m_eglDisplay == EGL_NO_DISPLAY) { CLog::Log(LOGERROR, "failed to get egl display\n"); return false; } if (!eglInitialize(m_eglDisplay, NULL, NULL)) { CLog::Log(LOGERROR, "failed to initialize egl display\n"); return false; } } XVisualInfo vMask; XVisualInfo *visuals; XVisualInfo *vInfo = NULL; int availableVisuals = 0; vMask.screen = screen; XWindowAttributes winAttr; /* Assume a depth of 24 in case the below calls to XGetWindowAttributes() or XGetVisualInfo() fail. That shouldn't happen unless something is fatally wrong, but lets prepare for everything. */ vMask.depth = 24; if (XGetWindowAttributes(m_dpy, glWindow, &winAttr)) { vMask.visualid = XVisualIDFromVisual(winAttr.visual); vInfo = XGetVisualInfo(m_dpy, VisualScreenMask | VisualIDMask, &vMask, &availableVisuals); if (!vInfo) CLog::Log(LOGWARNING, "Failed to get VisualInfo of visual 0x%x", (unsigned) vMask.visualid); else if(!IsSuitableVisual(vInfo)) { CLog::Log(LOGWARNING, "Visual 0x%x of the window is not suitable, looking for another one...", (unsigned) vInfo->visualid); vMask.depth = vInfo->depth; XFree(vInfo); vInfo = NULL; } } else CLog::Log(LOGWARNING, "Failed to get window attributes"); /* As per glXMakeCurrent documentation, we have to use the same visual as m_glWindow. Since that was not suitable for use, we try to use another one with the same depth and hope that the used implementation is less strict than the documentation. */ if (!vInfo) { visuals = XGetVisualInfo(m_dpy, VisualScreenMask | VisualDepthMask, &vMask, &availableVisuals); for (int i = 0; i < availableVisuals; i++) { if (IsSuitableVisual(&visuals[i])) { vMask.visualid = visuals[i].visualid; vInfo = XGetVisualInfo(m_dpy, VisualScreenMask | VisualIDMask, &vMask, &availableVisuals); break; } } XFree(visuals); } if (vInfo) { CLog::Log(LOGNOTICE, "Using visual 0x%x", (unsigned) vInfo->visualid); if (m_eglContext) { eglMakeCurrent(m_eglContext, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(m_eglDisplay, m_eglContext); m_eglContext = EGL_NO_CONTEXT; if (m_eglSurface) { eglDestroySurface(m_eglDisplay, m_eglSurface); m_eglSurface = EGL_NO_SURFACE; } eglTerminate(m_eglDisplay); m_eglDisplay = EGL_NO_DISPLAY; XSync(m_dpy, FALSE); newContext = true; } m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)m_dpy); if (m_eglDisplay == EGL_NO_DISPLAY) { CLog::Log(LOGERROR, "failed to get egl display"); return false; } if (!eglInitialize(m_eglDisplay, NULL, NULL)) { CLog::Log(LOGERROR, "failed to initialize egl\n"); return false; } #if defined (HAS_GL) if (!eglBindAPI(EGL_OPENGL_API)) { CLog::Log(LOGERROR, "failed to initialize egl"); XFree(vInfo); return false; } #endif if(m_eglConfig == EGL_NO_CONFIG) { m_eglConfig = getEGLConfig(m_eglDisplay, vInfo); } if (m_eglConfig == EGL_NO_CONFIG) { CLog::Log(LOGERROR, "failed to get eglconfig for visual id"); XFree(vInfo); return false; } if (m_eglSurface == EGL_NO_SURFACE) { m_eglSurface = eglCreateWindowSurface(m_eglDisplay, m_eglConfig, glWindow, NULL); if (m_eglSurface == EGL_NO_SURFACE) { CLog::Log(LOGERROR, "failed to create EGL window surface %d", eglGetError()); XFree(vInfo); return false; } } EGLint contextAttributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttributes); if (m_eglContext == EGL_NO_CONTEXT) { CLog::Log(LOGERROR, "failed to create EGL context\n"); return false; } if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext)) { CLog::Log(LOGERROR, "Failed to make context current %p %p %p\n", m_eglDisplay, m_eglSurface, m_eglContext); return false; } XFree(vInfo); retVal = true; } else { CLog::Log(LOGERROR, "EGL Error: vInfo is NULL!"); } return retVal; }