On Apple ARM platforms, iBoot sets up a 30-bit framebuffer Change-Id: I6c03937303a3363fde511c8b8b7f8fd66a6a6965 Reviewed-on: https://review.haiku-os.org/c/haiku/+/11128 Tested-by: Commit checker robot <[email protected]> Reviewed-by: waddlesplash <[email protected]>
208 lines
4.5 KiB
C
208 lines
4.5 KiB
C
/*
|
|
* Copyright 2008, Stephan Aßmus <[email protected]>
|
|
* Copyright 2008, Philippe Saint-Pierre <[email protected]>
|
|
* Copyright 2004-2009, Axel Dörfler, [email protected].
|
|
* 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
|
|
blit30(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] * 1023) / 255) << 20)
|
|
| (((src[1] * 1023) / 255) << 10)
|
|
| ((src[0] * 1023) / 255);
|
|
dst++;
|
|
src += 3;
|
|
}
|
|
|
|
data += params.fromWidth * 3;
|
|
start = (uint32*)((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 30:
|
|
blit30(params);
|
|
return;
|
|
case 32:
|
|
blit32(params);
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
#endif /* GENERIC_BLITTER_H */
|