Add 24-bit graphics support to kernel.

This commit is contained in:
Jonas 'Sortie' Termansen 2016-07-30 02:47:47 +02:00
parent bc1344dacf
commit 91a6ee7919
5 changed files with 59 additions and 38 deletions

View File

@ -108,18 +108,11 @@ find . | grep -Eq '\.xz$' && echo "insmod xzio"
echo echo
cat << EOF cat << EOF
if loadfont unicode ; then insmod all_video
insmod vbe if loadfont unicode; then
insmod vga
EOF
# TODO: Better method of detecting Sortix GRUB and desirable video_bochs.
if [ x"$(uname)" = x"Sortix" ]; then
echo " insmod video_bochs"
fi
cat << EOF
insmod gfxterm insmod gfxterm
terminal_output gfxterm
fi fi
terminal_output gfxterm
set menu_title="Sortix $version for $machine" set menu_title="Sortix $version for $machine"
set timeout=10 set timeout=10

View File

@ -299,7 +299,8 @@ bool BGADevice::Supports(uint64_t connector, struct dispmsg_crtc_mode mode) cons
// TODO: This is disabled because its support needs to be verified, see the // TODO: This is disabled because its support needs to be verified, see the
// framebuffer size calculation above? // framebuffer size calculation above?
if ( mode.fb_format != VBE_DISPI_BPP_32 ) if ( mode.fb_format != VBE_DISPI_BPP_24 &&
mode.fb_format != VBE_DISPI_BPP_32 )
return errno = ENOSYS, false; return errno = ENOSYS, false;
return ((BGADevice*) this)->SupportsResolution(mode.view_xres, mode.view_yres, mode.fb_format); return ((BGADevice*) this)->SupportsResolution(mode.view_xres, mode.view_yres, mode.fb_format);

View File

@ -35,12 +35,7 @@ namespace Sortix {
static uint32_t ColorFromRGB(uint8_t r, uint8_t g, uint8_t b) static uint32_t ColorFromRGB(uint8_t r, uint8_t g, uint8_t b)
{ {
union { struct { uint8_t b, g, r, a; }; uint32_t color; } ret; return (uint32_t) b << 0 | (uint32_t) g << 8 | (uint32_t) r << 16;
ret.r = r;
ret.g = g;
ret.b = b;
ret.a = 255;
return ret.color;
} }
static void LFBTextBuffer__RenderThread(void* user) static void LFBTextBuffer__RenderThread(void* user)
@ -92,6 +87,7 @@ LFBTextBuffer* CreateLFBTextBuffer(uint8_t* lfb, uint32_t lfbformat,
ret->lfb = lfb; ret->lfb = lfb;
ret->backbuf = backbuf; ret->backbuf = backbuf;
ret->lfbformat = lfbformat; ret->lfbformat = lfbformat;
ret->bytes_per_pixel = (lfbformat + 7) / 8;
ret->pixelsx = xres; ret->pixelsx = xres;
ret->pixelsy = yres; ret->pixelsy = yres;
ret->scansize = scansize; ret->scansize = scansize;
@ -110,7 +106,7 @@ LFBTextBuffer* CreateLFBTextBuffer(uint8_t* lfb, uint32_t lfbformat,
ret->cursorenabled = true; ret->cursorenabled = true;
ret->cursorpos = TextPos(0, 0); ret->cursorpos = TextPos(0, 0);
for ( size_t y = 0; y < yres; y++ ) for ( size_t y = 0; y < yres; y++ )
memset(lfb + scansize * y, 0, lfbformat/8UL * xres); memset(lfb + scansize * y, 0, ret->bytes_per_pixel * xres);
ret->emergency_state = false; ret->emergency_state = false;
ret->invalidated = false; ret->invalidated = false;
@ -202,8 +198,11 @@ void LFBTextBuffer::RenderChar(TextChar textchar, size_t posx, size_t posy)
{ {
if ( columns <= posx || rows <= posy ) if ( columns <= posx || rows <= posy )
return; return;
// TODO: Support other font sizes and resolutions. // TODO: Support other resolutions.
if ( lfbformat != 32 || VGA_FONT_WIDTH != 8UL ) if ( lfbformat != 24 && lfbformat != 32 )
return;
// TODO: Support other font sizes.
if ( VGA_FONT_WIDTH != 8UL )
return; return;
bool drawcursor = cursorenabled && posx == cursorpos.x && posy == cursorpos.y; bool drawcursor = cursorenabled && posx == cursorpos.x && posy == cursorpos.y;
uint8_t fgcoloridx = textchar.vgacolor >> 0 & 0x0F; uint8_t fgcoloridx = textchar.vgacolor >> 0 & 0x0F;
@ -214,37 +213,59 @@ void LFBTextBuffer::RenderChar(TextChar textchar, size_t posx, size_t posy)
uint32_t bgcolor = colors[bgcoloridx]; uint32_t bgcolor = colors[bgcoloridx];
int remap = VGA::MapWideToVGAFont(textchar.c); int remap = VGA::MapWideToVGAFont(textchar.c);
const uint8_t* charfont = VGA::GetCharacterFont(font, remap); const uint8_t* charfont = VGA::GetCharacterFont(font, remap);
size_t pixelyoff = rows * VGA_FONT_HEIGHT;
size_t pixelxoff = posx * (VGA_FONT_WIDTH+1);
for ( size_t y = 0; y < VGA_FONT_HEIGHT; y++ ) for ( size_t y = 0; y < VGA_FONT_HEIGHT; y++ )
{ {
size_t pixely = posy * VGA_FONT_HEIGHT + y; size_t pixely = posy * VGA_FONT_HEIGHT + y;
uint8_t linebitmap = charfont[y]; uint8_t linebitmap = charfont[y];
uint32_t* line = (uint32_t*) (lfb + pixely * scansize); uint8_t* line = (uint8_t*) (lfb + pixely * scansize);
size_t pixelxoff = posx * (VGA_FONT_WIDTH+1); size_t bytesxoff = bytes_per_pixel * pixelxoff;
for ( size_t x = 0; x < VGA_FONT_WIDTH; x++ ) for ( size_t x = 0; x < VGA_FONT_WIDTH; x++ )
line[pixelxoff + x] = linebitmap & 1 << (7-x) ? fgcolor : bgcolor; {
uint32_t color = linebitmap & 1 << (7-x) ? fgcolor : bgcolor;
line[bytesxoff++] = color >> 0;
line[bytesxoff++] = color >> 8;
line[bytesxoff++] = color >> 16;
if ( lfbformat == 32 )
line[bytesxoff++] = color >> 24;
}
uint32_t lastcolor = bgcolor; uint32_t lastcolor = bgcolor;
if ( 0xB0 <= remap && remap <= 0xDF && (linebitmap & 1) ) if ( 0xB0 <= remap && remap <= 0xDF && (linebitmap & 1) )
lastcolor = fgcolor; lastcolor = fgcolor;
line[pixelxoff + VGA_FONT_WIDTH] = lastcolor; line[bytesxoff++] = lastcolor >> 0;
line[bytesxoff++] = lastcolor >> 8;
line[bytesxoff++] = lastcolor >> 16;
if ( lfbformat == 32 )
line[bytesxoff++] = lastcolor >> 24;
if ( unlikely(posx + 1 == columns) ) if ( unlikely(posx + 1 == columns) )
{ {
for ( size_t x = pixelxoff + VGA_FONT_WIDTH + 1; x < pixelsx; x++ ) for ( size_t x = pixelxoff + VGA_FONT_WIDTH + 1; x < pixelsx; x++ )
line[x] = bgcolor; {
line[bytesxoff++] = bgcolor >> 0;
line[bytesxoff++] = bgcolor >> 8;
line[bytesxoff++] = bgcolor >> 16;
if ( lfbformat == 32 )
line[bytesxoff++] = bgcolor >> 24;
}
} }
} }
if ( unlikely(posy + 1 == rows) ) if ( unlikely(posy + 1 == rows) )
{ {
size_t pixelyoff = rows * VGA_FONT_HEIGHT; size_t width = VGA_FONT_WIDTH + 1;
if ( unlikely(posx + 1 == columns) )
width = pixelsx - pixelxoff;
for ( size_t y = pixelyoff; y < pixelsy; y++ ) for ( size_t y = pixelyoff; y < pixelsy; y++ )
{ {
uint32_t* line = (uint32_t*) (lfb + y * scansize); size_t bytesxoff = bytes_per_pixel * pixelxoff;
size_t pixelxoff = posx * (VGA_FONT_WIDTH+1); uint8_t* line = (uint8_t*) (lfb + y * scansize);
for ( size_t x = 0; x < VGA_FONT_WIDTH + 1; x++ ) for ( size_t x = 0; x < width; x++ )
line[pixelxoff + x] = bgcolor;
if ( unlikely(posx + 1 == columns) )
{ {
for ( size_t x = pixelxoff + VGA_FONT_WIDTH + 1; x < pixelsx; x++ ) line[bytesxoff++] = bgcolor >> 0;
line[x] = bgcolor; line[bytesxoff++] = bgcolor >> 8;
line[bytesxoff++] = bgcolor >> 16;
if ( lfbformat == 32 )
line[bytesxoff++] = bgcolor >> 24;
} }
} }
} }
@ -254,11 +275,15 @@ void LFBTextBuffer::RenderChar(TextChar textchar, size_t posx, size_t posy)
for ( size_t y = VGA_FONT_HEIGHT - 2; y < underlines; y++ ) for ( size_t y = VGA_FONT_HEIGHT - 2; y < underlines; y++ )
{ {
size_t pixely = posy * VGA_FONT_HEIGHT + y; size_t pixely = posy * VGA_FONT_HEIGHT + y;
uint8_t* line = (uint8_t*) (lfb + pixely * scansize);
size_t bytesxoff = bytes_per_pixel * pixelxoff;
for ( size_t x = 0; x < VGA_FONT_WIDTH+1; x++ ) for ( size_t x = 0; x < VGA_FONT_WIDTH+1; x++ )
{ {
uint32_t* line = (uint32_t*) (lfb + pixely * scansize); line[bytesxoff++] = fgcolor >> 0;
size_t pixelx = posx * (VGA_FONT_WIDTH+1) + x; line[bytesxoff++] = fgcolor >> 8;
line[pixelx] = fgcolor; line[bytesxoff++] = fgcolor >> 16;
if ( lfbformat == 32 )
line[bytesxoff++] = fgcolor >> 24;
} }
} }
} }
@ -304,7 +329,7 @@ void LFBTextBuffer::RenderRange(TextPos from, TextPos to)
for ( size_t sc = scanline_start; sc <= scanline_end; sc++ ) for ( size_t sc = scanline_start; sc <= scanline_end; sc++ )
{ {
size_t offset = sc * scansize; size_t offset = sc * scansize;
memcpy(lfb + offset, backbuf + offset, pixelsx * sizeof(uint32_t)); memcpy(lfb + offset, backbuf + offset, pixelsx * bytes_per_pixel);
} }
} }
} }

View File

@ -133,6 +133,7 @@ private:
size_t scansize; size_t scansize;
uint32_t colors[16UL]; uint32_t colors[16UL];
uint32_t lfbformat; uint32_t lfbformat;
size_t bytes_per_pixel;
bool cursorenabled; bool cursorenabled;
TextPos cursorpos; TextPos cursorpos;
bool emergency_state; bool emergency_state;

View File

@ -143,7 +143,8 @@ void Init(multiboot_info_t* bootinfo)
bootinfo->framebuffer_type != MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT ) bootinfo->framebuffer_type != MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT )
{ {
assert(bootinfo->framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB); assert(bootinfo->framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB);
assert(bootinfo->framebuffer_bpp == 32); assert(bootinfo->framebuffer_bpp == 24 ||
bootinfo->framebuffer_bpp == 32);
assert(0 < bootinfo->framebuffer_width); assert(0 < bootinfo->framebuffer_width);
assert(0 < bootinfo->framebuffer_height); assert(0 < bootinfo->framebuffer_height);
pcibar_t fakebar; pcibar_t fakebar;