Mercurial > sdl-ios-xcode
annotate src/video/dga/SDL_dgavideo.c @ 1240:3b8a43c428bb
From Bug #36:
There are a couple of issues with the selection of Altivec alpha-blitting
routines in CalculateAlphaBlit() in src/video/SDL_Blit_A.c.
1) There's no check for the presence of Altivec when checking if the
Blit32to565PixelAlphaAltivec() routine can be selected.
2) Altivec cannot be used in video memory, and there's no check if the
destination surface is a hardware surface. (Alpha-blitting to a hardware
surface with GPU support is a bad idea, but somebody's bound to do it anyway.)
Patch to fix these attached.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sun, 08 Jan 2006 21:18:15 +0000 |
parents | 045f186426e1 |
children | 0c105755b110 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
559
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
202
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* DGA 2.0 based SDL video driver implementation. | |
29 */ | |
30 | |
31 #include <stdlib.h> | |
32 #include <string.h> | |
33 #include <X11/Xlib.h> | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
34 #include <XFree86/extensions/xf86dga.h> |
0 | 35 |
36 #ifdef HAVE_ALLOCA_H | |
37 #include <alloca.h> | |
38 #endif | |
39 | |
40 #include "SDL.h" | |
41 #include "SDL_error.h" | |
42 #include "SDL_video.h" | |
43 #include "SDL_mouse.h" | |
44 #include "SDL_sysvideo.h" | |
45 #include "SDL_pixels_c.h" | |
46 #include "SDL_events_c.h" | |
47 #include "SDL_dgavideo.h" | |
48 #include "SDL_dgamouse_c.h" | |
49 #include "SDL_dgaevents_c.h" | |
50 | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
51 /* get function pointers... */ |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
52 #include "../x11/SDL_x11dyn.h" |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
53 |
0 | 54 /* Initialization/Query functions */ |
55 static int DGA_VideoInit(_THIS, SDL_PixelFormat *vformat); | |
56 static SDL_Rect **DGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | |
57 static SDL_Surface *DGA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
58 static int DGA_SetColors(_THIS, int firstcolor, int ncolors, | |
59 SDL_Color *colors); | |
60 static int DGA_SetGammaRamp(_THIS, Uint16 *ramp); | |
61 static void DGA_VideoQuit(_THIS); | |
62 | |
63 /* Hardware surface functions */ | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
64 static int DGA_InitHWSurfaces(_THIS, SDL_Surface *screen, Uint8 *base, int size); |
0 | 65 static void DGA_FreeHWSurfaces(_THIS); |
66 static int DGA_AllocHWSurface(_THIS, SDL_Surface *surface); | |
67 static int DGA_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color); | |
68 static int DGA_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst); | |
69 static int DGA_LockHWSurface(_THIS, SDL_Surface *surface); | |
70 static void DGA_UnlockHWSurface(_THIS, SDL_Surface *surface); | |
71 static void DGA_FreeHWSurface(_THIS, SDL_Surface *surface); | |
72 static int DGA_FlipHWSurface(_THIS, SDL_Surface *surface); | |
73 | |
74 /* DGA driver bootstrap functions */ | |
75 | |
76 static int DGA_Available(void) | |
77 { | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
78 const char *display = NULL; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
79 Display *dpy = NULL; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
80 int available = 0; |
0 | 81 |
82 /* The driver is available is available if the display is local | |
83 and the DGA 2.0+ extension is available, and we can map mem. | |
84 */ | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
85 if ( SDL_X11_LoadSymbols() ) { |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
86 if ( (strncmp(pXDisplayName(display), ":", 1) == 0) || |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
87 (strncmp(pXDisplayName(display), "unix:", 5) == 0) ) { |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
88 dpy = pXOpenDisplay(display); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
89 if ( dpy ) { |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
90 int events, errors, major, minor; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
91 |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
92 if ( SDL_NAME(XDGAQueryExtension)(dpy, &events, &errors) && |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
93 SDL_NAME(XDGAQueryVersion)(dpy, &major, &minor) ) { |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
94 int screen; |
0 | 95 |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
96 screen = DefaultScreen(dpy); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
97 if ( (major >= 2) && |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
98 SDL_NAME(XDGAOpenFramebuffer)(dpy, screen) ) { |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
99 available = 1; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
100 SDL_NAME(XDGACloseFramebuffer)(dpy, screen); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
101 } |
0 | 102 } |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
103 pXCloseDisplay(dpy); |
0 | 104 } |
105 } | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
106 SDL_X11_UnloadSymbols(); |
0 | 107 } |
108 return(available); | |
109 } | |
110 | |
111 static void DGA_DeleteDevice(SDL_VideoDevice *device) | |
112 { | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
113 if (device != NULL) { |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
114 free(device->hidden); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
115 free(device); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
116 SDL_X11_UnloadSymbols(); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
117 } |
0 | 118 } |
119 | |
120 static SDL_VideoDevice *DGA_CreateDevice(int devindex) | |
121 { | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
122 SDL_VideoDevice *device = NULL; |
0 | 123 |
124 /* Initialize all variables that we clean on shutdown */ | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
125 if (SDL_X11_LoadSymbols()) { |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
126 device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); |
0 | 127 if ( device ) { |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
128 memset(device, 0, (sizeof *device)); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
129 device->hidden = (struct SDL_PrivateVideoData *) |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
130 malloc((sizeof *device->hidden)); |
0 | 131 } |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
132 if ( (device == NULL) || (device->hidden == NULL) ) { |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
133 SDL_OutOfMemory(); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
134 if ( device ) { |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
135 free(device); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
136 } |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
137 SDL_X11_UnloadSymbols(); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
138 return(0); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
139 } |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
140 memset(device->hidden, 0, (sizeof *device->hidden)); |
0 | 141 |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
142 /* Set the function pointers */ |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
143 device->VideoInit = DGA_VideoInit; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
144 device->ListModes = DGA_ListModes; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
145 device->SetVideoMode = DGA_SetVideoMode; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
146 device->SetColors = DGA_SetColors; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
147 device->UpdateRects = NULL; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
148 device->VideoQuit = DGA_VideoQuit; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
149 device->AllocHWSurface = DGA_AllocHWSurface; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
150 device->CheckHWBlit = DGA_CheckHWBlit; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
151 device->FillHWRect = DGA_FillHWRect; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
152 device->SetHWColorKey = NULL; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
153 device->SetHWAlpha = NULL; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
154 device->LockHWSurface = DGA_LockHWSurface; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
155 device->UnlockHWSurface = DGA_UnlockHWSurface; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
156 device->FlipHWSurface = DGA_FlipHWSurface; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
157 device->FreeHWSurface = DGA_FreeHWSurface; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
158 device->SetGammaRamp = DGA_SetGammaRamp; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
159 device->GetGammaRamp = NULL; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
160 device->SetCaption = NULL; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
161 device->SetIcon = NULL; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
162 device->IconifyWindow = NULL; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
163 device->GrabInput = NULL; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
164 device->GetWMInfo = NULL; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
165 device->InitOSKeymap = DGA_InitOSKeymap; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
166 device->PumpEvents = DGA_PumpEvents; |
0 | 167 |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
168 device->free = DGA_DeleteDevice; |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
169 } |
0 | 170 |
171 return device; | |
172 } | |
173 | |
174 VideoBootStrap DGA_bootstrap = { | |
175 "dga", "XFree86 DGA 2.0", | |
176 DGA_Available, DGA_CreateDevice | |
177 }; | |
178 | |
179 static int DGA_AddMode(_THIS, int bpp, int w, int h) | |
180 { | |
181 SDL_Rect *mode; | |
182 int i, index; | |
183 int next_mode; | |
184 | |
185 /* Check to see if we already have this mode */ | |
186 if ( bpp < 8 ) { /* Not supported */ | |
187 return(0); | |
188 } | |
189 index = ((bpp+7)/8)-1; | |
190 for ( i=0; i<SDL_nummodes[index]; ++i ) { | |
191 mode = SDL_modelist[index][i]; | |
192 if ( (mode->w == w) && (mode->h == h) ) { | |
193 return(0); | |
194 } | |
195 } | |
196 | |
197 /* Set up the new video mode rectangle */ | |
198 mode = (SDL_Rect *)malloc(sizeof *mode); | |
199 if ( mode == NULL ) { | |
200 SDL_OutOfMemory(); | |
201 return(-1); | |
202 } | |
203 mode->x = 0; | |
204 mode->y = 0; | |
205 mode->w = w; | |
206 mode->h = h; | |
207 | |
208 /* Allocate the new list of modes, and fill in the new mode */ | |
209 next_mode = SDL_nummodes[index]; | |
210 SDL_modelist[index] = (SDL_Rect **) | |
211 realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *)); | |
212 if ( SDL_modelist[index] == NULL ) { | |
213 SDL_OutOfMemory(); | |
214 SDL_nummodes[index] = 0; | |
215 free(mode); | |
216 return(-1); | |
217 } | |
218 SDL_modelist[index][next_mode] = mode; | |
219 SDL_modelist[index][next_mode+1] = NULL; | |
220 SDL_nummodes[index]++; | |
221 | |
222 return(0); | |
223 } | |
224 | |
225 /* This whole function is a hack. :) */ | |
226 static Uint32 get_video_size(_THIS) | |
227 { | |
228 /* This is a non-exported function from libXxf86dga.a */ | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
229 extern unsigned char *SDL_NAME(XDGAGetMappedMemory)(int screen); |
0 | 230 FILE *proc; |
231 unsigned long mem; | |
232 unsigned start, stop; | |
233 char line[BUFSIZ]; | |
234 Uint32 size; | |
235 | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
236 mem = (unsigned long)SDL_NAME(XDGAGetMappedMemory)(DGA_Screen); |
0 | 237 size = 0; |
238 proc = fopen("/proc/self/maps", "r"); | |
239 if ( proc ) { | |
240 while ( fgets(line, sizeof(line)-1, proc) ) { | |
241 sscanf(line, "%x-%x", &start, &stop); | |
242 if ( start == mem ) { | |
243 size = (Uint32)((stop-start)/1024); | |
244 break; | |
245 } | |
246 } | |
247 fclose(proc); | |
248 } | |
249 return(size); | |
250 } | |
251 | |
252 #ifdef DGA_DEBUG | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
253 static void PrintMode(SDL_NAME(XDGAMode) *mode) |
0 | 254 { |
255 printf("Mode: %s (%dx%d) at %d bpp (%f refresh, %d pitch) num: %d\n", | |
256 mode->name, | |
257 mode->viewportWidth, mode->viewportHeight, | |
258 mode->depth == 24 ? mode->bitsPerPixel : mode->depth, | |
259 mode->verticalRefresh, mode->bytesPerScanline, mode->num); | |
260 printf("\tRGB: 0x%8.8x 0x%8.8x 0x%8.8x (%d - %s)\n", | |
261 mode->redMask, mode->greenMask, mode->blueMask, | |
262 mode->visualClass, | |
263 mode->visualClass == TrueColor ? "truecolor" : | |
264 mode->visualClass == DirectColor ? "directcolor" : | |
265 mode->visualClass == PseudoColor ? "pseudocolor" : "unknown"); | |
266 printf("\tFlags: "); | |
267 if ( mode->flags & XDGAConcurrentAccess ) | |
268 printf(" XDGAConcurrentAccess"); | |
269 if ( mode->flags & XDGASolidFillRect ) | |
270 printf(" XDGASolidFillRect"); | |
271 if ( mode->flags & XDGABlitRect ) | |
272 printf(" XDGABlitRect"); | |
273 if ( mode->flags & XDGABlitTransRect ) | |
274 printf(" XDGABlitTransRect"); | |
275 if ( mode->flags & XDGAPixmap ) | |
276 printf(" XDGAPixmap"); | |
277 if ( mode->flags & XDGAInterlaced ) | |
278 printf(" XDGAInterlaced"); | |
279 if ( mode->flags & XDGADoublescan ) | |
280 printf(" XDGADoublescan"); | |
281 if ( mode->viewportFlags & XDGAFlipRetrace ) | |
282 printf(" XDGAFlipRetrace"); | |
283 if ( mode->viewportFlags & XDGAFlipImmediate ) | |
284 printf(" XDGAFlipImmediate"); | |
285 printf("\n"); | |
286 } | |
287 #endif /* DGA_DEBUG */ | |
288 | |
289 static int cmpmodes(const void *va, const void *vb) | |
290 { | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
291 const SDL_NAME(XDGAMode) *a = (const SDL_NAME(XDGAMode) *)va; |
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
292 const SDL_NAME(XDGAMode) *b = (const SDL_NAME(XDGAMode) *)vb; |
0 | 293 |
294 /* Prefer DirectColor visuals for otherwise equal modes */ | |
295 if ( (a->viewportWidth == b->viewportWidth) && | |
296 (b->viewportHeight == a->viewportHeight) ) { | |
966
f72cc0c7305f
Video modes are sorted width first, then height
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
297 if ( a->visualClass == DirectColor ) |
f72cc0c7305f
Video modes are sorted width first, then height
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
298 return -1; |
f72cc0c7305f
Video modes are sorted width first, then height
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
299 if ( b->visualClass == DirectColor ) |
f72cc0c7305f
Video modes are sorted width first, then height
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
300 return 1; |
f72cc0c7305f
Video modes are sorted width first, then height
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
301 return 0; |
f72cc0c7305f
Video modes are sorted width first, then height
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
302 } else if ( a->viewportWidth == b->viewportWidth ) { |
f72cc0c7305f
Video modes are sorted width first, then height
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
303 return b->viewportHeight - a->viewportHeight; |
0 | 304 } else { |
966
f72cc0c7305f
Video modes are sorted width first, then height
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
305 return b->viewportWidth - a->viewportWidth; |
0 | 306 } |
307 } | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
308 static void UpdateHWInfo(_THIS, SDL_NAME(XDGAMode) *mode) |
0 | 309 { |
310 this->info.wm_available = 0; | |
311 this->info.hw_available = 1; | |
312 if ( mode->flags & XDGABlitRect ) { | |
313 this->info.blit_hw = 1; | |
314 } else { | |
315 this->info.blit_hw = 0; | |
316 } | |
317 if ( mode->flags & XDGABlitTransRect ) { | |
318 this->info.blit_hw_CC = 1; | |
319 } else { | |
320 this->info.blit_hw_CC = 0; | |
321 } | |
322 if ( mode->flags & XDGASolidFillRect ) { | |
323 this->info.blit_fill = 1; | |
324 } else { | |
325 this->info.blit_fill = 0; | |
326 } | |
327 this->info.video_mem = get_video_size(this); | |
328 } | |
329 | |
330 static int DGA_VideoInit(_THIS, SDL_PixelFormat *vformat) | |
331 { | |
332 const char *display; | |
333 int event_base, error_base; | |
334 int major_version, minor_version; | |
335 Visual *visual; | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
336 SDL_NAME(XDGAMode) *modes; |
0 | 337 int i, num_modes; |
338 | |
339 /* Open the X11 display */ | |
340 display = NULL; /* Get it from DISPLAY environment variable */ | |
341 | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
342 DGA_Display = pXOpenDisplay(display); |
0 | 343 if ( DGA_Display == NULL ) { |
344 SDL_SetError("Couldn't open X11 display"); | |
345 return(-1); | |
346 } | |
347 | |
348 /* Check for the DGA extension */ | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
349 if ( ! SDL_NAME(XDGAQueryExtension)(DGA_Display, &event_base, &error_base) || |
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
350 ! SDL_NAME(XDGAQueryVersion)(DGA_Display, &major_version, &minor_version) ) { |
0 | 351 SDL_SetError("DGA extension not available"); |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
352 pXCloseDisplay(DGA_Display); |
0 | 353 return(-1); |
354 } | |
355 if ( major_version < 2 ) { | |
356 SDL_SetError("DGA driver requires DGA 2.0 or newer"); | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
357 pXCloseDisplay(DGA_Display); |
0 | 358 return(-1); |
359 } | |
360 DGA_event_base = event_base; | |
361 | |
362 /* Determine the current screen depth */ | |
363 visual = DefaultVisual(DGA_Display, DGA_Screen); | |
364 { | |
365 XPixmapFormatValues *pix_format; | |
366 int i, num_formats; | |
367 | |
368 vformat->BitsPerPixel = DefaultDepth(DGA_Display, DGA_Screen); | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
369 pix_format = pXListPixmapFormats(DGA_Display, &num_formats); |
0 | 370 if ( pix_format == NULL ) { |
371 SDL_SetError("Couldn't determine screen formats"); | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
372 pXCloseDisplay(DGA_Display); |
0 | 373 return(-1); |
374 } | |
375 for ( i=0; i<num_formats; ++i ) { | |
376 if ( vformat->BitsPerPixel == pix_format[i].depth ) | |
377 break; | |
378 } | |
379 if ( i != num_formats ) | |
380 vformat->BitsPerPixel = pix_format[i].bits_per_pixel; | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
381 pXFree((char *)pix_format); |
0 | 382 } |
383 if ( vformat->BitsPerPixel > 8 ) { | |
384 vformat->Rmask = visual->red_mask; | |
385 vformat->Gmask = visual->green_mask; | |
386 vformat->Bmask = visual->blue_mask; | |
387 } | |
388 | |
389 /* Open access to the framebuffer */ | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
390 if ( ! SDL_NAME(XDGAOpenFramebuffer)(DGA_Display, DGA_Screen) ) { |
0 | 391 SDL_SetError("Unable to map the video memory"); |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
392 pXCloseDisplay(DGA_Display); |
0 | 393 return(-1); |
394 } | |
395 | |
396 /* Query for the list of available video modes */ | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
397 modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes); |
0 | 398 qsort(modes, num_modes, sizeof *modes, cmpmodes); |
399 for ( i=0; i<num_modes; ++i ) { | |
400 #ifdef DGA_DEBUG | |
401 PrintMode(&modes[i]); | |
402 #endif | |
403 if ( (modes[i].visualClass == PseudoColor) || | |
404 (modes[i].visualClass == DirectColor) || | |
405 (modes[i].visualClass == TrueColor) ) { | |
406 DGA_AddMode(this, modes[i].bitsPerPixel, | |
407 modes[i].viewportWidth, | |
408 modes[i].viewportHeight); | |
409 } | |
410 } | |
411 UpdateHWInfo(this, modes); | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
412 pXFree(modes); |
0 | 413 |
414 /* Create the hardware surface lock mutex */ | |
415 hw_lock = SDL_CreateMutex(); | |
416 if ( hw_lock == NULL ) { | |
417 SDL_SetError("Unable to create lock mutex"); | |
418 DGA_VideoQuit(this); | |
419 return(-1); | |
420 } | |
421 | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
422 #ifdef LOCK_DGA_DISPLAY |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
423 /* Create the event lock so we're thread-safe.. :-/ */ |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
424 event_lock = SDL_CreateMutex(); |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
425 #endif /* LOCK_DGA_DISPLAY */ |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
426 |
0 | 427 /* We're done! */ |
428 return(0); | |
429 } | |
430 | |
431 SDL_Rect **DGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | |
432 { | |
433 return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]); | |
434 } | |
435 | |
436 /* Various screen update functions available */ | |
437 static void DGA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); | |
438 | |
439 SDL_Surface *DGA_SetVideoMode(_THIS, SDL_Surface *current, | |
440 int width, int height, int bpp, Uint32 flags) | |
441 { | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
442 SDL_NAME(XDGAMode) *modes; |
0 | 443 int i, num_modes; |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
444 SDL_NAME(XDGADevice) *mode; |
0 | 445 int screen_len; |
446 Uint8 *surfaces_mem; | |
447 int surfaces_len; | |
448 | |
449 /* Free any previous colormap */ | |
450 if ( DGA_colormap ) { | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
451 pXFreeColormap(DGA_Display, DGA_colormap); |
0 | 452 DGA_colormap = 0; |
453 } | |
454 | |
455 /* Search for a matching video mode */ | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
456 modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes); |
0 | 457 qsort(modes, num_modes, sizeof *modes, cmpmodes); |
458 for ( i=0; i<num_modes; ++i ) { | |
459 int depth; | |
460 | |
461 | |
462 depth = modes[i].depth; | |
463 if ( depth == 24 ) { /* Distinguish between 24 and 32 bpp */ | |
464 depth = modes[i].bitsPerPixel; | |
465 } | |
466 if ( (depth == bpp) && | |
467 (modes[i].viewportWidth == width) && | |
468 (modes[i].viewportHeight == height) && | |
469 ((modes[i].visualClass == PseudoColor) || | |
470 (modes[i].visualClass == DirectColor) || | |
471 (modes[i].visualClass == TrueColor)) ) { | |
472 break; | |
473 } | |
474 } | |
475 if ( i == num_modes ) { | |
476 SDL_SetError("No matching video mode found"); | |
477 return(NULL); | |
478 } | |
479 | |
480 /* Set the video mode */ | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
481 mode = SDL_NAME(XDGASetMode)(DGA_Display, DGA_Screen, modes[i].num); |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
482 pXFree(modes); |
0 | 483 if ( mode == NULL ) { |
484 SDL_SetError("Unable to switch to requested mode"); | |
485 return(NULL); | |
486 } | |
559
b528214c8c9a
Fixed invalid memory access in DGA video driver (thanks ldb!)
Sam Lantinga <slouken@libsdl.org>
parents:
540
diff
changeset
|
487 DGA_visualClass = mode->mode.visualClass; |
0 | 488 memory_base = (Uint8 *)mode->data; |
489 memory_pitch = mode->mode.bytesPerScanline; | |
490 | |
491 /* Set up the new mode framebuffer */ | |
492 current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE); | |
493 current->w = mode->mode.viewportWidth; | |
494 current->h = mode->mode.viewportHeight; | |
495 current->pitch = memory_pitch; | |
496 current->pixels = memory_base; | |
497 if ( ! SDL_ReallocFormat(current, mode->mode.bitsPerPixel, | |
498 mode->mode.redMask, | |
499 mode->mode.greenMask, | |
500 mode->mode.blueMask, 0) ) { | |
501 return(NULL); | |
502 } | |
503 screen_len = current->h*current->pitch; | |
504 | |
505 /* Create a colormap if necessary */ | |
506 if ( (DGA_visualClass == PseudoColor) || | |
507 (DGA_visualClass == DirectColor) ) { | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
508 DGA_colormap = SDL_NAME(XDGACreateColormap)(DGA_Display, DGA_Screen, |
0 | 509 mode, AllocAll); |
510 if ( DGA_visualClass == PseudoColor ) { | |
511 current->flags |= SDL_HWPALETTE; | |
512 } else { | |
513 /* Initialize the colormap to the identity mapping */ | |
514 SDL_GetGammaRamp(0, 0, 0); | |
515 this->screen = current; | |
516 DGA_SetGammaRamp(this, this->gamma); | |
517 this->screen = NULL; | |
518 } | |
519 } else { | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
520 DGA_colormap = SDL_NAME(XDGACreateColormap)(DGA_Display, DGA_Screen, |
0 | 521 mode, AllocNone); |
522 } | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
523 SDL_NAME(XDGAInstallColormap)(DGA_Display, DGA_Screen, DGA_colormap); |
0 | 524 |
525 /* Update the hardware capabilities */ | |
526 UpdateHWInfo(this, &mode->mode); | |
527 | |
528 /* Set up the information for hardware surfaces */ | |
529 surfaces_mem = (Uint8 *)current->pixels + screen_len; | |
530 surfaces_len = (mode->mode.imageHeight*current->pitch - screen_len); | |
531 | |
532 /* Update for double-buffering, if we can */ | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
533 SDL_NAME(XDGASetViewport)(DGA_Display, DGA_Screen, 0, 0, XDGAFlipRetrace); |
0 | 534 if ( flags & SDL_DOUBLEBUF ) { |
535 if ( mode->mode.imageHeight >= (current->h*2) ) { | |
536 current->flags |= SDL_DOUBLEBUF; | |
537 flip_page = 0; | |
538 flip_yoffset[0] = 0; | |
539 flip_yoffset[1] = current->h; | |
540 flip_address[0] = memory_base; | |
541 flip_address[1] = memory_base+screen_len; | |
542 surfaces_mem += screen_len; | |
543 surfaces_len -= screen_len; | |
544 } | |
545 } | |
546 | |
547 /* Allocate memory tracking for hardware surfaces */ | |
548 DGA_FreeHWSurfaces(this); | |
549 if ( surfaces_len < 0 ) { | |
550 surfaces_len = 0; | |
551 } | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
552 DGA_InitHWSurfaces(this, current, surfaces_mem, surfaces_len); |
0 | 553 |
202
401f0134f4f9
Fixed crash when using double-buffering with DGA
Sam Lantinga <slouken@libsdl.org>
parents:
105
diff
changeset
|
554 /* Expose the back buffer as surface memory */ |
401f0134f4f9
Fixed crash when using double-buffering with DGA
Sam Lantinga <slouken@libsdl.org>
parents:
105
diff
changeset
|
555 if ( current->flags & SDL_DOUBLEBUF ) { |
401f0134f4f9
Fixed crash when using double-buffering with DGA
Sam Lantinga <slouken@libsdl.org>
parents:
105
diff
changeset
|
556 this->screen = current; |
401f0134f4f9
Fixed crash when using double-buffering with DGA
Sam Lantinga <slouken@libsdl.org>
parents:
105
diff
changeset
|
557 DGA_FlipHWSurface(this, current); |
401f0134f4f9
Fixed crash when using double-buffering with DGA
Sam Lantinga <slouken@libsdl.org>
parents:
105
diff
changeset
|
558 this->screen = NULL; |
401f0134f4f9
Fixed crash when using double-buffering with DGA
Sam Lantinga <slouken@libsdl.org>
parents:
105
diff
changeset
|
559 } |
401f0134f4f9
Fixed crash when using double-buffering with DGA
Sam Lantinga <slouken@libsdl.org>
parents:
105
diff
changeset
|
560 |
0 | 561 /* Set the update rectangle function */ |
562 this->UpdateRects = DGA_DirectUpdate; | |
563 | |
564 /* Enable mouse and keyboard support */ | |
565 { long input_mask; | |
566 input_mask = (KeyPressMask | KeyReleaseMask); | |
567 input_mask |= (ButtonPressMask | ButtonReleaseMask); | |
568 input_mask |= PointerMotionMask; | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
569 SDL_NAME(XDGASelectInput)(DGA_Display, DGA_Screen, input_mask); |
0 | 570 } |
571 | |
572 /* We're done */ | |
573 return(current); | |
574 } | |
575 | |
576 #ifdef DGA_DEBUG | |
577 static void DGA_DumpHWSurfaces(_THIS) | |
578 { | |
579 vidmem_bucket *bucket; | |
580 | |
581 printf("Memory left: %d (%d total)\n", surfaces_memleft, surfaces_memtotal); | |
582 printf("\n"); | |
583 printf(" Base Size\n"); | |
584 for ( bucket=&surfaces; bucket; bucket=bucket->next ) { | |
585 printf("Bucket: %p, %d (%s)\n", bucket->base, bucket->size, bucket->used ? "used" : "free"); | |
586 if ( bucket->prev ) { | |
587 if ( bucket->base != bucket->prev->base+bucket->prev->size ) { | |
588 printf("Warning, corrupt bucket list! (prev)\n"); | |
589 } | |
590 } else { | |
591 if ( bucket != &surfaces ) { | |
592 printf("Warning, corrupt bucket list! (!prev)\n"); | |
593 } | |
594 } | |
595 if ( bucket->next ) { | |
596 if ( bucket->next->base != bucket->base+bucket->size ) { | |
597 printf("Warning, corrupt bucket list! (next)\n"); | |
598 } | |
599 } | |
600 } | |
601 printf("\n"); | |
602 } | |
603 #endif | |
604 | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
605 static int DGA_InitHWSurfaces(_THIS, SDL_Surface *screen, Uint8 *base, int size) |
0 | 606 { |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
607 vidmem_bucket *bucket; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
608 |
0 | 609 surfaces_memtotal = size; |
610 surfaces_memleft = size; | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
611 |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
612 if ( surfaces_memleft > 0 ) { |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
613 bucket = (vidmem_bucket *)malloc(sizeof(*bucket)); |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
614 if ( bucket == NULL ) { |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
615 SDL_OutOfMemory(); |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
616 return(-1); |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
617 } |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
618 bucket->prev = &surfaces; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
619 bucket->used = 0; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
620 bucket->dirty = 0; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
621 bucket->base = base; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
622 bucket->size = size; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
623 bucket->next = NULL; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
624 } else { |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
625 bucket = NULL; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
626 } |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
627 |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
628 surfaces.prev = NULL; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
629 surfaces.used = 1; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
630 surfaces.dirty = 0; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
631 surfaces.base = screen->pixels; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
632 surfaces.size = (unsigned int)((long)base - (long)surfaces.base); |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
633 surfaces.next = bucket; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
634 screen->hwdata = (struct private_hwdata *)&surfaces; |
0 | 635 return(0); |
636 } | |
637 static void DGA_FreeHWSurfaces(_THIS) | |
638 { | |
639 vidmem_bucket *bucket, *freeable; | |
640 | |
641 bucket = surfaces.next; | |
642 while ( bucket ) { | |
643 freeable = bucket; | |
644 bucket = bucket->next; | |
645 free(freeable); | |
646 } | |
647 surfaces.next = NULL; | |
648 } | |
649 | |
105
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
650 static __inline__ void DGA_AddBusySurface(SDL_Surface *surface) |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
651 { |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
652 ((vidmem_bucket *)surface->hwdata)->dirty = 1; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
653 } |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
654 |
105
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
655 static __inline__ int DGA_IsSurfaceBusy(SDL_Surface *surface) |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
656 { |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
657 return ((vidmem_bucket *)surface->hwdata)->dirty; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
658 } |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
659 |
105
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
660 static __inline__ void DGA_WaitBusySurfaces(_THIS) |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
661 { |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
662 vidmem_bucket *bucket; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
663 |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
664 /* Wait for graphic operations to complete */ |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
665 SDL_NAME(XDGASync)(DGA_Display, DGA_Screen); |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
666 |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
667 /* Clear all surface dirty bits */ |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
668 for ( bucket=&surfaces; bucket; bucket=bucket->next ) { |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
669 bucket->dirty = 0; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
670 } |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
671 } |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
672 |
0 | 673 static int DGA_AllocHWSurface(_THIS, SDL_Surface *surface) |
674 { | |
675 vidmem_bucket *bucket; | |
676 int size; | |
677 int extra; | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
678 int retval = 0; |
0 | 679 |
680 /* Temporarily, we only allow surfaces the same width as display. | |
681 Some blitters require the pitch between two hardware surfaces | |
682 to be the same. Others have interesting alignment restrictions. | |
683 */ | |
684 if ( surface->pitch > SDL_VideoSurface->pitch ) { | |
685 SDL_SetError("Surface requested wider than screen"); | |
686 return(-1); | |
687 } | |
688 surface->pitch = SDL_VideoSurface->pitch; | |
689 size = surface->h * surface->pitch; | |
690 #ifdef DGA_DEBUG | |
691 fprintf(stderr, "Allocating bucket of %d bytes\n", size); | |
692 #endif | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
693 LOCK_DISPLAY(); |
0 | 694 |
695 /* Quick check for available mem */ | |
696 if ( size > surfaces_memleft ) { | |
697 SDL_SetError("Not enough video memory"); | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
698 retval = -1; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
699 goto done; |
0 | 700 } |
701 | |
702 /* Search for an empty bucket big enough */ | |
703 for ( bucket=&surfaces; bucket; bucket=bucket->next ) { | |
704 if ( ! bucket->used && (size <= bucket->size) ) { | |
705 break; | |
706 } | |
707 } | |
708 if ( bucket == NULL ) { | |
709 SDL_SetError("Video memory too fragmented"); | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
710 retval = -1; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
711 goto done; |
0 | 712 } |
713 | |
714 /* Create a new bucket for left-over memory */ | |
715 extra = (bucket->size - size); | |
716 if ( extra ) { | |
717 vidmem_bucket *newbucket; | |
718 | |
719 #ifdef DGA_DEBUG | |
720 fprintf(stderr, "Adding new free bucket of %d bytes\n", extra); | |
721 #endif | |
722 newbucket = (vidmem_bucket *)malloc(sizeof(*newbucket)); | |
723 if ( newbucket == NULL ) { | |
724 SDL_OutOfMemory(); | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
725 retval = -1; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
726 goto done; |
0 | 727 } |
728 newbucket->prev = bucket; | |
729 newbucket->used = 0; | |
730 newbucket->base = bucket->base+size; | |
731 newbucket->size = extra; | |
732 newbucket->next = bucket->next; | |
733 if ( bucket->next ) { | |
734 bucket->next->prev = newbucket; | |
735 } | |
736 bucket->next = newbucket; | |
737 } | |
738 | |
739 /* Set the current bucket values and return it! */ | |
740 bucket->used = 1; | |
741 bucket->size = size; | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
742 bucket->dirty = 0; |
0 | 743 #ifdef DGA_DEBUG |
744 fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base); | |
745 #endif | |
746 surfaces_memleft -= size; | |
747 surface->flags |= SDL_HWSURFACE; | |
748 surface->pixels = bucket->base; | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
749 surface->hwdata = (struct private_hwdata *)bucket; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
750 done: |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
751 UNLOCK_DISPLAY(); |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
752 return(retval); |
0 | 753 } |
754 static void DGA_FreeHWSurface(_THIS, SDL_Surface *surface) | |
755 { | |
756 vidmem_bucket *bucket, *freeable; | |
757 | |
758 /* Look for the bucket in the current list */ | |
102
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
759 for ( bucket=&surfaces; bucket; bucket=bucket->next ) { |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
760 if ( bucket == (vidmem_bucket *)surface->hwdata ) { |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
761 break; |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
762 } |
0 | 763 } |
102
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
764 if ( bucket && bucket->used ) { |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
765 /* Add the memory back to the total */ |
0 | 766 #ifdef DGA_DEBUG |
767 printf("Freeing bucket of %d bytes\n", bucket->size); | |
768 #endif | |
102
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
769 surfaces_memleft += bucket->size; |
0 | 770 |
102
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
771 /* Can we merge the space with surrounding buckets? */ |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
772 bucket->used = 0; |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
773 if ( bucket->next && ! bucket->next->used ) { |
0 | 774 #ifdef DGA_DEBUG |
775 printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size); | |
776 #endif | |
102
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
777 freeable = bucket->next; |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
778 bucket->size += bucket->next->size; |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
779 bucket->next = bucket->next->next; |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
780 if ( bucket->next ) { |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
781 bucket->next->prev = bucket; |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
782 } |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
783 free(freeable); |
0 | 784 } |
102
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
785 if ( bucket->prev && ! bucket->prev->used ) { |
0 | 786 #ifdef DGA_DEBUG |
787 printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size); | |
788 #endif | |
102
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
789 freeable = bucket; |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
790 bucket->prev->size += bucket->size; |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
791 bucket->prev->next = bucket->next; |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
792 if ( bucket->next ) { |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
793 bucket->next->prev = bucket->prev; |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
794 } |
9162d62280b5
Don't crash if freeing a hardware surface after the video mode has been
Sam Lantinga <slouken@lokigames.com>
parents:
101
diff
changeset
|
795 free(freeable); |
0 | 796 } |
797 } | |
798 surface->pixels = NULL; | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
799 surface->hwdata = NULL; |
0 | 800 } |
801 | |
105
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
802 static __inline__ void DGA_dst_to_xy(_THIS, SDL_Surface *dst, int *x, int *y) |
0 | 803 { |
804 *x = (long)((Uint8 *)dst->pixels - memory_base)%memory_pitch; | |
805 *y = (long)((Uint8 *)dst->pixels - memory_base)/memory_pitch; | |
806 } | |
807 | |
808 static int DGA_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) | |
809 { | |
810 int x, y; | |
811 unsigned int w, h; | |
812 | |
813 /* Don't fill the visible part of the screen, wait until flipped */ | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
814 LOCK_DISPLAY(); |
0 | 815 if ( was_flipped && (dst == this->screen) ) { |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
816 while ( SDL_NAME(XDGAGetViewportStatus)(DGA_Display, DGA_Screen) ) |
0 | 817 /* Keep waiting for the hardware ... */ ; |
818 was_flipped = 0; | |
819 } | |
105
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
820 DGA_dst_to_xy(this, dst, &x, &y); |
0 | 821 x += rect->x; |
822 y += rect->y; | |
823 w = rect->w; | |
824 h = rect->h; | |
825 #if 0 | |
826 printf("Hardware accelerated rectangle fill: %dx%d at %d,%d\n", w, h, x, y); | |
827 #endif | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
828 SDL_NAME(XDGAFillRectangle)(DGA_Display, DGA_Screen, x, y, w, h, color); |
540
4bcfb93e0dfe
Greatly improved X11 DGA video speed (thanks Cezary!)
Sam Lantinga <slouken@libsdl.org>
parents:
462
diff
changeset
|
829 if ( !(this->screen->flags & SDL_DOUBLEBUF) ) { |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
830 pXFlush(DGA_Display); |
540
4bcfb93e0dfe
Greatly improved X11 DGA video speed (thanks Cezary!)
Sam Lantinga <slouken@libsdl.org>
parents:
462
diff
changeset
|
831 } |
105
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
832 DGA_AddBusySurface(dst); |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
833 UNLOCK_DISPLAY(); |
0 | 834 return(0); |
835 } | |
836 | |
837 static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, | |
838 SDL_Surface *dst, SDL_Rect *dstrect) | |
839 { | |
840 SDL_VideoDevice *this; | |
841 int srcx, srcy; | |
842 int dstx, dsty; | |
843 unsigned int w, h; | |
844 | |
845 this = current_video; | |
846 /* Don't blit to the visible part of the screen, wait until flipped */ | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
847 LOCK_DISPLAY(); |
0 | 848 if ( was_flipped && (dst == this->screen) ) { |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
849 while ( SDL_NAME(XDGAGetViewportStatus)(DGA_Display, DGA_Screen) ) |
0 | 850 /* Keep waiting for the hardware ... */ ; |
851 was_flipped = 0; | |
852 } | |
105
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
853 DGA_dst_to_xy(this, src, &srcx, &srcy); |
0 | 854 srcx += srcrect->x; |
855 srcy += srcrect->y; | |
105
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
856 DGA_dst_to_xy(this, dst, &dstx, &dsty); |
0 | 857 dstx += dstrect->x; |
858 dsty += dstrect->y; | |
859 w = srcrect->w; | |
860 h = srcrect->h; | |
861 #if 0 | |
862 printf("Blitting %dx%d from %d,%d to %d,%d\n", w, h, srcx, srcy, dstx, dsty); | |
863 #endif | |
864 if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
865 SDL_NAME(XDGACopyTransparentArea)(DGA_Display, DGA_Screen, |
0 | 866 srcx, srcy, w, h, dstx, dsty, src->format->colorkey); |
867 } else { | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
868 SDL_NAME(XDGACopyArea)(DGA_Display, DGA_Screen, |
0 | 869 srcx, srcy, w, h, dstx, dsty); |
870 } | |
540
4bcfb93e0dfe
Greatly improved X11 DGA video speed (thanks Cezary!)
Sam Lantinga <slouken@libsdl.org>
parents:
462
diff
changeset
|
871 if ( !(this->screen->flags & SDL_DOUBLEBUF) ) { |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
872 pXFlush(DGA_Display); |
540
4bcfb93e0dfe
Greatly improved X11 DGA video speed (thanks Cezary!)
Sam Lantinga <slouken@libsdl.org>
parents:
462
diff
changeset
|
873 } |
105
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
874 DGA_AddBusySurface(src); |
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
875 DGA_AddBusySurface(dst); |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
876 UNLOCK_DISPLAY(); |
0 | 877 return(0); |
878 } | |
879 | |
880 static int DGA_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst) | |
881 { | |
882 int accelerated; | |
883 | |
884 /* Set initial acceleration on */ | |
885 src->flags |= SDL_HWACCEL; | |
886 | |
887 /* Set the surface attributes */ | |
888 if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { | |
889 if ( ! this->info.blit_hw_A ) { | |
890 src->flags &= ~SDL_HWACCEL; | |
891 } | |
892 } | |
893 if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { | |
894 if ( ! this->info.blit_hw_CC ) { | |
895 src->flags &= ~SDL_HWACCEL; | |
896 } | |
897 } | |
898 | |
899 /* Check to see if final surface blit is accelerated */ | |
900 accelerated = !!(src->flags & SDL_HWACCEL); | |
901 if ( accelerated ) { | |
902 src->map->hw_blit = HWAccelBlit; | |
903 } | |
904 return(accelerated); | |
905 } | |
906 | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
907 static __inline__ void DGA_WaitFlip(_THIS) |
0 | 908 { |
909 if ( was_flipped ) { | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
910 while ( SDL_NAME(XDGAGetViewportStatus)(DGA_Display, DGA_Screen) ) |
0 | 911 /* Keep waiting for the hardware ... */ ; |
912 was_flipped = 0; | |
913 } | |
914 } | |
915 | |
916 static int DGA_LockHWSurface(_THIS, SDL_Surface *surface) | |
917 { | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
918 if ( surface == this->screen ) { |
0 | 919 SDL_mutexP(hw_lock); |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
920 LOCK_DISPLAY(); |
105
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
921 if ( DGA_IsSurfaceBusy(surface) ) { |
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
922 DGA_WaitBusySurfaces(this); |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
923 } |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
924 DGA_WaitFlip(this); |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
925 UNLOCK_DISPLAY(); |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
926 } else { |
105
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
927 if ( DGA_IsSurfaceBusy(surface) ) { |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
928 LOCK_DISPLAY(); |
105
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
929 DGA_WaitBusySurfaces(this); |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
930 UNLOCK_DISPLAY(); |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
931 } |
0 | 932 } |
933 return(0); | |
934 } | |
935 static void DGA_UnlockHWSurface(_THIS, SDL_Surface *surface) | |
936 { | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
937 if ( surface == this->screen ) { |
0 | 938 SDL_mutexV(hw_lock); |
939 } | |
940 } | |
941 | |
942 static int DGA_FlipHWSurface(_THIS, SDL_Surface *surface) | |
943 { | |
944 /* Wait for vertical retrace and then flip display */ | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
945 LOCK_DISPLAY(); |
105
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
946 if ( DGA_IsSurfaceBusy(this->screen) ) { |
2136ea8953f9
Some minor name changes to clean up
Sam Lantinga <slouken@lokigames.com>
parents:
102
diff
changeset
|
947 DGA_WaitBusySurfaces(this); |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
948 } |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
949 DGA_WaitFlip(this); |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
950 SDL_NAME(XDGASetViewport)(DGA_Display, DGA_Screen, |
0 | 951 0, flip_yoffset[flip_page], XDGAFlipRetrace); |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
952 pXFlush(DGA_Display); |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
953 UNLOCK_DISPLAY(); |
0 | 954 was_flipped = 1; |
955 flip_page = !flip_page; | |
956 | |
957 surface->pixels = flip_address[flip_page]; | |
958 return(0); | |
959 } | |
960 | |
961 static void DGA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) | |
962 { | |
963 /* The application is already updating the visible video memory */ | |
964 return; | |
965 } | |
966 | |
967 static int DGA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | |
968 { | |
969 int i; | |
970 XColor *xcmap; | |
971 | |
972 /* This happens on initialization */ | |
973 if ( ! DGA_colormap ) { | |
974 return(0); | |
975 } | |
976 xcmap = (XColor *)alloca(ncolors*sizeof(*xcmap)); | |
977 for ( i=0; i<ncolors; ++i ) { | |
978 xcmap[i].pixel = firstcolor + i; | |
979 xcmap[i].red = (colors[i].r<<8)|colors[i].r; | |
980 xcmap[i].green = (colors[i].g<<8)|colors[i].g; | |
981 xcmap[i].blue = (colors[i].b<<8)|colors[i].b; | |
982 xcmap[i].flags = (DoRed|DoGreen|DoBlue); | |
983 } | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
984 LOCK_DISPLAY(); |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
985 pXStoreColors(DGA_Display, DGA_colormap, xcmap, ncolors); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
986 pXSync(DGA_Display, False); |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
987 UNLOCK_DISPLAY(); |
0 | 988 |
989 /* That was easy. :) */ | |
990 return(1); | |
991 } | |
992 | |
993 int DGA_SetGammaRamp(_THIS, Uint16 *ramp) | |
994 { | |
995 int i, ncolors; | |
996 XColor xcmap[256]; | |
997 | |
998 /* See if actually setting the gamma is supported */ | |
999 if ( DGA_visualClass != DirectColor ) { | |
1000 SDL_SetError("Gamma correction not supported on this visual"); | |
1001 return(-1); | |
1002 } | |
1003 | |
1004 /* Calculate the appropriate palette for the given gamma ramp */ | |
1005 if ( this->screen->format->BitsPerPixel <= 16 ) { | |
1006 ncolors = 64; /* Is this right? */ | |
1007 } else { | |
1008 ncolors = 256; | |
1009 } | |
1010 for ( i=0; i<ncolors; ++i ) { | |
1011 Uint8 c = (256 * i / ncolors); | |
1012 xcmap[i].pixel = SDL_MapRGB(this->screen->format, c, c, c); | |
1013 xcmap[i].red = ramp[0*256+c]; | |
1014 xcmap[i].green = ramp[1*256+c]; | |
1015 xcmap[i].blue = ramp[2*256+c]; | |
1016 xcmap[i].flags = (DoRed|DoGreen|DoBlue); | |
1017 } | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1018 LOCK_DISPLAY(); |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
1019 pXStoreColors(DGA_Display, DGA_colormap, xcmap, ncolors); |
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
1020 pXSync(DGA_Display, False); |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1021 UNLOCK_DISPLAY(); |
0 | 1022 return(0); |
1023 } | |
1024 | |
1025 void DGA_VideoQuit(_THIS) | |
1026 { | |
1027 int i, j; | |
1028 | |
1029 if ( DGA_Display ) { | |
1030 /* Free colormap, if necessary */ | |
1031 if ( DGA_colormap ) { | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
1032 pXFreeColormap(DGA_Display, DGA_colormap); |
0 | 1033 DGA_colormap = 0; |
1034 } | |
1035 | |
1036 /* Unmap memory and reset video mode */ | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
1037 SDL_NAME(XDGACloseFramebuffer)(DGA_Display, DGA_Screen); |
0 | 1038 if ( this->screen ) { |
1039 /* Tell SDL not to free the pixels */ | |
1040 this->screen->pixels = NULL; | |
1041 } | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
1042 SDL_NAME(XDGASetMode)(DGA_Display, DGA_Screen, 0); |
0 | 1043 |
1044 /* Clear the lock mutex */ | |
1045 if ( hw_lock != NULL ) { | |
1046 SDL_DestroyMutex(hw_lock); | |
1047 hw_lock = NULL; | |
1048 } | |
101
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1049 #ifdef LOCK_DGA_DISPLAY |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1050 if ( event_lock != NULL ) { |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1051 SDL_DestroyMutex(event_lock); |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1052 event_lock = NULL; |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1053 } |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1054 #endif /* LOCK_DGA_DISPLAY */ |
825b2fa28e2e
DGA video driver is now thread-safe
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1055 |
0 | 1056 |
1057 /* Clean up defined video modes */ | |
1058 for ( i=0; i<NUM_MODELISTS; ++i ) { | |
1059 if ( SDL_modelist[i] != NULL ) { | |
1060 for ( j=0; SDL_modelist[i][j]; ++j ) { | |
1061 free(SDL_modelist[i][j]); | |
1062 } | |
1063 free(SDL_modelist[i]); | |
1064 SDL_modelist[i] = NULL; | |
1065 } | |
1066 } | |
1067 | |
1068 /* Clean up the memory bucket list */ | |
1069 DGA_FreeHWSurfaces(this); | |
1070 | |
1071 /* Close up the display */ | |
1168
045f186426e1
Dynamically load X11 libraries like we currently do for alsa, esd, etc.
Ryan C. Gordon <icculus@icculus.org>
parents:
966
diff
changeset
|
1072 pXCloseDisplay(DGA_Display); |
0 | 1073 } |
1074 } |