From 768f59202df49290c45a595b7159adce7a5ec8f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 12 May 2014 15:19:49 +0200 Subject: qpa: Merge qgl_qpa.cpp into qgl.cpp Change-Id: I91cfd7daf7f1dd88659019ccc671ec0d9245067f Reviewed-by: Paul Olav Tvete --- src/opengl/opengl.pro | 2 - src/opengl/qgl.cpp | 399 ++++++++++++++++++++++++++++++++++++++++-- src/opengl/qgl_qpa.cpp | 464 ------------------------------------------------- 3 files changed, 388 insertions(+), 477 deletions(-) delete mode 100644 src/opengl/qgl_qpa.cpp (limited to 'src/opengl') diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 5fef609a2a..9c62d41d3e 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -53,5 +53,3 @@ SOURCES += qglshaderprogram.cpp \ gl2paintengineex/qpaintengineex_opengl2.cpp \ gl2paintengineex/qglcustomshaderstage.cpp \ gl2paintengineex/qtextureglyphcache_gl.cpp - -SOURCES += qgl_qpa.cpp diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index f033b51edd..8223536608 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -70,6 +70,11 @@ #include "qlibrary.h" #include +#include "qsurfaceformat.h" +#include +#include +#include + #ifndef QT_OPENGL_ES_2 #include #endif @@ -438,6 +443,80 @@ QGLFormat::~QGLFormat() delete d; } +/*! + Returns an OpenGL format for the window format specified by \a format. +*/ +QGLFormat QGLFormat::fromSurfaceFormat(const QSurfaceFormat &format) +{ + QGLFormat retFormat; + if (format.alphaBufferSize() >= 0) + retFormat.setAlphaBufferSize(format.alphaBufferSize()); + if (format.blueBufferSize() >= 0) + retFormat.setBlueBufferSize(format.blueBufferSize()); + if (format.greenBufferSize() >= 0) + retFormat.setGreenBufferSize(format.greenBufferSize()); + if (format.redBufferSize() >= 0) + retFormat.setRedBufferSize(format.redBufferSize()); + if (format.depthBufferSize() >= 0) + retFormat.setDepthBufferSize(format.depthBufferSize()); + if (format.samples() > 1) { + retFormat.setSampleBuffers(true); + retFormat.setSamples(format.samples()); + } + if (format.stencilBufferSize() > 0) { + retFormat.setStencil(true); + retFormat.setStencilBufferSize(format.stencilBufferSize()); + } + retFormat.setDoubleBuffer(format.swapBehavior() != QSurfaceFormat::SingleBuffer); + retFormat.setStereo(format.stereo()); + retFormat.setVersion(format.majorVersion(), format.minorVersion()); + retFormat.setProfile(static_cast(format.profile())); + return retFormat; +} + +/*! + Returns a window format for the OpenGL format specified by \a format. +*/ +QSurfaceFormat QGLFormat::toSurfaceFormat(const QGLFormat &format) +{ + QSurfaceFormat retFormat; + if (format.alpha()) + retFormat.setAlphaBufferSize(format.alphaBufferSize() == -1 ? 1 : format.alphaBufferSize()); + if (format.blueBufferSize() >= 0) + retFormat.setBlueBufferSize(format.blueBufferSize()); + if (format.greenBufferSize() >= 0) + retFormat.setGreenBufferSize(format.greenBufferSize()); + if (format.redBufferSize() >= 0) + retFormat.setRedBufferSize(format.redBufferSize()); + if (format.depth()) + retFormat.setDepthBufferSize(format.depthBufferSize() == -1 ? 1 : format.depthBufferSize()); + retFormat.setSwapBehavior(format.doubleBuffer() ? QSurfaceFormat::DoubleBuffer : QSurfaceFormat::SingleBuffer); + if (format.sampleBuffers()) + retFormat.setSamples(format.samples() == -1 ? 4 : format.samples()); + if (format.stencil()) + retFormat.setStencilBufferSize(format.stencilBufferSize() == -1 ? 1 : format.stencilBufferSize()); + retFormat.setStereo(format.stereo()); + retFormat.setMajorVersion(format.majorVersion()); + retFormat.setMinorVersion(format.minorVersion()); + retFormat.setProfile(static_cast(format.profile())); + // QGLFormat has no way to set DeprecatedFunctions, that is, to tell that forward + // compatibility should not be requested. Some drivers fail to ignore the fwdcompat + // bit with compatibility profiles so make sure it is not set. + if (format.profile() == QGLFormat::CompatibilityProfile) + retFormat.setOption(QSurfaceFormat::DeprecatedFunctions); + return retFormat; +} + +void QGLContextPrivate::setupSharing() { + Q_Q(QGLContext); + QOpenGLContext *sharedContext = guiGlContext->shareContext(); + if (sharedContext) { + QGLContext *actualSharedContext = QGLContext::fromOpenGLContext(sharedContext); + sharing = true; + QGLContextGroup::addShare(q, actualSharedContext); + } +} + /*! \fn bool QGLFormat::doubleBuffer() const @@ -1132,8 +1211,11 @@ QGLFormat::OpenGLContextProfile QGLFormat::profile() const \warning This function must not be called until the QApplication object has been created. */ - - +bool QGLFormat::hasOpenGL() +{ + return QApplicationPrivate::platformIntegration() + ->hasCapability(QPlatformIntegration::OpenGL); +} /*! \fn bool QGLFormat::hasOpenGLOverlays() @@ -1144,6 +1226,10 @@ QGLFormat::OpenGLContextProfile QGLFormat::profile() const \warning This function must not be called until the QApplication object has been created. */ +bool QGLFormat::hasOpenGLOverlays() +{ + return false; +} QGLFormat::OpenGLVersionFlags Q_AUTOTEST_EXPORT qOpenGLVersionFlagsFromString(const QString &versionString) { @@ -1649,6 +1735,60 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) QGLContext* QGLContext::currentCtx = 0; +/* + QGLTemporaryContext implementation +*/ +class QGLTemporaryContextPrivate +{ +public: + QWindow *window; + QOpenGLContext *context; + + QGLContext *oldContext; +}; + +QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) + : d(new QGLTemporaryContextPrivate) +{ + d->oldContext = const_cast(QGLContext::currentContext()); + + d->window = new QWindow; + d->window->setSurfaceType(QWindow::OpenGLSurface); + d->window->setGeometry(QRect(0, 0, 3, 3)); + d->window->create(); + + d->context = new QOpenGLContext; +#if !defined(QT_OPENGL_ES) + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { + // On desktop, request latest released version + QSurfaceFormat format; +#if defined(Q_OS_MAC) + // OS X is limited to OpenGL 3.2 Core Profile at present + // so set that here. If we use compatibility profile it + // only reports 2.x contexts. + format.setMajorVersion(3); + format.setMinorVersion(2); + format.setProfile(QSurfaceFormat::CoreProfile); +#else + format.setMajorVersion(4); + format.setMinorVersion(3); +#endif + d->context->setFormat(format); + } +#endif // QT_OPENGL_ES + d->context->create(); + d->context->makeCurrent(d->window); +} + +QGLTemporaryContext::~QGLTemporaryContext() +{ + if (d->oldContext) + d->oldContext->makeCurrent(); + + delete d->context; + delete d->window; +} + /* Read back the contents of the currently bound framebuffer, used in QGLWidget::grabFrameBuffer(), QGLPixelbuffer::toImage() and @@ -2000,6 +2140,47 @@ QGLContext::QGLContext(const QGLFormat &format) d->init(0, format); } +void qDeleteQGLContext(void *handle) +{ + QGLContext *context = static_cast(handle); + delete context; +} + +QGLContext::QGLContext(QOpenGLContext *context) + : d_ptr(new QGLContextPrivate(this)) +{ + Q_D(QGLContext); + d->init(0, QGLFormat::fromSurfaceFormat(context->format())); + d->guiGlContext = context; + d->guiGlContext->setQGLContextHandle(this, qDeleteQGLContext); + d->ownContext = false; + d->valid = context->isValid(); + d->setupSharing(); +} + +QOpenGLContext *QGLContext::contextHandle() const +{ + Q_D(const QGLContext); + return d->guiGlContext; +} + +/*! + Returns a OpenGL context for the window context specified by the \a context + parameter. +*/ +QGLContext *QGLContext::fromOpenGLContext(QOpenGLContext *context) +{ + if (!context) + return 0; + if (context->qGLContextHandle()) { + return reinterpret_cast(context->qGLContextHandle()); + } + QGLContext *glContext = new QGLContext(context); + //Don't call create on context. This can cause the platformFormat to be set on the widget, which + //will cause the platformWindow to be recreated. + return glContext; +} + /*! Destroys the OpenGL context and frees its resources. */ @@ -3059,7 +3240,10 @@ bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *contex Returns a colormap index for the color c, in ColorIndex mode. Used by qglColor() and qglClearColor(). */ - +uint QGLContext::colorIndex(const QColor&) const +{ + return 0; +} /*! \fn bool QGLContext::initialized() const @@ -3107,7 +3291,10 @@ bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *contex also be used to draw transparent graphics with a QPainter. See the examples/opengl/overlay_x11 example for details. */ - +QColor QGLContext::overlayTransparentColor() const +{ + return QColor(); // Invalid color +} /*! Creates the GL context. Returns \c true if it was successful in @@ -3267,6 +3454,51 @@ void QGLContext::moveToThread(QThread *thread) the virtual function chooseVisual() which finds an appropriate X visual. On other platforms it may work differently. */ +bool QGLContext::chooseContext(const QGLContext* shareContext) +{ + Q_D(QGLContext); + if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) { + // Unlike in Qt 4, the only possible target is a widget backed by an OpenGL-based + // QWindow. Pixmaps in particular are not supported anymore as paint devices since + // starting from Qt 5 QPixmap is raster-backed on almost all platforms. + d->valid = false; + }else { + QWidget *widget = static_cast(d->paintDevice); + QGLFormat glformat = format(); + QSurfaceFormat winFormat = QGLFormat::toSurfaceFormat(glformat); + if (widget->testAttribute(Qt::WA_TranslucentBackground)) + winFormat.setAlphaBufferSize(qMax(winFormat.alphaBufferSize(), 8)); + + QWindow *window = widget->windowHandle(); + if (!window->handle() + || window->surfaceType() != QWindow::OpenGLSurface + || window->requestedFormat() != winFormat) + { + window->setSurfaceType(QWindow::OpenGLSurface); + window->setFormat(winFormat); + window->destroy(); + window->create(); + } + + if (d->ownContext) + delete d->guiGlContext; + d->ownContext = true; + QOpenGLContext *shareGlContext = shareContext ? shareContext->d_func()->guiGlContext : 0; + d->guiGlContext = new QOpenGLContext; + d->guiGlContext->setFormat(winFormat); + d->guiGlContext->setShareContext(shareGlContext); + d->valid = d->guiGlContext->create(); + + if (d->valid) + d->guiGlContext->setQGLContextHandle(this, qDeleteQGLContext); + + d->glFormat = QGLFormat::fromSurfaceFormat(d->guiGlContext->format()); + d->setupSharing(); + } + + + return d->valid; +} /*! \fn void QGLContext::reset() @@ -3275,7 +3507,33 @@ void QGLContext::moveToThread(QThread *thread) \sa create(), isValid() */ - +void QGLContext::reset() +{ + Q_D(QGLContext); + if (!d->valid) + return; + d->cleanup(); + + d->crWin = false; + d->sharing = false; + d->valid = false; + d->transpColor = QColor(); + d->initDone = false; + QGLContextGroup::removeShare(this); + if (d->guiGlContext) { + if (QOpenGLContext::currentContext() == d->guiGlContext) + doneCurrent(); + if (d->ownContext) { + if (d->guiGlContext->thread() == QThread::currentThread()) + delete d->guiGlContext; + else + d->guiGlContext->deleteLater(); + } else + d->guiGlContext->setQGLContextHandle(0,0); + d->guiGlContext = 0; + } + d->ownContext = false; +} /*! \fn void QGLContext::makeCurrent() @@ -3291,7 +3549,26 @@ void QGLContext::moveToThread(QThread *thread) make sure you've first pushed the context to the relevant thread from the UI thread using moveToThread(). */ +void QGLContext::makeCurrent() +{ + Q_D(QGLContext); + if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) + return; + QWidget *widget = static_cast(d->paintDevice); + if (!widget->windowHandle()) + return; + + if (d->guiGlContext->makeCurrent(widget->windowHandle())) { + if (!d->workaroundsCached) { + d->workaroundsCached = true; + const char *renderer = reinterpret_cast(d->guiGlContext->functions()->glGetString(GL_RENDERER)); + if (renderer && strstr(renderer, "Mali")) { + d->workaround_brokenFBOReadBack = true; + } + } + } +} /*! \fn void QGLContext::swapBuffers() const @@ -3299,7 +3576,18 @@ void QGLContext::moveToThread(QThread *thread) Call this to finish a frame of OpenGL rendering, and make sure to call makeCurrent() again before you begin a new frame. */ +void QGLContext::swapBuffers() const +{ + Q_D(const QGLContext); + if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) + return; + QWidget *widget = static_cast(d->paintDevice); + if (!widget->windowHandle()) + return; + + d->guiGlContext->swapBuffers(widget->windowHandle()); +} /*! \fn void QGLContext::doneCurrent() @@ -3307,7 +3595,11 @@ void QGLContext::moveToThread(QThread *thread) Makes no GL context the current context. Normally, you do not need to call this function; QGLContext calls it as necessary. */ - +void QGLContext::doneCurrent() +{ + Q_D(QGLContext); + d->guiGlContext->doneCurrent(); +} /*! \fn QPaintDevice* QGLContext::device() const @@ -3317,7 +3609,6 @@ void QGLContext::moveToThread(QThread *thread) \sa QGLContext::QGLContext() */ - /***************************************************************************** QGLWidget implementation *****************************************************************************/ @@ -3716,6 +4007,11 @@ QGLWidget::~QGLWidget() \a proc. 0 is returned if a pointer to the function could not be obtained. */ +QFunctionPointer QGLContext::getProcAddress(const QString &procName) const +{ + Q_D(const QGLContext); + return d->guiGlContext->getProcAddress(procName.toLatin1()); +} /*! \fn bool QGLWidget::isValid() const @@ -3803,8 +4099,10 @@ void QGLWidget::swapBuffers() \sa context() */ - - +const QGLContext* QGLWidget::overlayContext() const +{ + return 0; +} /*! \fn void QGLWidget::makeOverlayCurrent() @@ -3817,7 +4115,9 @@ void QGLWidget::swapBuffers() \sa makeCurrent() */ - +void QGLWidget::makeOverlayCurrent() +{ +} /*! \obsolete @@ -3893,8 +4193,28 @@ void QGLWidget::setFormat(const QGLFormat &format) \sa context(), isSharing() */ +void QGLWidget::setContext(QGLContext *context, + const QGLContext* shareContext, + bool deleteOldContext) +{ + Q_D(QGLWidget); + if (context == 0) { + qWarning("QGLWidget::setContext: Cannot set null context"); + return; + } + if (context->device() == 0) // a context may refere to more than 1 window. + context->setDevice(this); //but its better to point to 1 of them than none of them. + QGLContext* oldcx = d->glcx; + d->glcx = context; + + if (!d->glcx->isValid()) + d->glcx->create(shareContext ? shareContext : oldcx); + + if (deleteOldContext) + delete oldcx; +} /*! \fn void QGLWidget::updateGL() @@ -3920,7 +4240,9 @@ void QGLWidget::updateGL() The widget's rendering context will become the current context and initializeGL() will be called if it hasn't already been called. */ - +void QGLWidget::updateOverlayGL() +{ +} /*! This virtual function is called once before the first call to @@ -4022,6 +4344,20 @@ void QGLWidget::resizeOverlayGL(int, int) { } +bool QGLWidget::event(QEvent *e) +{ + Q_D(QGLWidget); + + // A re-parent will destroy the window and re-create it. We should not reset the context while it happens. + if (e->type() == QEvent::ParentAboutToChange) + d->parent_changing = true; + + if (e->type() == QEvent::ParentChange) + d->parent_changing = false; + + return QWidget::event(e); +} + /*! \fn void QGLWidget::paintEvent(QPaintEvent *event) @@ -4047,7 +4383,21 @@ void QGLWidget::paintEvent(QPaintEvent *) Handles resize events that are passed in the \a event parameter. Calls the virtual function resizeGL(). */ +void QGLWidget::resizeEvent(QResizeEvent *e) +{ + Q_D(QGLWidget); + + QWidget::resizeEvent(e); + if (!isValid()) + return; + makeCurrent(); + if (!d->glcx->initialized()) + glInit(); + const qreal scaleFactor = (window() && window()->windowHandle()) ? + window()->windowHandle()->devicePixelRatio() : 1.0; + resizeGL(width() * scaleFactor, height() * scaleFactor); +} /*! Renders the current scene on a pixmap and returns the pixmap. @@ -4333,6 +4683,11 @@ QImage QGLWidget::convertToGLFormat(const QImage& img) \sa setColormap(), QGLColormap::isEmpty() */ +const QGLColormap & QGLWidget::colormap() const +{ + Q_D(const QGLWidget); + return d->cmap; +} /*! \fn void QGLWidget::setColormap(const QGLColormap & cmap) @@ -4342,6 +4697,10 @@ QImage QGLWidget::convertToGLFormat(const QImage& img) \sa colormap() */ +void QGLWidget::setColormap(const QGLColormap & c) +{ + Q_UNUSED(c); +} #ifndef QT_OPENGL_ES @@ -4767,6 +5126,11 @@ QPaintEngine *QGLWidget::paintEngine() const return qt_qgl_paint_engine(); } +void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget) +{ + initContext(context, shareWidget); +} + /* This is the shared initialization for all platforms. Called from QGLWidgetPrivate::init() */ @@ -4787,6 +5151,19 @@ void QGLWidgetPrivate::initContext(QGLContext *context, const QGLWidget* shareWi glcx = new QGLContext(QGLFormat::defaultFormat(), q); } +bool QGLWidgetPrivate::renderCxPm(QPixmap*) +{ + return false; +} + +/*! \internal + Free up any allocated colormaps. This fn is only called for + top-level widgets. +*/ +void QGLWidgetPrivate::cleanupColormaps() +{ +} + Q_GLOBAL_STATIC(QString, qt_gl_lib_name) void qt_set_gl_library_name(const QString& name) diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp deleted file mode 100644 index fbabbecdfb..0000000000 --- a/src/opengl/qgl_qpa.cpp +++ /dev/null @@ -1,464 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include - -#include -#include -#include - -#include "qgl.h" -#include "qgl_p.h" - -QT_BEGIN_NAMESPACE - -/*! - Returns an OpenGL format for the window format specified by \a format. -*/ -QGLFormat QGLFormat::fromSurfaceFormat(const QSurfaceFormat &format) -{ - QGLFormat retFormat; - if (format.alphaBufferSize() >= 0) - retFormat.setAlphaBufferSize(format.alphaBufferSize()); - if (format.blueBufferSize() >= 0) - retFormat.setBlueBufferSize(format.blueBufferSize()); - if (format.greenBufferSize() >= 0) - retFormat.setGreenBufferSize(format.greenBufferSize()); - if (format.redBufferSize() >= 0) - retFormat.setRedBufferSize(format.redBufferSize()); - if (format.depthBufferSize() >= 0) - retFormat.setDepthBufferSize(format.depthBufferSize()); - if (format.samples() > 1) { - retFormat.setSampleBuffers(true); - retFormat.setSamples(format.samples()); - } - if (format.stencilBufferSize() > 0) { - retFormat.setStencil(true); - retFormat.setStencilBufferSize(format.stencilBufferSize()); - } - retFormat.setDoubleBuffer(format.swapBehavior() != QSurfaceFormat::SingleBuffer); - retFormat.setStereo(format.stereo()); - retFormat.setVersion(format.majorVersion(), format.minorVersion()); - retFormat.setProfile(static_cast(format.profile())); - return retFormat; -} - -/*! - Returns a window format for the OpenGL format specified by \a format. -*/ -QSurfaceFormat QGLFormat::toSurfaceFormat(const QGLFormat &format) -{ - QSurfaceFormat retFormat; - if (format.alpha()) - retFormat.setAlphaBufferSize(format.alphaBufferSize() == -1 ? 1 : format.alphaBufferSize()); - if (format.blueBufferSize() >= 0) - retFormat.setBlueBufferSize(format.blueBufferSize()); - if (format.greenBufferSize() >= 0) - retFormat.setGreenBufferSize(format.greenBufferSize()); - if (format.redBufferSize() >= 0) - retFormat.setRedBufferSize(format.redBufferSize()); - if (format.depth()) - retFormat.setDepthBufferSize(format.depthBufferSize() == -1 ? 1 : format.depthBufferSize()); - retFormat.setSwapBehavior(format.doubleBuffer() ? QSurfaceFormat::DoubleBuffer : QSurfaceFormat::SingleBuffer); - if (format.sampleBuffers()) - retFormat.setSamples(format.samples() == -1 ? 4 : format.samples()); - if (format.stencil()) - retFormat.setStencilBufferSize(format.stencilBufferSize() == -1 ? 1 : format.stencilBufferSize()); - retFormat.setStereo(format.stereo()); - retFormat.setMajorVersion(format.majorVersion()); - retFormat.setMinorVersion(format.minorVersion()); - retFormat.setProfile(static_cast(format.profile())); - // QGLFormat has no way to set DeprecatedFunctions, that is, to tell that forward - // compatibility should not be requested. Some drivers fail to ignore the fwdcompat - // bit with compatibility profiles so make sure it is not set. - if (format.profile() == QGLFormat::CompatibilityProfile) - retFormat.setOption(QSurfaceFormat::DeprecatedFunctions); - return retFormat; -} - -void QGLContextPrivate::setupSharing() { - Q_Q(QGLContext); - QOpenGLContext *sharedContext = guiGlContext->shareContext(); - if (sharedContext) { - QGLContext *actualSharedContext = QGLContext::fromOpenGLContext(sharedContext); - sharing = true; - QGLContextGroup::addShare(q, actualSharedContext); - } -} - -bool QGLFormat::hasOpenGL() -{ - return QApplicationPrivate::platformIntegration() - ->hasCapability(QPlatformIntegration::OpenGL); -} - -void qDeleteQGLContext(void *handle) -{ - QGLContext *context = static_cast(handle); - delete context; -} - -bool QGLContext::chooseContext(const QGLContext* shareContext) -{ - Q_D(QGLContext); - if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) { - // Unlike in Qt 4, the only possible target is a widget backed by an OpenGL-based - // QWindow. Pixmaps in particular are not supported anymore as paint devices since - // starting from Qt 5 QPixmap is raster-backed on almost all platforms. - d->valid = false; - }else { - QWidget *widget = static_cast(d->paintDevice); - QGLFormat glformat = format(); - QSurfaceFormat winFormat = QGLFormat::toSurfaceFormat(glformat); - if (widget->testAttribute(Qt::WA_TranslucentBackground)) - winFormat.setAlphaBufferSize(qMax(winFormat.alphaBufferSize(), 8)); - - QWindow *window = widget->windowHandle(); - if (!window->handle() - || window->surfaceType() != QWindow::OpenGLSurface - || window->requestedFormat() != winFormat) - { - window->setSurfaceType(QWindow::OpenGLSurface); - window->setFormat(winFormat); - window->destroy(); - window->create(); - } - - if (d->ownContext) - delete d->guiGlContext; - d->ownContext = true; - QOpenGLContext *shareGlContext = shareContext ? shareContext->d_func()->guiGlContext : 0; - d->guiGlContext = new QOpenGLContext; - d->guiGlContext->setFormat(winFormat); - d->guiGlContext->setShareContext(shareGlContext); - d->valid = d->guiGlContext->create(); - - if (d->valid) - d->guiGlContext->setQGLContextHandle(this,qDeleteQGLContext); - - d->glFormat = QGLFormat::fromSurfaceFormat(d->guiGlContext->format()); - d->setupSharing(); - } - - - return d->valid; -} - -void QGLContext::reset() -{ - Q_D(QGLContext); - if (!d->valid) - return; - d->cleanup(); - - d->crWin = false; - d->sharing = false; - d->valid = false; - d->transpColor = QColor(); - d->initDone = false; - QGLContextGroup::removeShare(this); - if (d->guiGlContext) { - if (QOpenGLContext::currentContext() == d->guiGlContext) - doneCurrent(); - if (d->ownContext) { - if (d->guiGlContext->thread() == QThread::currentThread()) - delete d->guiGlContext; - else - d->guiGlContext->deleteLater(); - } else - d->guiGlContext->setQGLContextHandle(0,0); - d->guiGlContext = 0; - } - d->ownContext = false; -} - -void QGLContext::makeCurrent() -{ - Q_D(QGLContext); - if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) - return; - - QWidget *widget = static_cast(d->paintDevice); - if (!widget->windowHandle()) - return; - - if (d->guiGlContext->makeCurrent(widget->windowHandle())) { - if (!d->workaroundsCached) { - d->workaroundsCached = true; - const char *renderer = reinterpret_cast(d->guiGlContext->functions()->glGetString(GL_RENDERER)); - if (renderer && strstr(renderer, "Mali")) { - d->workaround_brokenFBOReadBack = true; - } - } - } -} - -void QGLContext::doneCurrent() -{ - Q_D(QGLContext); - d->guiGlContext->doneCurrent(); -} - -void QGLContext::swapBuffers() const -{ - Q_D(const QGLContext); - if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) - return; - - QWidget *widget = static_cast(d->paintDevice); - if (!widget->windowHandle()) - return; - - d->guiGlContext->swapBuffers(widget->windowHandle()); -} - -QFunctionPointer QGLContext::getProcAddress(const QString &procName) const -{ - Q_D(const QGLContext); - return d->guiGlContext->getProcAddress(procName.toLatin1()); -} - -void QGLWidget::setContext(QGLContext *context, - const QGLContext* shareContext, - bool deleteOldContext) -{ - Q_D(QGLWidget); - if (context == 0) { - qWarning("QGLWidget::setContext: Cannot set null context"); - return; - } - - if (context->device() == 0) // a context may refere to more than 1 window. - context->setDevice(this); //but its better to point to 1 of them than none of them. - - QGLContext* oldcx = d->glcx; - d->glcx = context; - - if (!d->glcx->isValid()) - d->glcx->create(shareContext ? shareContext : oldcx); - - if (deleteOldContext) - delete oldcx; -} - -void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget) -{ - initContext(context, shareWidget); -} - -bool QGLFormat::hasOpenGLOverlays() -{ - return false; -} - -QColor QGLContext::overlayTransparentColor() const -{ - return QColor(); // Invalid color -} - -uint QGLContext::colorIndex(const QColor&) const -{ - return 0; -} - -/* - QGLTemporaryContext implementation -*/ -class QGLTemporaryContextPrivate -{ -public: - QWindow *window; - QOpenGLContext *context; - - QGLContext *oldContext; -}; - -QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) - : d(new QGLTemporaryContextPrivate) -{ - d->oldContext = const_cast(QGLContext::currentContext()); - - d->window = new QWindow; - d->window->setSurfaceType(QWindow::OpenGLSurface); - d->window->setGeometry(QRect(0, 0, 3, 3)); - d->window->create(); - - d->context = new QOpenGLContext; -#if !defined(QT_OPENGL_ES) - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { - // On desktop, request latest released version - QSurfaceFormat format; -#if defined(Q_OS_MAC) - // OS X is limited to OpenGL 3.2 Core Profile at present - // so set that here. If we use compatibility profile it - // only reports 2.x contexts. - format.setMajorVersion(3); - format.setMinorVersion(2); - format.setProfile(QSurfaceFormat::CoreProfile); -#else - format.setMajorVersion(4); - format.setMinorVersion(3); -#endif - d->context->setFormat(format); - } -#endif // QT_OPENGL_ES - d->context->create(); - d->context->makeCurrent(d->window); -} - -QGLTemporaryContext::~QGLTemporaryContext() -{ - if (d->oldContext) - d->oldContext->makeCurrent(); - - delete d->context; - delete d->window; -} - - -bool QGLWidgetPrivate::renderCxPm(QPixmap*) -{ - return false; -} - -/*! \internal - Free up any allocated colormaps. This fn is only called for - top-level widgets. -*/ -void QGLWidgetPrivate::cleanupColormaps() -{ -} - -bool QGLWidget::event(QEvent *e) -{ - Q_D(QGLWidget); - - // A re-parent will destroy the window and re-create it. We should not reset the context while it happens. - if (e->type() == QEvent::ParentAboutToChange) - d->parent_changing = true; - - if (e->type() == QEvent::ParentChange) - d->parent_changing = false; - - return QWidget::event(e); -} - -void QGLWidget::resizeEvent(QResizeEvent *e) -{ - Q_D(QGLWidget); - - QWidget::resizeEvent(e); - if (!isValid()) - return; - makeCurrent(); - if (!d->glcx->initialized()) - glInit(); - const qreal scaleFactor = (window() && window()->windowHandle()) ? - window()->windowHandle()->devicePixelRatio() : 1.0; - - resizeGL(width() * scaleFactor, height() * scaleFactor); -} - - -const QGLContext* QGLWidget::overlayContext() const -{ - return 0; -} - -void QGLWidget::makeOverlayCurrent() -{ -} - - -void QGLWidget::updateOverlayGL() -{ -} - -const QGLColormap & QGLWidget::colormap() const -{ - Q_D(const QGLWidget); - return d->cmap; -} - -void QGLWidget::setColormap(const QGLColormap & c) -{ - Q_UNUSED(c); -} - -QGLContext::QGLContext(QOpenGLContext *context) - : d_ptr(new QGLContextPrivate(this)) -{ - Q_D(QGLContext); - d->init(0, QGLFormat::fromSurfaceFormat(context->format())); - d->guiGlContext = context; - d->guiGlContext->setQGLContextHandle(this,qDeleteQGLContext); - d->ownContext = false; - d->valid = context->isValid(); - d->setupSharing(); -} - -QOpenGLContext *QGLContext::contextHandle() const -{ - Q_D(const QGLContext); - return d->guiGlContext; -} - -/*! - Returns a OpenGL context for the window context specified by the \a context - parameter. -*/ -QGLContext *QGLContext::fromOpenGLContext(QOpenGLContext *context) -{ - if (!context) - return 0; - if (context->qGLContextHandle()) { - return reinterpret_cast(context->qGLContextHandle()); - } - QGLContext *glContext = new QGLContext(context); - //Don't call create on context. This can cause the platformFormat to be set on the widget, which - //will cause the platformWindow to be recreated. - return glContext; -} - -QT_END_NAMESPACE -- cgit v1.2.3