This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_DirectFB_video.c
1178 lines (965 loc) · 34 KB
1
/*
2
3
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
4
5
6
7
8
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.
9
10
11
12
13
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.
14
15
16
17
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
18
19
20
Sam Lantinga
slouken@libsdl.org
21
22
23
24
MGA CRTC2 support by Thomas Jarosch - tomj@simonv.com
CRTC2 support is inspired by mplayer's dfbmga driver
written by Ville Syrj��<syrjala@sci.fi>
25
*/
26
#include "SDL_config.h"
27
28
29
30
31
32
33
34
35
/* DirectFB video driver implementation.
*/
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <directfb.h>
36
#include <directfb_version.h>
37
38
39
#include "SDL_video.h"
#include "SDL_mouse.h"
40
41
42
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"
43
44
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_events.h"
45
#include "SDL_DirectFB_yuv.h"
46
47
/* The implementation dependent data for the window manager cursor */
48
49
50
struct WMcursor
{
int unused;
51
52
};
53
54
/* Initialization/Query functions */
55
56
57
58
59
60
static int DirectFB_VideoInit(_THIS, SDL_PixelFormat * vformat);
static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat * format,
Uint32 flags);
static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface * current,
int width, int height, int bpp,
Uint32 flags);
61
static int DirectFB_SetColors(_THIS, int firstcolor, int ncolors,
62
SDL_Color * colors);
63
64
65
static void DirectFB_VideoQuit(_THIS);
/* Hardware surface functions */
66
67
68
69
70
71
72
73
74
75
76
77
78
static int DirectFB_AllocHWSurface(_THIS, SDL_Surface * surface);
static int DirectFB_FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * dstrect,
Uint32 color);
static int DirectFB_LockHWSurface(_THIS, SDL_Surface * surface);
static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface * surface);
static void DirectFB_FreeHWSurface(_THIS, SDL_Surface * surface);
static int DirectFB_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst);
static int DirectFB_HWAccelBlit(SDL_Surface * src, SDL_Rect * srcrect,
SDL_Surface * dst, SDL_Rect * dstrect);
static int DirectFB_SetHWColorKey(_THIS, SDL_Surface * surface, Uint32 key);
static int DirectFB_SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 alpha);
static int DirectFB_FlipHWSurface(_THIS, SDL_Surface * surface);
static int DirectFB_ShowWMCursor(_THIS, WMcursor * cursor);
79
80
/* Various screen update functions available */
81
82
static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect * rects);
static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect * rects);
83
84
/* This is the rect EnumModes2 uses */
85
86
87
88
struct DirectFBEnumRect
{
SDL_Rect r;
struct DirectFBEnumRect *next;
89
90
};
91
static struct DirectFBEnumRect *enumlist = NULL;
92
93
94
95
/* DirectFB driver bootstrap functions */
96
97
static int
DirectFB_Available(void)
98
{
99
return 1;
100
101
}
102
103
static void
DirectFB_DeleteDevice(SDL_VideoDevice * device)
104
{
105
106
SDL_free(device->hidden);
SDL_free(device);
107
108
}
109
110
static SDL_VideoDevice *
DirectFB_CreateDevice(int devindex)
111
{
112
113
114
115
116
117
118
119
SDL_VideoDevice *device;
/* Initialize all variables that we clean on shutdown */
device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice));
if (device) {
SDL_memset(device, 0, (sizeof *device));
device->hidden = (struct SDL_PrivateVideoData *)
malloc(sizeof(*device->hidden));
120
}
121
122
123
124
if (device == NULL || device->hidden == NULL) {
SDL_OutOfMemory();
if (device) {
free(device);
125
}
126
return (0);
127
}
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
SDL_memset(device->hidden, 0, sizeof(*device->hidden));
/* Set the function pointers */
device->VideoInit = DirectFB_VideoInit;
device->ListModes = DirectFB_ListModes;
device->SetVideoMode = DirectFB_SetVideoMode;
device->SetColors = DirectFB_SetColors;
device->UpdateRects = NULL;
device->CreateYUVOverlay = DirectFB_CreateYUVOverlay;
device->VideoQuit = DirectFB_VideoQuit;
device->AllocHWSurface = DirectFB_AllocHWSurface;
device->CheckHWBlit = DirectFB_CheckHWBlit;
device->FillHWRect = DirectFB_FillHWRect;
device->SetHWColorKey = DirectFB_SetHWColorKey;
device->SetHWAlpha = DirectFB_SetHWAlpha;
device->LockHWSurface = DirectFB_LockHWSurface;
device->UnlockHWSurface = DirectFB_UnlockHWSurface;
device->FlipHWSurface = DirectFB_FlipHWSurface;
device->FreeHWSurface = DirectFB_FreeHWSurface;
device->ShowWMCursor = DirectFB_ShowWMCursor;
device->SetCaption = NULL;
device->SetIcon = NULL;
device->IconifyWindow = NULL;
device->GrabInput = NULL;
device->GetWMInfo = NULL;
device->InitOSKeymap = DirectFB_InitOSKeymap;
device->PumpEvents = DirectFB_PumpEvents;
device->free = DirectFB_DeleteDevice;
return device;
159
160
161
}
VideoBootStrap DirectFB_bootstrap = {
162
163
"directfb", "DirectFB",
DirectFB_Available, DirectFB_CreateDevice
164
165
};
166
167
static DFBSurfacePixelFormat
GetFormatForBpp(int bpp, IDirectFBDisplayLayer * layer)
168
{
169
170
DFBDisplayLayerConfig dlc;
int bytes = (bpp + 7) / 8;
171
172
layer->GetConfiguration(layer, &dlc);
173
174
175
if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat) && bytes > 1)
return dlc.pixelformat;
176
177
switch (bytes) {
178
case 1:
179
return DSPF_LUT8;
180
case 2:
181
return DSPF_RGB16;
182
case 3:
183
return DSPF_RGB24;
184
case 4:
185
return DSPF_RGB32;
186
187
}
188
return DSPF_UNKNOWN;
189
190
}
191
192
static DFBEnumerationResult
EnumModesCallback(int width, int height, int bpp, void *data)
193
{
194
195
SDL_VideoDevice *this = (SDL_VideoDevice *) data;
struct DirectFBEnumRect *enumrect;
196
197
HIDDEN->nummodes++;
198
199
200
if (enumlist && enumlist->r.w == width && enumlist->r.h == height)
return DFENUM_OK;
201
202
203
204
205
enumrect = SDL_calloc(1, sizeof(struct DirectFBEnumRect));
if (!enumrect) {
SDL_OutOfMemory();
return DFENUM_CANCEL;
206
207
}
208
209
210
enumrect->r.w = (Uint16) width;
enumrect->r.h = (Uint16) height;
enumrect->next = enumlist;
211
212
enumlist = enumrect;
213
214
return DFENUM_OK;
215
216
}
217
218
219
220
struct private_hwdata
{
IDirectFBSurface *surface;
IDirectFBPalette *palette;
221
222
};
223
224
void
SetDirectFBerror(const char *function, DFBResult code)
225
{
226
const char *error = DirectFBErrorString(code);
227
228
229
230
231
if (error)
SDL_SetError("%s: %s", function, error);
else
SDL_SetError("Unknown error code from %s", function);
232
233
}
234
235
static DFBSurfacePixelFormat
SDLToDFBPixelFormat(SDL_PixelFormat * format)
236
{
237
238
if (format->Rmask && format->Gmask && format->Bmask) {
switch (format->BitsPerPixel) {
239
case 8:
240
241
return DSPF_LUT8;
242
case 16:
243
244
245
246
247
if (format->Rmask == 0xF800 &&
format->Gmask == 0x07E0 && format->Bmask == 0x001F)
return DSPF_RGB16;
/* fall through */
248
case 15:
249
250
251
252
253
if (format->Rmask == 0x7C00 &&
format->Gmask == 0x03E0 && format->Bmask == 0x001F)
return DSPF_ARGB1555;
break;
254
case 24:
255
256
257
258
if (format->Rmask == 0xFF0000 &&
format->Gmask == 0x00FF00 && format->Bmask == 0x0000FF)
return DSPF_RGB24;
break;
259
260
case 32:
261
262
263
264
265
266
if (format->Rmask == 0xFF0000 &&
format->Gmask == 0x00FF00 && format->Bmask == 0x0000FF) {
if (format->Amask == 0xFF000000)
return DSPF_ARGB;
else
return DSPF_RGB32;
267
}
268
break;
269
}
270
271
} else {
switch (format->BitsPerPixel) {
272
case 8:
273
274
275
276
277
278
279
280
281
282
return DSPF_LUT8;
case 15:
return DSPF_ARGB1555;
case 16:
return DSPF_RGB16;
case 24:
return DSPF_RGB24;
case 32:
return DSPF_RGB32;
}
283
284
}
285
return DSPF_UNKNOWN;
286
287
}
288
289
static SDL_Palette *
AllocatePalette(int size)
290
{
291
292
293
294
295
296
297
SDL_Palette *palette;
SDL_Color *colors;
palette = SDL_calloc(1, sizeof(SDL_Palette));
if (!palette) {
SDL_OutOfMemory();
return NULL;
298
299
}
300
301
302
303
colors = SDL_calloc(size, sizeof(SDL_Color));
if (!colors) {
SDL_OutOfMemory();
return NULL;
304
305
}
306
307
palette->ncolors = size;
palette->colors = colors;
308
309
return palette;
310
311
}
312
313
314
static int
DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat,
SDL_PixelFormat * format)
315
{
316
317
format->Amask = format->Rmask = format->Gmask = format->Bmask = 0;
format->BitsPerPixel = format->BytesPerPixel = 0;
318
319
switch (pixelformat) {
320
case DSPF_A8:
321
322
format->Amask = 0x000000FF;
break;
323
324
case DSPF_ARGB1555:
325
326
327
328
format->Rmask = 0x00007C00;
format->Gmask = 0x000003E0;
format->Bmask = 0x0000001F;
break;
329
330
case DSPF_RGB16:
331
332
333
334
format->Rmask = 0x0000F800;
format->Gmask = 0x000007E0;
format->Bmask = 0x0000001F;
break;
335
336
case DSPF_ARGB:
337
338
format->Amask = 0; /* apps don't seem to like that: 0xFF000000; */
/* fall through */
339
340
case DSPF_RGB24:
case DSPF_RGB32:
341
342
343
344
format->Rmask = 0x00FF0000;
format->Gmask = 0x0000FF00;
format->Bmask = 0x000000FF;
break;
345
346
case DSPF_LUT8:
347
348
349
format->Rmask = 0x000000FF;
format->Gmask = 0x000000FF;
format->Bmask = 0x000000FF;
350
351
352
353
if (!format->palette)
format->palette = AllocatePalette(256);
break;
354
355
default:
356
357
358
359
fprintf(stderr,
"SDL_DirectFB: Unsupported pixelformat (0x%08x)!\n",
pixelformat);
return -1;
360
361
}
362
363
format->BitsPerPixel = DFB_BYTES_PER_PIXEL(pixelformat) * 8;
format->BytesPerPixel = DFB_BYTES_PER_PIXEL(pixelformat);
364
365
return 0;
366
367
368
}
369
370
int
DirectFB_VideoInit(_THIS, SDL_PixelFormat * vformat)
371
{
372
373
int i;
DFBResult ret;
374
#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
375
DFBCardCapabilities caps;
376
#else
377
DFBGraphicsDeviceDescription caps;
378
#endif
379
380
381
382
383
384
385
386
387
388
389
390
391
392
DFBDisplayLayerConfig dlc;
struct DirectFBEnumRect *rect;
IDirectFB *dfb = NULL;
IDirectFBDisplayLayer *layer = NULL;
IDirectFBEventBuffer *events = NULL;
HIDDEN->c2layer = NULL, HIDDEN->c2frame = NULL;
HIDDEN->enable_mga_crtc2 = 0;
HIDDEN->mga_crtc2_stretch_overscan = 1;
ret = DirectFBInit(NULL, NULL);
if (ret) {
SetDirectFBerror("DirectFBInit", ret);
goto error;
393
394
}
395
396
397
398
ret = DirectFBCreate(&dfb);
if (ret) {
SetDirectFBerror("DirectFBCreate", ret);
goto error;
399
400
}
401
402
403
404
ret = dfb->GetDisplayLayer(dfb, DLID_PRIMARY, &layer);
if (ret) {
SetDirectFBerror("dfb->GetDisplayLayer", ret);
goto error;
405
406
}
407
408
409
410
ret = dfb->CreateInputEventBuffer(dfb, DICAPS_ALL, DFB_FALSE, &events);
if (ret) {
SetDirectFBerror("dfb->CreateEventBuffer", ret);
goto error;
411
}
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
layer->EnableCursor(layer, 1);
/* Query layer configuration to determine the current mode and pixelformat */
layer->GetConfiguration(layer, &dlc);
/* If current format is not supported use LUT8 as the default */
if (DFBToSDLPixelFormat(dlc.pixelformat, vformat))
DFBToSDLPixelFormat(DSPF_LUT8, vformat);
/* Enumerate the available fullscreen modes */
ret = dfb->EnumVideoModes(dfb, EnumModesCallback, this);
if (ret) {
SetDirectFBerror("dfb->EnumVideoModes", ret);
goto error;
427
}
428
429
430
431
432
HIDDEN->modelist = SDL_calloc(HIDDEN->nummodes + 1, sizeof(SDL_Rect *));
if (!HIDDEN->modelist) {
SDL_OutOfMemory();
goto error;
433
434
}
435
436
for (i = 0, rect = enumlist; rect; ++i, rect = rect->next) {
HIDDEN->modelist[i] = &rect->r;
437
438
}
439
HIDDEN->modelist[i] = NULL;
440
441
442
/* Query card capabilities to get the video memory size */
443
#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
444
dfb->GetCardCapabilities(dfb, &caps);
445
#else
446
dfb->GetDeviceDescription(dfb, &caps);
447
#endif
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
this->info.wm_available = 1;
this->info.hw_available = 1;
this->info.blit_hw = 1;
this->info.blit_hw_CC = 1;
this->info.blit_hw_A = 1;
this->info.blit_fill = 1;
this->info.video_mem = caps.video_memory / 1024;
HIDDEN->initialized = 1;
HIDDEN->dfb = dfb;
HIDDEN->layer = layer;
HIDDEN->eventbuffer = events;
if (SDL_getenv("SDL_DIRECTFB_MGA_CRTC2") != NULL)
HIDDEN->enable_mga_crtc2 = 1;
if (HIDDEN->enable_mga_crtc2) {
DFBDisplayLayerConfig dlc;
DFBDisplayLayerConfigFlags failed;
ret = dfb->GetDisplayLayer(dfb, 2, &HIDDEN->c2layer);
if (ret) {
SetDirectFBerror("dfb->GetDisplayLayer(CRTC2)", ret);
goto error;
473
474
}
475
476
477
478
479
480
481
ret =
HIDDEN->layer->SetCooperativeLevel(HIDDEN->layer,
DLSCL_EXCLUSIVE);
if (ret) {
SetDirectFBerror
("layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret);
goto error;
482
}
483
484
485
486
487
488
489
490
ret =
HIDDEN->c2layer->SetCooperativeLevel(HIDDEN->c2layer,
DLSCL_EXCLUSIVE);
if (ret) {
SetDirectFBerror
("c2layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret);
goto error;
491
492
}
493
494
495
496
497
498
499
500
501
502
503
504
505
HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0x0);
/* Init the surface here as it got a fixed size */
dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
dlc.buffermode = DLBM_BACKVIDEO;
dlc.pixelformat = DSPF_RGB32;
ret =
HIDDEN->c2layer->TestConfiguration(HIDDEN->c2layer, &dlc,
&failed);
if (ret) {
SetDirectFBerror("c2layer->TestConfiguration", ret);
goto error;
506
}
507
508
509
510
511
ret = HIDDEN->c2layer->SetConfiguration(HIDDEN->c2layer, &dlc);
if (ret) {
SetDirectFBerror("c2layer->SetConfiguration", ret);
goto error;
512
}
513
514
515
516
517
ret = HIDDEN->c2layer->GetSurface(HIDDEN->c2layer, &HIDDEN->c2frame);
if (ret) {
SetDirectFBerror("c2layer->GetSurface", ret);
goto error;
518
519
}
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
HIDDEN->c2framesize.x = 0;
HIDDEN->c2framesize.y = 0;
HIDDEN->c2frame->GetSize(HIDDEN->c2frame, &HIDDEN->c2framesize.w,
&HIDDEN->c2framesize.h);
HIDDEN->c2frame->SetBlittingFlags(HIDDEN->c2frame, DSBLIT_NOFX);
HIDDEN->c2frame->SetColor(HIDDEN->c2frame, 0, 0, 0, 0xff);
/* Clear CRTC2 */
HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff);
HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0);
HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff);
HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0);
HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff);
HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0xFF);
/* Check if overscan is possibly set */
if (SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN") != NULL) {
float overscan = 0;
if (SDL_sscanf
(SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN"), "%f",
&overscan) == 1)
if (overscan > 0 && overscan < 2)
HIDDEN->mga_crtc2_stretch_overscan = overscan;
}
#ifdef DIRECTFB_CRTC2_DEBUG
printf("CRTC2 overscan: %f\n", HIDDEN->mga_crtc2_stretch_overscan);
#endif
549
550
}
551
return 0;
552
553
554
555
error:
if (events)
events->Release(events);
556
557
558
if (HIDDEN->c2frame)
HIDDEN->c2frame->Release(HIDDEN->c2frame);
559
560
561
if (HIDDEN->c2layer)
HIDDEN->c2layer->Release(HIDDEN->c2layer);
562
563
564
if (layer)
layer->Release(layer);
565
566
567
568
569
if (dfb)
dfb->Release(dfb);
return -1;
570
571
}
572
573
static SDL_Rect **
DirectFB_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
574
{
575
576
577
578
if (flags & SDL_FULLSCREEN)
return HIDDEN->modelist;
else if (SDLToDFBPixelFormat(format) != DSPF_UNKNOWN)
return (SDL_Rect **) - 1;
579
580
return NULL;
581
582
}
583
584
585
static SDL_Surface *
DirectFB_SetVideoMode(_THIS, SDL_Surface * current, int width, int height,
int bpp, Uint32 flags)
586
{
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
DFBResult ret;
DFBSurfaceDescription dsc;
DFBSurfacePixelFormat pixelformat;
IDirectFBSurface *surface;
fprintf(stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n",
width, height, bpp, flags);
flags |= SDL_FULLSCREEN;
/* Release previous primary surface */
if (current->hwdata && current->hwdata->surface) {
current->hwdata->surface->Release(current->hwdata->surface);
current->hwdata->surface = NULL;
/* And its palette if present */
if (current->hwdata->palette) {
current->hwdata->palette->Release(current->hwdata->palette);
current->hwdata->palette = NULL;
}
} else if (!current->hwdata) {
/* Allocate the hardware acceleration data */
current->hwdata =
(struct private_hwdata *) SDL_calloc(1, sizeof(*current->hwdata));
if (!current->hwdata) {
SDL_OutOfMemory();
return NULL;
614
}
615
616
}
617
618
619
620
621
622
/* Set cooperative level depending on flag SDL_FULLSCREEN */
if (flags & SDL_FULLSCREEN) {
ret = HIDDEN->dfb->SetCooperativeLevel(HIDDEN->dfb, DFSCL_FULLSCREEN);
if (ret && !HIDDEN->enable_mga_crtc2) {
DirectFBError("dfb->SetCooperativeLevel", ret);
flags &= ~SDL_FULLSCREEN;
623
}
624
625
626
627
628
629
630
631
632
633
} else
HIDDEN->dfb->SetCooperativeLevel(HIDDEN->dfb, DFSCL_NORMAL);
/* Set video mode */
ret = HIDDEN->dfb->SetVideoMode(HIDDEN->dfb, width, height, bpp);
if (ret) {
if (flags & SDL_FULLSCREEN) {
flags &= ~SDL_FULLSCREEN;
HIDDEN->dfb->SetCooperativeLevel(HIDDEN->dfb, DFSCL_NORMAL);
ret = HIDDEN->dfb->SetVideoMode(HIDDEN->dfb, width, height, bpp);
634
635
}
636
637
638
if (ret) {
SetDirectFBerror("dfb->SetVideoMode", ret);
return NULL;
639
640
641
}
}
642
643
644
645
646
647
648
649
650
651
652
/* Create primary surface */
dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT;
dsc.caps =
DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
dsc.pixelformat = GetFormatForBpp(bpp, HIDDEN->layer);
ret = HIDDEN->dfb->CreateSurface(HIDDEN->dfb, &dsc, &surface);
if (ret && (flags & SDL_DOUBLEBUF)) {
/* Try without double buffering */
dsc.caps &= ~DSCAPS_FLIPPING;
ret = HIDDEN->dfb->CreateSurface(HIDDEN->dfb, &dsc, &surface);
653
}
654
655
656
if (ret) {
SetDirectFBerror("dfb->CreateSurface", ret);
return NULL;
657
658
}
659
660
661
current->w = width;
current->h = height;
current->flags = SDL_HWSURFACE | SDL_PREALLOC;
662
663
664
665
666
667
if (flags & SDL_FULLSCREEN) {
current->flags |= SDL_FULLSCREEN;
this->UpdateRects = DirectFB_DirectUpdate;
} else
this->UpdateRects = DirectFB_WindowedUpdate;
668
669
670
if (dsc.caps & DSCAPS_FLIPPING)
current->flags |= SDL_DOUBLEBUF;
671
672
surface->GetPixelFormat(surface, &pixelformat);
673
674
DFBToSDLPixelFormat(pixelformat, current->format);
675
676
677
678
/* Get the surface palette (if supported) */
if (DFB_PIXELFORMAT_IS_INDEXED(pixelformat)) {
surface->GetPalette(surface, ¤t->hwdata->palette);
679
680
current->flags |= SDL_HWPALETTE;
681
682
}
683
current->hwdata->surface = surface;
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
/* MGA CRTC2 stuff */
if (HIDDEN->enable_mga_crtc2) {
/* no stretching if c2ssize == c2framesize */
HIDDEN->c2ssize.x = 0, HIDDEN->c2ssize.y = 0;
HIDDEN->c2ssize.w = width;
HIDDEN->c2ssize.h = height;
HIDDEN->c2dsize.x = 0, HIDDEN->c2dsize.y = 0;
HIDDEN->c2dsize.w = width;
HIDDEN->c2dsize.h = height;
HIDDEN->mga_crtc2_stretch = 0;
if (SDL_getenv("SDL_DIRECTFB_MGA_STRETCH") != NULL) {
/* Normally assume a picture aspect ratio of 4:3 */
int zoom_aspect_x = 4, zoom_aspect_y = 3, i, j;
for (i = 1; i < 20; i++) {
for (j = 1; j < 10; j++) {
if ((float) width / (float) i * (float) j == height) {
zoom_aspect_x = i;
zoom_aspect_y = j;
/* break the loop */
i = 21;
break;
}
712
}
713
}
714
715
716
717
718
719
720
721
#ifdef DIRECTFB_CRTC2_DEBUG
printf
("Source resolution: X: %d, Y: %d, Aspect ratio: %d:%d\n",
width, height, zoom_aspect_x, zoom_aspect_y);
printf("CRTC2 resolution: X: %d, Y: %d\n",
HIDDEN->c2framesize.w, HIDDEN->c2framesize.h);
#endif
722
723
724
725
726
727
728
729
730
731
732
733
734
/* don't stretch only slightly smaller/larger images */
if ((float) width < (float) HIDDEN->c2framesize.w * 0.95
|| (float) height < (float) HIDDEN->c2framesize.h * 0.95) {
while ((float) HIDDEN->c2dsize.w <
(float) HIDDEN->c2framesize.w *
HIDDEN->mga_crtc2_stretch_overscan
&& (float) HIDDEN->c2dsize.h <
(float) HIDDEN->c2framesize.h *
HIDDEN->mga_crtc2_stretch_overscan) {
HIDDEN->c2dsize.w += zoom_aspect_x;
HIDDEN->c2dsize.h += zoom_aspect_y;
}
735
736
737
738
/* one step down */
HIDDEN->c2dsize.w -= zoom_aspect_x;
HIDDEN->c2dsize.h -= zoom_aspect_y;
739
740
741
742
743
#ifdef DIRECTFB_CRTC2_DEBUG
printf("Stretched resolution: X: %d, Y: %d\n",
HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
#endif
744
745
746
747
748
749
750
751
752
753
754
755
756
757
HIDDEN->mga_crtc2_stretch = 1;
} else if ((float) width > (float) HIDDEN->c2framesize.w * 0.95
|| (float) height >
(float) HIDDEN->c2framesize.h * 0.95) {
while ((float) HIDDEN->c2dsize.w >
(float) HIDDEN->c2framesize.w *
HIDDEN->mga_crtc2_stretch_overscan
|| (float) HIDDEN->c2dsize.h >
(float) HIDDEN->c2framesize.h *
HIDDEN->mga_crtc2_stretch_overscan) {
HIDDEN->c2dsize.w -= zoom_aspect_x;
HIDDEN->c2dsize.h -= zoom_aspect_y;
}
758
759
760
761
762
#ifdef DIRECTFB_CRTC2_DEBUG
printf("Down-Stretched resolution: X: %d, Y: %d\n",
HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
#endif
763
764
765
766
767
768
769
HIDDEN->mga_crtc2_stretch = 1;
} else {
#ifdef DIRECTFB_CRTC2_DEBUG
printf("Not stretching image\n");
#endif
}
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
/* Panning */
if (HIDDEN->c2framesize.w > HIDDEN->c2dsize.w)
HIDDEN->c2dsize.x =
(HIDDEN->c2framesize.w - HIDDEN->c2dsize.w) / 2;
else
HIDDEN->c2dsize.x =
(HIDDEN->c2dsize.w - HIDDEN->c2framesize.w) / 2;
if (HIDDEN->c2framesize.h > HIDDEN->c2dsize.h)
HIDDEN->c2dsize.y =
(HIDDEN->c2framesize.h - HIDDEN->c2dsize.h) / 2;
else
HIDDEN->c2dsize.y =
(HIDDEN->c2dsize.h - HIDDEN->c2framesize.h) / 2;
#ifdef DIRECTFB_CRTC2_DEBUG
printf("CRTC2 position X: %d, Y: %d\n", HIDDEN->c2dsize.x,
HIDDEN->c2dsize.y);
#endif
}
}
792
793
794
return current;
}
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
static int
DirectFB_AllocHWSurface(_THIS, SDL_Surface * surface)
{
DFBResult ret;
DFBSurfaceDescription dsc;
/* fprintf(stderr, "SDL: DirectFB_AllocHWSurface (%dx%d@%d, flags: 0x%08x)\n",
surface->w, surface->h, surface->format->BitsPerPixel, surface->flags); */
if (surface->w < 8 || surface->h < 8)
return -1;
/* fill surface description */
dsc.flags =
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
dsc.width = surface->w;
dsc.height = surface->h;
dsc.caps = (surface->flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0;
/* find the right pixelformat */
dsc.pixelformat = SDLToDFBPixelFormat(surface->format);
if (dsc.pixelformat == DSPF_UNKNOWN)
return -1;
/* Allocate the hardware acceleration data */
surface->hwdata =
(struct private_hwdata *) SDL_calloc(1, sizeof(*surface->hwdata));
if (surface->hwdata == NULL) {
SDL_OutOfMemory();
return -1;
826
827
}
828
829
830
831
832
833
834
835
836
/* Create the surface */
ret =
HIDDEN->dfb->CreateSurface(HIDDEN->dfb, &dsc,
&surface->hwdata->surface);
if (ret) {
SetDirectFBerror("dfb->CreateSurface", ret);
free(surface->hwdata);
surface->hwdata = NULL;
return -1;
837
838
}
839
surface->flags |= SDL_HWSURFACE | SDL_PREALLOC;
840
841
return 0;
842
843
}
844
845
static void
DirectFB_FreeHWSurface(_THIS, SDL_Surface * surface)
846
{
847
848
849
850
if (surface->hwdata && HIDDEN->initialized) {
surface->hwdata->surface->Release(surface->hwdata->surface);
free(surface->hwdata);
surface->hwdata = NULL;
851
852
853
}
}
854
855
static int
DirectFB_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst)
856
{
857
858
/* fprintf(stderr, "SDL: DirectFB_CheckHWBlit (src->hwdata: %p, dst->hwdata: %p)\n",
src->hwdata, dst->hwdata); */
859
860
861
if (!src->hwdata || !dst->hwdata)
return 0;
862
863
864
src->flags |= SDL_HWACCEL;
src->map->hw_blit = DirectFB_HWAccelBlit;
865
866
return 1;
867
868
}
869
870
871
static int
DirectFB_HWAccelBlit(SDL_Surface * src, SDL_Rect * srcrect,
SDL_Surface * dst, SDL_Rect * dstrect)
872
{
873
DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
874
875
876
DFBRectangle sr = { srcrect->x, srcrect->y, srcrect->w, srcrect->h };
DFBRectangle dr = { dstrect->x, dstrect->y, dstrect->w, dstrect->h };
877
878
IDirectFBSurface *surface = dst->hwdata->surface;
879
880
881
882
if (src->flags & SDL_SRCCOLORKEY) {
flags |= DSBLIT_SRC_COLORKEY;
DirectFB_SetHWColorKey(NULL, src, src->format->colorkey);
883
884
}
885
886
887
if (src->flags & SDL_SRCALPHA) {
flags |= DSBLIT_BLEND_COLORALPHA;
surface->SetColor(surface, 0xff, 0xff, 0xff, src->format->alpha);
888
889
}
890
surface->SetBlittingFlags(surface, flags);
891
892
893
894
895
if (sr.w == dr.w && sr.h == dr.h)
surface->Blit(surface, src->hwdata->surface, &sr, dr.x, dr.y);
else
surface->StretchBlit(surface, src->hwdata->surface, &sr, &dr);
896
897
return 0;
898
899
}
900
901
902
static int
DirectFB_FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * dstrect,
Uint32 color)
903
{
904
905
SDL_PixelFormat *fmt = dst->format;
IDirectFBSurface *surface = dst->hwdata->surface;
906
907
908
909
910
911
912
913
914
/* ugly */
surface->SetColor(surface,
(color & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss),
(color & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss),
(color & fmt->Bmask) << (fmt->Bloss - fmt->Bshift),
0xFF);
surface->FillRectangle(surface, dstrect->x, dstrect->y, dstrect->w,
dstrect->h);
915
916
return 0;
917
918
}
919
920
static int
DirectFB_SetHWColorKey(_THIS, SDL_Surface * src, Uint32 key)
921
{
922
923
SDL_PixelFormat *fmt = src->format;
IDirectFBSurface *surface = src->hwdata->surface;
924
925
926
927
928
929
930
931
932
933
934
935
if (fmt->BitsPerPixel == 8)
surface->SetSrcColorKeyIndex(surface, key);
else
/* ugly */
surface->SetSrcColorKey(surface,
(key & fmt->Rmask) >> (fmt->Rshift -
fmt->Rloss),
(key & fmt->Gmask) >> (fmt->Gshift -
fmt->Gloss),
(key & fmt->Bmask) << (fmt->Bloss -
fmt->Bshift));
936
937
return 0;
938
939
}
940
941
static int
DirectFB_SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 alpha)
942
{
943
return 0;
944
945
}
946
947
static int
DirectFB_FlipHWSurface(_THIS, SDL_Surface * surface)
948
{
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
if (HIDDEN->enable_mga_crtc2) {
int rtn =
surface->hwdata->surface->Flip(surface->hwdata->surface, NULL,
0);
if (HIDDEN->mga_crtc2_stretch)
HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame,
surface->hwdata->surface,
&HIDDEN->c2ssize, &HIDDEN->c2dsize);
else
HIDDEN->c2frame->Blit(HIDDEN->c2frame,
surface->hwdata->surface, NULL,
HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
return rtn;
} else
return surface->hwdata->surface->Flip(surface->hwdata->surface, NULL,
DSFLIP_WAITFORSYNC);
967
968
}
969
970
static int
DirectFB_LockHWSurface(_THIS, SDL_Surface * surface)
971
{
972
973
974
975
976
977
978
979
980
DFBResult ret;
void *data;
int pitch;
ret = surface->hwdata->surface->Lock(surface->hwdata->surface,
DSLF_WRITE, &data, &pitch);
if (ret) {
SetDirectFBerror("surface->Lock", ret);
return -1;
981
982
}
983
984
surface->pixels = data;
surface->pitch = pitch;
985
986
return 0;
987
988
}
989
990
static void
DirectFB_UnlockHWSurface(_THIS, SDL_Surface * surface)
991
{
992
993
surface->hwdata->surface->Unlock(surface->hwdata->surface);
surface->pixels = NULL;
994
995
}
996
997
static void
DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect * rects)
998
{
999
1000
if (HIDDEN->enable_mga_crtc2) {
if (HIDDEN->mga_crtc2_stretch)