1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 06:47:34 +00:00

Kernel/aarch64: Move logo drawing and initializing into RPi::Framebuffer

This is for a upcoming commit that merges the x86_64 and aarch64
init.cpp files.
This commit is contained in:
Timon Kruiper 2023-04-01 01:51:57 +02:00 committed by Andrew Kaster
parent aa40cef2b7
commit 2613ac4cb4
3 changed files with 81 additions and 56 deletions

View file

@ -5,8 +5,18 @@
*/
#include <AK/Format.h>
#include <Kernel/Arch/aarch64/BootPPMParser.h>
#include <Kernel/Arch/aarch64/RPi/Framebuffer.h>
#include <Kernel/Arch/aarch64/RPi/FramebufferMailboxMessages.h>
#include <Kernel/Sections.h>
extern READONLY_AFTER_INIT PhysicalAddress multiboot_framebuffer_addr;
extern READONLY_AFTER_INIT u32 multiboot_framebuffer_pitch;
extern READONLY_AFTER_INIT u32 multiboot_framebuffer_width;
extern READONLY_AFTER_INIT u32 multiboot_framebuffer_height;
extern READONLY_AFTER_INIT u8 multiboot_framebuffer_type;
extern const u32 serenity_boot_logo_start;
extern const u32 serenity_boot_logo_size;
namespace Kernel::RPi {
@ -111,4 +121,69 @@ Framebuffer& Framebuffer::the()
static Framebuffer instance;
return instance;
}
void Framebuffer::initialize()
{
auto& framebuffer = the();
if (framebuffer.initialized()) {
multiboot_framebuffer_addr = PhysicalAddress((PhysicalPtr)framebuffer.gpu_buffer());
multiboot_framebuffer_width = framebuffer.width();
multiboot_framebuffer_height = framebuffer.height();
multiboot_framebuffer_pitch = framebuffer.pitch();
VERIFY(framebuffer.pixel_order() == PixelOrder::RGB);
multiboot_framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
}
}
void Framebuffer::draw_logo(u8* framebuffer_data)
{
BootPPMParser logo_parser(reinterpret_cast<u8 const*>(&serenity_boot_logo_start), serenity_boot_logo_size);
if (!logo_parser.parse()) {
dbgln("Failed to parse boot logo.");
return;
}
dbgln("Boot logo size: {} ({} x {})", serenity_boot_logo_size, logo_parser.image.width, logo_parser.image.height);
auto fb_ptr = framebuffer_data;
auto image_left = (width() - logo_parser.image.width) / 2;
auto image_right = image_left + logo_parser.image.width;
auto image_top = (height() - logo_parser.image.height) / 2;
auto image_bottom = image_top + logo_parser.image.height;
auto logo_pixels = logo_parser.image.pixel_data;
for (u32 y = 0; y < height(); y++) {
for (u32 x = 0; x < width(); x++) {
if (x >= image_left && x < image_right && y >= image_top && y < image_bottom) {
switch (pixel_order()) {
case RPi::Framebuffer::PixelOrder::RGB:
fb_ptr[0] = logo_pixels[0];
fb_ptr[1] = logo_pixels[1];
fb_ptr[2] = logo_pixels[2];
break;
case RPi::Framebuffer::PixelOrder::BGR:
fb_ptr[0] = logo_pixels[2];
fb_ptr[1] = logo_pixels[1];
fb_ptr[2] = logo_pixels[0];
break;
default:
dbgln("Unsupported pixel format");
VERIFY_NOT_REACHED();
}
logo_pixels += 3;
} else {
fb_ptr[0] = 0xBD;
fb_ptr[1] = 0xBD;
fb_ptr[2] = 0xBD;
}
fb_ptr[3] = 0xFF;
fb_ptr += 4;
}
fb_ptr += pitch() - width() * 4;
}
}
}

View file

@ -18,6 +18,7 @@ public:
};
static Framebuffer& the();
static void initialize();
bool initialized() const { return m_initialized; }
u16 width() const { return m_width; }
@ -28,6 +29,8 @@ public:
u32 pitch() const { return m_pitch; }
PixelOrder pixel_order() { return m_pixel_order; }
void draw_logo(u8* framebuffer_data);
private:
u16 m_width;
u16 m_height;

View file

@ -47,7 +47,6 @@ READONLY_AFTER_INIT bool g_in_early_boot;
namespace Kernel {
static void draw_logo(u8* framebuffer_data);
static u32 query_firmware_version();
extern "C" [[noreturn]] void halt();
@ -148,10 +147,12 @@ extern "C" [[noreturn]] void init()
for (ctor_func_t* ctor = start_ctors; ctor < end_ctors; ctor++)
(*ctor)();
RPi::Framebuffer::initialize();
auto& framebuffer = RPi::Framebuffer::the();
if (framebuffer.initialized()) {
g_boot_console = &try_make_lock_ref_counted<Graphics::BootFramebufferConsole>(PhysicalAddress((PhysicalPtr)framebuffer.gpu_buffer()), framebuffer.width(), framebuffer.height(), framebuffer.pitch()).value().leak_ref();
draw_logo(static_cast<Graphics::BootFramebufferConsole*>(g_boot_console.load())->unsafe_framebuffer_data());
framebuffer.draw_logo(static_cast<Graphics::BootFramebufferConsole*>(g_boot_console.load())->unsafe_framebuffer_data());
}
initialize_interrupts();
@ -204,58 +205,4 @@ static u32 query_firmware_version()
return message_queue.query_firmware_version.version;
}
extern "C" const u32 serenity_boot_logo_start;
extern "C" const u32 serenity_boot_logo_size;
static void draw_logo(u8* framebuffer_data)
{
BootPPMParser logo_parser(reinterpret_cast<u8 const*>(&serenity_boot_logo_start), serenity_boot_logo_size);
if (!logo_parser.parse()) {
dbgln("Failed to parse boot logo.");
return;
}
dbgln("Boot logo size: {} ({} x {})", serenity_boot_logo_size, logo_parser.image.width, logo_parser.image.height);
auto& framebuffer = RPi::Framebuffer::the();
auto fb_ptr = framebuffer_data;
auto image_left = (framebuffer.width() - logo_parser.image.width) / 2;
auto image_right = image_left + logo_parser.image.width;
auto image_top = (framebuffer.height() - logo_parser.image.height) / 2;
auto image_bottom = image_top + logo_parser.image.height;
auto logo_pixels = logo_parser.image.pixel_data;
for (u32 y = 0; y < framebuffer.height(); y++) {
for (u32 x = 0; x < framebuffer.width(); x++) {
if (x >= image_left && x < image_right && y >= image_top && y < image_bottom) {
switch (framebuffer.pixel_order()) {
case RPi::Framebuffer::PixelOrder::RGB:
fb_ptr[0] = logo_pixels[0];
fb_ptr[1] = logo_pixels[1];
fb_ptr[2] = logo_pixels[2];
break;
case RPi::Framebuffer::PixelOrder::BGR:
fb_ptr[0] = logo_pixels[2];
fb_ptr[1] = logo_pixels[1];
fb_ptr[2] = logo_pixels[0];
break;
default:
dbgln("Unsupported pixel format");
VERIFY_NOT_REACHED();
}
logo_pixels += 3;
} else {
fb_ptr[0] = 0xBD;
fb_ptr[1] = 0xBD;
fb_ptr[2] = 0xBD;
}
fb_ptr[3] = 0xFF;
fb_ptr += 4;
}
fb_ptr += framebuffer.pitch() - framebuffer.width() * 4;
}
}
}