Mercurial > sdl-ios-xcode
comparison src/video/SDL_blit_A.c @ 1:cf2af46e9e2a
Changes since SDL 1.2.0 release
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Thu, 26 Apr 2001 16:50:19 +0000 |
parents | 74212992fb08 |
children | e8157fcb3114 |
comparison
equal
deleted
inserted
replaced
0:74212992fb08 | 1:cf2af46e9e2a |
---|---|
193 src += srcskip; | 193 src += srcskip; |
194 dst += dstskip; | 194 dst += dstskip; |
195 } | 195 } |
196 } | 196 } |
197 | 197 |
198 /* fast RGB888->(A)RGB888 blending with surface alpha */ | 198 /* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ |
199 static void BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo *info) | 199 static void BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo *info) |
200 { | 200 { |
201 int width = info->d_width; | 201 int width = info->d_width; |
202 int height = info->d_height; | 202 int height = info->d_height; |
203 Uint32 *srcp = (Uint32 *)info->s_pixels; | 203 Uint32 *srcp = (Uint32 *)info->s_pixels; |
204 int srcskip = info->s_skip >> 2; | 204 int srcskip = info->s_skip >> 2; |
205 Uint32 *dstp = (Uint32 *)info->d_pixels; | 205 Uint32 *dstp = (Uint32 *)info->d_pixels; |
206 int dstskip = info->d_skip >> 2; | 206 int dstskip = info->d_skip >> 2; |
207 SDL_PixelFormat *srcfmt = info->src; | |
208 unsigned alpha = srcfmt->alpha; | |
209 | 207 |
210 while(height--) { | 208 while(height--) { |
211 DUFFS_LOOP4({ | 209 DUFFS_LOOP4({ |
212 Uint32 s; | 210 Uint32 s = *srcp++; |
213 Uint32 d; | 211 Uint32 d = *dstp; |
214 Uint32 s1; | 212 *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) |
215 Uint32 d1; | 213 + (s & d & 0x00010101)) | 0xff000000; |
216 s = *srcp; | |
217 d = *dstp; | |
218 s1 = s & 0xff00ff; | |
219 d1 = d & 0xff00ff; | |
220 d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; | |
221 s &= 0xff00; | |
222 d &= 0xff00; | |
223 d = (d + ((s - d) * alpha >> 8)) & 0xff00; | |
224 *dstp = d1 | d | 0xff000000; | |
225 ++srcp; | |
226 ++dstp; | |
227 }, width); | 214 }, width); |
228 srcp += srcskip; | 215 srcp += srcskip; |
229 dstp += dstskip; | 216 dstp += dstskip; |
217 } | |
218 } | |
219 | |
220 /* fast RGB888->(A)RGB888 blending with surface alpha */ | |
221 static void BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo *info) | |
222 { | |
223 unsigned alpha = info->src->alpha; | |
224 if(alpha == 128) { | |
225 BlitRGBtoRGBSurfaceAlpha128(info); | |
226 } else { | |
227 int width = info->d_width; | |
228 int height = info->d_height; | |
229 Uint32 *srcp = (Uint32 *)info->s_pixels; | |
230 int srcskip = info->s_skip >> 2; | |
231 Uint32 *dstp = (Uint32 *)info->d_pixels; | |
232 int dstskip = info->d_skip >> 2; | |
233 | |
234 while(height--) { | |
235 DUFFS_LOOP4({ | |
236 Uint32 s; | |
237 Uint32 d; | |
238 Uint32 s1; | |
239 Uint32 d1; | |
240 s = *srcp; | |
241 d = *dstp; | |
242 s1 = s & 0xff00ff; | |
243 d1 = d & 0xff00ff; | |
244 d1 = (d1 + ((s1 - d1) * alpha >> 8)) | |
245 & 0xff00ff; | |
246 s &= 0xff00; | |
247 d &= 0xff00; | |
248 d = (d + ((s - d) * alpha >> 8)) & 0xff00; | |
249 *dstp = d1 | d | 0xff000000; | |
250 ++srcp; | |
251 ++dstp; | |
252 }, width); | |
253 srcp += srcskip; | |
254 dstp += dstskip; | |
255 } | |
230 } | 256 } |
231 } | 257 } |
232 | 258 |
233 /* fast ARGB888->(A)RGB888 blending with pixel alpha */ | 259 /* fast ARGB888->(A)RGB888 blending with pixel alpha */ |
234 static void BlitRGBtoRGBPixelAlpha(SDL_BlitInfo *info) | 260 static void BlitRGBtoRGBPixelAlpha(SDL_BlitInfo *info) |
275 srcp += srcskip; | 301 srcp += srcskip; |
276 dstp += dstskip; | 302 dstp += dstskip; |
277 } | 303 } |
278 } | 304 } |
279 | 305 |
280 /* fast RGB565->RGB565 blending with surface alpha */ | 306 /* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */ |
281 static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info) | 307 |
308 /* blend a single 16 bit pixel at 50% */ | |
309 #define BLEND16_50(d, s, mask) \ | |
310 ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff))) | |
311 | |
312 /* blend two 16 bit pixels at 50% */ | |
313 #define BLEND2x16_50(d, s, mask) \ | |
314 (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \ | |
315 + (s & d & (~(mask | mask << 16)))) | |
316 | |
317 static void Blit16to16SurfaceAlpha128(SDL_BlitInfo *info, Uint16 mask) | |
282 { | 318 { |
283 int width = info->d_width; | 319 int width = info->d_width; |
284 int height = info->d_height; | 320 int height = info->d_height; |
285 Uint16 *srcp = (Uint16 *)info->s_pixels; | 321 Uint16 *srcp = (Uint16 *)info->s_pixels; |
286 int srcskip = info->s_skip >> 1; | 322 int srcskip = info->s_skip >> 1; |
287 Uint16 *dstp = (Uint16 *)info->d_pixels; | 323 Uint16 *dstp = (Uint16 *)info->d_pixels; |
288 int dstskip = info->d_skip >> 1; | 324 int dstskip = info->d_skip >> 1; |
289 unsigned alpha = info->src->alpha >> 3; /* downscale alpha to 5 bits */ | |
290 | 325 |
291 while(height--) { | 326 while(height--) { |
292 DUFFS_LOOP4({ | 327 if(((unsigned long)srcp ^ (unsigned long)dstp) & 2) { |
293 Uint32 s = *srcp++; | 328 /* |
294 Uint32 d = *dstp; | 329 * Source and destination not aligned, pipeline it. |
295 /* | 330 * This is mostly a win for big blits but no loss for |
296 * shift out the middle component (green) to the high 16 | 331 * small ones |
297 * bits, and process all three RGB components at the same | 332 */ |
298 * time. | 333 Uint32 prev_sw; |
299 */ | 334 int w = width; |
300 s = (s | s << 16) & 0x07e0f81f; | 335 |
301 d = (d | d << 16) & 0x07e0f81f; | 336 /* handle odd destination */ |
302 d += (s - d) * alpha >> 5; | 337 if((unsigned long)dstp & 2) { |
303 d &= 0x07e0f81f; | 338 Uint16 d = *dstp, s = *srcp; |
304 *dstp++ = d | d >> 16; | 339 *dstp = BLEND16_50(d, s, mask); |
305 }, width); | 340 dstp++; |
306 srcp += srcskip; | 341 srcp++; |
307 dstp += dstskip; | 342 w--; |
343 } | |
344 srcp++; /* srcp is now 32-bit aligned */ | |
345 | |
346 /* bootstrap pipeline with first halfword */ | |
347 prev_sw = ((Uint32 *)srcp)[-1]; | |
348 | |
349 while(w > 1) { | |
350 Uint32 sw, dw, s; | |
351 sw = *(Uint32 *)srcp; | |
352 dw = *(Uint32 *)dstp; | |
353 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) | |
354 s = (prev_sw << 16) + (sw >> 16); | |
355 else | |
356 s = (prev_sw >> 16) + (sw << 16); | |
357 prev_sw = sw; | |
358 *(Uint32 *)dstp = BLEND2x16_50(dw, s, mask); | |
359 dstp += 2; | |
360 srcp += 2; | |
361 w -= 2; | |
362 } | |
363 | |
364 /* final pixel if any */ | |
365 if(w) { | |
366 Uint16 d = *dstp, s; | |
367 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) | |
368 s = prev_sw; | |
369 else | |
370 s = prev_sw >> 16; | |
371 *dstp = BLEND16_50(d, s, mask); | |
372 srcp++; | |
373 dstp++; | |
374 } | |
375 srcp += srcskip - 1; | |
376 dstp += dstskip; | |
377 } else { | |
378 /* source and destination are aligned */ | |
379 int w = width; | |
380 | |
381 /* first odd pixel? */ | |
382 if((unsigned long)srcp & 2) { | |
383 Uint16 d = *dstp, s = *srcp; | |
384 *dstp = BLEND16_50(d, s, mask); | |
385 srcp++; | |
386 dstp++; | |
387 w--; | |
388 } | |
389 /* srcp and dstp are now 32-bit aligned */ | |
390 | |
391 while(w > 1) { | |
392 Uint32 sw = *(Uint32 *)srcp; | |
393 Uint32 dw = *(Uint32 *)dstp; | |
394 *(Uint32 *)dstp = BLEND2x16_50(dw, sw, mask); | |
395 srcp += 2; | |
396 dstp += 2; | |
397 w -= 2; | |
398 } | |
399 | |
400 /* last odd pixel? */ | |
401 if(w) { | |
402 Uint16 d = *dstp, s = *srcp; | |
403 *dstp = BLEND16_50(d, s, mask); | |
404 srcp++; | |
405 dstp++; | |
406 } | |
407 srcp += srcskip; | |
408 dstp += dstskip; | |
409 } | |
410 } | |
411 } | |
412 | |
413 /* fast RGB565->RGB565 blending with surface alpha */ | |
414 static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info) | |
415 { | |
416 unsigned alpha = info->src->alpha; | |
417 if(alpha == 128) { | |
418 Blit16to16SurfaceAlpha128(info, 0xf7de); | |
419 } else { | |
420 int width = info->d_width; | |
421 int height = info->d_height; | |
422 Uint16 *srcp = (Uint16 *)info->s_pixels; | |
423 int srcskip = info->s_skip >> 1; | |
424 Uint16 *dstp = (Uint16 *)info->d_pixels; | |
425 int dstskip = info->d_skip >> 1; | |
426 alpha >>= 3; /* downscale alpha to 5 bits */ | |
427 | |
428 while(height--) { | |
429 DUFFS_LOOP4({ | |
430 Uint32 s = *srcp++; | |
431 Uint32 d = *dstp; | |
432 /* | |
433 * shift out the middle component (green) to | |
434 * the high 16 bits, and process all three RGB | |
435 * components at the same time. | |
436 */ | |
437 s = (s | s << 16) & 0x07e0f81f; | |
438 d = (d | d << 16) & 0x07e0f81f; | |
439 d += (s - d) * alpha >> 5; | |
440 d &= 0x07e0f81f; | |
441 *dstp++ = d | d >> 16; | |
442 }, width); | |
443 srcp += srcskip; | |
444 dstp += dstskip; | |
445 } | |
308 } | 446 } |
309 } | 447 } |
310 | 448 |
311 /* fast RGB555->RGB555 blending with surface alpha */ | 449 /* fast RGB555->RGB555 blending with surface alpha */ |
312 static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info) | 450 static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info) |
313 { | 451 { |
314 int width = info->d_width; | 452 unsigned alpha = info->src->alpha; /* downscale alpha to 5 bits */ |
315 int height = info->d_height; | 453 if(alpha == 128) { |
316 Uint16 *srcp = (Uint16 *)info->s_pixels; | 454 Blit16to16SurfaceAlpha128(info, 0xfbde); |
317 int srcskip = info->s_skip >> 1; | 455 } else { |
318 Uint16 *dstp = (Uint16 *)info->d_pixels; | 456 int width = info->d_width; |
319 int dstskip = info->d_skip >> 1; | 457 int height = info->d_height; |
320 unsigned alpha = info->src->alpha >> 3; /* downscale alpha to 5 bits */ | 458 Uint16 *srcp = (Uint16 *)info->s_pixels; |
321 | 459 int srcskip = info->s_skip >> 1; |
322 while(height--) { | 460 Uint16 *dstp = (Uint16 *)info->d_pixels; |
323 DUFFS_LOOP4({ | 461 int dstskip = info->d_skip >> 1; |
324 Uint32 s = *srcp++; | 462 alpha >>= 3; /* downscale alpha to 5 bits */ |
325 Uint32 d = *dstp; | 463 |
326 /* | 464 while(height--) { |
327 * shift out the middle component (green) to the high 16 | 465 DUFFS_LOOP4({ |
328 * bits, and process all three RGB components at the same | 466 Uint32 s = *srcp++; |
329 * time. | 467 Uint32 d = *dstp; |
330 */ | 468 /* |
331 s = (s | s << 16) & 0x03e07c1f; | 469 * shift out the middle component (green) to |
332 d = (d | d << 16) & 0x03e07c1f; | 470 * the high 16 bits, and process all three RGB |
333 d += (s - d) * alpha >> 5; | 471 * components at the same time. |
334 d &= 0x03e07c1f; | 472 */ |
335 *dstp++ = d | d >> 16; | 473 s = (s | s << 16) & 0x03e07c1f; |
336 }, width); | 474 d = (d | d << 16) & 0x03e07c1f; |
337 srcp += srcskip; | 475 d += (s - d) * alpha >> 5; |
338 dstp += dstskip; | 476 d &= 0x03e07c1f; |
477 *dstp++ = d | d >> 16; | |
478 }, width); | |
479 srcp += srcskip; | |
480 dstp += dstskip; | |
481 } | |
339 } | 482 } |
340 } | 483 } |
341 | 484 |
342 /* fast ARGB8888->RGB565 blending with pixel alpha */ | 485 /* fast ARGB8888->RGB565 blending with pixel alpha */ |
343 static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info) | 486 static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info) |