/*
* 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
}