This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_DirectFB_render.c
1102 lines (975 loc) · 36 KB
1
2
/*
SDL - Simple DirectMedia Layer
3
Copyright (C) 1997-2010 Sam Lantinga
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
SDL1.3 implementation by couriersud@arcor.de
*/
#include "SDL_config.h"
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_render.h"
#include "../SDL_rect_c.h"
#include "../SDL_yuv_sw_c.h"
32
33
34
/* the following is not yet tested ... */
#define USE_DISPLAY_PALETTE (0)
35
36
37
38
39
/* GDI renderer implementation */
static SDL_Renderer *DirectFB_CreateRenderer(SDL_Window * window,
Uint32 flags);
static int DirectFB_DisplayModeChanged(SDL_Renderer * renderer);
40
static int DirectFB_ActivateRenderer(SDL_Renderer * renderer);
41
42
43
static int DirectFB_CreateTexture(SDL_Renderer * renderer,
SDL_Texture * texture);
static int DirectFB_QueryTexturePixels(SDL_Renderer * renderer,
44
45
SDL_Texture * texture,
void **pixels, int *pitch);
46
47
48
49
50
51
static int DirectFB_SetTexturePalette(SDL_Renderer * renderer,
SDL_Texture * texture,
const SDL_Color * colors,
int firstcolor, int ncolors);
static int DirectFB_GetTexturePalette(SDL_Renderer * renderer,
SDL_Texture * texture,
52
53
SDL_Color * colors,
int firstcolor, int ncolors);
54
55
56
57
58
59
60
61
62
63
static int DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer,
SDL_Texture * texture);
static int DirectFB_SetTextureColorMod(SDL_Renderer * renderer,
SDL_Texture * texture);
static int DirectFB_SetTextureBlendMode(SDL_Renderer * renderer,
SDL_Texture * texture);
static int DirectFB_SetTextureScaleMode(SDL_Renderer * renderer,
SDL_Texture * texture);
static int DirectFB_UpdateTexture(SDL_Renderer * renderer,
SDL_Texture * texture,
64
65
const SDL_Rect * rect,
const void *pixels, int pitch);
66
static int DirectFB_LockTexture(SDL_Renderer * renderer,
67
68
69
SDL_Texture * texture,
const SDL_Rect * rect, int markDirty,
void **pixels, int *pitch);
70
71
72
73
74
static void DirectFB_UnlockTexture(SDL_Renderer * renderer,
SDL_Texture * texture);
static void DirectFB_DirtyTexture(SDL_Renderer * renderer,
SDL_Texture * texture, int numrects,
const SDL_Rect * rects);
75
76
77
78
79
80
81
82
static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer,
const SDL_Point * points, int count);
static int DirectFB_RenderDrawLines(SDL_Renderer * renderer,
const SDL_Point * points, int count);
static int DirectFB_RenderDrawRects(SDL_Renderer * renderer,
const SDL_Rect ** rects, int count);
static int DirectFB_RenderFillRects(SDL_Renderer * renderer,
const SDL_Rect ** rects, int count);
83
84
static int DirectFB_RenderCopy(SDL_Renderer * renderer,
SDL_Texture * texture,
85
86
87
88
89
90
91
const SDL_Rect * srcrect,
const SDL_Rect * dstrect);
static void DirectFB_RenderPresent(SDL_Renderer * renderer);
static void DirectFB_DestroyTexture(SDL_Renderer * renderer,
SDL_Texture * texture);
static void DirectFB_DestroyRenderer(SDL_Renderer * renderer);
92
93
#define SDL_DFB_WINDOWSURFACE(win) IDirectFBSurface *destsurf = ((DFB_WindowData *) ((win)->driverdata))->surface;
94
95
96
97
98
99
SDL_RenderDriver DirectFB_RenderDriver = {
DirectFB_CreateRenderer,
{
"directfb",
(SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
100
101
SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_PRESENTDISCARD |
SDL_RENDERER_ACCELERATED),
102
103
(SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
SDL_TEXTUREMODULATE_ALPHA),
104
105
(SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND |
SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD),
106
107
(SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST |
SDL_TEXTURESCALEMODE_SLOW | SDL_TEXTURESCALEMODE_BEST),
108
109
110
14,
{
SDL_PIXELFORMAT_INDEX4LSB,
111
SDL_PIXELFORMAT_INDEX8,
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
SDL_PIXELFORMAT_RGB332,
SDL_PIXELFORMAT_RGB555,
SDL_PIXELFORMAT_RGB565,
SDL_PIXELFORMAT_RGB888,
SDL_PIXELFORMAT_ARGB8888,
SDL_PIXELFORMAT_ARGB4444,
SDL_PIXELFORMAT_ARGB1555,
SDL_PIXELFORMAT_RGB24,
SDL_PIXELFORMAT_YV12,
SDL_PIXELFORMAT_IYUV,
SDL_PIXELFORMAT_YUY2,
SDL_PIXELFORMAT_UYVY},
0,
0}
};
typedef struct
{
130
SDL_Window *window;
131
132
DFBSurfaceFlipFlags flipflags;
int isyuvdirect;
133
int size_changed;
134
135
136
int lastBlendMode;
DFBSurfaceBlittingFlags blitFlags;
DFBSurfaceDrawingFlags drawFlags;
137
138
139
140
141
142
143
144
145
} DirectFB_RenderData;
typedef struct
{
IDirectFBSurface *surface;
Uint32 format;
void *pixels;
int pitch;
IDirectFBPalette *palette;
146
147
SDL_VideoDisplay *display;
SDL_DirtyRectList dirty;
148
#if (DFB_VERSION_ATLEAST(1,2,0))
149
150
DFBSurfaceRenderOptions render_options;
#endif
151
152
} DirectFB_TextureData;
153
154
155
156
157
158
159
160
161
static __inline__ void
SDLtoDFBRect(const SDL_Rect * sr, DFBRectangle * dr)
{
dr->x = sr->x;
dr->y = sr->y;
dr->h = sr->h;
dr->w = sr->w;
}
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
static int
TextureHasAlpha(DirectFB_TextureData * data)
{
/* Drawing primitive ? */
if (!data)
return 0;
switch (data->format) {
case SDL_PIXELFORMAT_INDEX4LSB:
case SDL_PIXELFORMAT_ARGB4444:
case SDL_PIXELFORMAT_ARGB1555:
case SDL_PIXELFORMAT_ARGB8888:
case SDL_PIXELFORMAT_RGBA8888:
case SDL_PIXELFORMAT_ABGR8888:
case SDL_PIXELFORMAT_BGRA8888:
case SDL_PIXELFORMAT_ARGB2101010:
return 1;
default:
return 0;
}
}
static void
SetBlendMode(DirectFB_RenderData * data, int blendMode,
DirectFB_TextureData * source)
{
188
189
190
SDL_DFB_WINDOWSURFACE(data->window);
//FIXME: check for format change
191
192
193
194
195
196
if (1 || data->lastBlendMode != blendMode) {
switch (blendMode) {
case SDL_BLENDMODE_NONE:
/**< No blending */
data->blitFlags = DSBLIT_NOFX;
data->drawFlags = DSDRAW_NOFX;
197
198
destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE);
destsurf->SetDstBlendFunction(destsurf, DSBF_ZERO);
199
200
201
202
break;
case SDL_BLENDMODE_MASK:
data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
data->drawFlags = DSDRAW_BLEND;
203
destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA);
204
destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA);
205
206
207
208
break;
case SDL_BLENDMODE_BLEND:
data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
data->drawFlags = DSDRAW_BLEND;
209
destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA);
210
destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA);
211
212
213
214
break;
case SDL_BLENDMODE_ADD:
data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
data->drawFlags = DSDRAW_BLEND;
215
216
217
218
// FIXME: SRCALPHA kills performance on radeon ...
// It will be cheaper to copy the surface to
// a temporay surface and premultiply
if (source && TextureHasAlpha(source))
219
destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA);
220
else
221
222
destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE);
destsurf->SetDstBlendFunction(destsurf, DSBF_ONE);
223
224
225
226
break;
case SDL_BLENDMODE_MOD:
data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
data->drawFlags = DSDRAW_BLEND;
227
228
destsurf->SetSrcBlendFunction(destsurf, DSBF_DESTCOLOR);
destsurf->SetDstBlendFunction(destsurf, DSBF_ZERO);
229
230
231
232
233
234
break;
}
data->lastBlendMode = blendMode;
}
}
235
236
237
238
void
DirectFB_AddRenderDriver(_THIS)
{
int i;
239
240
for (i = 0; i < _this->num_displays; ++i) {
241
SDL_AddRenderDriver(&_this->displays[i], &DirectFB_RenderDriver);
242
}
243
244
}
245
246
247
248
249
static int
DisplayPaletteChanged(void *userdata, SDL_Palette * palette)
{
#if USE_DISPLAY_PALETTE
DirectFB_RenderData *data = (DirectFB_RenderData *) userdata;
250
SDL_DFB_WINDOWSURFACE(data->window);
251
252
253
254
255
256
257
IDirectFBPalette *surfpal;
int ret;
int i;
int ncolors;
DFBColor entries[256];
258
SDL_DFB_CHECKERR(destsurf->GetPalette(destsurf, &surfpal));
259
260
261
262
263
264
265
266
267
268
269
270
271
/* FIXME: number of colors */
ncolors = (palette->ncolors < 256 ? palette->ncolors : 256);
for (i = 0; i < ncolors; ++i) {
entries[i].r = palette->colors[i].r;
entries[i].g = palette->colors[i].g;
entries[i].b = palette->colors[i].b;
entries[i].a = palette->colors[i].unused;
}
SDL_DFB_CHECKERR(surfpal->SetEntries(surfpal, entries, ncolors, 0));
return 0;
error:
272
273
#else
SDL_Unsupported();
274
275
276
277
278
#endif
return -1;
}
279
280
281
282
SDL_Renderer *
DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags)
{
SDL_DFB_WINDOWDATA(window);
283
SDL_VideoDisplay *display = window->display;
284
285
286
287
288
289
290
291
292
293
SDL_Renderer *renderer = NULL;
DirectFB_RenderData *data = NULL;
DFBResult ret;
DFBSurfaceCapabilities scaps;
char *p;
SDL_DFB_CALLOC(renderer, 1, sizeof(*renderer));
SDL_DFB_CALLOC(data, 1, sizeof(*data));
renderer->DisplayModeChanged = DirectFB_DisplayModeChanged;
294
renderer->ActivateRenderer = DirectFB_ActivateRenderer;
295
296
297
298
299
300
301
302
303
304
305
306
renderer->CreateTexture = DirectFB_CreateTexture;
renderer->QueryTexturePixels = DirectFB_QueryTexturePixels;
renderer->SetTexturePalette = DirectFB_SetTexturePalette;
renderer->GetTexturePalette = DirectFB_GetTexturePalette;
renderer->SetTextureAlphaMod = DirectFB_SetTextureAlphaMod;
renderer->SetTextureColorMod = DirectFB_SetTextureColorMod;
renderer->SetTextureBlendMode = DirectFB_SetTextureBlendMode;
renderer->SetTextureScaleMode = DirectFB_SetTextureScaleMode;
renderer->UpdateTexture = DirectFB_UpdateTexture;
renderer->LockTexture = DirectFB_LockTexture;
renderer->UnlockTexture = DirectFB_UnlockTexture;
renderer->DirtyTexture = DirectFB_DirtyTexture;
307
308
309
310
renderer->RenderDrawPoints = DirectFB_RenderDrawPoints;
renderer->RenderDrawLines = DirectFB_RenderDrawLines;
renderer->RenderFillRects = DirectFB_RenderFillRects;
renderer->RenderDrawRects = DirectFB_RenderDrawRects;
311
312
313
314
315
renderer->RenderCopy = DirectFB_RenderCopy;
renderer->RenderPresent = DirectFB_RenderPresent;
renderer->DestroyTexture = DirectFB_DestroyTexture;
renderer->DestroyRenderer = DirectFB_DestroyRenderer;
renderer->info = DirectFB_RenderDriver.info;
316
renderer->window = window; /* SDL window */
317
318
319
320
321
renderer->driverdata = data;
renderer->info.flags =
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTDISCARD;
322
data->window = window;
323
324
data->flipflags = DSFLIP_PIPELINE | DSFLIP_BLIT;
325
326
if (flags & SDL_RENDERER_PRESENTVSYNC) {
327
data->flipflags |= DSFLIP_WAITFORSYNC;
328
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
329
330
} else
data->flipflags |= DSFLIP_ONSYNC;
331
332
333
SDL_DFB_CHECKERR(windata->surface->
GetCapabilities(windata->surface, &scaps));
334
335
336
337
338
339
340
if (scaps & DSCAPS_DOUBLE)
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
else if (scaps & DSCAPS_TRIPLE)
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
else
renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
341
data->isyuvdirect = 0; /* default is off! */
342
p = SDL_getenv(DFBENV_USE_YUV_DIRECT);
343
344
345
if (p)
data->isyuvdirect = atoi(p);
346
347
348
349
350
/* Set up a palette watch on the display palette */
if (display->palette) {
SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged, data);
}
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
return renderer;
error:
SDL_DFB_FREE(renderer);
SDL_DFB_FREE(data);
return NULL;
}
static DFBSurfacePixelFormat
SDLToDFBPixelFormat(Uint32 format)
{
switch (format) {
case SDL_PIXELFORMAT_INDEX4LSB:
return DSPF_ALUT44;
case SDL_PIXELFORMAT_INDEX8:
return DSPF_LUT8;
case SDL_PIXELFORMAT_RGB332:
return DSPF_RGB332;
case SDL_PIXELFORMAT_RGB555:
return DSPF_ARGB1555;
case SDL_PIXELFORMAT_ARGB4444:
return DSPF_ARGB4444;
case SDL_PIXELFORMAT_ARGB1555:
return DSPF_ARGB1555;
case SDL_PIXELFORMAT_RGB565:
return DSPF_RGB16;
case SDL_PIXELFORMAT_RGB24:
return DSPF_RGB24;
case SDL_PIXELFORMAT_RGB888:
return DSPF_RGB32;
case SDL_PIXELFORMAT_ARGB8888:
return DSPF_ARGB;
case SDL_PIXELFORMAT_YV12:
return DSPF_YV12; /* Planar mode: Y + V + U (3 planes) */
case SDL_PIXELFORMAT_IYUV:
return DSPF_I420; /* Planar mode: Y + U + V (3 planes) */
case SDL_PIXELFORMAT_YUY2:
return DSPF_YUY2; /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
case SDL_PIXELFORMAT_UYVY:
return DSPF_UYVY; /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
case SDL_PIXELFORMAT_YVYU:
return DSPF_UNKNOWN; /* Packed mode: Y0+V0+Y1+U0 (1 plane) */
case SDL_PIXELFORMAT_INDEX1LSB:
return DSPF_UNKNOWN;
case SDL_PIXELFORMAT_INDEX1MSB:
return DSPF_UNKNOWN;
case SDL_PIXELFORMAT_INDEX4MSB:
return DSPF_UNKNOWN;
case SDL_PIXELFORMAT_RGB444:
400
#if (DFB_VERSION_ATLEAST(1,2,0))
401
402
return DSPF_RGB444;
#else
403
return DSPF_UNKNOWN;
404
#endif
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
case SDL_PIXELFORMAT_BGR24:
return DSPF_UNKNOWN;
case SDL_PIXELFORMAT_BGR888:
return DSPF_UNKNOWN;
case SDL_PIXELFORMAT_RGBA8888:
return DSPF_UNKNOWN;
case SDL_PIXELFORMAT_ABGR8888:
return DSPF_UNKNOWN;
case SDL_PIXELFORMAT_BGRA8888:
return DSPF_UNKNOWN;
case SDL_PIXELFORMAT_ARGB2101010:
return DSPF_UNKNOWN;
default:
return DSPF_UNKNOWN;
}
}
static int
423
DirectFB_ActivateRenderer(SDL_Renderer * renderer)
424
425
{
SDL_DFB_RENDERERDATA(renderer);
426
SDL_Window *window = renderer->window;
427
428
SDL_DFB_WINDOWDATA(window);
429
430
if (renddata->size_changed || windata->wm_needs_redraw) {
DirectFB_AdjustWindowSurface(window);
431
}
432
433
434
return 0;
}
435
436
437
438
439
440
441
442
443
static int
DirectFB_DisplayModeChanged(SDL_Renderer * renderer)
{
SDL_DFB_RENDERERDATA(renderer);
renddata->size_changed = SDL_TRUE;
return 0;
}
444
static int
445
DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture)
446
447
{
SDL_DFB_RENDERERDATA(renderer);
448
SDL_Window *window = renderer->window;
449
SDL_VideoDisplay *display = window->display;
450
451
SDL_DFB_DEVICEDATA(display->device);
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
452
DirectFB_TextureData *data = texture->driverdata;
453
DFBDisplayLayerConfig layconf;
454
int ret;
455
456
if (renddata->isyuvdirect && (dispdata->vidID >= 0)
457
&& (!dispdata->vidIDinuse)
458
&& SDL_ISPIXELFORMAT_FOURCC(data->format)) {
459
460
461
layconf.flags =
DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
DLCONF_SURFACE_CAPS;
462
463
464
layconf.width = texture->w;
layconf.height = texture->h;
layconf.pixelformat = SDLToDFBPixelFormat(data->format);
465
layconf.surface_caps = DSCAPS_VIDEOONLY | DSCAPS_DOUBLE;
466
467
468
469
470
471
472
SDL_DFB_CHECKERR(devdata->dfb->GetDisplayLayer(devdata->dfb,
dispdata->vidID,
&dispdata->vidlayer));
SDL_DFB_CHECKERR(dispdata->
vidlayer->SetCooperativeLevel(dispdata->vidlayer,
DLSCL_EXCLUSIVE));
473
474
475
476
477
478
if (devdata->use_yuv_underlays) {
ret = dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1);
if (ret != DFB_OK)
SDL_DFB_DEBUG("Underlay Setlevel not supported\n");
}
479
480
481
482
483
484
SDL_DFB_CHECKERR(dispdata->
vidlayer->SetConfiguration(dispdata->vidlayer,
&layconf));
SDL_DFB_CHECKERR(dispdata->
vidlayer->GetSurface(dispdata->vidlayer,
&data->surface));
485
486
dispdata->vidIDinuse = 1;
data->display = display;
487
return 0;
488
}
489
490
return 1;
error:
491
if (dispdata->vidlayer) {
492
SDL_DFB_RELEASE(data->surface);
493
494
495
SDL_DFB_CHECKERR(dispdata->
vidlayer->SetCooperativeLevel(dispdata->vidlayer,
DLSCL_ADMINISTRATIVE));
496
SDL_DFB_RELEASE(dispdata->vidlayer);
497
498
499
500
501
502
503
}
return 1;
}
static int
DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
504
SDL_Window *window = renderer->window;
505
SDL_VideoDisplay *display = window->display;
506
507
508
509
SDL_DFB_DEVICEDATA(display->device);
DirectFB_TextureData *data;
DFBResult ret;
DFBSurfaceDescription dsc;
510
DFBSurfacePixelFormat pixelformat;
511
512
513
514
SDL_DFB_CALLOC(data, 1, sizeof(*data));
texture->driverdata = data;
515
516
517
518
519
520
521
/* find the right pixelformat */
pixelformat = SDLToDFBPixelFormat(texture->format);
if (pixelformat == DSPF_UNKNOWN) {
SDL_SetError("Unknown pixel format %d\n", data->format);
goto error;
}
522
data->format = texture->format;
523
data->pitch = texture->w * DFB_BYTES_PER_PIXEL(pixelformat);
524
525
if (DirectFB_AcquireVidLayer(renderer, texture) != 0) {
526
527
528
529
530
/* fill surface description */
dsc.flags =
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
dsc.width = texture->w;
dsc.height = texture->h;
531
/* <1.2 Never use DSCAPS_VIDEOONLY here. It kills performance
532
* No DSCAPS_SYSTEMONLY either - let dfb decide
533
* 1.2: DSCAPS_SYSTEMONLY boosts performance by factor ~8
534
* Depends on other settings as well. Let dfb decide.
535
*/
536
dsc.caps = DSCAPS_PREMULTIPLIED;
537
#if 0
538
539
540
541
if (texture->access == SDL_TEXTUREACCESS_STREAMING)
dsc.caps |= DSCAPS_SYSTEMONLY;
else
dsc.caps |= DSCAPS_VIDEOONLY;
542
#endif
543
544
dsc.pixelformat = pixelformat;
545
546
547
data->pixels = NULL;
/* Create the surface */
548
549
SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
&data->surface));
550
551
if (SDL_ISPIXELFORMAT_INDEXED(data->format)
&& !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
552
553
SDL_DFB_CHECKERR(data->surface->GetPalette(data->surface,
&data->palette));
554
555
556
}
}
557
#if (DFB_VERSION_ATLEAST(1,2,0))
558
559
560
561
data->render_options = DSRO_NONE;
#endif
if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
562
563
564
565
566
567
568
/* 3 plane YUVs return 1 bpp, but we need more space for other planes */
if(texture->format == SDL_PIXELFORMAT_YV12 ||
texture->format == SDL_PIXELFORMAT_IYUV) {
SDL_DFB_CALLOC(data->pixels, 1, (texture->h * data->pitch * 3 + texture->h * data->pitch * 3 % 2) / 2);
} else {
SDL_DFB_CALLOC(data->pixels, 1, texture->h * data->pitch);
}
569
570
}
571
572
573
574
575
576
577
578
579
580
return 0;
error:
SDL_DFB_RELEASE(data->palette);
SDL_DFB_RELEASE(data->surface);
SDL_DFB_FREE(texture->driverdata);
return -1;
}
static int
581
582
DirectFB_QueryTexturePixels(SDL_Renderer * renderer,
SDL_Texture * texture, void **pixels, int *pitch)
583
{
584
585
DirectFB_TextureData *texturedata =
(DirectFB_TextureData *) texture->driverdata;
586
587
588
589
590
591
592
593
if (texturedata->display) {
return -1;
} else {
*pixels = texturedata->pixels;
*pitch = texturedata->pitch;
}
return 0;
594
595
596
}
static int
597
598
DirectFB_SetTexturePalette(SDL_Renderer * renderer,
SDL_Texture * texture,
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
const SDL_Color * colors, int firstcolor,
int ncolors)
{
DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
DFBResult ret;
if (SDL_ISPIXELFORMAT_INDEXED(data->format)
&& !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
DFBColor entries[256];
int i;
for (i = 0; i < ncolors; ++i) {
entries[i].r = colors[i].r;
entries[i].g = colors[i].g;
entries[i].b = colors[i].b;
entries[i].a = 0xFF;
}
616
617
618
SDL_DFB_CHECKERR(data->
palette->SetEntries(data->palette, entries, ncolors,
firstcolor));
619
620
621
622
623
624
625
626
627
628
return 0;
} else {
SDL_SetError("YUV textures don't have a palette");
return -1;
}
error:
return -1;
}
static int
629
630
631
DirectFB_GetTexturePalette(SDL_Renderer * renderer,
SDL_Texture * texture, SDL_Color * colors,
int firstcolor, int ncolors)
632
633
634
635
636
637
638
639
640
{
DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
DFBResult ret;
if (SDL_ISPIXELFORMAT_INDEXED(data->format)
&& !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
DFBColor entries[256];
int i;
641
642
643
SDL_DFB_CHECKERR(data->
palette->GetEntries(data->palette, entries, ncolors,
firstcolor));
644
645
646
647
648
for (i = 0; i < ncolors; ++i) {
colors[i].r = entries[i].r;
colors[i].g = entries[i].g;
colors[i].b = entries[i].b;
649
colors->unused = SDL_ALPHA_OPAQUE;
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
}
return 0;
} else {
SDL_SetError("YUV textures don't have a palette");
return -1;
}
error:
return -1;
}
static int
DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
{
return 0;
}
static int
DirectFB_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
{
return 0;
}
static int
DirectFB_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
{
switch (texture->blendMode) {
676
677
678
679
680
case SDL_BLENDMODE_NONE:
case SDL_BLENDMODE_MASK:
case SDL_BLENDMODE_BLEND:
case SDL_BLENDMODE_ADD:
case SDL_BLENDMODE_MOD:
681
682
683
return 0;
default:
SDL_Unsupported();
684
texture->blendMode = SDL_BLENDMODE_NONE;
685
686
687
688
689
690
691
return -1;
}
}
static int
DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
{
692
#if (DFB_VERSION_ATLEAST(1,2,0))
693
694
695
DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
696
697
698
switch (texture->scaleMode) {
case SDL_TEXTURESCALEMODE_NONE:
case SDL_TEXTURESCALEMODE_FAST:
699
700
data->render_options = DSRO_NONE;
break;
701
case SDL_TEXTURESCALEMODE_SLOW:
702
703
data->render_options = DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE;
break;
704
case SDL_TEXTURESCALEMODE_BEST:
705
706
707
data->render_options =
DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE | DSRO_ANTIALIAS;
break;
708
709
default:
SDL_Unsupported();
710
data->render_options = DSRO_NONE;
711
712
713
texture->scaleMode = SDL_TEXTURESCALEMODE_NONE;
return -1;
}
714
#endif
715
716
717
718
719
720
721
722
return 0;
}
static int
DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels, int pitch)
{
DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
723
724
DFBResult ret;
Uint8 *dpixels;
725
int dpitch;
726
727
728
Uint8 *src, *dst;
int row;
size_t length;
729
730
int bpp = DFB_BYTES_PER_PIXEL(SDLToDFBPixelFormat(texture->format));
// FIXME: SDL_BYTESPERPIXEL(texture->format) broken for yuv yv12 3 planes
731
732
SDL_DFB_CHECKERR(data->surface->Lock(data->surface,
733
734
DSLF_WRITE | DSLF_READ,
((void **) &dpixels), &dpitch));
735
src = (Uint8 *) pixels;
736
737
dst = (Uint8 *) dpixels + rect->y * dpitch + rect->x * bpp;
length = rect->w * bpp;
738
739
740
741
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
src += pitch;
dst += dpitch;
742
}
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
/* copy other planes for 3 plane formats */
if (texture->format == SDL_PIXELFORMAT_YV12 ||
texture->format == SDL_PIXELFORMAT_IYUV) {
src = (Uint8 *) pixels + texture->h * pitch;
dst = (Uint8 *) dpixels + texture->h * dpitch + rect->y * dpitch / 4 + rect->x * bpp / 2;
for (row = 0; row < rect->h / 2; ++row) {
SDL_memcpy(dst, src, length / 2);
src += pitch / 2;
dst += dpitch / 2;
}
src = (Uint8 *) pixels + texture->h * pitch + texture->h * pitch / 4;
dst = (Uint8 *) dpixels + texture->h * dpitch + texture->h * dpitch / 4 + rect->y * dpitch / 4 + rect->x * bpp / 2;
for (row = 0; row < rect->h / 2; ++row) {
SDL_memcpy(dst, src, length / 2);
src += pitch / 2;
dst += dpitch / 2;
}
}
761
SDL_DFB_CHECKERR(data->surface->Unlock(data->surface));
762
return 0;
763
764
error:
return 1;
765
766
767
768
769
}
static int
DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
770
771
const SDL_Rect * rect, int markDirty,
void **pixels, int *pitch)
772
{
773
774
DirectFB_TextureData *texturedata =
(DirectFB_TextureData *) texture->driverdata;
775
776
DFBResult ret;
777
778
if (markDirty) {
SDL_AddDirtyRect(&texturedata->dirty, rect);
779
780
}
781
782
783
if (texturedata->display) {
void *fdata;
int fpitch;
784
785
786
787
788
789
790
791
792
793
SDL_DFB_CHECKERR(texturedata->surface->Lock(texturedata->surface,
DSLF_WRITE | DSLF_READ,
&fdata, &fpitch));
*pitch = fpitch;
*pixels = fdata;
} else {
*pixels =
(void *) ((Uint8 *) texturedata->pixels +
rect->y * texturedata->pitch +
794
rect->x * DFB_BYTES_PER_PIXEL(SDLToDFBPixelFormat(texture->format)));
795
796
*pitch = texturedata->pitch;
}
797
return 0;
798
799
800
801
802
803
804
805
error:
return -1;
}
static void
DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
806
807
DirectFB_TextureData *texturedata =
(DirectFB_TextureData *) texture->driverdata;
808
809
810
811
812
if (texturedata->display) {
texturedata->surface->Unlock(texturedata->surface);
texturedata->pixels = NULL;
}
813
814
815
816
817
818
}
static void
DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
int numrects, const SDL_Rect * rects)
{
819
820
821
822
823
824
DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
int i;
for (i = 0; i < numrects; ++i) {
SDL_AddDirtyRect(&data->dirty, &rects[i]);
}
825
826
}
827
828
static int
PrepareDraw(SDL_Renderer * renderer)
829
830
{
DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
831
SDL_DFB_WINDOWSURFACE(data->window);
832
833
DFBResult ret;
834
835
836
837
838
839
840
841
Uint8 r, g, b, a;
r = renderer->r;
g = renderer->g;
b = renderer->b;
a = renderer->a;
SetBlendMode(data, renderer->blendMode, NULL);
842
SDL_DFB_CHECKERR(destsurf->SetDrawingFlags(destsurf, data->drawFlags));
843
844
845
846
847
848
849
850
851
852
853
854
855
856
switch (renderer->blendMode) {
case SDL_BLENDMODE_NONE:
case SDL_BLENDMODE_MASK:
case SDL_BLENDMODE_BLEND:
break;
case SDL_BLENDMODE_ADD:
case SDL_BLENDMODE_MOD:
r = ((int) r * (int) a) / 255;
g = ((int) g * (int) a) / 255;
b = ((int) b * (int) a) / 255;
a = 255;
break;
}
857
858
SDL_DFB_CHECKERR(destsurf->SetColor(destsurf, r, g, b, a));
859
860
861
862
863
return 0;
error:
return -1;
}
864
865
static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer,
const SDL_Point * points, int count)
866
867
{
DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
868
SDL_DFB_WINDOWSURFACE(data->window);
869
DFBResult ret;
870
int i;
871
872
PrepareDraw(renderer);
873
874
for (i=0; i < count; i++)
SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, points[i].x, points[i].y, points[i].x, points[i].y));
875
876
877
878
879
return 0;
error:
return -1;
}
880
881
static int DirectFB_RenderDrawLines(SDL_Renderer * renderer,
const SDL_Point * points, int count)
882
883
{
DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
884
SDL_DFB_WINDOWSURFACE(data->window);
885
DFBResult ret;
886
int i;
887
888
PrepareDraw(renderer);
889
/* Use antialiasing when available */
890
#if (DFB_VERSION_ATLEAST(1,2,0))
891
SDL_DFB_CHECKERR(destsurf->SetRenderOptions(destsurf, DSRO_ANTIALIAS));
892
#endif
893
894
895
896
for (i=0; i < count - 1; i++)
SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, points[i].x, points[i].y, points[i+1].x, points[i+1].y));
897
898
899
900
901
902
return 0;
error:
return -1;
}
static int
903
DirectFB_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
904
905
{
DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
906
SDL_DFB_WINDOWSURFACE(data->window);
907
DFBResult ret;
908
int i;
909
910
PrepareDraw(renderer);
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
for (i=0; i<count; i++)
SDL_DFB_CHECKERR(destsurf->DrawRectangle(destsurf, rects[i]->x, rects[i]->y,
rects[i]->w, rects[i]->h));
return 0;
error:
return -1;
}
static int
DirectFB_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
{
DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
SDL_DFB_WINDOWSURFACE(data->window);
DFBResult ret;
int i;
PrepareDraw(renderer);
for (i=0; i<count; i++)
SDL_DFB_CHECKERR(destsurf->FillRectangle(destsurf, rects[i]->x, rects[i]->y,
rects[i]->w, rects[i]->h));
934
935
936
937
938
939
940
941
942
943
944
return 0;
error:
return -1;
}
static int
DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect)
{
DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
945
SDL_DFB_WINDOWSURFACE(data->window);
946
947
DirectFB_TextureData *texturedata =
(DirectFB_TextureData *) texture->driverdata;
948
Uint8 alpha = 0xFF;
949
950
DFBResult ret;
951
if (texturedata->display) {
952
int px, py;
953
SDL_Window *window = renderer->window;
954
SDL_DFB_WINDOWDATA(window);
955
956
SDL_VideoDisplay *display = texturedata->display;
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
957
958
959
960
961
962
SDL_DFB_CHECKERR(dispdata->
vidlayer->SetSourceRectangle(dispdata->vidlayer,
srcrect->x, srcrect->y,
srcrect->w,
srcrect->h));
963
windata->window->GetPosition(windata->window, &px, &py);
964
965
966
967
968
969
970
971
px += windata->client.x;
py += windata->client.y;
SDL_DFB_CHECKERR(dispdata->
vidlayer->SetScreenRectangle(dispdata->vidlayer,
px + dstrect->x,
py + dstrect->y,
dstrect->w,
dstrect->h));
972
973
974
975
} else {
DFBRectangle sr, dr;
DFBSurfaceBlittingFlags flags = 0;
976
977
978
if (texturedata->dirty.list) {
SDL_DirtyRect *dirty;
void *pixels;
979
int bpp = DFB_BYTES_PER_PIXEL(SDLToDFBPixelFormat(texture->format));
980
981
982
983
984
985
986
987
988
989
990
991
992
int pitch = texturedata->pitch;
for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
SDL_Rect *rect = &dirty->rect;
pixels =
(void *) ((Uint8 *) texturedata->pixels +
rect->y * pitch + rect->x * bpp);
DirectFB_UpdateTexture(renderer, texture, rect,
texturedata->pixels,
texturedata->pitch);
}
SDL_ClearDirtyRects(&texturedata->dirty);
}
993
994
995
SDLtoDFBRect(srcrect, &sr);
SDLtoDFBRect(dstrect, &dr);
996
997
998
999
1000
SDL_DFB_CHECKERR(destsurf->
SetColor(destsurf, 0xFF, 0xFF, 0xFF, 0xFF));
if (texture->
modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA))