Jon Pomrenke
2013-02-11 22:31:09 UTC
I am trying to implement a double-buffering capable framebuffer using
DirectFB 1.4-13. I'm doing something very similar to this example:
http://tech.groups.yahoo.com/group/lpc3000/message/647 . In short, the
framebuffer allocates twice the memory of the display resolution, reports
twice the resolution as the virtual resolution, and switches the active
buffers through ioctl(/dev/fb0, FBIOPAN_DISPLAY).
My display layer is configured to use the extra framebuffer memory:
DBCK(dfb->SetCooperativeLevel( dfb, DFSCL_FULLSCREEN ));
DBCK( layer->SetCooperativeLevel( layer, DLSCL_EXCLUSIVE ));
config.flags = DLCONF_BUFFERMODE;
config.buffermode = DLBM_BACKVIDEO;
DFBCK(layer->SetConfiguration(layer, &config));
My framebuffer reports properly as a double-buffered display:
(*) FBDev/Mode: Switched to 240x320 (virtual 240x640)
Now here comes the complicated part. Because fbdev.c uses mmap to handle
data transfer to the framebuffer, I have no events to trigger data transfer
to the LCD within my framebuffer driver. The LCD was previously looping
continuously on a FRAME_DONE IRQ so I'm trying to find a way to throttle
the refresh.
If I work with a full screen window, FBIOPAN_DISPLAY is called and I can
trigger the LCD refresh that way. If the window is not full screen, the
double buffer is updated properly, but I don't get FBIOPAN_DISPLAY and,
therefore, no LCD refresh.
The code in DirectFB-1.4.13/systems/fbdev/fbdev.c handling FBIOPAN_DISPLAY
is here:
switch (region->config.buffermode) {
case DLBM_TRIPLE:
case DLBM_BACKVIDEO:
/* Check if simply swapping the buffers is possible... */
if (!(flags & DSFLIP_BLIT) && !surface->rotation &&
(!update || (update->x1 == 0 &&
update->y1 == 0 &&
update->x2 == surface->config.size.w - 1 &&
update->y2 == surface->config.size.h - 1)))
{
D_INFO("%s() -> Going to swap
buffers...\n",__FUNCTION__ );
if (funcs->FlipRegion)
ret = funcs->FlipRegion( layer,
This leads me to believe that the only way to induce FBIOPAN_DISPLAY is to
create all windows at the full screen resolution or explicitly call
IDirectFBDisplayLayer::Flip(). Obviously creating full screen windows
consumes unnecessary resources. Calling Flip explicitly, and when not
actually necessary, causes the double-buffering system to go out of sync
and display the inactive buffer. Am I missing something?
I'd like to configure DirectFB to pass some sort of external refresh event
to the framebuffer system, such as a frame done, or pan display. It is
looking more like the correct way is to implement the clock-based IRQ
refresh and utilize double-buffering to prevent flicker...
Thanks for the help,
Jon Pomrenke
DirectFB 1.4-13. I'm doing something very similar to this example:
http://tech.groups.yahoo.com/group/lpc3000/message/647 . In short, the
framebuffer allocates twice the memory of the display resolution, reports
twice the resolution as the virtual resolution, and switches the active
buffers through ioctl(/dev/fb0, FBIOPAN_DISPLAY).
My display layer is configured to use the extra framebuffer memory:
DBCK(dfb->SetCooperativeLevel( dfb, DFSCL_FULLSCREEN ));
DBCK( layer->SetCooperativeLevel( layer, DLSCL_EXCLUSIVE ));
config.flags = DLCONF_BUFFERMODE;
config.buffermode = DLBM_BACKVIDEO;
DFBCK(layer->SetConfiguration(layer, &config));
My framebuffer reports properly as a double-buffered display:
(*) FBDev/Mode: Switched to 240x320 (virtual 240x640)
Now here comes the complicated part. Because fbdev.c uses mmap to handle
data transfer to the framebuffer, I have no events to trigger data transfer
to the LCD within my framebuffer driver. The LCD was previously looping
continuously on a FRAME_DONE IRQ so I'm trying to find a way to throttle
the refresh.
If I work with a full screen window, FBIOPAN_DISPLAY is called and I can
trigger the LCD refresh that way. If the window is not full screen, the
double buffer is updated properly, but I don't get FBIOPAN_DISPLAY and,
therefore, no LCD refresh.
The code in DirectFB-1.4.13/systems/fbdev/fbdev.c handling FBIOPAN_DISPLAY
is here:
switch (region->config.buffermode) {
case DLBM_TRIPLE:
case DLBM_BACKVIDEO:
/* Check if simply swapping the buffers is possible... */
if (!(flags & DSFLIP_BLIT) && !surface->rotation &&
(!update || (update->x1 == 0 &&
update->y1 == 0 &&
update->x2 == surface->config.size.w - 1 &&
update->y2 == surface->config.size.h - 1)))
{
D_INFO("%s() -> Going to swap
buffers...\n",__FUNCTION__ );
if (funcs->FlipRegion)
ret = funcs->FlipRegion( layer,
This leads me to believe that the only way to induce FBIOPAN_DISPLAY is to
create all windows at the full screen resolution or explicitly call
IDirectFBDisplayLayer::Flip(). Obviously creating full screen windows
consumes unnecessary resources. Calling Flip explicitly, and when not
actually necessary, causes the double-buffering system to go out of sync
and display the inactive buffer. Am I missing something?
I'd like to configure DirectFB to pass some sort of external refresh event
to the framebuffer system, such as a frame done, or pan display. It is
looking more like the correct way is to implement the clock-based IRQ
refresh and utilize double-buffering to prevent flicker...
Thanks for the help,
Jon Pomrenke