1

I want to clone framebuffer content from /dev/fb0 to /dev/fb2. I am using iMx6Q running Debian 8 and my application runs on Qt5. I am not using X11 or Wayland. The application runs on a LVDS Display with 1280x800 pixels and it is addressed at framebuffer /dev/fb0. On the framebuffer /dev/fb2 i have addressed HDMI output with 1920x1080 pixels.

I wrote a c code that clones from 1280x800 to 1920x1080 framebuffer, but this is not efficient.

1-How to make this more efficient?
2-How to up scale 1280x800 to 1920x1080?
3-How to rotate framebuffer to 180° in C?

#include <stdio.h>
#include <syslog.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

inline uint32_t pixel_color(uint8_t r, uint8_t g, uint8_t b, struct fb_var_screeninfo *vinfo)
{
    return (r<<vinfo->red.offset) | (g<<vinfo->green.offset) | (b<<vinfo->blue.offset);
}

int process() {

    uint32_t image_prt;
    long int location = 0;
    int ret;
    int fbfd = 0;
    int fbfd2 = 0;
    uint8_t *fbp=0;
    uint8_t *fbp0=0; 
    int x=0, y=0;
    printf("Display Clone Frame Buffer fb0 to fb2\n");

    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;
    struct fb_var_screeninfo vinfo2;
    struct fb_fix_screeninfo finfo2;


    fbfd = open("/dev/fb0", O_RDWR);
    if (fbfd == -1) {
        printf("Unable to open first display");
        return -1;
    }
    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
        printf("Unable to get first display information");
        return -1;
    }
    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
        printf("Unable to get first display information");
        return -1;
    }

    printf("First display is %d x %d %dbps\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);

    fbfd2 = open("/dev/fb2", O_RDWR);
    if (fbfd2 == -1) {
        printf("Unable to open secondary display");
        return -1;
    }
    if (ioctl(fbfd2, FBIOGET_FSCREENINFO, &finfo2)) {
        printf("Unable to get secondary display information");
        return -1;
    }
    if (ioctl(fbfd2, FBIOGET_VSCREENINFO, &vinfo2)) {
        printf("Unable to get secondary display information");
        return -1;
    }

    printf("Second display is %d x %d %dbps\n", vinfo2.xres, vinfo2.yres, vinfo2.bits_per_pixel);


   fbp = mmap(0, vinfo2.yres_virtual * finfo2.line_length, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd2,(off_t)0); 
   if (fbp <= 0) 
    {
        printf("Unable to create memory mapping");
        close(fbfd2);
        return -1;
    }

   fbp0 = mmap(0, vinfo.yres_virtual * finfo.line_length, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd,(off_t)0); 
   if (fbp0 <= 0) 
    {
        printf("Unable to create memory mapping");
        close(fbfd);
        return -1;
    }

    long int screensize = finfo.smem_len;
        long pix_offset;
    long pix_offset_LVDS;


        for (x = 0; x < vinfo2.xres; x++) 
        {
                for (y = 0; y < vinfo2.yres;y++) 
                {
                        pix_offset = (x+vinfo2.xoffset) * (vinfo2.bits_per_pixel/8) + (y+vinfo2.yoffset) * finfo2.line_length;

                         *((uint32_t*)(fbp + pix_offset)) = pixel_color(0x00,0x00,0xFF, &vinfo2);
                }
        }



    while (1) 
    {
    //memcpy(fbp,fbp0, screensize);
        for (x = 0; x < vinfo.xres; x++) 
    {
            for (y = 0; y < vinfo.yres;y++) 
        {
                pix_offset = (x+vinfo2.xoffset) * (vinfo2.bits_per_pixel/8) + (y+vinfo2.yoffset) * finfo2.line_length;
            pix_offset_LVDS=(x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + (y+vinfo.yoffset) * finfo.line_length;
                *((uint32_t*)(fbp + pix_offset)) =*((uint32_t*) (fbp0 + pix_offset_LVDS));

            }
        }

    usleep(25 * 1000);
    }

    munmap(fbp, screensize);
    close(fbfd);
}

int main(int argc, char **argv) {
    setlogmask(LOG_UPTO(LOG_DEBUG));
    openlog("fbcp", LOG_NDELAY | LOG_PID, LOG_USER);

    return process();
}
  • For 3rd question, refer here: https://stackoverflow.com/questions/56601993/how-to-rotate-a-qt5-application-using-the-linux-framebuffer Try upsampling the image externally to get the required resolution. – abunickabhi Sep 13 '19 at 08:06

0 Answers0