summaryrefslogtreecommitdiffstats
path: root/src/gui/opengl
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-09-07 10:31:03 +0200
committerPaul Olav Tvete <paul.tvete@nokia.com>2011-09-08 11:07:56 +0200
commit1b1831500142c995137f5e4b1bc03d21aa08e1e1 (patch)
tree5fcd21ee23c37fbe3466fde353d0bcfd09a051e2 /src/gui/opengl
parent68974d8e647febb80a47d9cf6ce9452f3ce4fa21 (diff)
Improved and made public the QOpenGLPaintDevice API.
The new API is more flexible, allowing the use of QOpenGLPaintDevice with any QOpenGLContext, and putting more responsibility on the user for ensuring the correct FBO is current (the user knows best anyhow). Task-number: QTBUG-21263 Change-Id: I50b954125f552baef52fbb3fe2ed907a11ad519c Reviewed-on: http://codereview.qt-project.org/4325 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Paul Olav Tvete <paul.tvete@nokia.com>
Diffstat (limited to 'src/gui/opengl')
-rw-r--r--src/gui/opengl/opengl.pri2
-rw-r--r--src/gui/opengl/qopengl_p.h20
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp117
-rw-r--r--src/gui/opengl/qopenglframebufferobject.h9
-rw-r--r--src/gui/opengl/qopenglframebufferobject_p.h24
-rw-r--r--src/gui/opengl/qopenglpaintdevice.cpp220
-rw-r--r--src/gui/opengl/qopenglpaintdevice.h (renamed from src/gui/opengl/qopenglpaintdevice_p.h)68
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp35
-rw-r--r--src/gui/opengl/qopenglpaintengine_p.h3
9 files changed, 197 insertions, 301 deletions
diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri
index ed715d9f35..22fc05e56a 100644
--- a/src/gui/opengl/opengl.pri
+++ b/src/gui/opengl/opengl.pri
@@ -9,7 +9,7 @@ HEADERS += opengl/qopengl.h \
opengl/qopenglfunctions.h \
opengl/qopenglframebufferobject.h \
opengl/qopenglframebufferobject_p.h \
- opengl/qopenglpaintdevice_p.h \
+ opengl/qopenglpaintdevice.h \
opengl/qopenglbuffer.h \
opengl/qopenglshaderprogram.h \
opengl/qopenglextensions_p.h \
diff --git a/src/gui/opengl/qopengl_p.h b/src/gui/opengl/qopengl_p.h
index 309ea22acd..59368f1a7b 100644
--- a/src/gui/opengl/qopengl_p.h
+++ b/src/gui/opengl/qopengl_p.h
@@ -80,26 +80,6 @@ private:
QVector<int> m_offsets;
};
-// this is a class that wraps a QThreadStorage object for storing
-// thread local instances of the GL 1 and GL 2 paint engines
-
-class QPaintEngine;
-
-template <class T>
-class QOpenGLEngineThreadStorage
-{
-public:
- QPaintEngine *engine() {
- QPaintEngine *&localEngine = storage.localData();
- if (!localEngine)
- localEngine = new T;
- return localEngine;
- }
-
-private:
- QThreadStorage<QPaintEngine *> storage;
-};
-
class QOpenGLTexture : public QOpenGLSharedResource {
public:
QOpenGLTexture(QOpenGLContext *ctx, GLuint id, bool inverted)
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 51d6f7ee32..4512904a15 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -47,7 +47,6 @@
#include <private/qopenglcontext_p.h>
#include <private/qopenglextensions_p.h>
#include <private/qfont_p.h>
-#include <private/qopenglpaintengine_p.h>
#include <qwindow.h>
#include <qlibrary.h>
@@ -314,41 +313,6 @@ bool QOpenGLFramebufferObjectFormat::operator!=(const QOpenGLFramebufferObjectFo
return !(*this == other);
}
-void QOpenGLFBOGLPaintDevice::setFBO(QOpenGLFramebufferObject* f,
- QOpenGLFramebufferObject::Attachment attachment)
-{
- fbo = f;
- m_thisFBO = fbo->d_func()->fbo(); // This shouldn't be needed
-
- // The context that the fbo was created in may not have depth
- // and stencil buffers, but the fbo itself might.
- fboFormat = QOpenGLContext::currentContext()->format();
- if (attachment == QOpenGLFramebufferObject::CombinedDepthStencil) {
- fboFormat.setDepthBufferSize(24);
- fboFormat.setStencilBufferSize(8);
- } else if (attachment == QOpenGLFramebufferObject::Depth) {
- fboFormat.setDepthBufferSize(24);
- fboFormat.setStencilBufferSize(0);
- } else {
- fboFormat.setDepthBufferSize(0);
- fboFormat.setStencilBufferSize(0);
- }
-
- GLenum format = f->format().internalTextureFormat();
- reqAlpha = (format != GL_RGB
-#ifndef QT_OPENGL_ES
- && format != GL_RGB5 && format != GL_RGB8
-#endif
- );
-}
-
-QOpenGLContextGroup *QOpenGLFBOGLPaintDevice::group() const
-{
- QOpenGLSharedResourceGuard *fbo_guard =
- fbo->d_func()->fbo_guard;
- return fbo_guard ? fbo_guard->group() : 0;
-}
-
bool QOpenGLFramebufferObjectPrivate::checkFramebufferStatus() const
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
@@ -414,7 +378,7 @@ namespace
}
}
-void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *q, const QSize &sz,
+void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSize &sz,
QOpenGLFramebufferObject::Attachment attachment,
GLenum texture_target, GLenum internal_format,
GLint samples, bool mipmap)
@@ -646,8 +610,6 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *q, const QS
format.setAttachment(fbo_attachment);
format.setInternalTextureFormat(internal_format);
format.setMipmap(mipmap);
-
- glDevice.setFBO(q, attachment);
}
/*!
@@ -704,12 +666,6 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *q, const QS
the constructors that take a QOpenGLFramebufferObject parameter, and set the
QOpenGLFramebufferObject::samples() property to a non-zero value.
- When painting to a QOpenGLFramebufferObject using QPainter, the state of
- the current GL context will be altered by the paint engine to reflect
- its needs. Applications should not rely upon the GL state being reset
- to its original conditions, particularly the current shader program,
- GL viewport, texture units, and drawing modes.
-
For multisample framebuffer objects a color render buffer is created,
otherwise a texture with the specified texture target is created.
The color render buffer or texture will have the specified internal
@@ -875,8 +831,6 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject()
{
Q_D(QOpenGLFramebufferObject);
- delete d->engine;
-
if (d->texture_guard)
d->texture_guard->free();
if (d->color_buffer_guard)
@@ -1103,23 +1057,6 @@ QImage QOpenGLFramebufferObject::toImage() const
return image;
}
-Q_GLOBAL_STATIC(QOpenGLEngineThreadStorage<QOpenGL2PaintEngineEx>, qt_buffer_2_engine)
-
-/*! \reimp */
-QPaintEngine *QOpenGLFramebufferObject::paintEngine() const
-{
- Q_D(const QOpenGLFramebufferObject);
- if (d->engine)
- return d->engine;
-
- QPaintEngine *engine = qt_buffer_2_engine()->engine();
- if (engine->isActive() && engine->paintDevice() != this) {
- d->engine = new QOpenGL2PaintEngineEx;
- return d->engine;
- }
- return engine;
-}
-
/*!
\fn bool QOpenGLFramebufferObject::bindDefault()
\internal
@@ -1158,53 +1095,6 @@ bool QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()
return QOpenGLFunctions(QOpenGLContext::currentContext()).hasOpenGLFeature(QOpenGLFunctions::Framebuffers);
}
-/*! \reimp */
-int QOpenGLFramebufferObject::metric(PaintDeviceMetric metric) const
-{
- Q_D(const QOpenGLFramebufferObject);
-
- float dpmx = qt_defaultDpiX()*100./2.54;
- float dpmy = qt_defaultDpiY()*100./2.54;
- int w = d->size.width();
- int h = d->size.height();
- switch (metric) {
- case PdmWidth:
- return w;
-
- case PdmHeight:
- return h;
-
- case PdmWidthMM:
- return qRound(w * 1000 / dpmx);
-
- case PdmHeightMM:
- return qRound(h * 1000 / dpmy);
-
- case PdmNumColors:
- return 0;
-
- case PdmDepth:
- return 32;//d->depth;
-
- case PdmDpiX:
- return qRound(dpmx * 0.0254);
-
- case PdmDpiY:
- return qRound(dpmy * 0.0254);
-
- case PdmPhysicalDpiX:
- return qRound(dpmx * 0.0254);
-
- case PdmPhysicalDpiY:
- return qRound(dpmy * 0.0254);
-
- default:
- qWarning("QOpenGLFramebufferObject::metric(), Unhandled metric type: %d.\n", metric);
- break;
- }
- return 0;
-}
-
/*!
\fn GLuint QOpenGLFramebufferObject::handle() const
@@ -1220,11 +1110,6 @@ GLuint QOpenGLFramebufferObject::handle() const
return d->fbo();
}
-/*! \fn int QOpenGLFramebufferObject::devType() const
- \internal
-*/
-
-
/*!
Returns the status of the depth and stencil buffers attached to
this framebuffer object.
diff --git a/src/gui/opengl/qopenglframebufferobject.h b/src/gui/opengl/qopenglframebufferobject.h
index b7c38479ff..8c3895b293 100644
--- a/src/gui/opengl/qopenglframebufferobject.h
+++ b/src/gui/opengl/qopenglframebufferobject.h
@@ -56,7 +56,7 @@ QT_MODULE(Gui)
class QOpenGLFramebufferObjectPrivate;
class QOpenGLFramebufferObjectFormat;
-class Q_GUI_EXPORT QOpenGLFramebufferObject : public QPaintDevice
+class Q_GUI_EXPORT QOpenGLFramebufferObject
{
Q_DECLARE_PRIVATE(QOpenGLFramebufferObject)
public:
@@ -92,6 +92,9 @@ public:
bool bind();
bool release();
+ int width() const { return size().width(); }
+ int height() const { return size().width(); }
+
GLuint texture() const;
QSize size() const;
QImage toImage() const;
@@ -110,10 +113,6 @@ public:
GLbitfield buffers = GL_COLOR_BUFFER_BIT,
GLenum filter = GL_NEAREST);
-protected:
- int metric(PaintDeviceMetric metric) const;
- int devType() const { return QInternal::FramebufferObject; }
-
private:
Q_DISABLE_COPY(QOpenGLFramebufferObject)
QScopedPointer<QOpenGLFramebufferObjectPrivate> d_ptr;
diff --git a/src/gui/opengl/qopenglframebufferobject_p.h b/src/gui/opengl/qopenglframebufferobject_p.h
index 6ea6eb26ee..93a8bbf32f 100644
--- a/src/gui/opengl/qopenglframebufferobject_p.h
+++ b/src/gui/opengl/qopenglframebufferobject_p.h
@@ -58,7 +58,6 @@ QT_BEGIN_NAMESPACE
QT_BEGIN_INCLUDE_NAMESPACE
#include <qopenglframebufferobject.h>
-#include <private/qopenglpaintdevice_p.h>
#include <private/qopenglcontext_p.h>
#include <private/qopenglextensions_p.h>
@@ -109,31 +108,12 @@ public:
uint mipmap : 1;
};
-class QOpenGLFBOGLPaintDevice : public QOpenGLPaintDevice
-{
-public:
- virtual QPaintEngine* paintEngine() const {return fbo->paintEngine();}
- virtual QSize size() const {return fbo->size();}
- virtual QSurfaceFormat format() const {return fboFormat;}
- virtual QOpenGLContextGroup *group() const;
- virtual bool alphaRequested() const { return reqAlpha; }
-
- void setFBO(QOpenGLFramebufferObject* f,
- QOpenGLFramebufferObject::Attachment attachment);
-
-private:
- QOpenGLFramebufferObject* fbo;
- QSurfaceFormat fboFormat;
- bool wasBound;
- bool reqAlpha;
-};
-
class QOpenGLFramebufferObjectPrivate
{
public:
QOpenGLFramebufferObjectPrivate() : fbo_guard(0), texture_guard(0), depth_buffer_guard(0)
, stencil_buffer_guard(0), color_buffer_guard(0)
- , valid(false), engine(0) {}
+ , valid(false) {}
~QOpenGLFramebufferObjectPrivate() {}
void init(QOpenGLFramebufferObject *q, const QSize& sz,
@@ -151,8 +131,6 @@ public:
QOpenGLFramebufferObjectFormat format;
uint valid : 1;
QOpenGLFramebufferObject::Attachment fbo_attachment;
- mutable QPaintEngine *engine;
- QOpenGLFBOGLPaintDevice glDevice;
QOpenGLExtensions funcs;
inline GLuint fbo() const { return fbo_guard ? fbo_guard->id() : 0; }
diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp
index e3ff5ae1f9..4e5c2703dc 100644
--- a/src/gui/opengl/qopenglpaintdevice.cpp
+++ b/src/gui/opengl/qopenglpaintdevice.cpp
@@ -39,115 +39,193 @@
**
****************************************************************************/
-#include <private/qopenglpaintdevice_p.h>
+#include <qopenglpaintdevice.h>
+#include <qpaintengine.h>
+#include <qthreadstorage.h>
+
+#include <private/qobject_p.h>
#include <private/qopenglcontext_p.h>
#include <private/qopenglframebufferobject_p.h>
+#include <private/qopenglpaintengine_p.h>
+
+// for qt_defaultDpiX/Y
+#include <private/qfont_p.h>
#include <qopenglfunctions.h>
QT_BEGIN_NAMESPACE
-QOpenGLPaintDevice::QOpenGLPaintDevice()
- : m_thisFBO(0)
+/*!
+ \class QOpenGLPaintDevice
+ \brief The QOpenGLPaintDevice class enables painting to an OpenGL context using QPainter.
+ \since 5.0
+
+ \ingroup painting-3D
+
+ When painting to a QOpenGLPaintDevice using QPainter, the state of
+ the current GL context will be altered by the paint engine to reflect
+ its needs. Applications should not rely upon the GL state being reset
+ to its original conditions, particularly the current shader program,
+ GL viewport, texture units, and drawing modes.
+*/
+
+class QOpenGLPaintDevicePrivate
+{
+public:
+ QOpenGLPaintDevicePrivate(const QSize &size);
+
+ QSize size;
+ QOpenGLContext *ctx;
+
+ qreal dpmx;
+ qreal dpmy;
+
+ bool flipped;
+
+ QPaintEngine *engine;
+
+ void init(const QSize &size, QOpenGLContext *ctx);
+};
+
+/*!
+ Constructs a QOpenGLPaintDevice with the given \a size.
+
+ The QOpenGLPaintDevice is only valid for the current context.
+
+ \sa QOpenGLContext::currentContext()
+*/
+QOpenGLPaintDevice::QOpenGLPaintDevice(const QSize &size)
+ : d_ptr(new QOpenGLPaintDevicePrivate(size))
+{
+}
+
+/*!
+ Constructs a QOpenGLPaintDevice with the given \a size and \a ctx.
+
+ The QOpenGLPaintDevice is only valid for the current context.
+
+ \sa QOpenGLContext::currentContext()
+*/
+QOpenGLPaintDevice::QOpenGLPaintDevice(int width, int height)
+ : d_ptr(new QOpenGLPaintDevicePrivate(QSize(width, height)))
{
}
QOpenGLPaintDevice::~QOpenGLPaintDevice()
{
+ delete d_ptr->engine;
}
-int QOpenGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
+QOpenGLPaintDevicePrivate::QOpenGLPaintDevicePrivate(const QSize &sz)
+ : size(sz)
+ , ctx(QOpenGLContext::currentContext())
+ , dpmx(qt_defaultDpiX() * 100. / 2.54)
+ , dpmy(qt_defaultDpiY() * 100. / 2.54)
+ , flipped(false)
+ , engine(0)
{
- switch(metric) {
- case PdmWidth:
- return size().width();
- case PdmHeight:
- return size().height();
- case PdmDepth: {
- const QSurfaceFormat f = format();
- return f.redBufferSize() + f.greenBufferSize() + f.blueBufferSize() + f.alphaBufferSize();
- }
- default:
- qWarning("QOpenGLPaintDevice::metric() - metric %d not known", metric);
- return 0;
- }
}
-void QOpenGLPaintDevice::beginPaint()
+class QOpenGLEngineThreadStorage
{
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
+public:
+ QPaintEngine *engine() {
+ QPaintEngine *&localEngine = storage.localData();
+ if (!localEngine)
+ localEngine = new QOpenGL2PaintEngineEx;
+ return localEngine;
+ }
+
+private:
+ QThreadStorage<QPaintEngine *> storage;
+};
- // Record the currently bound FBO so we can restore it again
- // in endPaint() and bind this device's FBO
- //
- // Note: m_thisFBO could be zero if the paint device is not
- // backed by an FBO (e.g. window back buffer). But there could
- // be a previous FBO bound to the context which we need to
- // explicitly unbind. Otherwise the painting will go into
- // the previous FBO instead of to the window.
- m_previousFBO = ctx->d_func()->current_fbo;
+Q_GLOBAL_STATIC(QOpenGLEngineThreadStorage, qt_opengl_engine)
+
+QPaintEngine *QOpenGLPaintDevice::paintEngine() const
+{
+ if (d_ptr->engine)
+ return d_ptr->engine;
- if (m_previousFBO != m_thisFBO) {
- ctx->d_func()->current_fbo = m_thisFBO;
- QOpenGLFunctions(ctx).glBindFramebuffer(GL_FRAMEBUFFER, m_thisFBO);
+ QPaintEngine *engine = qt_opengl_engine()->engine();
+ if (engine->isActive() && engine->paintDevice() != this) {
+ d_ptr->engine = new QOpenGL2PaintEngineEx;
+ return d_ptr->engine;
}
- // Set the default fbo for the context to m_thisFBO so that
- // if some raw GL code between beginNativePainting() and
- // endNativePainting() calls QOpenGLFramebufferObject::release(),
- // painting will revert to the window surface's fbo.
- ctx->d_func()->default_fbo = m_thisFBO;
+ return engine;
}
-void QOpenGLPaintDevice::ensureActiveTarget()
+QOpenGLContext *QOpenGLPaintDevice::context() const
{
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ return d_ptr->ctx;
+}
- if (ctx->d_func()->current_fbo != m_thisFBO) {
- ctx->d_func()->current_fbo = m_thisFBO;
- QOpenGLFunctions(ctx).glBindFramebuffer(GL_FRAMEBUFFER, m_thisFBO);
- }
+QSize QOpenGLPaintDevice::size() const
+{
+ return d_ptr->size;
+}
- ctx->d_func()->default_fbo = m_thisFBO;
+int QOpenGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
+{
+ switch (metric) {
+ case PdmWidth:
+ return d_ptr->size.width();
+ case PdmHeight:
+ return d_ptr->size.height();
+ case PdmDepth:
+ return 32;
+ case PdmWidthMM:
+ return qRound(d_ptr->size.width() * 1000 / d_ptr->dpmx);
+ case PdmHeightMM:
+ return qRound(d_ptr->size.height() * 1000 / d_ptr->dpmy);
+ case PdmNumColors:
+ return 0;
+ case PdmDpiX:
+ return qRound(d_ptr->dpmx * 0.0254);
+ case PdmDpiY:
+ return qRound(d_ptr->dpmy * 0.0254);
+ case PdmPhysicalDpiX:
+ return qRound(d_ptr->dpmx * 0.0254);
+ case PdmPhysicalDpiY:
+ return qRound(d_ptr->dpmy * 0.0254);
+ default:
+ qWarning("QOpenGLPaintDevice::metric() - metric %d not known", metric);
+ return 0;
+ }
}
-void QOpenGLPaintDevice::endPaint()
+qreal QOpenGLPaintDevice::dotsPerMeterX() const
{
- // Make sure the FBO bound at beginPaint is re-bound again here:
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ return d_ptr->dpmx;
+}
- if (m_previousFBO != ctx->d_func()->current_fbo) {
- ctx->d_func()->current_fbo = m_previousFBO;
- QOpenGLFunctions(ctx).glBindFramebuffer(GL_FRAMEBUFFER, m_previousFBO);
- }
+qreal QOpenGLPaintDevice::dotsPerMeterY() const
+{
+ return d_ptr->dpmy;
+}
- ctx->d_func()->default_fbo = 0;
+void QOpenGLPaintDevice::setDotsPerMeterX(qreal dpmx)
+{
+ d_ptr->dpmx = dpmx;
}
-bool QOpenGLPaintDevice::isFlipped() const
+void QOpenGLPaintDevice::setDotsPerMeterY(qreal dpmy)
{
- return false;
+ d_ptr->dpmx = dpmy;
}
-// returns the QOpenGLPaintDevice for the given QPaintDevice
-QOpenGLPaintDevice* QOpenGLPaintDevice::getDevice(QPaintDevice* pd)
-{
- QOpenGLPaintDevice* glpd = 0;
-
- switch(pd->devType()) {
- case QInternal::FramebufferObject:
- glpd = &(static_cast<QOpenGLFramebufferObject*>(pd)->d_func()->glDevice);
- break;
- case QInternal::Pixmap: {
- qWarning("Pixmap type not supported for GL rendering");
- break;
- }
- default:
- qWarning("QOpenGLPaintDevice::getDevice() - Unknown device type %d", pd->devType());
- break;
- }
+/*!
+ Specifies whether painting should be flipped around the Y-axis or not.
+*/
+void QOpenGLPaintDevice::setPaintFlipped(bool flipped)
+{
+ d_ptr->flipped = flipped;
+}
- return glpd;
+bool QOpenGLPaintDevice::paintFlipped() const
+{
+ return d_ptr->flipped;
}
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglpaintdevice_p.h b/src/gui/opengl/qopenglpaintdevice.h
index 492bc1649a..0f11595ca8 100644
--- a/src/gui/opengl/qopenglpaintdevice_p.h
+++ b/src/gui/opengl/qopenglpaintdevice.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QOPENGLPAINTDEVICE_P_H
-#define QOPENGLPAINTDEVICE_P_H
+#ifndef QOPENGLPAINTDEVICE_H
+#define QOPENGLPAINTDEVICE_H
//
// W A R N I N G
@@ -58,62 +58,46 @@
#include <QtGui/qopengl.h>
#include <QtGui/qopenglcontext.h>
+QT_BEGIN_HEADER
+
QT_BEGIN_NAMESPACE
+QT_MODULE(Gui)
+
+class QOpenGLPaintDevicePrivate;
+
class Q_GUI_EXPORT QOpenGLPaintDevice : public QPaintDevice
{
+ Q_DECLARE_PRIVATE(QOpenGLPaintDevice)
public:
- QOpenGLPaintDevice();
+ QOpenGLPaintDevice(const QSize &size);
+ QOpenGLPaintDevice(int width, int height);
virtual ~QOpenGLPaintDevice();
- int devType() const {return QInternal::OpenGL;}
-
- virtual void beginPaint();
- virtual void ensureActiveTarget();
- virtual void endPaint();
+ int devType() const { return QInternal::OpenGL; }
+ QPaintEngine *paintEngine() const;
- virtual QOpenGLContextGroup *group() const = 0;
+ QOpenGLContext *context() const;
+ QSize size() const;
- virtual QSurfaceFormat format() const = 0;
- virtual QSize size() const = 0;
+ qreal dotsPerMeterX() const;
+ qreal dotsPerMeterY() const;
- virtual bool alphaRequested() const = 0;
- virtual bool isFlipped() const;
+ void setDotsPerMeterX(qreal);
+ void setDotsPerMeterY(qreal);
- // returns the QOpenGLPaintDevice for the given QPaintDevice
- static QOpenGLPaintDevice* getDevice(QPaintDevice*);
+ void setPaintFlipped(bool flipped);
+ bool paintFlipped() const;
protected:
int metric(QPaintDevice::PaintDeviceMetric metric) const;
- GLuint m_previousFBO;
- GLuint m_thisFBO;
-};
-
-#if 0
-// Wraps a QOpenGLWidget
-class QOpenGLWidget;
-class Q_GUI_EXPORT QOpenGLWidgetGLPaintDevice : public QOpenGLPaintDevice
-{
-public:
- QOpenGLWidgetGLPaintDevice();
-
- virtual QPaintEngine* paintEngine() const;
-
- // QOpenGLWidgets need to do swapBufers in endPaint:
- virtual void beginPaint();
- virtual void endPaint();
- virtual QSize size() const;
- virtual QOpenGLContext* context() const;
-
- void setWidget(QOpenGLWidget*);
-
-private:
- friend class QOpenGLWidget;
- QOpenGLWidget *glWidget;
+ Q_DISABLE_COPY(QOpenGLPaintDevice)
+ QScopedPointer<QOpenGLPaintDevicePrivate> d_ptr;
};
-#endif
QT_END_NAMESPACE
-#endif // QOPENGLPAINTDEVICE_P_H
+QT_END_HEADER
+
+#endif // QOPENGLPAINTDEVICE_H
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index dfb8549375..519dd3b893 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -342,7 +342,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushUniforms()
QTransform translate(1, 0, 0, 1, -translationPoint.x(), -translationPoint.y());
qreal m22 = -1;
qreal dy = height;
- if (device->isFlipped()) {
+ if (device->paintFlipped()) {
m22 = 1;
dy = 0;
}
@@ -390,7 +390,7 @@ void QOpenGL2PaintEngineExPrivate::updateMatrix()
GLfloat dx = transform.dx();
GLfloat dy = transform.dy();
- if (device->isFlipped()) {
+ if (device->paintFlipped()) {
hfactor *= -1;
dy -= height;
}
@@ -542,7 +542,8 @@ void QOpenGL2PaintEngineEx::beginNativePainting()
d->funcs.glDisableVertexAttribArray(i);
#ifndef QT_OPENGL_ES_2
- const QSurfaceFormat &fmt = d->device->format();
+ Q_ASSERT(QOpenGLContext::currentContext());
+ const QSurfaceFormat &fmt = d->device->context()->format();
if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
|| fmt.profile() == QSurfaceFormat::CompatibilityProfile)
{
@@ -878,7 +879,7 @@ void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path)
// Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable
path.makeCacheable();
- if (!device->format().stencilBufferSize()) {
+ if (device->context()->format().stencilBufferSize() == 0) {
// If there is no stencil buffer, triangulate the path instead.
QRectF bbox = path.controlPointRect();
@@ -1421,7 +1422,7 @@ void QOpenGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem)
? QFontEngineGlyphCache::Type(textItem->fontEngine()->glyphFormat)
: d->glyphCacheType;
if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) {
- if (d->device->alphaRequested() || s->matrix.type() > QTransform::TxTranslate
+ if (d->device->context()->format().alphaBufferSize() > 0 || s->matrix.type() > QTransform::TxTranslate
|| (s->composition_mode != QPainter::CompositionMode_Source
&& s->composition_mode != QPainter::CompositionMode_SourceOver))
{
@@ -1480,7 +1481,7 @@ void QOpenGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &text
if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) {
- if (d->device->alphaRequested() || txtype > QTransform::TxTranslate
+ if (d->device->context()->format().alphaBufferSize() > 0 || txtype > QTransform::TxTranslate
|| (state()->composition_mode != QPainter::CompositionMode_Source
&& state()->composition_mode != QPainter::CompositionMode_SourceOver))
{
@@ -1944,17 +1945,14 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
{
Q_D(QOpenGL2PaintEngineEx);
-// qDebug("QOpenGL2PaintEngineEx::begin()");
- if (pdev->devType() == QInternal::OpenGL)
- d->device = static_cast<QOpenGLPaintDevice*>(pdev);
- else
- d->device = QOpenGLPaintDevice::getDevice(pdev);
+ Q_ASSERT(pdev->devType() == QInternal::OpenGL);
+ d->device = static_cast<QOpenGLPaintDevice*>(pdev);
if (!d->device)
return false;
- if (d->device->group() != QOpenGLContextGroup::currentContextGroup()) {
- qWarning("QPainter::begin(): OpenGL resource not valid in current context");
+ if (d->device->context() != QOpenGLContext::currentContext()) {
+ qWarning("QPainter::begin(): QOpenGLPaintDevice's context needs to be current");
return false;
}
@@ -1983,10 +1981,6 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->dirtyStencilRegion = QRect(0, 0, d->width, d->height);
d->stencilClean = true;
- // Calling begin paint should make the correct context current. So, any
- // code which calls into GL or otherwise needs a current context *must*
- // go after beginPaint:
- d->device->beginPaint();
d->shaderManager = new QOpenGLEngineShaderManager(d->ctx);
glDisable(GL_STENCIL_TEST);
@@ -2013,7 +2007,7 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
#if defined(QT_OPENGL_ES_2)
// OpenGL ES can't switch MSAA off, so if the gl paint device is
// multisampled, it's always multisampled.
- d->multisamplingAlwaysEnabled = d->device->format().samples() > 1;
+ d->multisamplingAlwaysEnabled = d->device->context()->format().samples() > 1;
#else
d->multisamplingAlwaysEnabled = false;
#endif
@@ -2028,7 +2022,6 @@ bool QOpenGL2PaintEngineEx::end()
QOpenGLContext *ctx = d->ctx;
d->funcs.glUseProgram(0);
d->transferMode(BrushDrawingMode);
- d->device->endPaint();
ctx->d_func()->active_engine = 0;
@@ -2062,8 +2055,6 @@ void QOpenGL2PaintEngineEx::ensureActive()
d->needsSync = true;
}
- d->device->ensureActiveTarget();
-
if (d->needsSync) {
d->transferMode(BrushDrawingMode);
glViewport(0, 0, d->width, d->height);
@@ -2120,7 +2111,7 @@ void QOpenGL2PaintEngineExPrivate::setScissor(const QRect &rect)
const int left = rect.left();
const int width = rect.width();
int bottom = height - (rect.top() + rect.height());
- if (device->isFlipped()) {
+ if (device->paintFlipped()) {
bottom = rect.top();
}
const int height = rect.height();
diff --git a/src/gui/opengl/qopenglpaintengine_p.h b/src/gui/opengl/qopenglpaintengine_p.h
index d38f2a8659..1ce04eb5a7 100644
--- a/src/gui/opengl/qopenglpaintengine_p.h
+++ b/src/gui/opengl/qopenglpaintengine_p.h
@@ -55,10 +55,11 @@
#include <QDebug>
+#include <qopenglpaintdevice.h>
+
#include <private/qpaintengineex_p.h>
#include <private/qopenglengineshadermanager_p.h>
#include <private/qopengl2pexvertexarray_p.h>
-#include <private/qopenglpaintdevice_p.h>
#include <private/qfontengine_p.h>
#include <private/qdatabuffer_p.h>
#include <private/qopengltriangulatingstroker_p.h>