Hi All,
I've attached the example code which reproduces the tearing effect in the
graphics. I use DSFLIP_WAITFORSYNC flag during Flip and vsync-after in
directfbrc.
But still I get the tearing effect when I introduce more blitting operation
just before Flipping. When there are lesser blitting operations I see the
graphics running fine without any artifacts and it looks in sync with vertical
retrace.
I'm doing below steps in the example code:
1. Clear the screen to blue by calling FillRect to cover the entire screen.
2. Draw 4 groups of 4 vertical stripes (16 in all). Each stripe is
positioned at the top of the display and is 20 pixels wide, 1080 pixels high.
Each group of 4 stripes should be coloured red / white / blue / white. Each
group should start 500 pixels to the right of the previous group. Successive
frames move all four groups 20 pixels to the right.
3. Wait a bit (I use more blitting operations to introduce some delay.
Instead we can use usleep as well
4. Flip on vsync.
Please give me some inputs to resolve this.
BTW I use DirectFB 1.4.12 version.
Thanks & Regards
Kirubha
#include <stdio.h>
#include <directfb.h>
/**
* this is the same demo as "mali_swapbuffers", but the rendering is done in
DirectFB only.
* shows a similar effect of incomplete / disturbed frames
* when rendering duration is +/- around a single frame length (20 ms @ 50hz)
*/
static IDirectFB *dfb = 0;
static IDirectFBSurface *primary = 0;
static IDirectFBSurface *temp_surf = 0;
void init_dfb() {
int err;
err = DirectFBInit( NULL, 0 );
if (err) { printf("dfb init failed (%d), exiting\n",err); exit(-1); }
err = DirectFBCreate( &dfb );
if (err) { printf("dfb create failed (%d), exiting\n",err); exit(-1); }
err = dfb->SetCooperativeLevel( dfb, DFSCL_FULLSCREEN );
if (err) { printf("dfb coop level failed (%d), exiting\n",err); exit(-1); }
//err = dfb->SetVideoMode( dfb, 1920, 1080, 32 );
if (err) { printf("dfb set video mode failed (%d), exiting\n",err);
exit(-1); }
IDirectFBDisplayLayer *displayer = 0;
err = dfb->GetDisplayLayer( dfb, DLID_PRIMARY, &displayer );
if (err) { printf("dfb get disp layer failed (%d), exiting\n",err);
exit(-1); }
err = displayer->SetCooperativeLevel(displayer, DLSCL_EXCLUSIVE);
if (err) { printf("dfb set layer exclusive failed (%d), exiting\n",err);
exit(-1); }
DFBDisplayLayerConfig layerconfig;
err = displayer->GetConfiguration( displayer, &layerconfig );
if (err) { printf("dfb get layer conf failed (%d), exiting\n",err);
exit(-1); }
printf("got display layer config %d x %d\n", layerconfig.width,
layerconfig.height );
layerconfig.flags |= DLCONF_BUFFERMODE;
layerconfig.buffermode = DLBM_BACKVIDEO;
layerconfig.surface_caps |= DSCAPS_DOUBLE|DSCAPS_PRIMARY; // |
DSCAPS_PRIMARY;
err = displayer->SetConfiguration(displayer,&layerconfig);
if (err) { printf("dfb set layer conf failed (%d), exiting\n",err);
exit(-1); }
DFBDisplayLayerDescription desc;
DFBSurfaceDescription surfdesc;
err = displayer->GetDescription( displayer, &desc );
if (err) { printf("dfb get layer desc failed (%d), exiting\n",err);
exit(-1); }
printf("disp layer description:\n");
printf("--- type : %04x\n", desc.type);
printf("--- caps : %08x\n", desc.caps);
printf("--- name : %s\n", desc.name);
err = displayer->GetSurface( displayer, &primary );
if (err) { printf("dfb get layer surface failed (%d), exiting\n",err);
exit(-1); }
surfdesc.width = 200;
surfdesc.height = 200;
surfdesc.flags |= DSDESC_WIDTH | DSDESC_HEIGHT;
err = dfb->CreateSurface( dfb, &surfdesc, &temp_surf );
if (err) { printf("dfb get layer surface failed (%d), exiting\n",err);
exit(-1); }
DFBSurfaceCapabilities caps;
err = primary->GetCapabilities ( primary, &caps );
if (err) { printf("dfb get surface caps failed (%d), exiting\n",err);
exit(-1); }
printf("surface caps : %08x\n",caps);
}
void exit_dfb() {
}
static void simple_fill( int x, int y, int w, int h, uint32_t col )
{
primary->SetColor( primary, (col & 0x00ff0000) >> 16, (col & 0x0000ff00) >>
8, (col & 0x000000ff) >> 0, (col & 0xff000000) >> 24 );
primary->FillRectangle( primary, x,y,w,h );
}
static void temp_fill( int x, int y, int w, int h, uint32_t col )
{
temp_surf->SetColor( temp_surf, (col & 0x00ff0000) >> 16, (col &
0x0000ff00) >> 8, (col & 0x000000ff) >> 0, (col & 0xff000000) >> 24 );
temp_surf->FillRectangle( temp_surf, x,y,w,h );
}
int main(int c, char **v) {
int x,n;
int i = 1000;
int j = 50*1000;
init_dfb();
int step = 20;
while(1) {
for (x=0; x<500; x+=step) {
primary->SetColor ( primary, 0x20, 0x20, 0x80, 0xff );
primary->FillRectangle( primary, 0,0, 1920, 1080 );
for (n=0; n<4; n++) {
simple_fill( -20 + n*500 + x + 0*step, 0, step, 1080,
0xffcc0000 );
simple_fill( -20 + n*500 + x + 1*step, 0, step, 1080,
0xffffffff );
simple_fill( -20 + n*500 + x + 2*step, 0, step, 1080,
0xff0000cc );
simple_fill( -20 + n*500 + x + 3*step, 0, step, 1080,
0xffffffff );
}
// longer time before flip provokes error case: rendering time >= 1
frame duration
//usleep( 15*1000 );
while(i)
{
i--;
simple_fill( 0, 0, 100, 100, 0xffcc00ff );
}
i = 1000;
// shorter time before flip is safely < frame duration
// usleep( 5*1000 );
// we should expect this to wait until the blitter finishes, but it
does not:
dfb->WaitIdle(dfb);
primary->Flip( primary, NULL, DSFLIP_WAITFORSYNC
);//DSFLIP_WAITFORSYNC
}
}
exit_dfb();
}
_______________________________________________
directfb-users mailing list
[email protected]
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-users