· Add linuxfb platform.
· Add patches to be able to rotate linuxfb platform and touch.
Signed-off-by: Josep Orga <jorga@somdevices.com>
--- /dev/null
+From 949eba2d5224200b5e4bb378948eda75b04366c9 Mon Sep 17 00:00:00 2001
+From: Josep Orga <jorga@somdevices.com>
+Date: Tue, 22 Sep 2020 16:07:49 +0200
+Subject: [PATCH 1/2] SOMDEVICES Fix the qt5.12 linuxfb rotation problem This
+ patch fix the qt5 linuxfb rotation problem, create an mrotation option which
+ can rotate the display by 90,180 and 270 degrees. Based on
+ https://patchwork.openembedded.org/patch/149258/
+
+Signed-off-by: Josep Orga <jorga@somdevices.com>
+---
+ .../platforms/linuxfb/qlinuxfbscreen.cpp | 38 +++++++++++++++++--
+ .../platforms/linuxfb/qlinuxfbscreen.h | 1 +
+ 2 files changed, 35 insertions(+), 4 deletions(-)
+
+diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+index dc7ea08dc5..5be8a482f9 100644
+--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
++++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+@@ -287,7 +287,7 @@ static void blankScreen(int fd, bool on)
+ }
+
+ QLinuxFbScreen::QLinuxFbScreen(const QStringList &args)
+- : mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0)
++ : mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0), mRotation(90)
+ {
+ mMmap.data = 0;
+ }
+@@ -313,6 +313,7 @@ bool QLinuxFbScreen::initialize()
+ QRegularExpression mmSizeRx(QLatin1String("mmsize=(\\d+)x(\\d+)"));
+ QRegularExpression sizeRx(QLatin1String("size=(\\d+)x(\\d+)"));
+ QRegularExpression offsetRx(QLatin1String("offset=(\\d+)x(\\d+)"));
++ QRegularExpression rotationRx(QLatin1String("rotation=(0|90|180|270)"));
+
+ QString fbDevice, ttyDevice;
+ QSize userMmSize;
+@@ -334,6 +335,8 @@ bool QLinuxFbScreen::initialize()
+ ttyDevice = match.captured(1);
+ else if (arg.contains(fbRx, &match))
+ fbDevice = match.captured(1);
++ else if (arg.contains(rotationRx, &match))
++ mRotation = match.captured(1).toInt();
+ }
+
+ if (fbDevice.isEmpty()) {
+@@ -372,9 +375,17 @@ bool QLinuxFbScreen::initialize()
+ mDepth = determineDepth(vinfo);
+ mBytesPerLine = finfo.line_length;
+ QRect geometry = determineGeometry(vinfo, userGeometry);
++ QRect originalGeometry = geometry;
++ if( mRotation == 90 || mRotation == 270 )
++ {
++ int tmp = geometry.width();
++ geometry.setWidth(geometry.height());
++ geometry.setHeight(tmp);
++ }
++
+ mGeometry = QRect(QPoint(0, 0), geometry.size());
+ mFormat = determineFormat(vinfo, mDepth);
+- mPhysicalSize = determinePhysicalSize(vinfo, userMmSize, geometry.size());
++ mPhysicalSize = determinePhysicalSize(vinfo, userMmSize, originalGeometry.size());
+
+ // mmap the framebuffer
+ mMmap.size = finfo.smem_len;
+@@ -384,11 +395,11 @@ bool QLinuxFbScreen::initialize()
+ return false;
+ }
+
+- mMmap.offset = geometry.y() * mBytesPerLine + geometry.x() * mDepth / 8;
++ mMmap.offset = originalGeometry.y() * mBytesPerLine + originalGeometry.x() * mDepth / 8;
+ mMmap.data = data + mMmap.offset;
+
+ QFbScreen::initializeCompositor();
+- mFbScreenImage = QImage(mMmap.data, geometry.width(), geometry.height(), mBytesPerLine, mFormat);
++ mFbScreenImage = QImage(mMmap.data, originalGeometry.width(), originalGeometry.height(), mBytesPerLine, mFormat);
+
+ mCursor = new QFbCursor(this);
+
+@@ -414,8 +425,27 @@ QRegion QLinuxFbScreen::doRedraw()
+
+ mBlitter->setCompositionMode(QPainter::CompositionMode_Source);
+ for (const QRect &rect : touched)
++ {
++ if( mRotation == 90 || mRotation == 270 )
++ {
++ mBlitter->translate(mGeometry.height()/2, mGeometry.width()/2);
++ }
++ else if( mRotation == 180 )
++ {
++ mBlitter->translate(mGeometry.width()/2, mGeometry.height()/2);
++ }
++
++ if( mRotation != 0 )
++ {
++ mBlitter->rotate(mRotation);
++ mBlitter->translate(-mGeometry.width()/2, -mGeometry.height()/2);
++ }
++
+ mBlitter->drawImage(rect, mScreenImage, rect);
+
++ mBlitter->resetTransform();
++ }
++
+ return touched;
+ }
+
+diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
+index c7ce455e6a..385d29c365 100644
+--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
++++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
+@@ -64,6 +64,7 @@ private:
+ QStringList mArgs;
+ int mFbFd;
+ int mTtyFd;
++ int mRotation;
+
+ QImage mFbScreenImage;
+ int mBytesPerLine;
+--
+2.17.1
+
--- /dev/null
+From a5f4c505a0efd25095b72d2329ba8a4dd937d38f Mon Sep 17 00:00:00 2001
+From: Josep Orga <jorga@somdevices.com>
+Date: Tue, 22 Sep 2020 16:08:48 +0200
+Subject: [PATCH 2/2] SOMDEVICES Fix rotate tslib Use tslib as a touch plugin
+ to make rotation of touch coordinates effective. Based on
+ https://patchwork.openembedded.org/patch/149258/
+
+Signed-off-by: Josep Orga <jorga@somdevices.com>
+---
+ src/platformsupport/input/tslib/qtslib.cpp | 49 +++++++++++++++++++++-
+ 1 file changed, 48 insertions(+), 1 deletion(-)
+
+diff --git a/src/platformsupport/input/tslib/qtslib.cpp b/src/platformsupport/input/tslib/qtslib.cpp
+index 7609416fea..19ac0c2611 100644
+--- a/src/platformsupport/input/tslib/qtslib.cpp
++++ b/src/platformsupport/input/tslib/qtslib.cpp
+@@ -41,6 +41,8 @@
+
+ #include <QSocketNotifier>
+ #include <QStringList>
++#include <QString>
++#include <QPointF>
+ #include <QPoint>
+ #include <QLoggingCategory>
+
+@@ -108,6 +110,30 @@ static bool get_sample(struct tsdev *dev, struct ts_sample *sample, bool rawMode
+ void QTsLibMouseHandler::readMouseData()
+ {
+ ts_sample sample;
++ QString spec = QString::fromLocal8Bit(qgetenv("TSLIB_PARAMETERS"));
++ int RotateAngle;
++ int Width;
++ int Height;
++ QString ModeArg;
++
++ if(spec.isEmpty()){
++ RotateAngle = 0;
++ Height = 480;
++ Width = 272;
++ }
++
++ QStringList args = spec.split(QLatin1Char(':'));
++ for (int i = 0; i < args.count(); ++i) {
++ if(args.at(i).startsWith(QLatin1String("rotate"))) {
++ QString rotateArg = args.at(i).section(QLatin1Char('='), 1, 1);
++ RotateAngle = rotateArg.toInt();
++ }
++ else if(args.at(i).startsWith(QLatin1String("mode"))) {
++ ModeArg = args.at(i).section(QLatin1Char('='), 1, 1);
++ Width = ModeArg.section(QLatin1Char('x'),0,0).toInt();
++ Height= ModeArg.section(QLatin1Char('x'),1,1).toInt();
++ }
++ }
+
+ while (get_sample(m_dev, &sample, m_rawMode)) {
+ bool pressed = sample.pressure;
+@@ -127,7 +153,28 @@ void QTsLibMouseHandler::readMouseData()
+ if (dx*dx <= 4 && dy*dy <= 4 && pressed == m_pressed)
+ continue;
+ }
+- QPoint pos(x, y);
++ QPoint pos(x,y);
++ //Switch to apply rotation
++ switch (RotateAngle) {
++ case 0:
++ pos.setX(x);
++ pos.setY(y);
++ break;
++ case 90:
++ pos.setX(y);
++ pos.setY(Width-x);
++ break;
++ case 180:
++ pos.setX(Width-x);
++ pos.setY(Height-y);
++ break;
++ case 270:
++ pos.setX(Height-y);
++ pos.setY(x);
++ break;
++ default:
++ break;
++ }
+
+ QWindowSystemInterface::handleMouseEvent(nullptr, pos, pos,
+ pressed ? Qt::LeftButton : Qt::NoButton,
+--
+2.17.1
+
--- /dev/null
+From e4e369b537bd1d8d534851487c52ba212e0f524a Mon Sep 17 00:00:00 2001
+From: Josep Orga <jorga@somdevices.com>
+Date: Tue, 29 Sep 2020 09:26:57 +0200
+Subject: [PATCH] SOMDEVICES Don't copy pixels twice until they end up on the
+ screen
+
+Based on: https://codereview.qt-project.org/c/qt/qtbase/+/211945
+
+Signed-off-by: Josep Orga <jorga@somdevices.com>
+---
+ .../platforms/linuxfb/qlinuxfbscreen.cpp | 71 ++++++++++++-------
+ 1 file changed, 46 insertions(+), 25 deletions(-)
+
+diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+index 5be8a482f9..17cfd12f9c 100644
+--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
++++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+@@ -40,6 +40,7 @@
+ #include "qlinuxfbscreen.h"
+ #include <QtFbSupport/private/qfbcursor_p.h>
+ #include <QtFbSupport/private/qfbwindow_p.h>
++#include <QtFbSupport/private/qfbbackingstore_p.h>
+ #include <QtCore/QFile>
+ #include <QtCore/QRegularExpression>
+ #include <QtGui/QPainter>
+@@ -287,7 +288,7 @@ static void blankScreen(int fd, bool on)
+ }
+
+ QLinuxFbScreen::QLinuxFbScreen(const QStringList &args)
+- : mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0), mRotation(90)
++ : mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0), mRotation(0)
+ {
+ mMmap.data = 0;
+ }
+@@ -415,37 +416,57 @@ bool QLinuxFbScreen::initialize()
+
+ QRegion QLinuxFbScreen::doRedraw()
+ {
+- QRegion touched = QFbScreen::doRedraw();
++ const QPoint screenOffset = mGeometry.topLeft();
+
+- if (touched.isEmpty())
+- return touched;
++ if (mRepaintRegion.isEmpty())
++ return mRepaintRegion;
+
+ if (!mBlitter)
+ mBlitter = new QPainter(&mFbScreenImage);
+-
+- mBlitter->setCompositionMode(QPainter::CompositionMode_Source);
+- for (const QRect &rect : touched)
+- {
+- if( mRotation == 90 || mRotation == 270 )
+- {
+- mBlitter->translate(mGeometry.height()/2, mGeometry.width()/2);
+- }
+- else if( mRotation == 180 )
+- {
+- mBlitter->translate(mGeometry.width()/2, mGeometry.height()/2);
+- }
+-
+- if( mRotation != 0 )
+- {
+- mBlitter->rotate(mRotation);
+- mBlitter->translate(-mGeometry.width()/2, -mGeometry.height()/2);
++
++ const QVector<QRect> rects = mRepaintRegion.rects();
++ const QRect screenRect = mGeometry.translated(-screenOffset);
++ for (int rectIndex = 0; rectIndex < mRepaintRegion.rectCount(); rectIndex++) {
++ const QRect rect = rects[rectIndex].intersected(screenRect);
++ if (rect.isEmpty())
++ continue;
++
++ mBlitter->setCompositionMode(QPainter::CompositionMode_Source);
++// mBlitter->fillRect(rect, mScreenImage.hasAlphaChannel() ? Qt::transparent : Qt::black);
++
++ for (int layerIndex = mWindowStack.size() - 1; layerIndex != -1; layerIndex--) {
++ if (!mWindowStack[layerIndex]->window()->isVisible())
++ continue;
++
++ const QRect windowRect = mWindowStack[layerIndex]->geometry().translated(-screenOffset);
++ const QRect windowIntersect = rect.translated(-windowRect.left(), -windowRect.top());
++ QFbBackingStore *backingStore = mWindowStack[layerIndex]->backingStore();
++ if (backingStore) {
++ backingStore->lock();
++ if( mRotation == 90 || mRotation == 270 )
++ {
++ mBlitter->translate(mGeometry.height()/2, mGeometry.width()/2);
++ }
++ else if( mRotation == 180 )
++ {
++ mBlitter->translate(mGeometry.width()/2, mGeometry.height()/2);
++ }
++
++ if( mRotation != 0 )
++ {
++ mBlitter->rotate(mRotation);
++ mBlitter->translate(-mGeometry.width()/2, -mGeometry.height()/2);
++ }
++ mBlitter->drawImage(rect, backingStore->image(), windowIntersect);
++ mBlitter->resetTransform();
++ backingStore->unlock();
++ }
+ }
+-
+- mBlitter->drawImage(rect, mScreenImage, rect);
+-
+- mBlitter->resetTransform();
+ }
+
++ QRegion touched = mRepaintRegion;
++ mRepaintRegion = QRegion();
++
+ return touched;
+ }
+
+--
+2.17.1
+
--- /dev/null
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+PR = "somdevices.0"
+MAINTAINER = "SomDevices <somdevices@somdevices.com>"
+
+SRC_URI += "\
+ file://0021-SOMDEVICES-Fix-the-qt5.12-linuxfb-rotation-problem.patch \
+ file://0022-SOMDEVICES-Fix-rotate-tslib.patch \
+ file://0023-SOMDEVICES-Don-t-copy-pixels-twice-until-they-end-up.patch \
+"
+
+PACKAGECONFIG_append = " linuxfb"