Factor out the splash image display logic too.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32395 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol 2009-08-14 20:51:29 +00:00
parent 7cd672ff50
commit 7db9fbfe80
5 changed files with 178 additions and 126 deletions

View File

@ -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

View File

@ -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
;

View File

@ -20,7 +20,6 @@
#include <boot/platform.h>
#include <boot/menu.h>
#include <boot/kernel_args.h>
#include <boot/images.h>
#include <boot/platform/generic/video.h>
#include <util/list.h>
#include <drivers/driver_settings.h>
@ -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);
}

View File

@ -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);
}
}

View File

@ -0,0 +1,134 @@
/*
* Copyright 2004-2009, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2008, Stephan Aßmus <superstippi@gmx.de>
* Copyright 2008, Philippe Saint-Pierre <stpere@gmail.com>
* Distributed under the terms of the MIT License.
*/
#include "video.h"
#include "mmu.h"
#include <arch/cpu.h>
#include <boot/stage2.h>
#include <boot/platform.h>
#include <boot/menu.h>
#include <boot/kernel_args.h>
#include <boot/images.h>
#include <boot/platform/generic/video.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#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);
}