linuxfb: Support transparency

Always clearing to opaque black makes it impossible to create
semi-transparent overlays with linuxfb. Instead, behave like other
platforms' backingstores: if the target image has an alpha channel,
clear to transparent instead and set the correct composition mode.

Task-number: QTBUG-52475
Change-Id: I2db4588e0112e200a3aa5eed49f806c37d7ca8b5
Reviewed-by: Louai Al-Khanji <louai.al-khanji@qt.io>
This commit is contained in:
Laszlo Agocs 2016-04-08 17:27:14 +02:00
parent 1e971f8555
commit 844ea8beea
3 changed files with 19 additions and 4 deletions

View File

@ -37,6 +37,7 @@
#include <qpa/qplatformwindow.h> #include <qpa/qplatformwindow.h>
#include <QtGui/qscreen.h> #include <QtGui/qscreen.h>
#include <QtGui/qpainter.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -84,9 +85,17 @@ void QFbBackingStore::unlock()
mImageMutex.unlock(); mImageMutex.unlock();
} }
void QFbBackingStore::beginPaint(const QRegion &) void QFbBackingStore::beginPaint(const QRegion &region)
{ {
lock(); lock();
if (mImage.hasAlphaChannel()) {
QPainter p(&mImage);
p.setCompositionMode(QPainter::CompositionMode_Source);
const QVector<QRect> rects = region.rects();
for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it)
p.fillRect(*it, Qt::transparent);
}
} }
void QFbBackingStore::endPaint() void QFbBackingStore::endPaint()

View File

@ -233,6 +233,7 @@ QRegion QFbScreen::doRedraw()
if (!mCompositePainter) if (!mCompositePainter)
mCompositePainter = new QPainter(mScreenImage); mCompositePainter = new QPainter(mScreenImage);
for (int rectIndex = 0; rectIndex < mRepaintRegion.rectCount(); rectIndex++) { for (int rectIndex = 0; rectIndex < mRepaintRegion.rectCount(); rectIndex++) {
QRegion rectRegion = rects[rectIndex]; QRegion rectRegion = rects[rectIndex];
@ -250,7 +251,8 @@ QRegion QFbScreen::doRedraw()
foreach (const QRect &rect, intersect.rects()) { foreach (const QRect &rect, intersect.rects()) {
bool firstLayer = true; bool firstLayer = true;
if (layer == -1) { if (layer == -1) {
mCompositePainter->fillRect(rect, Qt::black); mCompositePainter->setCompositionMode(QPainter::CompositionMode_Source);
mCompositePainter->fillRect(rect, mScreenImage->hasAlphaChannel() ? Qt::transparent : Qt::black);
firstLayer = false; firstLayer = false;
layer = mWindowStack.size() - 1; layer = mWindowStack.size() - 1;
} }
@ -283,6 +285,7 @@ QRegion QFbScreen::doRedraw()
QRect cursorRect; QRect cursorRect;
if (mCursor && (mCursor->isDirty() || mRepaintRegion.intersects(mCursor->lastPainted()))) { if (mCursor && (mCursor->isDirty() || mRepaintRegion.intersects(mCursor->lastPainted()))) {
mCompositePainter->setCompositionMode(QPainter::CompositionMode_SourceOver);
cursorRect = mCursor->drawCursor(*mCompositePainter); cursorRect = mCursor->drawCursor(*mCompositePainter);
touchedRegion += cursorRect; touchedRegion += cursorRect;
} }

View File

@ -405,9 +405,12 @@ QRegion QLinuxFbScreen::doRedraw()
if (!mBlitter) if (!mBlitter)
mBlitter = new QPainter(&mFbScreenImage); mBlitter = new QPainter(&mFbScreenImage);
QVector<QRect> rects = touched.rects(); const QVector<QRect> rects = touched.rects();
for (int i = 0; i < rects.size(); i++) mBlitter->setCompositionMode(QPainter::CompositionMode_Source);
for (int i = 0; i < rects.size(); ++i)
mBlitter->drawImage(rects[i], *mScreenImage, rects[i]); mBlitter->drawImage(rects[i], *mScreenImage, rects[i]);
return touched; return touched;
} }