Hi,
My platform is i.mx6 dual lite running Android JB. I have a HDMI screen connected to it.
Because I have a VSYNC problem under Android JB (logcat overflows screen with FBIO_WAITFORVSYNC errors) I am trying to understand how the IPUv3 frame buffer works.
I am familiar with linux framebuffers but there are parts I don't understand in the i.mx6 IPUv3 frame buffer, even after reading the IPUv3 chapter in the Reference manual, and also the linux BSP manual.
If I look at /sys/class/graphics on my card, I can see two nodes:
fb0
fb1
With following values:
# cat fb0/name
DISP3 BG
# cat fb0/fsl_disp_dev_property
hdmi
# cat fb0/fsl_disp_property
2-layer-fb-bg
# cat fb1/name
DISP3 FG
# cat fb1/fsl_disp_dev_property
overlay
# cat fb1/fsl_disp_property
2-layer-fb-fg
It looks as if, the HDMI screen uses the two fb0 and fb1 nodes for its usage. One being the foreground layer (fb0) and fb1 being the background layer.
My guess is that this is part of an anti-tearing strategy.
I have read that the IPU defines many channels to move data between memory, the display ports....
But I still do not understand the following snippets of code. The first one is the IOCTL VSYNC. Basically it says:
-If we are the foreground FB, then we look at the BG FB, for a reaon I don't get. Any idea?
The second one is the channel swapping code (swap_disp_chan() ). This code seems to be called when someone does an "echo <value> /sys/class/graphics/fsl_disp..."
Why would anyone want to switch channels? what is the deal here?
...........................................................................................................................................
case MXCFB_WAIT_FOR_VSYNC:
{
if (mxc_fbi->ipu_ch == MEM_FG_SYNC) {
/* BG should poweron */
struct mxcfb_info *bg_mxcfbi = NULL;
struct fb_info *fbi_tmp;
fbi_tmp = found_registered_fb(MEM_BG_SYNC, mxc_fbi->ipu_id);
if (fbi_tmp)
bg_mxcfbi = ((struct mxcfb_info *)(fbi_tmp->par));
if (!bg_mxcfbi) {
retval = -EINVAL;
break;
}
if (bg_mxcfbi->cur_blank != FB_BLANK_UNBLANK) {
retval = -EINVAL;
break;
}
}
if (mxc_fbi->cur_blank != FB_BLANK_UNBLANK) {
retval = -EINVAL;
break;
} (snipped)
..................................................................................................................................
static ssize_t swap_disp_chan(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct fb_info *info = dev_get_drvdata(dev);
struct mxcfb_info *mxcfbi = (struct mxcfb_info *)info->par;
struct mxcfb_info *fg_mxcfbi = NULL;
console_lock();
/* swap only happen between DP-BG and DC, while DP-FG disable */
if (((mxcfbi->ipu_ch == MEM_BG_SYNC) &&
(strstr(buf, "1-layer-fb") != NULL)) ||
((mxcfbi->ipu_ch == MEM_DC_SYNC) &&
(strstr(buf, "2-layer-fb-bg") != NULL))) {
struct fb_info *fbi_fg;
fbi_fg = found_registered_fb(MEM_FG_SYNC, mxcfbi->ipu_id);
if (fbi_fg)
fg_mxcfbi = (struct mxcfb_info *)fbi_fg->par;
if (!fg_mxcfbi ||
fg_mxcfbi->cur_blank == FB_BLANK_UNBLANK) {
dev_err(dev,
"Can not switch while fb2(fb-fg) is on.\n");
console_unlock();
return count;
}
if (swap_channels(info) < 0)
dev_err(dev, "Swap display channel failed.\n");
}
By the way, here is my kernel parameter line:
Kernel command line: androidboot.hardware=freescale enable_wait_mode=off console=ttymxc0,115200 vmalloc=400M consoleblank=0 video=mxcfb0:dev=hdmi,bpp=32,1280x720M@60,if=RGB24 video=mxcfb1:off video=mxcfb2:off fbmem=48M androidboot.hardware=freescale
If you have any information to share I will gladly take it.
Thanks so much
-jf simon
Solved! Go to Solution.
FG and BG framebuffers always shows image according to the buffer content. I think to avoid tearing artifacts, the upper layer (Android?) should aware of the VSYNC timing, which it should complete the update of any framebuffer before next VSYNC IRQ.
Regards,
Jacky
JF, has Jacky answered your question? If yes, please click Correct Answer/Helpful Answer, otherwise please keep communicating with Jacky. The DI will be closed if no response from you in 3 days.
Thanks,
Yixing
From my understanding, there are 2 framebuffers because the application can use the FG layer as the OSD function. Such application may be a video player, while BG is showing video, FG can display the timing bar, play, pause buttons, etc...
Regards,
Jacky
Hi Jacky
Thanks for yr answer. That makes sense.
But now I am confused as I read somewhere that android was using two buffers for drawing to the screen to avoid tearing artifacts. If this is not done at frame buffer layer where does that happen?
thx
-jfs
FG and BG framebuffers always shows image according to the buffer content. I think to avoid tearing artifacts, the upper layer (Android?) should aware of the VSYNC timing, which it should complete the update of any framebuffer before next VSYNC IRQ.
Regards,
Jacky