summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/opengl/paintedwindow/main.cpp4
-rw-r--r--examples/opengl/paintedwindow/paintedwindow.cpp95
-rw-r--r--examples/opengl/paintedwindow/paintedwindow.h6
-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
-rw-r--r--src/gui/painting/qpaintdevice.h12
13 files changed, 210 insertions, 405 deletions
diff --git a/examples/opengl/paintedwindow/main.cpp b/examples/opengl/paintedwindow/main.cpp
index c77cf41f0f..345cea7bc5 100644
--- a/examples/opengl/paintedwindow/main.cpp
+++ b/examples/opengl/paintedwindow/main.cpp
@@ -12,10 +12,6 @@ int main(int argc, char **argv)
QRect screenGeometry = screen->availableGeometry();
- QSurfaceFormat format;
- format.setDepthBufferSize(16);
- format.setSamples(4);
-
QPoint center = screenGeometry.center();
QRect windowRect(0, 0, 640, 480);
diff --git a/examples/opengl/paintedwindow/paintedwindow.cpp b/examples/opengl/paintedwindow/paintedwindow.cpp
index b9ecac1293..9b27c56914 100644
--- a/examples/opengl/paintedwindow/paintedwindow.cpp
+++ b/examples/opengl/paintedwindow/paintedwindow.cpp
@@ -1,17 +1,17 @@
#include "paintedwindow.h"
#include <QOpenGLContext>
-#include <QOpenGLFunctions>
+#include <QOpenGLPaintDevice>
#include <QPainter>
#include <QTimer>
#include <qmath.h>
PaintedWindow::PaintedWindow()
- : m_fbo(0)
{
QSurfaceFormat format;
format.setStencilBufferSize(8);
+ format.setSamples(4);
setSurfaceType(QWindow::OpenGLSurface);
setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
@@ -22,103 +22,32 @@ PaintedWindow::PaintedWindow()
m_context = new QOpenGLContext(this);
m_context->setFormat(format);
m_context->create();
-
- QTimer *timer = new QTimer(this);
- timer->setInterval(16);
- connect(timer, SIGNAL(timeout()), this, SLOT(paint()));
- timer->start();
-
- m_context->makeCurrent(this);
-
- QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
- const char *vsrc =
- "attribute highp vec2 vertexCoordsInput;\n"
- "attribute mediump vec2 texCoordsInput;\n"
- "varying mediump vec2 texCoords;\n"
- "void main(void)\n"
- "{\n"
- " texCoords = texCoordsInput;\n"
- " gl_Position = vec4(vertexCoordsInput, 0, 1);\n"
- "}\n";
- vshader->compileSourceCode(vsrc);
-
- QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
- const char *fsrc =
- "uniform sampler2D tex;\n"
- "varying mediump vec2 texCoords;\n"
- "void main(void)\n"
- "{\n"
- " gl_FragColor = texture2D(tex, texCoords);\n"
- "}\n";
- fshader->compileSourceCode(fsrc);
-
- m_program = new QOpenGLShaderProgram;
- m_program->addShader(vshader);
- m_program->addShader(fshader);
- m_program->link();
-
- m_vertexAttribute = m_program->attributeLocation("vertexCoordsInput");
- m_texCoordsAttribute = m_program->attributeLocation("texCoordsInput");
}
void PaintedWindow::resizeEvent(QResizeEvent *)
{
- m_context->makeCurrent(this);
+ paint();
+}
- delete m_fbo;
- m_fbo = new QOpenGLFramebufferObject(size());
+void PaintedWindow::exposeEvent(QExposeEvent *)
+{
+ paint();
}
void PaintedWindow::paint()
{
- if (!m_fbo)
- return;
-
m_context->makeCurrent(this);
QPainterPath path;
- path.addEllipse(0, 0, m_fbo->width(), m_fbo->height());
+ path.addEllipse(0, 0, width(), height());
+
+ QOpenGLPaintDevice device(size());
- QPainter painter;
- painter.begin(m_fbo);
- painter.fillRect(0, 0, m_fbo->width(), m_fbo->height(), Qt::white);
+ QPainter painter(&device);
+ painter.fillRect(0, 0, width(), height(), Qt::white);
painter.setRenderHint(QPainter::Antialiasing);
painter.fillPath(path, Qt::blue);
painter.end();
- glViewport(0, 0, width(), height());
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_BLEND);
-
- glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- GLfloat texCoords[] = { 0, 0, 1, 0, 0, 1,
- 1, 0, 1, 1, 0, 1 };
-
- GLfloat vertexCoords[] = { -1, -1, 1, -1, -1, 1,
- 1, -1, 1, 1, -1, 1 };
-
- m_program->bind();
-
- m_context->functions()->glEnableVertexAttribArray(m_vertexAttribute);
- m_context->functions()->glEnableVertexAttribArray(m_texCoordsAttribute);
-
- m_context->functions()->glVertexAttribPointer(m_vertexAttribute, 2, GL_FLOAT, GL_FALSE, 0, vertexCoords);
- m_context->functions()->glVertexAttribPointer(m_texCoordsAttribute, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
-
- glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
-
- glDrawArrays(GL_TRIANGLES, 0, 6);
-
- glBindTexture(GL_TEXTURE_2D, 0);
-
- m_context->functions()->glDisableVertexAttribArray(m_vertexAttribute);
- m_context->functions()->glDisableVertexAttribArray(m_texCoordsAttribute);
-
- m_program->release();
-
m_context->swapBuffers(this);
}
diff --git a/examples/opengl/paintedwindow/paintedwindow.h b/examples/opengl/paintedwindow/paintedwindow.h
index 9e1b43638c..9da9992a3e 100644
--- a/examples/opengl/paintedwindow/paintedwindow.h
+++ b/examples/opengl/paintedwindow/paintedwindow.h
@@ -20,11 +20,7 @@ private slots:
private:
void resizeEvent(QResizeEvent *);
+ void exposeEvent(QExposeEvent *);
QOpenGLContext *m_context;
- QOpenGLFramebufferObject *m_fbo;
- QOpenGLShaderProgram *m_program;
-
- GLuint m_vertexAttribute;
- GLuint m_texCoordsAttribute;
};
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>
diff --git a/src/gui/painting/qpaintdevice.h b/src/gui/painting/qpaintdevice.h
index 0b44990c69..95509a9daa 100644
--- a/src/gui/painting/qpaintdevice.h
+++ b/src/gui/painting/qpaintdevice.h
@@ -79,15 +79,6 @@ public:
bool paintingActive() const;
virtual QPaintEngine *paintEngine() const = 0;
-#if defined(Q_WS_QWS)
- static QWSDisplay *qwsDisplay();
-#endif
-
-#ifdef Q_WS_WIN
- virtual HDC getDC() const;
- virtual void releaseDC(HDC hdc) const;
-#endif
-
int width() const { return metric(PdmWidth); }
int height() const { return metric(PdmHeight); }
int widthMM() const { return metric(PdmWidthMM); }
@@ -96,9 +87,6 @@ public:
int logicalDpiY() const { return metric(PdmDpiY); }
int physicalDpiX() const { return metric(PdmPhysicalDpiX); }
int physicalDpiY() const { return metric(PdmPhysicalDpiY); }
-#ifdef QT_DEPRECATED
- QT_DEPRECATED int numColors() const { return metric(PdmNumColors); }
-#endif
int colorCount() const { return metric(PdmNumColors); }
int depth() const { return metric(PdmDepth); }