Multi & LinuxFb display drivers: Changing frame buffer resolutions at run-time



  • I've seen some unanswered questions similar to this on the net...hoping I can get some insight here.

    I'm currently using the Multi display driver with a few LinuxFb's, and need to be able to allow an application user to change the display resolution between a couple different presets. All of the Multi's LinuxFb's will have the same resolution. I assume (1) is the right way to go, but would like to understand why I can't get away with (2).

    (1) Is this possible with the current LinuxFb implementation, or will I need to write a custom display driver?

    I was hoping that I might be able to subclass the existing LinuxFb implementation, sneak in the FBIOPUT_VSCREENINFO ioctl()'s I need, and roll it up into a display driver plugin. Any advice on where to start here? It'd be nice to re-use as much of the existing LinuxFb functionality as possible...

    (2) As a quick (and probably terribly unorthodox) hack to try runtime resolution changes out, I had the following in a test app. This segfaults on the initDevice(). As far as the the Multi driver goes -- are all bets off once you call shutdownDevice() and disconnect()? Is there no way to reconnect and reinitialize?
    @
    QScreen *screen = QScreen::instance();
    screen->shutdownDevice();
    screen->disconnect();

    // Open up our /dev/fb*'s and make the necessary changes
    reconfigure_fbs();
    
    screen->connect("Multi: LinuxFb:/dev/fb0 LinuxFb:/dev/fb2");
    screen->initDevice();
    

    @

    I dove in a bit with GDB, and noted was that QMultiScreen::disconnect() doesn't appear to make calls to removeSubScreen() as I would have expected, which seems to result in QMultiScreen keeping around the old (and deinitialized) subscreens. I added removeSubScreen()'s as shown below:
    @void QMultiScreen::disconnect()
    {
    const int n = d_ptr->screens.size();
    for (int i = 0; i < n; ++i)
    d_ptr->screens.at(i)->disconnect();

    while(d_ptr->screens.size() > 0) 
        removeSubScreen(d_ptr->screens.at(0));
    

    }
    @

    With that in place, I wind up with some sort of invalid memory access in the LinuxFb init;
    @
    (gdb)

    Program received signal SIGSEGV, Segmentation fault.
    0x4091b82c in QLinuxFbScreen::initDevice (this=0x122ad0)
    at embedded/qscreenlinuxfb_qws.cpp:766
    766 shared->fifocount = 0;
    (gdb) print *shared
    Cannot access memory at address 0x46001701
    @

    Ultimately, I'm guessing (2) is downright wrong....and I suppose I'm using things incorrectly, unaware of the side effects that I'm inducing. Could someone familiar with this code confirm/deny?

    Thanks! Hopefully I kept it under the tl;dr theshold ;)


    Qt Version info: Currently using 4.7.4



  • [quote author="jonszy" date="1328309045"]
    (1) Is this possible with the current LinuxFb implementation, or will I need to write a custom display driver?
    [/quote]

    It appears that I somehow managed to overlook setMode(), which would do the trick in most cases. (In my case, the FB implementation has some non-standard ioctl() implementations that I need work with, so I'm still figuring this out.)

    I find it interesting that the QLinuxFbScreen disconnect()'s and then connect()'s with the saved display spec string, but does not shutdown/reinitialize -- still not entirely sure why those steps were causing me trouble...thought I had things in the right order. Back to the docs and source, I suppose!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.