/* * secde -- experimental lightweight Wayland/X11 server * Copyright (C) 2019 Samuel Lidén Borell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include "fbdev.h" #include "fbops.h" static unsigned char *mapfb(int fd) { struct fb_fix_screeninfo fixinfo; if (ioctl(fd, FBIOGET_FSCREENINFO, &fixinfo) == -1) { perror("Failed to get framebuffer fscreeninfo (ioctl failed)"); return NULL; } printf("fbmem Start: %lx, length: %x\n", fixinfo.smem_start, fixinfo.smem_len); printf("MMIO Start: %lx, length: %x\n", fixinfo.mmio_start, fixinfo.mmio_len); return mmap(NULL, fixinfo.smem_len, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0/*fixinfo.smem_start*/); /* return mmap(NULL, fixinfo.smem_len, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0) + fixinfo.smem_start; */ /*return mmap(NULL, fixinfo.mmio_len, PROT_WRITE|PROT_READ, MAP_SHARED, fd, fixinfo.mmio_start);*/ /*return mmap(NULL, 1920*1080*3, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);*/ } int display_fbdev_init(struct FdInfo *info) { (void) info; /* TODO */ return 1; } void display_fbdev_test(struct FdInfo *info) { int fd; unsigned char *screenptr; int x, y, w, h, i, bypp; struct fb_fix_screeninfo fixinfo; struct fb_var_screeninfo varinfo; struct FbPixelFormat format; struct FbSurf screen; struct FbDestSurf screendest = { &screen, &format }; struct FbSurf offscreen; struct FbDestSurf offscreendest = { &offscreen, &format }; fd = protohnd_getfd(info); screenptr = mapfb(fd); if (!screenptr) { perror("Failed to map framebuffer"); return; } if (ioctl(fd, FBIOGET_FSCREENINFO, &fixinfo) == -1) { perror("Failed to get framebuffer fscreeninfo (ioctl failed)"); return; } if (ioctl(fd, FBIOGET_VSCREENINFO, &varinfo) == -1) { perror("Failed to get framebuffer vscreeninfo (ioctl failed)"); return; } screen.w = varinfo.xres; screen.h = varinfo.yres; screen.line_length = fixinfo.line_length; screen.pixels = screenptr; format.bytes_per_pixel = varinfo.bits_per_pixel/8; offscreen.w = varinfo.xres; offscreen.h = 1; offscreen.line_length = offscreen.w*format.bytes_per_pixel; printf("offscreen width: %d, bypp: %d, len %d\n", offscreen.w, format.bytes_per_pixel, offscreen.line_length); offscreen.pixels = malloc(offscreen.line_length); #if 0 printf("Test time\n"); /*x = 100; w = 800; h = 900; for (y = 30; y < 30+h; y++) { memset(&screen[(x+varinfo.xoffset)*(varinfo.bits_per_pixel/8) + ((y+varinfo.yoffset)*fixinfo.line_length)], 0xFF, w*(varinfo.bits_per_pixel/8)); }*/ bypp = (varinfo.bits_per_pixel/8); /* * RPI3 perf: 255*20 frames = 5100 frames * * single memset: 28.213s = 180.8 fps * multiple memsets w/ mult: 28.134s (faster, so probably no diff) * multiple memcpys w/ mult: 28.063s (faster, so probably no diff) * scrolling w/ 17 px margin: 108.305s = 47 fps * scrolling w/ 32 px margin: 100.932s = 50.5 fps (so not an alignment problem) * copying row 0: 113.445s = 45.0 fps (so not a cache problem?) * "scrolling" w/o read: 29.560s = 172.5 fps ( = reading from the framebuffer is slow!) */ for (i = 0; i <= 255*20; i++){ /*x = 0; w = 1920; for (y = 0; y < 1080; y++) { memset(&screen[(x+varinfo.xoffset)*bypp + ((y+varinfo.yoffset)*fixinfo.line_length)], i, w*(varinfo.bits_per_pixel/8)); }*/ /*memset(screen, i, fixinfo.line_length*1080);*/ /*x = 0; w = 1920; for (y = 0; y < 1080; y++) { memcpy(&screen[(x+varinfo.xoffset)*bypp + ((y+varinfo.yoffset)*fixinfo.line_length)], (char*)info-1024 + i, w*(varinfo.bits_per_pixel/8)); }*/ int m = 0; struct FbRect rect1, rect2, rect3; rect1.x = 0; rect1.y = 0; rect1.w = screen.w - 2*m; rect1.h = 1; rect2.x = m; rect2.y = m; rect2.w = rect1.w; rect2.h = 1; fbops_copysurf1(&offscreendest, 0, 0, &screen, &rect2); rect3.x = m; rect3.y = m+1; rect3.w = screen.w - 2*m; rect3.h = screen.h - 2*m - 1; fbops_moverect(&screendest, m, m, &rect3); fbops_copysurf1(&screendest, m, screen.h - m - 1, &offscreen, &rect1); } exit(0); /*screen[0] = 0xFF;*/ /*printf("pixel 0 = %d\n", screen[(varinfo.xoffset)*(varinfo.bits_per_pixel/8) + (y+varinfo.yoffset) * fixinfo.line_length]);*/ /*screen[(varinfo.xoffset)*(varinfo.bits_per_pixel/8) + (y+varinfo.yoffset) * fixinfo.line_length] = 0xFF;*/ #endif }