From 0573d397e1c87762473770183413613e0039797e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 14 Aug 2009 18:15:44 +0000 Subject: [PATCH] Factor out the RLE and blitting functions from bios_ia32 to platform/generic/ so it can be reused by other platforms. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32383 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/boot/platform/generic/video.h | 36 +++ src/system/boot/platform/bios_ia32/Jamfile | 11 +- src/system/boot/platform/bios_ia32/video.cpp | 226 ++---------------- .../boot/platform/generic/video_blit.cpp | 178 ++++++++++++++ .../boot/platform/generic/video_rle.cpp | 99 ++++++++ 5 files changed, 339 insertions(+), 211 deletions(-) create mode 100644 headers/private/kernel/boot/platform/generic/video.h create mode 100644 src/system/boot/platform/generic/video_blit.cpp create mode 100644 src/system/boot/platform/generic/video_rle.cpp diff --git a/headers/private/kernel/boot/platform/generic/video.h b/headers/private/kernel/boot/platform/generic/video.h new file mode 100644 index 0000000000..8811f8f802 --- /dev/null +++ b/headers/private/kernel/boot/platform/generic/video.h @@ -0,0 +1,36 @@ +/* + * Copyright 2009, Haiku Inc. + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef GENERIC_VIDEO_H +#define GENERIC_VIDEO_H + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* 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, + 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); + + +/* Run Length Encoding splash decompression */ + +void uncompress_24bit_RLE(const uint8 compressed[], uint8 *uncompressed); +void uncompress_8bit_RLE(const uint8 compressed[], uint8 *uncompressed); + +#ifdef __cplusplus +} +#endif + +#endif /* GENERIC_VIDEO_H */ diff --git a/src/system/boot/platform/bios_ia32/Jamfile b/src/system/boot/platform/bios_ia32/Jamfile index 73f4f33a21..0980e7641a 100644 --- a/src/system/boot/platform/bios_ia32/Jamfile +++ b/src/system/boot/platform/bios_ia32/Jamfile @@ -17,6 +17,12 @@ UsePrivateHeaders [ FDirName storage ] ; SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ; +local genericPlatformSources = + text_menu.cpp + video_blit.cpp + video_rle.cpp +; + KernelMergeObject boot_platform_bios_ia32.o : shell.S start.c @@ -38,8 +44,7 @@ KernelMergeObject boot_platform_bios_ia32.o : apm.cpp hpet.cpp - # generic - text_menu.cpp + $(genericPlatformSources) # VESA/DDC EDID decode_edid.c @@ -48,7 +53,7 @@ KernelMergeObject boot_platform_bios_ia32.o : : -fno-pic ; -SEARCH on [ FGristFiles text_menu.cpp ] +SEARCH on [ FGristFiles $(genericPlatformSources) ] = [ FDirName $(HAIKU_TOP) src system boot platform generic ] ; # Tell the build system to where stage1.bin can be found, so it can be used diff --git a/src/system/boot/platform/bios_ia32/video.cpp b/src/system/boot/platform/bios_ia32/video.cpp index 5ce2eabe97..8d28e69249 100644 --- a/src/system/boot/platform/bios_ia32/video.cpp +++ b/src/system/boot/platform/bios_ia32/video.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -702,135 +703,17 @@ set_text_mode(void) // #pragma mark - blit -static void -blit32(const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, - uint16 left, uint16 top) +void +platform_blit4(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, + uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top) { - uint32 *start = (uint32 *)(sFrameBuffer - + gKernelArgs.frame_buffer.bytes_per_row * top + 4 * left); - - for (int32 y = 0; y < height; y++) { - const uint8* src = data; - uint32* dst = start; - for (int32 x = 0; x < width; x++) { - dst[0] = (src[2] << 16) | (src[1] << 8) | (src[0]); - dst++; - src += 3; - } - - data += imageWidth * 3; - start = (uint32 *)((addr_t)start - + gKernelArgs.frame_buffer.bytes_per_row); - } -} - - -static void -blit24(const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, - uint16 left, uint16 top) -{ - uint8 *start = (uint8 *)sFrameBuffer - + gKernelArgs.frame_buffer.bytes_per_row * top + 3 * left; - - for (int32 y = 0; y < height; y++) { - const uint8* src = data; - uint8* dst = start; - for (int32 x = 0; x < width; x++) { - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst += 3; - src += 3; - } - - data += imageWidth * 3; - start = start + gKernelArgs.frame_buffer.bytes_per_row; - } -} - - -static void -blit16(const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, - uint16 left, uint16 top) -{ - uint16 *start = (uint16 *)(sFrameBuffer - + gKernelArgs.frame_buffer.bytes_per_row * top + 2 * left); - - for (int32 y = 0; y < height; y++) { - const uint8* src = data; - uint16* dst = start; - for (int32 x = 0; x < width; x++) { - dst[0] = ((src[2] >> 3) << 11) - | ((src[1] >> 2) << 5) - | ((src[0] >> 3)); - dst++; - src += 3; - } - - data += imageWidth * 3; - start = (uint16 *)((addr_t)start - + gKernelArgs.frame_buffer.bytes_per_row); - } -} - - -static void -blit15(const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, - uint16 left, uint16 top) -{ - uint16 *start = (uint16 *)(sFrameBuffer - + gKernelArgs.frame_buffer.bytes_per_row * top + 2 * left); - - for (int32 y = 0; y < height; y++) { - const uint8* src = data; - uint16* dst = start; - for (int32 x = 0; x < width; x++) { - dst[0] = ((src[2] >> 3) << 10) - | ((src[1] >> 3) << 5) - | ((src[0] >> 3)); - dst++; - src += 3; - } - - data += imageWidth * 3; - start = (uint16 *)((addr_t)start - + gKernelArgs.frame_buffer.bytes_per_row); - } -} - - -static void -blit8(const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, - const uint8 *palette, uint16 left, uint16 top) -{ - if (!data || !palette) + if (!data) return; - - if (vesa_set_palette((const uint8 *)palette, 0, 256) != B_OK) - dprintf("set palette failed!\n"); - - addr_t start = sFrameBuffer + gKernelArgs.frame_buffer.bytes_per_row * top - + left; - - for (int32 i = 0; i < height; i++) { - memcpy((void *)(start + gKernelArgs.frame_buffer.bytes_per_row * i), - &data[i * imageWidth], width); - } -} - - -static void -blit4(const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, - const uint8 *palette, uint16 left, uint16 top) -{ - if (!data || !palette) - return; - // vga_set_palette((const uint8 *)kPalette16, 0, 16); // ToDo: no boot logo yet in VGA mode #if 1 // this draws 16 big rectangles in all the available colors uint8 *bits = (uint8 *)sFrameBuffer; - uint32 bytesPerRow = 80; + bytesPerRow = 80; for (int32 i = 0; i < 32; i++) { bits[9 * bytesPerRow + i + 2] = 0x55; bits[30 * bytesPerRow + i + 2] = 0xaa; @@ -876,91 +759,18 @@ blit_image(const uint8 *data, uint16 width, uint16 height, uint16 imageWidth, { switch (gKernelArgs.frame_buffer.depth) { case 4: - return blit4(data, width, height, imageWidth, palette, - left, top); + //vga_set_palette((const uint8 *)kPalette16, 0, 16); + break; case 8: - return blit8(data, width, height, imageWidth, palette, - left, top); - case 15: - return blit15(data, width, height, imageWidth, left, top); - case 16: - return blit16(data, width, height, imageWidth, left, top); - case 24: - return blit24(data, width, height, imageWidth, left, top); - case 32: - return blit32(data, width, height, imageWidth, left, top); - } -} - - -static void -uncompress_24bit_RLE(const uint8 compressed[], uint8 *uncompressed) -{ - uint32 cursorUncompressed = 0; - uint32 cursorCompressed = 0; - uint8 count = 0; - uint8 item = 0; - int i = 0; - for (uint8 c = 0; c < 3; c++) { - // for Red channel, then Green, then finally Blue... - cursorUncompressed = c; - while (compressed[cursorCompressed]) { - // at the end of the channel there is a terminating 0, - // so the loop will end... (ref: generate_boot_screen.cpp) - count = compressed[cursorCompressed++]; - if (count < 128) { - // regular run, repeat "item" "count" times... - item = compressed[cursorCompressed++]; - for (i = count - 1; i >= 0; --i) { - uncompressed[cursorUncompressed] = item; - cursorUncompressed += 3; - } - } else { - // enumeration, just write the next "count" items as is... - count = count - 128; - for (i = count - 1; i >= 0; --i) { - uncompressed[cursorUncompressed] - = compressed[cursorCompressed++]; - cursorUncompressed += 3; - } - } - } - // the current position of compressed[cursor] is the end of channel, - // we skip it... - cursorCompressed++; - } -} - -static void -uncompress_8Bit_RLE(const uint8 compressed[], uint8 *uncompressed) -{ - uint32 cursorUncompressed = 0; - uint32 cursorCompressed = 0; - uint8 count = 0; - uint8 item = 0; - int i = 0; - - while (compressed[cursorCompressed]) { - // at the end of the channel there is a terminating 0, - // so the loop will end... (ref: generate_boot_screen.cpp) - count = compressed[cursorCompressed++]; - if (count < 128) { - // regular run, repeat "item" "count" times... - item = compressed[cursorCompressed++]; - for (i = count - 1; i >= 0; --i) { - uncompressed[cursorUncompressed] = item; - cursorUncompressed++; - } - } else { - // enumeration, just write the next "count" items as is... - count = count - 128; - for (i = count - 1; i >= 0; --i) { - uncompressed[cursorUncompressed] - = compressed[cursorCompressed++]; - cursorUncompressed++; - } - } + if (vesa_set_palette((const uint8 *)palette, 0, 256) != B_OK) + dprintf("set palette failed!\n"); + + break; + default: + break; } + video_blit_image(sFrameBuffer, gKernelArgs.frame_buffer.bytes_per_row, + data, width, height, imageWidth, left, top); } @@ -1048,7 +858,7 @@ fallback: * kSplashLogoHeight); if (uncompressedLogo == NULL) return; - uncompress_8Bit_RLE(kSplashLogo8BitCompressedImage, + uncompress_8bit_RLE(kSplashLogo8BitCompressedImage, uncompressedLogo); break; default: @@ -1091,7 +901,7 @@ fallback: * kSplashIconsHeight); if (gKernelArgs.boot_splash == NULL) return; - uncompress_8Bit_RLE(kSplashIcons8BitCompressedImage, + uncompress_8bit_RLE(kSplashIcons8BitCompressedImage, gKernelArgs.boot_splash ); lowerHalfIconImage = gKernelArgs.boot_splash + (kSplashIconsWidth * iconsHalfHeight); diff --git a/src/system/boot/platform/generic/video_blit.cpp b/src/system/boot/platform/generic/video_blit.cpp new file mode 100644 index 0000000000..8837ef2686 --- /dev/null +++ b/src/system/boot/platform/generic/video_blit.cpp @@ -0,0 +1,178 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include + + +#define TRACE_VIDEO +#ifdef TRACE_VIDEO +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + + +static void +blit32(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, + uint16 height, uint16 imageWidth, uint16 left, uint16 top) +{ + uint32 *start = (uint32 *)(frameBuffer + bytesPerRow * top + 4 * left); + + for (int32 y = 0; y < height; y++) { + const uint8* src = data; + uint32* dst = start; + for (int32 x = 0; x < width; x++) { + dst[0] = (src[2] << 16) | (src[1] << 8) | (src[0]); + dst++; + src += 3; + } + + data += imageWidth * 3; + start = (uint32 *)((addr_t)start + + bytesPerRow); + } +} + + +static void +blit24(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, + uint16 height, uint16 imageWidth, uint16 left, uint16 top) +{ + uint8 *start = (uint8 *)frameBuffer + bytesPerRow * top + 3 * left; + + for (int32 y = 0; y < height; y++) { + const uint8* src = data; + uint8* dst = start; + for (int32 x = 0; x < width; x++) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst += 3; + src += 3; + } + + data += imageWidth * 3; + start = start + bytesPerRow; + } +} + + +static void +blit16(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, + uint16 height, uint16 imageWidth, uint16 left, uint16 top) +{ + uint16 *start = (uint16 *)(frameBuffer + bytesPerRow * top + 2 * left); + + for (int32 y = 0; y < height; y++) { + const uint8* src = data; + uint16* dst = start; + for (int32 x = 0; x < width; x++) { + dst[0] = ((src[2] >> 3) << 11) + | ((src[1] >> 2) << 5) + | ((src[0] >> 3)); + dst++; + src += 3; + } + + data += imageWidth * 3; + start = (uint16 *)((addr_t)start + + bytesPerRow); + } +} + + +static void +blit15(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, + uint16 height, uint16 imageWidth, uint16 left, uint16 top) +{ + uint16 *start = (uint16 *)(frameBuffer + bytesPerRow * top + 2 * left); + + for (int32 y = 0; y < height; y++) { + const uint8* src = data; + uint16* dst = start; + for (int32 x = 0; x < width; x++) { + dst[0] = ((src[2] >> 3) << 10) + | ((src[1] >> 3) << 5) + | ((src[0] >> 3)); + dst++; + src += 3; + } + + data += imageWidth * 3; + start = (uint16 *)((addr_t)start + + bytesPerRow); + } +} + + +static void +blit8(addr_t frameBuffer, uint32 bytesPerRow, const uint8 *data, uint16 width, + uint16 height, uint16 imageWidth, uint16 left, uint16 top) +{ + if (!data) + return; + + addr_t start = frameBuffer + bytesPerRow * top + + left; + + for (int32 i = 0; i < height; i++) { + memcpy((void *)(start + bytesPerRow * i), + &data[i * imageWidth], width); + } +} + + +static void +blit4(addr_t frameBuffer, uint32 bytesPerRow, 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, + imageWidth, left, top); +} + + +void +video_blit_image(addr_t frameBuffer, uint32 bytesPerRow, 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, + width, height, imageWidth, left, top); + case 8: + return blit8(frameBuffer, bytesPerRow, data, + width, height, imageWidth, left, top); + case 15: + return blit15(frameBuffer, bytesPerRow, data, + width, height, imageWidth, left, top); + case 16: + return blit16(frameBuffer, bytesPerRow, data, + width, height, imageWidth, left, top); + case 24: + return blit24(frameBuffer, bytesPerRow, data, + width, height, imageWidth, left, top); + case 32: + return blit32(frameBuffer, bytesPerRow, data, + width, height, imageWidth, left, top); + } +} + diff --git a/src/system/boot/platform/generic/video_rle.cpp b/src/system/boot/platform/generic/video_rle.cpp new file mode 100644 index 0000000000..4708da077e --- /dev/null +++ b/src/system/boot/platform/generic/video_rle.cpp @@ -0,0 +1,99 @@ +/* + * 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 +#include +#include +#include +#include + +#include +#include +#include + + +#define TRACE_VIDEO +#ifdef TRACE_VIDEO +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + +void +uncompress_24bit_RLE(const uint8 compressed[], uint8 *uncompressed) +{ + uint32 cursorUncompressed = 0; + uint32 cursorCompressed = 0; + uint8 count = 0; + uint8 item = 0; + int i = 0; + for (uint8 c = 0; c < 3; c++) { + // for Red channel, then Green, then finally Blue... + cursorUncompressed = c; + while (compressed[cursorCompressed]) { + // at the end of the channel there is a terminating 0, + // so the loop will end... (ref: generate_boot_screen.cpp) + count = compressed[cursorCompressed++]; + if (count < 128) { + // regular run, repeat "item" "count" times... + item = compressed[cursorCompressed++]; + for (i = count - 1; i >= 0; --i) { + uncompressed[cursorUncompressed] = item; + cursorUncompressed += 3; + } + } else { + // enumeration, just write the next "count" items as is... + count = count - 128; + for (i = count - 1; i >= 0; --i) { + uncompressed[cursorUncompressed] + = compressed[cursorCompressed++]; + cursorUncompressed += 3; + } + } + } + // the current position of compressed[cursor] is the end of channel, + // we skip it... + cursorCompressed++; + } +} + +void +uncompress_8bit_RLE(const uint8 compressed[], uint8 *uncompressed) +{ + uint32 cursorUncompressed = 0; + uint32 cursorCompressed = 0; + uint8 count = 0; + uint8 item = 0; + int i = 0; + + while (compressed[cursorCompressed]) { + // at the end of the channel there is a terminating 0, + // so the loop will end... (ref: generate_boot_screen.cpp) + count = compressed[cursorCompressed++]; + if (count < 128) { + // regular run, repeat "item" "count" times... + item = compressed[cursorCompressed++]; + for (i = count - 1; i >= 0; --i) { + uncompressed[cursorUncompressed] = item; + cursorUncompressed++; + } + } else { + // enumeration, just write the next "count" items as is... + count = count - 128; + for (i = count - 1; i >= 0; --i) { + uncompressed[cursorUncompressed] + = compressed[cursorCompressed++]; + cursorUncompressed++; + } + } + } +} + +