Qt 5.5 LinuxFb Plugin with Base Layer Transparency
-
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?
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.
-
Hi and welcome to devnet,
Since it's getting pretty low-level, I'd recommend posting this on the interest mailing list. You'll find there Qt's developers/maintainers. This forum is more user oriented.
-
Thank you,
I've posted to the list.
Phil
-
Did you subscribe first ?
-
I did register but realized I posted with the wrong email address. Now I've corrected it and can see my post on the list. Thank you.