diff --git a/src/driver/Makefile.am b/src/driver/Makefile.am index 5c41feb9c..5cc0574bf 100644 --- a/src/driver/Makefile.am +++ b/src/driver/Makefile.am @@ -69,4 +69,10 @@ endif # simple_display.cpp #endif +if BOXTYPE_GENERIC +libneutrino_driver_a_SOURCES += \ + fb_accel_glfb.cpp \ + simple_display.cpp +endif + libneutrino_driver_netfile_a_SOURCES = netfile.cpp diff --git a/src/driver/fb_accel.h b/src/driver/fb_accel.h index de4d3270f..67225d44a 100644 --- a/src/driver/fb_accel.h +++ b/src/driver/fb_accel.h @@ -134,4 +134,25 @@ class CFbAccelCSApollo void setBlendLevel(int); }; +class CFbAccelGLFB + : public OpenThreads::Thread, public CFbAccel +{ + private: + void run(void); + void blit(void); + void _blit(void); + bool blit_thread; + bool blit_pending; + OpenThreads::Condition blit_cond; + OpenThreads::Mutex blit_mutex; + fb_pixel_t *backbuffer; + public: + CFbAccelGLFB(); + ~CFbAccelGLFB(); + void init(const char * const); + int setMode(unsigned int xRes, unsigned int yRes, unsigned int bpp); + void blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool transp); + fb_pixel_t * getBackBufferPointer() const; +}; + #endif diff --git a/src/driver/fb_accel_glfb.cpp b/src/driver/fb_accel_glfb.cpp new file mode 100644 index 000000000..f6784c48f --- /dev/null +++ b/src/driver/fb_accel_glfb.cpp @@ -0,0 +1,149 @@ +/* + Framebuffer acceleration hardware abstraction functions. + This implements stuff needed by the GL Framebuffer. + Not really accelerated ;-) + + (C) 2017 Stefan Seyfried + + License: GPL + + 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 2 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 . +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include + +#include +extern GLFramebuffer *glfb; + +#include +#include + +#define LOGTAG "[fb_glfb] " + +CFbAccelGLFB::CFbAccelGLFB() +{ + fb_name = "GL ramebuffer"; +} + +void CFbAccelGLFB::init(const char *) +{ + fd = -1; + if (!glfb) { + fprintf(stderr, LOGTAG "init: GL Framebuffer is not set up? we are doomed...\n"); + return; + } + screeninfo = glfb->getScreenInfo(); + stride = 4 * screeninfo.xres; + available = glfb->getOSDBuffer()->size(); /* allocated in glfb constructor */ + lbb = lfb = reinterpret_cast(glfb->getOSDBuffer()->data()); + + memset(lfb, 0, available); + setMode(720, 576, 8 * sizeof(fb_pixel_t)); + + blit_thread = false; + /* start the autoblit-thread (run() function) */ + OpenThreads::Thread::start(); +}; + +CFbAccelGLFB::~CFbAccelGLFB() +{ + if (blit_thread) + { + blit_thread = false; + blit(); /* wakes up the thread */ + OpenThreads::Thread::join(); + } +} + +void CFbAccelGLFB::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool transp) +{ + CFrameBuffer::blit2FB(fbbuff, width, height, xoff, yoff, xp, yp, transp); + blit(); +} + +#define BLIT_INTERVAL_MIN 40 +#define BLIT_INTERVAL_MAX 250 +void CFbAccelGLFB::run() +{ + printf(LOGTAG "run start\n"); + time_t last_blit = 0; + blit_pending = false; + blit_thread = true; + blit_mutex.lock(); + set_threadname("glfb::autoblit"); + while (blit_thread) { + blit_cond.wait(&blit_mutex, blit_pending ? BLIT_INTERVAL_MIN : BLIT_INTERVAL_MAX); + time_t now = time_monotonic_ms(); + if (now - last_blit < BLIT_INTERVAL_MIN) + { + blit_pending = true; + //printf(LOGTAG "run: skipped, time %ld\n", now - last_blit); + } + else + { + blit_pending = false; + blit_mutex.unlock(); + _blit(); + blit_mutex.lock(); + last_blit = now; + } + } + blit_mutex.unlock(); + printf(LOGTAG "run end\n"); +} + +void CFbAccelGLFB::blit() +{ + //printf(LOGTAG "blit\n"); + blit_mutex.lock(); + blit_cond.signal(); + blit_mutex.unlock(); +} + +void CFbAccelGLFB::_blit() +{ + if (glfb) + glfb->blit(); +} + +/* wrong name... */ +int CFbAccelGLFB::setMode(unsigned int, unsigned int, unsigned int) +{ + xRes = screeninfo.xres; + yRes = screeninfo.yres; + bpp = screeninfo.bits_per_pixel; + int needmem = stride * yRes * 2; + if (available >= needmem) + { + backbuffer = lfb + stride / sizeof(fb_pixel_t) * yRes; + return 0; + } + fprintf(stderr, LOGTAG " not enough FB memory (have %d, need %d)\n", available, needmem); + backbuffer = lfb; /* will not work well, but avoid crashes */ + return 0; +} + +fb_pixel_t * CFbAccelGLFB::getBackBufferPointer() const +{ + return backbuffer; +} diff --git a/src/driver/fb_generic.cpp b/src/driver/fb_generic.cpp index ec1dc1540..90ac9ad5f 100644 --- a/src/driver/fb_generic.cpp +++ b/src/driver/fb_generic.cpp @@ -129,6 +129,9 @@ CFrameBuffer* CFrameBuffer::getInstance() #else frameBuffer = new CFbAccelCSNevis(); #endif +#endif +#if HAVE_GENERIC_HARDWARE + frameBuffer = new CFbAccelGLFB(); #endif if (!frameBuffer) frameBuffer = new CFrameBuffer();