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
parent
668a3a4da1
commit
d7068cbe1b
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ®ion);
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue