When I draw directly to the framebuffer, it looks like this:
When I double-buffer, it looks like this:
You can see the branch with my WIP code trying to figure this out in my GitHub repo, where the only difference is uncommenting the line here. So I'm still mallocing the back buffer, still drawing the same way, still even copying the frame (though then it's just copying the framebuffer to itself). I must just be forgetting something stupid here, but I can't for the life of me figure it out.
For ease of looking at, here's the most relevant code:
Code: Select all
screen::screen(volatile void *addr, unsigned hres, unsigned vres, unsigned scanline, pixel_order order) :
m_fb(static_cast<volatile pixel_t *>(addr)),
m_order(order),
m_scanline(scanline),
m_resx(hres),
m_resy(vres)
{
m_back = reinterpret_cast<pixel_t*>(malloc(scanline*vres*sizeof(pixel_t)));
//m_back = const_cast<pixel_t*>(m_fb); // <==== Uncommenting this to use the FB directly
}
void
screen::fill(pixel_t color)
{
const size_t len = m_scanline * m_resy;
asm volatile ( "rep stosl" : :
"a"(color), "c"(len), "D"(m_back) );
}
void
screen::update()
{
const size_t len = m_scanline * m_resy;
for (size_t i = 0; i < len; ++i) {
m_fb[i] = m_back[i];
}
}
// this function is defined inline in the header
inline void draw_pixel(unsigned x, unsigned y, pixel_t color) {
const size_t index = x + y * m_scanline;
if (x > m_resx || y > m_resy)
return;
m_back[index] = color;
}