From 7db9fbfe80a760d4806aa7eb9d3ebd53c4760823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 14 Aug 2009 20:51:29 +0000 Subject: [PATCH] Factor out the splash image display logic too. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32395 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/boot/platform/generic/video.h | 13 +- src/system/boot/platform/bios_ia32/Jamfile | 1 + src/system/boot/platform/bios_ia32/video.cpp | 104 +------------- .../boot/platform/generic/video_blit.cpp | 52 +++---- .../boot/platform/generic/video_splash.cpp | 134 ++++++++++++++++++ 5 files changed, 178 insertions(+), 126 deletions(-) create mode 100644 src/system/boot/platform/generic/video_splash.cpp diff --git a/headers/private/kernel/boot/platform/generic/video.h b/headers/private/kernel/boot/platform/generic/video.h index 8811f8f802..b157372b90 100644 --- a/headers/private/kernel/boot/platform/generic/video.h +++ b/headers/private/kernel/boot/platform/generic/video.h @@ -15,13 +15,15 @@ extern "C" { /* blit helpers */ /* platform code is responsible for setting the palette correctly */ -void video_blit_image(addr_t frameBuffer, uint32 bytesPerRow, - const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, +void video_blit_image(addr_t frameBuffer, const uint8 *data, + uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top); /* platform code must implement 4bit on its own */ -void platform_blit4(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, - uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top); +void platform_blit4(addr_t frameBuffer, const uint8 *data, + uint16 width, uint16 height, uint16 imageWidth, + uint16 left, uint16 top); +void platform_set_palette(const uint8 *palette); /* Run Length Encoding splash decompression */ @@ -29,6 +31,9 @@ void platform_blit4(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, void uncompress_24bit_RLE(const uint8 compressed[], uint8 *uncompressed); void uncompress_8bit_RLE(const uint8 compressed[], uint8 *uncompressed); +/* default splash display */ +status_t video_display_splash(addr_t frameBuffer); + #ifdef __cplusplus } #endif diff --git a/src/system/boot/platform/bios_ia32/Jamfile b/src/system/boot/platform/bios_ia32/Jamfile index 0980e7641a..ef03efd27f 100644 --- a/src/system/boot/platform/bios_ia32/Jamfile +++ b/src/system/boot/platform/bios_ia32/Jamfile @@ -20,6 +20,7 @@ SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ; local genericPlatformSources = text_menu.cpp video_blit.cpp + video_splash.cpp video_rle.cpp ; diff --git a/src/system/boot/platform/bios_ia32/video.cpp b/src/system/boot/platform/bios_ia32/video.cpp index 8d28e69249..6285360944 100644 --- a/src/system/boot/platform/bios_ia32/video.cpp +++ b/src/system/boot/platform/bios_ia32/video.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -704,7 +703,7 @@ set_text_mode(void) void -platform_blit4(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, +platform_blit4(addr_t frameBuffer, const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top) { if (!data) @@ -712,8 +711,8 @@ platform_blit4(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, // ToDo: no boot logo yet in VGA mode #if 1 // this draws 16 big rectangles in all the available colors - uint8 *bits = (uint8 *)sFrameBuffer; - bytesPerRow = 80; + uint8 *bits = (uint8 *)frameBuffer; + uint32 bytesPerRow = 80; for (int32 i = 0; i < 32; i++) { bits[9 * bytesPerRow + i + 2] = 0x55; bits[30 * bytesPerRow + i + 2] = 0xaa; @@ -753,9 +752,8 @@ platform_blit4(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, } -static void -blit_image(const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, - const uint8 *palette, uint16 left, uint16 top) +extern "C" void +platform_set_palette(const uint8 *palette) { switch (gKernelArgs.frame_buffer.depth) { case 4: @@ -769,8 +767,6 @@ blit_image(const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, default: break; } - video_blit_image(sFrameBuffer, gKernelArgs.frame_buffer.bytes_per_row, - data, width, height, imageWidth, left, top); } @@ -847,95 +843,7 @@ fallback: gKernelArgs.frame_buffer.physical_buffer.size, kDefaultPageFlags); } - // clear the video memory - memset((void *)sFrameBuffer, 0, - gKernelArgs.frame_buffer.physical_buffer.size); - - uint8 *uncompressedLogo = NULL; - switch (gKernelArgs.frame_buffer.depth) { - case 8: - uncompressedLogo = (uint8 *)kernel_args_malloc(kSplashLogoWidth - * kSplashLogoHeight); - if (uncompressedLogo == NULL) - return; - uncompress_8bit_RLE(kSplashLogo8BitCompressedImage, - uncompressedLogo); - break; - default: - uncompressedLogo = (uint8 *)kernel_args_malloc(kSplashLogoWidth - * kSplashLogoHeight * 3); - if (uncompressedLogo == NULL) - return; - uncompress_24bit_RLE(kSplashLogo24BitCompressedImage, - uncompressedLogo); - break; - } - - // TODO: support 4-bit indexed version of the images! - - // render splash logo - uint16 iconsHalfHeight = kSplashIconsHeight / 2; - - int width = min_c(kSplashLogoWidth, gKernelArgs.frame_buffer.width); - int height = min_c(kSplashLogoHeight + iconsHalfHeight, - gKernelArgs.frame_buffer.height); - int placementX = max_c(0, min_c(100, kSplashLogoPlacementX)); - int placementY = max_c(0, min_c(100, kSplashLogoPlacementY)); - - int x = (gKernelArgs.frame_buffer.width - width) * placementX / 100; - int y = (gKernelArgs.frame_buffer.height - height) * placementY / 100; - - height = min_c(kSplashLogoHeight, gKernelArgs.frame_buffer.height); - blit_image(uncompressedLogo, width, height, kSplashLogoWidth, - k8BitPalette, x, y); - - kernel_args_free(uncompressedLogo); - - const uint8* lowerHalfIconImage; - - switch (gKernelArgs.frame_buffer.depth) { - case 8: - // pointer into the lower half of the icons image data - gKernelArgs.boot_splash - = (uint8 *)kernel_args_malloc(kSplashIconsWidth - * kSplashIconsHeight); - if (gKernelArgs.boot_splash == NULL) - return; - uncompress_8bit_RLE(kSplashIcons8BitCompressedImage, - gKernelArgs.boot_splash ); - lowerHalfIconImage = gKernelArgs.boot_splash - + (kSplashIconsWidth * iconsHalfHeight); - break; - default: - // pointer into the lower half of the icons image data - gKernelArgs.boot_splash - = (uint8 *)kernel_args_malloc(kSplashIconsWidth - * kSplashIconsHeight * 3); - if (gKernelArgs.boot_splash == NULL) - return; - uncompress_24bit_RLE(kSplashIcons24BitCompressedImage, - gKernelArgs.boot_splash ); - lowerHalfIconImage = gKernelArgs.boot_splash - + (kSplashIconsWidth * iconsHalfHeight) * 3; - break; - } - - // render initial (grayed out) icons - // the grayed out version is the lower half of the icons image - - width = min_c(kSplashIconsWidth, gKernelArgs.frame_buffer.width); - height = min_c(kSplashLogoHeight + iconsHalfHeight, - gKernelArgs.frame_buffer.height); - placementX = max_c(0, min_c(100, kSplashIconsPlacementX)); - placementY = max_c(0, min_c(100, kSplashIconsPlacementY)); - - x = (gKernelArgs.frame_buffer.width - width) * placementX / 100; - y = kSplashLogoHeight + (gKernelArgs.frame_buffer.height - height) - * placementY / 100; - - height = min_c(iconsHalfHeight, gKernelArgs.frame_buffer.height); - blit_image(lowerHalfIconImage, width, height, kSplashIconsWidth, - k8BitPalette, x, y); + video_display_splash(sFrameBuffer); } diff --git a/src/system/boot/platform/generic/video_blit.cpp b/src/system/boot/platform/generic/video_blit.cpp index 8837ef2686..56e45fb302 100644 --- a/src/system/boot/platform/generic/video_blit.cpp +++ b/src/system/boot/platform/generic/video_blit.cpp @@ -29,10 +29,11 @@ static void -blit32(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, +blit32(addr_t frameBuffer, const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top) { - uint32 *start = (uint32 *)(frameBuffer + bytesPerRow * top + 4 * left); + uint32 *start = (uint32 *)(frameBuffer + + gKernelArgs.frame_buffer.bytes_per_row * top + 4 * left); for (int32 y = 0; y < height; y++) { const uint8* src = data; @@ -45,16 +46,17 @@ blit32(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, data += imageWidth * 3; start = (uint32 *)((addr_t)start - + bytesPerRow); + + gKernelArgs.frame_buffer.bytes_per_row); } } static void -blit24(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, +blit24(addr_t frameBuffer, const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top) { - uint8 *start = (uint8 *)frameBuffer + bytesPerRow * top + 3 * left; + uint8 *start = (uint8 *)frameBuffer + + gKernelArgs.frame_buffer.bytes_per_row * top + 3 * left; for (int32 y = 0; y < height; y++) { const uint8* src = data; @@ -68,16 +70,17 @@ blit24(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, } data += imageWidth * 3; - start = start + bytesPerRow; + start = start + gKernelArgs.frame_buffer.bytes_per_row; } } static void -blit16(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, +blit16(addr_t frameBuffer, const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top) { - uint16 *start = (uint16 *)(frameBuffer + bytesPerRow * top + 2 * left); + uint16 *start = (uint16 *)(frameBuffer + + gKernelArgs.frame_buffer.bytes_per_row * top + 2 * left); for (int32 y = 0; y < height; y++) { const uint8* src = data; @@ -92,16 +95,17 @@ blit16(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, data += imageWidth * 3; start = (uint16 *)((addr_t)start - + bytesPerRow); + + gKernelArgs.frame_buffer.bytes_per_row); } } static void -blit15(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, +blit15(addr_t frameBuffer, const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top) { - uint16 *start = (uint16 *)(frameBuffer + bytesPerRow * top + 2 * left); + uint16 *start = (uint16 *)(frameBuffer + + gKernelArgs.frame_buffer.bytes_per_row * top + 2 * left); for (int32 y = 0; y < height; y++) { const uint8* src = data; @@ -116,62 +120,62 @@ blit15(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, data += imageWidth * 3; start = (uint16 *)((addr_t)start - + bytesPerRow); + + gKernelArgs.frame_buffer.bytes_per_row); } } static void -blit8(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, +blit8(addr_t frameBuffer, const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top) { if (!data) return; - addr_t start = frameBuffer + bytesPerRow * top + addr_t start = frameBuffer + gKernelArgs.frame_buffer.bytes_per_row * top + left; for (int32 i = 0; i < height; i++) { - memcpy((void *)(start + bytesPerRow * i), + memcpy((void *)(start + gKernelArgs.frame_buffer.bytes_per_row * i), &data[i * imageWidth], width); } } static void -blit4(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, +blit4(addr_t frameBuffer, const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top) { if (!data) return; // call back platform specific code since it's really platform-specific. - platform_blit4(frameBuffer, bytesPerRow, data, width, height, + platform_blit4(frameBuffer, data, width, height, imageWidth, left, top); } void -video_blit_image(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, +video_blit_image(addr_t frameBuffer, const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top) { switch (gKernelArgs.frame_buffer.depth) { case 4: - return blit4(frameBuffer, bytesPerRow, data, + return blit4(frameBuffer, data, width, height, imageWidth, left, top); case 8: - return blit8(frameBuffer, bytesPerRow, data, + return blit8(frameBuffer, data, width, height, imageWidth, left, top); case 15: - return blit15(frameBuffer, bytesPerRow, data, + return blit15(frameBuffer, data, width, height, imageWidth, left, top); case 16: - return blit16(frameBuffer, bytesPerRow, data, + return blit16(frameBuffer, data, width, height, imageWidth, left, top); case 24: - return blit24(frameBuffer, bytesPerRow, data, + return blit24(frameBuffer, data, width, height, imageWidth, left, top); case 32: - return blit32(frameBuffer, bytesPerRow, data, + return blit32(frameBuffer, data, width, height, imageWidth, left, top); } } diff --git a/src/system/boot/platform/generic/video_splash.cpp b/src/system/boot/platform/generic/video_splash.cpp new file mode 100644 index 0000000000..4d131ba44c --- /dev/null +++ b/src/system/boot/platform/generic/video_splash.cpp @@ -0,0 +1,134 @@ +/* + * Copyright 2004-2009, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2008, Stephan Aßmus + * Copyright 2008, Philippe Saint-Pierre + * Distributed under the terms of the MIT License. + */ + + +#include "video.h" +#include "mmu.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +//#define TRACE_VIDEO +#ifdef TRACE_VIDEO +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + + +extern "C" status_t +video_display_splash(addr_t frameBuffer) +{ + if (!gKernelArgs.frame_buffer.enabled) + return B_NO_INIT; + + // clear the video memory + memset((void *)frameBuffer, 0, + gKernelArgs.frame_buffer.physical_buffer.size); + + uint8 *uncompressedLogo = NULL; + switch (gKernelArgs.frame_buffer.depth) { + case 8: + platform_set_palette(k8BitPalette); + uncompressedLogo = (uint8 *)kernel_args_malloc(kSplashLogoWidth + * kSplashLogoHeight); + if (uncompressedLogo == NULL) + return B_NO_MEMORY; + uncompress_8bit_RLE(kSplashLogo8BitCompressedImage, + uncompressedLogo); + break; + default: + uncompressedLogo = (uint8 *)kernel_args_malloc(kSplashLogoWidth + * kSplashLogoHeight * 3); + if (uncompressedLogo == NULL) + return B_NO_MEMORY; + uncompress_24bit_RLE(kSplashLogo24BitCompressedImage, + uncompressedLogo); + break; + } + + // TODO: support 4-bit indexed version of the images! + + // render splash logo + uint16 iconsHalfHeight = kSplashIconsHeight / 2; + + int width = min_c(kSplashLogoWidth, gKernelArgs.frame_buffer.width); + int height = min_c(kSplashLogoHeight + iconsHalfHeight, + gKernelArgs.frame_buffer.height); + int placementX = max_c(0, min_c(100, kSplashLogoPlacementX)); + int placementY = max_c(0, min_c(100, kSplashLogoPlacementY)); + + int x = (gKernelArgs.frame_buffer.width - width) * placementX / 100; + int y = (gKernelArgs.frame_buffer.height - height) * placementY / 100; + + height = min_c(kSplashLogoHeight, gKernelArgs.frame_buffer.height); + switch (gKernelArgs.frame_buffer.depth) { + case 8: + break; + } + video_blit_image(frameBuffer, uncompressedLogo, width, height, + kSplashLogoWidth, x, y); + + kernel_args_free(uncompressedLogo); + + const uint8* lowerHalfIconImage; + + switch (gKernelArgs.frame_buffer.depth) { + case 8: + // pointer into the lower half of the icons image data + gKernelArgs.boot_splash + = (uint8 *)kernel_args_malloc(kSplashIconsWidth + * kSplashIconsHeight); + if (gKernelArgs.boot_splash == NULL) + return B_NO_MEMORY; + uncompress_8bit_RLE(kSplashIcons8BitCompressedImage, + gKernelArgs.boot_splash ); + lowerHalfIconImage = gKernelArgs.boot_splash + + (kSplashIconsWidth * iconsHalfHeight); + break; + default: + // pointer into the lower half of the icons image data + gKernelArgs.boot_splash + = (uint8 *)kernel_args_malloc(kSplashIconsWidth + * kSplashIconsHeight * 3); + if (gKernelArgs.boot_splash == NULL) + return B_NO_MEMORY; + uncompress_24bit_RLE(kSplashIcons24BitCompressedImage, + gKernelArgs.boot_splash ); + lowerHalfIconImage = gKernelArgs.boot_splash + + (kSplashIconsWidth * iconsHalfHeight) * 3; + break; + } + + // render initial (grayed out) icons + // the grayed out version is the lower half of the icons image + + width = min_c(kSplashIconsWidth, gKernelArgs.frame_buffer.width); + height = min_c(kSplashLogoHeight + iconsHalfHeight, + gKernelArgs.frame_buffer.height); + placementX = max_c(0, min_c(100, kSplashIconsPlacementX)); + placementY = max_c(0, min_c(100, kSplashIconsPlacementY)); + + x = (gKernelArgs.frame_buffer.width - width) * placementX / 100; + y = kSplashLogoHeight + (gKernelArgs.frame_buffer.height - height) + * placementY / 100; + + height = min_c(iconsHalfHeight, gKernelArgs.frame_buffer.height); + video_blit_image(frameBuffer, lowerHalfIconImage, width, height, + kSplashIconsWidth, x, y); +} +