Implement frame buffer double-buffering

This slowed down drawing to video in QEMU/VirtualBox but greatly sped up
doing so on real hardware (no longer reading from video memory).
Despite the speed-up, it is still quite slow though.
This commit is contained in:
josh committed 2022-11-08 06:19:03 -05:00
1 parent 55604468c8
commit edba40b2c6
3 files changed
+49 -19

No files matched your search

+34 -16
View File
@@ -13,8 +13,11 @@ import hulk.kfont;
*/
struct fb
{
/** Frame buffer base address. */
private __gshared static uint * m_buffer;
/** Device frame buffer base address. */
private __gshared static uint * m_device_buffer;
/** Frame buffer 1 base address. */
private __gshared static uint * m_buffer1;
/** Frame buffer width. */
private __gshared static uint m_width;
@@ -47,14 +50,16 @@ struct fb
/**
* Initialize a frame buffer.
*
* @param buffer Frame buffer base address.
* @param device_buffer Device frame buffer base address.
* @param buffer1 Frame buffer 1 base address.
* @param width Frame buffer width.
* @param height Frame buffer height.
* @param stride Frame buffer stride.
*/
static void initialize(uint * buffer, uint width, uint height, uint stride)
static void initialize(uint * device_buffer, uint * buffer1, uint width, uint height, uint stride)
{
m_buffer = buffer;
m_device_buffer = device_buffer;
m_buffer1 = buffer1;
m_width = width;
m_height = height;
m_stride = stride;
@@ -68,7 +73,8 @@ struct fb
*/
static void clear(uint color = 0u)
{
memset32(m_buffer, color, m_buffer_size);
memset32(m_buffer1, color, m_buffer_size);
memset32(m_device_buffer, color, m_buffer_size);
}
/**
@@ -85,7 +91,8 @@ struct fb
for (size_t iy = 0u; iy < height; iy++)
{
size_t buffer_index = buffer_index(x, y);
memset32(&m_buffer[buffer_index], color, width);
memset32(&m_buffer1[buffer_index], color, width);
memset32(&m_device_buffer[buffer_index], color, width);
y++;
}
}
@@ -101,7 +108,8 @@ struct fb
static void hline(size_t x, size_t y, size_t width, uint color)
{
size_t buffer_index = buffer_index(x, y);
memset32(&m_buffer[buffer_index], color, width);
memset32(&m_buffer1[buffer_index], color, width);
memset32(&m_device_buffer[buffer_index], color, width);
}
/**
@@ -117,7 +125,8 @@ struct fb
size_t buffer_index = buffer_index(x, y);
for (size_t iy = 0u; iy < height; iy++)
{
m_buffer[buffer_index] = color;
m_buffer1[buffer_index] = color;
m_device_buffer[buffer_index] = color;
buffer_index -= m_stride;
}
}
@@ -153,17 +162,19 @@ struct fb
size_t bitmap_index;
for (size_t iy = 0u; iy < height; iy++)
{
size_t row_buffer_index = buffer_index(x, y);
for (size_t ix = 0u; ix < width; ix++)
{
size_t buffer_index = buffer_index(x + ix, y);
size_t buffer_index = row_buffer_index + ix;
ubyte alpha = alpha_bitmap[bitmap_index];
uint current_color = m_buffer[buffer_index];
uint current_color = m_buffer1[buffer_index];
uint in_color_scaled = scale_color(color, alpha);
uint old_color_scaled = scale_color(current_color, 255u - alpha);
uint new_color = old_color_scaled + in_color_scaled;
m_buffer[buffer_index] = new_color;
m_buffer1[buffer_index] = new_color;
bitmap_index++;
}
memcpy32(&m_device_buffer[row_buffer_index], &m_buffer1[row_buffer_index], width);
y--;
}
}
@@ -202,13 +213,15 @@ struct fb
size_t bitmap_index;
for (size_t iy = 0u; iy < height; iy++)
{
size_t row_buffer_index = buffer_index(x, y);
for (size_t ix = 0u; ix < width; ix++)
{
size_t buffer_index = buffer_index(x + ix, y);
size_t buffer_index = row_buffer_index + ix;
ubyte alpha = alpha_bitmap[bitmap_index];
m_buffer[buffer_index] = (alpha << 16u) | (alpha << 8u) | alpha;
m_buffer1[buffer_index] = (alpha << 16u) | (alpha << 8u) | alpha;
bitmap_index++;
}
memcpy32(&m_device_buffer[row_buffer_index], &m_buffer1[row_buffer_index], width);
y--;
}
}
@@ -239,9 +252,14 @@ struct fb
*/
static void copy_rows_up(size_t y, size_t height, size_t offset)
{
memcpy32(&m_buffer[buffer_index(0u, y + height + offset - 1u)],
&m_buffer[buffer_index(0u, y + height - 1u)],
size_t dest_buffer_index = buffer_index(0u, y + height + offset - 1u);
size_t src_buffer_index = buffer_index(0u, y + height - 1u);
memcpy32(&m_buffer1[dest_buffer_index],
&m_buffer1[src_buffer_index],
(m_stride * height));
memcpy32(&m_device_buffer[dest_buffer_index],
&m_buffer1[dest_buffer_index],
(m_stride * height));
}
/**