comparison src/video/x11/SDL_x11render.c @ 4616:05eb4a07e5e3

Add support for texture modulation (both color and alpha). testsprite2 works now with --cyclealpha and --cyclecolor.
author Sunny Sachanandani <sunnysachanandani@gmail.com>
date Wed, 28 Jul 2010 11:56:17 +0530
parents 789483a20081
children cfbb1ff4b8ec
comparison
equal deleted inserted replaced
4615:789483a20081 4616:05eb4a07e5e3
37 static int X11_DisplayModeChanged(SDL_Renderer * renderer); 37 static int X11_DisplayModeChanged(SDL_Renderer * renderer);
38 static int X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); 38 static int X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
39 static int X11_QueryTexturePixels(SDL_Renderer * renderer, 39 static int X11_QueryTexturePixels(SDL_Renderer * renderer,
40 SDL_Texture * texture, void **pixels, 40 SDL_Texture * texture, void **pixels,
41 int *pitch); 41 int *pitch);
42 static int X11_SetTextureRGBAMod(SDL_Renderer * renderer,
43 SDL_Texture * texture);
42 static int X11_SetTextureBlendMode(SDL_Renderer * renderer, 44 static int X11_SetTextureBlendMode(SDL_Renderer * renderer,
43 SDL_Texture * texture); 45 SDL_Texture * texture);
44 static int X11_SetTextureScaleMode(SDL_Renderer * renderer, 46 static int X11_SetTextureScaleMode(SDL_Renderer * renderer,
45 SDL_Texture * texture); 47 SDL_Texture * texture);
46 static int X11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, 48 static int X11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
131 int depth; 133 int depth;
132 Visual *visual; 134 Visual *visual;
133 GC gc; 135 GC gc;
134 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 136 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
135 Picture picture; 137 Picture picture;
138 Pixmap modulated_pixmap;
139 Picture modulated_picture;
136 XRenderPictFormat* picture_fmt; 140 XRenderPictFormat* picture_fmt;
137 int blend_op; 141 int blend_op;
138 const char* filter; 142 const char* filter;
139 #endif 143 #endif
140 XImage *image; 144 XImage *image;
307 } 311 }
308 } 312 }
309 else 313 else
310 break; 314 break;
311 } 315 }
312 info->blend_modes = (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | 316 info->blend_modes |= (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD |
313 SDL_BLENDMODE_MOD | SDL_BLENDMODE_MASK); 317 SDL_BLENDMODE_MOD | SDL_BLENDMODE_MASK);
314 info->scale_modes = (SDL_TEXTURESCALEMODE_FAST | SDL_TEXTURESCALEMODE_SLOW | 318 info->scale_modes |= (SDL_TEXTURESCALEMODE_FAST | SDL_TEXTURESCALEMODE_SLOW |
315 SDL_TEXTURESCALEMODE_BEST); 319 SDL_TEXTURESCALEMODE_BEST);
320 info->mod_modes |= (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA);
316 } 321 }
317 #endif 322 #endif
318 323
319 for (i = 0; i < _this->num_displays; ++i) { 324 for (i = 0; i < _this->num_displays; ++i) {
320 SDL_AddRenderDriver(&_this->displays[i], &X11_RenderDriver); 325 SDL_AddRenderDriver(&_this->displays[i], &X11_RenderDriver);
355 data->xwindow = windowdata->xwindow; 360 data->xwindow = windowdata->xwindow;
356 361
357 renderer->DisplayModeChanged = X11_DisplayModeChanged; 362 renderer->DisplayModeChanged = X11_DisplayModeChanged;
358 renderer->CreateTexture = X11_CreateTexture; 363 renderer->CreateTexture = X11_CreateTexture;
359 renderer->QueryTexturePixels = X11_QueryTexturePixels; 364 renderer->QueryTexturePixels = X11_QueryTexturePixels;
365 renderer->SetTextureAlphaMod = X11_SetTextureRGBAMod;
366 renderer->SetTextureColorMod = X11_SetTextureRGBAMod;
360 renderer->SetTextureBlendMode = X11_SetTextureBlendMode; 367 renderer->SetTextureBlendMode = X11_SetTextureBlendMode;
361 renderer->SetTextureScaleMode = X11_SetTextureScaleMode; 368 renderer->SetTextureScaleMode = X11_SetTextureScaleMode;
362 renderer->UpdateTexture = X11_UpdateTexture; 369 renderer->UpdateTexture = X11_UpdateTexture;
363 renderer->LockTexture = X11_LockTexture; 370 renderer->LockTexture = X11_LockTexture;
364 renderer->UnlockTexture = X11_UnlockTexture; 371 renderer->UnlockTexture = X11_UnlockTexture;
785 return ret[0].visual; 792 return ret[0].visual;
786 } 793 }
787 } 794 }
788 795
789 return NULL; 796 return NULL;
797 }
798
799 static XRenderColor
800 SDLColorToXRenderColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
801 double rd, gd, bd, ad;
802 XRenderColor ret;
803 rd = r / 255.0;
804 gd = g / 255.0;
805 bd = b / 255.0;
806 ad = a / 255.0;
807
808 ret.red = (unsigned short) (rd * ad * 0xFFFF);
809 ret.green = (unsigned short) (gd * ad * 0xFFFF);
810 ret.blue = (unsigned short) (bd * ad * 0xFFFF);
811 ret.alpha = (unsigned short) (ad * 0xFFFF);
812
813 return ret;
790 } 814 }
791 #endif 815 #endif
792 816
793 static int 817 static int
794 X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) 818 X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
963 if (!data->picture) { 987 if (!data->picture) {
964 X11_DestroyTexture(renderer, texture); 988 X11_DestroyTexture(renderer, texture);
965 SDL_SetError("XRenderCreatePicture() failed"); 989 SDL_SetError("XRenderCreatePicture() failed");
966 return -1; 990 return -1;
967 } 991 }
992 data->modulated_pixmap =
993 XCreatePixmap(renderdata->display, renderdata->xwindow,
994 texture->w, texture->h, data->depth);
995 if (!data->modulated_pixmap) {
996 X11_DestroyTexture(renderer, texture);
997 SDL_SetError("XCreatePixmap() failed");
998 return -1;
999 }
1000 data->modulated_picture =
1001 XRenderCreatePicture(renderdata->display, data->modulated_pixmap,
1002 data->picture_fmt, 0, NULL);
1003 if (!data->modulated_picture) {
1004 X11_DestroyTexture(renderer, texture);
1005 SDL_SetError("XRenderCreatePicture() failed");
1006 return -1;
1007 }
968 texture->blendMode = SDL_BLENDMODE_NONE; 1008 texture->blendMode = SDL_BLENDMODE_NONE;
969 data->blend_op = PictOpSrc; 1009 data->blend_op = PictOpSrc;
970 } 1010 }
971 #endif 1011 #endif
972 return 0; 1012 return 0;
982 return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch); 1022 return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch);
983 } else { 1023 } else {
984 *pixels = data->pixels; 1024 *pixels = data->pixels;
985 *pitch = data->pitch; 1025 *pitch = data->pitch;
986 return 0; 1026 return 0;
1027 }
1028 }
1029
1030 static int
1031 X11_SetTextureRGBAMod(SDL_Renderer * renderer, SDL_Texture * texture)
1032 {
1033
1034 X11_TextureData *data = (X11_TextureData *) texture->driverdata;
1035 X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata;
1036
1037 if (renderdata->use_xrender) {
1038
1039 Uint8 r = 0xFF, g = 0xFF, b = 0xFF, a = 0xFF;
1040
1041 if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
1042 a = texture->a;
1043 }
1044
1045 if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
1046 r = texture->r;
1047 g = texture->g;
1048 b = texture->b;
1049 }
1050
1051 if (texture->modMode != SDL_TEXTUREMODULATE_NONE) {
1052 XRenderColor mod_color =
1053 SDLColorToXRenderColor(r, g, b, a);
1054 XRenderFillRectangle(renderdata->display, PictOpSrc,
1055 renderdata->brush_pict, &mod_color,
1056 0, 0, 1, 1);
1057 }
1058
1059 XRenderPictureAttributes attr;
1060 if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
1061 attr.component_alpha = True;
1062 XRenderChangePicture(renderdata->display, renderdata->brush_pict,
1063 CPComponentAlpha, &attr);
1064 }
1065
1066 if (texture->modMode != SDL_TEXTUREMODULATE_NONE) {
1067 XRenderComposite(renderdata->display, PictOpSrc,
1068 data->picture, renderdata->brush_pict,
1069 data->modulated_picture,
1070 0, 0, 0, 0, 0, 0, texture->w, texture->h);
1071 }
1072
1073 if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
1074 attr.component_alpha = False;
1075 XRenderChangePicture(renderdata->display, renderdata->brush_pict,
1076 CPComponentAlpha, &attr);
1077 }
1078
1079 return 0;
1080 }
1081 else {
1082 SDL_Unsupported();
1083 return -1;
987 } 1084 }
988 } 1085 }
989 1086
990 static int 1087 static int
991 X11_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) 1088 X11_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
1201 } 1298 }
1202 1299
1203 static XRenderColor 1300 static XRenderColor
1204 xrenderdrawcolor(SDL_Renderer *renderer) 1301 xrenderdrawcolor(SDL_Renderer *renderer)
1205 { 1302 {
1206 // Premultiply the color channels as well as modulate them to a 16 bit color space
1207 XRenderColor xrender_color; 1303 XRenderColor xrender_color;
1208 double alphad; 1304 if(renderer->blendMode == SDL_BLENDMODE_NONE) {
1209 if(renderer->blendMode == SDL_BLENDMODE_NONE) 1305 xrender_color =
1210 alphad = 1.0; 1306 SDLColorToXRenderColor(renderer->r, renderer->g, renderer->b, 0xFF);
1211 else 1307 }
1212 alphad = (renderer->a) / 255.0; 1308 else {
1213 1309 xrender_color =
1214 xrender_color.alpha = (unsigned short) ((renderer->a / 255.0) * 0xFFFF); 1310 SDLColorToXRenderColor(renderer->r, renderer->g, renderer->b, renderer->a);
1215 1311 }
1216 xrender_color.red =
1217 (unsigned short) ((renderer->r / 255.0) * alphad * 0xFFFF);
1218 xrender_color.green =
1219 (unsigned short) ((renderer->g / 255.0) * alphad * 0xFFFF);
1220 xrender_color.blue =
1221 (unsigned short) ((renderer->b / 255.0) * alphad * 0xFFFF);
1222
1223 return xrender_color; 1312 return xrender_color;
1224 } 1313 }
1225 1314
1226 static int 1315 static int
1227 X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, 1316 X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
1756 texturedata->image, srcrect->x, srcrect->y, srcrect->x, 1845 texturedata->image, srcrect->x, srcrect->y, srcrect->x,
1757 srcrect->y, srcrect->w, srcrect->h); 1846 srcrect->y, srcrect->w, srcrect->h);
1758 } 1847 }
1759 XSync(data->display, False); 1848 XSync(data->display, False);
1760 } 1849 }
1761 Picture mask; 1850 Picture src, mask;
1762 XRenderPictureAttributes attr; 1851 XRenderPictureAttributes attr;
1763 const SDL_Rect *mrect; 1852 const SDL_Rect *mrect;
1853
1854 if (texture->modMode == SDL_TEXTUREMODULATE_NONE) {
1855 src = texturedata->picture;
1856 }
1857 else {
1858 src = texturedata->modulated_picture;
1859 }
1860
1764 if(texture->blendMode == SDL_BLENDMODE_NONE) 1861 if(texture->blendMode == SDL_BLENDMODE_NONE)
1765 { 1862 {
1766 mask = None; 1863 mask = None;
1767 mrect = srcrect; 1864 mrect = srcrect;
1768 } 1865 }
1774 else 1871 else
1775 { 1872 {
1776 mask = texturedata->picture; 1873 mask = texturedata->picture;
1777 mrect = srcrect; 1874 mrect = srcrect;
1778 } 1875 }
1876
1779 if(srcrect->w == dstrect->w && srcrect->h == dstrect->h) { 1877 if(srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
1780 if (texture->blendMode == SDL_BLENDMODE_MOD) { 1878 if (texture->blendMode == SDL_BLENDMODE_MOD) {
1781 XRenderComposite(data->display, PictOpSrc, data->drawable_pict, 1879 XRenderComposite(data->display, PictOpSrc, data->drawable_pict,
1782 texturedata->picture, data->stencil_pict, 1880 src, data->stencil_pict,
1783 dstrect->x, dstrect->y, srcrect->x, srcrect->y, 1881 dstrect->x, dstrect->y, srcrect->x, srcrect->y,
1784 dstrect->x, dstrect->y, dstrect->w, dstrect->h); 1882 dstrect->x, dstrect->y, dstrect->w, dstrect->h);
1785 attr.component_alpha = True; 1883 attr.component_alpha = True;
1786 XRenderChangePicture(data->display, data->stencil_pict, 1884 XRenderChangePicture(data->display, data->stencil_pict,
1787 CPComponentAlpha, &attr); 1885 CPComponentAlpha, &attr);
1788 } 1886 }
1789 XRenderComposite(data->display, texturedata->blend_op, texturedata->picture, 1887 XRenderComposite(data->display, texturedata->blend_op,
1790 mask, data->drawable_pict, srcrect->x, srcrect->y, 1888 src, mask, data->drawable_pict, srcrect->x, srcrect->y,
1791 mrect->x, mrect->y, dstrect->x, dstrect->y, 1889 mrect->x, mrect->y, dstrect->x, dstrect->y,
1792 dstrect->w, dstrect->h); 1890 dstrect->w, dstrect->h);
1793 } else { 1891 } else {
1794 double xscale = ((double) dstrect->w) / srcrect->w; 1892 double xscale = ((double) dstrect->w) / srcrect->w;
1795 double yscale = ((double) dstrect->h) / srcrect->h; 1893 double yscale = ((double) dstrect->h) / srcrect->h;
1796 XTransform xform = {{ 1894 XTransform xform = {{
1797 {XDoubleToFixed(xscale), XDoubleToFixed(0), XDoubleToFixed(0)}, 1895 {XDoubleToFixed(xscale), XDoubleToFixed(0), XDoubleToFixed(0)},
1798 {XDoubleToFixed(0), XDoubleToFixed(yscale), XDoubleToFixed(0)}, 1896 {XDoubleToFixed(0), XDoubleToFixed(yscale), XDoubleToFixed(0)},
1799 {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(xscale * yscale)}}}; 1897 {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(xscale * yscale)}}};
1800 XRenderSetPictureTransform(data->display, texturedata->picture, &xform); 1898 XRenderSetPictureTransform(data->display, src, &xform);
1801 1899
1802 if (texture->blendMode == SDL_BLENDMODE_MOD) { 1900 if (texture->blendMode == SDL_BLENDMODE_MOD) {
1803 XRenderComposite(data->display, PictOpSrc, data->drawable_pict, 1901 XRenderComposite(data->display, PictOpSrc, data->drawable_pict,
1804 texturedata->picture, data->stencil_pict, 1902 src, data->stencil_pict,
1805 dstrect->x, dstrect->y, srcrect->x, srcrect->y, 1903 dstrect->x, dstrect->y, srcrect->x, srcrect->y,
1806 dstrect->x, dstrect->y, dstrect->w, dstrect->h); 1904 dstrect->x, dstrect->y, dstrect->w, dstrect->h);
1807 attr.component_alpha = True; 1905 attr.component_alpha = True;
1808 XRenderChangePicture(data->display, data->stencil_pict, 1906 XRenderChangePicture(data->display, data->stencil_pict,
1809 CPComponentAlpha, &attr); 1907 CPComponentAlpha, &attr);
1810 } 1908 }
1811 1909
1812 XRenderSetPictureFilter(data->display, texturedata->picture, 1910 XRenderSetPictureFilter(data->display, src,
1813 texturedata->filter, 0, 0); 1911 texturedata->filter, 0, 0);
1814 1912
1815 XRenderComposite(data->display, texturedata->blend_op, 1913 XRenderComposite(data->display, texturedata->blend_op,
1816 texturedata->picture, mask, data->drawable_pict, 1914 src, mask, data->drawable_pict,
1817 srcrect->x, srcrect->y, mrect->x, mrect->y, 1915 srcrect->x, srcrect->y, mrect->x, mrect->y,
1818 dstrect->x, dstrect->y, dstrect->w, dstrect->h); 1916 dstrect->x, dstrect->y, dstrect->w, dstrect->h);
1819 1917
1820 XTransform identity = {{ 1918 XTransform identity = {{
1821 {XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0)}, 1919 {XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0)},
1822 {XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0)}, 1920 {XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0)},
1823 {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1)}}}; 1921 {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1)}}};
1824 XRenderSetPictureTransform(data->display, texturedata->picture, &identity); 1922 XRenderSetPictureTransform(data->display, src, &identity);
1825 } 1923 }
1826 if (renderer->blendMode == SDL_BLENDMODE_MOD) { 1924 if (renderer->blendMode == SDL_BLENDMODE_MOD) {
1827 attr.component_alpha = False; 1925 attr.component_alpha = False;
1828 XRenderChangePicture(data->display, data->stencil_pict, 1926 XRenderChangePicture(data->display, data->stencil_pict,
1829 CPComponentAlpha, &attr); 1927 CPComponentAlpha, &attr);
2079 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER 2177 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER
2080 if (renderdata->use_xrender) { 2178 if (renderdata->use_xrender) {
2081 if (data->picture) { 2179 if (data->picture) {
2082 XRenderFreePicture(renderdata->display, data->picture); 2180 XRenderFreePicture(renderdata->display, data->picture);
2083 } 2181 }
2182 if (data->modulated_pixmap) {
2183 XFreePixmap(renderdata->display, data->modulated_pixmap);
2184 }
2185 if (data->modulated_picture) {
2186 XRenderFreePicture(renderdata->display, data->modulated_picture);
2187 }
2084 } 2188 }
2085 #endif 2189 #endif
2086 if (data->scaling_image) { 2190 if (data->scaling_image) {
2087 SDL_free(data->scaling_image->data); 2191 SDL_free(data->scaling_image->data);
2088 data->scaling_image->data = NULL; 2192 data->scaling_image->data = NULL;