* Added debug_screen_output_enabled() function.
* The boot splash code now checks wether debug screen output is enabled or not using the above function. * The boot splash code no longer maps it's own copy of the frame buffer, instead, it will use the boot item feature as the VESA driver does. Also removed the lock, as that's not needed at all. * Renamed splash.cpp to boot_splash.cpp, and boot/splash.h to boot_splash.h (it's not part of the boot loader, but the kernel). * Removed dead code from boot_splash.cpp, added license. Replaced license header in boot_splash.h to a style guide conforming one. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24489 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
48498869f9
commit
a886f802fc
@ -1,60 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2008, Haiku, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// File Name: bootsplashstructs.h
|
||||
// Author: Artur Wyszynski <harakash@gmail.com>
|
||||
// Description: Boot splash header
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef KERNEL_BOOT_SPLASH_H
|
||||
#define KERNEL_BOOT_SPLASH_H
|
||||
|
||||
struct kernel_args;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
BOOT_SPLASH_STAGE_1_INIT_MODULES = 0,
|
||||
BOOT_SPLASH_STAGE_2_BOOTSTRAP_FS,
|
||||
BOOT_SPLASH_STAGE_3_INIT_DEVICES,
|
||||
BOOT_SPLASH_STAGE_4_MOUNT_BOOT_FS,
|
||||
BOOT_SPLASH_STAGE_5_INIT_CPU_MODULES,
|
||||
BOOT_SPLASH_STAGE_6_INIT_VM_MODULES,
|
||||
BOOT_SPLASH_STAGE_7_RUN_BOOT_SCRIPT,
|
||||
|
||||
BOOT_SPLASH_STAGE_MAX // keep this at the end
|
||||
};
|
||||
|
||||
status_t boot_splash_fb_init(struct kernel_args *args);
|
||||
bool boot_splash_fb_available(void);
|
||||
|
||||
void boot_splash_set_stage(int stage);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KERNEL_BOOT_SPLASH_H */
|
||||
|
||||
|
39
headers/private/kernel/boot_splash.h
Normal file
39
headers/private/kernel/boot_splash.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2008, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Artur Wyszynski <harakash@gmail.com>
|
||||
*/
|
||||
#ifndef KERNEL_BOOT_SPLASH_H
|
||||
#define KERNEL_BOOT_SPLASH_H
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
enum {
|
||||
BOOT_SPLASH_STAGE_1_INIT_MODULES = 0,
|
||||
BOOT_SPLASH_STAGE_2_BOOTSTRAP_FS,
|
||||
BOOT_SPLASH_STAGE_3_INIT_DEVICES,
|
||||
BOOT_SPLASH_STAGE_4_MOUNT_BOOT_FS,
|
||||
BOOT_SPLASH_STAGE_5_INIT_CPU_MODULES,
|
||||
BOOT_SPLASH_STAGE_6_INIT_VM_MODULES,
|
||||
BOOT_SPLASH_STAGE_7_RUN_BOOT_SCRIPT,
|
||||
|
||||
BOOT_SPLASH_STAGE_MAX // keep this at the end
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void boot_splash_init(void);
|
||||
void boot_splash_set_stage(int stage);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KERNEL_BOOT_SPLASH_H */
|
@ -70,6 +70,7 @@ extern status_t debug_init_post_modules(struct kernel_args *args);
|
||||
extern void debug_early_boot_message(const char *string);
|
||||
extern void debug_puts(const char *s, int32 length);
|
||||
extern bool debug_debugger_running(void);
|
||||
extern bool debug_screen_output_enabled(void);
|
||||
extern void debug_stop_screen_debug_output(void);
|
||||
|
||||
extern void kputs(const char *string);
|
||||
|
@ -17,6 +17,7 @@ AddResources kernel_$(TARGET_ARCH) : kernel.rdef ;
|
||||
|
||||
KernelMergeObject kernel_core.o :
|
||||
boot_item.cpp
|
||||
boot_splash.cpp
|
||||
commpage.cpp
|
||||
condition_variable.cpp
|
||||
cpu.c
|
||||
@ -39,7 +40,6 @@ KernelMergeObject kernel_core.o :
|
||||
system_info.cpp
|
||||
smp.c
|
||||
syscalls.cpp
|
||||
splash.cpp
|
||||
team.cpp
|
||||
thread.cpp
|
||||
timer.c
|
||||
|
204
src/system/kernel/boot_splash.cpp
Normal file
204
src/system/kernel/boot_splash.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright 2008, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Artur Wyszynski <harakash@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include <boot_splash.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <boot/images.h>
|
||||
#include <boot_item.h>
|
||||
#include <debug.h>
|
||||
#include <frame_buffer_console.h>
|
||||
|
||||
|
||||
//#define TRACE_BOOT_SPLASH 1
|
||||
#ifdef TRACE_BOOT_SPLASH
|
||||
# define TRACE(x...) dprintf(x);
|
||||
#else
|
||||
# define TRACE(x...) ;
|
||||
#endif
|
||||
|
||||
|
||||
static struct frame_buffer_boot_info *sInfo;
|
||||
|
||||
|
||||
static void
|
||||
blit15_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop,
|
||||
uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
|
||||
uint16 imageHeight, const uint8 *palette, uint16 left, uint16 top)
|
||||
{
|
||||
data += (imageWidth * imageTop + imageLeft) * 3;
|
||||
uint16* start = (uint16*)(sInfo->frame_buffer
|
||||
+ sInfo->bytes_per_row * (top + imageTop)
|
||||
+ 2 * (left + imageLeft));
|
||||
|
||||
for (int32 y = imageTop; y < imageBottom; y++) {
|
||||
const uint8* src = data;
|
||||
uint16* dst = start;
|
||||
for (int32 x = imageLeft; x < imageRight; 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 + sInfo->bytes_per_row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
blit16_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop,
|
||||
uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
|
||||
uint16 imageHeight, const uint8 *palette, uint16 left, uint16 top)
|
||||
{
|
||||
data += (imageWidth * imageTop + imageLeft) * 3;
|
||||
uint16* start = (uint16*)(sInfo->frame_buffer
|
||||
+ sInfo->bytes_per_row * (top + imageTop) + 2 * (left + imageLeft));
|
||||
|
||||
for (int32 y = imageTop; y < imageBottom; y++) {
|
||||
const uint8* src = data;
|
||||
uint16* dst = start;
|
||||
for (int32 x = imageLeft; x < imageRight; 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 + sInfo->bytes_per_row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
blit24_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop,
|
||||
uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
|
||||
uint16 imageHeight, const uint8 *palette, uint16 left, uint16 top)
|
||||
{
|
||||
data += (imageWidth * imageTop + imageLeft) * 3;
|
||||
uint8* start = (uint8*)(sInfo->frame_buffer
|
||||
+ sInfo->bytes_per_row * (top + imageTop) + 3 * (left + imageLeft));
|
||||
|
||||
for (int32 y = imageTop; y < imageBottom; y++) {
|
||||
const uint8* src = data;
|
||||
uint8* dst = start;
|
||||
for (int32 x = imageLeft; x < imageRight; x++) {
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
dst += 3;
|
||||
src += 3;
|
||||
}
|
||||
|
||||
data += imageWidth * 3;
|
||||
start = (uint8*)((addr_t)start + sInfo->bytes_per_row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
blit32_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop,
|
||||
uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
|
||||
uint16 imageHeight, const uint8 *palette, uint16 left, uint16 top)
|
||||
{
|
||||
data += (imageWidth * imageTop + imageLeft) * 3;
|
||||
uint32* start = (uint32*)(sInfo->frame_buffer
|
||||
+ sInfo->bytes_per_row * (top + imageTop) + 4 * (left + imageLeft));
|
||||
|
||||
for (int32 y = imageTop; y < imageBottom; y++) {
|
||||
const uint8* src = data;
|
||||
uint32* dst = start;
|
||||
for (int32 x = imageLeft; x < imageRight; x++) {
|
||||
dst[0] = (src[2] << 16) | (src[1] << 8) | (src[0]);
|
||||
dst++;
|
||||
src += 3;
|
||||
}
|
||||
|
||||
data += imageWidth * 3;
|
||||
start = (uint32*)((addr_t)start + sInfo->bytes_per_row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
blit_cropped(const uint8* data, const uint8* indexedData,
|
||||
uint16 imageLeft, uint16 imageTop, uint16 imageRight, uint16 imageBottom,
|
||||
uint16 imageWidth, uint16 imageHeight, const uint8 *palette,
|
||||
uint16 left, uint16 top)
|
||||
{
|
||||
switch (sInfo->depth) {
|
||||
case 15:
|
||||
blit15_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
|
||||
imageWidth, imageHeight, palette, left, top);
|
||||
return;
|
||||
case 16:
|
||||
blit16_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
|
||||
imageWidth, imageHeight, palette, left, top);
|
||||
return;
|
||||
case 24:
|
||||
blit24_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
|
||||
imageWidth, imageHeight, palette, left, top);
|
||||
return;
|
||||
case 32:
|
||||
blit32_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
|
||||
imageWidth, imageHeight, palette, left, top);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - exported functions
|
||||
|
||||
|
||||
void
|
||||
boot_splash_init(void)
|
||||
{
|
||||
TRACE("boot_splash_init: enter\n");
|
||||
|
||||
if (debug_screen_output_enabled())
|
||||
return;
|
||||
|
||||
sInfo = (frame_buffer_boot_info *)get_boot_item(FRAME_BUFFER_BOOT_INFO);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
boot_splash_set_stage(int stage)
|
||||
{
|
||||
TRACE("boot_splash_set_stage: stage=%d\n", stage);
|
||||
|
||||
if (sInfo == NULL || stage < 0 || stage >= BOOT_SPLASH_STAGE_MAX)
|
||||
return;
|
||||
|
||||
// TODO: Use placement info from images.h
|
||||
int x = sInfo->width / 2 - kSplashIconsWidth / 2;
|
||||
int y = sInfo->height / 2 - kSplashLogoHeight / 2;
|
||||
y = y + kSplashLogoHeight;
|
||||
|
||||
int stageLeftEdge = kSplashIconsWidth * stage / BOOT_SPLASH_STAGE_MAX;
|
||||
int stageRightEdge = kSplashIconsWidth * (stage + 1)
|
||||
/ BOOT_SPLASH_STAGE_MAX;
|
||||
|
||||
blit_cropped(kSplashIconsImage, NULL, stageLeftEdge, 0, stageRightEdge,
|
||||
kSplashIconsHeight / 2, kSplashIconsWidth, kSplashIconsHeight, NULL,
|
||||
x, y);
|
||||
}
|
||||
|
@ -899,6 +899,13 @@ call_modules_hook(bool enter)
|
||||
// #pragma mark - private kernel API
|
||||
|
||||
|
||||
bool
|
||||
debug_screen_output_enabled(void)
|
||||
{
|
||||
return sDebugScreenEnabled;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
debug_stop_screen_debug_output(void)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
#include <arch/platform.h>
|
||||
#include <boot_item.h>
|
||||
#include <boot_splash.h>
|
||||
#include <cbuf.h>
|
||||
#include <commpage.h>
|
||||
#include <condition_variable.h>
|
||||
@ -40,7 +41,6 @@
|
||||
#include <vfs.h>
|
||||
#include <vm.h>
|
||||
#include <boot/kernel_args.h>
|
||||
#include <boot/splash.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -222,8 +222,7 @@ main2(void *unused)
|
||||
|
||||
TRACE("start of main2: initializing devices\n");
|
||||
|
||||
TRACE("Init boot splash frame buffer\n");
|
||||
boot_splash_fb_init(&sKernelArgs);
|
||||
boot_splash_init();
|
||||
|
||||
TRACE("Init modules\n");
|
||||
boot_splash_set_stage(BOOT_SPLASH_STAGE_1_INIT_MODULES);
|
||||
|
@ -1,432 +0,0 @@
|
||||
#include <KernelExport.h>
|
||||
#include <kernel/elf32.h>
|
||||
#include <kernel.h>
|
||||
#include <lock.h>
|
||||
#include <vm.h>
|
||||
#include <fs/devfs.h>
|
||||
#include <boot/images.h>
|
||||
#include <boot/kernel_args.h>
|
||||
#include <boot/splash.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <graphics/vesa/vga.h>
|
||||
|
||||
//#define TRACE_BOOT_SPLASH 1
|
||||
#ifdef TRACE_BOOT_SPLASH
|
||||
# define TRACE(x...) dprintf(x);
|
||||
#else
|
||||
# define TRACE(x...) ;
|
||||
#endif
|
||||
|
||||
|
||||
struct boot_splash_info {
|
||||
mutex lock;
|
||||
area_id area;
|
||||
addr_t frame_buffer;
|
||||
bool enabled;
|
||||
int32 width;
|
||||
int32 height;
|
||||
int32 depth;
|
||||
int32 bytes_per_pixel;
|
||||
int32 bytes_per_row;
|
||||
};
|
||||
|
||||
static struct boot_splash_info sBootSplash;
|
||||
|
||||
/*
|
||||
static void
|
||||
boot_splash_fb_vga_set_palette(const uint8 *palette, int32 firstIndex,
|
||||
int32 numEntries)
|
||||
{
|
||||
out8(firstIndex, VGA_COLOR_WRITE_MODE);
|
||||
// write VGA palette
|
||||
for (int32 i = firstIndex; i < numEntries; i++) {
|
||||
// VGA (usually) has only 6 bits per gun
|
||||
out8(palette[i * 3 + 0] >> 2, VGA_COLOR_DATA);
|
||||
out8(palette[i * 3 + 1] >> 2, VGA_COLOR_DATA);
|
||||
out8(palette[i * 3 + 2] >> 2, VGA_COLOR_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
boot_splash_fb_blit4(const uint8 *data, uint16 width,
|
||||
uint16 height, const uint8 *palette, uint16 left, uint16 top)
|
||||
{
|
||||
if (!data || !palette)
|
||||
return;
|
||||
// ToDo: no blit yet in VGA mode
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
boot_splash_fb_blit8(const uint8 *data, uint16 width,
|
||||
uint16 height, const uint8 *palette, uint16 left, uint16 top)
|
||||
{
|
||||
if (!data || !palette)
|
||||
return;
|
||||
|
||||
boot_splash_fb_vga_set_palette(palette, 0, 256);
|
||||
|
||||
addr_t start = sBootSplash.frame_buffer + sBootSplash.bytes_per_row * top
|
||||
+ left;
|
||||
|
||||
for (int32 i = 0; i < height; i++) {
|
||||
memcpy((void *)(start + sBootSplash.bytes_per_row * i),
|
||||
&data[i * width], width);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
boot_splash_fb_blit15(const uint8 *data, uint16 width, uint16 height,
|
||||
uint16 left, uint16 top)
|
||||
{
|
||||
uint16* start = (uint16*)(sBootSplash.frame_buffer
|
||||
+ sBootSplash.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 += width * 3;
|
||||
start = (uint16*)((addr_t)start + sBootSplash.bytes_per_row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
boot_splash_fb_blit16(const uint8 *data, uint16 width, uint16 height,
|
||||
uint16 left, uint16 top)
|
||||
{
|
||||
uint16* start = (uint16*)(sBootSplash.frame_buffer
|
||||
+ sBootSplash.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 += width * 3;
|
||||
start = (uint16*)((addr_t)start + sBootSplash.bytes_per_row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
boot_splash_fb_blit24(const uint8 *data, uint16 width, uint16 height,
|
||||
uint16 left, uint16 top)
|
||||
{
|
||||
uint8* start = (uint8*)sBootSplash.frame_buffer
|
||||
+ sBootSplash.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[2];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[0];
|
||||
dst += 3;
|
||||
src += 3;
|
||||
}
|
||||
|
||||
data += width * 3;
|
||||
start = start + sBootSplash.bytes_per_row;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
boot_splash_fb_blit32(const uint8 *data, uint16 width, uint16 height,
|
||||
uint16 left, uint16 top)
|
||||
{
|
||||
uint32* start = (uint32*)(sBootSplash.frame_buffer
|
||||
+ sBootSplash.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 += width * 3;
|
||||
start = (uint32*)((addr_t)start + sBootSplash.bytes_per_row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
boot_splash_fb_blit(const uint8 *data, const uint8* indexedData, uint16 width,
|
||||
uint16 height, const uint8 *palette, uint16 left, uint16 top)
|
||||
{
|
||||
switch (sBootSplash.depth) {
|
||||
case 4:
|
||||
boot_splash_fb_blit4(indexedData, width, height, palette,
|
||||
left, top);
|
||||
return;
|
||||
case 8:
|
||||
boot_splash_fb_blit8(indexedData, width, height, palette,
|
||||
left, top);
|
||||
return;
|
||||
case 15:
|
||||
boot_splash_fb_blit15(data, width, height, left, top);
|
||||
return;
|
||||
case 16:
|
||||
boot_splash_fb_blit16(data, width, height, left, top);
|
||||
return;
|
||||
case 24:
|
||||
boot_splash_fb_blit24(data, width, height, left, top);
|
||||
return;
|
||||
case 32:
|
||||
boot_splash_fb_blit32(data, width, height, left, top);
|
||||
return;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static void
|
||||
boot_splash_fb_blit15_cropped(const uint8 *data, uint16 imageLeft,
|
||||
uint16 imageTop, uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
|
||||
uint16 imageHeight, const uint8 *palette, uint16 left, uint16 top)
|
||||
{
|
||||
data += (imageWidth * imageTop + imageLeft) * 3;
|
||||
uint16* start = (uint16*)(sBootSplash.frame_buffer
|
||||
+ sBootSplash.bytes_per_row * (top + imageTop)
|
||||
+ 2 * (left + imageLeft));
|
||||
|
||||
for (int32 y = imageTop; y < imageBottom; y++) {
|
||||
const uint8* src = data;
|
||||
uint16* dst = start;
|
||||
for (int32 x = imageLeft; x < imageRight; 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 + sBootSplash.bytes_per_row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
boot_splash_fb_blit16_cropped(const uint8 *data, uint16 imageLeft,
|
||||
uint16 imageTop, uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
|
||||
uint16 imageHeight, const uint8 *palette, uint16 left, uint16 top)
|
||||
{
|
||||
data += (imageWidth * imageTop + imageLeft) * 3;
|
||||
uint16* start = (uint16*)(sBootSplash.frame_buffer
|
||||
+ sBootSplash.bytes_per_row * (top + imageTop)
|
||||
+ 2 * (left + imageLeft));
|
||||
|
||||
for (int32 y = imageTop; y < imageBottom; y++) {
|
||||
const uint8* src = data;
|
||||
uint16* dst = start;
|
||||
for (int32 x = imageLeft; x < imageRight; 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 + sBootSplash.bytes_per_row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
boot_splash_fb_blit24_cropped(const uint8 *data, uint16 imageLeft,
|
||||
uint16 imageTop, uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
|
||||
uint16 imageHeight, const uint8 *palette, uint16 left, uint16 top)
|
||||
{
|
||||
data += (imageWidth * imageTop + imageLeft) * 3;
|
||||
uint8* start = (uint8*)(sBootSplash.frame_buffer
|
||||
+ sBootSplash.bytes_per_row * (top + imageTop)
|
||||
+ 3 * (left + imageLeft));
|
||||
|
||||
for (int32 y = imageTop; y < imageBottom; y++) {
|
||||
const uint8* src = data;
|
||||
uint8* dst = start;
|
||||
for (int32 x = imageLeft; x < imageRight; x++) {
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
dst += 3;
|
||||
src += 3;
|
||||
}
|
||||
|
||||
data += imageWidth * 3;
|
||||
start = (uint8*)((addr_t)start + sBootSplash.bytes_per_row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
boot_splash_fb_blit32_cropped(const uint8 *data, uint16 imageLeft,
|
||||
uint16 imageTop, uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
|
||||
uint16 imageHeight, const uint8 *palette, uint16 left, uint16 top)
|
||||
{
|
||||
data += (imageWidth * imageTop + imageLeft) * 3;
|
||||
uint32* start = (uint32*)(sBootSplash.frame_buffer
|
||||
+ sBootSplash.bytes_per_row * (top + imageTop)
|
||||
+ 4 * (left + imageLeft));
|
||||
|
||||
for (int32 y = imageTop; y < imageBottom; y++) {
|
||||
const uint8* src = data;
|
||||
uint32* dst = start;
|
||||
for (int32 x = imageLeft; x < imageRight; x++) {
|
||||
dst[0] = (src[2] << 16) | (src[1] << 8) | (src[0]);
|
||||
dst++;
|
||||
src += 3;
|
||||
}
|
||||
|
||||
data += imageWidth * 3;
|
||||
start = (uint32*)((addr_t)start + sBootSplash.bytes_per_row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
boot_splash_fb_blit_cropped(const uint8* data, const uint8* indexedData,
|
||||
uint16 imageLeft, uint16 imageTop, uint16 imageRight, uint16 imageBottom,
|
||||
uint16 imageWidth, uint16 imageHeight, const uint8 *palette,
|
||||
uint16 left, uint16 top)
|
||||
{
|
||||
switch (sBootSplash.depth) {
|
||||
case 4:
|
||||
case 8:
|
||||
return;
|
||||
case 15:
|
||||
boot_splash_fb_blit15_cropped(data, imageLeft, imageTop,
|
||||
imageRight, imageBottom, imageWidth, imageHeight, palette,
|
||||
left, top);
|
||||
return;
|
||||
case 16:
|
||||
boot_splash_fb_blit16_cropped(data, imageLeft, imageTop,
|
||||
imageRight, imageBottom, imageWidth, imageHeight, palette,
|
||||
left, top);
|
||||
return;
|
||||
case 24:
|
||||
boot_splash_fb_blit24_cropped(data, imageLeft, imageTop,
|
||||
imageRight, imageBottom, imageWidth, imageHeight, palette,
|
||||
left, top);
|
||||
return;
|
||||
case 32:
|
||||
boot_splash_fb_blit32_cropped(data, imageLeft, imageTop,
|
||||
imageRight, imageBottom, imageWidth, imageHeight, palette,
|
||||
left, top);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
boot_splash_fb_update(addr_t baseAddress, int32 width, int32 height,
|
||||
int32 depth, int32 bytesPerRow)
|
||||
{
|
||||
TRACE("boot_splash_fb_update: buffer=%p, width=%ld, height=%ld, depth=%ld, "
|
||||
"bytesPerRow=%ld\n", (void *)baseAddress, width, height, depth,
|
||||
bytesPerRow);
|
||||
|
||||
mutex_lock(&sBootSplash.lock);
|
||||
|
||||
sBootSplash.frame_buffer = baseAddress;
|
||||
sBootSplash.width = width;
|
||||
sBootSplash.height = height;
|
||||
sBootSplash.depth = depth;
|
||||
sBootSplash.bytes_per_pixel = (depth + 7) / 8;
|
||||
sBootSplash.bytes_per_row = bytesPerRow;
|
||||
|
||||
TRACE("boot_splash_fb_update: frame buffer mapped at %p\n",
|
||||
(void *)sBootSplash.frame_buffer);
|
||||
|
||||
mutex_unlock(&sBootSplash.lock);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
boot_splash_fb_available(void)
|
||||
{
|
||||
TRACE("boot_splash_fb_available: enter\n");
|
||||
return sBootSplash.frame_buffer != (addr_t)NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
boot_splash_fb_init(struct kernel_args *args)
|
||||
{
|
||||
TRACE("boot_splash_fb_init: enter\n");
|
||||
|
||||
if (!args->frame_buffer.enabled/* || sDebugScreenEnabled*/) {
|
||||
sBootSplash.enabled = false;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
sBootSplash.enabled = true;
|
||||
|
||||
void *frameBuffer;
|
||||
sBootSplash.area = map_physical_memory("vesa_fb",
|
||||
(void *)args->frame_buffer.physical_buffer.start,
|
||||
args->frame_buffer.physical_buffer.size, B_ANY_KERNEL_ADDRESS,
|
||||
B_READ_AREA | B_WRITE_AREA | B_USER_CLONEABLE_AREA, &frameBuffer);
|
||||
if (sBootSplash.area < B_OK)
|
||||
return sBootSplash.area;
|
||||
|
||||
boot_splash_fb_update((addr_t)frameBuffer, args->frame_buffer.width,
|
||||
args->frame_buffer.height, args->frame_buffer.depth,
|
||||
args->frame_buffer.bytes_per_row);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
boot_splash_set_stage(int stage)
|
||||
{
|
||||
TRACE("boot_splash_set_stage: stage=%d\n", stage);
|
||||
|
||||
if (!sBootSplash.enabled)
|
||||
return;
|
||||
|
||||
if (stage < 0 || stage >= BOOT_SPLASH_STAGE_MAX)
|
||||
return;
|
||||
|
||||
// TODO: Use placement info from images.h
|
||||
int x = sBootSplash.width / 2 - kSplashIconsWidth / 2;
|
||||
int y = sBootSplash.height / 2 - kSplashLogoHeight / 2;
|
||||
y = y + kSplashLogoHeight;
|
||||
|
||||
int stageLeftEdge = kSplashIconsWidth * stage / BOOT_SPLASH_STAGE_MAX;
|
||||
int stageRightEdge = kSplashIconsWidth * (stage + 1)
|
||||
/ BOOT_SPLASH_STAGE_MAX;
|
||||
boot_splash_fb_blit_cropped(kSplashIconsImage, NULL, stageLeftEdge, 0,
|
||||
stageRightEdge, kSplashIconsHeight / 2,
|
||||
kSplashIconsWidth, kSplashIconsHeight, NULL, x, y );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user