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
61
62
63
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);
static int DirectFB_SetColors(_THIS, int firstcolor, int ncolors,
SDL_Color * colors);
static void DirectFB_VideoQuit(_THIS);
64
65
/* 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
static int
97
DirectFB_Available(void)
98
{
99
return 1;
100
101
}
102
static void
103
DirectFB_DeleteDevice(SDL_VideoDevice * device)
104
{
105
106
SDL_free(device->hidden);
SDL_free(device);
107
108
}
109
static SDL_VideoDevice *
110
DirectFB_CreateDevice(int devindex)
111
{
112
113
114
SDL_VideoDevice *device;
/* Initialize all variables that we clean on shutdown */
115
device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice));
116
if (device) {
117
SDL_memset(device, 0, (sizeof *device));
118
device->hidden = (struct SDL_PrivateVideoData *)
119
malloc(sizeof(*device->hidden));
120
}
121
if (device == NULL || device->hidden == NULL) {
122
SDL_OutOfMemory();
123
if (device) {
124
free(device);
125
}
126
return (0);
127
}
128
SDL_memset(device->hidden, 0, sizeof(*device->hidden));
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
/* 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
static DFBSurfacePixelFormat
167
GetFormatForBpp(int bpp, IDirectFBDisplayLayer * layer)
168
{
169
170
DFBDisplayLayerConfig dlc;
int bytes = (bpp + 7) / 8;
171
172
layer->GetConfiguration(layer, &dlc);
173
174
if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat) && bytes > 1)
175
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
static DFBEnumerationResult
192
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
enumrect = SDL_calloc(1, sizeof(struct DirectFBEnumRect));
203
if (!enumrect) {
204
SDL_OutOfMemory();
205
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
void
224
SetDirectFBerror(const char *function, DFBResult code)
225
{
226
const char *error = DirectFBErrorString(code);
227
228
if (error)
229
SDL_SetError("%s: %s", function, error);
230
else
231
SDL_SetError("Unknown error code from %s", function);
232
233
}
234
static DFBSurfacePixelFormat
235
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
static SDL_Palette *
289
AllocatePalette(int size)
290
{
291
292
293
SDL_Palette *palette;
SDL_Color *colors;
294
palette = SDL_calloc(1, sizeof(SDL_Palette));
295
if (!palette) {
296
SDL_OutOfMemory();
297
return NULL;
298
299
}
300
colors = SDL_calloc(size, sizeof(SDL_Color));
301
if (!colors) {
302
SDL_OutOfMemory();
303
return NULL;
304
305
}
306
307
palette->ncolors = size;
palette->colors = colors;
308
309
return palette;
310
311
}
312
static int
313
314
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
if (!format->palette)
352
format->palette = AllocatePalette(256);
353
break;
354
355
default:
356
357
358
fprintf(stderr,
"SDL_DirectFB: Unsupported pixelformat (0x%08x)!\n",
pixelformat);
359
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
int
370
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
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;
389
ret = DirectFBInit(NULL, NULL);
390
if (ret) {
391
SetDirectFBerror("DirectFBInit", ret);
392
goto error;
393
394
}
395
ret = DirectFBCreate(&dfb);
396
if (ret) {
397
SetDirectFBerror("DirectFBCreate", ret);
398
goto error;
399
400
}
401
ret = dfb->GetDisplayLayer(dfb, DLID_PRIMARY, &layer);
402
if (ret) {
403
SetDirectFBerror("dfb->GetDisplayLayer", ret);
404
goto error;
405
406
}
407
ret = dfb->CreateInputEventBuffer(dfb, DICAPS_ALL, DFB_FALSE, &events);
408
if (ret) {
409
SetDirectFBerror("dfb->CreateEventBuffer", ret);
410
goto error;
411
}
412
413
layer->EnableCursor(layer, 1);
414
415
/* Query layer configuration to determine the current mode and pixelformat */
416
layer->GetConfiguration(layer, &dlc);
417
418
/* If current format is not supported use LUT8 as the default */
419
420
if (DFBToSDLPixelFormat(dlc.pixelformat, vformat))
DFBToSDLPixelFormat(DSPF_LUT8, vformat);
421
422
/* Enumerate the available fullscreen modes */
423
ret = dfb->EnumVideoModes(dfb, EnumModesCallback, this);
424
if (ret) {
425
SetDirectFBerror("dfb->EnumVideoModes", ret);
426
goto error;
427
}
428
429
HIDDEN->modelist = SDL_calloc(HIDDEN->nummodes + 1, sizeof(SDL_Rect *));
430
if (!HIDDEN->modelist) {
431
SDL_OutOfMemory();
432
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
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;
462
if (SDL_getenv("SDL_DIRECTFB_MGA_CRTC2") != NULL)
463
464
465
466
467
468
HIDDEN->enable_mga_crtc2 = 1;
if (HIDDEN->enable_mga_crtc2) {
DFBDisplayLayerConfig dlc;
DFBDisplayLayerConfigFlags failed;
469
ret = dfb->GetDisplayLayer(dfb, 2, &HIDDEN->c2layer);
470
if (ret) {
471
SetDirectFBerror("dfb->GetDisplayLayer(CRTC2)", ret);
472
goto error;
473
474
}
475
ret =
476
477
HIDDEN->layer->SetCooperativeLevel(HIDDEN->layer,
DLSCL_EXCLUSIVE);
478
479
480
481
if (ret) {
SetDirectFBerror
("layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret);
goto error;
482
}
483
484
ret =
485
486
HIDDEN->c2layer->SetCooperativeLevel(HIDDEN->c2layer,
DLSCL_EXCLUSIVE);
487
488
489
490
if (ret) {
SetDirectFBerror
("c2layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret);
goto error;
491
492
}
493
HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0x0);
494
495
496
497
498
499
500
/* 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 =
501
502
HIDDEN->c2layer->TestConfiguration(HIDDEN->c2layer, &dlc,
&failed);
503
if (ret) {
504
SetDirectFBerror("c2layer->TestConfiguration", ret);
505
goto error;
506
}
507
508
ret = HIDDEN->c2layer->SetConfiguration(HIDDEN->c2layer, &dlc);
509
if (ret) {
510
SetDirectFBerror("c2layer->SetConfiguration", ret);
511
goto error;
512
}
513
514
ret = HIDDEN->c2layer->GetSurface(HIDDEN->c2layer, &HIDDEN->c2frame);
515
if (ret) {
516
SetDirectFBerror("c2layer->GetSurface", ret);
517
goto error;
518
519
}
520
521
HIDDEN->c2framesize.x = 0;
HIDDEN->c2framesize.y = 0;
522
523
HIDDEN->c2frame->GetSize(HIDDEN->c2frame, &HIDDEN->c2framesize.w,
&HIDDEN->c2framesize.h);
524
525
526
HIDDEN->c2frame->SetBlittingFlags(HIDDEN->c2frame, DSBLIT_NOFX);
HIDDEN->c2frame->SetColor(HIDDEN->c2frame, 0, 0, 0, 0xff);
527
528
/* Clear CRTC2 */
529
530
531
532
533
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);
534
535
HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0xFF);
536
537
/* Check if overscan is possibly set */
538
if (SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN") != NULL) {
539
540
float overscan = 0;
if (SDL_sscanf
541
(SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN"), "%f",
542
543
544
545
546
&overscan) == 1)
if (overscan > 0 && overscan < 2)
HIDDEN->mga_crtc2_stretch_overscan = overscan;
}
#ifdef DIRECTFB_CRTC2_DEBUG
547
printf("CRTC2 overscan: %f\n", HIDDEN->mga_crtc2_stretch_overscan);
548
#endif
549
550
}
551
return 0;
552
553
554
error:
if (events)
555
events->Release(events);
556
557
if (HIDDEN->c2frame)
558
HIDDEN->c2frame->Release(HIDDEN->c2frame);
559
560
if (HIDDEN->c2layer)
561
HIDDEN->c2layer->Release(HIDDEN->c2layer);
562
563
if (layer)
564
layer->Release(layer);
565
566
if (dfb)
567
dfb->Release(dfb);
568
569
return -1;
570
571
}
572
static SDL_Rect **
573
DirectFB_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
574
{
575
576
if (flags & SDL_FULLSCREEN)
return HIDDEN->modelist;
577
else if (SDLToDFBPixelFormat(format) != DSPF_UNKNOWN)
578
return (SDL_Rect **) - 1;
579
580
return NULL;
581
582
}
583
static SDL_Surface *
584
585
DirectFB_SetVideoMode(_THIS, SDL_Surface * current, int width, int height,
int bpp, Uint32 flags)
586
{
587
588
589
590
591
DFBResult ret;
DFBSurfaceDescription dsc;
DFBSurfacePixelFormat pixelformat;
IDirectFBSurface *surface;
592
593
fprintf(stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n",
width, height, bpp, flags);
594
595
596
597
598
flags |= SDL_FULLSCREEN;
/* Release previous primary surface */
if (current->hwdata && current->hwdata->surface) {
599
current->hwdata->surface->Release(current->hwdata->surface);
600
601
602
603
current->hwdata->surface = NULL;
/* And its palette if present */
if (current->hwdata->palette) {
604
current->hwdata->palette->Release(current->hwdata->palette);
605
606
607
608
609
current->hwdata->palette = NULL;
}
} else if (!current->hwdata) {
/* Allocate the hardware acceleration data */
current->hwdata =
610
(struct private_hwdata *) SDL_calloc(1, sizeof(*current->hwdata));
611
if (!current->hwdata) {
612
SDL_OutOfMemory();
613
return NULL;
614
}
615
616
}
617
618
/* Set cooperative level depending on flag SDL_FULLSCREEN */
if (flags & SDL_FULLSCREEN) {
619
ret = HIDDEN->dfb->SetCooperativeLevel(HIDDEN->dfb, DFSCL_FULLSCREEN);
620
if (ret && !HIDDEN->enable_mga_crtc2) {
621
DirectFBError("dfb->SetCooperativeLevel", ret);
622
flags &= ~SDL_FULLSCREEN;
623
}
624
} else
625
HIDDEN->dfb->SetCooperativeLevel(HIDDEN->dfb, DFSCL_NORMAL);
626
627
/* Set video mode */
628
ret = HIDDEN->dfb->SetVideoMode(HIDDEN->dfb, width, height, bpp);
629
630
631
if (ret) {
if (flags & SDL_FULLSCREEN) {
flags &= ~SDL_FULLSCREEN;
632
633
HIDDEN->dfb->SetCooperativeLevel(HIDDEN->dfb, DFSCL_NORMAL);
ret = HIDDEN->dfb->SetVideoMode(HIDDEN->dfb, width, height, bpp);
634
635
}
636
if (ret) {
637
SetDirectFBerror("dfb->SetVideoMode", ret);
638
return NULL;
639
640
641
}
}
642
643
644
645
/* Create primary surface */
dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT;
dsc.caps =
DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
646
dsc.pixelformat = GetFormatForBpp(bpp, HIDDEN->layer);
647
648
ret = HIDDEN->dfb->CreateSurface(HIDDEN->dfb, &dsc, &surface);
649
650
651
if (ret && (flags & SDL_DOUBLEBUF)) {
/* Try without double buffering */
dsc.caps &= ~DSCAPS_FLIPPING;
652
ret = HIDDEN->dfb->CreateSurface(HIDDEN->dfb, &dsc, &surface);
653
}
654
if (ret) {
655
SetDirectFBerror("dfb->CreateSurface", ret);
656
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
/* Get the surface palette (if supported) */
677
678
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
/* 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;
698
if (SDL_getenv("SDL_DIRECTFB_MGA_STRETCH") != NULL) {
699
700
701
702
703
704
705
706
707
708
709
710
711
/* 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
#ifdef DIRECTFB_CRTC2_DEBUG
printf
("Source resolution: X: %d, Y: %d, Aspect ratio: %d:%d\n",
width, height, zoom_aspect_x, zoom_aspect_y);
719
720
printf("CRTC2 resolution: X: %d, Y: %d\n",
HIDDEN->c2framesize.w, HIDDEN->c2framesize.h);
721
#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
#ifdef DIRECTFB_CRTC2_DEBUG
741
742
printf("Stretched resolution: X: %d, Y: %d\n",
HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
743
#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
#ifdef DIRECTFB_CRTC2_DEBUG
760
761
printf("Down-Stretched resolution: X: %d, Y: %d\n",
HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
762
#endif
763
764
765
766
HIDDEN->mga_crtc2_stretch = 1;
} else {
#ifdef DIRECTFB_CRTC2_DEBUG
767
printf("Not stretching image\n");
768
769
#endif
}
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
/* 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
787
788
printf("CRTC2 position X: %d, Y: %d\n", HIDDEN->c2dsize.x,
HIDDEN->c2dsize.y);
789
790
791
#endif
}
}
792
793
794
return current;
}
795
796
static int
797
DirectFB_AllocHWSurface(_THIS, SDL_Surface * surface)
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
{
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 */
816
dsc.pixelformat = SDLToDFBPixelFormat(surface->format);
817
818
819
820
821
if (dsc.pixelformat == DSPF_UNKNOWN)
return -1;
/* Allocate the hardware acceleration data */
surface->hwdata =
822
(struct private_hwdata *) SDL_calloc(1, sizeof(*surface->hwdata));
823
if (surface->hwdata == NULL) {
824
SDL_OutOfMemory();
825
return -1;
826
827
}
828
829
/* Create the surface */
ret =
830
831
HIDDEN->dfb->CreateSurface(HIDDEN->dfb, &dsc,
&surface->hwdata->surface);
832
if (ret) {
833
834
SetDirectFBerror("dfb->CreateSurface", ret);
free(surface->hwdata);
835
836
surface->hwdata = NULL;
return -1;
837
838
}
839
surface->flags |= SDL_HWSURFACE | SDL_PREALLOC;
840
841
return 0;
842
843
}
844
static void
845
DirectFB_FreeHWSurface(_THIS, SDL_Surface * surface)
846
{
847
if (surface->hwdata && HIDDEN->initialized) {
848
849
surface->hwdata->surface->Release(surface->hwdata->surface);
free(surface->hwdata);
850
surface->hwdata = NULL;
851
852
853
}
}
854
static int
855
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
static int
870
871
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
if (src->flags & SDL_SRCCOLORKEY) {
flags |= DSBLIT_SRC_COLORKEY;
882
DirectFB_SetHWColorKey(NULL, src, src->format->colorkey);
883
884
}
885
886
if (src->flags & SDL_SRCALPHA) {
flags |= DSBLIT_BLEND_COLORALPHA;
887
surface->SetColor(surface, 0xff, 0xff, 0xff, src->format->alpha);
888
889
}
890
surface->SetBlittingFlags(surface, flags);
891
892
if (sr.w == dr.w && sr.h == dr.h)
893
surface->Blit(surface, src->hwdata->surface, &sr, dr.x, dr.y);
894
else
895
surface->StretchBlit(surface, src->hwdata->surface, &sr, &dr);
896
897
return 0;
898
899
}
900
static int
901
902
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
/* ugly */
908
909
910
911
912
913
914
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
static int
920
DirectFB_SetHWColorKey(_THIS, SDL_Surface * src, Uint32 key)
921
{
922
923
SDL_PixelFormat *fmt = src->format;
IDirectFBSurface *surface = src->hwdata->surface;
924
925
if (fmt->BitsPerPixel == 8)
926
surface->SetSrcColorKeyIndex(surface, key);
927
928
else
/* ugly */
929
930
931
932
933
934
935
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
static int
941
DirectFB_SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 alpha)
942
{
943
return 0;
944
945
}
946
static int
947
DirectFB_FlipHWSurface(_THIS, SDL_Surface * surface)
948
{
949
950
if (HIDDEN->enable_mga_crtc2) {
int rtn =
951
952
surface->hwdata->surface->Flip(surface->hwdata->surface, NULL,
0);
953
if (HIDDEN->mga_crtc2_stretch)
954
955
956
HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame,
surface->hwdata->surface,
&HIDDEN->c2ssize, &HIDDEN->c2dsize);
957
else
958
959
960
HIDDEN->c2frame->Blit(HIDDEN->c2frame,
surface->hwdata->surface, NULL,
HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
961
962
HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
963
964
return rtn;
} else
965
966
return surface->hwdata->surface->Flip(surface->hwdata->surface, NULL,
DSFLIP_WAITFORSYNC);
967
968
}
969
static int
970
DirectFB_LockHWSurface(_THIS, SDL_Surface * surface)
971
{
972
973
974
975
DFBResult ret;
void *data;
int pitch;
976
977
ret = surface->hwdata->surface->Lock(surface->hwdata->surface,
DSLF_WRITE, &data, &pitch);
978
if (ret) {
979
SetDirectFBerror("surface->Lock", ret);
980
return -1;
981
982
}
983
984
surface->pixels = data;
surface->pitch = pitch;
985
986
return 0;
987
988
}
989
static void
990
DirectFB_UnlockHWSurface(_THIS, SDL_Surface * surface)
991
{
992
surface->hwdata->surface->Unlock(surface->hwdata->surface);
993
surface->pixels = NULL;
994
995
}
996
static void
997
DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect * rects)
998
{
999
1000
if (HIDDEN->enable_mga_crtc2) {
if (HIDDEN->mga_crtc2_stretch)