This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM57XX EVM Transparent GFX DSS Layer with Qt 5.5

Other Parts Discussed in Thread: DM3730

Hello,

Our application requires that we blend 3 layers. 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. Our initial attempt using Wayland failed because it does not seem to support global alpha settings on the middle layer. 

After a discussion with our TI rep, we decided to use the DSS directly. We have disabled Wayland in the Arago distribution for the AM57XX EVM and enabled 3 framebuffers in the kernel. Using the sysfs entries, we've configured the GFX layer to be on top ( z-order 3 ) and the video1 and video2 layers to be beneath it.

The GFX layer uses Overlay0 and is tied to /dev/fb0. We have a Qt5.5 GUI app with semi-transparent widgets running on it using the following syntax: ./app -platform linuxfb:fb=/dev/fb0. We are confident the GUI code is written correctly as it displays as expected on both Ubuntu and Windows 7. Two other Qt 5.5 applications run "beneath" it on /dev/fb1 and /dev/fb2 and simply display static images for now.

We are using Overlay1 to globally alpha blend /dev/fb1 ( which has a z-order of 1 ) to an alpha value of 150. The application on Overlay1 is called like this: ./app2 -platform linuxfb:fb=/dev/fb1.

The last Qt5 application on /dev/fb2 has the lowest z-order and is fully opaque. It runs on Overlay2 and is launched with this command: ./app3 -platform linuxfb:fb=/dev/fb2.

Global alpha blending on Overlay1 works great, we partially see "through" our image on /dev/fb1 and it blends with the base layer on Overlay2. The problem is that when we run the top level GUI application, we cannot set the background of the GFX layer Overlay0 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.

  • I will forward this to the video experts.
  • Hi Phillip,

    We will look into this and get back.

    regards,
    Manisha
  • Thank you Manisha.

    Is there any other information I can send to help debug this?

    Phil

  • Phil,

    I am afraid that we won't be able to have quick turn around on looking into this issue. If you can share sample test application along with instructions to run, that may help to shorten the response time. Meanwhile, can you try setting the  trans-key-mode value to 2 (DSS transparency settings) and run your QT application. This can be done using the modetest app available in filesystem.

    To set the trans-key-mode, first run modetest application without any arguments to it as shown below.  It will print bunch of information. Check the CRTC id of the plane whose trans-key-mode needs changes.

    #modetest 

    Next, run the modetest app with -d option and arguments as below. In below example list of arguments, replace 28 with the CRTC id that you got running modetest at you end.

    #modetest -d 28:trans-key-mode:2

    Regards,

    Manisha

  • I received a reply on the Qt mailling list from Peter Seiderer with a patch that worked great. I've pasted it below:

    --- begin ---
    From dab806c4dce22efc5eb6615287cf803a1d72ee6a Mon Sep 17 00:00:00 2001
    From: Peter Seiderer <ps.report@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 ---
  • We were able to use the dual_camera_example from the latest SDK release ( April 2016 ) to understand how to perform z-ordering through OMAP DRM. It seems to be working fine.
  • Thanks Phillip for the update. I am glad to know that issue is resolved.

    Regards,
    Manisha