src/video/SDL_blit_N.c
changeset 12586 eb449394ec0e
parent 12583 338b02acfdfc
child 12599 e9be1aa42927
equal deleted inserted replaced
12585:dff36de37426 12586:eb449394ec0e
  2327     SDL_PixelFormat *dstfmt = info->dst_fmt;
  2327     SDL_PixelFormat *dstfmt = info->dst_fmt;
  2328     int srcbpp = srcfmt->BytesPerPixel;
  2328     int srcbpp = srcfmt->BytesPerPixel;
  2329     int dstbpp = dstfmt->BytesPerPixel;
  2329     int dstbpp = dstfmt->BytesPerPixel;
  2330     unsigned alpha = dstfmt->Amask ? info->a : 0;
  2330     unsigned alpha = dstfmt->Amask ? info->a : 0;
  2331     Uint32 rgbmask = ~srcfmt->Amask;
  2331     Uint32 rgbmask = ~srcfmt->Amask;
       
  2332     int sfmt = srcfmt->format;
       
  2333     int dfmt = dstfmt->format;
  2332 
  2334 
  2333     /* Set up some basic variables */
  2335     /* Set up some basic variables */
  2334     ckey &= rgbmask;
  2336     ckey &= rgbmask;
  2335 
  2337 
  2336     /* Fastpath: same source/destination format, no Amask, bpp 32, loop is vectorized. ~10x faster */
  2338     /* BPP 4, same rgb */
  2337     if (srcfmt->format == dstfmt->format &&
  2339     if (srcbpp == 4 && dstbpp == 4 && srcfmt->Rmask == dstfmt->Rmask && srcfmt->Gmask == dstfmt->Gmask && srcfmt->Bmask == dstfmt->Bmask) {
  2338         (srcfmt->format == SDL_PIXELFORMAT_RGB888 || srcfmt->format == SDL_PIXELFORMAT_BGR888)) {
       
  2339         Uint32 *src32 = (Uint32*)src;
  2340         Uint32 *src32 = (Uint32*)src;
  2340         Uint32 *dst32 = (Uint32*)dst;
  2341         Uint32 *dst32 = (Uint32*)dst;
  2341         srcskip /= sizeof(Uint32);
  2342  
  2342         dstskip /= sizeof(Uint32);
  2343         if (dstfmt->Amask) {
       
  2344             /* RGB->RGBA, SET_ALPHA */
       
  2345             Uint32 mask = info->a << dstfmt->Ashift;
       
  2346             while (height--) {
       
  2347                 /* *INDENT-OFF* */
       
  2348                 DUFFS_LOOP(
       
  2349                 {
       
  2350                     if ((*src32 & rgbmask) != ckey) {
       
  2351                         *dst32 = *src32 | mask;
       
  2352                     }
       
  2353                     ++dst32;
       
  2354                     ++src32;
       
  2355                 }, width);
       
  2356                 /* *INDENT-ON* */
       
  2357                 src32 = (Uint32 *) ((Uint8 *) src32 + srcskip);
       
  2358                 dst32 = (Uint32 *) ((Uint8 *) dst32 + dstskip);
       
  2359             }
       
  2360             return;
       
  2361         } else {
       
  2362             /* RGBA->RGB, NO_ALPHA */
       
  2363             Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
       
  2364             while (height--) {
       
  2365                 /* *INDENT-OFF* */
       
  2366                 DUFFS_LOOP(
       
  2367                 {
       
  2368                     if ((*src32 & rgbmask) != ckey) {
       
  2369                         *dst32 = *src32 & mask;
       
  2370                     }
       
  2371                     ++dst32;
       
  2372                     ++src32;
       
  2373                 }, width);
       
  2374                 /* *INDENT-ON* */
       
  2375                 src32 = (Uint32 *) ((Uint8 *) src32 + srcskip);
       
  2376                 dst32 = (Uint32 *) ((Uint8 *) dst32 + dstskip);
       
  2377             }
       
  2378             return;
       
  2379         }
       
  2380     }
       
  2381 
       
  2382     /* BPP 3, same rgb triplet */
       
  2383     if ((sfmt == SDL_PIXELFORMAT_RGB24 && dfmt == SDL_PIXELFORMAT_RGB24) ||
       
  2384         (sfmt == SDL_PIXELFORMAT_BGR24 && dfmt == SDL_PIXELFORMAT_BGR24)) {
       
  2385 
       
  2386         Uint8 k0 = ckey & 0x000000FF;
       
  2387         Uint8 k1 = (ckey & 0x0000FF00) >> 8;
       
  2388         Uint8 k2 = (ckey & 0x00FF0000) >> 16;
       
  2389 
  2343         while (height--) {
  2390         while (height--) {
  2344             /* *INDENT-OFF* */
  2391             /* *INDENT-OFF* */
  2345             DUFFS_LOOP(
  2392             DUFFS_LOOP(
  2346             {
  2393             {
  2347                 if (*src32 != ckey) {
  2394                 Uint8 s0 = src[0];
  2348                     *dst32 = *src32;
  2395                 Uint8 s1 = src[1];
       
  2396                 Uint8 s2 = src[2];
       
  2397 
       
  2398                 if (k0 != s0 || k1 != s1 || k2 != s2) {
       
  2399                     dst[0] = s0;
       
  2400                     dst[1] = s1;
       
  2401                     dst[2] = s2;
  2349                 }
  2402                 }
  2350                 ++src32;
  2403                 src += 3;
  2351                 ++dst32;
  2404                 dst += 3;
  2352             },
  2405             },
  2353             width);
  2406             width);
  2354             /* *INDENT-ON* */
  2407             /* *INDENT-ON* */
  2355             src32 += srcskip;
  2408             src += srcskip;
  2356             dst32 += dstskip;
  2409             dst += dstskip;
  2357         }
  2410         }
  2358         return;
  2411         return;
  2359     }
  2412     }
  2360 
  2413 
       
  2414     /* BPP 3, inversed rgb triplet */
       
  2415     if ((sfmt == SDL_PIXELFORMAT_RGB24 && dfmt == SDL_PIXELFORMAT_BGR24) ||
       
  2416         (sfmt == SDL_PIXELFORMAT_BGR24 && dfmt == SDL_PIXELFORMAT_RGB24)) {
       
  2417 
       
  2418         Uint8 k0 = ckey & 0xFF;
       
  2419         Uint8 k1 = (ckey >> 8)  & 0xFF;
       
  2420         Uint8 k2 = (ckey >> 16) & 0xFF;
       
  2421 
       
  2422         while (height--) {
       
  2423             /* *INDENT-OFF* */
       
  2424             DUFFS_LOOP(
       
  2425             {
       
  2426                 Uint8 s0 = src[0];
       
  2427                 Uint8 s1 = src[1];
       
  2428                 Uint8 s2 = src[2];
       
  2429                 if (k0 != s0 || k1 != s1 || k2 != s2) {
       
  2430                     /* Inversed RGB */
       
  2431                     dst[0] = s2;
       
  2432                     dst[1] = s1;
       
  2433                     dst[2] = s0;
       
  2434                 }
       
  2435                 src += 3;
       
  2436                 dst += 3;
       
  2437             },
       
  2438             width);
       
  2439             /* *INDENT-ON* */
       
  2440             src += srcskip;
       
  2441             dst += dstskip;
       
  2442         }
       
  2443         return;
       
  2444     } 
       
  2445    
  2361     while (height--) {
  2446     while (height--) {
  2362         /* *INDENT-OFF* */
  2447         /* *INDENT-OFF* */
  2363         DUFFS_LOOP(
  2448         DUFFS_LOOP(
  2364         {
  2449         {
  2365             Uint32 Pixel;
  2450             Uint32 Pixel;
  2404     srcbpp = srcfmt->BytesPerPixel;
  2489     srcbpp = srcfmt->BytesPerPixel;
  2405     dstbpp = dstfmt->BytesPerPixel;
  2490     dstbpp = dstfmt->BytesPerPixel;
  2406     ckey &= rgbmask;
  2491     ckey &= rgbmask;
  2407 
  2492 
  2408     /* Fastpath: same source/destination format, with Amask, bpp 32, loop is vectorized. ~10x faster */
  2493     /* Fastpath: same source/destination format, with Amask, bpp 32, loop is vectorized. ~10x faster */
  2409     if (srcfmt->format == dstfmt->format &&
  2494     if (srcfmt->format == dstfmt->format) {
  2410         (srcfmt->format == SDL_PIXELFORMAT_ARGB8888 ||
  2495 
  2411          srcfmt->format == SDL_PIXELFORMAT_ABGR8888 ||
  2496         if (srcfmt->format == SDL_PIXELFORMAT_ARGB8888 ||
  2412          srcfmt->format == SDL_PIXELFORMAT_BGRA8888 ||
  2497             srcfmt->format == SDL_PIXELFORMAT_ABGR8888 ||
  2413          srcfmt->format == SDL_PIXELFORMAT_RGBA8888)) {
  2498             srcfmt->format == SDL_PIXELFORMAT_BGRA8888 ||
  2414         Uint32 *src32 = (Uint32*)src;
  2499             srcfmt->format == SDL_PIXELFORMAT_RGBA8888) {
  2415         Uint32 *dst32 = (Uint32*)dst;
  2500 
  2416         srcskip /= sizeof(Uint32);
  2501             Uint32 *src32 = (Uint32*)src;
  2417         dstskip /= sizeof(Uint32);
  2502             Uint32 *dst32 = (Uint32*)dst;
  2418         while (height--) {
  2503             while (height--) {
  2419             /* *INDENT-OFF* */
  2504                 /* *INDENT-OFF* */
  2420             DUFFS_LOOP(
  2505                 DUFFS_LOOP(
  2421             {
  2506                 {
  2422                 if ((*src32 & rgbmask) != ckey) {
  2507                     if ((*src32 & rgbmask) != ckey) {
  2423                     *dst32 = *src32;
  2508                         *dst32 = *src32;
  2424                 }
  2509                     }
  2425                 ++src32;
  2510                     ++src32;
  2426                 ++dst32;
  2511                     ++dst32;
  2427             },
  2512                 },
  2428             width);
  2513                 width);
  2429             /* *INDENT-ON* */
  2514                 /* *INDENT-ON* */
  2430             src32 += srcskip;
  2515                 src32 = (Uint32 *)((Uint8 *)src32 + srcskip);
  2431             dst32 += dstskip;
  2516                 dst32 = (Uint32 *)((Uint8 *)dst32 + dstskip);
       
  2517             }
  2432         }
  2518         }
  2433         return;
  2519         return;
  2434     }
  2520     }
  2435 
  2521 
  2436     while (height--) {
  2522     while (height--) {
  2530     SDL_PixelFormat *dstfmt = info->dst_fmt;
  2616     SDL_PixelFormat *dstfmt = info->dst_fmt;
  2531     int dstbpp = dstfmt->BytesPerPixel;
  2617     int dstbpp = dstfmt->BytesPerPixel;
  2532 
  2618 
  2533     if (dstfmt->Amask) {
  2619     if (dstfmt->Amask) {
  2534         /* SET_ALPHA */
  2620         /* SET_ALPHA */
  2535         Uint32 alpha = info->a;
  2621         Uint32 mask = info->a << dstfmt->Ashift;
  2536         Uint32 alphashift = alpha << 24;
       
  2537         while (height--) {
  2622         while (height--) {
  2538             /* *INDENT-OFF* */
  2623             /* *INDENT-OFF* */
  2539             DUFFS_LOOP(
  2624             DUFFS_LOOP(
  2540             {
  2625             {
  2541                 Uint32  *dst32 = (Uint32*)dst;
  2626                 Uint32  *dst32 = (Uint32*)dst;
  2542                 Uint8 s0 = src[0];
  2627                 Uint8 s0 = src[0];
  2543                 Uint8 s1 = src[1];
  2628                 Uint8 s1 = src[1];
  2544                 Uint8 s2 = src[2];
  2629                 Uint8 s2 = src[2];
  2545                 *dst32 = (s0) | (s1 << 8) | (s2 << 16) | alphashift;
  2630                 *dst32 = (s0) | (s1 << 8) | (s2 << 16) | mask;
  2546                 dst += dstbpp;
  2631                 dst += dstbpp;
  2547                 src += srcbpp;
  2632                 src += srcbpp;
  2548             }, width);
  2633             }, width);
  2549             /* *INDENT-ON* */
  2634             /* *INDENT-ON* */
  2550             src += srcskip;
  2635             src += srcskip;
  2586     int srcbpp = srcfmt->BytesPerPixel;
  2671     int srcbpp = srcfmt->BytesPerPixel;
  2587     SDL_PixelFormat *dstfmt = info->dst_fmt;
  2672     SDL_PixelFormat *dstfmt = info->dst_fmt;
  2588     int dstbpp = dstfmt->BytesPerPixel;
  2673     int dstbpp = dstfmt->BytesPerPixel;
  2589 
  2674 
  2590     if (dstfmt->Amask) {
  2675     if (dstfmt->Amask) {
  2591 
       
  2592         if (srcfmt->Amask) {
  2676         if (srcfmt->Amask) {
  2593             /* COPY_ALPHA */
  2677             /* COPY_ALPHA */
  2594             /* Only to switch ABGR8888 <-> ARGB8888 */
  2678             /* Only to switch ABGR8888 <-> ARGB8888 */
  2595             while (height--) {
  2679             while (height--) {
  2596                 /* *INDENT-OFF* */
  2680                 /* *INDENT-OFF* */
  2597                 DUFFS_LOOP(
  2681                 DUFFS_LOOP(
  2598                 {
  2682                 {
  2599                     Uint32  *dst32 = (Uint32*)dst;
  2683                     Uint32 *dst32 = (Uint32*)dst;
  2600                     Uint8 s0 = src[0];
  2684                     Uint8 s0 = src[0];
  2601                     Uint8 s1 = src[1];
  2685                     Uint8 s1 = src[1];
  2602                     Uint8 s2 = src[2];
  2686                     Uint8 s2 = src[2];
  2603                     Uint32 alphashift = src[3] << 24;
  2687                     Uint32 alphashift = src[3] << dstfmt->Ashift;
  2604                     /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
  2688                     /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
  2605                     *dst32 = (s0 << 16) | (s1 << 8) | (s2) | alphashift;
  2689                     *dst32 = (s0 << 16) | (s1 << 8) | (s2) | alphashift;
  2606                     dst += dstbpp;
  2690                     dst += dstbpp;
  2607                     src += srcbpp;
  2691                     src += srcbpp;
  2608                 }, width);
  2692                 }, width);
  2610                 src += srcskip;
  2694                 src += srcskip;
  2611                 dst += dstskip;
  2695                 dst += dstskip;
  2612             }
  2696             }
  2613         } else {
  2697         } else {
  2614             /* SET_ALPHA */
  2698             /* SET_ALPHA */
  2615             Uint32 alpha = info->a;
  2699             Uint32 mask = info->a << dstfmt->Ashift;
  2616             Uint32 alphashift = alpha << 24;
       
  2617             while (height--) {
  2700             while (height--) {
  2618                 /* *INDENT-OFF* */
  2701                 /* *INDENT-OFF* */
  2619                 DUFFS_LOOP(
  2702                 DUFFS_LOOP(
  2620                 {
  2703                 {
  2621                     Uint32  *dst32 = (Uint32*)dst;
  2704                     Uint32 *dst32 = (Uint32*)dst;
  2622                     Uint8 s0 = src[0];
  2705                     Uint8 s0 = src[0];
  2623                     Uint8 s1 = src[1];
  2706                     Uint8 s1 = src[1];
  2624                     Uint8 s2 = src[2];
  2707                     Uint8 s2 = src[2];
  2625                     /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
  2708                     /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
  2626                     *dst32 = (s0 << 16) | (s1 << 8) | (s2) | alphashift;
  2709                     *dst32 = (s0 << 16) | (s1 << 8) | (s2) | mask;
  2627                     dst += dstbpp;
  2710                     dst += dstbpp;
  2628                     src += srcbpp;
  2711                     src += srcbpp;
  2629                 }, width);
  2712                 }, width);
  2630                 /* *INDENT-ON* */
  2713                 /* *INDENT-ON* */
  2631                 src += srcskip;
  2714                 src += srcskip;
  2636         /* NO_ALPHA */
  2719         /* NO_ALPHA */
  2637         while (height--) {
  2720         while (height--) {
  2638             /* *INDENT-OFF* */
  2721             /* *INDENT-OFF* */
  2639             DUFFS_LOOP(
  2722             DUFFS_LOOP(
  2640             {
  2723             {
  2641                 Uint32  *dst32 = (Uint32*)dst;
  2724                 Uint32 *dst32 = (Uint32*)dst;
  2642                 Uint8 s0 = src[0];
  2725                 Uint8 s0 = src[0];
  2643                 Uint8 s1 = src[1];
  2726                 Uint8 s1 = src[1];
  2644                 Uint8 s2 = src[2];
  2727                 Uint8 s2 = src[2];
  2645                 /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
  2728                 /* inversed, compared to Blit_3or4_to_3or4__same_rgb */
  2646                 *dst32 = (s0 << 16) | (s1 << 8) | (s2);
  2729                 *dst32 = (s0 << 16) | (s1 << 8) | (s2);
  2743     /* 4->4 with inversed rgb triplet, and COPY_ALPHA to switch ABGR8888 <-> ARGB8888 */
  2826     /* 4->4 with inversed rgb triplet, and COPY_ALPHA to switch ABGR8888 <-> ARGB8888 */
  2744     {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
  2827     {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
  2745      0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA | SET_ALPHA | COPY_ALPHA},
  2828      0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA | SET_ALPHA | COPY_ALPHA},
  2746     {0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
  2829     {0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
  2747      0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA | SET_ALPHA | COPY_ALPHA},
  2830      0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA | SET_ALPHA | COPY_ALPHA},
  2748     /* RBG 888 and RGB 565 */
  2831     /* RGB 888 and RGB 565 */
  2749     {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x0000F800, 0x000007E0, 0x0000001F,
  2832     {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x0000F800, 0x000007E0, 0x0000001F,
  2750      0, Blit_RGB888_RGB565, NO_ALPHA},
  2833      0, Blit_RGB888_RGB565, NO_ALPHA},
  2751     {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x00007C00, 0x000003E0, 0x0000001F,
  2834     {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x00007C00, 0x000003E0, 0x0000001F,
  2752      0, Blit_RGB888_RGB555, NO_ALPHA},
  2835      0, Blit_RGB888_RGB555, NO_ALPHA},
  2753     /* Default for 32-bit RGB source, used if no other blitter matches */
  2836     /* Default for 32-bit RGB source, used if no other blitter matches */