comparison src/video/directfb/SDL_DirectFB_render.c @ 2884:9dde605c7540

Date: Fri, 19 Dec 2008 20:17:35 +0100 From: Couriersud Subject: Re: Aw: Experience using SDL1.3 in sdlmame/Proposal for api additions > For consistency you'd probably want: > SDL_SetRenderDrawColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a); > SDL_SetRenderDrawBlendMode(SDL_BlendMode blendMode); > SDL_RenderLine(int x1, int y1, int x2, int y2); > SDL_RenderFill(SDL_Rect *rect); > > You probably also want to add API functions query the current state. > I have implemented the above api for the opengl, x11, directfb and software renderers. I have also renamed *TEXTUREBLENDMODE* constants to BLENDMODE*. The unix build compiles. The windows renderer still needs to be updated, but I have no windows development machine at hand. Have a look at the x11 renderer for a sample. Vector games now run at 90% both on opengl and directfb in comparison to sdlmame's own opengl renderer. The same applies to raster games. The diff also includes a) Changed XDrawRect to XFillRect in x11 renderer b) A number of changes to fix blending and modulation issues in the directfb renderer.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 20 Dec 2008 12:00:00 +0000
parents 99210400e8b9
children 133601e3b255
comparison
equal deleted inserted replaced
2883:11626a53e7bc 2884:9dde605c7540
69 static void DirectFB_UnlockTexture(SDL_Renderer * renderer, 69 static void DirectFB_UnlockTexture(SDL_Renderer * renderer,
70 SDL_Texture * texture); 70 SDL_Texture * texture);
71 static void DirectFB_DirtyTexture(SDL_Renderer * renderer, 71 static void DirectFB_DirtyTexture(SDL_Renderer * renderer,
72 SDL_Texture * texture, int numrects, 72 SDL_Texture * texture, int numrects,
73 const SDL_Rect * rects); 73 const SDL_Rect * rects);
74 static int DirectFB_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, 74 static int DirectFB_SetDrawColor(SDL_Renderer * renderer);
75 Uint8 b, Uint8 a, const SDL_Rect * rect); 75 static int DirectFB_SetDrawBlendMode(SDL_Renderer * renderer);
76 static int DirectFB_RenderLine(SDL_Renderer * renderer, int x1, int y1,
77 int x2, int y2);
78 static int DirectFB_RenderFill(SDL_Renderer * renderer,
79 const SDL_Rect * rect);
76 static int DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 80 static int DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
77 const SDL_Rect * srcrect, 81 const SDL_Rect * srcrect,
78 const SDL_Rect * dstrect); 82 const SDL_Rect * dstrect);
79 static void DirectFB_RenderPresent(SDL_Renderer * renderer); 83 static void DirectFB_RenderPresent(SDL_Renderer * renderer);
80 static void DirectFB_DestroyTexture(SDL_Renderer * renderer, 84 static void DirectFB_DestroyTexture(SDL_Renderer * renderer,
89 SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 | 93 SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
90 SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_PRESENTDISCARD | 94 SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_PRESENTDISCARD |
91 SDL_RENDERER_ACCELERATED), 95 SDL_RENDERER_ACCELERATED),
92 (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR | 96 (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
93 SDL_TEXTUREMODULATE_ALPHA), 97 SDL_TEXTUREMODULATE_ALPHA),
94 (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK | 98 (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK |
95 SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_ADD | 99 SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD),
96 SDL_TEXTUREBLENDMODE_MOD),
97 (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST | 100 (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST |
98 SDL_TEXTURESCALEMODE_SLOW | SDL_TEXTURESCALEMODE_BEST), 101 SDL_TEXTURESCALEMODE_SLOW | SDL_TEXTURESCALEMODE_BEST),
99 14, 102 14,
100 { 103 {
101 SDL_PIXELFORMAT_INDEX4LSB, 104 SDL_PIXELFORMAT_INDEX4LSB,
120 { 123 {
121 IDirectFBSurface *surface; 124 IDirectFBSurface *surface;
122 DFBSurfaceFlipFlags flipflags; 125 DFBSurfaceFlipFlags flipflags;
123 int isyuvdirect; 126 int isyuvdirect;
124 int size_changed; 127 int size_changed;
128 int lastBlendMode;
129 DFBSurfaceBlittingFlags blitFlags;
130 DFBSurfaceDrawingFlags drawFlags;
125 } DirectFB_RenderData; 131 } DirectFB_RenderData;
126 132
127 typedef struct 133 typedef struct
128 { 134 {
129 IDirectFBSurface *surface; 135 IDirectFBSurface *surface;
143 { 149 {
144 dr->x = sr->x; 150 dr->x = sr->x;
145 dr->y = sr->y; 151 dr->y = sr->y;
146 dr->h = sr->h; 152 dr->h = sr->h;
147 dr->w = sr->w; 153 dr->w = sr->w;
154 }
155
156
157 static int
158 TextureHasAlpha(DirectFB_TextureData * data)
159 {
160 /* Drawing primitive ? */
161 if (!data)
162 return 0;
163 switch (data->format) {
164 case SDL_PIXELFORMAT_INDEX4LSB:
165 case SDL_PIXELFORMAT_ARGB4444:
166 case SDL_PIXELFORMAT_ARGB1555:
167 case SDL_PIXELFORMAT_ARGB8888:
168 case SDL_PIXELFORMAT_RGBA8888:
169 case SDL_PIXELFORMAT_ABGR8888:
170 case SDL_PIXELFORMAT_BGRA8888:
171 case SDL_PIXELFORMAT_ARGB2101010:
172 return 1;
173 default:
174 return 0;
175 }
176 }
177
178 static void
179 SetBlendMode(DirectFB_RenderData * data, int blendMode,
180 DirectFB_TextureData * source)
181 {
182 //FIXME: check for format change
183 if (1 || data->lastBlendMode != blendMode) {
184 switch (blendMode) {
185 case SDL_BLENDMODE_NONE:
186 /**< No blending */
187 data->blitFlags = DSBLIT_NOFX;
188 data->drawFlags = DSDRAW_NOFX;
189 data->surface->SetSrcBlendFunction(data->surface, DSBF_ONE);
190 data->surface->SetDstBlendFunction(data->surface, DSBF_ZERO);
191 break;
192 case SDL_BLENDMODE_MASK:
193 data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
194 data->drawFlags = DSDRAW_BLEND;
195 data->surface->SetSrcBlendFunction(data->surface, DSBF_SRCALPHA);
196 data->surface->SetDstBlendFunction(data->surface,
197 DSBF_INVSRCALPHA);
198 break;
199 case SDL_BLENDMODE_BLEND:
200 data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
201 data->drawFlags = DSDRAW_BLEND;
202 data->surface->SetSrcBlendFunction(data->surface, DSBF_SRCALPHA);
203 data->surface->SetDstBlendFunction(data->surface,
204 DSBF_INVSRCALPHA);
205 break;
206 case SDL_BLENDMODE_ADD:
207 data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
208 data->drawFlags = DSDRAW_BLEND;
209 //FIXME: SRCALPHA kills performance on radeon ...
210 //Eventually use a premultiplied texture
211 if (0 && TextureHasAlpha(source))
212 data->surface->SetSrcBlendFunction(data->surface,
213 DSBF_SRCALPHA);
214 else
215 data->surface->SetSrcBlendFunction(data->surface, DSBF_ONE);
216 data->surface->SetDstBlendFunction(data->surface, DSBF_ONE);
217 break;
218 case SDL_BLENDMODE_MOD:
219 data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
220 data->drawFlags = DSDRAW_BLEND;
221 data->surface->SetSrcBlendFunction(data->surface, DSBF_DESTCOLOR);
222 data->surface->SetDstBlendFunction(data->surface, DSBF_ZERO);
223 break;
224 }
225 data->lastBlendMode = blendMode;
226 }
148 } 227 }
149 228
150 void 229 void
151 DirectFB_AddRenderDriver(_THIS) 230 DirectFB_AddRenderDriver(_THIS)
152 { 231 {
212 renderer->SetTextureScaleMode = DirectFB_SetTextureScaleMode; 291 renderer->SetTextureScaleMode = DirectFB_SetTextureScaleMode;
213 renderer->UpdateTexture = DirectFB_UpdateTexture; 292 renderer->UpdateTexture = DirectFB_UpdateTexture;
214 renderer->LockTexture = DirectFB_LockTexture; 293 renderer->LockTexture = DirectFB_LockTexture;
215 renderer->UnlockTexture = DirectFB_UnlockTexture; 294 renderer->UnlockTexture = DirectFB_UnlockTexture;
216 renderer->DirtyTexture = DirectFB_DirtyTexture; 295 renderer->DirtyTexture = DirectFB_DirtyTexture;
296 renderer->SetDrawColor = DirectFB_SetDrawColor;
297 renderer->SetDrawBlendMode = DirectFB_SetDrawBlendMode;
298 renderer->RenderLine = DirectFB_RenderLine;
217 renderer->RenderFill = DirectFB_RenderFill; 299 renderer->RenderFill = DirectFB_RenderFill;
218 renderer->RenderCopy = DirectFB_RenderCopy; 300 renderer->RenderCopy = DirectFB_RenderCopy;
219 renderer->RenderPresent = DirectFB_RenderPresent; 301 renderer->RenderPresent = DirectFB_RenderPresent;
220 renderer->DestroyTexture = DirectFB_DestroyTexture; 302 renderer->DestroyTexture = DirectFB_DestroyTexture;
221 renderer->DestroyRenderer = DirectFB_DestroyRenderer; 303 renderer->DestroyRenderer = DirectFB_DestroyRenderer;
302 case SDL_PIXELFORMAT_INDEX1MSB: 384 case SDL_PIXELFORMAT_INDEX1MSB:
303 return DSPF_UNKNOWN; 385 return DSPF_UNKNOWN;
304 case SDL_PIXELFORMAT_INDEX4MSB: 386 case SDL_PIXELFORMAT_INDEX4MSB:
305 return DSPF_UNKNOWN; 387 return DSPF_UNKNOWN;
306 case SDL_PIXELFORMAT_RGB444: 388 case SDL_PIXELFORMAT_RGB444:
389 #if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 2)
390 return DSPF_RGB444;
391 #else
307 return DSPF_UNKNOWN; 392 return DSPF_UNKNOWN;
393 #endif
308 case SDL_PIXELFORMAT_BGR24: 394 case SDL_PIXELFORMAT_BGR24:
309 return DSPF_UNKNOWN; 395 return DSPF_UNKNOWN;
310 case SDL_PIXELFORMAT_BGR888: 396 case SDL_PIXELFORMAT_BGR888:
311 return DSPF_UNKNOWN; 397 return DSPF_UNKNOWN;
312 case SDL_PIXELFORMAT_RGBA8888: 398 case SDL_PIXELFORMAT_RGBA8888:
574 660
575 static int 661 static int
576 DirectFB_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) 662 DirectFB_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
577 { 663 {
578 switch (texture->blendMode) { 664 switch (texture->blendMode) {
579 case SDL_TEXTUREBLENDMODE_NONE: 665 case SDL_BLENDMODE_NONE:
580 case SDL_TEXTUREBLENDMODE_MASK: 666 case SDL_BLENDMODE_MASK:
581 case SDL_TEXTUREBLENDMODE_BLEND: 667 case SDL_BLENDMODE_BLEND:
582 case SDL_TEXTUREBLENDMODE_ADD: 668 case SDL_BLENDMODE_ADD:
583 case SDL_TEXTUREBLENDMODE_MOD: 669 case SDL_BLENDMODE_MOD:
584 return 0; 670 return 0;
585 default: 671 default:
586 SDL_Unsupported(); 672 SDL_Unsupported();
587 texture->blendMode = SDL_TEXTUREBLENDMODE_NONE; 673 texture->blendMode = SDL_BLENDMODE_NONE;
588 return -1; 674 return -1;
589 } 675 }
590 } 676 }
591 677
592 static int 678 static int
708 SDL_AddDirtyRect(&data->dirty, &rects[i]); 794 SDL_AddDirtyRect(&data->dirty, &rects[i]);
709 } 795 }
710 } 796 }
711 797
712 static int 798 static int
713 DirectFB_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b, 799 DirectFB_SetDrawColor(SDL_Renderer * renderer)
714 Uint8 a, const SDL_Rect * rect) 800 {
801 return 0;
802 }
803
804 static int
805 DirectFB_SetDrawBlendMode(SDL_Renderer * renderer)
806 {
807 return 0;
808 }
809
810 static int
811 PrepareDraw(SDL_Renderer * renderer)
715 { 812 {
716 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; 813 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
717 DFBResult ret; 814 DFBResult ret;
815 Uint8 r, g, b, a;
816
817 r = renderer->r;
818 g = renderer->g;
819 b = renderer->b;
820 a = renderer->a;
821
822 SetBlendMode(data, renderer->blendMode, NULL);
823 SDL_DFB_CHECKERR(data->surface->
824 SetDrawingFlags(data->surface, data->drawFlags));
825
826 switch (renderer->blendMode) {
827 case SDL_BLENDMODE_NONE:
828 case SDL_BLENDMODE_MASK:
829 case SDL_BLENDMODE_BLEND:
830 break;
831 case SDL_BLENDMODE_ADD:
832 case SDL_BLENDMODE_MOD:
833 r = ((int) r * (int) a) / 255;
834 g = ((int) g * (int) a) / 255;
835 b = ((int) b * (int) a) / 255;
836 a = 255;
837 break;
838 }
718 839
719 SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, r, g, b, a)); 840 SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, r, g, b, a));
841 return 0;
842 error:
843 return -1;
844 }
845
846 static int
847 DirectFB_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
848 {
849 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
850 DFBResult ret;
851
852 PrepareDraw(renderer);
853 SDL_DFB_CHECKERR(data->surface->DrawLine(data->surface, x1, y1, x2, y2));
854 return 0;
855 error:
856 return -1;
857 }
858
859 static int
860 DirectFB_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect)
861 {
862 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
863 DFBResult ret;
864
865 PrepareDraw(renderer);
720 SDL_DFB_CHECKERR(data->surface-> 866 SDL_DFB_CHECKERR(data->surface->
721 FillRectangle(data->surface, rect->x, rect->y, rect->w, 867 FillRectangle(data->surface, rect->x, rect->y, rect->w,
722 rect->h)); 868 rect->h));
723 869
724 return 0; 870 return 0;
731 const SDL_Rect * srcrect, const SDL_Rect * dstrect) 877 const SDL_Rect * srcrect, const SDL_Rect * dstrect)
732 { 878 {
733 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; 879 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
734 DirectFB_TextureData *texturedata = 880 DirectFB_TextureData *texturedata =
735 (DirectFB_TextureData *) texture->driverdata; 881 (DirectFB_TextureData *) texture->driverdata;
882 Uint8 alpha = 0xFF;
736 DFBResult ret; 883 DFBResult ret;
737 884
738 if (texturedata->display) { 885 if (texturedata->display) {
739 int px, py; 886 int px, py;
740 SDL_Window *window = SDL_GetWindowFromID(renderer->window); 887 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
770 texturedata->pixels, 917 texturedata->pixels,
771 texturedata->pitch); 918 texturedata->pitch);
772 } 919 }
773 SDL_ClearDirtyRects(&texturedata->dirty); 920 SDL_ClearDirtyRects(&texturedata->dirty);
774 } 921 }
922
923 SDLtoDFBRect(srcrect, &sr);
924 SDLtoDFBRect(dstrect, &dr);
925
926 SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, 0xFF,
927 0xFF, 0xFF, 0xFF));
928 if (texture->
929 modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA))
930 {
931 if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
932 alpha = texture->a;
933 SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, 0xFF,
934 0xFF, 0xFF, alpha));
935 }
936 if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
937
938 SDL_DFB_CHECKERR(data->surface->
939 SetColor(data->surface, texture->r,
940 texture->g, texture->b, alpha));
941 flags |= DSBLIT_COLORIZE;
942 }
943 if (alpha < 0xFF)
944 flags |= DSBLIT_SRC_PREMULTCOLOR;
945 } else
946 SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, 0xFF,
947 0xFF, 0xFF, 0xFF));
948
949 SetBlendMode(data, texture->blendMode, texturedata);
950
951 SDL_DFB_CHECKERR(data->surface->
952 SetBlittingFlags(data->surface,
953 data->blitFlags | flags));
954
775 #if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 2) 955 #if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 2)
776 SDL_DFB_CHECKERR(data->surface->SetRenderOptions(data->surface, 956 SDL_DFB_CHECKERR(data->surface->SetRenderOptions(data->surface,
777 texturedata-> 957 texturedata->
778 render_options)); 958 render_options));
779 #endif 959 #endif
780
781 SDLtoDFBRect(srcrect, &sr);
782 SDLtoDFBRect(dstrect, &dr);
783
784 if (texture->
785 modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA))
786 {
787 Uint8 alpha = 0xFF;
788 if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
789 alpha = texture->a;
790 flags |= DSBLIT_SRC_PREMULTCOLOR;
791 SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, 0xFF,
792 0xFF, 0xFF, alpha));
793 }
794 if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
795 SDL_DFB_CHECKERR(data->surface->
796 SetColor(data->surface, texture->r,
797 texture->g, texture->b, alpha));
798 /* Only works together .... */
799 flags |= DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR;
800 }
801 }
802
803 switch (texture->blendMode) {
804 case SDL_TEXTUREBLENDMODE_NONE:
805 /**< No blending */
806 flags |= DSBLIT_NOFX;
807 data->surface->SetSrcBlendFunction(data->surface, DSBF_ONE);
808 data->surface->SetDstBlendFunction(data->surface, DSBF_ZERO);
809 break;
810 case SDL_TEXTUREBLENDMODE_MASK:
811 flags |= DSBLIT_BLEND_ALPHACHANNEL;
812 data->surface->SetSrcBlendFunction(data->surface, DSBF_SRCALPHA);
813 data->surface->SetDstBlendFunction(data->surface,
814 DSBF_INVSRCALPHA);
815 break;
816 case SDL_TEXTUREBLENDMODE_BLEND:
817 flags |= DSBLIT_BLEND_ALPHACHANNEL;
818 data->surface->SetSrcBlendFunction(data->surface, DSBF_SRCALPHA);
819 data->surface->SetDstBlendFunction(data->surface,
820 DSBF_INVSRCALPHA);
821 break;
822 case SDL_TEXTUREBLENDMODE_ADD:
823 flags |= DSBLIT_BLEND_ALPHACHANNEL;
824 data->surface->SetSrcBlendFunction(data->surface, DSBF_SRCALPHA);
825 data->surface->SetDstBlendFunction(data->surface, DSBF_ONE);
826 break;
827 case SDL_TEXTUREBLENDMODE_MOD:
828 flags |= DSBLIT_BLEND_ALPHACHANNEL;
829 data->surface->SetSrcBlendFunction(data->surface, DSBF_DESTCOLOR);
830 data->surface->SetDstBlendFunction(data->surface, DSBF_ZERO);
831 break;
832 }
833
834 SDL_DFB_CHECKERR(data->surface->
835 SetBlittingFlags(data->surface, flags));
836 960
837 if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) { 961 if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
838 SDL_DFB_CHECKERR(data->surface-> 962 SDL_DFB_CHECKERR(data->surface->
839 Blit(data->surface, texturedata->surface, 963 Blit(data->surface, texturedata->surface,
840 &sr, dr.x, dr.y)); 964 &sr, dr.x, dr.y));