Screen tearing: ClearFrameBuffer() and VSync

Post Reply
Lin
Posts: 18
Joined: Sat Feb 20, 2010 5:20 pm
Location: Salt Lake City

Screen tearing: ClearFrameBuffer() and VSync

Post by Lin » Sat Feb 20, 2010 5:48 pm

I'm programming the Wii. I'm trying to draw a 10-pixel-wide frame on the border of the screen. The top of the frame does not appear until I exit, where the last frame stays on the screen for a second before the launcher reappears. About 70 rows from the top of the screen are missing.

My hypothesis is that part of the frame buffer is getting cleared before the buffer is actually displayed. I don't know why my code would produce this behavior. It's generally as follows.

Code: Select all

// initialization stuff from template.c, including initializing rmode and xfb pointers

while (1)
{
    // get WPAD buttons, WPAD_IR structure, exit if home is pressed

    VIDEO_ClearFrameBuffer(rmode, xfb, COLOR_BLACK);
    drawBorder(); // a function that loops through four sections of the frame buffer, setting individual pixels
    VIDEO_Flush();
    VIDEO_WaitVSync();
}
I tried adding a second VIDEO_WaitVSync() to the end of the while loop. This made the top of the frame visible, but it flickered.

Any ideas? Is there a better way to synchronize internal frames with the display?

Lin
Posts: 18
Joined: Sat Feb 20, 2010 5:20 pm
Location: Salt Lake City

Re: Screen tearing: ClearFrameBuffer() and VSync

Post by Lin » Sun Feb 21, 2010 6:13 pm

So, I learned about double buffering yesterday, and this solves the problem (surprise surprise). I still want to know why the problem occurred in the first place, but it's probably to do with the VSync timing system that's deeper within libogc than I want to dig at this time.

For any interested parties with a similar problem, double buffering involves initializing two frame buffers. At any time one is set to be displayed and the other is being modified. On each frame cycle you copy the "display" buffer to the screen, modify the "background" buffer, and then switch the roles of the buffers: once the "background" buffer is modified it is ready to be displayed, so it becomes the "display" buffer, and once the "display" buffer is copied over it becomes the new "background" buffer.

My code now basically looks like this. Its double buffering stuff is based on the sprites example code from devkitPro, so look at that for details.

Code: Select all

// initialization stuff from template.c, including initializing rmode and xfb pointer array

while (1)
{
    // get WPAD buttons, WPAD_IR structure, exit if home is pressed

    VIDEO_ClearFrameBuffer(rmode, xfb[xfb_index], COLOR_BLACK);
    drawBorder(); // a function that loops through four sections of the frame buffer, setting individual pixels
    VIDEO_SetNextFramebuffer(xfb[xfb_index])
    VIDEO_Flush();
    VIDEO_WaitVSync();
    xfb_index ^= 1; // toggle active frame buffer
}

User avatar
Izhido
Posts: 107
Joined: Fri Oct 19, 2007 10:57 pm
Location: Costa Rica
Contact:

Re: Screen tearing: ClearFrameBuffer() and VSync

Post by Izhido » Wed Feb 24, 2010 6:58 pm

I actually have a question regarding that border you implemented.

Not everyone has LCD or Plasma TVs, or a 480p cable for it; meaning, not everyone will be able to see a 10 pix border around the screen, since many TVs actually aren't able to show anything in that area (mine, for instance, doesn't show the top/bottom 30 rows of pixels, and approx. 5 left/right "columns" of them). Do you have anything planned in your app when that happens?

Lin
Posts: 18
Joined: Sat Feb 20, 2010 5:20 pm
Location: Salt Lake City

Re: Screen tearing: ClearFrameBuffer() and VSync

Post by Lin » Sat Mar 06, 2010 12:54 am

Hey, sorry for the delay.

Even my LCD television doesn't scan exactly as you'd expect. It won't be much of a problem for me, since I'm just making a tic-tac-toe game. I suppose I could buffer everything by 50 blank pixels from the edge. Otherwise I don't have a good answer.

Also, I realized that my ramblings above were about "page-flipping," which is not the same as "double buffering" even though I used that term.

User avatar
DeeKay
Posts: 4
Joined: Thu Aug 12, 2010 9:07 pm

Re: Screen tearing: ClearFrameBuffer() and VSync

Post by DeeKay » Fri Aug 13, 2010 7:47 pm

Code: Select all

       code snippet: 

        ... 
        VIDEO_Flush();
        VIDEO_WaitVSync();
        ....
Do not know if it's true for the Wii but in my opinion these two are in the wrong order. You should wait for the Vsync before you flush (draw on screen). It's all to do with timing.
That is why you would first draw in another region of memory before showing on screen (page flipping) because there isn't enough time to (realtime draw and show on screen. That's the main cause for tearing. Because you draw out-of-sync with the screen.

The border issue explained above has to do with the so called "safe area" of the screen where safe area means the part that is actually displayed. On some TV-sets some(differs from brand to brand) of the border is "clipped" off screen. Don't know the real reason for that though.

Hope this explains a bit more...

Greetz DeeKay

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests