1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 11:27:35 +00:00

WindowServer: Coordinate double-buffering with the BochsVGA card.

Use the BochsVGA card's virtual-height + virtual-y features to implement
a "hardware double buffering" type scheme.

This is a performance degradation since we now draw a bunch more than before.
But there's also no tearing or cursor flickering. I'm gonna commit this and
try to improve upon it. :^)
This commit is contained in:
Andreas Kling 2019-02-07 08:53:57 +01:00
parent 1f159eaab0
commit 443d1c2237
6 changed files with 52 additions and 15 deletions

View file

@ -13,6 +13,8 @@
#define VBE_DISPI_INDEX_BANK 0x5
#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
#define VBE_DISPI_INDEX_X_OFFSET 0x8
#define VBE_DISPI_INDEX_Y_OFFSET 0x9
#define VBE_DISPI_DISABLED 0x00
#define VBE_DISPI_ENABLED 0x01
#define VBE_DISPI_LFB_ENABLED 0x40
@ -42,12 +44,17 @@ void BochsVGADevice::set_resolution(int width, int height)
set_register(VBE_DISPI_INDEX_XRES, width);
set_register(VBE_DISPI_INDEX_YRES, height);
set_register(VBE_DISPI_INDEX_VIRT_WIDTH, width);
set_register(VBE_DISPI_INDEX_VIRT_HEIGHT, height);
set_register(VBE_DISPI_INDEX_VIRT_HEIGHT, height * 2);
set_register(VBE_DISPI_INDEX_BPP, 32);
set_register(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
set_register(VBE_DISPI_INDEX_BANK, 0);
}
void BochsVGADevice::set_y_offset(int offset)
{
set_register(VBE_DISPI_INDEX_Y_OFFSET, offset);
}
dword BochsVGADevice::find_framebuffer_address()
{
static const PCI::ID bochs_vga_id = { 0x1234, 0x1111 };

View file

@ -15,6 +15,7 @@ public:
PhysicalAddress framebuffer_address() const { return m_framebuffer_address; }
void set_resolution(int width, int height);
void set_y_offset(int);
private:
void set_register(word index, word value);

View file

@ -276,7 +276,7 @@ DisplayInfo Process::set_video_resolution(int width, int height)
info.height = height;
info.bpp = 32;
info.pitch = width * 4;
size_t framebuffer_size = width * height * 4;
size_t framebuffer_size = width * height * 4 * 2;
if (!m_display_framebuffer_region) {
auto framebuffer_vmo = VMObject::create_framebuffer_wrapper(BochsVGADevice::the().framebuffer_address(), framebuffer_size);
m_display_framebuffer_region = allocate_region_with_vmo(LinearAddress(0xe0000000), framebuffer_size, move(framebuffer_vmo), 0, "framebuffer", true, true);