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