Mercurial > sdl-ios-xcode
comparison src/video/ps3/SDL_ps3render.c @ 3141:3df74541339b gsoc2009_ps3
Added ps3 video driver based on the dummy driver.
Added spulib for copying to framebuffer.
Added SPU managing functions.
Added open/close and taking control of the framebuffer.
author | Martin Lowinski <martin@goldtopf.org> |
---|---|
date | Fri, 29 May 2009 09:50:21 +0000 |
parents | |
children | c146645a770e |
comparison
equal
deleted
inserted
replaced
3140:9ef99b844c60 | 3141:3df74541339b |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997-2009 Sam Lantinga | |
4 | |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Lesser General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2.1 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 Lesser General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Lesser General Public | |
16 License along with this library; if not, write to the Free Software | |
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
18 | |
19 Sam Lantinga | |
20 slouken@libsdl.org | |
21 */ | |
22 #include "SDL_config.h" | |
23 | |
24 #include "SDL_video.h" | |
25 #include "../SDL_sysvideo.h" | |
26 #include "../SDL_yuv_sw_c.h" | |
27 #include "../SDL_renderer_sw.h" | |
28 | |
29 /* Debugging | |
30 * 0: No debug messages | |
31 * 1: Video debug messages | |
32 * 2: SPE debug messages | |
33 * 3: Memory adresses | |
34 */ | |
35 #define DEBUG_LEVEL 2 | |
36 | |
37 #ifdef DEBUG_LEVEL | |
38 #define deprintf( level, fmt, args... ) \ | |
39 do \ | |
40 { \ | |
41 if ( (unsigned)(level) <= DEBUG_LEVEL ) \ | |
42 { \ | |
43 fprintf( stdout, fmt, ##args ); \ | |
44 fflush( stdout ); \ | |
45 } \ | |
46 } while ( 0 ) | |
47 #else | |
48 #define deprintf( level, fmt, args... ) | |
49 #endif | |
50 | |
51 /* SDL surface based renderer implementation */ | |
52 | |
53 static SDL_Renderer *SDL_PS3_CreateRenderer(SDL_Window * window, | |
54 Uint32 flags); | |
55 static int SDL_PS3_RenderPoint(SDL_Renderer * renderer, int x, int y); | |
56 static int SDL_PS3_RenderLine(SDL_Renderer * renderer, int x1, int y1, | |
57 int x2, int y2); | |
58 static int SDL_PS3_RenderFill(SDL_Renderer * renderer, | |
59 const SDL_Rect * rect); | |
60 static int SDL_PS3_RenderCopy(SDL_Renderer * renderer, | |
61 SDL_Texture * texture, | |
62 const SDL_Rect * srcrect, | |
63 const SDL_Rect * dstrect); | |
64 static void SDL_PS3_RenderPresent(SDL_Renderer * renderer); | |
65 static void SDL_PS3_DestroyRenderer(SDL_Renderer * renderer); | |
66 | |
67 | |
68 SDL_RenderDriver SDL_PS3_RenderDriver = { | |
69 SDL_PS3_CreateRenderer, | |
70 { | |
71 "ps3", | |
72 (/*SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |*/ | |
73 SDL_RENDERER_PRESENTFLIP2 /*| SDL_RENDERER_PRESENTFLIP3 | | |
74 SDL_RENDERER_PRESENTDISCARD*/), | |
75 } | |
76 }; | |
77 | |
78 typedef struct | |
79 { | |
80 int current_screen; | |
81 SDL_Surface *screens[3]; | |
82 } SDL_PS3_RenderData; | |
83 | |
84 SDL_Renderer * | |
85 SDL_PS3_CreateRenderer(SDL_Window * window, Uint32 flags) | |
86 { | |
87 deprintf(1, "SDL_PS3_CreateRenderer()\n"); | |
88 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); | |
89 SDL_DisplayMode *displayMode = &display->current_mode; | |
90 SDL_Renderer *renderer; | |
91 SDL_PS3_RenderData *data; | |
92 int i, n; | |
93 int bpp; | |
94 Uint32 Rmask, Gmask, Bmask, Amask; | |
95 | |
96 if (!SDL_PixelFormatEnumToMasks | |
97 (displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { | |
98 SDL_SetError("Unknown display format"); | |
99 return NULL; | |
100 } | |
101 | |
102 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); | |
103 if (!renderer) { | |
104 SDL_OutOfMemory(); | |
105 return NULL; | |
106 } | |
107 | |
108 data = (SDL_PS3_RenderData *) SDL_malloc(sizeof(*data)); | |
109 if (!data) { | |
110 SDL_PS3_DestroyRenderer(renderer); | |
111 SDL_OutOfMemory(); | |
112 return NULL; | |
113 } | |
114 SDL_zerop(data); | |
115 | |
116 renderer->RenderPoint = SDL_PS3_RenderPoint; | |
117 renderer->RenderLine = SDL_PS3_RenderLine; | |
118 renderer->RenderFill = SDL_PS3_RenderFill; | |
119 renderer->RenderCopy = SDL_PS3_RenderCopy; | |
120 renderer->RenderPresent = SDL_PS3_RenderPresent; | |
121 renderer->DestroyRenderer = SDL_PS3_DestroyRenderer; | |
122 renderer->info.name = SDL_PS3_RenderDriver.info.name; | |
123 renderer->info.flags = 0; | |
124 renderer->window = window->id; | |
125 renderer->driverdata = data; | |
126 Setup_SoftwareRenderer(renderer); | |
127 | |
128 if (flags & SDL_RENDERER_PRESENTFLIP2) { | |
129 renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; | |
130 n = 2; | |
131 } else if (flags & SDL_RENDERER_PRESENTFLIP3) { | |
132 renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; | |
133 n = 3; | |
134 } else { | |
135 renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; | |
136 n = 1; | |
137 } | |
138 for (i = 0; i < n; ++i) { | |
139 data->screens[i] = | |
140 SDL_CreateRGBSurface(0, window->w, window->h, bpp, Rmask, Gmask, | |
141 Bmask, Amask); | |
142 if (!data->screens[i]) { | |
143 SDL_PS3_DestroyRenderer(renderer); | |
144 return NULL; | |
145 } | |
146 /* Allocate aligned memory for pixels */ | |
147 SDL_free(data->screens[i]->pixels); | |
148 data->screens[i]->pixels = (void *)memalign(16, data->screens[i]->h * data->screens[i]->pitch); | |
149 if (!data->screens[i]->pixels) { | |
150 SDL_FreeSurface(data->screens[i]); | |
151 SDL_OutOfMemory(); | |
152 return NULL; | |
153 } | |
154 SDL_memset(data->screens[i]->pixels, 0, data->screens[i]->h * data->screens[i]->pitch); | |
155 SDL_SetSurfacePalette(data->screens[i], display->palette); | |
156 } | |
157 data->current_screen = 0; | |
158 | |
159 return renderer; | |
160 } | |
161 | |
162 static int | |
163 SDL_PS3_RenderPoint(SDL_Renderer * renderer, int x, int y) | |
164 { | |
165 SDL_PS3_RenderData *data = | |
166 (SDL_PS3_RenderData *) renderer->driverdata; | |
167 SDL_Surface *target = data->screens[data->current_screen]; | |
168 int status; | |
169 | |
170 if (renderer->blendMode == SDL_BLENDMODE_NONE || | |
171 renderer->blendMode == SDL_BLENDMODE_MASK) { | |
172 Uint32 color = | |
173 SDL_MapRGBA(target->format, renderer->r, renderer->g, renderer->b, | |
174 renderer->a); | |
175 | |
176 status = SDL_DrawPoint(target, x, y, color); | |
177 } else { | |
178 status = | |
179 SDL_BlendPoint(target, x, y, renderer->blendMode, renderer->r, | |
180 renderer->g, renderer->b, renderer->a); | |
181 } | |
182 return status; | |
183 } | |
184 | |
185 static int | |
186 SDL_PS3_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) | |
187 { | |
188 SDL_PS3_RenderData *data = | |
189 (SDL_PS3_RenderData *) renderer->driverdata; | |
190 SDL_Surface *target = data->screens[data->current_screen]; | |
191 int status; | |
192 | |
193 if (renderer->blendMode == SDL_BLENDMODE_NONE || | |
194 renderer->blendMode == SDL_BLENDMODE_MASK) { | |
195 Uint32 color = | |
196 SDL_MapRGBA(target->format, renderer->r, renderer->g, renderer->b, | |
197 renderer->a); | |
198 | |
199 status = SDL_DrawLine(target, x1, y1, x2, y2, color); | |
200 } else { | |
201 status = | |
202 SDL_BlendLine(target, x1, y1, x2, y2, renderer->blendMode, | |
203 renderer->r, renderer->g, renderer->b, renderer->a); | |
204 } | |
205 return status; | |
206 } | |
207 | |
208 static int | |
209 SDL_PS3_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect) | |
210 { | |
211 deprintf(1, "SDL_PS3_RenderFill()\n"); | |
212 SDL_PS3_RenderData *data = | |
213 (SDL_PS3_RenderData *) renderer->driverdata; | |
214 SDL_Surface *target = data->screens[data->current_screen]; | |
215 SDL_Rect real_rect = *rect; | |
216 int status; | |
217 | |
218 if (renderer->blendMode == SDL_BLENDMODE_NONE) { | |
219 Uint32 color = | |
220 SDL_MapRGBA(target->format, renderer->r, renderer->g, renderer->b, | |
221 renderer->a); | |
222 | |
223 status = SDL_FillRect(target, &real_rect, color); | |
224 } else { | |
225 status = | |
226 SDL_BlendRect(target, &real_rect, renderer->blendMode, | |
227 renderer->r, renderer->g, renderer->b, renderer->a); | |
228 } | |
229 return status; | |
230 } | |
231 | |
232 static int | |
233 SDL_PS3_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, | |
234 const SDL_Rect * srcrect, const SDL_Rect * dstrect) | |
235 { | |
236 deprintf(1, "SDL_PS3_RenderCopy()\n"); | |
237 SDL_PS3_RenderData *data = | |
238 (SDL_PS3_RenderData *) renderer->driverdata; | |
239 SDL_Window *window = SDL_GetWindowFromID(renderer->window); | |
240 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); | |
241 | |
242 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | |
243 SDL_Surface *target = data->screens[data->current_screen]; | |
244 void *pixels = | |
245 (Uint8 *) target->pixels + dstrect->y * target->pitch + | |
246 dstrect->x * target->format->BytesPerPixel; | |
247 return SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata, | |
248 srcrect, display->current_mode.format, | |
249 dstrect->w, dstrect->h, pixels, | |
250 target->pitch); | |
251 } else { | |
252 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
253 SDL_Surface *target = data->screens[data->current_screen]; | |
254 SDL_Rect real_srcrect = *srcrect; | |
255 SDL_Rect real_dstrect = *dstrect; | |
256 | |
257 return SDL_LowerBlit(surface, &real_srcrect, target, &real_dstrect); | |
258 } | |
259 } | |
260 | |
261 static void | |
262 SDL_PS3_RenderPresent(SDL_Renderer * renderer) | |
263 { | |
264 deprintf(1, "SDL_PS3_RenderPresent()\n"); | |
265 static int frame_number; | |
266 SDL_PS3_RenderData *data = | |
267 (SDL_PS3_RenderData *) renderer->driverdata; | |
268 | |
269 /* Send the data to the display */ | |
270 if (SDL_getenv("SDL_VIDEO_PS3_SAVE_FRAMES")) { | |
271 char file[128]; | |
272 SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp", | |
273 renderer->window, ++frame_number); | |
274 SDL_SaveBMP(data->screens[data->current_screen], file); | |
275 } | |
276 | |
277 /* Update the flipping chain, if any */ | |
278 if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) { | |
279 data->current_screen = (data->current_screen + 1) % 2; | |
280 } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) { | |
281 data->current_screen = (data->current_screen + 1) % 3; | |
282 } | |
283 | |
284 /* How to access the framebuffer from here? | |
285 unsigned long crt = 0; | |
286 unsigned int s_center_index = 0; | |
287 unsigned int * s_center[2]; | |
288 s_center[0] = frame_buffer; | |
289 // Wait for vsync | |
290 deprintf(1, "[PS3] Wait for vsync\n"); | |
291 ioctl(fbdev, FBIO_WAITFORVSYNC, &crt); | |
292 // Page flip | |
293 deprintf(1, "[PS3] Page flip to buffer #%u 0x%x\n", s_center_index, s_center[s_center_index]); | |
294 ioctl(fbdev, PS3FB_IOCTL_FSEL, (unsigned long)&s_center_index); | |
295 */ | |
296 } | |
297 | |
298 static void | |
299 SDL_PS3_DestroyRenderer(SDL_Renderer * renderer) | |
300 { | |
301 deprintf(1, "SDL_PS3_DestroyRenderer()\n"); | |
302 SDL_PS3_RenderData *data = | |
303 (SDL_PS3_RenderData *) renderer->driverdata; | |
304 int i; | |
305 | |
306 if (data) { | |
307 for (i = 0; i < SDL_arraysize(data->screens); ++i) { | |
308 if (data->screens[i]) { | |
309 SDL_FreeSurface(data->screens[i]); | |
310 } | |
311 } | |
312 SDL_free(data); | |
313 } | |
314 SDL_free(renderer); | |
315 } | |
316 | |
317 /* vi: set ts=4 sw=4 expandtab: */ |