video: Do not switch video modes when unnecessary to avoid flickering and screen blanking out

This commit is contained in:
mintsuki 2021-04-04 03:38:38 +02:00
parent b44fa6c8e2
commit 1ffb45ac9c
5 changed files with 57 additions and 14 deletions

View File

@ -2,6 +2,7 @@
#include <efi.h>
#include <lib/blib.h>
#include <lib/term.h>
#include <drivers/gop.h>
#include <drivers/edid.h>
#include <lib/print.h>
@ -98,19 +99,34 @@ static bool try_mode(struct fb_info *ret, size_t mode, int width, int height, in
print("gop: Found matching mode %x, attempting to set...\n", mode);
if ((int)mode == current_video_mode) {
print("gop: Mode was already set, perfect!\n");
}
status = uefi_call_wrapper(gop->SetMode, 2, gop, mode);
if (status) {
current_video_mode = -2;
print("gop: Failed to set video mode %x, moving on...\n", mode);
return false;
}
current_video_mode = mode;
ret->memory_model = 0x06;
ret->framebuffer_addr = gop->Mode->FrameBufferBase;
ret->framebuffer_pitch = gop->Mode->Info->PixelsPerScanLine * 4;
ret->framebuffer_width = gop->Mode->Info->HorizontalResolution;
ret->framebuffer_height = gop->Mode->Info->VerticalResolution;
// Clear framebuffer
for (size_t y = 0; y < ret->framebuffer_height; y++) {
for (size_t x = 0; x < ret->framebuffer_pitch; x++) {
uint8_t *fbp = (uint8_t *)(uintptr_t)ret->framebuffer_addr;
fbp[y * ret->framebuffer_pitch + x] = 0;
}
}
return true;
}

View File

@ -12,6 +12,7 @@
#include <lib/image.h>
#include <lib/config.h>
#include <lib/uri.h>
#include <lib/term.h>
#include <mm/pmm.h>
struct vbe_info_struct {
@ -175,10 +176,15 @@ retry:
if (!(vbe_mode_info.mode_attributes & (1 << 7)))
continue;
print("vbe: Found matching mode %x, attempting to set...\n", vid_modes[i]);
if (set_vbe_mode(vid_modes[i]) == 0x01) {
if (vid_modes[i] == current_video_mode) {
print("vbe: Mode was already set, perfect!\n");
} else if (set_vbe_mode(vid_modes[i]) == 0x01) {
current_video_mode = -2;
print("vbe: Failed to set video mode %x, moving on...\n", vid_modes[i]);
continue;
}
current_video_mode = vid_modes[i];
print("vbe: Framebuffer address: %x\n", vbe_mode_info.framebuffer_addr);
ret->memory_model = vbe_mode_info.memory_model;
ret->framebuffer_addr = vbe_mode_info.framebuffer_addr;
@ -202,6 +208,15 @@ retry:
ret->blue_mask_size = vbe_mode_info.lin_blue_mask_size;
ret->blue_mask_shift = vbe_mode_info.lin_blue_mask_shift;
}
// Clear framebuffer
for (size_t y = 0; y < ret->framebuffer_height; y++) {
for (size_t x = 0; x < ret->framebuffer_pitch; x++) {
uint8_t *fbp = (uint8_t *)(uintptr_t)ret->framebuffer_addr;
fbp[y * ret->framebuffer_pitch + x] = 0;
}
}
return true;
}
}

View File

@ -7,6 +7,7 @@
#include <sys/cpu.h>
#include <lib/real.h>
#include <lib/libc.h>
#include <lib/term.h>
#include <mm/pmm.h>
#define VIDEO_BOTTOM ((VD_ROWS * VD_COLS) - 1)
@ -19,10 +20,10 @@ static uint8_t *video_mem = (uint8_t *)0xb8000;
static uint8_t *current_buffer;
static size_t cursor_offset = 0;
static int cursor_status = 1;
static uint8_t text_palette = 0x07;
static uint8_t cursor_palette = 0x70;
static size_t cursor_offset;
static int cursor_status;
static uint8_t text_palette;
static uint8_t cursor_palette;
static void clear_cursor(void) {
current_buffer[cursor_offset + 1] = text_palette;
@ -75,13 +76,28 @@ void text_disable_cursor(void) {
// VGA cursor code taken from: https://wiki.osdev.org/Text_Mode_Cursor
void init_vga_textmode(int *_rows, int *_cols) {
if (current_video_mode != -1) {
struct rm_regs r = {0};
r.eax = 0x0003;
rm_int(0x10, &r, &r);
current_video_mode = -1;
}
outb(0x3d4, 0x0a);
outb(0x3d5, 0x20);
*_rows = VD_ROWS;
*_cols = VD_COLS / 2;
cursor_offset = 0;
cursor_status = 1;
text_palette = 0x07;
cursor_palette = 0x70;
text_double_buffer(false);
text_clear(false);
*_rows = VD_ROWS;
*_cols = VD_COLS / 2;
}
void text_double_buffer(bool state) {

View File

@ -31,5 +31,6 @@ enum {
};
extern int term_backend;
extern int current_video_mode;
#endif

View File

@ -7,6 +7,8 @@
#include <lib/blib.h>
#include <drivers/vga_textmode.h>
int current_video_mode = -1;
int term_backend = NOT_READY;
void (*raw_putchar)(uint8_t c);
@ -25,7 +27,6 @@ int term_rows, term_cols;
#if defined (bios)
void term_textmode(void) {
term_deinit();
init_vga_textmode(&term_rows, &term_cols);
raw_putchar = text_putchar;
@ -45,12 +46,6 @@ void term_textmode(void) {
#endif
void term_deinit(void) {
#if defined (bios)
struct rm_regs r = {0};
r.eax = 0x0003;
rm_int(0x10, &r, &r);
#endif
term_backend = NOT_READY;
}