Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
1178 lines (965 loc) · 34 KB

SDL_DirectFB_video.c

File metadata and controls

1178 lines (965 loc) · 34 KB
 
Feb 1, 2006
Feb 1, 2006
2
3
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
Feb 1, 2006
Feb 1, 2006
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.
Feb 1, 2006
Feb 1, 2006
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.
Feb 1, 2006
Feb 1, 2006
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
Feb 1, 2006
Feb 1, 2006
19
20
Sam Lantinga
slouken@libsdl.org
Oct 3, 2003
Oct 3, 2003
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>
Feb 21, 2006
Feb 21, 2006
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>
Nov 1, 2005
Nov 1, 2005
36
#include <directfb_version.h>
37
38
39
#include "SDL_video.h"
#include "SDL_mouse.h"
Feb 16, 2006
Feb 16, 2006
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"
Aug 31, 2002
Aug 31, 2002
45
#include "SDL_DirectFB_yuv.h"
Jan 4, 2004
Jan 4, 2004
47
/* The implementation dependent data for the window manager cursor */
Jul 10, 2006
Jul 10, 2006
48
49
50
struct WMcursor
{
int unused;
Jan 4, 2004
Jan 4, 2004
51
52
};
53
54
/* Initialization/Query functions */
Jul 10, 2006
Jul 10, 2006
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,
Jul 10, 2006
Jul 10, 2006
62
SDL_Color * colors);
63
64
65
static void DirectFB_VideoQuit(_THIS);
/* Hardware surface functions */
Jul 10, 2006
Jul 10, 2006
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 */
Jul 10, 2006
Jul 10, 2006
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 */
Jul 10, 2006
Jul 10, 2006
85
86
87
88
struct DirectFBEnumRect
{
SDL_Rect r;
struct DirectFBEnumRect *next;
Aug 24, 2002
Aug 24, 2002
91
static struct DirectFBEnumRect *enumlist = NULL;
92
93
94
95
/* DirectFB driver bootstrap functions */
Jul 10, 2006
Jul 10, 2006
96
97
static int
DirectFB_Available(void)
Jul 10, 2006
Jul 10, 2006
99
return 1;
Jul 10, 2006
Jul 10, 2006
102
103
static void
DirectFB_DeleteDevice(SDL_VideoDevice * device)
Jul 10, 2006
Jul 10, 2006
105
106
SDL_free(device->hidden);
SDL_free(device);
Jul 10, 2006
Jul 10, 2006
109
110
static SDL_VideoDevice *
DirectFB_CreateDevice(int devindex)
Jul 10, 2006
Jul 10, 2006
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));
Jul 10, 2006
Jul 10, 2006
121
122
123
124
if (device == NULL || device->hidden == NULL) {
SDL_OutOfMemory();
if (device) {
free(device);
Jul 10, 2006
Jul 10, 2006
126
return (0);
Jul 10, 2006
Jul 10, 2006
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 = {
Jul 10, 2006
Jul 10, 2006
162
163
"directfb", "DirectFB",
DirectFB_Available, DirectFB_CreateDevice
Jul 10, 2006
Jul 10, 2006
166
167
static DFBSurfacePixelFormat
GetFormatForBpp(int bpp, IDirectFBDisplayLayer * layer)
Aug 24, 2002
Aug 24, 2002
168
{
Jul 10, 2006
Jul 10, 2006
169
170
DFBDisplayLayerConfig dlc;
int bytes = (bpp + 7) / 8;
Aug 24, 2002
Aug 24, 2002
171
Jul 10, 2006
Jul 10, 2006
172
layer->GetConfiguration(layer, &dlc);
Aug 24, 2002
Aug 24, 2002
173
Jul 10, 2006
Jul 10, 2006
174
175
if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat) && bytes > 1)
return dlc.pixelformat;
Aug 24, 2002
Aug 24, 2002
176
Jul 10, 2006
Jul 10, 2006
177
switch (bytes) {
Aug 24, 2002
Aug 24, 2002
178
case 1:
Jul 10, 2006
Jul 10, 2006
179
return DSPF_LUT8;
Aug 24, 2002
Aug 24, 2002
180
case 2:
Jul 10, 2006
Jul 10, 2006
181
return DSPF_RGB16;
Aug 24, 2002
Aug 24, 2002
182
case 3:
Jul 10, 2006
Jul 10, 2006
183
return DSPF_RGB24;
Aug 24, 2002
Aug 24, 2002
184
case 4:
Jul 10, 2006
Jul 10, 2006
185
return DSPF_RGB32;
Aug 24, 2002
Aug 24, 2002
186
187
}
Jul 10, 2006
Jul 10, 2006
188
return DSPF_UNKNOWN;
Aug 24, 2002
Aug 24, 2002
189
190
}
Jul 10, 2006
Jul 10, 2006
191
192
static DFBEnumerationResult
EnumModesCallback(int width, int height, int bpp, void *data)
Jul 10, 2006
Jul 10, 2006
194
195
SDL_VideoDevice *this = (SDL_VideoDevice *) data;
struct DirectFBEnumRect *enumrect;
Jul 10, 2006
Jul 10, 2006
197
HIDDEN->nummodes++;
Aug 24, 2002
Aug 24, 2002
198
Jul 10, 2006
Jul 10, 2006
199
200
if (enumlist && enumlist->r.w == width && enumlist->r.h == height)
return DFENUM_OK;
May 8, 2006
May 8, 2006
201
Jul 10, 2006
Jul 10, 2006
202
203
204
205
enumrect = SDL_calloc(1, sizeof(struct DirectFBEnumRect));
if (!enumrect) {
SDL_OutOfMemory();
return DFENUM_CANCEL;
Jul 10, 2006
Jul 10, 2006
208
209
210
enumrect->r.w = (Uint16) width;
enumrect->r.h = (Uint16) height;
enumrect->next = enumlist;
Aug 24, 2002
Aug 24, 2002
211
Jul 10, 2006
Jul 10, 2006
212
enumlist = enumrect;
Aug 24, 2002
Aug 24, 2002
213
Jul 10, 2006
Jul 10, 2006
214
return DFENUM_OK;
Jul 10, 2006
Jul 10, 2006
217
218
219
220
struct private_hwdata
{
IDirectFBSurface *surface;
IDirectFBPalette *palette;
Jul 10, 2006
Jul 10, 2006
223
224
void
SetDirectFBerror(const char *function, DFBResult code)
Jul 10, 2006
Jul 10, 2006
226
const char *error = DirectFBErrorString(code);
Jul 10, 2006
Jul 10, 2006
228
229
230
231
if (error)
SDL_SetError("%s: %s", function, error);
else
SDL_SetError("Unknown error code from %s", function);
Jul 10, 2006
Jul 10, 2006
234
235
static DFBSurfacePixelFormat
SDLToDFBPixelFormat(SDL_PixelFormat * format)
Jul 10, 2006
Jul 10, 2006
237
238
if (format->Rmask && format->Gmask && format->Bmask) {
switch (format->BitsPerPixel) {
Aug 31, 2002
Aug 31, 2002
239
case 8:
Jul 10, 2006
Jul 10, 2006
240
241
return DSPF_LUT8;
Jul 10, 2006
Jul 10, 2006
243
244
245
246
247
if (format->Rmask == 0xF800 &&
format->Gmask == 0x07E0 && format->Bmask == 0x001F)
return DSPF_RGB16;
/* fall through */
Jul 10, 2006
Jul 10, 2006
249
250
251
252
253
if (format->Rmask == 0x7C00 &&
format->Gmask == 0x03E0 && format->Bmask == 0x001F)
return DSPF_ARGB1555;
break;
Jul 10, 2006
Jul 10, 2006
255
256
257
258
if (format->Rmask == 0xFF0000 &&
format->Gmask == 0x00FF00 && format->Bmask == 0x0000FF)
return DSPF_RGB24;
break;
Aug 24, 2002
Aug 24, 2002
259
Jul 10, 2006
Jul 10, 2006
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;
Jul 10, 2006
Jul 10, 2006
268
break;
Jul 10, 2006
Jul 10, 2006
270
271
} else {
switch (format->BitsPerPixel) {
Aug 24, 2002
Aug 24, 2002
272
case 8:
Jul 10, 2006
Jul 10, 2006
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;
}
Jul 10, 2006
Jul 10, 2006
285
return DSPF_UNKNOWN;
Jul 10, 2006
Jul 10, 2006
288
289
static SDL_Palette *
AllocatePalette(int size)
Aug 24, 2002
Aug 24, 2002
290
{
Jul 10, 2006
Jul 10, 2006
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;
Aug 24, 2002
Aug 24, 2002
298
299
}
Jul 10, 2006
Jul 10, 2006
300
301
302
303
colors = SDL_calloc(size, sizeof(SDL_Color));
if (!colors) {
SDL_OutOfMemory();
return NULL;
Aug 24, 2002
Aug 24, 2002
304
305
}
Jul 10, 2006
Jul 10, 2006
306
307
palette->ncolors = size;
palette->colors = colors;
Aug 24, 2002
Aug 24, 2002
308
Jul 10, 2006
Jul 10, 2006
309
return palette;
Aug 24, 2002
Aug 24, 2002
310
311
}
Jul 10, 2006
Jul 10, 2006
312
313
314
static int
DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat,
SDL_PixelFormat * format)
Jul 10, 2006
Jul 10, 2006
316
317
format->Amask = format->Rmask = format->Gmask = format->Bmask = 0;
format->BitsPerPixel = format->BytesPerPixel = 0;
Jul 10, 2006
Jul 10, 2006
319
switch (pixelformat) {
320
case DSPF_A8:
Jul 10, 2006
Jul 10, 2006
321
322
format->Amask = 0x000000FF;
break;
Aug 24, 2002
Aug 24, 2002
323
Jan 28, 2004
Jan 28, 2004
324
case DSPF_ARGB1555:
Jul 10, 2006
Jul 10, 2006
325
326
327
328
format->Rmask = 0x00007C00;
format->Gmask = 0x000003E0;
format->Bmask = 0x0000001F;
break;
Aug 24, 2002
Aug 24, 2002
329
330
case DSPF_RGB16:
Jul 10, 2006
Jul 10, 2006
331
332
333
334
format->Rmask = 0x0000F800;
format->Gmask = 0x000007E0;
format->Bmask = 0x0000001F;
break;
Aug 24, 2002
Aug 24, 2002
335
336
case DSPF_ARGB:
Jul 10, 2006
Jul 10, 2006
337
338
format->Amask = 0; /* apps don't seem to like that: 0xFF000000; */
/* fall through */
339
340
case DSPF_RGB24:
case DSPF_RGB32:
Jul 10, 2006
Jul 10, 2006
341
342
343
344
format->Rmask = 0x00FF0000;
format->Gmask = 0x0000FF00;
format->Bmask = 0x000000FF;
break;
Aug 24, 2002
Aug 24, 2002
345
Aug 31, 2002
Aug 31, 2002
346
case DSPF_LUT8:
Jul 10, 2006
Jul 10, 2006
347
348
349
format->Rmask = 0x000000FF;
format->Gmask = 0x000000FF;
format->Bmask = 0x000000FF;
Aug 24, 2002
Aug 24, 2002
350
Jul 10, 2006
Jul 10, 2006
351
352
353
if (!format->palette)
format->palette = AllocatePalette(256);
break;
Aug 24, 2002
Aug 24, 2002
354
Jul 10, 2006
Jul 10, 2006
356
357
358
359
fprintf(stderr,
"SDL_DirectFB: Unsupported pixelformat (0x%08x)!\n",
pixelformat);
return -1;
Jul 10, 2006
Jul 10, 2006
362
363
format->BitsPerPixel = DFB_BYTES_PER_PIXEL(pixelformat) * 8;
format->BytesPerPixel = DFB_BYTES_PER_PIXEL(pixelformat);
Jul 10, 2006
Jul 10, 2006
365
return 0;
Jul 10, 2006
Jul 10, 2006
369
370
int
DirectFB_VideoInit(_THIS, SDL_PixelFormat * vformat)
Jul 10, 2006
Jul 10, 2006
372
373
int i;
DFBResult ret;
Nov 1, 2005
Nov 1, 2005
374
#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
Jul 10, 2006
Jul 10, 2006
375
DFBCardCapabilities caps;
Nov 1, 2005
Nov 1, 2005
376
#else
Jul 10, 2006
Jul 10, 2006
377
DFBGraphicsDeviceDescription caps;
Nov 1, 2005
Nov 1, 2005
378
#endif
Jul 10, 2006
Jul 10, 2006
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;
Jul 10, 2006
Jul 10, 2006
395
396
397
398
ret = DirectFBCreate(&dfb);
if (ret) {
SetDirectFBerror("DirectFBCreate", ret);
goto error;
Jul 10, 2006
Jul 10, 2006
401
402
403
404
ret = dfb->GetDisplayLayer(dfb, DLID_PRIMARY, &layer);
if (ret) {
SetDirectFBerror("dfb->GetDisplayLayer", ret);
goto error;
Jul 10, 2006
Jul 10, 2006
407
408
409
410
ret = dfb->CreateInputEventBuffer(dfb, DICAPS_ALL, DFB_FALSE, &events);
if (ret) {
SetDirectFBerror("dfb->CreateEventBuffer", ret);
goto error;
Jul 10, 2006
Jul 10, 2006
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;
Aug 24, 2002
Aug 24, 2002
428
Jul 10, 2006
Jul 10, 2006
429
430
431
432
HIDDEN->modelist = SDL_calloc(HIDDEN->nummodes + 1, sizeof(SDL_Rect *));
if (!HIDDEN->modelist) {
SDL_OutOfMemory();
goto error;
Aug 24, 2002
Aug 24, 2002
433
434
}
Jul 10, 2006
Jul 10, 2006
435
436
for (i = 0, rect = enumlist; rect; ++i, rect = rect->next) {
HIDDEN->modelist[i] = &rect->r;
Jul 10, 2006
Jul 10, 2006
439
HIDDEN->modelist[i] = NULL;
Aug 24, 2002
Aug 24, 2002
440
441
Jul 10, 2006
Jul 10, 2006
442
/* Query card capabilities to get the video memory size */
Nov 1, 2005
Nov 1, 2005
443
#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
Jul 10, 2006
Jul 10, 2006
444
dfb->GetCardCapabilities(dfb, &caps);
Nov 1, 2005
Nov 1, 2005
445
#else
Jul 10, 2006
Jul 10, 2006
446
dfb->GetDeviceDescription(dfb, &caps);
Nov 1, 2005
Nov 1, 2005
447
#endif
Jul 10, 2006
Jul 10, 2006
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;
Oct 3, 2003
Oct 3, 2003
473
474
}
Jul 10, 2006
Jul 10, 2006
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;
Oct 3, 2003
Oct 3, 2003
482
}
Jul 10, 2006
Jul 10, 2006
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;
Oct 3, 2003
Oct 3, 2003
491
492
}
Jul 10, 2006
Jul 10, 2006
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;
Oct 3, 2003
Oct 3, 2003
506
}
Jul 10, 2006
Jul 10, 2006
507
508
509
510
511
ret = HIDDEN->c2layer->SetConfiguration(HIDDEN->c2layer, &dlc);
if (ret) {
SetDirectFBerror("c2layer->SetConfiguration", ret);
goto error;
Oct 3, 2003
Oct 3, 2003
512
}
Jul 10, 2006
Jul 10, 2006
513
514
515
516
517
ret = HIDDEN->c2layer->GetSurface(HIDDEN->c2layer, &HIDDEN->c2frame);
if (ret) {
SetDirectFBerror("c2layer->GetSurface", ret);
goto error;
Oct 3, 2003
Oct 3, 2003
518
519
}
Jul 10, 2006
Jul 10, 2006
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
Oct 3, 2003
Oct 3, 2003
549
550
}
Jul 10, 2006
Jul 10, 2006
551
return 0;
Aug 24, 2002
Aug 24, 2002
552
Jul 10, 2006
Jul 10, 2006
553
554
555
error:
if (events)
events->Release(events);
Oct 3, 2003
Oct 3, 2003
556
Jul 10, 2006
Jul 10, 2006
557
558
if (HIDDEN->c2frame)
HIDDEN->c2frame->Release(HIDDEN->c2frame);
Oct 3, 2003
Oct 3, 2003
559
Jul 10, 2006
Jul 10, 2006
560
561
if (HIDDEN->c2layer)
HIDDEN->c2layer->Release(HIDDEN->c2layer);
Aug 24, 2002
Aug 24, 2002
562
Jul 10, 2006
Jul 10, 2006
563
564
if (layer)
layer->Release(layer);
Aug 24, 2002
Aug 24, 2002
565
Jul 10, 2006
Jul 10, 2006
566
567
568
569
if (dfb)
dfb->Release(dfb);
return -1;
Jul 10, 2006
Jul 10, 2006
572
573
static SDL_Rect **
DirectFB_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
Jul 10, 2006
Jul 10, 2006
575
576
577
578
if (flags & SDL_FULLSCREEN)
return HIDDEN->modelist;
else if (SDLToDFBPixelFormat(format) != DSPF_UNKNOWN)
return (SDL_Rect **) - 1;
Jul 10, 2006
Jul 10, 2006
580
return NULL;
Jul 10, 2006
Jul 10, 2006
583
584
585
static SDL_Surface *
DirectFB_SetVideoMode(_THIS, SDL_Surface * current, int width, int height,
int bpp, Uint32 flags)
Jul 10, 2006
Jul 10, 2006
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;
Aug 31, 2002
Aug 31, 2002
614
}
Jul 10, 2006
Jul 10, 2006
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;
Jul 10, 2006
Jul 10, 2006
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);
Jul 10, 2006
Jul 10, 2006
636
637
638
if (ret) {
SetDirectFBerror("dfb->SetVideoMode", ret);
return NULL;
Jul 10, 2006
Jul 10, 2006
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);
Jul 10, 2006
Jul 10, 2006
654
655
656
if (ret) {
SetDirectFBerror("dfb->CreateSurface", ret);
return NULL;
Jul 10, 2006
Jul 10, 2006
659
660
661
current->w = width;
current->h = height;
current->flags = SDL_HWSURFACE | SDL_PREALLOC;
Jul 10, 2006
Jul 10, 2006
663
664
665
666
667
if (flags & SDL_FULLSCREEN) {
current->flags |= SDL_FULLSCREEN;
this->UpdateRects = DirectFB_DirectUpdate;
} else
this->UpdateRects = DirectFB_WindowedUpdate;
Jul 10, 2006
Jul 10, 2006
669
670
if (dsc.caps & DSCAPS_FLIPPING)
current->flags |= SDL_DOUBLEBUF;
Jul 10, 2006
Jul 10, 2006
672
surface->GetPixelFormat(surface, &pixelformat);
Aug 31, 2002
Aug 31, 2002
673
Jul 10, 2006
Jul 10, 2006
674
DFBToSDLPixelFormat(pixelformat, current->format);
Jul 10, 2006
Jul 10, 2006
676
677
678
/* Get the surface palette (if supported) */
if (DFB_PIXELFORMAT_IS_INDEXED(pixelformat)) {
surface->GetPalette(surface, &current->hwdata->palette);
Aug 31, 2002
Aug 31, 2002
679
Jul 10, 2006
Jul 10, 2006
680
current->flags |= SDL_HWPALETTE;
Aug 31, 2002
Aug 31, 2002
681
682
}
Jul 10, 2006
Jul 10, 2006
683
current->hwdata->surface = surface;
Oct 3, 2003
Oct 3, 2003
684
Jul 10, 2006
Jul 10, 2006
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;
}
Oct 3, 2003
Oct 3, 2003
712
}
Jul 10, 2006
Jul 10, 2006
713
}
Oct 3, 2003
Oct 3, 2003
714
Jul 10, 2006
Jul 10, 2006
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
Oct 3, 2003
Oct 3, 2003
722
Jul 10, 2006
Jul 10, 2006
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;
}
Oct 3, 2003
Oct 3, 2003
735
Jul 10, 2006
Jul 10, 2006
736
737
738
/* one step down */
HIDDEN->c2dsize.w -= zoom_aspect_x;
HIDDEN->c2dsize.h -= zoom_aspect_y;
Oct 3, 2003
Oct 3, 2003
739
Jul 10, 2006
Jul 10, 2006
740
741
742
743
#ifdef DIRECTFB_CRTC2_DEBUG
printf("Stretched resolution: X: %d, Y: %d\n",
HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
#endif
Jul 10, 2006
Jul 10, 2006
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;
}
Jul 10, 2006
Jul 10, 2006
759
760
761
762
#ifdef DIRECTFB_CRTC2_DEBUG
printf("Down-Stretched resolution: X: %d, Y: %d\n",
HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
#endif
Jul 10, 2006
Jul 10, 2006
764
765
766
767
768
769
HIDDEN->mga_crtc2_stretch = 1;
} else {
#ifdef DIRECTFB_CRTC2_DEBUG
printf("Not stretching image\n");
#endif
}
Jul 10, 2006
Jul 10, 2006
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
}
}
Jul 10, 2006
Jul 10, 2006
793
794
return current;
}
Jul 10, 2006
Jul 10, 2006
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;
Jul 10, 2006
Jul 10, 2006
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;
Jul 10, 2006
Jul 10, 2006
839
surface->flags |= SDL_HWSURFACE | SDL_PREALLOC;
Jul 10, 2006
Jul 10, 2006
841
return 0;
Jul 10, 2006
Jul 10, 2006
844
845
static void
DirectFB_FreeHWSurface(_THIS, SDL_Surface * surface)
Jul 10, 2006
Jul 10, 2006
847
848
849
850
if (surface->hwdata && HIDDEN->initialized) {
surface->hwdata->surface->Release(surface->hwdata->surface);
free(surface->hwdata);
surface->hwdata = NULL;
Jul 10, 2006
Jul 10, 2006
854
855
static int
DirectFB_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst)
Jul 10, 2006
Jul 10, 2006
857
858
/* fprintf(stderr, "SDL: DirectFB_CheckHWBlit (src->hwdata: %p, dst->hwdata: %p)\n",
src->hwdata, dst->hwdata); */
Jul 10, 2006
Jul 10, 2006
860
861
if (!src->hwdata || !dst->hwdata)
return 0;
Jul 10, 2006
Jul 10, 2006
863
864
src->flags |= SDL_HWACCEL;
src->map->hw_blit = DirectFB_HWAccelBlit;
Jul 10, 2006
Jul 10, 2006
866
return 1;
Jul 10, 2006
Jul 10, 2006
869
870
871
static int
DirectFB_HWAccelBlit(SDL_Surface * src, SDL_Rect * srcrect,
SDL_Surface * dst, SDL_Rect * dstrect)
Jul 10, 2006
Jul 10, 2006
873
DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
Jul 10, 2006
Jul 10, 2006
875
876
DFBRectangle sr = { srcrect->x, srcrect->y, srcrect->w, srcrect->h };
DFBRectangle dr = { dstrect->x, dstrect->y, dstrect->w, dstrect->h };
Jul 10, 2006
Jul 10, 2006
878
IDirectFBSurface *surface = dst->hwdata->surface;
Jul 10, 2006
Jul 10, 2006
880
881
882
if (src->flags & SDL_SRCCOLORKEY) {
flags |= DSBLIT_SRC_COLORKEY;
DirectFB_SetHWColorKey(NULL, src, src->format->colorkey);
Jul 10, 2006
Jul 10, 2006
885
886
887
if (src->flags & SDL_SRCALPHA) {
flags |= DSBLIT_BLEND_COLORALPHA;
surface->SetColor(surface, 0xff, 0xff, 0xff, src->format->alpha);
Jul 10, 2006
Jul 10, 2006
890
surface->SetBlittingFlags(surface, flags);
Jul 10, 2006
Jul 10, 2006
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);
Jul 10, 2006
Jul 10, 2006
897
return 0;
Jul 10, 2006
Jul 10, 2006
900
901
902
static int
DirectFB_FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * dstrect,
Uint32 color)
Jul 10, 2006
Jul 10, 2006
904
905
SDL_PixelFormat *fmt = dst->format;
IDirectFBSurface *surface = dst->hwdata->surface;
Jul 10, 2006
Jul 10, 2006
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);
Jul 10, 2006
Jul 10, 2006
916
return 0;
Jul 10, 2006
Jul 10, 2006
919
920
static int
DirectFB_SetHWColorKey(_THIS, SDL_Surface * src, Uint32 key)
Jul 10, 2006
Jul 10, 2006
922
923
SDL_PixelFormat *fmt = src->format;
IDirectFBSurface *surface = src->hwdata->surface;
Nov 1, 2001
Nov 1, 2001
924
Jul 10, 2006
Jul 10, 2006
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));
Nov 1, 2001
Nov 1, 2001
936
Jul 10, 2006
Jul 10, 2006
937
return 0;
Jul 10, 2006
Jul 10, 2006
940
941
static int
DirectFB_SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 alpha)
Jul 10, 2006
Jul 10, 2006
943
return 0;
Jul 10, 2006
Jul 10, 2006
946
947
static int
DirectFB_FlipHWSurface(_THIS, SDL_Surface * surface)
Jul 10, 2006
Jul 10, 2006
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);
Jul 10, 2006
Jul 10, 2006
969
970
static int
DirectFB_LockHWSurface(_THIS, SDL_Surface * surface)
Jul 10, 2006
Jul 10, 2006
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;
Jul 10, 2006
Jul 10, 2006
983
984
surface->pixels = data;
surface->pitch = pitch;
Jul 10, 2006
Jul 10, 2006
986
return 0;
Jul 10, 2006
Jul 10, 2006
989
990
static void
DirectFB_UnlockHWSurface(_THIS, SDL_Surface * surface)
Jul 10, 2006
Jul 10, 2006
992
993
surface->hwdata->surface->Unlock(surface->hwdata->surface);
surface->pixels = NULL;
Jul 10, 2006
Jul 10, 2006
996
997
static void
DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect * rects)
Jul 10, 2006
Jul 10, 2006
999
1000
if (HIDDEN->enable_mga_crtc2) {
if (HIDDEN->mga_crtc2_stretch)