diff --git a/kernel/kernel/Device/FramebufferDevice.cpp b/kernel/kernel/Device/FramebufferDevice.cpp index 0d27f38771..3f2b5de64a 100644 --- a/kernel/kernel/Device/FramebufferDevice.cpp +++ b/kernel/kernel/Device/FramebufferDevice.cpp @@ -9,9 +9,6 @@ namespace Kernel { - // Internally we hold 32 bpp buffer (top 8 bits not used) - static constexpr uint32_t bytes_per_pixel_internal = 4; - static uint32_t get_framebuffer_device_index() { static uint32_t index = 0; @@ -75,7 +72,7 @@ namespace Kernel m_video_buffer = TRY(VirtualRange::create_to_vaddr_range( PageTable::kernel(), KERNEL_OFFSET, UINTPTR_MAX, - BAN::Math::div_round_up(m_width * m_height * bytes_per_pixel_internal, PAGE_SIZE) * PAGE_SIZE, + BAN::Math::div_round_up(m_width * m_height * (BANAN_FB_BPP / 8), PAGE_SIZE) * PAGE_SIZE, PageTable::Flags::ReadWrite | PageTable::Flags::Present, true )); @@ -94,15 +91,14 @@ namespace Kernel auto& fb_info = buffer.as(); fb_info.width = m_width; fb_info.height = m_height; - fb_info.bpp = m_bpp; return sizeof(framebuffer_info_t); } - if ((size_t)offset >= m_width * m_height * bytes_per_pixel_internal) + if ((size_t)offset >= m_width * m_height * (BANAN_FB_BPP / 8)) return 0; - size_t bytes_to_copy = BAN::Math::min(m_width * m_height * bytes_per_pixel_internal - offset, buffer.size()); + size_t bytes_to_copy = BAN::Math::min(m_width * m_height * (BANAN_FB_BPP / 8) - offset, buffer.size()); memcpy(buffer.data(), reinterpret_cast(m_video_buffer->vaddr() + offset), bytes_to_copy); return bytes_to_copy; @@ -112,14 +108,14 @@ namespace Kernel { if (offset < 0) return BAN::Error::from_errno(EINVAL); - if ((size_t)offset >= m_width * m_height * bytes_per_pixel_internal) + if ((size_t)offset >= m_width * m_height * (BANAN_FB_BPP / 8)) return 0; - size_t bytes_to_copy = BAN::Math::min(m_width * m_height * bytes_per_pixel_internal - offset, buffer.size()); + size_t bytes_to_copy = BAN::Math::min(m_width * m_height * (BANAN_FB_BPP / 8) - offset, buffer.size()); memcpy(reinterpret_cast(m_video_buffer->vaddr() + offset), buffer.data(), bytes_to_copy); - uint32_t first_pixel = offset / bytes_per_pixel_internal; - uint32_t pixel_count = BAN::Math::div_round_up(bytes_to_copy + (offset % bytes_per_pixel_internal), bytes_per_pixel_internal); + uint32_t first_pixel = offset / (BANAN_FB_BPP / 8); + uint32_t pixel_count = BAN::Math::div_round_up(bytes_to_copy + (offset % (BANAN_FB_BPP / 8)), (BANAN_FB_BPP / 8)); sync_pixels_linear(first_pixel, pixel_count); return bytes_to_copy; @@ -129,8 +125,12 @@ namespace Kernel { if (x >= m_width || y >= m_height) return; - auto* video_buffer_u32 = reinterpret_cast(m_video_buffer->vaddr()); - video_buffer_u32[y * m_width + x] = rgb; + auto* video_buffer_u8 = reinterpret_cast(m_video_buffer->vaddr()); + video_buffer_u8[(y * m_width + x) * (BANAN_FB_BPP / 8) + 0] = rgb >> 0; + video_buffer_u8[(y * m_width + x) * (BANAN_FB_BPP / 8) + 1] = rgb >> 8; + video_buffer_u8[(y * m_width + x) * (BANAN_FB_BPP / 8) + 2] = rgb >> 16; + if constexpr(BANAN_FB_BPP == 32) + video_buffer_u8[(y * m_width + x) * (BANAN_FB_BPP / 8) + 3] = rgb >> 24; } void FramebufferDevice::sync_pixels_full() @@ -143,9 +143,9 @@ namespace Kernel uint32_t row = i / m_width; uint32_t idx = i % m_width; - video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 0] = video_buffer_u8[i * bytes_per_pixel_internal + 0]; - video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 1] = video_buffer_u8[i * bytes_per_pixel_internal + 1]; - video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 2] = video_buffer_u8[i * bytes_per_pixel_internal + 2]; + video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 0] = video_buffer_u8[i * (BANAN_FB_BPP / 8) + 0]; + video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 1] = video_buffer_u8[i * (BANAN_FB_BPP / 8) + 1]; + video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 2] = video_buffer_u8[i * (BANAN_FB_BPP / 8) + 2]; } } @@ -164,9 +164,9 @@ namespace Kernel uint32_t row = (first_pixel + i) / m_width; uint32_t idx = (first_pixel + i) % m_width; - video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 0] = video_buffer_u8[(first_pixel + i) * bytes_per_pixel_internal + 0]; - video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 1] = video_buffer_u8[(first_pixel + i) * bytes_per_pixel_internal + 1]; - video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 2] = video_buffer_u8[(first_pixel + i) * bytes_per_pixel_internal + 2]; + video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 0] = video_buffer_u8[(first_pixel + i) * (BANAN_FB_BPP / 8) + 0]; + video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 1] = video_buffer_u8[(first_pixel + i) * (BANAN_FB_BPP / 8) + 1]; + video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 2] = video_buffer_u8[(first_pixel + i) * (BANAN_FB_BPP / 8) + 2]; } } @@ -186,9 +186,9 @@ namespace Kernel { for (uint32_t idx = top_right_x; idx < top_right_x + width; idx++) { - video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 0] = video_buffer_u8[(row * m_width + idx) * bytes_per_pixel_internal + 0]; - video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 1] = video_buffer_u8[(row * m_width + idx) * bytes_per_pixel_internal + 1]; - video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 2] = video_buffer_u8[(row * m_width + idx) * bytes_per_pixel_internal + 2]; + video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 0] = video_buffer_u8[(row * m_width + idx) * (BANAN_FB_BPP / 8) + 0]; + video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 1] = video_buffer_u8[(row * m_width + idx) * (BANAN_FB_BPP / 8) + 1]; + video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 2] = video_buffer_u8[(row * m_width + idx) * (BANAN_FB_BPP / 8) + 2]; } } } @@ -224,8 +224,8 @@ namespace Kernel size = (vaddr - m_vaddr) + m_size; m_framebuffer->sync_pixels_linear( - (vaddr - m_vaddr) / bytes_per_pixel_internal, - BAN::Math::div_round_up((vaddr % bytes_per_pixel_internal) + size, bytes_per_pixel_internal) + (vaddr - m_vaddr) / (BANAN_FB_BPP / 8), + BAN::Math::div_round_up((vaddr % (BANAN_FB_BPP / 8)) + size, (BANAN_FB_BPP / 8)) ); return {}; diff --git a/libc/include/sys/framebuffer.h b/libc/include/sys/framebuffer.h index ab92ad0daa..a201ed8522 100644 --- a/libc/include/sys/framebuffer.h +++ b/libc/include/sys/framebuffer.h @@ -7,11 +7,12 @@ __BEGIN_DECLS #include +#define BANAN_FB_BPP 32 + struct framebuffer_info_t { uint32_t width; uint32_t height; - uint8_t bpp; }; __END_DECLS diff --git a/userspace/image/Image.cpp b/userspace/image/Image.cpp index 2015290980..bf81cd07dc 100644 --- a/userspace/image/Image.cpp +++ b/userspace/image/Image.cpp @@ -103,14 +103,9 @@ bool Image::render_to_framebuffer() return false; } - if (fb_info.bpp != 24 && fb_info.bpp != 32) - { - fprintf(stderr, "unsupported framebuffer bpp\n"); - close(fd); - return false; - } + ASSERT(BANAN_FB_BPP == 24 || BANAN_FB_BPP == 32); - size_t mmap_size = fb_info.height * fb_info.width * fb_info.bpp / 8; + size_t mmap_size = fb_info.height * fb_info.width * BANAN_FB_BPP / 8; void* mmap_addr = mmap(nullptr, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mmap_addr == MAP_FAILED) @@ -126,11 +121,11 @@ bool Image::render_to_framebuffer() { for (uint64_t x = 0; x < BAN::Math::min(width(), fb_info.width); x++) { - u8_fb[(y * fb_info.width + x) * fb_info.bpp / 8 + 0] = m_bitmap[y * width() + x].r; - u8_fb[(y * fb_info.width + x) * fb_info.bpp / 8 + 1] = m_bitmap[y * width() + x].g; - u8_fb[(y * fb_info.width + x) * fb_info.bpp / 8 + 2] = m_bitmap[y * width() + x].b; - if (fb_info.bpp == 32) - u8_fb[(y * fb_info.width + x) * fb_info.bpp / 8 + 3] = m_bitmap[y * width() + x].a; + u8_fb[(y * fb_info.width + x) * BANAN_FB_BPP / 8 + 0] = m_bitmap[y * width() + x].r; + u8_fb[(y * fb_info.width + x) * BANAN_FB_BPP / 8 + 1] = m_bitmap[y * width() + x].g; + u8_fb[(y * fb_info.width + x) * BANAN_FB_BPP / 8 + 2] = m_bitmap[y * width() + x].b; + if constexpr(BANAN_FB_BPP == 32) + u8_fb[(y * fb_info.width + x) * BANAN_FB_BPP / 8 + 3] = m_bitmap[y * width() + x].a; } } diff --git a/userspace/test-framebuffer/main.cpp b/userspace/test-framebuffer/main.cpp index 159bba03aa..314e6bf1c7 100644 --- a/userspace/test-framebuffer/main.cpp +++ b/userspace/test-framebuffer/main.cpp @@ -19,7 +19,7 @@ int main() return 1; } - size_t fb_size = fb_info.width * fb_info.height * fb_info.bpp / 8; + size_t fb_size = fb_info.width * fb_info.height * BANAN_FB_BPP / 8; void* addr = mmap(nullptr, fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (addr == MAP_FAILED)