xref: /OK3568_Linux_fs/buildroot/package/qt5/qt5base/0014-linuxfb-Support-rotate.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593SmuzhiyunFrom cc8e902f0511700b797fed870b1a7e6a61e84711 Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com>
3*4882a593SmuzhiyunDate: Mon, 29 Apr 2019 12:11:42 +0800
4*4882a593SmuzhiyunSubject: [PATCH 14/28] linuxfb: Support rotate
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunBase on:
7*4882a593Smuzhiyunhttps://borkedlabs.com/blog/2015/06-01-qt5-linuxfb-rotation-for-lcds/
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunUsage:
10*4882a593Smuzhiyunexport QT_QPA_PLATFORM=linuxfb:rotation=90
11*4882a593Smuzhiyun
12*4882a593SmuzhiyunConflicts:
13*4882a593Smuzhiyun    src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp
14*4882a593Smuzhiyun
15*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
16*4882a593SmuzhiyunSigned-off-by: Ziyuan Xu <xzy.xu@rock-chips.com>
17*4882a593Smuzhiyun---
18*4882a593Smuzhiyun .../platforms/linuxfb/qlinuxfbdrmscreen.cpp   | 33 +++++++++++++++++--
19*4882a593Smuzhiyun .../platforms/linuxfb/qlinuxfbdrmscreen.h     |  2 ++
20*4882a593Smuzhiyun .../platforms/linuxfb/qlinuxfbscreen.cpp      | 33 ++++++++++++++++---
21*4882a593Smuzhiyun .../platforms/linuxfb/qlinuxfbscreen.h        |  2 ++
22*4882a593Smuzhiyun 4 files changed, 62 insertions(+), 8 deletions(-)
23*4882a593Smuzhiyun
24*4882a593Smuzhiyundiff --git a/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp
25*4882a593Smuzhiyunindex 29d146f4..0c4f6d2c 100644
26*4882a593Smuzhiyun--- a/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp
27*4882a593Smuzhiyun+++ b/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp
28*4882a593Smuzhiyun@@ -49,6 +49,7 @@
29*4882a593Smuzhiyun #include <QLoggingCategory>
30*4882a593Smuzhiyun #include <QGuiApplication>
31*4882a593Smuzhiyun #include <QPainter>
32*4882a593Smuzhiyun+#include <QtCore/QRegularExpression>
33*4882a593Smuzhiyun #include <QtFbSupport/private/qfbcursor_p.h>
34*4882a593Smuzhiyun #include <QtFbSupport/private/qfbwindow_p.h>
35*4882a593Smuzhiyun #include <QtKmsSupport/private/qkmsdevice_p.h>
36*4882a593Smuzhiyun@@ -408,9 +409,16 @@ void QLinuxFbDevice::swapBuffers(Output *output)
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun QLinuxFbDrmScreen::QLinuxFbDrmScreen(const QStringList &args)
39*4882a593Smuzhiyun     : m_screenConfig(nullptr),
40*4882a593Smuzhiyun-      m_device(nullptr)
41*4882a593Smuzhiyun+      m_device(nullptr),
42*4882a593Smuzhiyun+      m_rotation(0)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun-    Q_UNUSED(args);
45*4882a593Smuzhiyun+    QRegularExpression rotationRx(QLatin1String("rotation=(0|90|180|270)"));
46*4882a593Smuzhiyun+
47*4882a593Smuzhiyun+    for (const QString &arg : qAsConst(args)) {
48*4882a593Smuzhiyun+        QRegularExpressionMatch match;
49*4882a593Smuzhiyun+        if (arg.contains(rotationRx, &match))
50*4882a593Smuzhiyun+            m_rotation = match.captured(1).toInt();
51*4882a593Smuzhiyun+    }
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun QLinuxFbDrmScreen::~QLinuxFbDrmScreen()
55*4882a593Smuzhiyun@@ -440,6 +448,12 @@ bool QLinuxFbDrmScreen::initialize()
56*4882a593Smuzhiyun     QLinuxFbDevice::Output *output(m_device->output(0));
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun     mGeometry = QRect(QPoint(0, 0), output->currentRes());
59*4882a593Smuzhiyun+    if(m_rotation % 180) {
60*4882a593Smuzhiyun+        int tmp = mGeometry.width();
61*4882a593Smuzhiyun+        mGeometry.setWidth(mGeometry.height());
62*4882a593Smuzhiyun+        mGeometry.setHeight(tmp);
63*4882a593Smuzhiyun+    }
64*4882a593Smuzhiyun+
65*4882a593Smuzhiyun     mDepth = depthForDrmFormat(output->kmsOutput.drm_format);
66*4882a593Smuzhiyun     mFormat = formatForDrmFormat(output->kmsOutput.drm_format);
67*4882a593Smuzhiyun     mPhysicalSize = output->kmsOutput.physical_size;
68*4882a593Smuzhiyun@@ -475,8 +489,21 @@ QRegion QLinuxFbDrmScreen::doRedraw()
69*4882a593Smuzhiyun     // Image has alpha but no need for blending at this stage.
70*4882a593Smuzhiyun     // Do not waste time with the default SourceOver.
71*4882a593Smuzhiyun     pntr.setCompositionMode(QPainter::CompositionMode_Source);
72*4882a593Smuzhiyun-    for (const QRect &rect : qAsConst(output->dirty[output->backFb]))
73*4882a593Smuzhiyun+    for (const QRect &rect : qAsConst(output->dirty[output->backFb])) {
74*4882a593Smuzhiyun+        if(m_rotation) {
75*4882a593Smuzhiyun+            if(m_rotation == 180)
76*4882a593Smuzhiyun+                pntr.translate(mGeometry.width()/2, mGeometry.height()/2);
77*4882a593Smuzhiyun+            else
78*4882a593Smuzhiyun+                pntr.translate(mGeometry.height()/2, mGeometry.width()/2);
79*4882a593Smuzhiyun+
80*4882a593Smuzhiyun+            pntr.rotate(m_rotation);
81*4882a593Smuzhiyun+            pntr.translate(-mGeometry.width()/2, -mGeometry.height()/2);
82*4882a593Smuzhiyun+        }
83*4882a593Smuzhiyun+
84*4882a593Smuzhiyun         pntr.drawImage(rect, mScreenImage, rect);
85*4882a593Smuzhiyun+
86*4882a593Smuzhiyun+        pntr.resetTransform();
87*4882a593Smuzhiyun+    }
88*4882a593Smuzhiyun     pntr.end();
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun     output->dirty[output->backFb] = QRegion();
91*4882a593Smuzhiyundiff --git a/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.h
92*4882a593Smuzhiyunindex 50a95767..4065392d 100644
93*4882a593Smuzhiyun--- a/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.h
94*4882a593Smuzhiyun+++ b/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.h
95*4882a593Smuzhiyun@@ -61,6 +61,8 @@ public:
96*4882a593Smuzhiyun private:
97*4882a593Smuzhiyun     QKmsScreenConfig *m_screenConfig;
98*4882a593Smuzhiyun     QLinuxFbDevice *m_device;
99*4882a593Smuzhiyun+
100*4882a593Smuzhiyun+    int m_rotation;
101*4882a593Smuzhiyun };
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun QT_END_NAMESPACE
104*4882a593Smuzhiyundiff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
105*4882a593Smuzhiyunindex cb8962d4..40381fcb 100644
106*4882a593Smuzhiyun--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
107*4882a593Smuzhiyun+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
108*4882a593Smuzhiyun@@ -287,7 +287,7 @@ static void blankScreen(int fd, bool on)
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun QLinuxFbScreen::QLinuxFbScreen(const QStringList &args)
112*4882a593Smuzhiyun-    : mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0)
113*4882a593Smuzhiyun+    : mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0), mRotation(0)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun     mMmap.data = 0;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun@@ -313,6 +313,7 @@ bool QLinuxFbScreen::initialize()
118*4882a593Smuzhiyun     QRegularExpression mmSizeRx(QLatin1String("mmsize=(\\d+)x(\\d+)"));
119*4882a593Smuzhiyun     QRegularExpression sizeRx(QLatin1String("size=(\\d+)x(\\d+)"));
120*4882a593Smuzhiyun     QRegularExpression offsetRx(QLatin1String("offset=(\\d+)x(\\d+)"));
121*4882a593Smuzhiyun+    QRegularExpression rotationRx(QLatin1String("rotation=(0|90|180|270)"));
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun     QString fbDevice, ttyDevice;
124*4882a593Smuzhiyun     QSize userMmSize;
125*4882a593Smuzhiyun@@ -334,6 +335,8 @@ bool QLinuxFbScreen::initialize()
126*4882a593Smuzhiyun             ttyDevice = match.captured(1);
127*4882a593Smuzhiyun         else if (arg.contains(fbRx, &match))
128*4882a593Smuzhiyun             fbDevice = match.captured(1);
129*4882a593Smuzhiyun+        else if (arg.contains(rotationRx, &match))
130*4882a593Smuzhiyun+            mRotation = match.captured(1).toInt();
131*4882a593Smuzhiyun     }
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun     if (fbDevice.isEmpty()) {
134*4882a593Smuzhiyun@@ -372,9 +375,16 @@ bool QLinuxFbScreen::initialize()
135*4882a593Smuzhiyun     mDepth = determineDepth(vinfo);
136*4882a593Smuzhiyun     mBytesPerLine = finfo.line_length;
137*4882a593Smuzhiyun     QRect geometry = determineGeometry(vinfo, userGeometry);
138*4882a593Smuzhiyun+    QRect originalGeometry = geometry;
139*4882a593Smuzhiyun+    if(mRotation % 180) {
140*4882a593Smuzhiyun+        int tmp = geometry.width();
141*4882a593Smuzhiyun+        geometry.setWidth(geometry.height());
142*4882a593Smuzhiyun+        geometry.setHeight(tmp);
143*4882a593Smuzhiyun+    }
144*4882a593Smuzhiyun+
145*4882a593Smuzhiyun     mGeometry = QRect(QPoint(0, 0), geometry.size());
146*4882a593Smuzhiyun     mFormat = determineFormat(vinfo, mDepth);
147*4882a593Smuzhiyun-    mPhysicalSize = determinePhysicalSize(vinfo, userMmSize, geometry.size());
148*4882a593Smuzhiyun+    mPhysicalSize = determinePhysicalSize(vinfo, userMmSize, originalGeometry.size());
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun     // mmap the framebuffer
151*4882a593Smuzhiyun     mMmap.size = finfo.smem_len;
152*4882a593Smuzhiyun@@ -384,11 +394,11 @@ bool QLinuxFbScreen::initialize()
153*4882a593Smuzhiyun         return false;
154*4882a593Smuzhiyun     }
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun-    mMmap.offset = geometry.y() * mBytesPerLine + geometry.x() * mDepth / 8;
157*4882a593Smuzhiyun+    mMmap.offset = originalGeometry.y() * mBytesPerLine + originalGeometry.x() * mDepth / 8;
158*4882a593Smuzhiyun     mMmap.data = data + mMmap.offset;
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun     QFbScreen::initializeCompositor();
161*4882a593Smuzhiyun-    mFbScreenImage = QImage(mMmap.data, geometry.width(), geometry.height(), mBytesPerLine, mFormat);
162*4882a593Smuzhiyun+    mFbScreenImage = QImage(mMmap.data, originalGeometry.width(), originalGeometry.height(), mBytesPerLine, mFormat);
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun     mCursor = new QFbCursor(this);
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun@@ -413,9 +423,22 @@ QRegion QLinuxFbScreen::doRedraw()
167*4882a593Smuzhiyun         mBlitter = new QPainter(&mFbScreenImage);
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun     mBlitter->setCompositionMode(QPainter::CompositionMode_Source);
170*4882a593Smuzhiyun-    for (const QRect &rect : touched)
171*4882a593Smuzhiyun+    for (const QRect &rect : touched) {
172*4882a593Smuzhiyun+        if(mRotation) {
173*4882a593Smuzhiyun+            if(mRotation == 180)
174*4882a593Smuzhiyun+                mBlitter->translate(mGeometry.width()/2, mGeometry.height()/2);
175*4882a593Smuzhiyun+            else
176*4882a593Smuzhiyun+                mBlitter->translate(mGeometry.height()/2, mGeometry.width()/2);
177*4882a593Smuzhiyun+
178*4882a593Smuzhiyun+            mBlitter->rotate(mRotation);
179*4882a593Smuzhiyun+            mBlitter->translate(-mGeometry.width()/2, -mGeometry.height()/2);
180*4882a593Smuzhiyun+        }
181*4882a593Smuzhiyun+
182*4882a593Smuzhiyun         mBlitter->drawImage(rect, mScreenImage, rect);
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun+        mBlitter->resetTransform();
185*4882a593Smuzhiyun+    }
186*4882a593Smuzhiyun+
187*4882a593Smuzhiyun     return touched;
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun
190*4882a593Smuzhiyundiff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
191*4882a593Smuzhiyunindex c7ce455e..70ea02fa 100644
192*4882a593Smuzhiyun--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
193*4882a593Smuzhiyun+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
194*4882a593Smuzhiyun@@ -75,6 +75,8 @@ private:
195*4882a593Smuzhiyun     } mMmap;
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun     QPainter *mBlitter;
198*4882a593Smuzhiyun+
199*4882a593Smuzhiyun+    int mRotation;
200*4882a593Smuzhiyun };
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun QT_END_NAMESPACE
203*4882a593Smuzhiyun--
204*4882a593Smuzhiyun2.20.1
205*4882a593Smuzhiyun
206