Я хочу клонировать содержимое кадрового буфера из / dev / fb0 в / dev / fb2.Я использую iMx6Q под управлением Debian 8, а мое приложение работает на Qt5.Я не использую X11 или Wayland.Приложение работает на дисплее LVDS с разрешением 1280x800 пикселей и адресуется по адресу framebuffer / dev / fb0.На кадровом буфере / dev / fb2 я обратился к выходу HDMI с разрешением 1920x1080 пикселей.
Я написал AC-код, который клонирует от 1280x800 до 1920x1080 кадрового буфера, но это неэффективно.
1-Как сделать это более эффективным?
2-Как увеличить масштаб с 1280x800 до 1920x1080?
3-Как повернуть кадровый буфер до 180 ° в 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();
}