1 /*
2    (c) Copyright 2001-2009  The world wide DirectFB Open Source Community (directfb.org)
3    (c) Copyright 2000-2004  Convergence (integrated media) GmbH
4 
5    All rights reserved.
6 
7    Written by Denis Oliver Kropp <dok@directfb.org>,
8               Andreas Hundt <andi@fischlustig.de>,
9               Sven Neumann <neo@directfb.org>,
10               Ville Syrjälä <syrjala@sci.fi> and
11               Claudio Ciccani <klan@users.sf.net>.
12 
13    This library is free software; you can redistribute it and/or
14    modify it under the terms of the GNU Lesser General Public
15    License as published by the Free Software Foundation; either
16    version 2 of the License, or (at your option) any later version.
17 
18    This library is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    Lesser General Public License for more details.
22 
23    You should have received a copy of the GNU Lesser General Public
24    License along with this library; if not, write to the
25    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26    Boston, MA 02111-1307, USA.
27 */
28 
29 #include <config.h>
30 
31 #include <stdio.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 
35 #include <directfb.h>
36 
37 #include <SDL.h>
38 
39 #include <core/coredefs.h>
40 #include <core/coretypes.h>
41 
42 #include <core/state.h>
43 #include <core/gfxcard.h>
44 #include <core/windows.h>
45 #include <core/layers.h>
46 #include <core/screens.h>
47 #include <core/surface.h>
48 
49 #include <gfx/convert.h>
50 
51 #include <core/graphics_driver.h>
52 
53 DFB_GRAPHICS_DRIVER( sdlgraphics )
54 
55 #include "sdl.h"
56 
57 /* FIXME: support for destination color keying */
58 
59 #define SDL_DRAWING_FLAGS \
60                (DSDRAW_NOFX)
61 
62 #define SDL_DRAWING_FUNCTIONS \
63                (DFXL_FILLRECTANGLE)
64 
65 #define SDL_BLITTING_FLAGS \
66                (DSBLIT_SRC_COLORKEY)
67 
68 #define SDL_BLITTING_FUNCTIONS \
69                (DFXL_BLIT)
70 
71 D_DEBUG_DOMAIN( SDL_GFX, "SDL/Graphics", "SDL Graphics" );
72 
73 typedef struct {
74 } SDLDriverData;
75 
76 typedef struct {
77      SDL_Surface *dest;
78      SDL_Surface *source;
79 
80      u32          color;
81 
82      bool         color_valid;
83      bool         key_valid;
84 } SDLDeviceData;
85 
86 
sdlEngineSync(void * drv,void * dev)87 static DFBResult sdlEngineSync( void *drv, void *dev )
88 {
89      return DFB_OK;
90 }
91 
sdlCheckState(void * drv,void * dev,CardState * state,DFBAccelerationMask accel)92 static void sdlCheckState( void *drv, void *dev,
93                            CardState *state, DFBAccelerationMask accel )
94 {
95      /* check destination format first */
96      switch (state->destination->config.format) {
97           case DSPF_RGB16:
98           case DSPF_RGB32:
99                break;
100           default:
101                return;
102      }
103 
104      if (DFB_DRAWING_FUNCTION( accel )) {
105           /* if there are no other drawing flags than the supported */
106           if (state->drawingflags & ~SDL_DRAWING_FLAGS)
107                return;
108 
109           state->accel |= SDL_DRAWING_FUNCTIONS;
110      }
111      else {
112           /* if there are no other blitting flags than the supported
113              and the source and destination formats are the same */
114           if (state->blittingflags & ~SDL_BLITTING_FLAGS)
115                return;
116 
117           /* check source format */
118           switch (state->source->config.format) {
119                case DSPF_RGB16:
120                case DSPF_RGB32:
121                     break;
122                default:
123                     return;
124           }
125 
126           state->accel |= SDL_BLITTING_FUNCTIONS;
127      }
128 }
129 
sdlSetState(void * drv,void * dev,GraphicsDeviceFuncs * funcs,CardState * state,DFBAccelerationMask accel)130 static void sdlSetState( void *drv, void *dev, GraphicsDeviceFuncs *funcs,
131                          CardState *state, DFBAccelerationMask accel )
132 {
133      SDLDeviceData *sdev = (SDLDeviceData*) dev;
134 
135      sdev->dest   = state->dst.handle;
136      sdev->source = state->src.handle;
137 
138      if (state->mod_hw & (SMF_SOURCE | SMF_BLITTING_FLAGS | SMF_SRC_COLORKEY))
139           sdev->key_valid = false;
140 
141      if (state->mod_hw & (SMF_DESTINATION | SMF_COLOR))
142           sdev->color_valid = false;
143 
144      switch (accel) {
145           case DFXL_FILLRECTANGLE:
146                if (!sdev->color_valid) {
147                     switch (state->destination->config.format) {
148                          case DSPF_RGB16:
149                          case DSPF_RGB32:
150                               sdev->color = dfb_color_to_pixel( state->destination->config.format,
151                                                                 state->color.r,
152                                                                 state->color.g,
153                                                                 state->color.b );
154                               break;
155 
156                          default:
157                               D_BUG( "unexpected format" );
158                     }
159 
160                     sdev->color_valid = true;
161                }
162 
163                state->set |= SDL_DRAWING_FUNCTIONS;
164                break;
165 
166           case DFXL_BLIT:
167                if (!sdev->key_valid) {
168                     SDL_SetColorKey( sdev->source,
169                                      (state->blittingflags &
170                                       DSBLIT_SRC_COLORKEY) ? SDL_SRCCOLORKEY : 0,
171                                      state->src_colorkey | 0xff000000 );
172 
173                     sdev->key_valid = true;
174                }
175 
176                state->set |= SDL_BLITTING_FUNCTIONS;
177                break;
178 
179           default:
180                D_BUG("unexpected acceleration" );
181                break;
182      }
183 
184      state->mod_hw = 0;
185 }
186 
sdlFillRectangle(void * drv,void * dev,DFBRectangle * rect)187 static bool sdlFillRectangle( void *drv, void *dev, DFBRectangle *rect )
188 {
189      SDLDeviceData *sdev = (SDLDeviceData*) dev;
190      SDL_Rect       dr;
191 
192      dr.x = rect->x;
193      dr.y = rect->y;
194      dr.w = rect->w;
195      dr.h = rect->h;
196 
197      return SDL_FillRect( sdev->dest, &dr, sdev->color ) == 0;
198 }
199 
sdlBlit(void * drv,void * dev,DFBRectangle * rect,int dx,int dy)200 static bool sdlBlit( void *drv, void *dev, DFBRectangle *rect, int dx, int dy )
201 {
202      SDLDeviceData *sdev = (SDLDeviceData*) dev;
203      SDL_Rect       sr, dr;
204 
205      D_DEBUG_AT( SDL_GFX, "%s()\n", __FUNCTION__ );
206 
207      sr.x = rect->x;
208      sr.y = rect->y;
209      sr.w = rect->w;
210      sr.h = rect->h;
211 
212      dr.x = dx;
213      dr.y = dy;
214      dr.w = rect->w;
215      dr.h = rect->h;
216 
217      return SDL_BlitSurface( sdev->source, &sr, sdev->dest, &dr ) == 0;
218 }
219 
220 
221 /* exported symbols */
222 
223 static int
driver_probe(CoreGraphicsDevice * device)224 driver_probe( CoreGraphicsDevice *device )
225 {
226      return dfb_system_type() == CORE_SDL;
227 }
228 
229 static void
driver_get_info(CoreGraphicsDevice * device,GraphicsDriverInfo * info)230 driver_get_info( CoreGraphicsDevice *device,
231                  GraphicsDriverInfo *info )
232 {
233      /* fill driver info structure */
234      snprintf( info->name,
235                DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH,
236                "SDL Graphics Driver" );
237 
238      snprintf( info->vendor,
239                DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH,
240                "directfb.org" );
241 
242      info->version.major = 0;
243      info->version.minor = 1;
244 
245      info->driver_data_size = sizeof (SDLDriverData);
246      info->device_data_size = sizeof (SDLDeviceData);
247 }
248 
249 static DFBResult
driver_init_driver(CoreGraphicsDevice * device,GraphicsDeviceFuncs * funcs,void * driver_data,void * device_data,CoreDFB * core)250 driver_init_driver( CoreGraphicsDevice  *device,
251                     GraphicsDeviceFuncs *funcs,
252                     void                *driver_data,
253                     void                *device_data,
254                     CoreDFB             *core )
255 {
256      /* fill acceleration function table */
257      funcs->EngineSync    = sdlEngineSync;
258      funcs->CheckState    = sdlCheckState;
259      funcs->SetState      = sdlSetState;
260 
261      funcs->FillRectangle = sdlFillRectangle;
262      funcs->Blit          = sdlBlit;
263 
264      return DFB_OK;
265 }
266 
267 static DFBResult
driver_init_device(CoreGraphicsDevice * device,GraphicsDeviceInfo * device_info,void * driver_data,void * device_data)268 driver_init_device( CoreGraphicsDevice *device,
269                     GraphicsDeviceInfo *device_info,
270                     void               *driver_data,
271                     void               *device_data )
272 {
273      /* fill device info */
274      snprintf( device_info->name,
275                DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "Graphics" );
276 
277      snprintf( device_info->vendor,
278                DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "SDL" );
279 
280 
281      device_info->caps.flags    = CCF_READSYSMEM;
282      device_info->caps.accel    = SDL_DRAWING_FUNCTIONS |
283                                   SDL_BLITTING_FUNCTIONS;
284      device_info->caps.drawing  = SDL_DRAWING_FLAGS;
285      device_info->caps.blitting = SDL_BLITTING_FLAGS;
286 
287      return DFB_OK;
288 }
289 
290 static void
driver_close_device(CoreGraphicsDevice * device,void * driver_data,void * device_data)291 driver_close_device( CoreGraphicsDevice *device,
292                      void               *driver_data,
293                      void               *device_data )
294 {
295 }
296 
297 static void
driver_close_driver(CoreGraphicsDevice * device,void * driver_data)298 driver_close_driver( CoreGraphicsDevice *device,
299                      void               *driver_data )
300 {
301 }
302 
303