src/video/SDL_surface.c
changeset 2253 6d99edd791bf
parent 2251 292bee385630
child 2257 340942cfda48
equal deleted inserted replaced
2252:b80e3d57941f 2253:6d99edd791bf
   507     }
   507     }
   508     dstrect->w = dstrect->h = 0;
   508     dstrect->w = dstrect->h = 0;
   509     return 0;
   509     return 0;
   510 }
   510 }
   511 
   511 
   512 #ifdef __SSE__
       
   513 /* *INDENT-OFF* */
       
   514 
       
   515 #ifdef _MSC_VER
       
   516 #define SSE_BEGIN \
       
   517     __m128 c128; \
       
   518 	c128.m128_u32[0] = color; \
       
   519 	c128.m128_u32[1] = color; \
       
   520 	c128.m128_u32[2] = color; \
       
   521 	c128.m128_u32[3] = color;
       
   522 #else
       
   523 #define SSE_BEGIN \
       
   524     DECLARE_ALIGNED(Uint32, cccc[4], 16); \
       
   525     cccc[0] = color; \
       
   526     cccc[1] = color; \
       
   527     cccc[2] = color; \
       
   528     cccc[3] = color; \
       
   529     __m128 c128 = *(__m128 *)cccc;
       
   530 #endif
       
   531 
       
   532 #define SSE_WORK \
       
   533     for (i = n / 64; i--;) { \
       
   534         _mm_stream_ps((float *)(p+0), c128); \
       
   535         _mm_stream_ps((float *)(p+16), c128); \
       
   536         _mm_stream_ps((float *)(p+32), c128); \
       
   537         _mm_stream_ps((float *)(p+48), c128); \
       
   538         p += 64; \
       
   539     }
       
   540 
       
   541 #define SSE_END
       
   542 
       
   543 #define DEFINE_SSE_FILLRECT(bpp, type) \
       
   544 static void \
       
   545 SDL_FillRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
       
   546 { \
       
   547     SSE_BEGIN; \
       
   548  \
       
   549     while (h--) { \
       
   550         int i, n = w * bpp; \
       
   551         Uint8 *p = pixels; \
       
   552  \
       
   553         if (n > 15) { \
       
   554             int adjust = 16 - ((uintptr_t)p & 15); \
       
   555             if (adjust < 16) { \
       
   556                 n -= adjust; \
       
   557                 adjust /= bpp; \
       
   558                 while(adjust--) { \
       
   559                     *((type *)p) = (type)color; \
       
   560                     p += bpp; \
       
   561                 } \
       
   562             } \
       
   563             SSE_WORK; \
       
   564         } \
       
   565         if (n & 63) { \
       
   566             int remainder = (n & 63); \
       
   567             remainder /= bpp; \
       
   568             while(remainder--) { \
       
   569                 *((type *)p) = (type)color; \
       
   570                 p += bpp; \
       
   571             } \
       
   572         } \
       
   573         pixels += pitch; \
       
   574     } \
       
   575  \
       
   576     SSE_END; \
       
   577 }
       
   578 
       
   579 DEFINE_SSE_FILLRECT(1, Uint8)
       
   580 DEFINE_SSE_FILLRECT(2, Uint16)
       
   581 DEFINE_SSE_FILLRECT(4, Uint32)
       
   582 
       
   583 /* *INDENT-ON* */
       
   584 #endif /* __SSE__ */
       
   585 
       
   586 #ifdef __MMX__
       
   587 /* *INDENT-OFF* */
       
   588 
       
   589 #define MMX_BEGIN \
       
   590     __m64 c64 = _mm_set_pi32(color, color)
       
   591 
       
   592 #define MMX_WORK \
       
   593     for (i = n / 64; i--;) { \
       
   594         _mm_stream_pi((__m64 *)(p+0), c64); \
       
   595         _mm_stream_pi((__m64 *)(p+8), c64); \
       
   596         _mm_stream_pi((__m64 *)(p+16), c64); \
       
   597         _mm_stream_pi((__m64 *)(p+24), c64); \
       
   598         _mm_stream_pi((__m64 *)(p+32), c64); \
       
   599         _mm_stream_pi((__m64 *)(p+40), c64); \
       
   600         _mm_stream_pi((__m64 *)(p+48), c64); \
       
   601         _mm_stream_pi((__m64 *)(p+56), c64); \
       
   602         p += 64; \
       
   603     }
       
   604 
       
   605 #define MMX_END \
       
   606     _mm_empty()
       
   607 
       
   608 #define DEFINE_MMX_FILLRECT(bpp, type) \
       
   609 static void \
       
   610 SDL_FillRect##bpp##MMX(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
       
   611 { \
       
   612     MMX_BEGIN; \
       
   613  \
       
   614     while (h--) { \
       
   615         int i, n = w * bpp; \
       
   616         Uint8 *p = pixels; \
       
   617  \
       
   618         if (n > 7) { \
       
   619             int adjust = 8 - ((uintptr_t)p & 7); \
       
   620             if (adjust < 8) { \
       
   621                 n -= adjust; \
       
   622                 adjust /= bpp; \
       
   623                 while(adjust--) { \
       
   624                     *((type *)p) = (type)color; \
       
   625                     p += bpp; \
       
   626                 } \
       
   627             } \
       
   628             MMX_WORK; \
       
   629         } \
       
   630         if (n & 63) { \
       
   631             int remainder = (n & 63); \
       
   632             remainder /= bpp; \
       
   633             while(remainder--) { \
       
   634                 *((type *)p) = (type)color; \
       
   635                 p += bpp; \
       
   636             } \
       
   637         } \
       
   638         pixels += pitch; \
       
   639     } \
       
   640  \
       
   641     MMX_END; \
       
   642 }
       
   643 
       
   644 DEFINE_MMX_FILLRECT(1, Uint8)
       
   645 DEFINE_MMX_FILLRECT(2, Uint16)
       
   646 DEFINE_MMX_FILLRECT(4, Uint32)
       
   647 
       
   648 /* *INDENT-ON* */
       
   649 #endif /* __MMX__ */
       
   650 
       
   651 static void
       
   652 SDL_FillRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
       
   653 {
       
   654     while (h--) {
       
   655         int n = w;
       
   656         Uint8 *p = pixels;
       
   657 
       
   658         if (n > 3) {
       
   659             switch ((uintptr_t) p & 3) {
       
   660             case 1:
       
   661                 *p++ = (Uint8) color;
       
   662                 --n;
       
   663             case 2:
       
   664                 *p++ = (Uint8) color;
       
   665                 --n;
       
   666             case 3:
       
   667                 *p++ = (Uint8) color;
       
   668                 --n;
       
   669             }
       
   670             SDL_memset4(p, color, (n >> 2));
       
   671         }
       
   672         if (n & 3) {
       
   673             p += (n & ~3);
       
   674             switch (n & 3) {
       
   675             case 3:
       
   676                 *p++ = (Uint8) color;
       
   677             case 2:
       
   678                 *p++ = (Uint8) color;
       
   679             case 1:
       
   680                 *p++ = (Uint8) color;
       
   681             }
       
   682         }
       
   683         pixels += pitch;
       
   684     }
       
   685 }
       
   686 
       
   687 static void
       
   688 SDL_FillRect2(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
       
   689 {
       
   690     while (h--) {
       
   691         int n = w;
       
   692         Uint16 *p = (Uint16 *) pixels;
       
   693 
       
   694         if (n > 1) {
       
   695             if ((uintptr_t) p & 2) {
       
   696                 *p++ = (Uint16) color;
       
   697                 --n;
       
   698             }
       
   699             SDL_memset4(p, color, (n >> 1));
       
   700         }
       
   701         if (n & 1) {
       
   702             p[n - 1] = (Uint16) color;
       
   703         }
       
   704         pixels += pitch;
       
   705     }
       
   706 }
       
   707 
       
   708 static void
       
   709 SDL_FillRect3(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
       
   710 {
       
   711     Uint8 r = (Uint8) (color & 0xFF);
       
   712     Uint8 g = (Uint8) ((color >> 8) & 0xFF);
       
   713     Uint8 b = (Uint8) ((color >> 16) & 0xFF);
       
   714 
       
   715     while (h--) {
       
   716         int n = w;
       
   717         Uint8 *p = pixels;
       
   718 
       
   719         while (n--) {
       
   720             *p++ = r;
       
   721             *p++ = g;
       
   722             *p++ = b;
       
   723         }
       
   724         pixels += pitch;
       
   725     }
       
   726 }
       
   727 
       
   728 static void
       
   729 SDL_FillRect4(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
       
   730 {
       
   731     while (h--) {
       
   732         SDL_memset4(pixels, color, w);
       
   733         pixels += pitch;
       
   734     }
       
   735 }
       
   736 
       
   737 /* 
       
   738  * This function performs a fast fill of the given rectangle with 'color'
       
   739  */
       
   740 int
       
   741 SDL_FillRect(SDL_Surface * dst, SDL_Rect * dstrect, Uint32 color)
       
   742 {
       
   743     Uint8 *pixels;
       
   744 
       
   745     /* This function doesn't work on surfaces < 8 bpp */
       
   746     if (dst->format->BitsPerPixel < 8) {
       
   747         SDL_SetError("Fill rect on unsupported surface format");
       
   748         return (-1);
       
   749     }
       
   750 
       
   751     /* If 'dstrect' == NULL, then fill the whole surface */
       
   752     if (dstrect) {
       
   753         /* Perform clipping */
       
   754         if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) {
       
   755             return (0);
       
   756         }
       
   757     } else {
       
   758         dstrect = &dst->clip_rect;
       
   759     }
       
   760 
       
   761     /* Perform software fill */
       
   762     if (SDL_LockSurface(dst) != 0) {
       
   763         return (-1);
       
   764     }
       
   765 
       
   766     pixels =
       
   767         (Uint8 *) dst->pixels + dstrect->y * dst->pitch +
       
   768         dstrect->x * dst->format->BytesPerPixel;
       
   769 
       
   770     switch (dst->format->BytesPerPixel) {
       
   771     case 1:
       
   772         {
       
   773             color |= (color << 8);
       
   774             color |= (color << 16);
       
   775 #ifdef __SSE__
       
   776             if (SDL_HasSSE()) {
       
   777                 SDL_FillRect1SSE(pixels, dst->pitch, color, dstrect->w,
       
   778                                  dstrect->h);
       
   779                 break;
       
   780             }
       
   781 #endif
       
   782 #ifdef __MMX__
       
   783             if (SDL_HasMMX()) {
       
   784                 SDL_FillRect1MMX(pixels, dst->pitch, color, dstrect->w,
       
   785                                  dstrect->h);
       
   786                 break;
       
   787             }
       
   788 #endif
       
   789             SDL_FillRect1(pixels, dst->pitch, color, dstrect->w, dstrect->h);
       
   790             break;
       
   791         }
       
   792 
       
   793     case 2:
       
   794         {
       
   795             color |= (color << 16);
       
   796 #ifdef __SSE__
       
   797             if (SDL_HasSSE()) {
       
   798                 SDL_FillRect2SSE(pixels, dst->pitch, color, dstrect->w,
       
   799                                  dstrect->h);
       
   800                 break;
       
   801             }
       
   802 #endif
       
   803 #ifdef __MMX__
       
   804             if (SDL_HasMMX()) {
       
   805                 SDL_FillRect2MMX(pixels, dst->pitch, color, dstrect->w,
       
   806                                  dstrect->h);
       
   807                 break;
       
   808             }
       
   809 #endif
       
   810             SDL_FillRect2(pixels, dst->pitch, color, dstrect->w, dstrect->h);
       
   811             break;
       
   812         }
       
   813 
       
   814     case 3:
       
   815         /* 24-bit RGB is a slow path, at least for now. */
       
   816         {
       
   817             SDL_FillRect3(pixels, dst->pitch, color, dstrect->w, dstrect->h);
       
   818             break;
       
   819         }
       
   820 
       
   821     case 4:
       
   822         {
       
   823 #ifdef __SSE__
       
   824             if (SDL_HasSSE()) {
       
   825                 SDL_FillRect4SSE(pixels, dst->pitch, color, dstrect->w,
       
   826                                  dstrect->h);
       
   827                 break;
       
   828             }
       
   829 #endif
       
   830 #ifdef __MMX__
       
   831             if (SDL_HasMMX()) {
       
   832                 SDL_FillRect4MMX(pixels, dst->pitch, color, dstrect->w,
       
   833                                  dstrect->h);
       
   834                 break;
       
   835             }
       
   836 #endif
       
   837             SDL_FillRect4(pixels, dst->pitch, color, dstrect->w, dstrect->h);
       
   838             break;
       
   839         }
       
   840     }
       
   841 
       
   842     SDL_UnlockSurface(dst);
       
   843 
       
   844     /* We're done! */
       
   845     return (0);
       
   846 }
       
   847 
       
   848 /*
   512 /*
   849  * Lock a surface to directly access the pixels
   513  * Lock a surface to directly access the pixels
   850  */
   514  */
   851 int
   515 int
   852 SDL_LockSurface(SDL_Surface * surface)
   516 SDL_LockSurface(SDL_Surface * surface)