X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/40253d1a081381a643b8841aeb2914f75211ddb9..2048bec4bfd7a99833b50557020a43d05d92ac8b:/lib/gdi/fb.cpp diff --git a/lib/gdi/fb.cpp b/lib/gdi/fb.cpp index 38ae37dd..cde3e357 100644 --- a/lib/gdi/fb.cpp +++ b/lib/gdi/fb.cpp @@ -7,9 +7,17 @@ #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; fbClass *fbClass::getInstance() @@ -19,6 +27,7 @@ fbClass *fbClass::getInstance() fbClass::fbClass(const char *fb) { + m_manual_blit=-1; instance=this; locked=0; available=0; @@ -35,6 +44,8 @@ fbClass::fbClass(const char *fb) perror(fb); goto nolfb; } + + if (ioctl(fd, FBIOGET_VSCREENINFO, &screeninfo)<0) { perror("FBIOGET_VSCREENINFO"); @@ -51,6 +62,7 @@ fbClass::fbClass(const char *fb) } available=fix.smem_len; + m_phys_mem = fix.smem_start; eDebug("%dk video mem", available/1024); lfb=(unsigned char*)mmap(0, available, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); if (!lfb) @@ -59,7 +71,9 @@ fbClass::fbClass(const char *fb) goto nolfb; } -// showConsole(0); + showConsole(0); + + enableManualBlit(); return; nolfb: lfb=0; @@ -84,17 +98,56 @@ int fbClass::showConsole(int state) int fbClass::SetMode(unsigned int nxRes, unsigned int nyRes, unsigned int nbpp) { screeninfo.xres_virtual=screeninfo.xres=nxRes; - screeninfo.yres_virtual=screeninfo.yres=nyRes; + screeninfo.yres_virtual=(screeninfo.yres=nyRes)*2; screeninfo.height=0; screeninfo.width=0; screeninfo.xoffset=screeninfo.yoffset=0; screeninfo.bits_per_pixel=nbpp; + + switch (nbpp) { + case 16: + // ARGB 1555 + screeninfo.transp.offset = 15; + screeninfo.transp.length = 1; + screeninfo.red.offset = 10; + screeninfo.red.length = 5; + screeninfo.green.offset = 5; + screeninfo.green.length = 5; + screeninfo.blue.offset = 0; + screeninfo.blue.length = 5; + break; + case 32: + // ARGB 8888 + screeninfo.transp.offset = 24; + screeninfo.transp.length = 8; + screeninfo.red.offset = 16; + screeninfo.red.length = 8; + screeninfo.green.offset = 8; + screeninfo.green.length = 8; + screeninfo.blue.offset = 0; + screeninfo.blue.length = 8; + break; + } + if (ioctl(fd, FBIOPUT_VSCREENINFO, &screeninfo)<0) { - perror("FBIOPUT_VSCREENINFO"); - printf("fb failed\n"); - return -1; - } + // try single buffering + screeninfo.yres_virtual=screeninfo.yres=nyRes; + + if (ioctl(fd, FBIOPUT_VSCREENINFO, &screeninfo)<0) + { + perror("FBIOPUT_VSCREENINFO"); + printf("fb failed\n"); + return -1; + } + eDebug(" - double buffering not available."); + } else + eDebug(" - double buffering available!"); + + 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", @@ -115,68 +168,53 @@ int fbClass::SetMode(unsigned int nxRes, unsigned int nyRes, unsigned int nbpp) return 0; } -fbClass::~fbClass() +int fbClass::setOffset(int off) { - if (available) - ioctl(fd, FBIOPUT_VSCREENINFO, &oldscreen); - if (lfb) - munmap(lfb, available); - showConsole(1); + screeninfo.xoffset = 0; + screeninfo.yoffset = off; + return ioctl(fd, FBIOPAN_DISPLAY, &screeninfo); } -int fbClass::PutCMAP() +int fbClass::waitVSync() { - return ioctl(fd, FBIOPUTCMAP, &cmap); + int c = 0; + return ioctl(fd, FBIO_WAITFORVSYNC, &c); } -void fbClass::Box(int x, int y, int width, int height, int color, int backcolor) +void fbClass::blit() { - if (width<=2 || locked) - return; - int offset=y*stride+x/2; - int first=0xF0|((color&0xF0)>>4); - int last= 0xF0|((backcolor&0xF0)>>4); - color=(color&0xF)*0x11; - int halfwidth=width/2; - for (int ay=y; ay<(y+height); ay++) - { - lfb[offset]=first; - memset(lfb+offset+1, color, halfwidth-2); - lfb[offset+halfwidth-1]=last; - offset+=stride; + if (m_manual_blit == 1) { + if (ioctl(fd, FBIO_BLIT) < 0) + perror("FBIO_BLIT"); } } -void fbClass::NBox(int x, int y, int width, int height, int color) +fbClass::~fbClass() { - if (locked) - return; - int offset=y*stride+x/2; - int halfwidth=width/2; - for (int ay=y; ay<(y+height); ay++) - { - memset(lfb+offset, color, halfwidth); - offset+=stride; - } + if (available) + ioctl(fd, FBIOPUT_VSCREENINFO, &oldscreen); + if (lfb) + munmap(lfb, available); + showConsole(1); + disableManualBlit(); } -void fbClass::VLine(int x, int y, int sy, int color) +int fbClass::PutCMAP() { - if (locked) - return; - int offset=y*stride+x/2; - while (sy--) - { - lfb[offset]=color; - offset+=stride; - } + return ioctl(fd, FBIOPUTCMAP, &cmap); } int fbClass::lock() { if (locked) return -1; - locked=1; + if (m_manual_blit == 1) + { + locked = 2; + disableManualBlit(); + } + else + locked = 1; return fd; } @@ -184,7 +222,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; +} +