Make threaded rendering possible with LinuxFB

It was previously not possible to render to a QBackingStore
with the linuxfb platform plugin because of both the use of
a QTimer created on the main thread and there was no lock
on the backing store surface (which would lead to copy content
to screen that being rendered in another thread).

Change-Id: I0ea3600316ce29eb89f6595997847afe7086116f
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
bb10
Andy Nichols 2015-01-13 15:22:12 +01:00
parent 668a3a4da1
commit d7068cbe1b
4 changed files with 63 additions and 10 deletions

View File

@ -69,5 +69,30 @@ void QFbBackingStore::resize(const QSize &size, const QRegion &staticContents)
mImage = QImage(size, window()->screen()->handle()->format());
}
const QImage QFbBackingStore::image()
{
return mImage;
}
void QFbBackingStore::lock()
{
mImageMutex.lock();
}
void QFbBackingStore::unlock()
{
mImageMutex.unlock();
}
void QFbBackingStore::beginPaint(const QRegion &)
{
lock();
}
void QFbBackingStore::endPaint()
{
unlock();
}
QT_END_NAMESPACE

View File

@ -46,6 +46,7 @@
//
#include <qpa/qplatformbackingstore.h>
#include <QtCore/QMutex>
QT_BEGIN_NAMESPACE
@ -64,12 +65,19 @@ public:
virtual void resize(const QSize &size, const QRegion &region);
const QImage image() { return mImage; }
const QImage image();
void lock();
void unlock();
void beginPaint(const QRegion &);
void endPaint();
protected:
friend class QFbWindow;
QImage mImage;
QMutex mImageMutex;
};
QT_END_NAMESPACE

View File

@ -37,11 +37,15 @@
#include "qfbbackingstore_p.h"
#include <QtGui/QPainter>
#include <QtCore/QCoreApplication>
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/QDebug>
#include <QtCore/QElapsedTimer>
QT_BEGIN_NAMESPACE
QFbScreen::QFbScreen() : mCursor(0), mGeometry(), mDepth(16), mFormat(QImage::Format_RGB16), mScreenImage(0), mCompositePainter(0), mIsUpToDate(false)
QFbScreen::QFbScreen() : mUpdatePending(false), mCursor(0), mGeometry(), mDepth(16), mFormat(QImage::Format_RGB16), mScreenImage(0), mCompositePainter(0), mIsUpToDate(false)
{
}
@ -54,10 +58,17 @@ QFbScreen::~QFbScreen()
void QFbScreen::initializeCompositor()
{
mScreenImage = new QImage(mGeometry.size(), mFormat);
scheduleUpdate();
}
mRedrawTimer.setSingleShot(true);
mRedrawTimer.setInterval(0);
connect(&mRedrawTimer, SIGNAL(timeout()), this, SLOT(doRedraw()));
bool QFbScreen::event(QEvent *event)
{
if (event->type() == QEvent::UpdateRequest) {
doRedraw();
mUpdatePending = false;
return true;
}
return QObject::event(event);
}
void QFbScreen::addWindow(QFbWindow *window)
@ -146,8 +157,10 @@ void QFbScreen::setDirty(const QRect &rect)
void QFbScreen::scheduleUpdate()
{
if (!mRedrawTimer.isActive())
mRedrawTimer.start();
if (!mUpdatePending) {
mUpdatePending = true;
QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
}
}
void QFbScreen::setPhysicalSize(const QSize &size)
@ -246,12 +259,19 @@ QRegion QFbScreen::doRedraw()
continue;
// if (mWindowStack[layerIndex]->isMinimized())
// continue;
QRect windowRect = mWindowStack[layerIndex]->geometry().translated(-screenOffset);
QRect windowIntersect = rect.translated(-windowRect.left(),
-windowRect.top());
QFbBackingStore *backingStore = mWindowStack[layerIndex]->backingStore();
if (backingStore)
if (backingStore) {
backingStore->lock();
mCompositePainter->drawImage(rect, backingStore->image(), windowIntersect);
backingStore->unlock();
}
if (firstLayer) {
firstLayer = false;
}
@ -272,7 +292,6 @@ QRegion QFbScreen::doRedraw()
// qDebug() << "QFbScreen::doRedraw" << mWindowStack.size() << mScreenImage->size() << touchedRegion;
return touchedRegion;
}

View File

@ -94,10 +94,11 @@ protected slots:
protected:
void initializeCompositor();
bool event(QEvent *event);
QList<QFbWindow *> mWindowStack;
QRegion mRepaintRegion;
QTimer mRedrawTimer;
bool mUpdatePending;
QFbCursor *mCursor;
QRect mGeometry;