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