meta-somdevices: recipes-qt: qtbase: Added qtbase_%.bbappend:
authorJosep Orga <jorga@somdevices.com>
Wed, 9 Jun 2021 10:24:53 +0000 (12:24 +0200)
committerJosep Orga <jorga@somdevices.com>
Wed, 9 Jun 2021 10:24:53 +0000 (12:24 +0200)
· Add linuxfb platform.
· Add patches to be able to rotate linuxfb platform and touch.

Signed-off-by: Josep Orga <jorga@somdevices.com>
recipes-qt/qtbase/qtbase/0021-SOMDEVICES-Fix-the-qt5.12-linuxfb-rotation-problem.patch [new file with mode: 0644]
recipes-qt/qtbase/qtbase/0022-SOMDEVICES-Fix-rotate-tslib.patch [new file with mode: 0644]
recipes-qt/qtbase/qtbase/0023-SOMDEVICES-Don-t-copy-pixels-twice-until-they-end-up.patch [new file with mode: 0644]
recipes-qt/qtbase/qtbase_%.bbappend [new file with mode: 0644]

diff --git a/recipes-qt/qtbase/qtbase/0021-SOMDEVICES-Fix-the-qt5.12-linuxfb-rotation-problem.patch b/recipes-qt/qtbase/qtbase/0021-SOMDEVICES-Fix-the-qt5.12-linuxfb-rotation-problem.patch
new file mode 100644 (file)
index 0000000..4ca8d40
--- /dev/null
@@ -0,0 +1,120 @@
+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
+
diff --git a/recipes-qt/qtbase/qtbase/0022-SOMDEVICES-Fix-rotate-tslib.patch b/recipes-qt/qtbase/qtbase/0022-SOMDEVICES-Fix-rotate-tslib.patch
new file mode 100644 (file)
index 0000000..d982b09
--- /dev/null
@@ -0,0 +1,89 @@
+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
+
diff --git a/recipes-qt/qtbase/qtbase/0023-SOMDEVICES-Don-t-copy-pixels-twice-until-they-end-up.patch b/recipes-qt/qtbase/qtbase/0023-SOMDEVICES-Don-t-copy-pixels-twice-until-they-end-up.patch
new file mode 100644 (file)
index 0000000..8249612
--- /dev/null
@@ -0,0 +1,119 @@
+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
+
diff --git a/recipes-qt/qtbase/qtbase_%.bbappend b/recipes-qt/qtbase/qtbase_%.bbappend
new file mode 100644 (file)
index 0000000..4447bfd
--- /dev/null
@@ -0,0 +1,11 @@
+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"