bootloader & kernel: Unify bitmap blitting routines.

They were more-or-less duplicated between the two.
This commit is contained in:
Augustin Cavalier 2024-10-15 16:01:44 -04:00
parent 6a290d1dd1
commit 029e447bde
5 changed files with 218 additions and 344 deletions

View File

@ -0,0 +1,178 @@
/*
* Copyright 2008, Stephan Aßmus <superstippi@gmx.de>
* Copyright 2008, Philippe Saint-Pierre <stpere@gmail.com>
* Copyright 2004-2009, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2024, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef GENERIC_BLITTER_H
#define GENERIC_BLITTER_H
#include <SupportDefs.h>
struct BlitParameters {
const uint8* from;
uint32 fromWidth;
uint16 fromLeft, fromTop;
uint16 fromRight, fromBottom;
uint8* to;
uint32 toBytesPerRow;
uint16 toLeft, toTop;
};
static void
blit8(const BlitParameters& params)
{
const uint8* data = params.from;
data += (params.fromWidth * params.fromTop + params.fromLeft);
uint8* start = (uint8*)(params.to
+ params.toBytesPerRow * params.toTop
+ 1 * params.toLeft);
for (int32 y = params.fromTop; y < params.fromBottom; y++) {
const uint8* src = data;
uint8* dst = start;
for (int32 x = params.fromLeft; x < params.fromRight; x++) {
dst[0] = src[0];
dst++;
src++;
}
data += params.fromWidth;
start = (uint8*)((addr_t)start + params.toBytesPerRow);
}
}
static void
blit15(const BlitParameters& params)
{
const uint8* data = params.from;
data += (params.fromWidth * params.fromTop + params.fromLeft) * 3;
uint16* start = (uint16*)(params.to
+ params.toBytesPerRow * params.toTop
+ 2 * params.toLeft);
for (int32 y = params.fromTop; y < params.fromBottom; y++) {
const uint8* src = data;
uint16* dst = start;
for (int32 x = params.fromLeft; x < params.fromRight; x++) {
dst[0] = ((src[2] >> 3) << 10)
| ((src[1] >> 3) << 5)
| ((src[0] >> 3));
dst++;
src += 3;
}
data += params.fromWidth * 3;
start = (uint16*)((addr_t)start + params.toBytesPerRow);
}
}
static void
blit16(const BlitParameters& params)
{
const uint8* data = params.from;
data += (params.fromWidth * params.fromTop + params.fromLeft) * 3;
uint16* start = (uint16*)(params.to
+ params.toBytesPerRow * params.toTop
+ 2 * params.toLeft);
for (int32 y = params.fromTop; y < params.fromBottom; y++) {
const uint8* src = data;
uint16* dst = start;
for (int32 x = params.fromLeft; x < params.fromRight; x++) {
dst[0] = ((src[2] >> 3) << 11)
| ((src[1] >> 2) << 5)
| ((src[0] >> 3));
dst++;
src += 3;
}
data += params.fromWidth * 3;
start = (uint16*)((addr_t)start + params.toBytesPerRow);
}
}
static void
blit24(const BlitParameters& params)
{
const uint8* data = params.from;
data += (params.fromWidth * params.fromTop + params.fromLeft) * 3;
uint8* start = (uint8*)(params.to
+ params.toBytesPerRow * params.toTop
+ 3 * params.toLeft);
for (int32 y = params.fromTop; y < params.fromBottom; y++) {
const uint8* src = data;
uint8* dst = start;
for (int32 x = params.fromLeft; x < params.fromRight; x++) {
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst += 3;
src += 3;
}
data += params.fromWidth * 3;
start = (uint8*)((addr_t)start + params.toBytesPerRow);
}
}
static void
blit32(const BlitParameters& params)
{
const uint8* data = params.from;
data += (params.fromWidth * params.fromTop + params.fromLeft) * 3;
uint32* start = (uint32*)(params.to
+ params.toBytesPerRow * params.toTop
+ 4 * params.toLeft);
for (int32 y = params.fromTop; y < params.fromBottom; y++) {
const uint8* src = data;
uint32* dst = start;
for (int32 x = params.fromLeft; x < params.fromRight; x++) {
dst[0] = (src[2] << 16) | (src[1] << 8) | (src[0]);
dst++;
src += 3;
}
data += params.fromWidth * 3;
start = (uint32*)((addr_t)start + params.toBytesPerRow);
}
}
static void
blit(const BlitParameters& params, int32 depth)
{
switch (depth) {
case 8:
blit8(params);
return;
case 15:
blit15(params);
return;
case 16:
blit16(params);
return;
case 24:
blit24(params);
return;
case 32:
blit32(params);
return;
}
}
#endif /* GENERIC_BLITTER_H */

View File

@ -11,7 +11,6 @@ for platform in [ MultiBootSubDirSetup ] {
BootStaticLibrary boot_platform_generic_$(platform:G=) :
text_console.cpp
text_menu.cpp
video_blit.cpp
video_splash.cpp
;
Includes [ FGristFiles video_splash.cpp ]

View File

@ -1,179 +0,0 @@
/*
* 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 <arch/cpu.h>
#include <boot/stage2.h>
#include <boot/platform.h>
#include <boot/platform/generic/video.h>
#include <boot/kernel_args.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
static void
blit32(addr_t frameBuffer, const uint8 *data, uint16 width,
uint16 height, uint16 imageWidth, uint16 left, uint16 top)
{
uint32 *start = (uint32 *)(frameBuffer
+ 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(addr_t frameBuffer, const uint8 *data, uint16 width,
uint16 height, uint16 imageWidth, uint16 left, uint16 top)
{
uint8 *start = (uint8 *)frameBuffer
+ 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(addr_t frameBuffer, const uint8 *data, uint16 width,
uint16 height, uint16 imageWidth, uint16 left, uint16 top)
{
uint16 *start = (uint16 *)(frameBuffer
+ 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(addr_t frameBuffer, const uint8 *data, uint16 width,
uint16 height, uint16 imageWidth, uint16 left, uint16 top)
{
uint16 *start = (uint16 *)(frameBuffer
+ 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(addr_t frameBuffer, const uint8 *data, uint16 width,
uint16 height, uint16 imageWidth, uint16 left, uint16 top)
{
if (!data)
return;
addr_t start = frameBuffer + 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(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, data, width, height,
imageWidth, left, top);
}
void
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, data,
width, height, imageWidth, left, top);
case 8:
return blit8(frameBuffer, data,
width, height, imageWidth, left, top);
case 15:
return blit15(frameBuffer, data,
width, height, imageWidth, left, top);
case 16:
return blit16(frameBuffer, data,
width, height, imageWidth, left, top);
case 24:
return blit24(frameBuffer, data,
width, height, imageWidth, left, top);
case 32:
return blit32(frameBuffer, data,
width, height, imageWidth, left, top);
}
}

View File

@ -12,6 +12,7 @@
#include <boot/menu.h>
#include <boot/kernel_args.h>
#include <boot/platform/generic/video.h>
#include <boot/platform/generic/video_blitter.h>
#include <boot/images.h>
#include <stdio.h>
@ -79,6 +80,30 @@ uncompress(const uint8 compressed[], unsigned int compressedSize,
}
extern "C" void
video_blit_image(addr_t frameBuffer, const uint8 *data,
uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top)
{
if (gKernelArgs.frame_buffer.depth == 4) {
// call platform specific code since it's really platform-specific.
platform_blit4(frameBuffer, data, width, height,
imageWidth, left, top);
} else {
BlitParameters params;
params.from = data;
params.fromWidth = imageWidth;
params.fromLeft = params.fromTop = 0;
params.fromRight = width;
params.fromBottom = height;
params.to = (uint8*)frameBuffer;
params.toBytesPerRow = gKernelArgs.frame_buffer.bytes_per_row;
params.toLeft = left;
params.toTop = top;
blit(params, gKernelArgs.frame_buffer.depth);
}
}
extern "C" status_t
video_display_splash(addr_t frameBuffer)
{
@ -203,6 +228,3 @@ video_display_splash(addr_t frameBuffer)
kSplashIconsWidth, x, y);
return B_OK;
}

View File

@ -16,6 +16,7 @@
#define __BOOTSPLASH_KERNEL__
#include <boot/images.h>
#include <boot/platform/generic/video_blitter.h>
#include <boot_item.h>
#include <debug.h>
@ -36,165 +37,6 @@ static struct frame_buffer_boot_info *sInfo;
static uint8 *sUncompressedIcons;
static void
blit8_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop,
uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
uint16 left, uint16 top)
{
data += (imageWidth * imageTop + imageLeft);
uint8* start = (uint8*)(sInfo->frame_buffer
+ sInfo->bytes_per_row * (top + imageTop) + 1 * (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++;
src++;
}
data += imageWidth;
start = (uint8*)((addr_t)start + sInfo->bytes_per_row);
}
}
static void
blit15_cropped(const uint8 *data, uint16 imageLeft, uint16 imageTop,
uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
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 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 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 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, uint16 imageLeft, uint16 imageTop,
uint16 imageRight, uint16 imageBottom, uint16 imageWidth,
uint16 left, uint16 top)
{
switch (sInfo->depth) {
case 8:
blit8_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
imageWidth, left, top);
return;
case 15:
blit15_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
imageWidth, left, top);
return;
case 16:
blit16_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
imageWidth, left, top);
return;
case 24:
blit24_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
imageWidth, left, top);
return;
case 32:
blit32_cropped(data, imageLeft, imageTop, imageRight, imageBottom,
imageWidth, left, top);
return;
}
}
// #pragma mark - exported functions
@ -241,7 +83,19 @@ boot_splash_set_stage(int stage)
int stageRightEdge = width * (stage + 1) / BOOT_SPLASH_STAGE_MAX;
height = min_c(iconsHalfHeight, sInfo->height);
blit_cropped(sUncompressedIcons, stageLeftEdge, 0, stageRightEdge,
height, kSplashIconsWidth, x, y);
BlitParameters params;
params.from = sUncompressedIcons;
params.fromWidth = kSplashIconsWidth;
params.fromLeft = stageLeftEdge;
params.fromTop = 0;
params.fromRight = stageRightEdge;
params.fromBottom = height;
params.to = (uint8*)sInfo->frame_buffer;
params.toBytesPerRow = sInfo->bytes_per_row;
params.toLeft = stageLeftEdge + x;
params.toTop = y;
blit(params, sInfo->depth);
}