comparison src/video/directfb/SDL_DirectFB_render.c @ 2226:0e70b4b8cf84

Date: Sat, 11 Aug 2007 02:03:16 +0200 (CEST) From: couriersud arcor.de To: slouken@libsdl.org Subject: Directfb driver for SDL1.3 Hi, the attachment contains a patch for a SDL1.3 directfb driver. It supports: - Renderer "directfb": Hardware acceleration as supported by the underlying directfb driver. With a radeon X850, testsprite2 runs at 50% to 70% of OpenGL (X11, dri) performance. Also supports hardware accelerated yuv overlays. This must be enabled by sett ing: export SDL_DIRECTFB_YUV_DIRECT=1 - Renderer "opengl" Supports software opengl using mesa opengl (make linux-directfb). Some more information may be found in README.DirectFB There will certainly still be some bugs, and there is some debug code around. When I find some time, I will compile against directfb-0.9.25 as distributed with ubuntu 7.04. The diff also contains a fix for SDL_LockYUVOverlay fixing a bug in *pixels and pitches initialization. Kind regards, couriersud
author Sam Lantinga <slouken@libsdl.org>
date Sat, 11 Aug 2007 21:51:19 +0000
parents
children 4932f192c565
comparison
equal deleted inserted replaced
2225:3bca1b7ca25b 2226:0e70b4b8cf84
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2006 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21
22 SDL1.3 implementation by couriersud@arcor.de
23
24 */
25 #include "SDL_config.h"
26
27 #include "SDL_DirectFB_video.h"
28 #include "SDL_DirectFB_render.h"
29 #include "../SDL_rect_c.h"
30 #include "../SDL_yuv_sw_c.h"
31
32 /* GDI renderer implementation */
33
34 static SDL_Renderer *DirectFB_CreateRenderer(SDL_Window * window,
35 Uint32 flags);
36 static int DirectFB_DisplayModeChanged(SDL_Renderer * renderer);
37 static int DirectFB_CreateTexture(SDL_Renderer * renderer,
38 SDL_Texture * texture);
39 static int DirectFB_QueryTexturePixels(SDL_Renderer * renderer,
40 SDL_Texture * texture, void **pixels,
41 int *pitch);
42 static int DirectFB_SetTexturePalette(SDL_Renderer * renderer,
43 SDL_Texture * texture,
44 const SDL_Color * colors,
45 int firstcolor, int ncolors);
46 static int DirectFB_GetTexturePalette(SDL_Renderer * renderer,
47 SDL_Texture * texture,
48 SDL_Color * colors, int firstcolor,
49 int ncolors);
50 static int DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer,
51 SDL_Texture * texture);
52 static int DirectFB_SetTextureColorMod(SDL_Renderer * renderer,
53 SDL_Texture * texture);
54 static int DirectFB_SetTextureBlendMode(SDL_Renderer * renderer,
55 SDL_Texture * texture);
56 static int DirectFB_SetTextureScaleMode(SDL_Renderer * renderer,
57 SDL_Texture * texture);
58 static int DirectFB_UpdateTexture(SDL_Renderer * renderer,
59 SDL_Texture * texture,
60 const SDL_Rect * rect, const void *pixels,
61 int pitch);
62 static int DirectFB_LockTexture(SDL_Renderer * renderer,
63 SDL_Texture * texture, const SDL_Rect * rect,
64 int markDirty, void **pixels, int *pitch);
65 static void DirectFB_UnlockTexture(SDL_Renderer * renderer,
66 SDL_Texture * texture);
67 static void DirectFB_DirtyTexture(SDL_Renderer * renderer,
68 SDL_Texture * texture, int numrects,
69 const SDL_Rect * rects);
70 static int DirectFB_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g,
71 Uint8 b, Uint8 a, const SDL_Rect * rect);
72 static int DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
73 const SDL_Rect * srcrect,
74 const SDL_Rect * dstrect);
75 static void DirectFB_RenderPresent(SDL_Renderer * renderer);
76 static void DirectFB_DestroyTexture(SDL_Renderer * renderer,
77 SDL_Texture * texture);
78 static void DirectFB_DestroyRenderer(SDL_Renderer * renderer);
79
80 SDL_RenderDriver DirectFB_RenderDriver = {
81 DirectFB_CreateRenderer,
82 {
83 "directfb",
84 (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
85 SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
86 SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED),
87 (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
88 SDL_TEXTUREMODULATE_ALPHA),
89 (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK |
90 SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_MOD),
91 (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST),
92 14,
93 {
94 SDL_PIXELFORMAT_INDEX8,
95 SDL_PIXELFORMAT_INDEX4LSB,
96 SDL_PIXELFORMAT_RGB332,
97 SDL_PIXELFORMAT_RGB555,
98 SDL_PIXELFORMAT_RGB565,
99 SDL_PIXELFORMAT_RGB888,
100 SDL_PIXELFORMAT_ARGB8888,
101 SDL_PIXELFORMAT_ARGB4444,
102 SDL_PIXELFORMAT_ARGB1555,
103 SDL_PIXELFORMAT_RGB24,
104 SDL_PIXELFORMAT_YV12,
105 SDL_PIXELFORMAT_IYUV,
106 SDL_PIXELFORMAT_YUY2,
107 SDL_PIXELFORMAT_UYVY},
108 0,
109 0}
110 };
111
112 typedef struct
113 {
114 IDirectFBSurface *surface;
115 DFBSurfaceFlipFlags flipflags;
116 int isyuvdirect;
117 } DirectFB_RenderData;
118
119 typedef struct
120 {
121 IDirectFBDisplayLayer *vidlayer;
122 IDirectFBSurface *surface;
123 Uint32 format;
124 void *pixels;
125 int pitch;
126 IDirectFBPalette *palette;
127 } DirectFB_TextureData;
128
129 static void
130 UpdateYUVTextureData(SDL_Texture * texture)
131 {
132 /*
133 * Not needed - directfb supports yuv surfaces
134 */
135 }
136
137 void
138 DirectFB_AddRenderDriver(_THIS)
139 {
140 int i;
141 for (i = 0; i < _this->num_displays; i++)
142 SDL_AddRenderDriver(i, &DirectFB_RenderDriver);
143 }
144
145 SDL_Renderer *
146 DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags)
147 {
148 SDL_DFB_WINDOWDATA(window);
149 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
150 SDL_DFB_DEVICEDATA(display->device);
151 SDL_Renderer *renderer = NULL;
152 DirectFB_RenderData *data = NULL;
153 DFBResult ret;
154 DFBSurfaceDescription dsc;
155 DFBSurfaceCapabilities scaps;
156 char *p;
157 int i, n;
158
159 SDL_DFB_CALLOC(renderer, 1, sizeof(*renderer));
160 SDL_DFB_CALLOC(data, 1, sizeof(*data));
161
162 renderer->DisplayModeChanged = DirectFB_DisplayModeChanged;
163 renderer->CreateTexture = DirectFB_CreateTexture;
164 renderer->QueryTexturePixels = DirectFB_QueryTexturePixels;
165 renderer->SetTexturePalette = DirectFB_SetTexturePalette;
166 renderer->GetTexturePalette = DirectFB_GetTexturePalette;
167 renderer->SetTextureAlphaMod = DirectFB_SetTextureAlphaMod;
168 renderer->SetTextureColorMod = DirectFB_SetTextureColorMod;
169 renderer->SetTextureBlendMode = DirectFB_SetTextureBlendMode;
170 renderer->SetTextureScaleMode = DirectFB_SetTextureScaleMode;
171 renderer->UpdateTexture = DirectFB_UpdateTexture;
172 renderer->LockTexture = DirectFB_LockTexture;
173 renderer->UnlockTexture = DirectFB_UnlockTexture;
174 renderer->DirtyTexture = DirectFB_DirtyTexture;
175 renderer->RenderFill = DirectFB_RenderFill;
176 renderer->RenderCopy = DirectFB_RenderCopy;
177 renderer->RenderPresent = DirectFB_RenderPresent;
178 renderer->DestroyTexture = DirectFB_DestroyTexture;
179 renderer->DestroyRenderer = DirectFB_DestroyRenderer;
180 renderer->info = DirectFB_RenderDriver.info;
181 renderer->window = window->id; // SDL window id
182 renderer->driverdata = data;
183
184 renderer->info.flags =
185 SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTDISCARD;
186
187 data->surface = windata->surface;
188 data->flipflags = 0;
189
190 if (flags & SDL_RENDERER_PRESENTVSYNC) {
191 data->flipflags = DSFLIP_ONSYNC;
192 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
193 }
194
195 data->surface->GetCapabilities(data->surface, &scaps);
196 if (scaps & DSCAPS_DOUBLE)
197 renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
198 else if (scaps & DSCAPS_TRIPLE)
199 renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
200 else
201 renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
202
203 data->isyuvdirect = 0;
204 p = getenv("SDL_DIRECTFB_YUV_DIRECT");
205 if (p)
206 data->isyuvdirect = atoi(p);
207
208 return renderer;
209
210 error:
211 SDL_DFB_FREE(renderer);
212 SDL_DFB_FREE(data);
213 return NULL;
214 }
215
216 static DFBSurfacePixelFormat
217 SDLToDFBPixelFormat(Uint32 format)
218 {
219 switch (format) {
220 case SDL_PIXELFORMAT_INDEX4LSB:
221 return DSPF_ALUT44;
222 case SDL_PIXELFORMAT_INDEX8:
223 return DSPF_LUT8;
224 case SDL_PIXELFORMAT_RGB332:
225 return DSPF_RGB332;
226 case SDL_PIXELFORMAT_RGB555:
227 return DSPF_ARGB1555;
228 case SDL_PIXELFORMAT_ARGB4444:
229 return DSPF_ARGB4444;
230 case SDL_PIXELFORMAT_ARGB1555:
231 return DSPF_ARGB1555;
232 case SDL_PIXELFORMAT_RGB565:
233 return DSPF_RGB16;
234 case SDL_PIXELFORMAT_RGB24:
235 return DSPF_RGB24;
236 case SDL_PIXELFORMAT_RGB888:
237 return DSPF_RGB32;
238 case SDL_PIXELFORMAT_ARGB8888:
239 return DSPF_ARGB;
240 case SDL_PIXELFORMAT_YV12:
241 return DSPF_YV12; /* Planar mode: Y + V + U (3 planes) */
242 case SDL_PIXELFORMAT_IYUV:
243 return DSPF_I420; /* Planar mode: Y + U + V (3 planes) */
244 case SDL_PIXELFORMAT_YUY2:
245 return DSPF_YUY2; /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
246 case SDL_PIXELFORMAT_UYVY:
247 return DSPF_UYVY; /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
248 case SDL_PIXELFORMAT_YVYU:
249 return DSPF_UNKNOWN; /* Packed mode: Y0+V0+Y1+U0 (1 plane) */
250 case SDL_PIXELFORMAT_INDEX1LSB:
251 return DSPF_UNKNOWN;
252 case SDL_PIXELFORMAT_INDEX1MSB:
253 return DSPF_UNKNOWN;
254 case SDL_PIXELFORMAT_INDEX4MSB:
255 return DSPF_UNKNOWN;
256 case SDL_PIXELFORMAT_RGB444:
257 return DSPF_UNKNOWN;
258 case SDL_PIXELFORMAT_BGR24:
259 return DSPF_UNKNOWN;
260 case SDL_PIXELFORMAT_BGR888:
261 return DSPF_UNKNOWN;
262 case SDL_PIXELFORMAT_RGBA8888:
263 return DSPF_UNKNOWN;
264 case SDL_PIXELFORMAT_ABGR8888:
265 return DSPF_UNKNOWN;
266 case SDL_PIXELFORMAT_BGRA8888:
267 return DSPF_UNKNOWN;
268 case SDL_PIXELFORMAT_ARGB2101010:
269 return DSPF_UNKNOWN;
270 default:
271 return DSPF_UNKNOWN;
272 }
273 }
274
275 static int
276 DirectFB_DisplayModeChanged(SDL_Renderer * renderer)
277 {
278 SDL_DFB_RENDERERDATA(renderer);
279 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
280 SDL_DFB_WINDOWDATA(window);
281 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
282 SDL_DFB_DEVICEDATA(display->device);
283 DFBResult ret;
284 DFBSurfaceDescription dsc;
285 int i, n;
286
287 /*
288 * Nothing to do here
289 */
290 return 0;
291 error:
292 return -1;
293 }
294
295 static int
296 DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
297 {
298 SDL_DFB_RENDERERDATA(renderer);
299 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
300 SDL_DFB_WINDOWDATA(window);
301 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
302 SDL_DFB_DEVICEDATA(display->device);
303 DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
304 DirectFB_TextureData *data;
305 DFBResult ret;
306 DFBSurfaceDescription dsc;
307 DFBDisplayLayerDescription laydsc;
308 DFBDisplayLayerConfig layconf;
309
310 SDL_DFB_CALLOC(data, 1, sizeof(*data));
311 texture->driverdata = data;
312
313 data->format = texture->format;
314 data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format));
315 data->vidlayer = NULL;
316 if (renddata->isyuvdirect && (dispdata->vidID >= 0)
317 && SDL_ISPIXELFORMAT_FOURCC(data->format)) {
318 SDL_DFB_CHECKERR(devdata->dfb->
319 GetDisplayLayer(devdata->dfb, dispdata->vidID,
320 &data->vidlayer));
321 layconf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
322 layconf.width = texture->w;
323 layconf.height = texture->h;
324 layconf.pixelformat = SDLToDFBPixelFormat(data->format);
325
326 SDL_DFB_CHECKERR(data->vidlayer->
327 SetCooperativeLevel(data->vidlayer,
328 DLSCL_EXCLUSIVE));
329 SDL_DFB_CHECKERR(data->vidlayer->
330 SetConfiguration(data->vidlayer, &layconf));
331 SDL_DFB_CHECKERR(data->vidlayer->
332 GetSurface(data->vidlayer, &data->surface));
333 SDL_DFB_CHECKERR(data->vidlayer->
334 GetDescription(data->vidlayer, &laydsc));
335 SDL_DFB_DEBUG("Created HW YUV surface\n");
336 }
337 if (!data->vidlayer) {
338 /* fill surface description */
339 dsc.flags =
340 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
341 dsc.width = texture->w;
342 dsc.height = texture->h;
343 /* Never use DSCAPS_VIDEOONLY here. It kills performance
344 * No DSCAPS_SYSTEMONLY either - let dfb decide
345 */
346 dsc.caps = 0; //DSCAPS_PREMULTIPLIED;
347
348 /* find the right pixelformat */
349
350 dsc.pixelformat = SDLToDFBPixelFormat(data->format);
351 if (dsc.pixelformat == DSPF_UNKNOWN) {
352 SDL_SetError("Unknown pixel format %d\n", data->format);
353 goto error;
354 }
355
356 data->pixels = NULL;
357
358 /* Create the surface */
359 SDL_DFB_CHECKERR(devdata->dfb->
360 CreateSurface(devdata->dfb, &dsc, &data->surface));
361 if (SDL_ISPIXELFORMAT_INDEXED(data->format)
362 && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
363 SDL_DFB_CHECKERR(data->surface->
364 GetPalette(data->surface, &data->palette));
365 }
366
367 }
368 return 0;
369
370 error:
371 SDL_DFB_RELEASE(data->palette);
372 SDL_DFB_RELEASE(data->surface);
373 SDL_DFB_FREE(texture->driverdata);
374 return -1;
375 }
376
377 static int
378 DirectFB_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
379 void **pixels, int *pitch)
380 {
381 DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
382
383 /*
384 * Always fail here so in compat mode SDL_HWSURFACE is set !
385 */
386
387 return -1;
388 }
389
390 static int
391 DirectFB_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
392 const SDL_Color * colors, int firstcolor,
393 int ncolors)
394 {
395 DirectFB_RenderData *renderdata =
396 (DirectFB_RenderData *) renderer->driverdata;
397 DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
398 DFBResult ret;
399
400 if (SDL_ISPIXELFORMAT_INDEXED(data->format)
401 && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
402 DFBColor entries[256];
403 int i;
404
405 for (i = 0; i < ncolors; ++i) {
406 entries[i].r = colors[i].r;
407 entries[i].g = colors[i].g;
408 entries[i].b = colors[i].b;
409 entries[i].a = 0xFF;
410 }
411 SDL_DFB_CHECKERR(data->palette->
412 SetEntries(data->palette, entries, ncolors,
413 firstcolor));
414 return 0;
415 } else {
416 SDL_SetError("YUV textures don't have a palette");
417 return -1;
418 }
419 error:
420 return -1;
421 }
422
423 static int
424 DirectFB_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
425 SDL_Color * colors, int firstcolor, int ncolors)
426 {
427 DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
428 DFBResult ret;
429
430 if (SDL_ISPIXELFORMAT_INDEXED(data->format)
431 && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
432 DFBColor entries[256];
433 int i;
434
435 SDL_DFB_CHECKERR(data->palette->
436 GetEntries(data->palette, entries, ncolors,
437 firstcolor));
438
439 for (i = 0; i < ncolors; ++i) {
440 colors[i].r = entries[i].r;
441 colors[i].g = entries[i].g;
442 colors[i].b = entries[i].b;
443 }
444 return 0;
445 } else {
446 SDL_SetError("YUV textures don't have a palette");
447 return -1;
448 }
449 error:
450 return -1;
451 }
452
453 static int
454 DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
455 {
456 return 0;
457 }
458
459 static int
460 DirectFB_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
461 {
462 return 0;
463 }
464
465 static int
466 DirectFB_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
467 {
468 switch (texture->blendMode) {
469 case SDL_TEXTUREBLENDMODE_NONE:
470 case SDL_TEXTUREBLENDMODE_MASK:
471 case SDL_TEXTUREBLENDMODE_BLEND:
472 case SDL_TEXTUREBLENDMODE_MOD:
473 return 0;
474 default:
475 SDL_Unsupported();
476 texture->blendMode = SDL_TEXTUREBLENDMODE_NONE;
477 return -1;
478 }
479 }
480
481 static int
482 DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
483 {
484 switch (texture->scaleMode) {
485 case SDL_TEXTURESCALEMODE_NONE:
486 case SDL_TEXTURESCALEMODE_FAST:
487 return 0;
488 case SDL_TEXTURESCALEMODE_SLOW:
489 case SDL_TEXTURESCALEMODE_BEST:
490 SDL_Unsupported();
491 texture->scaleMode = SDL_TEXTURESCALEMODE_FAST;
492 return -1;
493 default:
494 SDL_Unsupported();
495 texture->scaleMode = SDL_TEXTURESCALEMODE_NONE;
496 return -1;
497 }
498 return 0;
499 }
500
501 static int
502 DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
503 const SDL_Rect * rect, const void *pixels, int pitch)
504 {
505 DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
506 DirectFB_RenderData *renderdata =
507 (DirectFB_RenderData *) renderer->driverdata;
508
509 if (data->pixels) {
510 Uint8 *src, *dst;
511 int row;
512 size_t length;
513
514 src = (Uint8 *) pixels;
515 dst =
516 (Uint8 *) data->pixels + rect->y * data->pitch +
517 rect->x * SDL_BYTESPERPIXEL(texture->format);
518 length = rect->w * SDL_BYTESPERPIXEL(texture->format);
519 for (row = 0; row < rect->h; ++row) {
520 SDL_memcpy(dst, src, length);
521 src += pitch;
522 dst += data->pitch;
523 }
524 } else {
525 SDL_SetError("FIXME: Update without lock!\n");
526 return -1;
527 }
528 return 0;
529 }
530
531 static int
532 DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
533 const SDL_Rect * rect, int markDirty, void **pixels,
534 int *pitch)
535 {
536 DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
537 DFBResult ret;
538 void *fdata;
539 int fpitch;
540
541 SDL_DFB_CHECKERR(data->surface->Lock(data->surface,
542 DSLF_WRITE | DSLF_READ, &fdata,
543 &fpitch));
544 data->pixels = fdata;
545 data->pitch = fpitch;
546
547 switch (texture->format) {
548 case SDL_PIXELFORMAT_YV12:
549 case SDL_PIXELFORMAT_IYUV:
550 if (rect
551 && (rect->x != 0 || rect->y != 0 || rect->w != texture->w
552 || rect->h != texture->h)) {
553 SDL_SetError
554 ("YV12 and IYUV textures only support full surface locks");
555 return -1;
556 }
557 break;
558 default:
559 /* Only one plane, no worries */
560 break;
561 }
562
563 *pitch = data->pitch;
564 *pixels = data->pixels;
565
566 return 0;
567 error:
568 return -1;
569 }
570
571 static void
572 DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
573 {
574 DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
575
576 data->surface->Unlock(data->surface);
577 data->pixels = NULL;
578 }
579
580 static void
581 DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
582 int numrects, const SDL_Rect * rects)
583 {
584 //TODO: DirtyTexture
585 }
586
587 static int
588 DirectFB_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b,
589 Uint8 a, const SDL_Rect * rect)
590 {
591 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
592 DFBResult ret;
593
594 SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, r, g, b, a));
595 SDL_DFB_CHECKERR(data->surface->
596 FillRectangle(data->surface, rect->x, rect->y, rect->w,
597 rect->h));
598
599 return 0;
600 error:
601 return -1;
602 }
603
604 static int
605 DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
606 const SDL_Rect * srcrect, const SDL_Rect * dstrect)
607 {
608 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
609 DirectFB_TextureData *texturedata =
610 (DirectFB_TextureData *) texture->driverdata;
611 DFBResult ret;
612
613 if (texturedata->vidlayer) {
614 int px, py;
615 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
616 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
617 SDL_DFB_DEVICEDATA(display->device);
618 DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
619 SDL_DFB_WINDOWDATA(window);
620
621 SDL_DFB_CHECKERR(texturedata->vidlayer->
622 SetSourceRectangle(texturedata->vidlayer, srcrect->x,
623 srcrect->y, srcrect->w,
624 srcrect->h));
625 windata->window->GetPosition(windata->window, &px, &py);
626 SDL_DFB_CHECKERR(texturedata->vidlayer->
627 SetScreenRectangle(texturedata->vidlayer,
628 px + dstrect->x, py + dstrect->y,
629 dstrect->w, dstrect->h));
630 } else {
631 DFBRectangle sr, dr;
632 DFBSurfaceBlittingFlags flags = 0;
633
634 sr.x = srcrect->x;
635 sr.y = srcrect->y;
636 sr.w = srcrect->w;
637 sr.h = srcrect->h;
638
639 dr.x = dstrect->x;
640 dr.y = dstrect->y;
641 dr.w = dstrect->w;
642 dr.h = dstrect->h;
643
644 if (texture->
645 modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA))
646 {
647 u8 alpha = 0xFF;
648 if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA)
649 alpha = texture->a;
650 if (texture->modMode & SDL_TEXTUREMODULATE_COLOR)
651 SDL_DFB_CHECKERR(data->surface->
652 SetColor(data->surface, texture->r,
653 texture->g, texture->b, alpha));
654 else
655 SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, 0xFF,
656 0xFF, 0xFF, alpha));
657 // Only works together ....
658 flags |= DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR;
659 }
660
661 if (texture->
662 blendMode & (SDL_TEXTUREBLENDMODE_MASK |
663 SDL_TEXTUREBLENDMODE_BLEND)) {
664 flags |= DSBLIT_BLEND_ALPHACHANNEL;
665 } else {
666 flags |= DSBLIT_NOFX;
667 }
668 SDL_DFB_CHECKERR(data->surface->
669 SetBlittingFlags(data->surface, flags));
670 if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
671 SDL_DFB_CHECKERR(data->surface->
672 Blit(data->surface, texturedata->surface, &sr,
673 dr.x, dr.y));
674 } else {
675 SDL_DFB_CHECKERR(data->surface->
676 StretchBlit(data->surface, texturedata->surface,
677 &sr, &dr));
678 }
679 }
680 return 0;
681 error:
682 return -1;
683 }
684
685 static void
686 DirectFB_RenderPresent(SDL_Renderer * renderer)
687 {
688 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
689 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
690
691 SDL_DirtyRect *dirty;
692 DFBRectangle sr;
693 DFBResult ret;
694
695 sr.x = 0;
696 sr.y = 0;
697 sr.w = window->w;
698 sr.h = window->h;
699
700 /* Send the data to the display */
701 SDL_DFB_CHECKERR(data->surface->
702 Flip(data->surface, NULL, data->flipflags));
703
704 return;
705 error:
706 return;
707 }
708
709 static void
710 DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
711 {
712 DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
713
714 if (!data) {
715 return;
716 }
717 SDL_DFB_RELEASE(data->palette);
718 SDL_DFB_RELEASE(data->surface);
719 SDL_DFB_RELEASE(data->vidlayer);
720 SDL_free(data);
721 texture->driverdata = NULL;
722 }
723
724 static void
725 DirectFB_DestroyRenderer(SDL_Renderer * renderer)
726 {
727 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
728 int i;
729
730 if (data) {
731 data->surface = NULL;
732 SDL_free(data);
733 }
734 SDL_free(renderer);
735 }
736
737 /* vi: set ts=4 sw=4 expandtab: */