From 385d2d14bc7994c3abb1de11dacf9a81eea01d4a Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 27 Apr 2010 15:59:50 +0200 Subject: Add QPlatformGLWidgetSurface to GL integrtation This class is a way to for the GL platform integration to track the movement and resizing of a QGLWidget with respect to the top-level. Most platform implementations will seperate the surface from the context anyway, so this is a natural abstraction. --- src/gui/kernel/qplatformintegration_lite.cpp | 2 +- src/gui/kernel/qplatformintegration_lite.h | 3 +- src/opengl/qgl.h | 9 ++ src/opengl/qgl_lite.cpp | 47 ++++--- src/opengl/qgl_p.h | 4 +- src/opengl/qglplatformintegration_lite.h | 26 ++-- src/plugins/platforms/testlite/qglxglcontext.cpp | 150 --------------------- src/plugins/platforms/testlite/qglxglcontext.h | 73 ---------- src/plugins/platforms/testlite/qglxintegration.cpp | 150 +++++++++++++++++++++ src/plugins/platforms/testlite/qglxintegration.h | 73 ++++++++++ 10 files changed, 283 insertions(+), 254 deletions(-) delete mode 100644 src/plugins/platforms/testlite/qglxglcontext.cpp delete mode 100644 src/plugins/platforms/testlite/qglxglcontext.h create mode 100644 src/plugins/platforms/testlite/qglxintegration.cpp create mode 100644 src/plugins/platforms/testlite/qglxintegration.h diff --git a/src/gui/kernel/qplatformintegration_lite.cpp b/src/gui/kernel/qplatformintegration_lite.cpp index 3fa874c..2d181f1 100644 --- a/src/gui/kernel/qplatformintegration_lite.cpp +++ b/src/gui/kernel/qplatformintegration_lite.cpp @@ -67,7 +67,7 @@ QPlatformGLContext * QPlatformIntegration::createGLContext() return 0; } -QPlatformGLWidgetSurface * QPlatformIntegration::createGLWidgetSurface(QGLWidget*) +QPlatformGLWidgetSurface * QPlatformIntegration::createGLWidgetSurface() { return 0; } diff --git a/src/gui/kernel/qplatformintegration_lite.h b/src/gui/kernel/qplatformintegration_lite.h index 70bd0ce..a509b52 100644 --- a/src/gui/kernel/qplatformintegration_lite.h +++ b/src/gui/kernel/qplatformintegration_lite.h @@ -54,7 +54,6 @@ QT_MODULE(Gui) #ifndef QT_NO_OPENGL class QPlatformGLContext; class QPlatformGLWidgetSurface; -class QGLWidget; #endif class Q_GUI_EXPORT QPlatformIntegration @@ -76,7 +75,7 @@ public: #ifndef QT_NO_OPENGL virtual bool hasOpenGL() const; virtual QPlatformGLContext * createGLContext(); - virtual QPlatformGLWidgetSurface * createGLWidgetSurface(QGLWidget*); + virtual QPlatformGLWidgetSurface * createGLWidgetSurface(); #endif }; diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index b1e2ede..e389e3f 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -128,6 +128,10 @@ class QGLOverlayWidget; class QGLWidgetPrivate; class QGLContextPrivate; +#ifdef Q_WS_LITE +class QPlatformGLWidgetSurface; +#endif + // Namespace class: namespace QGL { @@ -531,6 +535,11 @@ public: void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D); #endif +#ifdef Q_WS_LITE + // Used by the platform context to get at the surface which it created for the glwidget: + QPlatformGLWidgetSurface* platformSurface(); +#endif + public Q_SLOTS: virtual void updateGL(); virtual void updateOverlayGL(); diff --git a/src/opengl/qgl_lite.cpp b/src/opengl/qgl_lite.cpp index 2a70545..fa1439c 100644 --- a/src/opengl/qgl_lite.cpp +++ b/src/opengl/qgl_lite.cpp @@ -60,7 +60,7 @@ QPlatformGLContext::~QPlatformGLContext() { } -QPlatformGLWidgetSurface::QPlatformGLWidgetSurface(QGLWidget*) +QPlatformGLWidgetSurface::QPlatformGLWidgetSurface() { } @@ -149,22 +149,30 @@ void QGLWidget::setContext(QGLContext *context, QGLContext* oldcx = d->glcx; d->glcx = context; - // If the application has set WA_TranslucentBackground and not explicitly set - // the alpha buffer size to zero, modify the format so it have an alpha channel - QGLFormat& fmt = d->glcx->d_func()->glFormat; - if (testAttribute(Qt::WA_TranslucentBackground) && fmt.alphaBufferSize() == -1) - fmt.setAlphaBufferSize(1); + if (!d->wsurf) { + // If the application has set WA_TranslucentBackground and not explicitly set + // the alpha buffer size to zero, modify the format so it have an alpha channel + QGLFormat format = d->glcx->d_func()->glFormat; + if (testAttribute(Qt::WA_TranslucentBackground) && format.alphaBufferSize() == -1) + format.setAlphaBufferSize(1); + + d->wsurf = QApplicationPrivate::platformIntegration()->createGLWidgetSurface(); + d->wsurf->create(this, format); + d->glcx->d_func()->glFormat = format; + } - bool success = false; if (!d->glcx->isValid()) - success = !d->glcx->create(shareContext ? shareContext : oldcx); + d->glcx->create(shareContext ? shareContext : oldcx); if (deleteOldContext) delete oldcx; } - - +QPlatformGLWidgetSurface* QGLWidget::platformSurface() +{ + Q_D(QGLWidget); + return d->wsurf; +} void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget) { @@ -181,7 +189,7 @@ QColor QGLContext::overlayTransparentColor() const return QColor(); // Invalid color } -uint QGLContext::colorIndex(const QColor& c) const +uint QGLContext::colorIndex(const QColor&) const { return 0; } @@ -214,7 +222,7 @@ QGLTemporaryContext::~QGLTemporaryContext() } -bool QGLWidgetPrivate::renderCxPm(QPixmap* pm) +bool QGLWidgetPrivate::renderCxPm(QPixmap*) { return false; } @@ -234,7 +242,7 @@ void QGLWidget::setMouseTracking(bool enable) bool QGLWidget::event(QEvent *e) { - QWidget::event(e); + return QWidget::event(e); } void QGLWidget::resizeEvent(QResizeEvent *) @@ -242,10 +250,17 @@ void QGLWidget::resizeEvent(QResizeEvent *) Q_D(QGLWidget); if (!isValid()) return; + + if (!d->wsurf) { + qWarning("QGLWidget::resizeEvent() - widget does not have a platform surface"); + return; + } + d->wsurf->setGeometry(geometry()); //### What about moveEvent? + makeCurrent(); -// if (!d->glcx->initialized()) -// glInit(); -// resizeGL(width(), height()); + if (!d->glcx->initialized()) + glInit(); + resizeGL(width(), height()); } diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index c7cd3fe..34cbdfc 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -165,7 +165,7 @@ class QGLWidgetPrivate : public QWidgetPrivate public: QGLWidgetPrivate() : QWidgetPrivate() , disable_clear_on_painter_begin(false) -#ifdef Q_WS_QWS +#if defined(Q_WS_QWS) || defined(Q_WS_LITE) , wsurf(0) #endif #if defined(Q_WS_X11) && !defined(QT_NO_EGL) @@ -207,6 +207,8 @@ public: void updatePaintDevice(); #elif defined(Q_WS_QWS) QWSGLWindowSurface *wsurf; +#elif defined (Q_WS_LITE) + QPlatformGLWidgetSurface* wsurf; #endif }; diff --git a/src/opengl/qglplatformintegration_lite.h b/src/opengl/qglplatformintegration_lite.h index d5bae45..94d4da0 100644 --- a/src/opengl/qglplatformintegration_lite.h +++ b/src/opengl/qglplatformintegration_lite.h @@ -48,13 +48,27 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +// QGLPlatformWidgetSurface does _not_ inherit from QWindowSurface +// - The backing store may be totally unaware of it's existance. +class Q_OPENGL_EXPORT QPlatformGLWidgetSurface +{ +public: + QPlatformGLWidgetSurface(); + virtual ~QPlatformGLWidgetSurface(); + + virtual bool create(QGLWidget*, QGLFormat&) = 0; + + virtual void setGeometry(const QRect&) = 0; +}; + + class Q_OPENGL_EXPORT QPlatformGLContext { public: QPlatformGLContext(); virtual ~QPlatformGLContext(); - virtual bool create(QPaintDevice* device, const QGLFormat& format, QPlatformGLContext* shareContext) = 0; + virtual bool create(QPaintDevice* device, QGLFormat& format, QPlatformGLContext* shareContext) = 0; virtual void makeCurrent() = 0; virtual void doneCurrent() = 0; @@ -63,16 +77,6 @@ public: }; -// QGLPlatformWidgetSurface does _not_ inherit from QWindowSurface -// - The backing store may be totally unaware of it's existance. -class QPlatformGLWidgetSurface -{ -public: - QPlatformGLWidgetSurface(QGLWidget*); - virtual ~QPlatformGLWidgetSurface(); - - virtual void setGeometry(const QRect&) = 0; -}; QT_END_NAMESPACE diff --git a/src/plugins/platforms/testlite/qglxglcontext.cpp b/src/plugins/platforms/testlite/qglxglcontext.cpp deleted file mode 100644 index 6fdbb56..0000000 --- a/src/plugins/platforms/testlite/qglxglcontext.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 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$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "x11util.h" -#include "qglxglcontext.h" -#include - -#include - -#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) -#include -#endif - - -QT_BEGIN_NAMESPACE - -QGLXGLContext::QGLXGLContext(Display *xdpy) - : QPlatformGLContext() - , m_display(xdpy) - , m_context(0) - , m_widget(0) -{ -} - -QGLXGLContext::~QGLXGLContext() -{ - if (m_context) { - qDebug("Destroying GLX context 0x%x", m_context); - glXDestroyContext(m_display, m_context); - } -} - -bool QGLXGLContext::create(QPaintDevice* device, const QGLFormat& format, QPlatformGLContext* shareContext) -{ - if (device->devType() != QInternal::Widget) { - qWarning("Creating a GL context is only supported on QWidgets"); - return false; - } - - m_widget = static_cast(device); - if (!m_widget->isTopLevel()) { - qWarning("Creating a GL context is only supported on top-level QWidgets"); - return false; - } - - // Get the XVisualInfo for the window: -// XWindowAttributes windowAttribs; -// XGetWindowAttributes(m_display, m_widget->winId(), &windowAttribs); - XVisualInfo visualInfoTemplate; - visualInfoTemplate.visualid = 33; //XVisualIDFromVisual(windowAttribs.visual); - XVisualInfo *visualInfo; - int matchingCount = 0; - visualInfo = XGetVisualInfo(m_display, VisualIDMask, &visualInfoTemplate, &matchingCount); - - m_context = glXCreateContext(m_display, visualInfo, 0, True); - - qDebug("Created GLX context 0x%x for visual ID %d", m_context, visualInfoTemplate.visualid); - - return true; -} - -void QGLXGLContext::makeCurrent() -{ - Window win = m_widget->winId(); - qDebug("QGLXGLContext::makeCurrent(window=0x%x, ctx=0x%x)", win, m_context); - - glXMakeCurrent(m_display, win, m_context); -} - -void QGLXGLContext::doneCurrent() -{ - glXMakeCurrent(m_display, 0, 0); -} - -void QGLXGLContext::swapBuffers() -{ - glXSwapBuffers(m_display, m_widget->winId()); -} - -void* QGLXGLContext::getProcAddress(const QString& procName) -{ - typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *); - static qt_glXGetProcAddressARB glXGetProcAddressARB = 0; - static bool resolved = false; - - if (resolved && !glXGetProcAddressARB) - return 0; - if (!glXGetProcAddressARB) { - QList glxExt = QByteArray(glXGetClientString(m_display, GLX_EXTENSIONS)).split(' '); - if (glxExt.contains("GLX_ARB_get_proc_address")) { -#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) - void *handle = dlopen(NULL, RTLD_LAZY); - if (handle) { - glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB"); - dlclose(handle); - } - if (!glXGetProcAddressARB) -#endif - { - extern const QString qt_gl_library_name(); - QLibrary lib(qt_gl_library_name()); - glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB"); - } - } - resolved = true; - } - if (!glXGetProcAddressARB) - return 0; - return glXGetProcAddressARB(reinterpret_cast(procName.toLatin1().data())); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/testlite/qglxglcontext.h b/src/plugins/platforms/testlite/qglxglcontext.h deleted file mode 100644 index ff8fe85..0000000 --- a/src/plugins/platforms/testlite/qglxglcontext.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 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$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef Q_GLX_CONTEXT_H -#define Q_GLX_CONTEXT_H - -#include -#include "x11util.h" -#include - -QT_BEGIN_NAMESPACE - -class QGLXGLContext : public QPlatformGLContext -{ -public: - QGLXGLContext(Display* xdpy); - ~QGLXGLContext(); - - bool create(QPaintDevice* device, const QGLFormat& format, QPlatformGLContext* shareContext); - - void makeCurrent(); - void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString& procName); - -private: - Display *m_display; - GLXContext m_context; - QWidget *m_widget; -}; - - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/platforms/testlite/qglxintegration.cpp b/src/plugins/platforms/testlite/qglxintegration.cpp new file mode 100644 index 0000000..6fdbb56 --- /dev/null +++ b/src/plugins/platforms/testlite/qglxintegration.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2009 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "x11util.h" +#include "qglxglcontext.h" +#include + +#include + +#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) +#include +#endif + + +QT_BEGIN_NAMESPACE + +QGLXGLContext::QGLXGLContext(Display *xdpy) + : QPlatformGLContext() + , m_display(xdpy) + , m_context(0) + , m_widget(0) +{ +} + +QGLXGLContext::~QGLXGLContext() +{ + if (m_context) { + qDebug("Destroying GLX context 0x%x", m_context); + glXDestroyContext(m_display, m_context); + } +} + +bool QGLXGLContext::create(QPaintDevice* device, const QGLFormat& format, QPlatformGLContext* shareContext) +{ + if (device->devType() != QInternal::Widget) { + qWarning("Creating a GL context is only supported on QWidgets"); + return false; + } + + m_widget = static_cast(device); + if (!m_widget->isTopLevel()) { + qWarning("Creating a GL context is only supported on top-level QWidgets"); + return false; + } + + // Get the XVisualInfo for the window: +// XWindowAttributes windowAttribs; +// XGetWindowAttributes(m_display, m_widget->winId(), &windowAttribs); + XVisualInfo visualInfoTemplate; + visualInfoTemplate.visualid = 33; //XVisualIDFromVisual(windowAttribs.visual); + XVisualInfo *visualInfo; + int matchingCount = 0; + visualInfo = XGetVisualInfo(m_display, VisualIDMask, &visualInfoTemplate, &matchingCount); + + m_context = glXCreateContext(m_display, visualInfo, 0, True); + + qDebug("Created GLX context 0x%x for visual ID %d", m_context, visualInfoTemplate.visualid); + + return true; +} + +void QGLXGLContext::makeCurrent() +{ + Window win = m_widget->winId(); + qDebug("QGLXGLContext::makeCurrent(window=0x%x, ctx=0x%x)", win, m_context); + + glXMakeCurrent(m_display, win, m_context); +} + +void QGLXGLContext::doneCurrent() +{ + glXMakeCurrent(m_display, 0, 0); +} + +void QGLXGLContext::swapBuffers() +{ + glXSwapBuffers(m_display, m_widget->winId()); +} + +void* QGLXGLContext::getProcAddress(const QString& procName) +{ + typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *); + static qt_glXGetProcAddressARB glXGetProcAddressARB = 0; + static bool resolved = false; + + if (resolved && !glXGetProcAddressARB) + return 0; + if (!glXGetProcAddressARB) { + QList glxExt = QByteArray(glXGetClientString(m_display, GLX_EXTENSIONS)).split(' '); + if (glxExt.contains("GLX_ARB_get_proc_address")) { +#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) + void *handle = dlopen(NULL, RTLD_LAZY); + if (handle) { + glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB"); + dlclose(handle); + } + if (!glXGetProcAddressARB) +#endif + { + extern const QString qt_gl_library_name(); + QLibrary lib(qt_gl_library_name()); + glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB"); + } + } + resolved = true; + } + if (!glXGetProcAddressARB) + return 0; + return glXGetProcAddressARB(reinterpret_cast(procName.toLatin1().data())); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/testlite/qglxintegration.h b/src/plugins/platforms/testlite/qglxintegration.h new file mode 100644 index 0000000..ff8fe85 --- /dev/null +++ b/src/plugins/platforms/testlite/qglxintegration.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2009 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$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q_GLX_CONTEXT_H +#define Q_GLX_CONTEXT_H + +#include +#include "x11util.h" +#include + +QT_BEGIN_NAMESPACE + +class QGLXGLContext : public QPlatformGLContext +{ +public: + QGLXGLContext(Display* xdpy); + ~QGLXGLContext(); + + bool create(QPaintDevice* device, const QGLFormat& format, QPlatformGLContext* shareContext); + + void makeCurrent(); + void doneCurrent(); + void swapBuffers(); + void* getProcAddress(const QString& procName); + +private: + Display *m_display; + GLXContext m_context; + QWidget *m_widget; +}; + + +QT_END_NAMESPACE + +#endif -- cgit v0.12