summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/platformsupport/platformcompositor/qopenglcompositor.cpp41
-rw-r--r--src/platformsupport/platformcompositor/qopenglcompositor_p.h7
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscursor.cpp9
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscursor_p.h3
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsscreen.cpp25
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsscreen_p.h1
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfswindow.cpp6
7 files changed, 75 insertions, 17 deletions
diff --git a/src/platformsupport/platformcompositor/qopenglcompositor.cpp b/src/platformsupport/platformcompositor/qopenglcompositor.cpp
index 610619a4e4..0f4946f81a 100644
--- a/src/platformsupport/platformcompositor/qopenglcompositor.cpp
+++ b/src/platformsupport/platformcompositor/qopenglcompositor.cpp
@@ -40,7 +40,6 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFramebufferObject>
#include <QtGui/QWindow>
-#include <QtGui/QMatrix4x4>
#include <qpa/qplatformbackingstore.h>
#include "qopenglcompositor_p.h"
@@ -78,7 +77,8 @@ static QOpenGLCompositor *compositor = 0;
QOpenGLCompositor::QOpenGLCompositor()
: m_context(0),
- m_targetWindow(0)
+ m_targetWindow(0),
+ m_rotation(0)
{
Q_ASSERT(!compositor);
m_updateTimer.setSingleShot(true);
@@ -93,10 +93,19 @@ QOpenGLCompositor::~QOpenGLCompositor()
compositor = 0;
}
-void QOpenGLCompositor::setTarget(QOpenGLContext *context, QWindow *targetWindow)
+void QOpenGLCompositor::setTarget(QOpenGLContext *context, QWindow *targetWindow,
+ const QRect &nativeTargetGeometry)
{
m_context = context;
m_targetWindow = targetWindow;
+ m_nativeTargetGeometry = nativeTargetGeometry;
+}
+
+void QOpenGLCompositor::setRotation(int degrees)
+{
+ m_rotation = degrees;
+ m_rotationMatrix.setToIdentity();
+ m_rotationMatrix.rotate(degrees, 0, 0, 1);
}
void QOpenGLCompositor::update()
@@ -109,7 +118,7 @@ QImage QOpenGLCompositor::grab()
{
Q_ASSERT(m_context && m_targetWindow);
m_context->makeCurrent(m_targetWindow);
- QScopedPointer<QOpenGLFramebufferObject> fbo(new QOpenGLFramebufferObject(m_targetWindow->geometry().size()));
+ QScopedPointer<QOpenGLFramebufferObject> fbo(new QOpenGLFramebufferObject(m_nativeTargetGeometry.size()));
renderAll(fbo.data());
return fbo->toImage();
}
@@ -127,9 +136,7 @@ void QOpenGLCompositor::renderAll(QOpenGLFramebufferObject *fbo)
fbo->bind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-
- const QRect targetWindowRect(QPoint(0, 0), m_targetWindow->geometry().size());
- glViewport(0, 0, targetWindowRect.width(), targetWindowRect.height());
+ glViewport(0, 0, m_nativeTargetGeometry.width(), m_nativeTargetGeometry.height());
if (!m_blitter.isCreated())
m_blitter.create();
@@ -181,7 +188,8 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
topLeftRect.width(), topLeftRect.height());
}
-static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect, QOpenGLTextureBlitter *blitter)
+static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect,
+ QOpenGLTextureBlitter *blitter, QMatrix4x4 *rotationMatrix)
{
const QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty())
@@ -191,7 +199,10 @@ static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRe
const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
- const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(clippedRectInWindow, targetWindowRect);
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(clippedRectInWindow, targetWindowRect);
+ if (rotationMatrix)
+ target = *rotationMatrix * target;
+
const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(srcRect, rectInWindow.size(),
QOpenGLTextureBlitter::OriginBottomLeft);
@@ -219,25 +230,29 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window)
if (textures->count() > 1 && i == textures->count() - 1) {
// Backingstore for a widget with QOpenGLWidget subwidgets
blend.set(true);
- const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect);
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect);
+ if (m_rotation)
+ target = m_rotationMatrix * target;
m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
} else if (textures->count() == 1) {
// A regular QWidget window
const bool translucent = window->sourceWindow()->requestedFormat().alphaBufferSize() > 0;
blend.set(translucent);
- const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect);
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect);
+ if (m_rotation)
+ target = m_rotationMatrix * target;
m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
} else if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
// Texture from an FBO belonging to a QOpenGLWidget
blend.set(false);
- clippedBlit(textures, i, targetWindowRect, &m_blitter);
+ clippedBlit(textures, i, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr);
}
}
for (int i = 0; i < textures->count(); ++i) {
if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
blend.set(true);
- clippedBlit(textures, i, targetWindowRect, &m_blitter);
+ clippedBlit(textures, i, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr);
}
}
diff --git a/src/platformsupport/platformcompositor/qopenglcompositor_p.h b/src/platformsupport/platformcompositor/qopenglcompositor_p.h
index 90651b807f..dece41f676 100644
--- a/src/platformsupport/platformcompositor/qopenglcompositor_p.h
+++ b/src/platformsupport/platformcompositor/qopenglcompositor_p.h
@@ -53,6 +53,7 @@
#include <QtCore/QTimer>
#include <QtGui/QOpenGLTextureBlitter>
+#include <QtGui/QMatrix4x4>
QT_BEGIN_NAMESPACE
@@ -78,7 +79,8 @@ public:
static QOpenGLCompositor *instance();
static void destroy();
- void setTarget(QOpenGLContext *context, QWindow *window);
+ void setTarget(QOpenGLContext *context, QWindow *window, const QRect &nativeTargetGeometry);
+ void setRotation(int degrees);
QOpenGLContext *context() const { return m_context; }
QWindow *targetWindow() const { return m_targetWindow; }
@@ -106,6 +108,9 @@ private:
QOpenGLContext *m_context;
QWindow *m_targetWindow;
+ QRect m_nativeTargetGeometry;
+ int m_rotation;
+ QMatrix4x4 m_rotationMatrix;
QTimer m_updateTimer;
QOpenGLTextureBlitter m_blitter;
QList<QOpenGLCompositorWindow *> m_windows;
diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
index ffee21a9b0..7c1f11372a 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
@@ -72,6 +72,10 @@ QEglFSCursor::QEglFSCursor(QPlatformScreen *screen)
if (!m_visible)
return;
+ int rotation = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ROTATION");
+ if (rotation)
+ m_rotationMatrix.rotate(rotation, 0, 0, 1);
+
// Try to load the cursor atlas. If this fails, m_visible is set to false and
// paintOnScreen() and setCurrentCursor() become no-ops.
initCursorAtlas();
@@ -129,9 +133,10 @@ void QEglFSCursor::createShaderPrograms()
"attribute highp vec2 vertexCoordEntry;\n"
"attribute highp vec2 textureCoordEntry;\n"
"varying highp vec2 textureCoord;\n"
+ "uniform highp mat4 mat;\n"
"void main() {\n"
" textureCoord = textureCoordEntry;\n"
- " gl_Position = vec4(vertexCoordEntry, 1.0, 1.0);\n"
+ " gl_Position = mat * vec4(vertexCoordEntry, 1.0, 1.0);\n"
"}\n";
static const char *textureFragmentProgram =
@@ -149,6 +154,7 @@ void QEglFSCursor::createShaderPrograms()
m_program->link();
m_textureEntry = m_program->uniformLocation("texture");
+ m_matEntry = m_program->uniformLocation("mat");
}
void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image)
@@ -492,6 +498,7 @@ void QEglFSCursor::draw(const QRectF &r)
m_program->setAttributeArray(1, textureCoordinates, 2);
m_program->setUniformValue(m_textureEntry, 0);
+ m_program->setUniformValue(m_matEntry, m_rotationMatrix);
glDisable(GL_CULL_FACE);
glFrontFace(GL_CCW);
diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
index bb30d53d6c..f72e4c0374 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
@@ -54,6 +54,7 @@
#include "qeglfsglobal.h"
#include <qpa/qplatformcursor.h>
#include <qpa/qplatformscreen.h>
+#include <QtGui/QMatrix4x4>
#include <QtGui/QOpenGLFunctions>
#include <QtGui/private/qinputdevicemanager_p.h>
@@ -138,8 +139,10 @@ private:
QEglFSScreen *m_screen;
QOpenGLShaderProgram *m_program;
int m_textureEntry;
+ int m_matEntry;
QEglFSCursorDeviceListener *m_deviceListener;
bool m_updateRequested;
+ QMatrix4x4 m_rotationMatrix;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp
index d636a783ec..47ef2f64e7 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp
@@ -65,6 +65,31 @@ QEglFSScreen::~QEglFSScreen()
QRect QEglFSScreen::geometry() const
{
+ QRect r = geometryForSurface();
+
+ static int rotation = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ROTATION");
+ switch (rotation) {
+ case 0:
+ case 180:
+ case -180:
+ break;
+ case 90:
+ case -90: {
+ int h = r.height();
+ r.setHeight(r.width());
+ r.setWidth(h);
+ break;
+ }
+ default:
+ qWarning("Invalid rotation %d specified in QT_QPA_EGLFS_ROTATION", rotation);
+ break;
+ }
+
+ return r;
+}
+
+QRect QEglFSScreen::geometryForSurface() const
+{
return QRect(QPoint(0, 0), qt_egl_device_integration()->screenSize());
}
diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h b/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h
index 092d853ffd..232525fae3 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h
@@ -68,6 +68,7 @@ public:
~QEglFSScreen();
QRect geometry() const Q_DECL_OVERRIDE;
+ QRect geometryForSurface() const;
int depth() const Q_DECL_OVERRIDE;
QImage::Format format() const Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
index f602c1b976..74723955c6 100644
--- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
@@ -142,7 +142,8 @@ void QEglFSWindow::create()
context->setScreen(window()->screen());
if (Q_UNLIKELY(!context->create()))
qFatal("EGLFS: Failed to create compositing context");
- compositor->setTarget(context, window());
+ compositor->setTarget(context, window(), screen->geometryForSurface());
+ compositor->setRotation(qEnvironmentVariableIntValue("QT_QPA_EGLFS_ROTATION"));
// If there is a "root" window into which raster and QOpenGLWidget content is
// composited, all other contexts must share with its context.
if (!qt_gl_global_share_context()) {
@@ -189,7 +190,8 @@ void QEglFSWindow::resetSurface()
m_config = QEglFSDeviceIntegration::chooseConfig(display, platformFormat);
m_format = q_glFormatFromConfig(display, m_config, platformFormat);
- m_window = qt_egl_device_integration()->createNativeWindow(this, screen()->geometry().size(), m_format);
+ const QSize surfaceSize = screen()->geometryForSurface().size();
+ m_window = qt_egl_device_integration()->createNativeWindow(this, surfaceSize, m_format);
m_surface = eglCreateWindowSurface(display, m_config, m_window, NULL);
}