Ha Nguyen
2012-09-13 09:38:19 UTC
Hi everybody,
I notice that my full screen surface (1280x720 pixel) doesn't fit to my
TV's screen. The (0,0) and (1279,719) are seemed to be drawn outside the
visible of my TV's screen at somewhere (-20,-15) and (1300, 735) instead.
Has anyone have some inputs how this can be solved.
We have seen a problem when the parts drawn outside the TV screen are mixed
back with subsequent FillRectangle() on visible TV screen
when DSPD_SRC_OVER rule is used. This happened only if hardware accel is
used. Below is the code that we see the issue. The off screen part of the
red rectangle are mixed back with the two gradient bars.
Thank you so much for your input!
/ha
#include <stdio.h>
#include <unistd.h>
#include <directfb.h>
static IDirectFB *dfb = NULL;
static IDirectFBSurface *primary = NULL;
static int screen_width = 0;
static int screen_height = 0;
#define DFBCHECK(x...) \
{ \
DFBResult err = x; \
\
if (err != DFB_OK) \
{ \
fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
DirectFBErrorFatal( #x, err ); \
} \
}
static IDirectFBSurface *logo = NULL;
static IDirectFBSurface *offscreen = NULL;
int main (int argc, char **argv)
{
int i;
DFBSurfaceDescription dsc;
DFBCHECK (DirectFBInit (&argc, &argv));
DFBCHECK (DirectFBCreate (&dfb));
DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN));
// create primary surface
dsc.flags = DSDESC_CAPS;
dsc.caps = (DFBSurfaceCapabilities)(DSCAPS_PRIMARY | DSCAPS_FLIPPING);
dsc.pixelformat = DSPF_ARGB;
DFBCHECK (dfb->CreateSurface( dfb, &dsc, &primary ));
DFBCHECK (primary->GetSize (primary, &screen_width, &screen_height));
// clear primary surface
primary->SetColor (primary, 0xff, 0xff, 0xff, 0xff);
DFBCHECK (primary->FillRectangle (primary, 0, 0, screen_width,
screen_height));
// create offscreen surface
dsc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT);
dsc.width = screen_width;
dsc.height = screen_height;
DFBCHECK (dfb->CreateSurface( dfb, &dsc, &offscreen ));
offscreen->SetColor (offscreen, 0xff, 0xff, 0xff, 0xff);
DFBCHECK (offscreen->FillRectangle (offscreen, 0, 0, screen_width,
screen_height));
// draw red rectangle on Offscreen
offscreen->SetColor (offscreen, 0xff, 0x00, 0x00, 0xff);
DFBCHECK (offscreen->FillRectangle (offscreen, 300, 0, 500, 100));
offscreen->SetColor (offscreen, 0x00, 0x00, 0xff, 0xff);
DFBCHECK (offscreen->FillRectangle (offscreen, 0, 460, 500, 50));
// create gradient bar
dsc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT);
dsc.width = 1;
dsc.height = 128;
DFBCHECK(dfb->CreateSurface( dfb, &dsc, &logo ));
{
// Create the gradient by writing directly to the surface
void* data;
int pitch;
DFBCHECK(logo->Lock(logo, DSLF_WRITE, &data, &pitch));
for (int i=0; i < 128; i++)
{
unsigned char* line = &((unsigned char*)data)[i*pitch];
unsigned char r = 0x50 + (0xff-0x50)*i/128;
unsigned char g = 0x80 + (0xff-0x80)*i/128;
unsigned char b = 0xa0 + (0xff-0xa0)*i/128;
unsigned char a = 0x30 + (0xff-0x30)*i/128;
unsigned int color = b;
color |= g << 8;
color |= r << 16;
color |= a << 24;
*((unsigned int*)line) = color;
}
DFBCHECK(logo->Unlock(logo));
}
// Set render flags
unsigned char opacity = (unsigned char)(0.6f * 255);
offscreen->SetColor(offscreen, opacity, opacity, opacity, opacity);
offscreen->SetPorterDuff(offscreen, DSPD_SRC_OVER);
offscreen->SetBlittingFlags(offscreen,
(DFBSurfaceBlittingFlags)(DSBLIT_BLEND_ALPHACHANNEL |
DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR));
offscreen->SetRenderOptions(offscreen,
(DFBSurfaceRenderOptions)(DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE));
//Blit two gradient bars to offscreen surf
DFBRectangle srec = {0, 0, 1, 128};
DFBRectangle drec = {0, 486, 1280, 15};
DFBCHECK (offscreen->StretchBlit (offscreen, logo, &srec, &drec));
drec.x = 0; drec.y = 426; drec.w = 1280; drec.h = 15;
DFBCHECK (offscreen->StretchBlit (offscreen, logo, &srec, &drec));
// flip Offscreen to primary
DFBCHECK (primary->Blit (primary, offscreen, NULL, 0, 0));
DFBCHECK (primary->Flip (primary, NULL, DSFLIP_BLIT));
sleep (60);
offscreen->Release (offscreen);
logo->Release (logo);
primary->Release (primary);
dfb->Release (dfb);
return 0;
}
I notice that my full screen surface (1280x720 pixel) doesn't fit to my
TV's screen. The (0,0) and (1279,719) are seemed to be drawn outside the
visible of my TV's screen at somewhere (-20,-15) and (1300, 735) instead.
Has anyone have some inputs how this can be solved.
We have seen a problem when the parts drawn outside the TV screen are mixed
back with subsequent FillRectangle() on visible TV screen
when DSPD_SRC_OVER rule is used. This happened only if hardware accel is
used. Below is the code that we see the issue. The off screen part of the
red rectangle are mixed back with the two gradient bars.
Thank you so much for your input!
/ha
#include <stdio.h>
#include <unistd.h>
#include <directfb.h>
static IDirectFB *dfb = NULL;
static IDirectFBSurface *primary = NULL;
static int screen_width = 0;
static int screen_height = 0;
#define DFBCHECK(x...) \
{ \
DFBResult err = x; \
\
if (err != DFB_OK) \
{ \
fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
DirectFBErrorFatal( #x, err ); \
} \
}
static IDirectFBSurface *logo = NULL;
static IDirectFBSurface *offscreen = NULL;
int main (int argc, char **argv)
{
int i;
DFBSurfaceDescription dsc;
DFBCHECK (DirectFBInit (&argc, &argv));
DFBCHECK (DirectFBCreate (&dfb));
DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN));
// create primary surface
dsc.flags = DSDESC_CAPS;
dsc.caps = (DFBSurfaceCapabilities)(DSCAPS_PRIMARY | DSCAPS_FLIPPING);
dsc.pixelformat = DSPF_ARGB;
DFBCHECK (dfb->CreateSurface( dfb, &dsc, &primary ));
DFBCHECK (primary->GetSize (primary, &screen_width, &screen_height));
// clear primary surface
primary->SetColor (primary, 0xff, 0xff, 0xff, 0xff);
DFBCHECK (primary->FillRectangle (primary, 0, 0, screen_width,
screen_height));
// create offscreen surface
dsc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT);
dsc.width = screen_width;
dsc.height = screen_height;
DFBCHECK (dfb->CreateSurface( dfb, &dsc, &offscreen ));
offscreen->SetColor (offscreen, 0xff, 0xff, 0xff, 0xff);
DFBCHECK (offscreen->FillRectangle (offscreen, 0, 0, screen_width,
screen_height));
// draw red rectangle on Offscreen
offscreen->SetColor (offscreen, 0xff, 0x00, 0x00, 0xff);
DFBCHECK (offscreen->FillRectangle (offscreen, 300, 0, 500, 100));
offscreen->SetColor (offscreen, 0x00, 0x00, 0xff, 0xff);
DFBCHECK (offscreen->FillRectangle (offscreen, 0, 460, 500, 50));
// create gradient bar
dsc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT);
dsc.width = 1;
dsc.height = 128;
DFBCHECK(dfb->CreateSurface( dfb, &dsc, &logo ));
{
// Create the gradient by writing directly to the surface
void* data;
int pitch;
DFBCHECK(logo->Lock(logo, DSLF_WRITE, &data, &pitch));
for (int i=0; i < 128; i++)
{
unsigned char* line = &((unsigned char*)data)[i*pitch];
unsigned char r = 0x50 + (0xff-0x50)*i/128;
unsigned char g = 0x80 + (0xff-0x80)*i/128;
unsigned char b = 0xa0 + (0xff-0xa0)*i/128;
unsigned char a = 0x30 + (0xff-0x30)*i/128;
unsigned int color = b;
color |= g << 8;
color |= r << 16;
color |= a << 24;
*((unsigned int*)line) = color;
}
DFBCHECK(logo->Unlock(logo));
}
// Set render flags
unsigned char opacity = (unsigned char)(0.6f * 255);
offscreen->SetColor(offscreen, opacity, opacity, opacity, opacity);
offscreen->SetPorterDuff(offscreen, DSPD_SRC_OVER);
offscreen->SetBlittingFlags(offscreen,
(DFBSurfaceBlittingFlags)(DSBLIT_BLEND_ALPHACHANNEL |
DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR));
offscreen->SetRenderOptions(offscreen,
(DFBSurfaceRenderOptions)(DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE));
//Blit two gradient bars to offscreen surf
DFBRectangle srec = {0, 0, 1, 128};
DFBRectangle drec = {0, 486, 1280, 15};
DFBCHECK (offscreen->StretchBlit (offscreen, logo, &srec, &drec));
drec.x = 0; drec.y = 426; drec.w = 1280; drec.h = 15;
DFBCHECK (offscreen->StretchBlit (offscreen, logo, &srec, &drec));
// flip Offscreen to primary
DFBCHECK (primary->Blit (primary, offscreen, NULL, 0, 0));
DFBCHECK (primary->Flip (primary, NULL, DSFLIP_BLIT));
sleep (60);
offscreen->Release (offscreen);
logo->Release (logo);
primary->Release (primary);
dfb->Release (dfb);
return 0;
}