summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2016-07-28 12:20:23 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2016-07-29 07:21:10 +0000
commitdd3a08dd539a17e52bb8eec19c9aff27f4de7de4 (patch)
treed9f5b7ce0fcf64a3fd4565bfd417c2f35a6af71b
parenta89875cd69787a469446523429ff610b45504a72 (diff)
Make QOpenGLTextureBlitter public
Change QOpenGLTextureBlitter to be a public API, as it was originally intended. There are now significant external uses outside qtbase (C++ compositor examples in QtWayland), and the API is considered proven enough. [ChangeLog][QtGui] QOpenGLTextureBlitter, a utility class to draw textured quads, has been made public. Change-Id: If7a2c94e1494195e2aa375d214932fa7b4c78321 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
-rw-r--r--src/gui/kernel/qopenglwindow.cpp2
-rw-r--r--src/gui/opengl/opengl.pri2
-rw-r--r--src/gui/opengl/qopengltextureblitter.cpp193
-rw-r--r--src/gui/opengl/qopengltextureblitter.h (renamed from src/gui/opengl/qopengltextureblitter_p.h)34
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp6
-rw-r--r--src/platformsupport/platformcompositor/qopenglcompositor_p.h2
-rw-r--r--src/plugins/platforms/mirclient/qmirclientbackingstore.cpp4
-rw-r--r--tests/auto/gui/qopengl/tst_qopengl.cpp2
-rw-r--r--tests/manual/qopenglcontext/qopenglcontextwindow.h2
-rw-r--r--tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp4
-rw-r--r--tests/manual/qopengltextureblitter/qopengltextureblitwindow.h2
11 files changed, 218 insertions, 35 deletions
diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp
index 8ab5c08442..e1bd3d11b2 100644
--- a/src/gui/kernel/qopenglwindow.cpp
+++ b/src/gui/kernel/qopenglwindow.cpp
@@ -42,7 +42,7 @@
#include <QtGui/QOpenGLFramebufferObject>
#include <QtGui/QOpenGLPaintDevice>
#include <QtGui/QOpenGLFunctions>
-#include <QtGui/private/qopengltextureblitter_p.h>
+#include <QtGui/QOpenGLTextureBlitter>
#include <QtGui/private/qopenglextensions_p.h>
#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/QMatrix4x4>
diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri
index b13f258fda..dfaf3042bc 100644
--- a/src/gui/opengl/opengl.pri
+++ b/src/gui/opengl/opengl.pri
@@ -32,7 +32,7 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
opengl/qopenglversionfunctionsfactory_p.h \
opengl/qopenglvertexarrayobject.h \
opengl/qopengldebug.h \
- opengl/qopengltextureblitter_p.h \
+ opengl/qopengltextureblitter.h \
opengl/qopengltexture.h \
opengl/qopengltexture_p.h \
opengl/qopengltexturehelper_p.h \
diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp
index 18ff0c4acf..2e74afcbc2 100644
--- a/src/gui/opengl/qopengltextureblitter.cpp
+++ b/src/gui/opengl/qopengltextureblitter.cpp
@@ -37,7 +37,7 @@
**
****************************************************************************/
-#include "qopengltextureblitter_p.h"
+#include "qopengltextureblitter.h"
#include <QtGui/QOpenGLBuffer>
#include <QtGui/QOpenGLShaderProgram>
@@ -51,6 +51,49 @@
QT_BEGIN_NAMESPACE
+/*!
+ \class QOpenGLTextureBlitter
+ \brief The QOpenGLTextureBlitter class provides a convenient way to draw textured quads via OpenGL.
+ \since 5.8
+ \ingroup painting-3D
+ \inmodule QtGui
+
+ Drawing textured quads, in order to get the contents of a texture
+ onto the screen, is a common operation when developing 2D user
+ interfaces. QOpenGLTextureBlitter provides a convenience class to
+ avoid repeating vertex data, shader sources, buffer and program
+ management and matrix calculations.
+
+ For example, a QOpenGLWidget subclass can do the following to draw
+ the contents rendered into a framebuffer at the pixel position \c{(x, y)}:
+
+ \code
+ void OpenGLWidget::initializeGL()
+ {
+ m_blitter.create();
+ m_fbo = new QOpenGLFramebufferObject(size);
+ }
+
+ void OpenGLWidget::paintGL()
+ {
+ m_fbo->bind();
+ // update offscreen content
+ m_fbo->release();
+
+ m_blitter.bind();
+ const QRect targetRect(QPoint(x, y), m_fbo->size());
+ const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, QRect(QPoint(0, 0), m_fbo->size()));
+ m_blitter.blit(m_fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft);
+ m_blitter.release();
+ }
+ \endcode
+
+ The blitter implements GLSL shaders both for GLSL 1.00 (suitable
+ for OpenGL (ES) 2.x and compatibility profiles of newer OpenGL
+ versions) and version 150 (suitable for core profile contexts with
+ OpenGL 3.2 and newer).
+ */
+
static const char vertex_shader150[] =
"#version 150 core\n"
"in vec3 vertexCoord;"
@@ -309,16 +352,44 @@ bool QOpenGLTextureBlitterPrivate::buildProgram(ProgramIndex idx, const char *vs
return true;
}
+/*!
+ Constructs a new QOpenGLTextureBlitter instance.
+
+ \note no graphics resources are initialized in the
+ constructor. This makes it safe to place plain
+ QOpenGLTextureBlitter members into classes because the actual
+ initialization that depends on the OpenGL context happens only in
+ create().
+ */
QOpenGLTextureBlitter::QOpenGLTextureBlitter()
: d_ptr(new QOpenGLTextureBlitterPrivate)
{
}
+/*!
+ Destructs the instance.
+
+ \note When the OpenGL context - or a context sharing resources
+ with it - that was current when calling create() is not current,
+ graphics resources will not be released. Therefore, it is
+ recommended to call destroy() manually instead of relying on the
+ destructor to perform OpenGL resource cleanup.
+ */
QOpenGLTextureBlitter::~QOpenGLTextureBlitter()
{
destroy();
}
+/*!
+ Initializes the graphics resources used by the blitter.
+
+ \return \c true if successful, \c false if there was a
+ failure. Failures can occur when there is no OpenGL context
+ current on the current thread, or when shader compilation fails
+ for some reason.
+
+ \sa isCreated(), destroy()
+ */
bool QOpenGLTextureBlitter::create()
{
QOpenGLContext *currentContext = QOpenGLContext::currentContext();
@@ -358,12 +429,26 @@ bool QOpenGLTextureBlitter::create()
return true;
}
+/*!
+ \return \c true if create() was called and succeeded. \c false otherwise.
+
+ \sa create(), destroy()
+ */
bool QOpenGLTextureBlitter::isCreated() const
{
Q_D(const QOpenGLTextureBlitter);
return d->programs[QOpenGLTextureBlitterPrivate::TEXTURE_2D].glProgram;
}
+/*!
+ Frees all graphics resources held by the blitter. Assumes that
+ the OpenGL context, or another context sharing resources with it,
+ that was current on the thread when invoking create() is current.
+
+ The function has no effect when the blitter is not in created state.
+
+ \sa create()
+ */
void QOpenGLTextureBlitter::destroy()
{
if (!isCreated())
@@ -376,12 +461,29 @@ void QOpenGLTextureBlitter::destroy()
d->vao.reset();
}
+/*!
+ \return \c true when bind() accepts \c GL_TEXTURE_EXTERNAL_OES as
+ its target argument.
+
+ \sa bind(), blit()
+ */
bool QOpenGLTextureBlitter::supportsExternalOESTarget() const
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
return ctx && ctx->isOpenGLES() && ctx->hasExtension("GL_OES_EGL_image_external");
}
+/*!
+ Binds the graphics resources used by the blitter. This must be
+ called before calling blit(). Code modifying the OpenGL state
+ should be avoided between the call to bind() and blit() because
+ otherwise conflicts may arise.
+
+ \a target is the texture target for the source texture and must be
+ either \c GL_TEXTURE_2D or \c GL_OES_EGL_image_external.
+
+ \sa release(), blit()
+ */
void QOpenGLTextureBlitter::bind(GLenum target)
{
Q_D(QOpenGLTextureBlitter);
@@ -404,6 +506,11 @@ void QOpenGLTextureBlitter::bind(GLenum target)
d->textureBuffer.release();
}
+/*!
+ Unbinds the graphics resources used by the blitter.
+
+ \sa bind()
+ */
void QOpenGLTextureBlitter::release()
{
Q_D(QOpenGLTextureBlitter);
@@ -412,18 +519,64 @@ void QOpenGLTextureBlitter::release()
d->vao->release();
}
-void QOpenGLTextureBlitter::setSwizzleRB(bool swizzle)
+/*!
+ Enables or disables swizzling for the red and blue color
+ channels. An BGRA to RGBA conversion (occurring in the shader on
+ the GPU, instead of a slow CPU-side transformation) can be useful
+ when the source texture contains data from a QImage with a format
+ like QImage::Format_ARGB32 which maps to BGRA on little endian
+ systems.
+
+ By default the red-blue swizzle is disabled since this is what a
+ texture attached to an framebuffer object or a texture based on a
+ byte ordered QImage format (like QImage::Format_RGBA8888) needs.
+ */
+void QOpenGLTextureBlitter::setRedBlueSwizzle(bool swizzle)
{
Q_D(QOpenGLTextureBlitter);
d->swizzle = swizzle;
}
+/*!
+ Changes the opacity. The default opacity is 1.0.
+
+ \note the blitter does not alter the blend state. It is up to the
+ caller of blit() to ensure the correct blend settings are active.
+ */
void QOpenGLTextureBlitter::setOpacity(float opacity)
{
Q_D(QOpenGLTextureBlitter);
d->opacity = opacity;
}
+/*!
+ \enum QOpenGLTextureBlitter::Origin
+
+ \value OriginBottomLeft Indicates that the data in the texture
+ follows the OpenGL convention of coordinate systems, meaning Y is
+ running from bottom to top.
+
+ \value OriginTopLeft Indicates that the data in the texture has Y
+ running from top to bottom, which is typical with regular,
+ unflipped image data.
+
+ \sa blit()
+ */
+
+/*!
+ Performs the blit with the source texture \a texture.
+
+ \a targetTransform specifies the transformation applied. This is
+ usually generated by the targetTransform() helper function.
+
+ \a sourceOrigin specifies if the image data needs flipping. When
+ \a texture corresponds to a texture attached to an FBO pass
+ OriginBottomLeft. On the other hand, when \a texture is based on
+ unflipped image data, pass OriginTopLeft. This is more efficient
+ than using QImage::mirrored().
+
+ \sa targetTransform(), Origin, bind()
+ */
void QOpenGLTextureBlitter::blit(GLuint texture,
const QMatrix4x4 &targetTransform,
Origin sourceOrigin)
@@ -432,6 +585,19 @@ void QOpenGLTextureBlitter::blit(GLuint texture,
d->blit(texture,targetTransform, sourceOrigin);
}
+/*!
+ Performs the blit with the source texture \a texture.
+
+ \a targetTransform specifies the transformation applied. This is
+ usually generated by the targetTransform() helper function.
+
+ \a sourceTransform specifies the transformation applied to the
+ source. This allows using only a sub-rect of the source
+ texture. This is usually generated by the sourceTransform() helper
+ function.
+
+ \sa sourceTransform(), targetTransform(), Origin, bind()
+ */
void QOpenGLTextureBlitter::blit(GLuint texture,
const QMatrix4x4 &targetTransform,
const QMatrix3x3 &sourceTransform)
@@ -440,6 +606,18 @@ void QOpenGLTextureBlitter::blit(GLuint texture,
d->blit(texture, targetTransform, sourceTransform);
}
+/*!
+ Calculates a target transform suitable for blit().
+
+ \a target is the target rectangle in pixels. \a viewport describes
+ the source dimensions and will in most cases be set to (0, 0,
+ image width, image height).
+
+ For unscaled output the size of \a target and \viewport should
+ match.
+
+ \sa blit()
+ */
QMatrix4x4 QOpenGLTextureBlitter::targetTransform(const QRectF &target,
const QRect &viewport)
{
@@ -460,6 +638,17 @@ QMatrix4x4 QOpenGLTextureBlitter::targetTransform(const QRectF &target,
return matrix;
}
+/*!
+ Calculates a 3x3 matrix suitable as the input to blit(). This is
+ used when only a part of the texture is to be used in the blit.
+
+ \a subTexture is the desired source rectangle in pixels, \a
+ textureSize is the full width and height of the texture data. \a
+ origin specifies the orientation of the image data when it comes
+ to the Y axis.
+
+ \sa blit(), Origin
+ */
QMatrix3x3 QOpenGLTextureBlitter::sourceTransform(const QRectF &subTexture,
const QSize &textureSize,
Origin origin)
diff --git a/src/gui/opengl/qopengltextureblitter_p.h b/src/gui/opengl/qopengltextureblitter.h
index cc6499672d..2f7c6b1a0a 100644
--- a/src/gui/opengl/qopengltextureblitter_p.h
+++ b/src/gui/opengl/qopengltextureblitter.h
@@ -37,29 +37,21 @@
**
****************************************************************************/
-#ifndef QOPENGLTEXTUREBLITTER_P_H
-#define QOPENGLTEXTUREBLITTER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qtguiglobal_p.h>
+#ifndef QOPENGLTEXTUREBLITTER_H
+#define QOPENGLTEXTUREBLITTER_H
+
+#include <QtGui/qtguiglobal.h>
+
+#ifndef QT_NO_OPENGL
+
#include <QtGui/qopengl.h>
#include <QtGui/QMatrix3x3>
+#include <QtGui/QMatrix4x4>
QT_BEGIN_NAMESPACE
class QOpenGLTextureBlitterPrivate;
-
class Q_GUI_EXPORT QOpenGLTextureBlitter
{
public:
@@ -80,7 +72,7 @@ public:
void bind(GLenum target = GL_TEXTURE_2D);
void release();
- void setSwizzleRB(bool swizzle);
+ void setRedBlueSwizzle(bool swizzle);
void setOpacity(float opacity);
void blit(GLuint texture, const QMatrix4x4 &targetTransform, Origin sourceOrigin);
@@ -90,11 +82,13 @@ public:
static QMatrix3x3 sourceTransform(const QRectF &subTexture, const QSize &textureSize, Origin origin);
private:
- Q_DISABLE_COPY(QOpenGLTextureBlitter);
- Q_DECLARE_PRIVATE(QOpenGLTextureBlitter);
+ Q_DISABLE_COPY(QOpenGLTextureBlitter)
+ Q_DECLARE_PRIVATE(QOpenGLTextureBlitter)
QScopedPointer<QOpenGLTextureBlitterPrivate> d_ptr;
};
QT_END_NAMESPACE
-#endif //QOPENGLTEXTUREBLITTER_P_H
+#endif
+
+#endif //QOPENGLTEXTUREBLITTER_H
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index d967a168d2..e2c5a82ffc 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -49,7 +49,7 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFunctions>
#ifndef QT_NO_OPENGL
-#include <QtGui/private/qopengltextureblitter_p.h>
+#include <QtGui/qopengltextureblitter.h>
#endif
#include <qpa/qplatformgraphicsbuffer.h>
#include <qpa/qplatformgraphicsbufferhelper.h>
@@ -389,7 +389,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
if (textureId) {
if (d_ptr->needsSwizzle)
- d_ptr->blitter->setSwizzleRB(true);
+ d_ptr->blitter->setRedBlueSwizzle(true);
// The backingstore is for the entire tlw.
// In case of native children offset tells the position relative to the tlw.
const QRect srcRect = toBottomLeftRect(deviceWindowRect.translated(offset), d_ptr->textureSize.height());
@@ -398,7 +398,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
origin);
d_ptr->blitter->blit(textureId, QMatrix4x4(), source);
if (d_ptr->needsSwizzle)
- d_ptr->blitter->setSwizzleRB(false);
+ d_ptr->blitter->setRedBlueSwizzle(false);
}
// Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
diff --git a/src/platformsupport/platformcompositor/qopenglcompositor_p.h b/src/platformsupport/platformcompositor/qopenglcompositor_p.h
index 2c34fba409..90651b807f 100644
--- a/src/platformsupport/platformcompositor/qopenglcompositor_p.h
+++ b/src/platformsupport/platformcompositor/qopenglcompositor_p.h
@@ -52,7 +52,7 @@
//
#include <QtCore/QTimer>
-#include <QtGui/private/qopengltextureblitter_p.h>
+#include <QtGui/QOpenGLTextureBlitter>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp b/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp
index f80d85842a..a4bb8864ab 100644
--- a/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp
@@ -43,7 +43,7 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLTexture>
#include <QtGui/QMatrix4x4>
-#include <QtGui/private/qopengltextureblitter_p.h>
+#include <QtGui/qopengltextureblitter.h>
#include <QtGui/qopenglfunctions.h>
QMirClientBackingStore::QMirClientBackingStore(QWindow* window)
@@ -76,7 +76,7 @@ void QMirClientBackingStore::flush(QWindow* window, const QRegion& region, const
mBlitter->create();
mBlitter->bind();
- mBlitter->setSwizzleRB(true);
+ mBlitter->setRedBlueSwizzle(true);
mBlitter->blit(mTexture->textureId(), QMatrix4x4(), QOpenGLTextureBlitter::OriginTopLeft);
mBlitter->release();
diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp
index 15244744bf..ed48a4978a 100644
--- a/tests/auto/gui/qopengl/tst_qopengl.cpp
+++ b/tests/auto/gui/qopengl/tst_qopengl.cpp
@@ -41,7 +41,7 @@
#include <QtGui/QOffscreenSurface>
#include <QtGui/QGenericMatrix>
#include <QtGui/QMatrix4x4>
-#include <QtGui/private/qopengltextureblitter_p.h>
+#include <QtGui/qopengltextureblitter.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qopenglextensions_p.h>
#include <qpa/qplatformintegration.h>
diff --git a/tests/manual/qopenglcontext/qopenglcontextwindow.h b/tests/manual/qopenglcontext/qopenglcontextwindow.h
index f436d1af0e..37ff1b2082 100644
--- a/tests/manual/qopenglcontext/qopenglcontextwindow.h
+++ b/tests/manual/qopenglcontext/qopenglcontextwindow.h
@@ -31,9 +31,9 @@
#include <QtGui/QWindow>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLTextureBlitter>
#include <QtGui/QImage>
#include <QtCore/QVariant>
-#include <QtGui/private/qopengltextureblitter_p.h>
class QOpenGLContextWindow : public QWindow
{
diff --git a/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp b/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp
index 63ac1e4e66..f4e093a967 100644
--- a/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp
+++ b/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp
@@ -123,9 +123,9 @@ void QOpenGLTextureBlitWindow::render()
m_blitter.blit(texture.textureId(), topRightOriginTopLeftVertex, topLeftOrigin);
m_blitter.blit(texture_mirrored.textureId(), bottomLeftOriginTopLeftVertex, topLeftOrigin);
- m_blitter.setSwizzleRB(true);
+ m_blitter.setRedBlueSwizzle(true);
m_blitter.blit(texture.textureId(), bottomRightOriginTopLeftVertex, texTopLeftOriginTopLeft);
- m_blitter.setSwizzleRB(false);
+ m_blitter.setRedBlueSwizzle(false);
m_blitter.release();
if (m_blitter.supportsExternalOESTarget()) {
diff --git a/tests/manual/qopengltextureblitter/qopengltextureblitwindow.h b/tests/manual/qopengltextureblitter/qopengltextureblitwindow.h
index 957d833ef3..0912f096e4 100644
--- a/tests/manual/qopengltextureblitter/qopengltextureblitwindow.h
+++ b/tests/manual/qopengltextureblitter/qopengltextureblitwindow.h
@@ -31,7 +31,7 @@
#include <QtGui/QWindow>
#include <QtGui/QOpenGLContext>
-#include <QtGui/private/qopengltextureblitter_p.h>
+#include <QtGui/QOpenGLTextureBlitter>
class QOpenGLTextureBlitWindow : public QWindow
{