X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/9bc92cbd0be7b1973960e88808feaca26a00aecd..d34456e1eb1869b92e221e9b18be04efff3a804c:/lib/gdi/fb.cpp diff --git a/lib/gdi/fb.cpp b/lib/gdi/fb.cpp index c8fd94be..e5bb46d0 100644 --- a/lib/gdi/fb.cpp +++ b/lib/gdi/fb.cpp @@ -7,13 +7,16 @@ #include #include -#include #include #ifndef FBIO_WAITFORVSYNC #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) #endif +#ifndef FBIO_BLIT +#define FBIO_SET_MANUAL_BLIT _IOW('F', 0x21, __u8) +#define FBIO_BLIT 0x22 +#endif fbClass *fbClass::instance; @@ -24,9 +27,11 @@ fbClass *fbClass::getInstance() fbClass::fbClass(const char *fb) { + lfb=0; + fb_fix_screeninfo fix; + m_manual_blit=-1; instance=this; locked=0; - available=0; cmap.start=0; cmap.len=256; cmap.red=red; @@ -36,39 +41,25 @@ fbClass::fbClass(const char *fb) fd=open(fb, O_RDWR); if (fd<0) - { perror(fb); - goto nolfb; - } - if (ioctl(fd, FBIOGET_VSCREENINFO, &screeninfo)<0) - { + else if (ioctl(fd, FBIOGET_VSCREENINFO, &screeninfo)<0) perror("FBIOGET_VSCREENINFO"); - goto nolfb; - } - - memcpy(&oldscreen, &screeninfo, sizeof(screeninfo)); - - fb_fix_screeninfo fix; - if (ioctl(fd, FBIOGET_FSCREENINFO, &fix)<0) - { + else if (ioctl(fd, FBIOGET_FSCREENINFO, &fix)<0) perror("FBIOGET_FSCREENINFO"); - goto nolfb; - } - - available=fix.smem_len; - eDebug("%dk video mem", available/1024); - lfb=(unsigned char*)mmap(0, available, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); - if (!lfb) + else { - perror("mmap"); - goto nolfb; + memcpy(&oldscreen, &screeninfo, sizeof(screeninfo)); + available=fix.smem_len; + lfb=(unsigned char*)mmap(0, available, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); + if (!lfb) + perror("mmap"); + else + { + showConsole(0); + enableManualBlit(); + stride=fix.line_length; + } } - - showConsole(0); - return; -nolfb: - lfb=0; - printf("framebuffer not available.\n"); return; } @@ -94,7 +85,12 @@ int fbClass::SetMode(unsigned int nxRes, unsigned int nyRes, unsigned int nbpp) screeninfo.width=0; screeninfo.xoffset=screeninfo.yoffset=0; screeninfo.bits_per_pixel=nbpp; - + + if (lfb) { + munmap(lfb, available); + lfb = 0; + } + if (ioctl(fd, FBIOPUT_VSCREENINFO, &screeninfo)<0) { // try single buffering @@ -112,6 +108,8 @@ int fbClass::SetMode(unsigned int nxRes, unsigned int nyRes, unsigned int nbpp) m_number_of_pages = screeninfo.yres_virtual / nyRes; + ioctl(fd, FBIOGET_VSCREENINFO, &screeninfo); + if ((screeninfo.xres!=nxRes) && (screeninfo.yres!=nyRes) && (screeninfo.bits_per_pixel!=nbpp)) { eDebug("SetMode failed: wanted: %dx%dx%d, got %dx%dx%d", @@ -121,15 +119,31 @@ int fbClass::SetMode(unsigned int nxRes, unsigned int nyRes, unsigned int nbpp) xRes=screeninfo.xres; yRes=screeninfo.yres; bpp=screeninfo.bits_per_pixel; + fb_fix_screeninfo fix; if (ioctl(fd, FBIOGET_FSCREENINFO, &fix)<0) { perror("FBIOGET_FSCREENINFO"); printf("fb failed\n"); + goto nolfb; + } + + available=fix.smem_len; + eDebug("%dk video mem", available/1024); + lfb=(unsigned char*)mmap(0, available, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); + if (!lfb) + { + perror("mmap"); + goto nolfb; } + stride=fix.line_length; - memset(lfb, 0, stride*yRes); + return 0; +nolfb: + lfb=0; + eFatal("framebuffer no more ready after SetMode(%d, %d, %d)", nxRes, nyRes, nbpp); + return -1; } int fbClass::setOffset(int off) @@ -145,6 +159,14 @@ int fbClass::waitVSync() return ioctl(fd, FBIO_WAITFORVSYNC, &c); } +void fbClass::blit() +{ + if (m_manual_blit == 1) { + if (ioctl(fd, FBIO_BLIT) < 0) + perror("FBIO_BLIT"); + } +} + fbClass::~fbClass() { if (available) @@ -152,6 +174,7 @@ fbClass::~fbClass() if (lfb) munmap(lfb, available); showConsole(1); + disableManualBlit(); } int fbClass::PutCMAP() @@ -163,7 +186,13 @@ int fbClass::lock() { if (locked) return -1; - locked=1; + if (m_manual_blit == 1) + { + locked = 2; + disableManualBlit(); + } + else + locked = 1; return fd; } @@ -171,7 +200,28 @@ void fbClass::unlock() { if (!locked) return; + if (locked == 2) // re-enable manualBlit + enableManualBlit(); locked=0; SetMode(xRes, yRes, bpp); PutCMAP(); } + +void fbClass::enableManualBlit() +{ + unsigned char tmp = 1; + if (ioctl(fd,FBIO_SET_MANUAL_BLIT, &tmp)<0) + perror("FBIO_SET_MANUAL_BLIT"); + else + m_manual_blit = 1; +} + +void fbClass::disableManualBlit() +{ + unsigned char tmp = 0; + if (ioctl(fd,FBIO_SET_MANUAL_BLIT, &tmp)<0) + perror("FBIO_SET_MANUAL_BLIT"); + else + m_manual_blit = 0; +} +