xref: /haiku/headers/private/kernel/boot/platform/generic/video_blitter.h (revision 029e447bde2eea56ce1426d7d2965000538211be)
1*029e447bSAugustin Cavalier /*
2*029e447bSAugustin Cavalier  * Copyright 2008, Stephan Aßmus <superstippi@gmx.de>
3*029e447bSAugustin Cavalier  * Copyright 2008, Philippe Saint-Pierre <stpere@gmail.com>
4*029e447bSAugustin Cavalier  * Copyright 2004-2009, Axel Dörfler, axeld@pinc-software.de.
5*029e447bSAugustin Cavalier  * Copyright 2024, Haiku, Inc. All rights reserved.
6*029e447bSAugustin Cavalier  * Distributed under the terms of the MIT License.
7*029e447bSAugustin Cavalier  */
8*029e447bSAugustin Cavalier #ifndef GENERIC_BLITTER_H
9*029e447bSAugustin Cavalier #define GENERIC_BLITTER_H
10*029e447bSAugustin Cavalier 
11*029e447bSAugustin Cavalier 
12*029e447bSAugustin Cavalier #include <SupportDefs.h>
13*029e447bSAugustin Cavalier 
14*029e447bSAugustin Cavalier 
15*029e447bSAugustin Cavalier struct BlitParameters {
16*029e447bSAugustin Cavalier 	const uint8* from;
17*029e447bSAugustin Cavalier 	uint32 fromWidth;
18*029e447bSAugustin Cavalier 	uint16 fromLeft, fromTop;
19*029e447bSAugustin Cavalier 	uint16 fromRight, fromBottom;
20*029e447bSAugustin Cavalier 
21*029e447bSAugustin Cavalier 	uint8* to;
22*029e447bSAugustin Cavalier 	uint32 toBytesPerRow;
23*029e447bSAugustin Cavalier 	uint16 toLeft, toTop;
24*029e447bSAugustin Cavalier };
25*029e447bSAugustin Cavalier 
26*029e447bSAugustin Cavalier 
27*029e447bSAugustin Cavalier static void
blit8(const BlitParameters & params)28*029e447bSAugustin Cavalier blit8(const BlitParameters& params)
29*029e447bSAugustin Cavalier {
30*029e447bSAugustin Cavalier 	const uint8* data = params.from;
31*029e447bSAugustin Cavalier 	data += (params.fromWidth * params.fromTop + params.fromLeft);
32*029e447bSAugustin Cavalier 	uint8* start = (uint8*)(params.to
33*029e447bSAugustin Cavalier 		+ params.toBytesPerRow * params.toTop
34*029e447bSAugustin Cavalier 		+ 1 * params.toLeft);
35*029e447bSAugustin Cavalier 
36*029e447bSAugustin Cavalier 	for (int32 y = params.fromTop; y < params.fromBottom; y++) {
37*029e447bSAugustin Cavalier 		const uint8* src = data;
38*029e447bSAugustin Cavalier 		uint8* dst = start;
39*029e447bSAugustin Cavalier 		for (int32 x = params.fromLeft; x < params.fromRight; x++) {
40*029e447bSAugustin Cavalier 			dst[0] = src[0];
41*029e447bSAugustin Cavalier 			dst++;
42*029e447bSAugustin Cavalier 			src++;
43*029e447bSAugustin Cavalier 		}
44*029e447bSAugustin Cavalier 
45*029e447bSAugustin Cavalier 		data += params.fromWidth;
46*029e447bSAugustin Cavalier 		start = (uint8*)((addr_t)start + params.toBytesPerRow);
47*029e447bSAugustin Cavalier 	}
48*029e447bSAugustin Cavalier }
49*029e447bSAugustin Cavalier 
50*029e447bSAugustin Cavalier 
51*029e447bSAugustin Cavalier static void
blit15(const BlitParameters & params)52*029e447bSAugustin Cavalier blit15(const BlitParameters& params)
53*029e447bSAugustin Cavalier {
54*029e447bSAugustin Cavalier 	const uint8* data = params.from;
55*029e447bSAugustin Cavalier 	data += (params.fromWidth * params.fromTop + params.fromLeft) * 3;
56*029e447bSAugustin Cavalier 	uint16* start = (uint16*)(params.to
57*029e447bSAugustin Cavalier 		+ params.toBytesPerRow * params.toTop
58*029e447bSAugustin Cavalier 		+ 2 * params.toLeft);
59*029e447bSAugustin Cavalier 
60*029e447bSAugustin Cavalier 	for (int32 y = params.fromTop; y < params.fromBottom; y++) {
61*029e447bSAugustin Cavalier 		const uint8* src = data;
62*029e447bSAugustin Cavalier 		uint16* dst = start;
63*029e447bSAugustin Cavalier 		for (int32 x = params.fromLeft; x < params.fromRight; x++) {
64*029e447bSAugustin Cavalier 			dst[0] = ((src[2] >> 3) << 10)
65*029e447bSAugustin Cavalier 				| ((src[1] >> 3) << 5)
66*029e447bSAugustin Cavalier 				| ((src[0] >> 3));
67*029e447bSAugustin Cavalier 
68*029e447bSAugustin Cavalier 			dst++;
69*029e447bSAugustin Cavalier 			src += 3;
70*029e447bSAugustin Cavalier 		}
71*029e447bSAugustin Cavalier 
72*029e447bSAugustin Cavalier 		data += params.fromWidth * 3;
73*029e447bSAugustin Cavalier 		start = (uint16*)((addr_t)start + params.toBytesPerRow);
74*029e447bSAugustin Cavalier 	}
75*029e447bSAugustin Cavalier }
76*029e447bSAugustin Cavalier 
77*029e447bSAugustin Cavalier 
78*029e447bSAugustin Cavalier static void
blit16(const BlitParameters & params)79*029e447bSAugustin Cavalier blit16(const BlitParameters& params)
80*029e447bSAugustin Cavalier {
81*029e447bSAugustin Cavalier 	const uint8* data = params.from;
82*029e447bSAugustin Cavalier 	data += (params.fromWidth * params.fromTop + params.fromLeft) * 3;
83*029e447bSAugustin Cavalier 	uint16* start = (uint16*)(params.to
84*029e447bSAugustin Cavalier 		+ params.toBytesPerRow * params.toTop
85*029e447bSAugustin Cavalier 		+ 2 * params.toLeft);
86*029e447bSAugustin Cavalier 
87*029e447bSAugustin Cavalier 	for (int32 y = params.fromTop; y < params.fromBottom; y++) {
88*029e447bSAugustin Cavalier 		const uint8* src = data;
89*029e447bSAugustin Cavalier 		uint16* dst = start;
90*029e447bSAugustin Cavalier 		for (int32 x = params.fromLeft; x < params.fromRight; x++) {
91*029e447bSAugustin Cavalier 			dst[0] = ((src[2] >> 3) << 11)
92*029e447bSAugustin Cavalier 				| ((src[1] >> 2) << 5)
93*029e447bSAugustin Cavalier 				| ((src[0] >> 3));
94*029e447bSAugustin Cavalier 
95*029e447bSAugustin Cavalier 			dst++;
96*029e447bSAugustin Cavalier 			src += 3;
97*029e447bSAugustin Cavalier 		}
98*029e447bSAugustin Cavalier 
99*029e447bSAugustin Cavalier 		data += params.fromWidth * 3;
100*029e447bSAugustin Cavalier 		start = (uint16*)((addr_t)start + params.toBytesPerRow);
101*029e447bSAugustin Cavalier 	}
102*029e447bSAugustin Cavalier }
103*029e447bSAugustin Cavalier 
104*029e447bSAugustin Cavalier 
105*029e447bSAugustin Cavalier static void
blit24(const BlitParameters & params)106*029e447bSAugustin Cavalier blit24(const BlitParameters& params)
107*029e447bSAugustin Cavalier {
108*029e447bSAugustin Cavalier 	const uint8* data = params.from;
109*029e447bSAugustin Cavalier 	data += (params.fromWidth * params.fromTop + params.fromLeft) * 3;
110*029e447bSAugustin Cavalier 	uint8* start = (uint8*)(params.to
111*029e447bSAugustin Cavalier 		+ params.toBytesPerRow * params.toTop
112*029e447bSAugustin Cavalier 		+ 3 * params.toLeft);
113*029e447bSAugustin Cavalier 
114*029e447bSAugustin Cavalier 	for (int32 y = params.fromTop; y < params.fromBottom; y++) {
115*029e447bSAugustin Cavalier 		const uint8* src = data;
116*029e447bSAugustin Cavalier 		uint8* dst = start;
117*029e447bSAugustin Cavalier 		for (int32 x = params.fromLeft; x < params.fromRight; x++) {
118*029e447bSAugustin Cavalier 			dst[0] = src[0];
119*029e447bSAugustin Cavalier 			dst[1] = src[1];
120*029e447bSAugustin Cavalier 			dst[2] = src[2];
121*029e447bSAugustin Cavalier 			dst += 3;
122*029e447bSAugustin Cavalier 			src += 3;
123*029e447bSAugustin Cavalier 		}
124*029e447bSAugustin Cavalier 
125*029e447bSAugustin Cavalier 		data += params.fromWidth * 3;
126*029e447bSAugustin Cavalier 		start = (uint8*)((addr_t)start + params.toBytesPerRow);
127*029e447bSAugustin Cavalier 	}
128*029e447bSAugustin Cavalier }
129*029e447bSAugustin Cavalier 
130*029e447bSAugustin Cavalier 
131*029e447bSAugustin Cavalier static void
blit32(const BlitParameters & params)132*029e447bSAugustin Cavalier blit32(const BlitParameters& params)
133*029e447bSAugustin Cavalier {
134*029e447bSAugustin Cavalier 	const uint8* data = params.from;
135*029e447bSAugustin Cavalier 	data += (params.fromWidth * params.fromTop + params.fromLeft) * 3;
136*029e447bSAugustin Cavalier 	uint32* start = (uint32*)(params.to
137*029e447bSAugustin Cavalier 		+ params.toBytesPerRow * params.toTop
138*029e447bSAugustin Cavalier 		+ 4 * params.toLeft);
139*029e447bSAugustin Cavalier 
140*029e447bSAugustin Cavalier 	for (int32 y = params.fromTop; y < params.fromBottom; y++) {
141*029e447bSAugustin Cavalier 		const uint8* src = data;
142*029e447bSAugustin Cavalier 		uint32* dst = start;
143*029e447bSAugustin Cavalier 		for (int32 x = params.fromLeft; x < params.fromRight; x++) {
144*029e447bSAugustin Cavalier 			dst[0] = (src[2] << 16) | (src[1] << 8) | (src[0]);
145*029e447bSAugustin Cavalier 			dst++;
146*029e447bSAugustin Cavalier 			src += 3;
147*029e447bSAugustin Cavalier 		}
148*029e447bSAugustin Cavalier 
149*029e447bSAugustin Cavalier 		data += params.fromWidth * 3;
150*029e447bSAugustin Cavalier 		start = (uint32*)((addr_t)start + params.toBytesPerRow);
151*029e447bSAugustin Cavalier 	}
152*029e447bSAugustin Cavalier }
153*029e447bSAugustin Cavalier 
154*029e447bSAugustin Cavalier 
155*029e447bSAugustin Cavalier static void
blit(const BlitParameters & params,int32 depth)156*029e447bSAugustin Cavalier blit(const BlitParameters& params, int32 depth)
157*029e447bSAugustin Cavalier {
158*029e447bSAugustin Cavalier 	switch (depth) {
159*029e447bSAugustin Cavalier 		case 8:
160*029e447bSAugustin Cavalier 			blit8(params);
161*029e447bSAugustin Cavalier 			return;
162*029e447bSAugustin Cavalier 		case 15:
163*029e447bSAugustin Cavalier 			blit15(params);
164*029e447bSAugustin Cavalier 			return;
165*029e447bSAugustin Cavalier 		case 16:
166*029e447bSAugustin Cavalier 			blit16(params);
167*029e447bSAugustin Cavalier 			return;
168*029e447bSAugustin Cavalier 		case 24:
169*029e447bSAugustin Cavalier 			blit24(params);
170*029e447bSAugustin Cavalier 			return;
171*029e447bSAugustin Cavalier 		case 32:
172*029e447bSAugustin Cavalier 			blit32(params);
173*029e447bSAugustin Cavalier 			return;
174*029e447bSAugustin Cavalier 	}
175*029e447bSAugustin Cavalier }
176*029e447bSAugustin Cavalier 
177*029e447bSAugustin Cavalier 
178*029e447bSAugustin Cavalier #endif	/* GENERIC_BLITTER_H */
179