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)