Mercurial > sdl-ios-xcode
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: */ |