comparison src/video/ps3/SDL_ps3render.c @ 3152:7f3341cccf42 gsoc2009_ps3

Working 1080p, 720p, 480p videomodes and double buffering.
author Martin Lowinski <martin@goldtopf.org>
date Thu, 06 Aug 2009 12:24:47 +0000
parents 0cf7bff804ad
children a16c4ec43631
comparison
equal deleted inserted replaced
3151:4a88137385f9 3152:7f3341cccf42
44 44
45 /* SDL surface based renderer implementation */ 45 /* SDL surface based renderer implementation */
46 46
47 static SDL_Renderer *SDL_PS3_CreateRenderer(SDL_Window * window, 47 static SDL_Renderer *SDL_PS3_CreateRenderer(SDL_Window * window,
48 Uint32 flags); 48 Uint32 flags);
49 static int SDL_PS3_DisplayModeChanged(SDL_Renderer * renderer);
49 static int SDL_PS3_ActivateRenderer(SDL_Renderer * renderer); 50 static int SDL_PS3_ActivateRenderer(SDL_Renderer * renderer);
50 static int SDL_PS3_RenderPoint(SDL_Renderer * renderer, int x, int y); 51 static int SDL_PS3_RenderPoint(SDL_Renderer * renderer, int x, int y);
51 static int SDL_PS3_RenderLine(SDL_Renderer * renderer, int x1, int y1, 52 static int SDL_PS3_RenderLine(SDL_Renderer * renderer, int x1, int y1,
52 int x2, int y2); 53 int x2, int y2);
53 static int SDL_PS3_RenderFill(SDL_Renderer * renderer, 54 static int SDL_PS3_RenderFill(SDL_Renderer * renderer,
124 int pitch; 125 int pitch;
125 /* Image data */ 126 /* Image data */
126 volatile void *pixels; 127 volatile void *pixels;
127 /* Use software renderer for not supported formats */ 128 /* Use software renderer for not supported formats */
128 SDL_SW_YUVTexture *yuv; 129 SDL_SW_YUVTexture *yuv;
129 /* Can we use the SPE to process this texture? */
130 unsigned int accelerated;
131 } PS3_TextureData; 130 } PS3_TextureData;
132 131
133 SDL_Renderer * 132 SDL_Renderer *
134 SDL_PS3_CreateRenderer(SDL_Window * window, Uint32 flags) 133 SDL_PS3_CreateRenderer(SDL_Window * window, Uint32 flags)
135 { 134 {
136 deprintf(1, "+SDL_PS3_CreateRenderer()\n"); 135 deprintf(1, "+SDL_PS3_CreateRenderer()\n");
137 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); 136 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
138 SDL_DisplayMode *displayMode = &display->current_mode; 137 SDL_DisplayMode *displayMode = &display->current_mode;
138 SDL_VideoData *devdata = display->device->driverdata;
139 SDL_Renderer *renderer; 139 SDL_Renderer *renderer;
140 SDL_PS3_RenderData *data; 140 SDL_PS3_RenderData *data;
141 struct ps3fb_ioctl_res res;
141 int i, n; 142 int i, n;
142 int bpp; 143 int bpp;
143 Uint32 Rmask, Gmask, Bmask, Amask; 144 Uint32 Rmask, Gmask, Bmask, Amask;
144 145
145 if (!SDL_PixelFormatEnumToMasks 146 if (!SDL_PixelFormatEnumToMasks
167 renderer->QueryTexturePixels = PS3_QueryTexturePixels; 168 renderer->QueryTexturePixels = PS3_QueryTexturePixels;
168 renderer->UpdateTexture = PS3_UpdateTexture; 169 renderer->UpdateTexture = PS3_UpdateTexture;
169 renderer->LockTexture = PS3_LockTexture; 170 renderer->LockTexture = PS3_LockTexture;
170 renderer->UnlockTexture = PS3_UnlockTexture; 171 renderer->UnlockTexture = PS3_UnlockTexture;
171 renderer->ActivateRenderer = SDL_PS3_ActivateRenderer; 172 renderer->ActivateRenderer = SDL_PS3_ActivateRenderer;
173 renderer->DisplayModeChanged = SDL_PS3_DisplayModeChanged;
172 renderer->RenderPoint = SDL_PS3_RenderPoint; 174 renderer->RenderPoint = SDL_PS3_RenderPoint;
173 renderer->RenderLine = SDL_PS3_RenderLine; 175 renderer->RenderLine = SDL_PS3_RenderLine;
174 renderer->RenderFill = SDL_PS3_RenderFill; 176 renderer->RenderFill = SDL_PS3_RenderFill;
175 renderer->RenderCopy = SDL_PS3_RenderCopy; 177 renderer->RenderCopy = SDL_PS3_RenderCopy;
176 renderer->RenderPresent = SDL_PS3_RenderPresent; 178 renderer->RenderPresent = SDL_PS3_RenderPresent;
177 renderer->DestroyRenderer = SDL_PS3_DestroyRenderer; 179 renderer->DestroyRenderer = SDL_PS3_DestroyRenderer;
178 renderer->info.name = SDL_PS3_RenderDriver.info.name; 180 renderer->info.name = SDL_PS3_RenderDriver.info.name;
179 renderer->info.flags = 0; 181 renderer->info.flags = 0;
180 renderer->window = window->id; 182 renderer->window = window->id;
181 renderer->driverdata = data; 183 renderer->driverdata = data;
182 //Setup_SoftwareRenderer(renderer);
183 184
184 deprintf(1, "window->w = %u\n", window->w); 185 deprintf(1, "window->w = %u\n", window->w);
185 deprintf(1, "window->h = %u\n", window->h); 186 deprintf(1, "window->h = %u\n", window->h);
186 187
187 data->double_buffering = 0; 188 data->double_buffering = 0;
188 189
189 if (flags & SDL_RENDERER_PRESENTFLIP2) { 190 /* Get ps3 screeninfo */
191 if (ioctl(devdata->fbdev, PS3FB_IOCTL_SCREENINFO, (unsigned long)&res) < 0) {
192 SDL_SetError("[PS3] PS3FB_IOCTL_SCREENINFO failed");
193 }
194 deprintf(2, "res.num_frames = %d\n", res.num_frames);
195
196 /* Only use double buffering if enough fb memory is available */
197 if (res.num_frames > 1) {
190 renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; 198 renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
191 n = 2; 199 n = 2;
192 data->double_buffering = 1; 200 data->double_buffering = 1;
193 } else { 201 } else {
194 renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; 202 renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
231 SDL_PS3_DestroyRenderer(renderer); 239 SDL_PS3_DestroyRenderer(renderer);
232 SDL_OutOfMemory(); 240 SDL_OutOfMemory();
233 return NULL; 241 return NULL;
234 } 242 }
235 243
236 /* Set up the SPE scaler */ 244 /* Set up the SPE scaler (booted) */
237 data->scaler_thread_data->program = bilin_scaler_spu; 245 data->scaler_thread_data->program = bilin_scaler_spu;
238 data->scaler_thread_data->program_name = "bilin_scaler_spu"; 246 data->scaler_thread_data->program_name = "bilin_scaler_spu";
239 data->scaler_thread_data->keepalive = 0; 247 data->scaler_thread_data->keepalive = 0;
240 data->scaler_thread_data->booted = 0; 248 data->scaler_thread_data->booted = 0;
241 249
242 /* Set up the SPE converter */ 250 /* Set up the SPE converter (always running) */
243 data->converter_thread_data->program = yuv2rgb_spu; 251 data->converter_thread_data->program = yuv2rgb_spu;
244 data->converter_thread_data->program_name = "yuv2rgb_spu"; 252 data->converter_thread_data->program_name = "yuv2rgb_spu";
245 data->converter_thread_data->keepalive = 1; 253 data->converter_thread_data->keepalive = 1;
246 data->converter_thread_data->booted = 0; 254 data->converter_thread_data->booted = 0;
247 255
256 { 264 {
257 deprintf(1, "+PS3_ActivateRenderer()\n"); 265 deprintf(1, "+PS3_ActivateRenderer()\n");
258 SDL_PS3_RenderData *data = (SDL_PS3_RenderData *) renderer->driverdata; 266 SDL_PS3_RenderData *data = (SDL_PS3_RenderData *) renderer->driverdata;
259 267
260 deprintf(1, "-PS3_ActivateRenderer()\n"); 268 deprintf(1, "-PS3_ActivateRenderer()\n");
269 return 0;
270 }
271
272 static int SDL_PS3_DisplayModeChanged(SDL_Renderer * renderer) {
273 deprintf(1, "+PS3_DisplayModeChanged()\n");
274 SDL_PS3_RenderData *data = (SDL_PS3_RenderData *) renderer->driverdata;
275
276 deprintf(1, "-PS3_DisplayModeChanged()\n");
261 return 0; 277 return 0;
262 } 278 }
263 279
264 static int 280 static int
265 PS3_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { 281 PS3_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) {
269 if (!data) { 285 if (!data) {
270 SDL_OutOfMemory(); 286 SDL_OutOfMemory();
271 return -1; 287 return -1;
272 } 288 }
273 data->pitch = (texture->w * SDL_BYTESPERPIXEL(texture->format)); 289 data->pitch = (texture->w * SDL_BYTESPERPIXEL(texture->format));
274 data->accelerated = 0;
275 290
276 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 291 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
277 /* Use SDLs SW_YUVTexture */ 292 /* Use SDLs SW_YUVTexture */
278 data->yuv = 293 data->yuv =
279 SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h); 294 SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h);
311 /* We should never get here (caught above) */ 326 /* We should never get here (caught above) */
312 break; 327 break;
313 } 328 }
314 if ((texture->format & SDL_PIXELFORMAT_YV12 || texture->format & SDL_PIXELFORMAT_IYUV) 329 if ((texture->format & SDL_PIXELFORMAT_YV12 || texture->format & SDL_PIXELFORMAT_IYUV)
315 && texture->w % 16 == 0 && texture->h % 16 == 0) { 330 && texture->w % 16 == 0 && texture->h % 16 == 0) {
316 data->accelerated = 1;
317 } 331 }
318 } else { 332 } else {
319 data->pixels = NULL; 333 data->pixels = NULL;
320 data->pixels = SDL_malloc(texture->h * data->pitch); 334 data->pixels = SDL_malloc(texture->h * data->pitch);
321 if (!data->pixels) { 335 if (!data->pixels) {
383 { 397 {
384 deprintf(1, "+PS3_LockTexture()\n"); 398 deprintf(1, "+PS3_LockTexture()\n");
385 PS3_TextureData *data = (PS3_TextureData *) texture->driverdata; 399 PS3_TextureData *data = (PS3_TextureData *) texture->driverdata;
386 400
387 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 401 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
402 deprintf(1, "-PS3_LockTexture()\n");
388 return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels, pitch); 403 return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels, pitch);
389 } else { 404 } else {
390 *pixels = 405 *pixels =
391 (void *) ((Uint8 *) data->pixels + rect->y * data->pitch + 406 (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
392 rect->x * SDL_BYTESPERPIXEL(texture->format)); 407 rect->x * SDL_BYTESPERPIXEL(texture->format));
393 *pitch = data->pitch; 408 *pitch = data->pitch;
409 deprintf(1, "-PS3_LockTexture()\n");
394 return 0; 410 return 0;
395 } 411 }
396 deprintf(1, "-PS3_LockTexture()\n");
397 } 412 }
398 413
399 static void 414 static void
400 PS3_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) 415 PS3_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
401 { 416 {
520 deprintf(1, "texture->w = %u\n", texture->w); 535 deprintf(1, "texture->w = %u\n", texture->w);
521 deprintf(1, "texture->h = %u\n", texture->h); 536 deprintf(1, "texture->h = %u\n", texture->h);
522 537
523 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 538 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
524 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = true\n"); 539 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = true\n");
525 if (txdata->accelerated) { 540 if ((texture->format & SDL_PIXELFORMAT_YV12 || texture->format & SDL_PIXELFORMAT_IYUV)
541 && texture->w % 8 == 0 && texture->h % 8 == 0
542 && dstrect->w % 8 == 0 && dstrect->h % 8 == 0) {
526 deprintf(1, "Use SPE for scaling/converting\n"); 543 deprintf(1, "Use SPE for scaling/converting\n");
527 544
528 SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) txdata->yuv; 545 SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) txdata->yuv;
529 Uint8 *lum, *Cr, *Cb; 546 Uint8 *lum, *Cr, *Cb;
530 Uint8 *scaler_out = NULL; 547 Uint8 *scaler_out = NULL;
628 645
629 static void 646 static void
630 SDL_PS3_RenderPresent(SDL_Renderer * renderer) 647 SDL_PS3_RenderPresent(SDL_Renderer * renderer)
631 { 648 {
632 deprintf(1, "+SDL_PS3_RenderPresent()\n"); 649 deprintf(1, "+SDL_PS3_RenderPresent()\n");
633 static int frame_number;
634 SDL_PS3_RenderData *data = 650 SDL_PS3_RenderData *data =
635 (SDL_PS3_RenderData *) renderer->driverdata; 651 (SDL_PS3_RenderData *) renderer->driverdata;
636 SDL_Window *window = SDL_GetWindowFromID(renderer->window); 652 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
637 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); 653 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
638 SDL_VideoData *devdata = display->device->driverdata; 654 SDL_VideoData *devdata = display->device->driverdata;
654 // txdata->bpp = fb_vinfo.red.length + fb_vinfo.green.length + fb_vinfo.blue.length; 670 // txdata->bpp = fb_vinfo.red.length + fb_vinfo.green.length + fb_vinfo.blue.length;
655 671
656 /* Adjust centering */ 672 /* Adjust centering */
657 data->bounded_width = window->w < fb_vinfo.xres ? window->w : fb_vinfo.xres; 673 data->bounded_width = window->w < fb_vinfo.xres ? window->w : fb_vinfo.xres;
658 data->bounded_height = window->h < fb_vinfo.yres ? window->h : fb_vinfo.yres; 674 data->bounded_height = window->h < fb_vinfo.yres ? window->h : fb_vinfo.yres;
675 /* We could use SDL's CENTERED flag for centering */
659 data->offset_left = (fb_vinfo.xres - data->bounded_width) >> 1; 676 data->offset_left = (fb_vinfo.xres - data->bounded_width) >> 1;
660 data->offset_top = (fb_vinfo.yres - data->bounded_height) >> 1; 677 data->offset_top = (fb_vinfo.yres - data->bounded_height) >> 1;
661 data->center[0] = devdata->frame_buffer + data->offset_left * /*txdata->bpp/8*/ 4 + 678 data->center[0] = devdata->frame_buffer + data->offset_left * /*txdata->bpp/8*/ 4 +
662 data->offset_top * fb_finfo.line_length; 679 data->offset_top * fb_finfo.line_length;
663 data->center[1] = data->center[0] + fb_vinfo.yres * fb_finfo.line_length; 680 data->center[1] = data->center[0] + fb_vinfo.yres * fb_finfo.line_length;
693 /* Page flip */ 710 /* Page flip */
694 deprintf(1, "[PS3] Page flip to buffer #%u 0x%x\n", data->current_screen, data->center[data->current_screen]); 711 deprintf(1, "[PS3] Page flip to buffer #%u 0x%x\n", data->current_screen, data->center[data->current_screen]);
695 ioctl(devdata->fbdev, PS3FB_IOCTL_FSEL, (unsigned long)&data->current_screen); 712 ioctl(devdata->fbdev, PS3FB_IOCTL_FSEL, (unsigned long)&data->current_screen);
696 713
697 /* Update the flipping chain, if any */ 714 /* Update the flipping chain, if any */
698 if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2 && data->double_buffering) { 715 if (data->double_buffering) {
699 data->current_screen = (data->current_screen + 1) % 2; 716 data->current_screen = (data->current_screen + 1) % 2;
700 } 717 }
701 deprintf(1, "-SDL_PS3_RenderPresent()\n"); 718 deprintf(1, "-SDL_PS3_RenderPresent()\n");
702 } 719 }
703 720