Commit 2de3ba20 authored by Sam Lantinga's avatar Sam Lantinga

Date: Sat, 11 Aug 2007 02:03:16 +0200 (CEST)

From: couriersud arcor.de
To: slouken@libsdl.org
Subject: Directfb driver for SDL1.3

Hi,

the attachment contains a patch for a SDL1.3 directfb driver. It supports:

- Renderer "directfb":

Hardware acceleration as supported by the underlying directfb driver. With a
radeon X850, testsprite2 runs at 50% to 70% of OpenGL (X11, dri) performance.

Also supports hardware accelerated yuv overlays. This must be enabled by sett
ing:

export SDL_DIRECTFB_YUV_DIRECT=1

- Renderer "opengl"

Supports software opengl using mesa opengl (make linux-directfb).

Some more information may be found in README.DirectFB

There will certainly still be some bugs, and there is some debug code around.
 When I find some time, I will compile against directfb-0.9.25 as distributed
 with ubuntu 7.04.

The diff also contains a fix for SDL_LockYUVOverlay fixing a bug in  *pixels
and pitches initialization.

Kind regards,

couriersud

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402588
parent fa64b7b1
SDL on DirectFB
Supports:
- Hardware YUV overlays
- OpenGL - software only
- 2D/3D accelerations (depends on directfb driver)
What you need:
DirectFB 1.0.0 - required
Kernel-Framebuffer support: required: vesafb, radeonfb ....
Mesa 7.0.x - optional for OpenGL
As of this writing 20070810 you need to pull Mesa from git and do the following:
------------------------
cd mesa
make linux-directfb
make
echo Installing - pleaser enter sudo pw.
sudo make install INSTALL_DIR=/usr/local/dfb_GL
cd src/mesa/drivers/directfb
make
sudo make install INSTALL_DIR=/usr/local/dfb_GL
------------------------
To run the SDL - testprograms:
export SDL_VIDEODRIVER=directfb
export LD_LIBRARY_PATH=/usr/local/dfb_GL/lib
export LD_PRELOAD=/usr/local/dfb_GL/libGL.so.7
./testgl
To use hardware accelerated YUV-overlays for YUV-textures, use:
export SDL_DIRECTFB_YUV_DIRECT=1
This is disabled by default. It will only support one concurrent
overlay and may behave strange if not used with SDL_CreateYUvOverlay
from SDLcompat.c.
...@@ -1440,19 +1440,21 @@ SDL_LockYUVOverlay(SDL_Overlay * overlay) ...@@ -1440,19 +1440,21 @@ SDL_LockYUVOverlay(SDL_Overlay * overlay)
< 0) { < 0) {
return -1; return -1;
} }
overlay->pixels[0] = (Uint8 *) pixels;
overlay->pitches[0] = pitch;
switch (overlay->format) { switch (overlay->format) {
case SDL_YV12_OVERLAY: case SDL_YV12_OVERLAY:
case SDL_IYUV_OVERLAY: case SDL_IYUV_OVERLAY:
overlay->pixels[0] = (Uint8 *) pixels; overlay->pitches[1] = pitch / 2;
overlay->pitches[2] = pitch / 2;
overlay->pixels[1] = overlay->pixels[1] =
overlay->pixels[0] + overlay->pitches[0] * overlay->h; overlay->pixels[0] + overlay->pitches[0] * overlay->h;
overlay->pixels[2] = overlay->pixels[2] =
overlay->pixels[1] + overlay->pitches[1] * overlay->h; overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2;
break; break;
case SDL_YUY2_OVERLAY: case SDL_YUY2_OVERLAY:
case SDL_UYVY_OVERLAY: case SDL_UYVY_OVERLAY:
case SDL_YVYU_OVERLAY: case SDL_YVYU_OVERLAY:
overlay->pixels[0] = (Uint8 *) pixels;
break; break;
} }
return 0; return 0;
......
This diff is collapsed.
...@@ -25,5 +25,4 @@ ...@@ -25,5 +25,4 @@
/* Functions to be exported */ /* Functions to be exported */
extern void DirectFB_InitOSKeymap(_THIS); extern void DirectFB_InitOSKeymap(_THIS);
extern void DirectFB_PumpEvents(_THIS); extern void DirectFB_PumpEventsWindow(_THIS);
/* vi: set ts=4 sw=4 expandtab: */
#define SCANCODE_ESCAPE 1
#define SCANCODE_1 2
#define SCANCODE_2 3
#define SCANCODE_3 4
#define SCANCODE_4 5
#define SCANCODE_5 6
#define SCANCODE_6 7
#define SCANCODE_7 8
#define SCANCODE_8 9
#define SCANCODE_9 10
#define SCANCODE_0 11
#define SCANCODE_MINUS 12
#define SCANCODE_EQUAL 13
#define SCANCODE_BACKSPACE 14
#define SCANCODE_TAB 15
#define SCANCODE_Q 16
#define SCANCODE_W 17
#define SCANCODE_E 18
#define SCANCODE_R 19
#define SCANCODE_T 20
#define SCANCODE_Y 21
#define SCANCODE_U 22
#define SCANCODE_I 23
#define SCANCODE_O 24
#define SCANCODE_P 25
#define SCANCODE_BRACKET_LEFT 26
#define SCANCODE_BRACKET_RIGHT 27
#define SCANCODE_ENTER 28
#define SCANCODE_LEFTCONTROL 29
#define SCANCODE_A 30
#define SCANCODE_S 31
#define SCANCODE_D 32
#define SCANCODE_F 33
#define SCANCODE_G 34
#define SCANCODE_H 35
#define SCANCODE_J 36
#define SCANCODE_K 37
#define SCANCODE_L 38
#define SCANCODE_SEMICOLON 39
#define SCANCODE_APOSTROPHE 40
#define SCANCODE_GRAVE 41
#define SCANCODE_LEFTSHIFT 42
#define SCANCODE_BACKSLASH 43
#define SCANCODE_Z 44
#define SCANCODE_X 45
#define SCANCODE_C 46
#define SCANCODE_V 47
#define SCANCODE_B 48
#define SCANCODE_N 49
#define SCANCODE_M 50
#define SCANCODE_COMMA 51
#define SCANCODE_PERIOD 52
#define SCANCODE_SLASH 53
#define SCANCODE_RIGHTSHIFT 54
#define SCANCODE_KEYPADMULTIPLY 55
#define SCANCODE_LEFTALT 56
#define SCANCODE_SPACE 57
#define SCANCODE_CAPSLOCK 58
#define SCANCODE_F1 59
#define SCANCODE_F2 60
#define SCANCODE_F3 61
#define SCANCODE_F4 62
#define SCANCODE_F5 63
#define SCANCODE_F6 64
#define SCANCODE_F7 65
#define SCANCODE_F8 66
#define SCANCODE_F9 67
#define SCANCODE_F10 68
#define SCANCODE_NUMLOCK 69
#define SCANCODE_SCROLLLOCK 70
#define SCANCODE_KEYPAD7 71
#define SCANCODE_CURSORUPLEFT 71
#define SCANCODE_KEYPAD8 72
#define SCANCODE_CURSORUP 72
#define SCANCODE_KEYPAD9 73
#define SCANCODE_CURSORUPRIGHT 73
#define SCANCODE_KEYPADMINUS 74
#define SCANCODE_KEYPAD4 75
#define SCANCODE_CURSORLEFT 75
#define SCANCODE_KEYPAD5 76
#define SCANCODE_KEYPAD6 77
#define SCANCODE_CURSORRIGHT 77
#define SCANCODE_KEYPADPLUS 78
#define SCANCODE_KEYPAD1 79
#define SCANCODE_CURSORDOWNLEFT 79
#define SCANCODE_KEYPAD2 80
#define SCANCODE_CURSORDOWN 80
#define SCANCODE_KEYPAD3 81
#define SCANCODE_CURSORDOWNRIGHT 81
#define SCANCODE_KEYPAD0 82
#define SCANCODE_KEYPADPERIOD 83
#define SCANCODE_LESS 86
#define SCANCODE_F11 87
#define SCANCODE_F12 88
#define SCANCODE_KEYPADENTER 96
#define SCANCODE_RIGHTCONTROL 97
#define SCANCODE_CONTROL 97
#define SCANCODE_KEYPADDIVIDE 98
#define SCANCODE_PRINTSCREEN 99
#define SCANCODE_RIGHTALT 100
#define SCANCODE_BREAK 101 /* Beware: is 119 */
#define SCANCODE_BREAK_ALTERNATIVE 119 /* on some keyboards! */
#define SCANCODE_HOME 102
#define SCANCODE_CURSORBLOCKUP 90 /* Cursor key block */
#define SCANCODE_PAGEUP 104
#define SCANCODE_CURSORBLOCKLEFT 92 /* Cursor key block */
#define SCANCODE_CURSORBLOCKRIGHT 94 /* Cursor key block */
#define SCANCODE_END 107
#define SCANCODE_CURSORBLOCKDOWN 108 /* Cursor key block */
#define SCANCODE_PAGEDOWN 109
#define SCANCODE_INSERT 110
#define SCANCODE_REMOVE 111
#define SCANCODE_RIGHTWIN 126
#define SCANCODE_LEFTWIN 125
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
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
*/
#include "SDL_config.h"
#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_mouse.h"
#include "../SDL_sysvideo.h"
#include "../../events/SDL_mouse_c.h"
static SDL_Cursor *DirectFB_CreateCursor(SDL_Surface * surface, int hot_x,
int hot_y);
static int DirectFB_ShowCursor(SDL_Cursor * cursor);
static void DirectFB_MoveCursor(SDL_Cursor * cursor);
static void DirectFB_FreeCursor(SDL_Cursor * cursor);
static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_WindowID windowID,
int x, int y);
static void DirectFB_FreeMouse(SDL_Mouse * mouse);
void
DirectFB_InitMouse(_THIS)
{
SDL_DFB_DEVICEDATA(_this);
SDL_Mouse mouse;
SDL_zero(mouse);
mouse.CreateCursor = DirectFB_CreateCursor;
mouse.ShowCursor = DirectFB_ShowCursor;
mouse.MoveCursor = DirectFB_MoveCursor;
mouse.FreeCursor = DirectFB_FreeCursor;
mouse.WarpMouse = DirectFB_WarpMouse;
mouse.FreeMouse = DirectFB_FreeMouse;
devdata->mouse = SDL_AddMouse(&mouse, -1);
}
void
DirectFB_QuitMouse(_THIS)
{
SDL_DFB_DEVICEDATA(_this);
SDL_DelMouse(devdata->mouse);
}
/* Create a cursor from a surface */
static SDL_Cursor *
DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
SDL_VideoDevice *dev = SDL_GetVideoDevice();
SDL_DFB_DEVICEDATA(dev);
DFB_CursorData *curdata;
DFBResult ret;
DFBSurfaceDescription dsc;
SDL_Cursor *cursor;
Uint32 *dest;
Uint32 *p;
int pitch, i;
SDL_DFB_CALLOC(cursor, 1, sizeof(*cursor));
SDL_DFB_CALLOC(curdata, 1, sizeof(*curdata));
dsc.flags =
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
dsc.caps = DSCAPS_NONE; //DSCAPS_SYSTEMONLY;
dsc.width = surface->w;
dsc.height = surface->h;
dsc.pixelformat = DSPF_ARGB;
SDL_DFB_CHECKERR(devdata->dfb->
CreateSurface(devdata->dfb, &dsc, &curdata->surf));
curdata->hotx = hot_x;
curdata->hoty = hot_y;
cursor->driverdata = curdata;
SDL_DFB_CHECKERR(curdata->surf->
Lock(curdata->surf, DSLF_WRITE, (void *) &dest, &pitch));
//FIXME: Implies a lot of things, e.g. rgba format for SDL_SURFACE ....
p = surface->pixels;
for (i = 0; i < surface->w * surface->h; i++)
if (p[i] == 0x00000000)
dest[i] = 0x00000000;
else
dest[i] = p[i];
//memcpy(dest, surface->pixels, surface->w * surface->h * 4);
curdata->surf->Unlock(curdata->surf);
return cursor;
error:
return NULL;
}
/* Show the specified cursor, or hide if cursor is NULL */
static int
DirectFB_ShowCursor(SDL_Cursor * cursor)
{
SDL_DFB_CURSORDATA(cursor);
SDL_VideoDevice *dev = SDL_GetVideoDevice();
SDL_DFB_DEVICEDATA(dev);
#if 0
DFB_DisplayData *dispdata =
(DFB_DisplayData *) dev->displays[dev->current_display].driverdata;
#endif
DFBResult ret;
SDL_WindowID wid;
wid = SDL_GetFocusWindow();
if (!wid)
return -1;
else {
SDL_Window *window = SDL_GetWindowFromID(wid);
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
SDL_DFB_CHECKERR(windata->window->
SetCursorShape(windata->window, curdata->surf,
curdata->hotx, curdata->hoty));
//FIXME: This is somehow a directfb issue
SDL_DFB_CHECKERR(dispdata->layer->
SetCooperativeLevel(dispdata->layer,
DLSCL_ADMINISTRATIVE));
SDL_DFB_CHECKERR(dispdata->layer->
SetCursorOpacity(dispdata->layer, 0xC0));
SDL_DFB_CHECKERR(dispdata->layer->
SetCooperativeLevel(dispdata->layer, DLSCL_SHARED));
}
#if 0
//TODO: Check administrative
SDL_DFB_CHECKERR(dispdata->layer->
SetCooperativeLevel(dispdata->layer,
DLSCL_ADMINISTRATIVE));
SDL_DFB_CHECKERR(dispdata->layer->
SetCursorShape(dispdata->layer, curdata->surf,
curdata->hotx, curdata->hoty));
SDL_DFB_CHECKERR(dispdata->layer->
SetCursorOpacity(dispdata->layer, 0xC0));
SDL_DFB_CHECKERR(dispdata->layer->
SetCooperativeLevel(dispdata->layer, DLSCL_SHARED));
#endif
return 0;
error:
return -1;
}
/* This is called when a mouse motion event occurs */
static void
DirectFB_MoveCursor(SDL_Cursor * cursor)
{
SDL_DFB_CURSORDATA(cursor);
/* Do we need to do something here ? */
}
/* Free a window manager cursor */
static void
DirectFB_FreeCursor(SDL_Cursor * cursor)
{
SDL_DFB_CURSORDATA(cursor);
SDL_DFB_RELEASE(curdata->surf);
SDL_DFB_FREE(cursor->driverdata);
SDL_DFB_FREE(cursor);
}
/* Warp the mouse to (x,y) */
static void
DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_WindowID windowID, int x, int y)
{
// SDL_DFB_CURSORDATA(cursor);
SDL_Window *window = SDL_GetWindowFromID(windowID);
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
DFBResult ret;
int cx, cy;
SDL_DFB_CHECKERR(windata->window->GetPosition(windata->window, &cx, &cy));
SDL_DFB_CHECKERR(dispdata->layer->
WarpCursor(dispdata->layer, cx + x, cy + y));
error:
return;
}
/* Free the mouse when it's time */
static void
DirectFB_FreeMouse(SDL_Mouse * mouse)
{
// nothing yet
}
/* vi: set ts=4 sw=4 expandtab: */
...@@ -21,21 +21,23 @@ ...@@ -21,21 +21,23 @@
*/ */
#include "SDL_config.h" #include "SDL_config.h"
/* This is the DirectFB implementation of YUV video overlays */ #ifndef _SDL_DirectFB_mouse_h
#define _SDL_DirectFB_mouse_h
#include "SDL_video.h" typedef struct _DFB_CursorData DFB_CursorData;
#include "SDL_DirectFB_video.h"
extern SDL_Overlay *DirectFB_CreateYUVOverlay(_THIS, int width, int height, struct _DFB_CursorData
Uint32 format, {
SDL_Surface * display); IDirectFBSurface *surf;
int hotx;
int hoty;
};
extern int DirectFB_LockYUVOverlay(_THIS, SDL_Overlay * overlay); #define SDL_DFB_CURSORDATA(curs) DFB_CursorData *curdata = (DFB_CursorData *) ((curs)->driverdata)
extern void DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay); extern void DirectFB_InitMouse(_THIS);
extern void DirectFB_QuitMouse(_THIS);
extern int DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, #endif /* _SDL_DirectFB_mouse_h */
SDL_Rect * src, SDL_Rect * dst);
extern void DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay * overlay);
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
This diff is collapsed.
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
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
*/
#include "SDL_config.h"
/* SDL surface based renderer implementation */
#define SDL_DFB_RENDERERDATA(rend) DirectFB_RenderData *renddata = ((rend) ? (DirectFB_RenderData *) (rend)->driverdata : NULL)
extern void DirectFB_AddRenderDriver(_THIS);
/* vi: set ts=4 sw=4 expandtab: */
This diff is collapsed.
...@@ -25,39 +25,155 @@ ...@@ -25,39 +25,155 @@
#define _SDL_DirectFB_video_h #define _SDL_DirectFB_video_h
#include <directfb.h> #include <directfb.h>
#include <directfb_version.h>
#define LOG_CHANNEL stdout
#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
#error "SDL_DIRECTFB: Please compile against libdirectfb version >=0.9.24"
#endif
#if (DIRECTFB_MAJOR_VERSION >= 1) && (DIRECTFB_MINOR_VERSION >= 0) && (DIRECTFB_MICRO_VERSION >= 0 )
#define SDL_DIRECTFB_OPENGL 1
#include <directfbgl.h>
#endif
#if SDL_DIRECTFB_OPENGL
#include "SDL_loadso.h"
#endif
#include "SDL_mouse.h" #include "SDL_mouse.h"
#include "../SDL_sysvideo.h" #include "../SDL_sysvideo.h"
#define _THIS SDL_VideoDevice *this #define DEBUG 1
#define SDL_DFB_RELEASE(x) do { if ( x ) { x->Release(x); x = NULL; } } while (0)
#define SDL_DFB_FREE(x) do { if ( x ) { SDL_free(x); x = NULL; } } while (0)
#define SDL_DFB_UNLOCK(x) do { if ( x ) { x->Unlock(x); } } while (0)
#if DEBUG
#define SDL_DFB_DEBUG(x...) do { fprintf(LOG_CHANNEL, "%s:", __FUNCTION__); fprintf(LOG_CHANNEL, x); } while (0)
#define SDL_DFB_DEBUGC(x...) do { fprintf(LOG_CHANNEL, x); } while (0)
#else
#define SDL_DFB_DEBUG(x...) do { } while (0)
#define SDL_DFB_DEBUGC(x...) do { } while (0)
#endif
#define SDL_DFB_CONTEXT "SDL_DirectFB"
#define SDL_DFB_ERR(x...) \
do { \
fprintf(LOG_CHANNEL, "%s: %s <%d>:\n\t", \
SDL_DFB_CONTEXT, __FILE__, __LINE__ ); \
fprintf(LOG_CHANNEL, x ); \
} while (0)
#define SDL_DFB_CHECK(x...) \
do { \
ret = x; \
if (ret != DFB_OK) { \
fprintf(LOG_CHANNEL, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
SDL_SetError( #x, DirectFBErrorString (ret) ); \
} \
} while (0)
#define SDL_DFB_CHECKERR(x...) \
do { \
ret = x; \
if (ret != DFB_OK) { \
fprintf(LOG_CHANNEL, "%s <%d>:\n", __FILE__, __LINE__ ); \
fprintf(LOG_CHANNEL, "\t%s\n", #x ); \
fprintf(LOG_CHANNEL, "\t%s\n", DirectFBErrorString (ret) ); \
SDL_SetError( #x, DirectFBErrorString (ret) ); \
goto error; \
} \
} while (0)
#define SDL_DFB_CALLOC(r, n, s) \
do { \
r = SDL_calloc (n, s); \
if (!(r)) { \
fprintf( LOG_CHANNEL, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
SDL_OutOfMemory(); \
goto error; \
} \
} while (0)
/* Private display data */ /* Private display data */
struct SDL_PrivateVideoData #define SDL_DFB_DEVICEDATA(dev) DFB_DeviceData *devdata = (DFB_DeviceData *) ((dev)->driverdata)
#define SDL_DFB_WINDOWDATA(win) DFB_WindowData *windata = ((win) ? (DFB_WindowData *) ((win)->driverdata) : NULL)
#define SDL_DFB_DISPLAYDATA(dev, win) DFB_DisplayData *dispdata = ((win && dev) ? (DFB_DisplayData *) (dev)->displays[(win)->display].driverdata : NULL)
typedef struct _DFB_DisplayData DFB_DisplayData;
#define DFB_MAX_SCREENS 10
#define DFB_MAX_MODES 50
struct _DFB_DisplayData
{
IDirectFBDisplayLayer *layer;
DFBSurfacePixelFormat pixelformat;
DFBDisplayLayerID vidID;
int cw;
int ch;
int nummodes;
SDL_DisplayMode *modelist;
#if 0
WMcursor *last_cursor;
WMcursor *blank_cursor;
WMcursor *default_cursor;
#endif
};
typedef struct _DFB_WindowData DFB_WindowData;
struct _DFB_WindowData
{
IDirectFBSurface *surface;
IDirectFBPalette *palette;
IDirectFBWindow *window;
IDirectFBGL *gl_context;
IDirectFBEventBuffer *eventbuffer;
DFBWindowID windowID;
int id; // SDL window id
DFB_WindowData *next;
u8 opacity;
};
typedef struct _DFB_DeviceData DFB_DeviceData;
struct _DFB_DeviceData
{ {
int initialized; int initialized;
IDirectFB *dfb; IDirectFB *dfb;
IDirectFBDisplayLayer *layer; int mouse;
IDirectFBEventBuffer *eventbuffer; int keyboard;
DFB_WindowData *firstwin;
int nummodes; int numscreens;
SDL_Rect **modelist; DFBScreenID screenid[DFB_MAX_SCREENS];
DFBDisplayLayerID gralayer[DFB_MAX_SCREENS];
/* MGA CRTC2 support */ DFBDisplayLayerID vidlayer[DFB_MAX_SCREENS];
int enable_mga_crtc2;
int mga_crtc2_stretch; // auxiliary integer for callbacks
float mga_crtc2_stretch_overscan; int aux;
IDirectFBDisplayLayer *c2layer;
IDirectFBSurface *c2frame; // OpenGL
DFBRectangle c2ssize; /* Real screen size */ void (*glFinish) (void);
DFBRectangle c2dsize; /* Stretched screen size */ void (*glFlush) (void);
DFBRectangle c2framesize; /* CRTC2 screen size */
}; };
#define HIDDEN (this->hidden) struct SDL_GLDriverData
{
int gl_active; /* to stop switching drivers while we have a valid context */
void SetDirectFBerror(const char *function, DFBResult code); #if SDL_DIRECTFB_OPENGL
IDirectFBGL *gl_context;
#endif /* SDL_DIRECTFB_OPENGL */
};
#endif /* _SDL_DirectFB_video_h */ #endif /* _SDL_DirectFB_video_h */
/* vi: set ts=4 sw=4 expandtab: */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
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
*/
#include "SDL_config.h"
/* This is the DirectFB implementation of YUV video overlays */
#include "SDL_video.h"
#include "SDL_DirectFB_yuv.h"
#include "../SDL_yuvfuncs.h"
/* The functions used to manipulate software video overlays */
static struct private_yuvhwfuncs directfb_yuvfuncs = {
DirectFB_LockYUVOverlay,
DirectFB_UnlockYUVOverlay,
DirectFB_DisplayYUVOverlay,
DirectFB_FreeYUVOverlay
};
struct private_yuvhwdata
{
DFBDisplayLayerID layer_id;
IDirectFBDisplayLayer *layer;
IDirectFBSurface *surface;
/* These are just so we don't have to allocate them separately */
Uint16 pitches[3];
Uint8 *planes[3];
};
static DFBEnumerationResult
enum_layers_callback(DFBDisplayLayerID id,
DFBDisplayLayerDescription desc, void *data)
{
struct private_yuvhwdata *hwdata = (struct private_yuvhwdata *) data;
/* we don't want the primary */
if (id == DLID_PRIMARY)
return DFENUM_OK;
/* take the one with a surface for video */
if ((desc.caps & DLCAPS_SURFACE) && (desc.type & DLTF_VIDEO)) {
hwdata->layer_id = id;
return DFENUM_CANCEL;
}
return DFENUM_OK;
}
static DFBResult
CreateYUVSurface(_THIS, struct private_yuvhwdata *hwdata,
int width, int height, Uint32 format)
{
DFBResult ret;
IDirectFB *dfb = HIDDEN->dfb;
IDirectFBDisplayLayer *layer;
DFBDisplayLayerConfig conf;
ret = dfb->EnumDisplayLayers(dfb, enum_layers_callback, hwdata);
if (ret) {
SetDirectFBerror("IDirectFB::EnumDisplayLayers", ret);
return ret;
}
if (!hwdata->layer_id)
return DFB_UNSUPPORTED;
ret = dfb->GetDisplayLayer(dfb, hwdata->layer_id, &layer);
if (ret) {
SetDirectFBerror("IDirectFB::GetDisplayLayer", ret);
return ret;
}
conf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
conf.width = width;
conf.height = height;
switch (format) {
case SDL_YV12_OVERLAY:
conf.pixelformat = DSPF_YV12;
break;
case SDL_IYUV_OVERLAY:
conf.pixelformat = DSPF_I420;
break;
case SDL_YUY2_OVERLAY:
conf.pixelformat = DSPF_YUY2;
break;
case SDL_UYVY_OVERLAY:
conf.pixelformat = DSPF_UYVY;
break;
default:
fprintf(stderr, "SDL_DirectFB: Unsupported YUV format (0x%08x)!\n",
format);
break;
}
/* Need to set coop level or newer DirectFB versions will fail here. */
ret = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
if (ret) {
SetDirectFBError
("IDirectFBDisplayLayer::SetCooperativeLevel() failed", ret);
layer->Release(layer);
return ret;
}
ret = layer->SetConfiguration(layer, &conf);
if (ret) {
SetDirectFBerror("IDirectFBDisplayLayer::SetConfiguration", ret);
layer->Release(layer);
return ret;
}
ret = layer->GetSurface(layer, &hwdata->surface);
if (ret) {
SetDirectFBerror("IDirectFBDisplayLayer::GetSurface", ret);
layer->Release(layer);
return ret;
}
hwdata->layer = layer;
return DFB_OK;
}
SDL_Overlay *
DirectFB_CreateYUVOverlay(_THIS, int width, int height, Uint32 format,
SDL_Surface * display)
{
SDL_Overlay *overlay;
struct private_yuvhwdata *hwdata;
/* Create the overlay structure */
overlay = SDL_calloc(1, sizeof(SDL_Overlay));
if (!overlay) {
SDL_OutOfMemory();
return NULL;
}
/* Fill in the basic members */
overlay->format = format;
overlay->w = width;
overlay->h = height;
/* Set up the YUV surface function structure */
overlay->hwfuncs = &directfb_yuvfuncs;
/* Create the pixel data and lookup tables */
hwdata = SDL_calloc(1, sizeof(struct private_yuvhwdata));
overlay->hwdata = hwdata;
if (!hwdata) {
SDL_OutOfMemory();
SDL_FreeYUVOverlay(overlay);
return NULL;
}
if (CreateYUVSurface(this, hwdata, width, height, format)) {
SDL_FreeYUVOverlay(overlay);
return NULL;
}
overlay->hw_overlay = 1;
/* Set up the plane pointers */
overlay->pitches = hwdata->pitches;
overlay->pixels = hwdata->planes;
switch (format) {
case SDL_YV12_OVERLAY:
case SDL_IYUV_OVERLAY:
overlay->planes = 3;
break;
default:
overlay->planes = 1;
break;
}
/* We're all done.. */
return overlay;
}
int
DirectFB_LockYUVOverlay(_THIS, SDL_Overlay * overlay)
{
DFBResult ret;
void *data;
int pitch;
IDirectFBSurface *surface = overlay->hwdata->surface;
ret = surface->Lock(surface, DSLF_READ | DSLF_WRITE, &data, &pitch);
if (ret) {
SetDirectFBerror("IDirectFBSurface::Lock", ret);
return -1;
}
/* Find the pitch and offset values for the overlay */
overlay->pitches[0] = (Uint16) pitch;
overlay->pixels[0] = (Uint8 *) data;
switch (overlay->format) {
case SDL_YV12_OVERLAY:
case SDL_IYUV_OVERLAY:
/* Add the two extra planes */
overlay->pitches[1] = overlay->pitches[0] / 2;
overlay->pitches[2] = overlay->pitches[0] / 2;
overlay->pixels[1] =
overlay->pixels[0] + overlay->pitches[0] * overlay->h;
overlay->pixels[2] =
overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2;
break;
default:
/* Only one plane, no worries */
break;
}
return 0;
}
void
DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay)
{
IDirectFBSurface *surface = overlay->hwdata->surface;
overlay->pixels[0] = overlay->pixels[1] = overlay->pixels[2] = NULL;
surface->Unlock(surface);
}
int
DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, SDL_Rect * src,
SDL_Rect * dst)
{
DFBResult ret;
DFBDisplayLayerConfig conf;
IDirectFBDisplayLayer *primary = HIDDEN->layer;
IDirectFBDisplayLayer *layer = overlay->hwdata->layer;
primary->GetConfiguration(primary, &conf);
ret = layer->SetScreenLocation(layer,
dst->x / (float) conf.width,
dst->y / (float) conf.height,
dst->w / (float) conf.width,
dst->h / (float) conf.height);
if (ret) {
SetDirectFBerror("IDirectFBDisplayLayer::SetScreenLocation", ret);
return -1;
}
return 0;
}
void
DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay * overlay)
{
struct private_yuvhwdata *hwdata;
hwdata = overlay->hwdata;
if (hwdata) {
if (hwdata->surface)
hwdata->surface->Release(hwdata->surface);
if (hwdata->layer)
hwdata->layer->Release(hwdata->layer);
free(hwdata);
}
}
/* vi: set ts=4 sw=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment