예제 #1
0
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();
}
예제 #2
0
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;
}
예제 #3
0
void EglHwcomposerBackend::present()
{
    if (lastDamage().isEmpty()) {
        return;
    }

    eglSwapBuffers(eglDisplay(), surface());
    setLastDamage(QRegion());
}
예제 #4
0
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);
}
예제 #5
0
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;
}
예제 #6
0
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
}
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #12
0
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();
}
예제 #13
0
QPlatformOffscreenSurface *QXcbEglIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
{
    QXcbScreen *screen = static_cast<QXcbScreen *>(surface->screen()->handle());
    return new QEGLPbuffer(eglDisplay(), screen->surfaceFormatFor(surface->requestedFormat()), surface);
}
예제 #14
0
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;
}
예제 #15
0
EglFSWaylandContext::~EglFSWaylandContext()
{
    delete m_blitter;
    eglDestroyContext(eglDisplay(), eglContext());
}
예제 #16
0
QPlatformOffscreenSurface *QXcbEglIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
{
    return new QEGLPbuffer(eglDisplay(), surface->requestedFormat(), surface);
}