mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-27 23:42:58 +02:00
libtriple/framebuffer: use DirectFB acceleration
Use a hack, almost as ugly as the original Coolstream code ;), to accelerate drawing of boxes and blitting with DirectFB functions.
This commit is contained in:
@@ -21,11 +21,12 @@ static const char * FILENAME = "init_td.cpp";
|
|||||||
static bool initialized = false;
|
static bool initialized = false;
|
||||||
|
|
||||||
/* the super interface */
|
/* the super interface */
|
||||||
static IDirectFB *dfb;
|
IDirectFB *dfb;
|
||||||
/* the primary surface */
|
/* the primary surface */
|
||||||
static IDirectFBSurface *primary;
|
static IDirectFBSurface *primary;
|
||||||
static IDirectFBSurface *dest;
|
IDirectFBSurface *dfbdest;
|
||||||
static IDirectFBDisplayLayer *layer;
|
static IDirectFBDisplayLayer *layer;
|
||||||
|
int gfxfd = -1;
|
||||||
|
|
||||||
#define DFBCHECK(x...) \
|
#define DFBCHECK(x...) \
|
||||||
err = x; \
|
err = x; \
|
||||||
@@ -74,13 +75,13 @@ static void dfb_init()
|
|||||||
primary->GetPixelFormat(primary, &pixelformat);
|
primary->GetPixelFormat(primary, &pixelformat);
|
||||||
primary->GetSize(primary, &SW, &SH);
|
primary->GetSize(primary, &SW, &SH);
|
||||||
primary->Clear(primary, 0, 0, 0, 0);
|
primary->Clear(primary, 0, 0, 0, 0);
|
||||||
primary->GetSubSurface(primary, NULL, &dest);
|
primary->GetSubSurface(primary, NULL, &dfbdest);
|
||||||
dest->Clear(dest, 0, 0, 0, 0);
|
dfbdest->Clear(dfbdest, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dfb_deinit()
|
static void dfb_deinit()
|
||||||
{
|
{
|
||||||
dest->Release(dest);
|
dfbdest->Release(dfbdest);
|
||||||
primary->Release(primary);
|
primary->Release(primary);
|
||||||
layer->Release(layer);
|
layer->Release(layer);
|
||||||
dfb->Release(dfb);
|
dfb->Release(dfb);
|
||||||
@@ -119,6 +120,9 @@ void init_td_api()
|
|||||||
if (setpgid(0, pid))
|
if (setpgid(0, pid))
|
||||||
perror("setpgid");
|
perror("setpgid");
|
||||||
rc_init();
|
rc_init();
|
||||||
|
gfxfd = open("/dev/stb/tdgfx", O_RDWR);
|
||||||
|
if (gfxfd < 0)
|
||||||
|
perror("open /dev/stb/tdgfx");
|
||||||
}
|
}
|
||||||
initialized = true;
|
initialized = true;
|
||||||
fprintf(stderr, "%s:%s end\n", FILENAME, __FUNCTION__);
|
fprintf(stderr, "%s:%s end\n", FILENAME, __FUNCTION__);
|
||||||
@@ -129,5 +133,8 @@ void shutdown_td_api()
|
|||||||
fprintf(stderr, "%s:%s, initialized = %d\n", FILENAME, __FUNCTION__, (int)initialized);
|
fprintf(stderr, "%s:%s, initialized = %d\n", FILENAME, __FUNCTION__, (int)initialized);
|
||||||
if (initialized)
|
if (initialized)
|
||||||
dfb_deinit();
|
dfb_deinit();
|
||||||
|
if (gfxfd > -1)
|
||||||
|
close(gfxfd);
|
||||||
|
gfxfd = -1;
|
||||||
initialized = false;
|
initialized = false;
|
||||||
}
|
}
|
||||||
|
@@ -50,7 +50,8 @@ libneutrino_driver_a_SOURCES += \
|
|||||||
lcdd.cpp
|
lcdd.cpp
|
||||||
|
|
||||||
INCLUDES += \
|
INCLUDES += \
|
||||||
-I$(top_srcdir)/lib/libtriple
|
-I$(top_srcdir)/lib/libtriple \
|
||||||
|
@DIRECTFB_CFLAGS@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libneutrino_driver_netfile_a_SOURCES = netfile.cpp
|
libneutrino_driver_netfile_a_SOURCES = netfile.cpp
|
||||||
|
@@ -149,6 +149,27 @@ void CFrameBuffer::waitForIdle(void)
|
|||||||
}
|
}
|
||||||
#endif /* USE_NEVIS_GXA */
|
#endif /* USE_NEVIS_GXA */
|
||||||
|
|
||||||
|
#if HAVE_TRIPLEDRAGON
|
||||||
|
#include <directfb.h>
|
||||||
|
#include <tdgfx/stb04gfx.h>
|
||||||
|
extern IDirectFB *dfb;
|
||||||
|
extern IDirectFBSurface *dfbdest;
|
||||||
|
extern int gfxfd;
|
||||||
|
void CFrameBuffer::waitForIdle(void)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
struct timeval ts, te;
|
||||||
|
gettimeofday(&ts, NULL);
|
||||||
|
#endif
|
||||||
|
/* does not work: DFBResult r = dfb->WaitForSync(dfb); */
|
||||||
|
ioctl(gfxfd, STB04GFX_ENGINE_SYNC);
|
||||||
|
#if 0
|
||||||
|
gettimeofday(&te, NULL);
|
||||||
|
printf("STB04GFX_ENGINE_SYNC took %lld us\n", (te.tv_sec * 1000000LL + te.tv_usec) - (ts.tv_sec * 1000000LL + ts.tv_usec));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
|
|
||||||
static uint8_t * virtual_fb = NULL;
|
static uint8_t * virtual_fb = NULL;
|
||||||
@@ -632,9 +653,14 @@ void CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int
|
|||||||
int corner_bl = (type & CORNER_BOTTOM_LEFT) ? 1 : 0;
|
int corner_bl = (type & CORNER_BOTTOM_LEFT) ? 1 : 0;
|
||||||
int corner_br = (type & CORNER_BOTTOM_RIGHT) ? 1 : 0;
|
int corner_br = (type & CORNER_BOTTOM_RIGHT) ? 1 : 0;
|
||||||
|
|
||||||
|
#if HAVE_TRIPLEDRAGON
|
||||||
|
char *c = (char *)&col;
|
||||||
|
dfbdest->SetColor(dfbdest, c[1], c[2], c[3], c[0]);
|
||||||
|
#else
|
||||||
#ifndef USE_NEVIS_GXA
|
#ifndef USE_NEVIS_GXA
|
||||||
int swidth = stride / sizeof(fb_pixel_t);
|
int swidth = stride / sizeof(fb_pixel_t);
|
||||||
fb_pixel_t *fbp = getFrameBufferPointer() + (swidth * y);
|
fb_pixel_t *fbp = getFrameBufferPointer() + (swidth * y);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* this table contains the x coordinates for a quarter circle (the bottom right quarter) with fixed
|
/* this table contains the x coordinates for a quarter circle (the bottom right quarter) with fixed
|
||||||
@@ -720,6 +746,16 @@ void CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int
|
|||||||
ofl = corner_bl ? ofs : 0;
|
ofl = corner_bl ? ofs : 0;
|
||||||
ofr = corner_br ? ofs : 0;
|
ofr = corner_br ? ofs : 0;
|
||||||
}
|
}
|
||||||
|
#if HAVE_TRIPLEDRAGON
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int height = dy - ((corner_tl|corner_tr) + (corner_bl|corner_br)) * radius;
|
||||||
|
dfbdest->FillRectangle(dfbdest, x, y + line, dx, height);
|
||||||
|
line += height;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dfbdest->DrawLine(dfbdest, x + ofl, y + line, x + dx - ofr - 1, y + line);
|
||||||
|
#else
|
||||||
#ifdef USE_NEVIS_GXA
|
#ifdef USE_NEVIS_GXA
|
||||||
_write_gxa(gxa_base, cmd, GXA_POINT(x + dx - ofr, y + line)); /* endig point */
|
_write_gxa(gxa_base, cmd, GXA_POINT(x + dx - ofr, y + line)); /* endig point */
|
||||||
_write_gxa(gxa_base, cmd, GXA_POINT(x + ofl, y + line)); /* start point */
|
_write_gxa(gxa_base, cmd, GXA_POINT(x + ofl, y + line)); /* start point */
|
||||||
@@ -729,12 +765,14 @@ void CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int
|
|||||||
*(fbp + pos) = col;
|
*(fbp + pos) = col;
|
||||||
}
|
}
|
||||||
fbp += swidth;
|
fbp += swidth;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
line++;
|
line++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#if !HAVE_TRIPLEDRAGON
|
||||||
while (line < dy)
|
while (line < dy)
|
||||||
{
|
{
|
||||||
#ifdef USE_NEVIS_GXA
|
#ifdef USE_NEVIS_GXA
|
||||||
@@ -749,6 +787,9 @@ void CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int
|
|||||||
#endif
|
#endif
|
||||||
line++;
|
line++;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
dfbdest->FillRectangle(dfbdest, x, y + line, dx, dy - line);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef USE_NEVIS_GXA
|
#ifdef USE_NEVIS_GXA
|
||||||
/* the GXA seems to do asynchronous rendering, so we add a sync marker
|
/* the GXA seems to do asynchronous rendering, so we add a sync marker
|
||||||
@@ -757,6 +798,7 @@ void CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !HAVE_TRIPLEDRAGON
|
||||||
void CFrameBuffer::paintVLine(int x, int ya, int yb, const fb_pixel_t col)
|
void CFrameBuffer::paintVLine(int x, int ya, int yb, const fb_pixel_t col)
|
||||||
{
|
{
|
||||||
if (!getActive())
|
if (!getActive())
|
||||||
@@ -850,6 +892,43 @@ void CFrameBuffer::paintHLineRel(int x, int dx, int y, const fb_pixel_t col)
|
|||||||
*(dest++) = col;
|
*(dest++) = col;
|
||||||
#endif /* USE_NEVIS_GXA */
|
#endif /* USE_NEVIS_GXA */
|
||||||
}
|
}
|
||||||
|
#else /* TRIPLEDRAGON */
|
||||||
|
void CFrameBuffer::paintPixel(const int x, const int y, const fb_pixel_t col)
|
||||||
|
{
|
||||||
|
paintLine(x, y, x, y, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFrameBuffer::paintLine(int xa, int ya, int xb, int yb, const fb_pixel_t col)
|
||||||
|
{
|
||||||
|
if (!getActive())
|
||||||
|
return;
|
||||||
|
|
||||||
|
char *c = (char *)&col;
|
||||||
|
dfbdest->SetColor(dfbdest, c[1], c[2], c[3], c[0]);
|
||||||
|
dfbdest->DrawLine(dfbdest, xa, ya, xb, yb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFrameBuffer::paintVLine(int x, int ya, int yb, const fb_pixel_t col)
|
||||||
|
{
|
||||||
|
paintLine(x, ya, x, yb, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFrameBuffer::paintVLineRel(int x, int y, int dy, const fb_pixel_t col)
|
||||||
|
{
|
||||||
|
paintLine(x, y, x, y + dy, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFrameBuffer::paintHLine(int xa, int xb, int y, const fb_pixel_t col)
|
||||||
|
{
|
||||||
|
paintLine(xa, y, xb, y, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFrameBuffer::paintHLineRel(int x, int dx, int y, const fb_pixel_t col)
|
||||||
|
{
|
||||||
|
paintLine(x, y, x + dx, y, col);
|
||||||
|
}
|
||||||
|
#endif /* TRIPLEDRAGON */
|
||||||
|
|
||||||
void CFrameBuffer::setIconBasePath(const std::string & iconPath)
|
void CFrameBuffer::setIconBasePath(const std::string & iconPath)
|
||||||
{
|
{
|
||||||
@@ -1127,6 +1206,7 @@ void CFrameBuffer::loadPal(const std::string & filename, const unsigned char off
|
|||||||
close(lfd);
|
close(lfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !HAVE_TRIPLEDRAGON
|
||||||
void CFrameBuffer::paintPixel(const int x, const int y, const fb_pixel_t col)
|
void CFrameBuffer::paintPixel(const int x, const int y, const fb_pixel_t col)
|
||||||
{
|
{
|
||||||
if (!getActive())
|
if (!getActive())
|
||||||
@@ -1142,6 +1222,7 @@ void CFrameBuffer::paintPixel(const int x, const int y, const fb_pixel_t col)
|
|||||||
*pos = col;
|
*pos = col;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void CFrameBuffer::paintBoxFrame(const int sx, const int sy, const int dx, const int dy, const int px, const fb_pixel_t col, const int rad)
|
void CFrameBuffer::paintBoxFrame(const int sx, const int sy, const int dx, const int dy, const int px, const fb_pixel_t col, const int rad)
|
||||||
{
|
{
|
||||||
@@ -1204,6 +1285,7 @@ void CFrameBuffer::paintBoxFrame(const int sx, const int sy, const int dx, const
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !HAVE_TRIPLEDRAGON
|
||||||
void CFrameBuffer::paintLine(int xa, int ya, int xb, int yb, const fb_pixel_t col)
|
void CFrameBuffer::paintLine(int xa, int ya, int xb, int yb, const fb_pixel_t col)
|
||||||
{
|
{
|
||||||
if (!getActive())
|
if (!getActive())
|
||||||
@@ -1291,6 +1373,7 @@ void CFrameBuffer::paintLine(int xa, int ya, int xb, int yb, const fb_pixel_t co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void CFrameBuffer::setBackgroundColor(const fb_pixel_t color)
|
void CFrameBuffer::setBackgroundColor(const fb_pixel_t color)
|
||||||
{
|
{
|
||||||
@@ -1677,6 +1760,7 @@ void * CFrameBuffer::convertRGBA2FB(unsigned char *rgbbuff, unsigned long x, uns
|
|||||||
return int_convertRGB2FB(rgbbuff, x, y, 0, true);
|
return int_convertRGB2FB(rgbbuff, x, y, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !HAVE_TRIPLEDRAGON
|
||||||
void CFrameBuffer::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool transp)
|
void CFrameBuffer::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool transp)
|
||||||
{
|
{
|
||||||
int xc, yc;
|
int xc, yc;
|
||||||
@@ -1729,6 +1813,41 @@ void CFrameBuffer::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void CFrameBuffer::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp, uint32_t yp, bool transp)
|
||||||
|
{
|
||||||
|
DFBRectangle src;
|
||||||
|
DFBResult err;
|
||||||
|
IDirectFBSurface *surf;
|
||||||
|
DFBSurfaceDescription dsc;
|
||||||
|
|
||||||
|
src.x = xp;
|
||||||
|
src.y = yp;
|
||||||
|
src.w = width - xp;
|
||||||
|
src.h = height - yp;
|
||||||
|
|
||||||
|
dsc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PREALLOCATED);
|
||||||
|
dsc.caps = DSCAPS_NONE;
|
||||||
|
dsc.width = width;
|
||||||
|
dsc.height = height;
|
||||||
|
dsc.preallocated[0].data = fbbuff;
|
||||||
|
dsc.preallocated[0].pitch = width * sizeof(fb_pixel_t);
|
||||||
|
err = dfb->CreateSurface(dfb, &dsc, &surf);
|
||||||
|
/* TODO: maybe we should not die if this fails? */
|
||||||
|
if (err != DFB_OK) {
|
||||||
|
fprintf(stderr, "CFrameBuffer::blit2FB: ");
|
||||||
|
DirectFBErrorFatal("dfb->CreateSurface(dfb, &dsc, &surf)", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transp)
|
||||||
|
surf->SetSrcColorKey(surf, 0, 0, 0);
|
||||||
|
|
||||||
|
dfbdest->SetBlittingFlags(dfbdest, DSBLIT_SRC_COLORKEY);
|
||||||
|
dfbdest->Blit(dfbdest, surf, &src, xoff, yoff);
|
||||||
|
surf->Release(surf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void CFrameBuffer::displayRGB(unsigned char *rgbbuff, int x_size, int y_size, int x_pan, int y_pan, int x_offs, int y_offs, bool clearfb, int transp)
|
void CFrameBuffer::displayRGB(unsigned char *rgbbuff, int x_size, int y_size, int x_pan, int y_pan, int x_offs, int y_offs, bool clearfb, int transp)
|
||||||
{
|
{
|
||||||
|
@@ -214,8 +214,12 @@ class CFrameBuffer
|
|||||||
#ifdef USE_NEVIS_GXA
|
#ifdef USE_NEVIS_GXA
|
||||||
void add_gxa_sync_marker(void);
|
void add_gxa_sync_marker(void);
|
||||||
void waitForIdle(void);
|
void waitForIdle(void);
|
||||||
|
#else
|
||||||
|
#if HAVE_TRIPLEDRAGON
|
||||||
|
void waitForIdle(void);
|
||||||
#else
|
#else
|
||||||
inline void waitForIdle(void) {};
|
inline void waitForIdle(void) {};
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
void* convertRGB2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y, int transp = 0xFF);
|
void* convertRGB2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y, int transp = 0xFF);
|
||||||
void* convertRGBA2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y);
|
void* convertRGBA2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y);
|
||||||
|
Reference in New Issue
Block a user