mirror of
https://github.com/limine-bootloader/limine
synced 2025-03-15 05:52:54 +03:00
video: Do not switch video modes when unnecessary to avoid flickering and screen blanking out
This commit is contained in:
parent
b44fa6c8e2
commit
1ffb45ac9c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -31,5 +31,6 @@ enum {
|
||||
};
|
||||
|
||||
extern int term_backend;
|
||||
extern int current_video_mode;
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user