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 directfb-users@directfb.org http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-users