Join us on Discord!
You can help CodeWalrus stay online by donating here.

Implementing triple buffering

Started by gameblabla, March 14, 2019, 08:34:42 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

gameblabla

So i'm working on porting an emulator (SMS Plus GX) to using fbdev and i managed to make double buffering work after reading this :http://betteros.org/tut/graphics1.php#doublebuffer
It roughly looks like this (Resolution is 320x240 and bitdepth is 16) :static inline void swap_buffers()
{
    if (vinfo.yoffset == 0)
        vinfo.yoffset = screensize;
    else
        vinfo.yoffset = 0;

    //"Pan" to the back buffer
    ioctl(fbfd, FBIOPAN_DISPLAY, &vinfo);

    //Update the pointer to the back buffer so we don't draw on the front buffer
    uint16_t* restrict tmp = front_buffer;
    front_buffer = back_buffer;
    back_buffer = tmp;
}
static void video_update()
{    //Draw our internal buffer to the back buffer
   upscale_SMS_to_320x240((uint32_t* restrict)back_buffer, (uint32_t* restrict)sms_bitmap, vdp.height);
   swap_buffers();
}

However, double buffering has its issues, as it can halve the framerate if it can't keep up, hence why i want triple buffering.
Wiki says this :
QuoteIn triple buffering the program has two back buffers and can immediately start drawing in the one that is not involved in such copying. The third buffer, the front buffer, is read by the graphics card to display the image on the monitor. Once the image has been sent to the monitor, the front buffer is flipped with (or copied from) the back buffer holding the most recent complete image.
How would this work in my case though, practically speaking ?I've tried to implement it like so :
Quotestatic inline void swap_buffers()
{
    buffer_swap_ready = NOT_READY;
    uint16_t *buffer_ready_tmp = buffer_ready;
    buffer_ready = buffer_render;
    buffer_render = buffer_ready_tmp;
    buffer_swap_ready = READY;
   
    if (buffer_swap_ready == READY)
    {
        if (vinfo.yoffset == 0)
            vinfo.yoffset = screensize;
        else
            vinfo.yoffset = 0;

        //"Pan" to the back buffer
        ioctl(fbfd, FBIOPAN_DISPLAY, &vinfo);

        //Update the pointer to the back buffer so we don't draw on the front buffer
        uint16_t* restrict buffer_screen_tmp = buffer_screen;
        buffer_screen = buffer_ready;
        buffer_ready = buffer_screen_tmp;
    }
}
Obviously it's still wrong... (it's always set to READY)
WalrusRPG was using an interrupt for the buffer swapping.What can i do ? I admit that i'm fairly new to this lol... But i wish to implement it myself.
  • Calculators owned: None (used to own an Nspire and TI-89)

Powered by EzPortal