splash.c revision 1.13 1 1.13 khorben /* $NetBSD: splash.c,v 1.13 2016/04/25 22:26:50 khorben Exp $ */
2 1.1 jmcneill
3 1.1 jmcneill /*-
4 1.1 jmcneill * Copyright (c) 2006 Jared D. McNeill <jmcneill (at) invisible.ca>
5 1.1 jmcneill * All rights reserved.
6 1.1 jmcneill *
7 1.1 jmcneill * Redistribution and use in source and binary forms, with or without
8 1.1 jmcneill * modification, are permitted provided that the following conditions
9 1.1 jmcneill * are met:
10 1.1 jmcneill * 1. Redistributions of source code must retain the above copyright
11 1.1 jmcneill * notice, this list of conditions and the following disclaimer.
12 1.1 jmcneill * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 jmcneill * notice, this list of conditions and the following disclaimer in the
14 1.1 jmcneill * documentation and/or other materials provided with the distribution.
15 1.6 martin * 3. All advertising materials mentioning features or use of this software
16 1.6 martin * must display the following acknowledgement:
17 1.6 martin * This product includes software developed by the NetBSD
18 1.6 martin * Foundation, Inc. and its contributors.
19 1.6 martin * 4. Neither the name of The NetBSD Foundation nor the names of its
20 1.6 martin * contributors may be used to endorse or promote products derived
21 1.6 martin * from this software without specific prior written permission.
22 1.1 jmcneill *
23 1.1 jmcneill * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24 1.1 jmcneill * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 1.1 jmcneill * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 1.1 jmcneill * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27 1.1 jmcneill * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 1.1 jmcneill * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 1.1 jmcneill * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 1.1 jmcneill * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 1.1 jmcneill * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 1.1 jmcneill * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 1.1 jmcneill * POSSIBILITY OF SUCH DAMAGE.
34 1.1 jmcneill */
35 1.1 jmcneill
36 1.1 jmcneill #include <sys/cdefs.h>
37 1.13 khorben __KERNEL_RCSID(0, "$NetBSD: splash.c,v 1.13 2016/04/25 22:26:50 khorben Exp $");
38 1.1 jmcneill
39 1.1 jmcneill #include "opt_splash.h"
40 1.1 jmcneill
41 1.1 jmcneill /* XXX */
42 1.9 jmcneill #define NSPLASH8 1
43 1.1 jmcneill #define NSPLASH16 1
44 1.1 jmcneill #define NSPLASH32 1
45 1.1 jmcneill
46 1.1 jmcneill #include <sys/param.h>
47 1.8 ahoka #include <sys/device.h>
48 1.1 jmcneill #include <sys/systm.h>
49 1.1 jmcneill #include <sys/types.h>
50 1.1 jmcneill #include <sys/kernel.h>
51 1.1 jmcneill #include <sys/kthread.h>
52 1.1 jmcneill
53 1.1 jmcneill #include <dev/splash/splash.h>
54 1.9 jmcneill #include <dev/stbi/stbi.h>
55 1.1 jmcneill
56 1.1 jmcneill #ifdef SPLASHSCREEN
57 1.1 jmcneill
58 1.9 jmcneill static struct {
59 1.9 jmcneill const u_char *data;
60 1.9 jmcneill size_t datalen;
61 1.9 jmcneill } splash_image = { NULL, 0 };
62 1.9 jmcneill
63 1.9 jmcneill #define SPLASH_INDEX(r, g, b) \
64 1.9 jmcneill ((((r) >> 6) << 4) | (((g) >> 6) << 2) | (((b) >> 6) << 0))
65 1.9 jmcneill
66 1.9 jmcneill static uint8_t splash_palette[SPLASH_CMAP_SIZE][3] = {
67 1.9 jmcneill { 0x00, 0x00, 0x00 },
68 1.9 jmcneill { 0x00, 0x00, 0x55 },
69 1.9 jmcneill { 0x00, 0x00, 0xaa },
70 1.9 jmcneill { 0x00, 0x00, 0xff },
71 1.9 jmcneill { 0x00, 0x55, 0x00 },
72 1.9 jmcneill { 0x00, 0x55, 0x55 },
73 1.9 jmcneill { 0x00, 0x55, 0xaa },
74 1.9 jmcneill { 0x00, 0x55, 0xff },
75 1.9 jmcneill { 0x00, 0xaa, 0x00 },
76 1.9 jmcneill { 0x00, 0xaa, 0x55 },
77 1.9 jmcneill { 0x00, 0xaa, 0xaa },
78 1.9 jmcneill { 0x00, 0xaa, 0xff },
79 1.9 jmcneill { 0x00, 0xff, 0x00 },
80 1.9 jmcneill { 0x00, 0xff, 0x55 },
81 1.9 jmcneill { 0x00, 0xff, 0xaa },
82 1.9 jmcneill { 0x00, 0xff, 0xff },
83 1.9 jmcneill { 0x55, 0x00, 0x00 },
84 1.9 jmcneill { 0x55, 0x00, 0x55 },
85 1.9 jmcneill { 0x55, 0x00, 0xaa },
86 1.9 jmcneill { 0x55, 0x00, 0xff },
87 1.9 jmcneill { 0x55, 0x55, 0x00 },
88 1.9 jmcneill { 0x55, 0x55, 0x55 },
89 1.9 jmcneill { 0x55, 0x55, 0xaa },
90 1.9 jmcneill { 0x55, 0x55, 0xff },
91 1.9 jmcneill { 0x55, 0xaa, 0x00 },
92 1.9 jmcneill { 0x55, 0xaa, 0x55 },
93 1.9 jmcneill { 0x55, 0xaa, 0xaa },
94 1.9 jmcneill { 0x55, 0xaa, 0xff },
95 1.9 jmcneill { 0x55, 0xff, 0x00 },
96 1.9 jmcneill { 0x55, 0xff, 0x55 },
97 1.9 jmcneill { 0x55, 0xff, 0xaa },
98 1.9 jmcneill { 0x55, 0xff, 0xff },
99 1.9 jmcneill { 0xaa, 0x00, 0x00 },
100 1.9 jmcneill { 0xaa, 0x00, 0x55 },
101 1.9 jmcneill { 0xaa, 0x00, 0xaa },
102 1.9 jmcneill { 0xaa, 0x00, 0xff },
103 1.9 jmcneill { 0xaa, 0x55, 0x00 },
104 1.9 jmcneill { 0xaa, 0x55, 0x55 },
105 1.9 jmcneill { 0xaa, 0x55, 0xaa },
106 1.9 jmcneill { 0xaa, 0x55, 0xff },
107 1.9 jmcneill { 0xaa, 0xaa, 0x00 },
108 1.9 jmcneill { 0xaa, 0xaa, 0x55 },
109 1.9 jmcneill { 0xaa, 0xaa, 0xaa },
110 1.9 jmcneill { 0xaa, 0xaa, 0xff },
111 1.9 jmcneill { 0xaa, 0xff, 0x00 },
112 1.9 jmcneill { 0xaa, 0xff, 0x55 },
113 1.9 jmcneill { 0xaa, 0xff, 0xaa },
114 1.9 jmcneill { 0xaa, 0xff, 0xff },
115 1.9 jmcneill { 0xff, 0x00, 0x00 },
116 1.9 jmcneill { 0xff, 0x00, 0x55 },
117 1.9 jmcneill { 0xff, 0x00, 0xaa },
118 1.9 jmcneill { 0xff, 0x00, 0xff },
119 1.9 jmcneill { 0xff, 0x55, 0x00 },
120 1.9 jmcneill { 0xff, 0x55, 0x55 },
121 1.9 jmcneill { 0xff, 0x55, 0xaa },
122 1.9 jmcneill { 0xff, 0x55, 0xff },
123 1.9 jmcneill { 0xff, 0xaa, 0x00 },
124 1.9 jmcneill { 0xff, 0xaa, 0x55 },
125 1.9 jmcneill { 0xff, 0xaa, 0xaa },
126 1.9 jmcneill { 0xff, 0xaa, 0xff },
127 1.9 jmcneill { 0xff, 0xff, 0x00 },
128 1.9 jmcneill { 0xff, 0xff, 0x55 },
129 1.9 jmcneill { 0xff, 0xff, 0xaa },
130 1.9 jmcneill { 0xff, 0xff, 0xff },
131 1.9 jmcneill };
132 1.1 jmcneill
133 1.1 jmcneill #if NSPLASH8 > 0
134 1.1 jmcneill static void splash_render8(struct splash_info *, const char *, int,
135 1.1 jmcneill int, int, int, int);
136 1.1 jmcneill #endif
137 1.1 jmcneill #if NSPLASH16 > 0
138 1.1 jmcneill static void splash_render16(struct splash_info *, const char *, int,
139 1.1 jmcneill int, int, int, int);
140 1.1 jmcneill #endif
141 1.1 jmcneill #if NSPLASH32 > 0
142 1.1 jmcneill static void splash_render32(struct splash_info *, const char *, int,
143 1.1 jmcneill int, int, int, int);
144 1.1 jmcneill #endif
145 1.1 jmcneill
146 1.9 jmcneill int
147 1.9 jmcneill splash_setimage(const void *imgdata, size_t imgdatalen)
148 1.9 jmcneill {
149 1.9 jmcneill if (splash_image.data != NULL) {
150 1.9 jmcneill aprint_debug("WARNING: %s: already initialized\n", __func__);
151 1.9 jmcneill return EBUSY;
152 1.9 jmcneill }
153 1.9 jmcneill
154 1.11 jmcneill aprint_verbose("%s: splash image @ %p, %zu bytes\n",
155 1.9 jmcneill __func__, imgdata, imgdatalen);
156 1.9 jmcneill splash_image.data = imgdata;
157 1.9 jmcneill splash_image.datalen = imgdatalen;
158 1.9 jmcneill
159 1.9 jmcneill return 0;
160 1.9 jmcneill }
161 1.9 jmcneill
162 1.9 jmcneill int
163 1.9 jmcneill splash_get_cmap(int index, uint8_t *r, uint8_t *g, uint8_t *b)
164 1.9 jmcneill {
165 1.9 jmcneill if (index < SPLASH_CMAP_OFFSET ||
166 1.9 jmcneill index >= SPLASH_CMAP_OFFSET + SPLASH_CMAP_SIZE)
167 1.9 jmcneill return ERANGE;
168 1.9 jmcneill
169 1.9 jmcneill *r = splash_palette[index - SPLASH_CMAP_OFFSET][0];
170 1.9 jmcneill *g = splash_palette[index - SPLASH_CMAP_OFFSET][1];
171 1.9 jmcneill *b = splash_palette[index - SPLASH_CMAP_OFFSET][2];
172 1.9 jmcneill
173 1.9 jmcneill return 0;
174 1.9 jmcneill }
175 1.9 jmcneill
176 1.9 jmcneill int
177 1.1 jmcneill splash_render(struct splash_info *si, int flg)
178 1.1 jmcneill {
179 1.9 jmcneill char *data = NULL;
180 1.9 jmcneill int xoff, yoff, width, height, comp;
181 1.9 jmcneill int error = 0;
182 1.9 jmcneill
183 1.9 jmcneill if (splash_image.data == NULL) {
184 1.9 jmcneill aprint_error("WARNING: %s: not initialized\n", __func__);
185 1.9 jmcneill return ENXIO;
186 1.9 jmcneill }
187 1.9 jmcneill
188 1.9 jmcneill data = stbi_load_from_memory(splash_image.data,
189 1.9 jmcneill splash_image.datalen, &width, &height, &comp, STBI_rgb);
190 1.9 jmcneill if (data == NULL) {
191 1.9 jmcneill aprint_error("WARNING: couldn't load splash image: %s\n",
192 1.9 jmcneill stbi_failure_reason());
193 1.9 jmcneill return EINVAL;
194 1.9 jmcneill }
195 1.9 jmcneill aprint_debug("%s: splash loaded, width %d height %d comp %d\n",
196 1.9 jmcneill __func__, width, height, comp);
197 1.1 jmcneill
198 1.13 khorben if ((width > si->si_width) || (height > si->si_height)) {
199 1.13 khorben aprint_error(
200 1.13 khorben "WARNING: splash size (%dx%d) too big for framebuffer (%dx%d)\n",
201 1.13 khorben width, height, si->si_width, si->si_height);
202 1.13 khorben stbi_image_free(data);
203 1.13 khorben return EINVAL;
204 1.13 khorben }
205 1.13 khorben
206 1.1 jmcneill /* XXX */
207 1.1 jmcneill if (flg & SPLASH_F_CENTER) {
208 1.9 jmcneill xoff = (si->si_width - width) / 2;
209 1.9 jmcneill yoff = (si->si_height - height) / 2;
210 1.1 jmcneill } else
211 1.1 jmcneill xoff = yoff = 0;
212 1.1 jmcneill
213 1.1 jmcneill switch (si->si_depth) {
214 1.1 jmcneill #if NSPLASH8 > 0
215 1.1 jmcneill case 8:
216 1.9 jmcneill splash_render8(si, data, xoff, yoff, width, height, flg);
217 1.1 jmcneill break;
218 1.1 jmcneill #endif
219 1.1 jmcneill #if NSPLASH16 > 0
220 1.1 jmcneill case 16:
221 1.9 jmcneill splash_render16(si, data, xoff, yoff, width, height, flg);
222 1.1 jmcneill break;
223 1.1 jmcneill #endif
224 1.1 jmcneill #if NSPLASH32 > 0
225 1.1 jmcneill case 32:
226 1.9 jmcneill splash_render32(si, data, xoff, yoff, width, height, flg);
227 1.1 jmcneill break;
228 1.1 jmcneill #endif
229 1.1 jmcneill default:
230 1.1 jmcneill aprint_error("WARNING: Splash not supported at %dbpp\n",
231 1.1 jmcneill si->si_depth);
232 1.9 jmcneill error = EINVAL;
233 1.1 jmcneill }
234 1.1 jmcneill
235 1.9 jmcneill if (data)
236 1.9 jmcneill stbi_image_free(data);
237 1.9 jmcneill
238 1.9 jmcneill return error;
239 1.1 jmcneill }
240 1.1 jmcneill
241 1.1 jmcneill #if NSPLASH8 > 0
242 1.9 jmcneill
243 1.1 jmcneill static void
244 1.1 jmcneill splash_render8(struct splash_info *si, const char *data, int xoff, int yoff,
245 1.1 jmcneill int swidth, int sheight, int flg)
246 1.1 jmcneill {
247 1.9 jmcneill const char *d;
248 1.9 jmcneill u_char *fb, *p;
249 1.9 jmcneill u_char pix[3];
250 1.1 jmcneill int x, y, i;
251 1.1 jmcneill int filled;
252 1.1 jmcneill
253 1.1 jmcneill fb = si->si_bits;
254 1.9 jmcneill
255 1.1 jmcneill if (flg & SPLASH_F_FILL)
256 1.1 jmcneill filled = 0;
257 1.1 jmcneill else
258 1.1 jmcneill filled = 1;
259 1.1 jmcneill
260 1.9 jmcneill d = data;
261 1.9 jmcneill fb += xoff + yoff * si->si_stride;
262 1.9 jmcneill
263 1.1 jmcneill for (y = 0; y < sheight; y++) {
264 1.1 jmcneill for (x = 0; x < swidth; x++) {
265 1.9 jmcneill pix[0] = *d++;
266 1.9 jmcneill pix[1] = *d++;
267 1.9 jmcneill pix[2] = *d++;
268 1.1 jmcneill if (filled == 0) {
269 1.9 jmcneill p = si->si_bits;
270 1.9 jmcneill i = 0;
271 1.9 jmcneill while (i < si->si_height*si->si_stride) {
272 1.9 jmcneill p[i] = SPLASH_INDEX(
273 1.9 jmcneill pix[0], pix[1], pix[2]) +
274 1.9 jmcneill SPLASH_CMAP_OFFSET;
275 1.9 jmcneill i++;
276 1.9 jmcneill }
277 1.1 jmcneill filled = 1;
278 1.1 jmcneill }
279 1.9 jmcneill fb[x] = SPLASH_INDEX(pix[0], pix[1], pix[2]) +
280 1.9 jmcneill SPLASH_CMAP_OFFSET;
281 1.1 jmcneill }
282 1.12 martin fb += si->si_stride;
283 1.1 jmcneill }
284 1.1 jmcneill
285 1.1 jmcneill /* If we've just written to the shadow fb, copy it to the display */
286 1.1 jmcneill if (si->si_hwbits) {
287 1.1 jmcneill if (flg & SPLASH_F_FILL) {
288 1.1 jmcneill memcpy(si->si_hwbits, si->si_bits,
289 1.9 jmcneill si->si_height*si->si_width);
290 1.1 jmcneill } else {
291 1.1 jmcneill u_char *rp, *hrp;
292 1.1 jmcneill
293 1.1 jmcneill rp = si->si_bits + xoff + (yoff * si->si_width);
294 1.1 jmcneill hrp = si->si_hwbits + xoff + (yoff * si->si_width);
295 1.1 jmcneill
296 1.1 jmcneill for (y = 0; y < sheight; y++) {
297 1.1 jmcneill memcpy(hrp, rp, swidth);
298 1.9 jmcneill rp += si->si_stride;
299 1.1 jmcneill hrp += si->si_stride;
300 1.1 jmcneill }
301 1.1 jmcneill }
302 1.1 jmcneill }
303 1.1 jmcneill
304 1.1 jmcneill return;
305 1.1 jmcneill }
306 1.1 jmcneill #endif /* !NSPLASH8 > 0 */
307 1.1 jmcneill
308 1.1 jmcneill #if NSPLASH16 > 0
309 1.1 jmcneill #define RGBTO16(b, o, x, c) \
310 1.1 jmcneill do { \
311 1.1 jmcneill uint16_t *_ptr = (uint16_t *)(&(b)[(o)]); \
312 1.1 jmcneill *_ptr = (((c)[(x)*3+0] / 8) << 11) | \
313 1.1 jmcneill (((c)[(x)*3+1] / 4) << 5) | \
314 1.1 jmcneill (((c)[(x)*3+2] / 8) << 0); \
315 1.1 jmcneill } while (0)
316 1.1 jmcneill
317 1.1 jmcneill static void
318 1.1 jmcneill splash_render16(struct splash_info *si, const char *data, int xoff, int yoff,
319 1.1 jmcneill int swidth, int sheight, int flg)
320 1.1 jmcneill {
321 1.1 jmcneill const char *d;
322 1.1 jmcneill u_char *fb, *p;
323 1.1 jmcneill u_char pix[3];
324 1.1 jmcneill int x, y, i;
325 1.1 jmcneill int filled;
326 1.1 jmcneill
327 1.1 jmcneill fb = si->si_bits;
328 1.1 jmcneill
329 1.1 jmcneill if (flg & SPLASH_F_FILL)
330 1.1 jmcneill filled = 0;
331 1.1 jmcneill else
332 1.1 jmcneill filled = 1;
333 1.1 jmcneill
334 1.1 jmcneill d = data;
335 1.1 jmcneill fb += xoff * 2 + yoff * si->si_stride;
336 1.1 jmcneill
337 1.1 jmcneill for (y = 0; y < sheight; y++) {
338 1.1 jmcneill for (x = 0; x < swidth; x++) {
339 1.9 jmcneill pix[0] = *d++;
340 1.9 jmcneill pix[1] = *d++;
341 1.9 jmcneill pix[2] = *d++;
342 1.1 jmcneill if (filled == 0) {
343 1.1 jmcneill p = si->si_bits;
344 1.1 jmcneill i = 0;
345 1.1 jmcneill while (i < si->si_height*si->si_stride) {
346 1.1 jmcneill RGBTO16(p, i, 0, pix);
347 1.1 jmcneill i += 2;
348 1.1 jmcneill }
349 1.1 jmcneill filled = 1;
350 1.1 jmcneill }
351 1.1 jmcneill RGBTO16(fb, x*2, 0, pix);
352 1.1 jmcneill }
353 1.1 jmcneill fb += si->si_stride;
354 1.1 jmcneill }
355 1.1 jmcneill
356 1.1 jmcneill /* If we've just written to the shadow fb, copy it to the display */
357 1.1 jmcneill if (si->si_hwbits) {
358 1.1 jmcneill if (flg & SPLASH_F_FILL) {
359 1.1 jmcneill memcpy(si->si_hwbits, si->si_bits,
360 1.1 jmcneill si->si_height*si->si_stride);
361 1.1 jmcneill } else {
362 1.1 jmcneill u_char *rp, *hrp;
363 1.1 jmcneill
364 1.1 jmcneill rp = si->si_bits + (xoff * 2) + (yoff * si->si_stride);
365 1.1 jmcneill hrp = si->si_hwbits + (xoff * 2) +
366 1.1 jmcneill (yoff * si->si_stride);
367 1.1 jmcneill
368 1.1 jmcneill for (y = 0; y < sheight; y++) {
369 1.1 jmcneill memcpy(hrp, rp, swidth * 2);
370 1.1 jmcneill rp += si->si_stride;
371 1.1 jmcneill hrp += si->si_stride;
372 1.1 jmcneill }
373 1.1 jmcneill }
374 1.1 jmcneill }
375 1.1 jmcneill
376 1.1 jmcneill return;
377 1.1 jmcneill }
378 1.1 jmcneill #undef RGBTO16
379 1.1 jmcneill #endif /* !NSPLASH16 > 0 */
380 1.1 jmcneill
381 1.1 jmcneill #if NSPLASH32 > 0
382 1.1 jmcneill static void
383 1.1 jmcneill splash_render32(struct splash_info *si, const char *data, int xoff, int yoff,
384 1.1 jmcneill int swidth, int sheight, int flg)
385 1.1 jmcneill {
386 1.1 jmcneill const char *d;
387 1.1 jmcneill u_char *fb, *p;
388 1.1 jmcneill u_char pix[3];
389 1.1 jmcneill int x, y, i;
390 1.1 jmcneill int filled;
391 1.1 jmcneill
392 1.1 jmcneill fb = si->si_bits;
393 1.1 jmcneill
394 1.1 jmcneill if (flg & SPLASH_F_FILL)
395 1.1 jmcneill filled = 0;
396 1.1 jmcneill else
397 1.1 jmcneill filled = 1;
398 1.1 jmcneill
399 1.1 jmcneill d = data;
400 1.1 jmcneill fb += xoff * 4 + yoff * si->si_stride;
401 1.1 jmcneill
402 1.1 jmcneill for (y = 0; y < sheight; y++) {
403 1.1 jmcneill for (x = 0; x < swidth; x++) {
404 1.9 jmcneill pix[0] = *d++;
405 1.9 jmcneill pix[1] = *d++;
406 1.9 jmcneill pix[2] = *d++;
407 1.1 jmcneill if (filled == 0) {
408 1.1 jmcneill p = si->si_bits;
409 1.1 jmcneill i = 0;
410 1.1 jmcneill while (i < si->si_height*si->si_stride) {
411 1.1 jmcneill p[i++] = pix[2];
412 1.1 jmcneill p[i++] = pix[1];
413 1.1 jmcneill p[i++] = pix[0];
414 1.1 jmcneill p[i++] = 0;
415 1.1 jmcneill }
416 1.1 jmcneill filled = 1;
417 1.1 jmcneill }
418 1.1 jmcneill fb[x*4+0] = pix[2];
419 1.1 jmcneill fb[x*4+1] = pix[1];
420 1.1 jmcneill fb[x*4+2] = pix[0];
421 1.1 jmcneill fb[x*4+3] = 0;
422 1.1 jmcneill }
423 1.1 jmcneill fb += si->si_stride;
424 1.1 jmcneill }
425 1.1 jmcneill
426 1.1 jmcneill /* If we've just written to the shadow fb, copy it to the display */
427 1.1 jmcneill if (si->si_hwbits) {
428 1.1 jmcneill if (flg & SPLASH_F_FILL) {
429 1.1 jmcneill memcpy(si->si_hwbits, si->si_bits,
430 1.1 jmcneill si->si_height*si->si_stride);
431 1.1 jmcneill } else {
432 1.1 jmcneill u_char *rp, *hrp;
433 1.1 jmcneill
434 1.1 jmcneill rp = si->si_bits + (xoff * 4) + (yoff * si->si_stride);
435 1.1 jmcneill hrp = si->si_hwbits + (xoff * 4) +
436 1.1 jmcneill (yoff * si->si_stride);
437 1.1 jmcneill
438 1.1 jmcneill for (y = 0; y < sheight; y++) {
439 1.1 jmcneill memcpy(hrp, rp, swidth * 4);
440 1.1 jmcneill rp += si->si_stride;
441 1.1 jmcneill hrp += si->si_stride;
442 1.1 jmcneill }
443 1.1 jmcneill }
444 1.1 jmcneill }
445 1.1 jmcneill
446 1.1 jmcneill return;
447 1.1 jmcneill }
448 1.1 jmcneill #endif /* !NSPLASH32 > 0 */
449 1.1 jmcneill
450 1.1 jmcneill #endif /* !SPLASHSCREEN */
451