Mercurial > sdl-ios-xcode
comparison src/video/x11/SDL_x11render.c @ 4610:32991e17e2b6
Make the SW renderer work properly by fixing support for textures with no alpha channels.
author | Sunny Sachanandani <sunnysachanandani@gmail.com> |
---|---|
date | Wed, 21 Jul 2010 23:08:09 +0530 |
parents | 630002c8be85 |
children | a2ed55b5ff85 |
comparison
equal
deleted
inserted
replaced
4609:630002c8be85 | 4610:32991e17e2b6 |
---|---|
669 } | 669 } |
670 | 670 |
671 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER | 671 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER |
672 static void | 672 static void |
673 SDLMaskToXRenderMask(Uint32 sdl_mask, short *comp, short *compMask) { | 673 SDLMaskToXRenderMask(Uint32 sdl_mask, short *comp, short *compMask) { |
674 (*comp) = 0; | 674 if (sdl_mask == 0) { |
675 (*compMask) = 0; | 675 *comp = 0; |
676 while(!(sdl_mask & 1)) { | 676 *compMask = 0; |
677 (*comp)++; | 677 } else { |
678 sdl_mask >>= 1; | 678 (*comp) = 0; |
679 } | 679 (*compMask) = 0; |
680 while(sdl_mask & 1) { | 680 while(!(sdl_mask & 1)) { |
681 (*compMask) = ((*compMask) << 1) | 1; | 681 (*comp)++; |
682 sdl_mask >>= 1; | 682 sdl_mask >>= 1; |
683 } | |
684 while(sdl_mask & 1) { | |
685 (*compMask) = ((*compMask) << 1) | 1; | |
686 sdl_mask >>= 1; | |
687 } | |
683 } | 688 } |
684 } | 689 } |
685 | 690 |
686 static XRenderPictFormat* | 691 static XRenderPictFormat* |
687 PixelFormatEnumToXRenderPictFormat(SDL_Renderer * renderer, Uint32 format) { | 692 PixelFormatEnumToXRenderPictFormat(SDL_Renderer * renderer, Uint32 format) { |
688 XRenderPictFormat* pict_fmt = NULL; | 693 XRenderPictFormat* pict_fmt = NULL; |
689 X11_RenderData *data = (X11_RenderData *) renderer->driverdata; | 694 X11_RenderData *data = (X11_RenderData *) renderer->driverdata; |
690 | 695 |
691 if (data->use_xrender) { | 696 if (data->use_xrender) { |
692 | 697 |
693 int bpp; | 698 int bpp; |
694 Uint32 Amask, Rmask, Gmask, Bmask; | 699 Uint32 Amask, Rmask, Gmask, Bmask; |
695 SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); | 700 if(!SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { |
696 | 701 SDL_SetError("Unknown pixel format"); |
702 return NULL; | |
703 } | |
697 XRenderPictFormat templ; | 704 XRenderPictFormat templ; |
698 unsigned long mask = (PictFormatType | PictFormatDepth | PictFormatRed | | 705 unsigned long mask = (PictFormatType | PictFormatDepth | PictFormatRed | |
699 PictFormatRedMask | PictFormatGreen | PictFormatGreenMask | | 706 PictFormatRedMask | PictFormatGreen | PictFormatGreenMask | |
700 PictFormatBlue | PictFormatBlueMask | PictFormatAlpha | | 707 PictFormatBlue | PictFormatBlueMask | PictFormatAlpha | |
701 PictFormatAlphaMask); | 708 PictFormatAlphaMask); |
704 templ.depth = bpp; | 711 templ.depth = bpp; |
705 SDLMaskToXRenderMask(Amask, &(templ.direct.alpha), &(templ.direct.alphaMask)); | 712 SDLMaskToXRenderMask(Amask, &(templ.direct.alpha), &(templ.direct.alphaMask)); |
706 SDLMaskToXRenderMask(Rmask, &(templ.direct.red), &(templ.direct.redMask)); | 713 SDLMaskToXRenderMask(Rmask, &(templ.direct.red), &(templ.direct.redMask)); |
707 SDLMaskToXRenderMask(Gmask, &(templ.direct.green), &(templ.direct.greenMask)); | 714 SDLMaskToXRenderMask(Gmask, &(templ.direct.green), &(templ.direct.greenMask)); |
708 SDLMaskToXRenderMask(Bmask, &(templ.direct.blue), &(templ.direct.blueMask)); | 715 SDLMaskToXRenderMask(Bmask, &(templ.direct.blue), &(templ.direct.blueMask)); |
709 | |
710 pict_fmt = XRenderFindFormat(data->display, mask, &templ, 0); | 716 pict_fmt = XRenderFindFormat(data->display, mask, &templ, 0); |
711 } | 717 } |
712 | 718 |
713 return pict_fmt; | 719 return pict_fmt; |
714 } | 720 } |
772 if (!data->yuv) { | 778 if (!data->yuv) { |
773 return -1; | 779 return -1; |
774 } | 780 } |
775 data->format = display->current_mode.format; | 781 data->format = display->current_mode.format; |
776 } else { | 782 } else { |
777 /* If Xrender support is builtin we only need to check whether | 783 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER |
778 Xrender is available at runtime. If it is available there | 784 if (renderdata->use_xrender) |
779 can be no BadMatch error since Xrender takes care of that. | 785 { |
780 */ | |
781 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER | |
782 if (renderdata->use_xrender == SDL_FALSE) { | |
783 if (texture->format != display->current_mode.format) { | |
784 SDL_SetError("Texture format doesn't match window format"); | |
785 return -1; | |
786 } | |
787 } else { | |
788 Uint32 Amask, Rmask, Gmask, Bmask; | 786 Uint32 Amask, Rmask, Gmask, Bmask; |
789 SDL_PixelFormatEnumToMasks(texture->format, &(data->depth), | 787 SDL_PixelFormatEnumToMasks(texture->format, &(data->depth), |
790 &Rmask, &Gmask, &Bmask, &Amask); | 788 &Rmask, &Gmask, &Bmask, &Amask); |
789 printf("%d %x %x %x %x\n", data->depth, Rmask, Gmask, Bmask, Amask); | |
791 data->visual = PixelFormatEnumToVisual(renderer, texture->format); | 790 data->visual = PixelFormatEnumToVisual(renderer, texture->format); |
792 } | 791 } |
793 #else | 792 else |
794 /* The image/pixmap depth must be the same as the window or you | 793 #endif |
795 get a BadMatch error when trying to putimage or copyarea. | 794 { |
796 This BadMatch error | 795 if (texture->format != display->current_mode.format) |
797 */ | 796 { |
798 if (texture->format != display->current_mode.format) { | 797 SDL_SetError("Texture format doesn't match window format"); |
799 SDL_SetError("Texture format doesn't match window format"); | 798 return -1; |
800 return -1; | 799 } |
801 } | 800 } |
802 #endif | |
803 data->format = texture->format; | 801 data->format = texture->format; |
804 } | 802 } |
805 data->pitch = texture->w * SDL_BYTESPERPIXEL(data->format); | 803 |
806 data->pitch = (data->pitch + pitch_alignmask) & ~pitch_alignmask; | |
807 | |
808 if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING) { | 804 if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING) { |
809 #ifndef NO_SHARED_MEMORY | 805 #ifndef NO_SHARED_MEMORY |
810 XShmSegmentInfo *shminfo = &data->shminfo; | 806 XShmSegmentInfo *shminfo = &data->shminfo; |
811 | 807 |
812 shm_error = True; | 808 shm_error = True; |
813 | 809 |
814 if (SDL_X11_HAVE_SHM) { | 810 if (SDL_X11_HAVE_SHM) { |
815 shminfo->shmid = | 811 data->image = |
816 shmget(IPC_PRIVATE, texture->h * data->pitch, | 812 XShmCreateImage(renderdata->display, data->visual, |
817 IPC_CREAT | 0777); | 813 data->depth, ZPixmap, NULL, |
818 if (shminfo->shmid >= 0) { | 814 shminfo, texture->w, texture->h); |
819 shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); | 815 if (data->image) { |
820 shminfo->readOnly = False; | 816 shminfo->shmid = |
821 if (shminfo->shmaddr != (char *) -1) { | 817 shmget(IPC_PRIVATE, texture->h * data->image->bytes_per_line, |
822 shm_error = False; | 818 IPC_CREAT | 0777); |
823 X_handler = XSetErrorHandler(shm_errhandler); | 819 if (shminfo->shmid >= 0) { |
824 XShmAttach(renderdata->display, shminfo); | 820 shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); |
825 XSync(renderdata->display, False); | 821 shminfo->readOnly = False; |
826 XSetErrorHandler(X_handler); | 822 if (shminfo->shmaddr != (char *) -1) { |
827 if (shm_error) { | 823 shm_error = False; |
828 shmdt(shminfo->shmaddr); | 824 X_handler = XSetErrorHandler(shm_errhandler); |
825 XShmAttach(renderdata->display, shminfo); | |
826 XSync(renderdata->display, False); | |
827 XSetErrorHandler(X_handler); | |
828 if (shm_error) { | |
829 XShmDetach(renderdata->display, shminfo); | |
830 shmdt(shminfo->shmaddr); | |
831 XDestroyImage(data->image); | |
832 XSync(renderdata->display, False); | |
833 } | |
834 else { | |
835 data->pixels = data->image->data = shminfo->shmaddr; | |
836 shmctl(shminfo->shmid, IPC_RMID, NULL); | |
837 data->pixmap = | |
838 XCreatePixmap(renderdata->display, renderdata->xwindow, | |
839 texture->w, texture->h, data->depth); | |
840 if (!data->pixmap) { | |
841 SDL_SetError("XCreatePixmap() failed"); | |
842 return -1; | |
843 } | |
844 } | |
829 } | 845 } |
830 } | 846 } |
831 shmctl(shminfo->shmid, IPC_RMID, NULL); | 847 } |
832 } | 848 } |
833 } | 849 if (shm_error) { |
834 if (!shm_error) { | 850 shminfo->shmaddr = NULL; |
835 data->pixels = shminfo->shmaddr; | 851 } |
852 if (!data->image) | |
853 #endif /* not NO_SHARED_MEMORY */ | |
854 { | |
855 data->image = | |
856 XCreateImage(renderdata->display, data->visual, | |
857 data->depth, ZPixmap, 0, NULL, | |
858 texture->w, texture->h, | |
859 SDL_BYTESPERPIXEL(data->format) * 8, | |
860 0); | |
861 if (!data->image) { | |
862 X11_DestroyTexture(renderer, texture); | |
863 SDL_SetError("XCreateImage() failed"); | |
864 return -1; | |
865 } | |
866 data->pixels = SDL_malloc(texture->h * data->image->bytes_per_line); | |
867 if (!data->pixels) { | |
868 X11_DestroyTexture(renderer, texture); | |
869 SDL_OutOfMemory(); | |
870 return -1; | |
871 } | |
872 data->image->data = data->pixels; | |
836 data->pixmap = | 873 data->pixmap = |
837 XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w, | 874 XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w, |
838 texture->h, data->depth); | 875 texture->h, data->depth); |
839 if (data->pixmap == None) { | 876 if (data->pixmap == None) { |
840 X11_DestroyTexture(renderer, texture); | 877 X11_DestroyTexture(renderer, texture); |
841 SDL_SetError("XCreatePixmap() failed"); | 878 SDL_SetError("XCreatePixmap() failed"); |
842 return -1; | 879 return -1; |
843 } | 880 } |
844 data->image = | |
845 XShmCreateImage(renderdata->display, data->visual, | |
846 data->depth, ZPixmap, shminfo->shmaddr, | |
847 shminfo, texture->w, texture->h); | |
848 | |
849 if (!data->image) { | |
850 XShmDetach(renderdata->display, shminfo); | |
851 XSync(renderdata->display, False); | |
852 shmdt(shminfo->shmaddr); | |
853 shm_error = True; | |
854 } | |
855 } | |
856 if (shm_error) { | |
857 shminfo->shmaddr = NULL; | |
858 } | |
859 if (!data->image) | |
860 #endif /* not NO_SHARED_MEMORY */ | |
861 { | |
862 data->pixels = SDL_malloc(texture->h * data->pitch); | |
863 if (!data->pixels) { | |
864 X11_DestroyTexture(renderer, texture); | |
865 SDL_OutOfMemory(); | |
866 return -1; | |
867 } | |
868 | |
869 data->pixmap = | |
870 XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w, | |
871 texture->h, data->depth); | |
872 if (data->pixmap == None) { | |
873 X11_DestroyTexture(renderer, texture); | |
874 SDL_SetError("XCreatePixmap() failed"); | |
875 return -1; | |
876 } | |
877 data->image = | |
878 XCreateImage(renderdata->display, data->visual, | |
879 data->depth, ZPixmap, 0, data->pixels, | |
880 texture->w, texture->h, | |
881 SDL_BYTESPERPIXEL(data->format) * 8, | |
882 data->pitch); | |
883 if (!data->image) { | |
884 X11_DestroyTexture(renderer, texture); | |
885 SDL_SetError("XCreateImage() failed"); | |
886 return -1; | |
887 } | |
888 } | 881 } |
889 } | 882 } |
890 else { | 883 else { |
884 data->image = | |
885 XCreateImage(renderdata->display, data->visual, | |
886 data->depth, ZPixmap, 0, NULL, | |
887 texture->w, texture->h, | |
888 SDL_BYTESPERPIXEL(data->format) * 8, | |
889 0); | |
890 if (!data->image) { | |
891 X11_DestroyTexture(renderer, texture); | |
892 SDL_SetError("XCreateImage() failed"); | |
893 return -1; | |
894 } | |
891 data->pixmap = | 895 data->pixmap = |
892 XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w, | 896 XCreatePixmap(renderdata->display, renderdata->xwindow, texture->w, |
893 texture->h, data->depth); | 897 texture->h, data->depth); |
894 if (data->pixmap == None) { | 898 if (data->pixmap == None) { |
895 X11_DestroyTexture(renderer, texture); | 899 X11_DestroyTexture(renderer, texture); |
896 SDL_SetError("XCreatePixmap() failed"); | 900 SDL_SetError("XCreatePixmap() failed"); |
897 return -1; | 901 return -1; |
898 } | 902 } |
899 data->image = | 903 } |
900 XCreateImage(renderdata->display, data->visual, | 904 |
901 data->depth, ZPixmap, 0, NULL, | 905 data->pitch = data->image->bytes_per_line; |
902 texture->w, texture->h, | 906 |
903 SDL_BYTESPERPIXEL(data->format) * 8, | |
904 data->pitch); | |
905 if (!data->image) { | |
906 X11_DestroyTexture(renderer, texture); | |
907 SDL_SetError("XCreateImage() failed"); | |
908 return -1; | |
909 } | |
910 } | |
911 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER | 907 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER |
912 if(renderdata->use_xrender) { | 908 if(renderdata->use_xrender) { |
913 gcv.graphics_exposures = False; | 909 gcv.graphics_exposures = False; |
914 data->gc = | 910 data->gc = |
915 XCreateGC(renderdata->display, data->pixmap, GCGraphicsExposures, &gcv); | 911 XCreateGC(renderdata->display, data->pixmap, GCGraphicsExposures, &gcv); |
930 if (!data->picture) { | 926 if (!data->picture) { |
931 X11_DestroyTexture(renderer, texture); | 927 X11_DestroyTexture(renderer, texture); |
932 SDL_SetError("XRenderCreatePicture() failed"); | 928 SDL_SetError("XRenderCreatePicture() failed"); |
933 return -1; | 929 return -1; |
934 } | 930 } |
931 texture->blendMode = SDL_BLENDMODE_NONE; | |
932 data->blend_op = PictOpSrc; | |
935 } | 933 } |
936 #endif | 934 #endif |
937 return 0; | 935 return 0; |
938 } | 936 } |
939 | 937 |
1711 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER | 1709 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER |
1712 if (data->use_xrender) { | 1710 if (data->use_xrender) { |
1713 if(texture->access == SDL_TEXTUREACCESS_STREAMING) { | 1711 if(texture->access == SDL_TEXTUREACCESS_STREAMING) { |
1714 #ifndef NO_SHARED_MEMORY | 1712 #ifndef NO_SHARED_MEMORY |
1715 if(texturedata->shminfo.shmaddr) { | 1713 if(texturedata->shminfo.shmaddr) { |
1716 XShmPutImage(data->display, texturedata->pixmap, data->gc, | 1714 XShmPutImage(data->display, texturedata->pixmap, texturedata->gc, |
1717 texturedata->image, srcrect->x, srcrect->y, | 1715 texturedata->image, srcrect->x, srcrect->y, |
1718 srcrect->x, srcrect->y, srcrect->w, srcrect->h, | 1716 srcrect->x, srcrect->y, srcrect->w, srcrect->h, |
1719 False); | 1717 False); |
1720 } | 1718 } |
1721 else | 1719 else |
1722 #endif | 1720 #endif |
1723 if (texturedata->pixels) { | 1721 if (texturedata->pixels) { |
1724 XPutImage(data->display, texturedata->pixmap, data->gc, | 1722 XPutImage(data->display, texturedata->pixmap, texturedata->gc, |
1725 texturedata->image, srcrect->x, srcrect->y, dstrect->x, | 1723 texturedata->image, srcrect->x, srcrect->y, srcrect->x, |
1726 dstrect->y, srcrect->w, srcrect->h); | 1724 srcrect->y, srcrect->w, srcrect->h); |
1727 } | 1725 } |
1726 XSync(data->display, False); | |
1728 } | 1727 } |
1729 Picture mask; | 1728 Picture mask; |
1730 XRenderPictureAttributes attr; | 1729 XRenderPictureAttributes attr; |
1731 const SDL_Rect *mrect; | 1730 const SDL_Rect *mrect; |
1732 if(texture->blendMode == SDL_BLENDMODE_NONE) { | 1731 if(texture->blendMode == SDL_BLENDMODE_NONE) { |