[Interest] Qt 5.5 LinuxFb Plugin with Base Layer Transparency
Peter Seiderer
ps.report at gmx.net
Thu Apr 7 23:34:56 CEST 2016
Hello Jack,
> Our application requires that we blend 3 layers with 3 framebuffers on a TI
> device. The base layer is opaque video, the middle layer is video blended
> on top of the base layer with a global alpha channel that we need to be
> able to modify on the fly, and a top GUI layer with transparency. This
> approach worked great with Qt 4.8 and we are trying to get it to work with
> Qt 5.5.
>
> The problem is that when we run the top level GUI application, we cannot
> set the background of the to be fully transparent. It simply appears black.
> This covers the 2 lower z-order applications and they are no longer visible.
>
> We attempted to investigate this issue by looking at the Qt5.5 linuxfb
> plugin source code. Beginning at line 251 of qfbscreen.cpp in the Qt5.5
> source ( located in qt5base-5.5.1/src/platformsupport/fbconvenience ), we
> see where the linuxfb plugin sets the base layer to black. If we change
> that one line to "qt::transparent", and re-launch our app, then we see the
> lower 2 layers "through" the GUI in the regions of the GUI where it is
> fully transparent. Initially, the fully transparent GUI displays correctly.
> It displays a menu, which initially appears correct. A problem occurs when
> we then try to hide the menu. It remains displayed on the screen.
> Apparently, the redraw of the base layer, which is transparent, does not
> replace the pixels from the menu, but is instead blended with the menu
> pixels.
>
> We have tried several composition modes in the base layer's paint event,
> including Source and Clear, but neither fixes the problem. On previous
> products ( using the DM3730 ), we used this same approach ( DSS blended
> framebuffers ) with Qt 4.8 and it worked as expected. How can we make this
> work with Qt 5.5?
>
Did have the same problem (but on a NXP/Freescale i.MX6 board), solved it
by the following patch/hack for Qt5.4.1 and a simple OSD GUI:
--- begin ---
From dab806c4dce22efc5eb6615287cf803a1d72ee6a Mon Sep 17 00:00:00 2001
From: Peter Seiderer <ps.report at gmx.net>
Date: Tue, 30 Sep 2014 16:53:00 +0200
Subject: [PATCH] platforms/linuxfb: enabel alpha channel on framebuffer output
---
src/platformsupport/fbconvenience/qfbscreen.cpp | 9 +++++++--
src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp | 4 +++-
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp
index aa35825..6670f8e 100644
--- a/src/platformsupport/fbconvenience/qfbscreen.cpp
+++ b/src/platformsupport/fbconvenience/qfbscreen.cpp
@@ -217,8 +217,13 @@ QRegion QFbScreen::doRedraw()
if (!mIsUpToDate)
generateRects();
- if (!mCompositePainter)
+ if (!mCompositePainter) {
mCompositePainter = new QPainter(mScreenImage);
+ // simple solution for OSD rendering (real solution should invalidate/init
+ // background always before rendering widget content with alpha blending)
+ mCompositePainter->setCompositionMode(QPainter::CompositionMode_Source);
+ }
+
for (int rectIndex = 0; rectIndex < mRepaintRegion.rectCount(); rectIndex++) {
QRegion rectRegion = rects[rectIndex];
@@ -236,7 +241,7 @@ QRegion QFbScreen::doRedraw()
foreach (const QRect &rect, intersect.rects()) {
bool firstLayer = true;
if (layer == -1) {
- mCompositePainter->fillRect(rect, Qt::black);
+ mCompositePainter->fillRect(rect, Qt::transparent);
firstLayer = false;
layer = mWindowStack.size() - 1;
}
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
index a66c9fa..522088c 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
@@ -431,8 +431,10 @@ QRegion QLinuxFbScreen::doRedraw()
if (touched.isEmpty())
return touched;
- if (!mBlitter)
+ if (!mBlitter) {
mBlitter = new QPainter(&mFbScreenImage);
+ mBlitter->setCompositionMode(QPainter::CompositionMode_Source);
+ }
QVector<QRect> rects = touched.rects();
for (int i = 0; i < rects.size(); i++)
--
2.1.4
--- end ---
Regards,
Peter
> qfbscreen.cpp:
>
> // we only expect one rectangle, but defensive coding...
> foreach (const QRect &rect, intersect.rects()) {
> bool firstLayer = true;
> if (layer == -1) {
> mCompositePainter->fillRect(rect, Qt::black);
> firstLayer = false;
> layer = mWindowStack.size() - 1;
> }
>
> for (int layerIndex = layer; layerIndex != -1; layerIndex--) {
> if (!mWindowStack[layerIndex]->window()->isVisible())
> 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) {
> backingStore->lock();
> mCompositePainter->drawImage(rect,
> backingStore->image(), windowIntersect);
> backingStore->unlock();
> }
> if (firstLayer) {
> firstLayer = false;
> }
> }
> }
> We greatly appreciate any help - thank you.
More information about the Interest
mailing list