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.

Output frame buffer resolution

I apologise if this question has been answered before.

I would like to know how I can change the resolution of the video output at runtime.  I have a graphics application, which uses OpenVG and outputs the rendered graphics to an EGL Window Surface. This is then output to a LCD panel that uses a custom driver. I would like to be able to create a simple function in my application that can change the output display resolution.

In my display panel driver, the x_res and y_res fields of the omap_video_timings structure are currently set to a default of 640x480, which will need to be changed later on in the application to an arbitrary resolution (to 1280x720 for example). How can I do this?

Thanks very much,

 

Andy

 

  • Andy,

    Have a look at the following Wiki pages.

    http://processors.wiki.ti.com/index.php/Display_Subsystem

    http://processors.wiki.ti.com/index.php/Adding_new_DVI_resolutions

    http://processors.wiki.ti.com/index.php/UserGuideDisplayDrivers_PSP_03.00.00.05

    BR,

    Steve

  • Hi Steve,

    Thank you for the links. I have read through the documentation and I am having no luck in changing the resolution.

    When reading the documentation, the useful functions appeared to be:

    • Disabling the overlay and display
    • Calling 'fbset' with the desired resolution
    • Writing the desired resolution to /sys/class/graphics/fb0/virtual_size
    • Writing display timings to /sys/devices/platform/omapdss/display0/timings
    • Enabling the overlay and display

    I have tried the above on the beagleboard for testing with no success. Is there any help you can give? Maybe any example code to show how this can be achieved from a linux application?

    Thanks,

     

    Andy

  • Andy,

    SYSFS interface can be used to configure the DSS pipeline dynamically, for example you can set the final display device timings using the following command:

    echo "<pixel_clock>,<xres/hfp/hbp/hsw>,<yres/vfp/vbp/vsw>" > /sys/devices/platform/omapdss/displayX/timings

    Now if you want to configure the fbdev framework using fbset you would need to ensure that the source code supports the resolution you require. If the resolution is not supported, even if you try to pass the configuration to the driver it will fall back to the default resolution. Please look at /drivers/video/modedb.c file and modify it according to your requirements.

    If you would like to test this with the currently supported parameters please use this example as a reference:

    echo 0 > /sys/devices/platform/omapdss/display0/enabled
    # Configure framebuffer timings, this resolution is defined in modedb.c file
    fbset -fb /dev/fb0 -xres 640 -yres 480   
    # Set manager0 to dvi display
    echo "dvi" > /sys/devices/platform/omapdss/manager0/display
    # Enable display2
    echo 1 > /sys/devices/platform/omapdss/display2/enabled
    # If needed display device timings can be set, for example to set display timings to 720P
    echo "72428,1280/190/120/32,720/13/3/5" > /sys/devices/platform/omapdss/display2/timings

    Regards, Punya
    ---------------------------------------------------------------------------------------------------------------------
    Please click the Verify Answer button on this post if it answers your question.
    ---------------------------------------------------------------------------------------------------------------------

  • Hi Punya,

    Thank you for the help, I had actually got this far and so it is nice to see I am doing the right thing. I believe that the steps that I am doing are changing the resolution in some way as the console output on the monitor looks larger or smaller depending on the resolution.

    I am starting Linux with the bootargs "...omapfb.mode=dvi:1024x768MR-24@60", which gives the following setup:

    • fbset
      mode "1024x768-60"
              # D: 56.000 MHz, H: 47.298 kHz, V: 59.870 Hz
              geometry 1024 768 1024 768 32
              timings 17857 80 48 3 15 32 4
              accel false
              rgba 8/16,8/8,8/0,0/0
      endmode
    • cat /sys/devices/platform/omapdss/display0/timings
      56000,1024/80/48/32,768/3/15/4
    • cat /sys/class/graphics/fb0/virtual_size
      1024,768 

    Now if I perform these steps...

    1. echo 0 > /sys/devices/platform/omapdss/display0/enabled
    2. fbset -fb /dev/fb0 -xres 800 -yres 600  -vxres 800 -vyres 600
    3. echo 1 > /sys/devices/platform/omapdss/display0/enabled
    4. echo "35500,800/80/48/32,600/3/11/4" > /sys/devices/platform/omapdss/display0/timings
    5. echo "800,600" > /sys/class/graphics/fb0/virtual_size

    the resolution looks as though it has successfully changed:

    • fbset
      mode "800x600-60"
              # D: 35.500 MHz, H: 36.979 kHz, V: 59.837 Hz
              geometry 800 600 800 600 32
              timings 28169 80 48 3 11 32 4
              accel false
              rgba 8/16,8/8,8/0,0/0
      endmode

    However, when I now run my graphics application, the EGL libraries still thinks the resolution is 1024x768, not 800x600. I.e. eglQuerySurface returns a width and height of 1024 and 768 respectively. Which is where the problem lies.

    Also, very strangely, I cannot return back to the original resolution of 1024x768. If I perform the following steps...

    1. echo 0 > /sys/devices/platform/omapdss/display0/enabled
    2. fbset -fb /dev/fb0 -xres 1024 -yres 768 -vxres 1024 -vyres 768
    3. echo 1 > /sys/devices/platform/omapdss/display0/enabled
    4. echo "56000,1024/80/48/32,768/3/15/4" > /sys/devices/platform/omapdss/display0/timings
    5. echo "1024,768" > /sys/class/graphics/fb0/virtual_size

    The resolution has not successfully changed:

    • fbset
      mode "800x600-94"
              # D: 56.000 MHz, H: 58.334 kHz, V: 93.784 Hz
              geometry 800 600 1024 768 32
              timings 17857 80 48 3 15 32 4
              accel false
              rgba 8/16,8/8,8/0,0/0
      endmode

    I should also point out that setting the resolution from the bootargs works fine, however this is unsuitable for my application.

    Thanks,

     

    Andy

  • Further to my last post, I have been able successfully return the resolution back to its original set up:

    Andrew Poole said:

    Also, very strangely, I cannot return back to the original resolution of 1024x768. If I perform the following steps...

    1. echo 0 > /sys/devices/platform/omapdss/display0/enabled
    2. fbset -fb /dev/fb0 -xres 1024 -yres 768 -vxres 1024 -vyres 768
    3. echo 1 > /sys/devices/platform/omapdss/display0/enabled
    4. echo "56000,1024/80/48/32,768/3/15/4" > /sys/devices/platform/omapdss/display0/timings
    5. echo "1024,768" > /sys/class/graphics/fb0/virtual_size

    The resolution has not successfully changed:

    • fbset
      mode "800x600-94"
              # D: 56.000 MHz, H: 58.334 kHz, V: 93.784 Hz
              geometry 800 600 1024 768 32
              timings 17857 80 48 3 15 32 4
              accel false
              rgba 8/16,8/8,8/0,0/0
      endmode

    I found that the fbset '-n' option was needed to change the video mode immediately. So step 2 in the above quote becomes:

    • fbset -n -fb /dev/fb0 -xres 1024 -yres 768
      (setting the virtual resolution here has no effect) 

    I still can't solve the main issue with my graphics application not detecting the new video resolution. I am assuming that the function 'eglCreateWindowSurface' reads the resolution from somewhere but as there is no useful documentation nor any source code, I can't tell where it reads it from. Does anyone have any idea how to get an EGL based Graphics application to detect a correct screen resolution?

    Thanks

     

  • HI Andy!

    I am unable to change back the resolution to Original one, once I change it. Where did you get the fbset utility from?

    The "fbset" utility I am using, does not have any '-n' option. I am using the utility from here ftp://ftp.scw.net.br/pub/slamd64/slamd64-12.2/source/a/bin/fbset-2.1.tar.gz.

    One thing that I am not able to understand is that why

    fbset -fb /dev/fb0 -xres $w -yres $h -vxres $w -vyres $h alone is not able to change  the resolution.

    Thanks in advance,

    regards

    -Nitin

  • Hi Nitin,

    I was using quite an older version of the Angstrom distribution (2009 stable) for the Beagleboard for testing, which had a version of fbset that supported the '-n' or '--now' option. I have since moved onto my target hardware which uses the Arago distribution from the latest TI PSP and this no longer has the '-n' option.

    I now have no ideas on how to change the resolution at runtime for either Linux or a graphics application that uses the SGX.

     

    Andy

  • HI Andy,

    I checked in the code for fbset v 2.1, it will immediately apply the settings if you have not given the 'test' option.

    I was trying to change the GFX overlay from TV(720x480) to LCD(1024x768) I have a VGA monitor as a display on this path. I am using 2.6.32 omap-linux kernel, nothing from PSP.

    I used this procedure

    ln -s /dev/graphics/fb0 /dev/fb0
    fbset
    echo 0 > /sys/devices/platform/omapdss/overlay0/enabled
    echo "" > /sys/devices/platform/omapdss/overlay0/manager
    echo 0 > /sys/devices/platform/omapdss/display1/enabled
    echo "64800,1024/44/116/156,768/3/29/6" > /sys/devices/platform/omapdss/display0/timings
    echo "1024,768" > /sys/class/graphics/fb0/virtual_size
    fbset -fb /dev/fb0 -xres 1024 -yres 768
    echo "lcd" > /sys/devices/platform/omapdss/overlay0/manager
    echo 1 > /sys/devices/platform/omapdss/display0/enabled
    echo 1 > /sys/devices/platform/omapdss/overlay0/enabled

    And I am not able to see the new resolution on LCD, it has retained the old one. Can anybody suggest what might be going wrong here?

    But if I used following commands to change resolution to 1024x768 from 800x600, if by default the kernel command-line asked to boot in "dvi"

    # echo 0 > /sys/devices/platform/omapdss/display0/enabled
    # echo "64800,1024/44/116/156,768/3/29/6" > /sys/devices/platform/omapdss/display0/timings
    # echo "1024,768" > /sys/class/graphics/fb0/virtual_size
    # fbset -fb /dev/fb0 -xres 1024 -yres 768
    # echo 1 > /sys/devices/platform/omapdss/display0/enabled

    I am able to change the resolution successfully.

     

    regards

    -Nitin

     

     

     

  • Hi Nitin,

    I can confirm that, running on my distribution of Linux (based on a 2.6.36 OMAP-Linux Kernel), fbset is at version 2.1 and now that I have my framebuffer working correctly the settings are immediately applied.

    Something that I have noticed is that the pvrsrvkm kernel module reads the framebuffer resolution only once at the time the module is loaded. This is what is causing the eglCreateWindowSurface to create a surface with the wrong resolution. Reloading the module ('/etc/init.d/rc.pvr restart') will re-read the framebuffer resolution and allow a graphics application to render to the correct size.

    However this really isn't ideal as it requires the application to release its graphics context and clean up before reloading the pvrsrvkm kernel module, only to then recreate the graphics context and egl window surface for the application to function correctly. I really hope that someone knows a nicer way to do this?!

    Your situation with changing from TV to LCD is a strange one... maybe reloading the kernel module after the call to fbset may help for you too.

    Regards,

     

    Andy

  • Does anyone have any ideas how to change the resolution without having to destroy the EGL graphics context and then reload the pvrsrvkm kernel module? Destroying the graphics context means that all my textures/colours/paths have to be recreated.

     

    Andy

  • Graphics vertex/fill calculations related to rendering - are relative to the current screen resolution. Also the line width of the buffer changes. In any case, even if it were theoretically possible to keep the same driver, the context still needs to be re-created.

    One possible suggestion is to load the textures in physical memory to avoid re-loading time if they are large.

    Another suggestion could be to always allocate the larger framebuffer, and play with Viewports to position your drawing appropriately.