mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-30 00:41:17 +02:00
spark: use blitter to scale to non-720p framebuffer resolutions
Let everyone render in an offscreen buffer of 1280x720 pixels, then blit to primary, scaling to target resolution. This will need some calls to ->blit() sprinkled all over neutrino which will come in a follow-up commit.
This commit is contained in:
@@ -233,15 +233,11 @@ class CFrameBuffer
|
|||||||
bool blitToPrimary(unsigned int * data, int dx, int dy, int sw, int sh);
|
bool blitToPrimary(unsigned int * data, int dx, int dy, int sw, int sh);
|
||||||
|
|
||||||
#if HAVE_SPARK_HARDWARE
|
#if HAVE_SPARK_HARDWARE
|
||||||
int scaleX(const int x, bool clamp = true);
|
void mark(int x, int y, int dx, int dy);
|
||||||
int scaleY(const int y, bool clamp = true);
|
void blit(void);
|
||||||
void resize(int format);
|
|
||||||
void update(void);
|
|
||||||
#else
|
#else
|
||||||
int scaleX(const int x, bool __attribute__((unused)) clamp = true) { return x; };
|
void mark(int, int, int, int) {};
|
||||||
int scaleY(const int y, bool __attribute__((unused)) clamp = true) { return y; };
|
void blit(void) {};
|
||||||
void resize(int) {};
|
|
||||||
void update(void) {};
|
|
||||||
#endif
|
#endif
|
||||||
void paintMuteIcon(bool paint, int ax, int ay, int dx, int dy, bool paintFrame=true);
|
void paintMuteIcon(bool paint, int ax, int ay, int dx, int dy, bool paintFrame=true);
|
||||||
|
|
||||||
|
@@ -50,6 +50,8 @@
|
|||||||
#include <linux/stmfb.h>
|
#include <linux/stmfb.h>
|
||||||
#include <bpamem.h>
|
#include <bpamem.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#define DEFAULT_XRES 1280
|
#define DEFAULT_XRES 1280
|
||||||
#define DEFAULT_YRES 720
|
#define DEFAULT_YRES 720
|
||||||
|
|
||||||
@@ -61,11 +63,44 @@ extern CPictureViewer * g_PicViewer;
|
|||||||
#define BACKGROUNDIMAGEWIDTH 720
|
#define BACKGROUNDIMAGEWIDTH 720
|
||||||
|
|
||||||
static int bpafd = -1;
|
static int bpafd = -1;
|
||||||
static fb_pixel_t *backbuffer = NULL;
|
static fb_pixel_t *backbuffer = NULL; /* buffer in BPA mem, mostly for tuxtxt or icons */
|
||||||
static int fake_xRes = 0;
|
static fb_pixel_t *lbb; /* "shadow buffer", will be scale-blitted to the FB */
|
||||||
static int fake_yRes = 0;
|
static size_t lbb_sz = 1920 * 1080; /* offset from fb start in 'pixels' */
|
||||||
static int fake_stride = 0;
|
static size_t lbb_off = lbb_sz * sizeof(fb_pixel_t); /* offset from fb start in bytes */
|
||||||
static int backbuf_sz = 0;
|
static int backbuf_sz = 0;
|
||||||
|
static unsigned int last_xres = 0;
|
||||||
|
|
||||||
|
struct dirty_region {
|
||||||
|
int xs;
|
||||||
|
int ys;
|
||||||
|
int xe;
|
||||||
|
int ye;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dirty_region to_blit = { INT_MAX, INT_MAX, 0, 0 };
|
||||||
|
static pthread_mutex_t blit_mutex;
|
||||||
|
|
||||||
|
static inline void blit_lock()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&blit_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void blit_unlock()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&blit_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void update_dirty(int xs, int ys, int xe, int ye)
|
||||||
|
{
|
||||||
|
if (xs < to_blit.xs)
|
||||||
|
to_blit.xs = xs;
|
||||||
|
if (xe > to_blit.xe)
|
||||||
|
to_blit.xe = xe;
|
||||||
|
if (ys < to_blit.ys)
|
||||||
|
to_blit.ys = ys;
|
||||||
|
if (ye > to_blit.ye)
|
||||||
|
to_blit.ye = ye;
|
||||||
|
}
|
||||||
|
|
||||||
void CFrameBuffer::waitForIdle(void)
|
void CFrameBuffer::waitForIdle(void)
|
||||||
{
|
{
|
||||||
@@ -73,7 +108,9 @@ void CFrameBuffer::waitForIdle(void)
|
|||||||
struct timeval ts, te;
|
struct timeval ts, te;
|
||||||
gettimeofday(&ts, NULL);
|
gettimeofday(&ts, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
blit_lock();
|
||||||
ioctl(fd, STMFBIO_SYNC_BLITTER);
|
ioctl(fd, STMFBIO_SYNC_BLITTER);
|
||||||
|
blit_unlock();
|
||||||
#if 0
|
#if 0
|
||||||
gettimeofday(&te, NULL);
|
gettimeofday(&te, NULL);
|
||||||
printf("STMFBIO_SYNC_BLITTER took %lld us\n", (te.tv_sec * 1000000LL + te.tv_usec) - (ts.tv_sec * 1000000LL + ts.tv_usec));
|
printf("STMFBIO_SYNC_BLITTER took %lld us\n", (te.tv_sec * 1000000LL + te.tv_usec) - (ts.tv_sec * 1000000LL + ts.tv_usec));
|
||||||
@@ -117,6 +154,7 @@ CFrameBuffer::CFrameBuffer()
|
|||||||
memset(green, 0, 256*sizeof(__u16));
|
memset(green, 0, 256*sizeof(__u16));
|
||||||
memset(blue, 0, 256*sizeof(__u16));
|
memset(blue, 0, 256*sizeof(__u16));
|
||||||
memset(trans, 0, 256*sizeof(__u16));
|
memset(trans, 0, 256*sizeof(__u16));
|
||||||
|
pthread_mutex_init(&blit_mutex, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFrameBuffer* CFrameBuffer::getInstance()
|
CFrameBuffer* CFrameBuffer::getInstance()
|
||||||
@@ -155,13 +193,15 @@ void CFrameBuffer::init(const char * const fbDevice)
|
|||||||
stride = xRes * bpp / 8;
|
stride = xRes * bpp / 8;
|
||||||
printf("FB: %dx%dx%d line length %d.\n", xRes, yRes, bpp, stride);
|
printf("FB: %dx%dx%d line length %d.\n", xRes, yRes, bpp, stride);
|
||||||
|
|
||||||
fake_xRes = DEFAULT_XRES;
|
xRes = DEFAULT_XRES;
|
||||||
fake_yRes = DEFAULT_YRES;
|
yRes = DEFAULT_YRES;
|
||||||
screeninfo.xres = DEFAULT_XRES;
|
screeninfo.xres = DEFAULT_XRES;
|
||||||
screeninfo.yres = DEFAULT_YRES;
|
screeninfo.yres = DEFAULT_YRES;
|
||||||
screeninfo.xres_virtual = DEFAULT_XRES;
|
screeninfo.xres_virtual = DEFAULT_XRES;
|
||||||
screeninfo.yres_virtual = DEFAULT_YRES;
|
screeninfo.yres_virtual = DEFAULT_YRES;
|
||||||
|
|
||||||
screeninfo.bits_per_pixel = 32;
|
screeninfo.bits_per_pixel = 32;
|
||||||
|
stride = xRes * bpp / 8;
|
||||||
backbuf_sz = stride * yRes;
|
backbuf_sz = stride * yRes;
|
||||||
|
|
||||||
memmove(&oldscreen, &screeninfo, sizeof(screeninfo));
|
memmove(&oldscreen, &screeninfo, sizeof(screeninfo));
|
||||||
@@ -173,8 +213,20 @@ printf("FB: %dx%dx%d line length %d.\n", xRes, yRes, bpp, stride);
|
|||||||
|
|
||||||
available = fix.smem_len;
|
available = fix.smem_len;
|
||||||
printf("%dk video mem\n", available/1024);
|
printf("%dk video mem\n", available/1024);
|
||||||
if (available < 8*1024*1024)
|
if (available < 12*1024*1024)
|
||||||
|
{
|
||||||
|
/* for old installations that did not upgrade their module config
|
||||||
|
* it will still work good enough to display the message below */
|
||||||
fprintf(stderr, "[neutrino] WARNING: not enough framebuffer memory available!\n");
|
fprintf(stderr, "[neutrino] WARNING: not enough framebuffer memory available!\n");
|
||||||
|
fprintf(stderr, "[neutrino] I need at least 12MB.\n");
|
||||||
|
FILE *f = fopen("/tmp/infobar.txt", "w");
|
||||||
|
if (f) {
|
||||||
|
fprintf(f, "NOT ENOUGH FRAMEBUFFER MEMORY!");
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
lbb_sz = 0;
|
||||||
|
lbb_off = 0;
|
||||||
|
}
|
||||||
|
|
||||||
lfb = (fb_pixel_t*)mmap(0, available, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
|
lfb = (fb_pixel_t*)mmap(0, available, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
|
||||||
|
|
||||||
@@ -183,6 +235,7 @@ printf("FB: %dx%dx%d line length %d.\n", xRes, yRes, bpp, stride);
|
|||||||
goto nolfb;
|
goto nolfb;
|
||||||
}
|
}
|
||||||
memset(lfb, 0, available);
|
memset(lfb, 0, available);
|
||||||
|
lbb = lfb + lbb_sz;
|
||||||
bpafd = open("/dev/bpamem0", O_RDWR);
|
bpafd = open("/dev/bpamem0", O_RDWR);
|
||||||
if (bpafd < 0)
|
if (bpafd < 0)
|
||||||
{
|
{
|
||||||
@@ -325,7 +378,7 @@ unsigned int CFrameBuffer::getStride() const
|
|||||||
unsigned int CFrameBuffer::getScreenWidth(bool real)
|
unsigned int CFrameBuffer::getScreenWidth(bool real)
|
||||||
{
|
{
|
||||||
if(real)
|
if(real)
|
||||||
return fake_xRes;
|
return xRes;
|
||||||
else
|
else
|
||||||
return g_settings.screen_EndX - g_settings.screen_StartX;
|
return g_settings.screen_EndX - g_settings.screen_StartX;
|
||||||
}
|
}
|
||||||
@@ -333,7 +386,7 @@ unsigned int CFrameBuffer::getScreenWidth(bool real)
|
|||||||
unsigned int CFrameBuffer::getScreenHeight(bool real)
|
unsigned int CFrameBuffer::getScreenHeight(bool real)
|
||||||
{
|
{
|
||||||
if(real)
|
if(real)
|
||||||
return fake_yRes;
|
return yRes;
|
||||||
else
|
else
|
||||||
return g_settings.screen_EndY - g_settings.screen_StartY;
|
return g_settings.screen_EndY - g_settings.screen_StartY;
|
||||||
}
|
}
|
||||||
@@ -351,7 +404,7 @@ unsigned int CFrameBuffer::getScreenY()
|
|||||||
fb_pixel_t * CFrameBuffer::getFrameBufferPointer() const
|
fb_pixel_t * CFrameBuffer::getFrameBufferPointer() const
|
||||||
{
|
{
|
||||||
if (active || (virtual_fb == NULL))
|
if (active || (virtual_fb == NULL))
|
||||||
return lfb;
|
return lbb;
|
||||||
else
|
else
|
||||||
return (fb_pixel_t *) virtual_fb;
|
return (fb_pixel_t *) virtual_fb;
|
||||||
}
|
}
|
||||||
@@ -388,7 +441,7 @@ void CFrameBuffer::setTransparency( int /*tr*/ )
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrameBuffer::setBlendMode(uint8_t mode)
|
void CFrameBuffer::setBlendMode(uint8_t /*mode*/)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
//g.use_global_alpha = (mode == 2); /* 1 == pixel alpha, 2 == global alpha */
|
//g.use_global_alpha = (mode == 2); /* 1 == pixel alpha, 2 == global alpha */
|
||||||
@@ -397,7 +450,7 @@ void CFrameBuffer::setBlendMode(uint8_t mode)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrameBuffer::setBlendLevel(int level)
|
void CFrameBuffer::setBlendLevel(int /*level*/)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
//printf("CFrameBuffer::setBlendLevel %d\n", level);
|
//printf("CFrameBuffer::setBlendLevel %d\n", level);
|
||||||
@@ -478,18 +531,12 @@ void CFrameBuffer::paletteSet(struct fb_cmap *map)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrameBuffer::paintBoxRel(const int _x, const int _y, const int _dx, const int _dy, const fb_pixel_t col, int _radius, int type)
|
void CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int dy, const fb_pixel_t col, int radius, int type)
|
||||||
{
|
{
|
||||||
/* draw a filled rectangle (with additional round corners) */
|
/* draw a filled rectangle (with additional round corners) */
|
||||||
if (!getActive())
|
if (!getActive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int x = scaleX(_x);
|
|
||||||
int y = scaleY(_y);
|
|
||||||
int dx = scaleX(_dx);
|
|
||||||
int dy = scaleY(_dy);
|
|
||||||
int radius = scaleX(_radius);
|
|
||||||
|
|
||||||
int corner_tl = (type & CORNER_TOP_LEFT) ? 1 : 0;
|
int corner_tl = (type & CORNER_TOP_LEFT) ? 1 : 0;
|
||||||
int corner_tr = (type & CORNER_TOP_RIGHT) ? 1 : 0;
|
int corner_tr = (type & CORNER_TOP_RIGHT) ? 1 : 0;
|
||||||
int corner_bl = (type & CORNER_BOTTOM_LEFT) ? 1 : 0;
|
int corner_bl = (type & CORNER_BOTTOM_LEFT) ? 1 : 0;
|
||||||
@@ -585,6 +632,7 @@ void CFrameBuffer::paintBoxRel(const int _x, const int _y, const int _dx, const
|
|||||||
blitRect(x + ofl, y + line, dx - ofl - ofr - 1, 1, col);
|
blitRect(x + ofl, y + line, dx - ofl - ofr - 1, 1, col);
|
||||||
line++;
|
line++;
|
||||||
}
|
}
|
||||||
|
update_dirty(x, y, x + dx, y + dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -672,6 +720,7 @@ void CFrameBuffer::paintLine(int xa, int ya, int xb, int yb, const fb_pixel_t co
|
|||||||
paintPixel(x, y, col);
|
paintPixel(x, y, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
update_dirty(xa, ya, xb, yb);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@@ -683,10 +732,7 @@ void CFrameBuffer::paintVLineRel(int x, int y, int dy, const fb_pixel_t col)
|
|||||||
{
|
{
|
||||||
if (!getActive())
|
if (!getActive())
|
||||||
return;
|
return;
|
||||||
int _x = scaleX(x);
|
blitRect(x, y, 1, dy, col);
|
||||||
int _y = scaleY(y);
|
|
||||||
int _dy = scaleY(dy);
|
|
||||||
blitRect(_x, _y, 1, _dy, col);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrameBuffer::paintHLine(int xa, int xb, int y, const fb_pixel_t col)
|
void CFrameBuffer::paintHLine(int xa, int xb, int y, const fb_pixel_t col)
|
||||||
@@ -698,10 +744,7 @@ void CFrameBuffer::paintHLineRel(int x, int dx, int y, const fb_pixel_t col)
|
|||||||
{
|
{
|
||||||
if (!getActive())
|
if (!getActive())
|
||||||
return;
|
return;
|
||||||
int _x = scaleX(x);
|
blitRect(x, y, dx, 1, col);
|
||||||
int _y = scaleY(y);
|
|
||||||
int _dx = scaleY(dx);
|
|
||||||
blitRect(_x, _y, _dx, 1, col);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrameBuffer::setIconBasePath(const std::string & iconPath)
|
void CFrameBuffer::setIconBasePath(const std::string & iconPath)
|
||||||
@@ -938,30 +981,21 @@ void CFrameBuffer::paintPixel(const int x, const int y, const fb_pixel_t col)
|
|||||||
*pos = col;
|
*pos = col;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 radius)
|
||||||
{
|
{
|
||||||
if (!getActive())
|
if (!getActive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int radius = rad;
|
int c_radius = radius << 1;
|
||||||
int c_radius = rad << 1;
|
|
||||||
|
|
||||||
paintBoxRel(_sx + rad , _sy , _dx - c_radius, _px, col); // upper horizontal
|
paintBoxRel(sx + radius , sy , dx - c_radius, px, col); // upper horizontal
|
||||||
paintBoxRel(_sx + rad , _sy + _dy - _px, _dx - c_radius, _px, col); // lower horizontal
|
paintBoxRel(sx + radius , sy + dy - px, dx - c_radius, px, col); // lower horizontal
|
||||||
paintBoxRel(_sx , _sy + rad , _px, _dy - c_radius, col); // left vertical
|
paintBoxRel(sx , sy + radius , px, dy - c_radius, col); // left vertical
|
||||||
paintBoxRel(_sx + _dx - _px, _sy + rad , _px, _dy - c_radius, col); // right vertical
|
paintBoxRel(sx + dx - px, sy + radius , px, dy - c_radius, col); // right vertical
|
||||||
|
|
||||||
if (!radius)
|
if (!radius)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
radius = scaleX(rad);
|
|
||||||
c_radius = radius * 2;
|
|
||||||
int sx = scaleX(_sx);
|
|
||||||
int sy = scaleY(_sy);
|
|
||||||
int dx = scaleX(_dx);
|
|
||||||
int dy = scaleY(_dy);
|
|
||||||
int px = scaleX(_px);
|
|
||||||
|
|
||||||
int x1 = sx + radius;
|
int x1 = sx + radius;
|
||||||
int y1 = sy + radius;
|
int y1 = sy + radius;
|
||||||
int x2 = sx + dx - radius -1;
|
int x2 = sx + dx - radius -1;
|
||||||
@@ -1237,6 +1271,7 @@ void CFrameBuffer::paintBackground()
|
|||||||
{
|
{
|
||||||
paintBoxRel(0, 0, xRes, yRes, backgroundColor);
|
paintBoxRel(0, 0, xRes, yRes, backgroundColor);
|
||||||
}
|
}
|
||||||
|
blit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrameBuffer::SaveScreen(int x, int y, int dx, int dy, fb_pixel_t * const memp)
|
void CFrameBuffer::SaveScreen(int x, int y, int dx, int dy, fb_pixel_t * const memp)
|
||||||
@@ -1244,7 +1279,6 @@ void CFrameBuffer::SaveScreen(int x, int y, int dx, int dy, fb_pixel_t * const m
|
|||||||
if (!getActive())
|
if (!getActive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
uint8_t * pos = ((uint8_t *)getFrameBufferPointer()) + x * sizeof(fb_pixel_t) + stride * y;
|
uint8_t * pos = ((uint8_t *)getFrameBufferPointer()) + x * sizeof(fb_pixel_t) + stride * y;
|
||||||
fb_pixel_t * bkpos = memp;
|
fb_pixel_t * bkpos = memp;
|
||||||
for (int count = 0; count < dy; count++) {
|
for (int count = 0; count < dy; count++) {
|
||||||
@@ -1284,31 +1318,11 @@ void CFrameBuffer::RestoreScreen(int x, int y, int dx, int dy, fb_pixel_t * cons
|
|||||||
fbpos += stride;
|
fbpos += stride;
|
||||||
bkpos += dx;
|
bkpos += dx;
|
||||||
}
|
}
|
||||||
|
update_dirty(x, y, x + dx, y + dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrameBuffer::switch_signal (int signal)
|
void CFrameBuffer::switch_signal(int)
|
||||||
{
|
{
|
||||||
CFrameBuffer * thiz = CFrameBuffer::getInstance();
|
|
||||||
if (signal == SIGUSR1) {
|
|
||||||
if (virtual_fb != NULL)
|
|
||||||
delete[] virtual_fb;
|
|
||||||
virtual_fb = new uint8_t[thiz->stride * thiz->yRes];
|
|
||||||
thiz->active = false;
|
|
||||||
if (virtual_fb != NULL)
|
|
||||||
memmove(virtual_fb, thiz->lfb, thiz->stride * thiz->yRes);
|
|
||||||
ioctl(thiz->tty, VT_RELDISP, 1);
|
|
||||||
printf ("release display\n");
|
|
||||||
}
|
|
||||||
else if (signal == SIGUSR2) {
|
|
||||||
ioctl(thiz->tty, VT_RELDISP, VT_ACKACQ);
|
|
||||||
thiz->active = true;
|
|
||||||
printf ("acquire display\n");
|
|
||||||
thiz->paletteSet(NULL);
|
|
||||||
if (virtual_fb != NULL)
|
|
||||||
memmove(thiz->lfb, virtual_fb, thiz->stride * thiz->yRes);
|
|
||||||
else
|
|
||||||
memset(thiz->lfb, 0, thiz->stride * thiz->yRes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrameBuffer::Clear()
|
void CFrameBuffer::Clear()
|
||||||
@@ -1404,7 +1418,7 @@ void CFrameBuffer::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32
|
|||||||
blt_data.ulFlags = ulFlags;
|
blt_data.ulFlags = ulFlags;
|
||||||
blt_data.srcOffset = 0;
|
blt_data.srcOffset = 0;
|
||||||
blt_data.srcPitch = width * 4;
|
blt_data.srcPitch = width * 4;
|
||||||
blt_data.dstOffset = 0;
|
blt_data.dstOffset = lbb_off;
|
||||||
blt_data.dstPitch = stride;
|
blt_data.dstPitch = stride;
|
||||||
blt_data.src_left = xp;
|
blt_data.src_left = xp;
|
||||||
blt_data.src_top = yp;
|
blt_data.src_top = yp;
|
||||||
@@ -1418,14 +1432,19 @@ void CFrameBuffer::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32
|
|||||||
blt_data.dstFormat = SURF_ARGB8888;
|
blt_data.dstFormat = SURF_ARGB8888;
|
||||||
blt_data.srcMemBase = (char *)backbuffer;
|
blt_data.srcMemBase = (char *)backbuffer;
|
||||||
blt_data.dstMemBase = (char *)lfb;
|
blt_data.dstMemBase = (char *)lfb;
|
||||||
blt_data.srcMemSize = backbuf_sz;
|
blt_data.srcMemSize = mem_sz;
|
||||||
blt_data.dstMemSize = stride * yRes;
|
blt_data.dstMemSize = stride * yRes + lbb_off;
|
||||||
|
|
||||||
|
blit_lock();
|
||||||
|
if (fbbuff != backbuffer)
|
||||||
|
memmove(backbuffer, fbbuff, mem_sz);
|
||||||
// icons are so small that they will still be in cache
|
// icons are so small that they will still be in cache
|
||||||
msync(backbuffer, backbuf_sz, MS_SYNC);
|
msync(backbuffer, backbuf_sz, MS_SYNC);
|
||||||
|
|
||||||
if(ioctl(fd, STMFBIO_BLT_EXTERN, &blt_data) < 0)
|
if(ioctl(fd, STMFBIO_BLT_EXTERN, &blt_data) < 0)
|
||||||
perror("blit2FB FBIO_BLIT");
|
perror("blit2FB FBIO_BLIT");
|
||||||
|
update_dirty(x, y, blt_data.dst_right, blt_data.dst_bottom);
|
||||||
|
blit_unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1458,60 +1477,26 @@ void CFrameBuffer::displayRGB(unsigned char *rgbbuff, int x_size, int y_size, in
|
|||||||
cs_free_uncached(fbbuff);
|
cs_free_uncached(fbbuff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrameBuffer::resize(int format)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
static const char *aVideoSystems[][2] = {
|
|
||||||
{"VIDEO_STD_NTSC", "pal"},
|
|
||||||
{"VIDEO_STD_SECAM", "pal"},
|
|
||||||
{"VIDEO_STD_PAL", "pal"},
|
|
||||||
{"VIDEO_STD_480P", "480p"},
|
|
||||||
{"VIDEO_STD_576P", "576p50"},
|
|
||||||
{"VIDEO_STD_720P60", "720p60"},
|
|
||||||
{"VIDEO_STD_1080I60", "1080i60"},
|
|
||||||
{"VIDEO_STD_720P50", "720p50"},
|
|
||||||
{"VIDEO_STD_1080I50", "1080i50"},
|
|
||||||
{"VIDEO_STD_1080P30", "1080p30"},
|
|
||||||
{"VIDEO_STD_1080P24", "1080p24"},
|
|
||||||
{"VIDEO_STD_1080P25", "1080p25"},
|
|
||||||
{"VIDEO_STD_AUTO", "1080i50"}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const int xyres[][2] = {
|
|
||||||
{720, 576},
|
|
||||||
{720, 576},
|
|
||||||
{720, 576},
|
|
||||||
{640, 480},
|
|
||||||
{720, 576},
|
|
||||||
{1280, 720},
|
|
||||||
{1920, 1080},
|
|
||||||
{1280, 720},
|
|
||||||
{1920, 1080},
|
|
||||||
{1920, 1080},
|
|
||||||
{1920, 1080},
|
|
||||||
{1920, 1080},
|
|
||||||
{1920, 1080}
|
|
||||||
};
|
|
||||||
|
|
||||||
paintBackground(); // clear framebuffer
|
|
||||||
xRes = xyres[format][0];
|
|
||||||
yRes = xyres[format][1];
|
|
||||||
bpp = 32;
|
|
||||||
stride = xRes * bpp / 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CFrameBuffer::blitRect(int x, int y, int width, int height, unsigned long color)
|
void CFrameBuffer::blitRect(int x, int y, int width, int height, unsigned long color)
|
||||||
{
|
{
|
||||||
//printf ("[fb - blitRect]: x=%d, y=%d, width=%d, height=%d\n", x, y, width, height);
|
//printf ("[fb - blitRect]: x=%d, y=%d, width=%d, height=%d\n", x, y, width, height);
|
||||||
if (width == 0 || height == 0)
|
if (width == 0 || height == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (x + width > (int)xRes) {
|
||||||
|
fprintf(stderr, "[neutrino] fb::%s: x + w > xRes! (%d+%d > %d)\n", __func__, x, width, xRes);
|
||||||
|
width = xRes - x;
|
||||||
|
}
|
||||||
|
if (y + height > (int)yRes) {
|
||||||
|
fprintf(stderr, "[neutrino] fb::%s: y + h > yRes! (%d+%d > %d)\n", __func__, y, height, yRes);
|
||||||
|
height = yRes - y;
|
||||||
|
}
|
||||||
|
|
||||||
STMFBIO_BLT_DATA bltData;
|
STMFBIO_BLT_DATA bltData;
|
||||||
memset(&bltData, 0, sizeof(STMFBIO_BLT_DATA));
|
memset(&bltData, 0, sizeof(STMFBIO_BLT_DATA));
|
||||||
|
|
||||||
bltData.operation = BLT_OP_FILL;
|
bltData.operation = BLT_OP_FILL;
|
||||||
bltData.dstOffset = 0;
|
bltData.dstOffset = lbb_off;
|
||||||
bltData.dstPitch = stride;
|
bltData.dstPitch = stride;
|
||||||
|
|
||||||
bltData.dst_left = x;
|
bltData.dst_left = x;
|
||||||
@@ -1525,8 +1510,11 @@ void CFrameBuffer::blitRect(int x, int y, int width, int height, unsigned long c
|
|||||||
bltData.srcMemBase = STMFBGP_FRAMEBUFFER;
|
bltData.srcMemBase = STMFBGP_FRAMEBUFFER;
|
||||||
bltData.colour = color;
|
bltData.colour = color;
|
||||||
|
|
||||||
|
blit_lock();
|
||||||
if (ioctl(fd, STMFBIO_BLT, &bltData ) < 0)
|
if (ioctl(fd, STMFBIO_BLT, &bltData ) < 0)
|
||||||
perror("blitRect FBIO_BLIT");
|
fprintf(stderr, "blitRect FBIO_BLIT: %m x:%d y:%d w:%d h:%d s:%d\n", x,y,width,height,stride);
|
||||||
|
update_dirty(x, y, bltData.dst_right, bltData.dst_bottom);
|
||||||
|
blit_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrameBuffer::blitIcon(int src_width, int src_height, int fb_x, int fb_y, int width, int height)
|
void CFrameBuffer::blitIcon(int src_width, int src_height, int fb_x, int fb_y, int width, int height)
|
||||||
@@ -1537,7 +1525,7 @@ void CFrameBuffer::blitIcon(int src_width, int src_height, int fb_x, int fb_y, i
|
|||||||
blt_data.ulFlags = BLT_OP_FLAGS_BLEND_SRC_ALPHA | BLT_OP_FLAGS_BLEND_DST_MEMORY; // we need alpha blending
|
blt_data.ulFlags = BLT_OP_FLAGS_BLEND_SRC_ALPHA | BLT_OP_FLAGS_BLEND_DST_MEMORY; // we need alpha blending
|
||||||
blt_data.srcOffset = 0;
|
blt_data.srcOffset = 0;
|
||||||
blt_data.srcPitch = src_width * 4;
|
blt_data.srcPitch = src_width * 4;
|
||||||
blt_data.dstOffset = 0;
|
blt_data.dstOffset = lbb_off;
|
||||||
blt_data.dstPitch = stride;
|
blt_data.dstPitch = stride;
|
||||||
blt_data.src_top = 0;
|
blt_data.src_top = 0;
|
||||||
blt_data.src_left = 0;
|
blt_data.src_left = 0;
|
||||||
@@ -1554,31 +1542,96 @@ void CFrameBuffer::blitIcon(int src_width, int src_height, int fb_x, int fb_y, i
|
|||||||
blt_data.srcMemSize = backbuf_sz;
|
blt_data.srcMemSize = backbuf_sz;
|
||||||
blt_data.dstMemSize = stride * yRes;
|
blt_data.dstMemSize = stride * yRes;
|
||||||
|
|
||||||
msync(backbuffer, backbuf_sz, MS_SYNC);
|
blit_lock();
|
||||||
|
msync(backbuffer, blt_data.srcPitch * src_height, MS_SYNC);
|
||||||
|
|
||||||
if(ioctl(fd, STMFBIO_BLT_EXTERN, &blt_data) < 0)
|
if(ioctl(fd, STMFBIO_BLT_EXTERN, &blt_data) < 0)
|
||||||
perror("blit_icon FBIO_BLIT");
|
perror("blit_icon FBIO_BLIT");
|
||||||
|
update_dirty(fb_x, fb_y, blt_data.dst_right, blt_data.dst_bottom);
|
||||||
|
blit_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrameBuffer::update(void)
|
void CFrameBuffer::mark(int xs, int ys, int xe, int ye)
|
||||||
{
|
{
|
||||||
|
update_dirty(xs, ys, xe, ye);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CFrameBuffer::blit()
|
||||||
int CFrameBuffer::scaleX(const int x, bool clamp)
|
|
||||||
{
|
{
|
||||||
unsigned int mul = x * xRes;
|
if (to_blit.xs == INT_MAX)
|
||||||
mul = mul / DEFAULT_XRES + (((mul % DEFAULT_XRES) >= (DEFAULT_XRES / 2)) ? 1 : 0);
|
return;
|
||||||
if (clamp && mul > xRes)
|
|
||||||
return xRes;
|
|
||||||
return mul;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CFrameBuffer::scaleY(const int y, bool clamp)
|
int srcXa = to_blit.xs;
|
||||||
{
|
int srcYa = to_blit.ys;
|
||||||
unsigned int mul = y * yRes;
|
int srcXb = to_blit.xe;
|
||||||
mul = mul / DEFAULT_YRES + (((mul % DEFAULT_YRES) >= (DEFAULT_YRES / 2)) ? 1 : 0);
|
int srcYb = to_blit.ye;
|
||||||
if (clamp && mul > yRes)
|
|
||||||
return yRes;
|
STMFBIO_BLT_DATA bltData;
|
||||||
return mul;
|
memset(&bltData, 0, sizeof(STMFBIO_BLT_DATA));
|
||||||
|
|
||||||
|
bltData.operation = BLT_OP_COPY;
|
||||||
|
//bltData.ulFlags = BLT_OP_FLAGS_BLEND_SRC_ALPHA | BLT_OP_FLAGS_BLEND_DST_MEMORY; // we need alpha blending
|
||||||
|
// src
|
||||||
|
bltData.srcOffset = lbb_off;
|
||||||
|
bltData.srcPitch = stride;
|
||||||
|
|
||||||
|
bltData.src_left = srcXa;
|
||||||
|
bltData.src_top = srcYa;
|
||||||
|
bltData.src_right = srcXb;
|
||||||
|
bltData.src_bottom = srcYb;
|
||||||
|
|
||||||
|
bltData.srcFormat = SURF_BGRA8888;
|
||||||
|
bltData.srcMemBase = STMFBGP_FRAMEBUFFER;
|
||||||
|
|
||||||
|
/* calculate dst/blit factor */
|
||||||
|
fb_var_screeninfo s;
|
||||||
|
if (ioctl(fd, FBIOGET_VSCREENINFO, &s) == -1)
|
||||||
|
perror("frameBuffer <FBIOGET_VSCREENINFO>");
|
||||||
|
|
||||||
|
if (s.xres != last_xres) /* fb resolution has changed -> clear artifacts */
|
||||||
|
{
|
||||||
|
last_xres = s.xres;
|
||||||
|
bltData.src_left = 0;
|
||||||
|
bltData.src_top = 0;
|
||||||
|
bltData.src_right = xRes;
|
||||||
|
bltData.src_bottom = yRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
double xFactor = (double)s.xres/(double)xRes;
|
||||||
|
double yFactor = (double)s.yres/(double)yRes;
|
||||||
|
|
||||||
|
int desXa = xFactor * bltData.src_left;
|
||||||
|
int desYa = yFactor * bltData.src_top;
|
||||||
|
int desXb = xFactor * bltData.src_right;
|
||||||
|
int desYb = yFactor * bltData.src_bottom;
|
||||||
|
|
||||||
|
/* dst */
|
||||||
|
bltData.dstOffset = 0;
|
||||||
|
bltData.dstPitch = s.xres * 4;
|
||||||
|
|
||||||
|
bltData.dst_left = desXa;
|
||||||
|
bltData.dst_top = desYa;
|
||||||
|
bltData.dst_right = desXb;
|
||||||
|
bltData.dst_bottom = desYb;
|
||||||
|
|
||||||
|
bltData.dstFormat = SURF_BGRA8888;
|
||||||
|
bltData.dstMemBase = STMFBGP_FRAMEBUFFER;
|
||||||
|
|
||||||
|
//printf("CFrameBuffer::blit: sx:%d sy:%d sxe:%d sye: %d dx:%d dy:%d dxe:%d dye:%d\n", srcXa, srcYa, srcXb, srcYb, desXa, desYa, desXb, desYb);
|
||||||
|
if ((bltData.dst_right > s.xres) || (bltData.dst_bottom > s.yres))
|
||||||
|
printf("CFrameBuffer::blit: values out of range desXb:%d desYb:%d\n",
|
||||||
|
bltData.dst_right, bltData.dst_bottom);
|
||||||
|
|
||||||
|
blit_lock();
|
||||||
|
if(ioctl(fd, STMFBIO_SYNC_BLITTER) < 0)
|
||||||
|
perror("CFrameBuffer::blit ioctl STMFBIO_SYNC_BLITTER 1");
|
||||||
|
msync(lbb, xRes * 4 * yRes, MS_SYNC);
|
||||||
|
if (ioctl(fd, STMFBIO_BLT, &bltData ) < 0)
|
||||||
|
perror("STMFBIO_BLT");
|
||||||
|
if(ioctl(fd, STMFBIO_SYNC_BLITTER) < 0)
|
||||||
|
perror("CFrameBuffer::blit ioctl STMFBIO_SYNC_BLITTER 2");
|
||||||
|
|
||||||
|
to_blit.xs = to_blit.ys = INT_MAX;
|
||||||
|
to_blit.xe = to_blit.ye = 0;
|
||||||
|
blit_unlock();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user