void AbstractEglBackend::cleanup() { #if HAVE_WAYLAND if (eglUnbindWaylandDisplayWL && eglDisplay() != EGL_NO_DISPLAY) { eglUnbindWaylandDisplayWL(eglDisplay(), *(WaylandServer::self()->display())); } #endif cleanupGL(); doneCurrent(); eglDestroyContext(m_display, m_context); cleanupSurfaces(); eglTerminate(m_display); eglReleaseThread(); }
bool EglHwcomposerBackend::initBufferConfigs() { const EGLint config_attribs[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE, }; EGLint count; EGLConfig configs[1024]; if (eglChooseConfig(eglDisplay(), config_attribs, configs, 1, &count) == EGL_FALSE) { qCCritical(KWIN_HWCOMPOSER) << "choose config failed"; return false; } if (count != 1) { qCCritical(KWIN_HWCOMPOSER) << "choose config did not return a config" << count; return false; } setConfig(configs[0]); return true; }
void EglHwcomposerBackend::present() { if (lastDamage().isEmpty()) { return; } eglSwapBuffers(eglDisplay(), surface()); setLastDamage(QRegion()); }
void EglFSWaylandContext::swapBuffers(QPlatformSurface *surface) { EglFSWaylandWindow *window = static_cast<EglFSWaylandWindow *>(surface); EGLSurface eglSurface = window->surface(); makeCurrent(surface); StateGuard stateGuard; if (!m_blitter) m_blitter = new EglFSWaylandBlitter(this); m_blitter->blit(window); eglSwapInterval(eglDisplay(), format().swapInterval()); eglSwapBuffers(eglDisplay(), eglSurface); //window.setCanResize(true); }
QPlatformOpenGLContext *QXcbEglIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle()); QXcbEglContext *platformContext = new QXcbEglContext(screen->surfaceFormatFor(context->format()), context->shareHandle(), eglDisplay(), context->nativeHandle()); context->setNativeHandle(platformContext->nativeHandle()); return platformContext; }
void AbstractEglBackend::initWayland() { #if HAVE_WAYLAND if (!WaylandServer::self()) { return; } if (hasGLExtension(QByteArrayLiteral("EGL_WL_bind_wayland_display"))) { eglBindWaylandDisplayWL = (eglBindWaylandDisplayWL_func)eglGetProcAddress("eglBindWaylandDisplayWL"); eglUnbindWaylandDisplayWL = (eglUnbindWaylandDisplayWL_func)eglGetProcAddress("eglUnbindWaylandDisplayWL"); eglQueryWaylandBufferWL = (eglQueryWaylandBufferWL_func)eglGetProcAddress("eglQueryWaylandBufferWL"); if (!eglBindWaylandDisplayWL(eglDisplay(), *(WaylandServer::self()->display()))) { eglUnbindWaylandDisplayWL = nullptr; eglQueryWaylandBufferWL = nullptr; } else { waylandServer()->display()->setEglDisplay(eglDisplay()); } } #endif }
bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface) { bool ok = false; QWindowsWindow *window = static_cast<QWindowsWindow *>(surface); if (EGLSurface eglSurface = window->ensureEglSurfaceHandle(m_staticContext, eglConfig())) { ok = eglMakeCurrent(eglDisplay(), eglSurface, eglSurface, eglContext()); if (!ok) qWarning("%s: eglMakeCurrent() failed, eglError: 0x%x, this: %p \n", Q_FUNC_INFO, eglGetError(), this); } return ok; }
bool EglHwcomposerBackend::makeContextCurrent() { if (eglMakeCurrent(eglDisplay(), surface(), surface(), context()) == EGL_FALSE) { qCCritical(KWIN_HWCOMPOSER) << "Make Context Current failed"; return false; } EGLint error = eglGetError(); if (error != EGL_SUCCESS) { qCWarning(KWIN_HWCOMPOSER) << "Error occurred while creating context " << error; return false; } return true; }
bool SharingPlatformContext::makeCurrent(QPlatformSurface *surface) { Window *window = static_cast<Window*>(surface); if (eglMakeCurrent(eglDisplay(), m_surface, m_surface, context())) { window->bindContentFBO(); return true; } qCWarning(KWIN_QPA) << "Failed to make context current"; EGLint error = eglGetError(); if (error != EGL_SUCCESS) { qCWarning(KWIN_QPA) << "EGL error code: " << error; } return false; }
bool QEglFSContext::makeCurrent(QPlatformSurface *surface) { bool current = QEGLPlatformContext::makeCurrent(surface); if (current && !m_swapIntervalConfigured) { m_swapIntervalConfigured = true; int swapInterval = 1; QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL"); if (!swapIntervalString.isEmpty()) { bool ok; swapInterval = swapIntervalString.toInt(&ok); if (!ok) swapInterval = 1; } eglSwapInterval(eglDisplay(), swapInterval); } return current; }
bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface) { Q_ASSERT(surface->surface()->supportsOpenGL()); eglBindAPI(m_api); EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface); if (eglSurface == EGL_NO_SURFACE) return false; // shortcut: on some GPUs, eglMakeCurrent is not a cheap operation if (eglGetCurrentContext() == m_eglContext && eglGetCurrentDisplay() == m_eglDisplay && eglGetCurrentSurface(EGL_READ) == eglSurface && eglGetCurrentSurface(EGL_DRAW) == eglSurface) { return true; } const bool ok = eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_eglContext); if (ok) { if (!m_swapIntervalEnvChecked) { m_swapIntervalEnvChecked = true; if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_SWAPINTERVAL")) { QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL"); bool intervalOk; const int swapInterval = swapIntervalString.toInt(&intervalOk); if (intervalOk) m_swapIntervalFromEnv = swapInterval; } } const int requestedSwapInterval = m_swapIntervalFromEnv >= 0 ? m_swapIntervalFromEnv : surface->format().swapInterval(); if (requestedSwapInterval >= 0 && m_swapInterval != requestedSwapInterval) { m_swapInterval = requestedSwapInterval; if (eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context eglSwapInterval(eglDisplay(), m_swapInterval); } } else { qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError()); } return ok; }
bool EglHwcomposerBackend::initRenderingContext() { if (!initBufferConfigs()) { return false; } if (!createContext()) { return false; } m_nativeSurface = m_backend->createSurface(); EGLSurface surface = eglCreateWindowSurface(eglDisplay(), config(), (EGLNativeWindowType)static_cast<ANativeWindow*>(m_nativeSurface), nullptr); if (surface == EGL_NO_SURFACE) { qCCritical(KWIN_HWCOMPOSER) << "Create surface failed"; return false; } setSurface(surface); return makeContextCurrent(); }
QPlatformOffscreenSurface *QXcbEglIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const { QXcbScreen *screen = static_cast<QXcbScreen *>(surface->screen()->handle()); return new QEGLPbuffer(eglDisplay(), screen->surfaceFormatFor(surface->requestedFormat()), surface); }
void AbstractPlatformContext::createContext(EGLContext shareContext) { const QByteArray eglExtensions = eglQueryString(eglDisplay(), EGL_EXTENSIONS); const QList<QByteArray> extensions = eglExtensions.split(' '); const bool haveRobustness = extensions.contains(QByteArrayLiteral("EGL_EXT_create_context_robustness")); const bool haveCreateContext = extensions.contains(QByteArrayLiteral("EGL_KHR_create_context")); EGLContext context = EGL_NO_CONTEXT; if (isOpenGLES()) { if (haveCreateContext && haveRobustness) { const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET_EXT, EGL_NONE }; context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs); } if (context == EGL_NO_CONTEXT) { const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; context = eglCreateContext(eglDisplay(), config(), shareContext, context_attribs); } } else { // Try to create a 3.1 core context if (m_format.majorVersion() >= 3 && haveCreateContext) { if (haveRobustness) { const int attribs[] = { EGL_CONTEXT_MAJOR_VERSION_KHR, m_format.majorVersion(), EGL_CONTEXT_MINOR_VERSION_KHR, m_format.minorVersion(), EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, m_format.profile() == QSurfaceFormat::CoreProfile ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, EGL_NONE }; context = eglCreateContext(eglDisplay(), config(), shareContext, attribs); } if (context == EGL_NO_CONTEXT) { // try without robustness const EGLint attribs[] = { EGL_CONTEXT_MAJOR_VERSION_KHR, m_format.majorVersion(), EGL_CONTEXT_MINOR_VERSION_KHR, m_format.minorVersion(), EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, m_format.profile() == QSurfaceFormat::CoreProfile ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, EGL_NONE }; context = eglCreateContext(eglDisplay(), config(), shareContext, attribs); } } if (context == EGL_NO_CONTEXT && haveRobustness && haveCreateContext) { const int attribs[] = { EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, EGL_LOSE_CONTEXT_ON_RESET_KHR, EGL_NONE }; context = eglCreateContext(eglDisplay(), config(), shareContext, attribs); } if (context == EGL_NO_CONTEXT) { // and last but not least: try without robustness const EGLint attribs[] = { EGL_NONE }; context = eglCreateContext(eglDisplay(), config(), shareContext, attribs); } } if (context == EGL_NO_CONTEXT) { return; } m_context = context; }
EglFSWaylandContext::~EglFSWaylandContext() { delete m_blitter; eglDestroyContext(eglDisplay(), eglContext()); }
QPlatformOffscreenSurface *QXcbEglIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const { return new QEGLPbuffer(eglDisplay(), surface->requestedFormat(), surface); }