Mercurial > sdl-ios-xcode
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) |