From 176f30b13739b352cbe453cba7796d9a9c808bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 21 Jun 2011 13:39:26 +0200 Subject: OpenGL API refactor. Rename QGuiGLFormat to QSurfaceFormat, and make QWindow sub-class of QSurface and QPlatformWindow sub-class of QPlatformSurface, instead of having QPlatformGLSurface accessor in QWindow. --- src/plugins/platforms/xcb/qglxintegration.cpp | 24 ++++----- src/plugins/platforms/xcb/qglxintegration.h | 20 +++----- src/plugins/platforms/xcb/qxcbbackingstore.cpp | 2 +- src/plugins/platforms/xcb/qxcbconnection.cpp | 8 +-- src/plugins/platforms/xcb/qxcbeglsurface.h | 68 ++++++++++++++++++++++++++ src/plugins/platforms/xcb/qxcbintegration.cpp | 21 +++++++- src/plugins/platforms/xcb/qxcbintegration.h | 2 +- src/plugins/platforms/xcb/qxcbwindow.cpp | 59 ++++++++++++---------- src/plugins/platforms/xcb/qxcbwindow.h | 22 ++++++--- src/plugins/platforms/xcb/xcb.pro | 1 + 10 files changed, 160 insertions(+), 67 deletions(-) create mode 100644 src/plugins/platforms/xcb/qxcbeglsurface.h (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index a47de88141..38f760ede9 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -59,13 +59,7 @@ #include #endif -QGLXSurface::QGLXSurface(GLXDrawable drawable, const QGuiGLFormat &format) - : QPlatformGLSurface(format) - , glxDrawable(drawable) -{ -} - -QGLXContext::QGLXContext(QXcbScreen *screen, const QGuiGLFormat &format, QPlatformGLContext *share) +QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformGLContext *share) : QPlatformGLContext() , m_screen(screen) , m_context(0) @@ -77,7 +71,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QGuiGLFormat &format, QPlatfo GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen),screen->screenNumber(),format); m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, shareGlxContext, TRUE); - m_format = qglx_guiGLFormatFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context); + m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context); Q_XCB_NOOP(m_screen->connection()); } @@ -88,13 +82,15 @@ QGLXContext::~QGLXContext() Q_XCB_NOOP(m_screen->connection()); } -bool QGLXContext::makeCurrent(const QPlatformGLSurface &surface) +bool QGLXContext::makeCurrent(QPlatformSurface *surface) { + Q_ASSERT(surface); + Q_XCB_NOOP(m_screen->connection()); - GLXDrawable glxSurface = static_cast(surface).glxDrawable; + GLXDrawable glxDrawable = static_cast(surface)->xcb_window(); - bool result = glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), glxSurface, m_context); + bool result = glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), glxDrawable, m_context); Q_XCB_NOOP(m_screen->connection()); return result; @@ -105,10 +101,10 @@ void QGLXContext::doneCurrent() glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0); } -void QGLXContext::swapBuffers(const QPlatformGLSurface &drawable) +void QGLXContext::swapBuffers(QPlatformSurface *surface) { Q_XCB_NOOP(m_screen->connection()); - GLXDrawable glxDrawable = static_cast(drawable).glxDrawable; + GLXDrawable glxDrawable = static_cast(surface)->xcb_window(); glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), glxDrawable); Q_XCB_NOOP(m_screen->connection()); } @@ -147,7 +143,7 @@ void (*QGLXContext::getProcAddress(const QByteArray &procName)) () return (void (*)())glXGetProcAddressARB(reinterpret_cast(procName.constData())); } -QGuiGLFormat QGLXContext::format() const +QSurfaceFormat QGLXContext::format() const { return m_format; } diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h index ae95e23b81..b431a45741 100644 --- a/src/plugins/platforms/xcb/qglxintegration.h +++ b/src/plugins/platforms/xcb/qglxintegration.h @@ -43,40 +43,34 @@ #define QGLXINTEGRATION_H #include "qxcbwindow.h" +#include "qxcbscreen.h" #include -#include +#include #include #include -class QGLXSurface : public QPlatformGLSurface -{ -public: - QGLXSurface(GLXDrawable drawable, const QGuiGLFormat &format); - GLXDrawable glxDrawable; -}; - class QGLXContext : public QPlatformGLContext { public: - QGLXContext(QXcbScreen *xd, const QGuiGLFormat &format, QPlatformGLContext *share); + QGLXContext(QXcbScreen *xd, const QSurfaceFormat &format, QPlatformGLContext *share); ~QGLXContext(); - bool makeCurrent(const QPlatformGLSurface &surface); + bool makeCurrent(QPlatformSurface *surface); void doneCurrent(); - void swapBuffers(const QPlatformGLSurface &surface); + void swapBuffers(QPlatformSurface *surface); void (*getProcAddress(const QByteArray &procName)) (); - QGuiGLFormat format() const; + QSurfaceFormat format() const; GLXContext glxContext() const { return m_context; } private: QXcbScreen *m_screen; GLXContext m_context; - QGuiGLFormat m_format; + QSurfaceFormat m_format; }; #endif diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 24ec65fb47..3def577462 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -260,7 +260,7 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &) QXcbWindow* win = static_cast(window()->handle()); delete m_image; - m_image = new QXcbShmImage(screen, size, win->depth(), win->format()); + m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat()); Q_XCB_NOOP(connection()); m_syncingResize = true; diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index d6460339a2..ac8a900d66 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -39,6 +39,9 @@ ** ****************************************************************************/ +#include +#include + #include "qxcbconnection.h" #include "qxcbkeyboard.h" #include "qxcbscreen.h" @@ -49,11 +52,8 @@ #include #include -#include #include -#include - #include #include #include @@ -108,7 +108,7 @@ QXcbConnection::QXcbConnection(const char *displayName) m_has_egl = eglInitialize(eglDisplay,&major,&minor); #endif //XCB_USE_EGL #else - m_connection = xcb_connect(m_displayName.constData(), &primaryScreen); + m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreen); #endif //XCB_USE_XLIB xcb_prefetch_extension_data (m_connection, &xcb_xfixes_id); diff --git a/src/plugins/platforms/xcb/qxcbeglsurface.h b/src/plugins/platforms/xcb/qxcbeglsurface.h new file mode 100644 index 0000000000..a1e6c148a2 --- /dev/null +++ b/src/plugins/platforms/xcb/qxcbeglsurface.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QXCBEGLSURFACE_H +#define QXCBEGLSURFACE_H + +#include + +class QXcbEGLSurface +{ +public: + QXcbEGLSurface(EGLDisplay display, EGLSurface surface) + : m_display(display) + , m_surface(surface) + { + } + + ~QXcbEGLSurface() + { + eglDestroySurface(m_display, m_surface); + } + + EGLSurface surface() const { return m_surface; } + +private: + EGLDisplay m_display; + EGLSurface m_surface; +}; + +#endif diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 72d0036a3c..d5f7c70ad2 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -66,6 +66,7 @@ #if defined(XCB_USE_GLX) #include "qglxintegration.h" #elif defined(XCB_USE_EGL) +#include "qxcbeglsurface.h" #include #endif @@ -103,12 +104,28 @@ QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const return new QXcbWindow(window); } -QPlatformGLContext *QXcbIntegration::createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const +#if defined(XCB_USE_EGL) +class QEGLXcbPlatformContext : public QEGLPlatformContext +{ +public: + QEGLXcbPlatformContext(const QSurfaceFormat &glFormat, QPlatformGLContext *share, EGLDisplay display) + : QEGLPlatformContext(glFormat, share, display) + { + } + + EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) + { + return static_cast(surface)->eglSurface()->surface(); + } +}; +#endif + +QPlatformGLContext *QXcbIntegration::createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *share) const { #if defined(XCB_USE_GLX) return new QGLXContext(static_cast(m_screens.at(0)), glFormat, share); #elif defined(XCB_USE_EGL) - return new QEGLPlatformContext(glFormat, share, m_connection->egl_display()); + return new QEGLXcbPlatformContext(glFormat, share, m_connection->egl_display()); #elif defined(XCB_USE_DRI2) return new QDri2Context(glFormat, share); #endif diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index 5837be1148..a839b78caa 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -58,7 +58,7 @@ public: bool hasCapability(Capability cap) const; QPixmapData *createPixmapData(QPixmapData::PixelType type) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; - QPlatformGLContext *createPlatformGLContext(const QGuiGLFormat &glFormat, QPlatformGLContext *share) const; + QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *share) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; QList screens() const; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 547a93be0b..f63cbe25e6 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -71,7 +71,7 @@ #include "qglxintegration.h" #include #elif defined(XCB_USE_EGL) -#include +#include "qxcbeglsurface.h" #include #include #endif @@ -98,6 +98,9 @@ QXcbWindow::QXcbWindow(QWindow *window) , m_syncCounter(0) , m_mapped(false) , m_netWmUserTimeWindow(XCB_NONE) +#if defined(XCB_USE_EGL) + , m_eglSurface(0) +#endif { m_screen = static_cast(QGuiApplicationPrivate::platformIntegration()->screens().at(0)); @@ -120,7 +123,7 @@ void QXcbWindow::create() if (type == Qt::Desktop) { m_window = m_screen->root(); m_depth = m_screen->screen()->root_depth; - m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; + m_imageFormat = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; connection()->addWindow(m_window, this); return; } @@ -155,17 +158,18 @@ void QXcbWindow::create() if (parent()) xcb_parent_id = static_cast(parent())->xcb_window(); + m_requestedFormat = window()->format(); + #if defined(XCB_USE_GLX) || defined(XCB_USE_EGL) - if ((window()->surfaceType() == QWindow::OpenGLSurface - && QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) - || window()->glFormat().hasAlpha()) + if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL) + || window()->format().hasAlpha()) { #if defined(XCB_USE_GLX) - XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), window()->glFormat()); + XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), window()->format()); #elif defined(XCB_USE_EGL) EGLDisplay eglDisplay = connection()->egl_display(); - EGLConfig eglConfig = q_configFromGLFormat(eglDisplay, window()->glFormat(), true); + EGLConfig eglConfig = q_configFromGLFormat(eglDisplay, window()->format(), true); VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig); XVisualInfo visualInfoTemplate; @@ -178,7 +182,7 @@ void QXcbWindow::create() #endif //XCB_USE_GLX if (visualInfo) { m_depth = visualInfo->depth; - m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; + m_imageFormat = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), xcb_parent_id, visualInfo->visual, AllocNone); XSetWindowAttributes a; @@ -196,7 +200,7 @@ void QXcbWindow::create() { m_window = xcb_generate_id(xcb_connection()); m_depth = m_screen->screen()->root_depth; - m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; + m_imageFormat = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; Q_XCB_CALL(xcb_create_window(xcb_connection(), XCB_COPY_FROM_PARENT, // depth -- same as root @@ -291,6 +295,11 @@ void QXcbWindow::destroy() Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window)); } m_mapped = false; + +#if defined(XCB_USE_EGL) + delete m_eglSurface; + m_eglSurface = 0; +#endif } void QXcbWindow::setGeometry(const QRect &rect) @@ -1028,28 +1037,26 @@ void QXcbWindow::requestActivateWindow() connection()->sync(); } -QPlatformGLSurface *QXcbWindow::createGLSurface() const +QSurfaceFormat QXcbWindow::format() const { - if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) { - qWarning() << "QXcb::createGLSurface() called without OpenGL support"; - return 0; - } - - QGuiGLFormat format = window()->glFormat(); + // ### return actual format + return m_requestedFormat; +} -#if defined(XCB_USE_GLX) - return new QGLXSurface(m_window, format); -#elif defined(XCB_USE_EGL) - EGLDisplay display = connection()->egl_display(); - EGLConfig config = q_configFromGLFormat(display, format, true); +#if defined(XCB_USE_EGL) +QXcbEGLSurface *QXcbWindow::eglSurface() const +{ + if (!m_eglSurface) { + EGLDisplay display = connection()->egl_display(); + EGLConfig config = q_configFromGLFormat(display, window()->format(), true); + EGLSurface surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)m_window, 0); - EGLSurface eglSurface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)m_window, 0); + m_eglSurface = new QXcbEGLSurface(display, surface); + } - return new QEGLSurface(eglSurface, window()->glFormat()); -#else - return 0; -#endif + return m_eglSurface; } +#endif void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event) { diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 501e9a33c4..89be3b78b2 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -43,7 +43,7 @@ #define QXCBWINDOW_H #include -#include +#include #include #include @@ -52,6 +52,7 @@ #include "qxcbobject.h" class QXcbScreen; +class QXcbEGLSurface; class QXcbWindow : public QXcbObject, public QPlatformWindow { @@ -74,8 +75,6 @@ public: void lower(); void propagateSizeHints(); - QPlatformGLSurface *createGLSurface() const; - void requestActivateWindow(); bool setKeyboardGrabEnabled(bool grab); @@ -83,9 +82,11 @@ public: void setCursor(xcb_cursor_t cursor); + QSurfaceFormat format() const; + xcb_window_t xcb_window() const { return m_window; } uint depth() const { return m_depth; } - QImage::Format format() const { return m_format; } + QImage::Format imageFormat() const { return m_imageFormat; } void handleExposeEvent(const xcb_expose_event_t *event); void handleClientMessageEvent(const xcb_client_message_event_t *event); @@ -107,6 +108,10 @@ public: void updateNetWmUserTime(xcb_timestamp_t timestamp); void netWmUserTime() const; +#if defined(XCB_USE_EGL) + QXcbEGLSurface *eglSurface() const; +#endif + private: void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0); QVector getNetWmState(); @@ -119,7 +124,6 @@ private: void updateMotifWmHintsBeforeMap(); void updateNetWmStateBeforeMap(); - void create(); void destroy(); @@ -131,7 +135,7 @@ private: xcb_window_t m_window; uint m_depth; - QImage::Format m_format; + QImage::Format m_imageFormat; xcb_sync_int64_t m_syncValue; xcb_sync_counter_t m_syncCounter; @@ -142,8 +146,14 @@ private: bool m_mapped; xcb_window_t m_netWmUserTimeWindow; + QSurfaceFormat m_requestedFormat; + mutable bool m_dirtyFrameMargins; mutable QMargins m_frameMargins; + +#if defined(XCB_USE_EGL) + mutable QXcbEGLSurface *m_eglSurface; +#endif }; #endif diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro index 8cf7ec4aff..33a7494133 100644 --- a/src/plugins/platforms/xcb/xcb.pro +++ b/src/plugins/platforms/xcb/xcb.pro @@ -67,6 +67,7 @@ contains(QT_CONFIG, opengl) { contains(QT_CONFIG, opengles2) { DEFINES += XCB_USE_EGL LIBS += -lEGL + HEADERS += qxcbeglsurface.h } else { DEFINES += XCB_USE_GLX HEADERS += qglxintegration.h -- cgit v1.2.3