comparison src/video/SDL_surface.c @ 2253:6d99edd791bf

Added notes on the next steps for SDL 1.3 Moved fill and copy routines to their own files.
author Sam Lantinga <slouken@libsdl.org>
date Thu, 16 Aug 2007 21:43:19 +0000
parents 292bee385630
children 340942cfda48
comparison
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)