comparison src/video/ps3/SDL_ps3render.c @ 3147:a80760096937 gsoc2009_ps3

Support all YUV texture formats using SW_Textures.
author Martin Lowinski <martin@goldtopf.org>
date Thu, 18 Jun 2009 03:27:12 +0000
parents 9e902f423497
children 104786a909a2
comparison
equal deleted inserted replaced
3146:9e902f423497 3147:a80760096937
78 }; 78 };
79 79
80 typedef struct 80 typedef struct
81 { 81 {
82 int current_screen; 82 int current_screen;
83 //SDL_Surface *screens[2]; 83 SDL_Surface *screen;
84 SDL_Surface *screen[1];
85 SDL_VideoDisplay *display; 84 SDL_VideoDisplay *display;
86 uint8_t *center[2]; 85 uint8_t *center[2];
87 86
88 /* width of input (bounded by writeable width) */ 87 /* width of input (bounded by writeable width) */
89 unsigned int bounded_width; 88 unsigned int bounded_width;
113 { 112 {
114 //SDL_PixelFormat * format; 113 //SDL_PixelFormat * format;
115 int pitch; 114 int pitch;
116 volatile void *pixels;// __attribute__((aligned(128))); we don't need alignment here 115 volatile void *pixels;// __attribute__((aligned(128))); we don't need alignment here
117 SDL_SW_YUVTexture *yuv; 116 SDL_SW_YUVTexture *yuv;
117 /* Can we use the SPE to process this texture? */
118 unsigned int accelerated;
118 } PS3_TextureData; 119 } PS3_TextureData;
119 120
120 SDL_Renderer * 121 SDL_Renderer *
121 SDL_PS3_CreateRenderer(SDL_Window * window, Uint32 flags) 122 SDL_PS3_CreateRenderer(SDL_Window * window, Uint32 flags)
122 { 123 {
181 data->double_buffering = 1; 182 data->double_buffering = 1;
182 } else { 183 } else {
183 renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; 184 renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
184 n = 1; 185 n = 1;
185 } 186 }
186 for (i = 0; i < n; ++i) { 187
187 data->screen[i] = 188 data->screen =
188 SDL_CreateRGBSurface(0, window->w, window->h, bpp, Rmask, Gmask, 189 SDL_CreateRGBSurface(0, window->w, window->h, bpp, Rmask, Gmask,
189 Bmask, Amask); 190 Bmask, Amask);
190 if (!data->screen[i]) { 191 if (!data->screen) {
191 SDL_PS3_DestroyRenderer(renderer); 192 SDL_PS3_DestroyRenderer(renderer);
192 return NULL; 193 return NULL;
193 } 194 }
194 /* Allocate aligned memory for pixels */ 195 /* Allocate aligned memory for pixels */
195 SDL_free(data->screen[i]->pixels); 196 SDL_free(data->screen->pixels);
196 data->screen[i]->pixels = (void *)memalign(16, data->screen[i]->h * data->screen[i]->pitch); 197 data->screen->pixels = (void *)memalign(16, data->screen->h * data->screen->pitch);
197 if (!data->screen[i]->pixels) { 198 if (!data->screen->pixels) {
198 SDL_FreeSurface(data->screen[i]); 199 SDL_FreeSurface(data->screen);
199 SDL_OutOfMemory(); 200 SDL_OutOfMemory();
200 return NULL; 201 return NULL;
201 } 202 }
202 SDL_memset(data->screen[i]->pixels, 0, data->screen[i]->h * data->screen[i]->pitch); 203 SDL_memset(data->screen->pixels, 0, data->screen->h * data->screen->pitch);
203 SDL_SetSurfacePalette(data->screen[i], display->palette); 204 SDL_SetSurfacePalette(data->screen, display->palette);
204 } 205
205 data->current_screen = 0; 206 data->current_screen = 0;
206 207
207 /* Create SPU parms structure */ 208 /* Create SPU parms structure */
208 data->converter_parms = (struct yuv2rgb_parms_t *) memalign(16, sizeof(struct yuv2rgb_parms_t)); 209 data->converter_parms = (struct yuv2rgb_parms_t *) memalign(16, sizeof(struct yuv2rgb_parms_t));
209 if (data->converter_parms == NULL) { 210 if (data->converter_parms == NULL) {
249 if (!data) { 250 if (!data) {
250 SDL_OutOfMemory(); 251 SDL_OutOfMemory();
251 return -1; 252 return -1;
252 } 253 }
253 data->pitch = (texture->w * SDL_BYTESPERPIXEL(texture->format)); 254 data->pitch = (texture->w * SDL_BYTESPERPIXEL(texture->format));
255 data->accelerated = 0;
254 256
255 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 257 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
256 /* Use SDLs SW_YUVTexture */ 258 /* Use SDLs SW_YUVTexture */
257 data->yuv = 259 data->yuv =
258 SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h); 260 SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h);
265 data->yuv->pixels = (Uint8 *)memalign(16, texture->w * texture->h * 2); 267 data->yuv->pixels = (Uint8 *)memalign(16, texture->w * texture->h * 2);
266 268
267 /* Redo: Find the pitch and offset values for the overlay */ 269 /* Redo: Find the pitch and offset values for the overlay */
268 SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) data->yuv; 270 SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) data->yuv;
269 switch (texture->format) { 271 switch (texture->format) {
270 case SDL_PIXELFORMAT_YV12: 272 case SDL_PIXELFORMAT_YV12:
271 case SDL_PIXELFORMAT_IYUV: 273 case SDL_PIXELFORMAT_IYUV:
272 swdata->pitches[0] = texture->w; 274 swdata->pitches[0] = texture->w;
273 swdata->pitches[1] = swdata->pitches[0] / 2; 275 swdata->pitches[1] = swdata->pitches[0] / 2;
274 swdata->pitches[2] = swdata->pitches[0] / 2; 276 swdata->pitches[2] = swdata->pitches[0] / 2;
275 swdata->planes[0] = swdata->pixels; 277 swdata->planes[0] = swdata->pixels;
276 swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * texture->h; 278 swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * texture->h;
277 swdata->planes[2] = swdata->planes[1] + swdata->pitches[1] * texture->h / 2; 279 swdata->planes[2] = swdata->planes[1] + swdata->pitches[1] * texture->h / 2;
278 break; 280 break;
279 case SDL_PIXELFORMAT_YUY2: 281 case SDL_PIXELFORMAT_YUY2:
280 case SDL_PIXELFORMAT_UYVY: 282 case SDL_PIXELFORMAT_UYVY:
281 case SDL_PIXELFORMAT_YVYU: 283 case SDL_PIXELFORMAT_YVYU:
282 swdata->pitches[0] = texture->w * 2; 284 swdata->pitches[0] = texture->w * 2;
283 swdata->planes[0] = swdata->pixels; 285 swdata->planes[0] = swdata->pixels;
284 break; 286 break;
285 default: 287 default:
286 /* We should never get here (caught above) */ 288 /* We should never get here (caught above) */
287 break; 289 break;
290 }
291 if ((texture->format & SDL_PIXELFORMAT_YV12 || texture->format & SDL_PIXELFORMAT_IYUV)
292 && texture->w % 8 == 0 && texture->h % 8 == 0) {
293 data->accelerated = 1;
288 } 294 }
289 } else { 295 } else {
290 data->pixels = NULL; 296 data->pixels = NULL;
291 data->pixels = SDL_malloc(texture->h * data->pitch); 297 data->pixels = SDL_malloc(texture->h * data->pitch);
292 if (!data->pixels) { 298 if (!data->pixels) {
401 static int 407 static int
402 SDL_PS3_RenderPoint(SDL_Renderer * renderer, int x, int y) 408 SDL_PS3_RenderPoint(SDL_Renderer * renderer, int x, int y)
403 { 409 {
404 SDL_PS3_RenderData *data = 410 SDL_PS3_RenderData *data =
405 (SDL_PS3_RenderData *) renderer->driverdata; 411 (SDL_PS3_RenderData *) renderer->driverdata;
406 SDL_Surface *target = data->screen[data->current_screen]; 412 SDL_Surface *target = data->screen;
407 int status; 413 int status;
408 414
409 if (renderer->blendMode == SDL_BLENDMODE_NONE || 415 if (renderer->blendMode == SDL_BLENDMODE_NONE ||
410 renderer->blendMode == SDL_BLENDMODE_MASK) { 416 renderer->blendMode == SDL_BLENDMODE_MASK) {
411 Uint32 color = 417 Uint32 color =
424 static int 430 static int
425 SDL_PS3_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) 431 SDL_PS3_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
426 { 432 {
427 SDL_PS3_RenderData *data = 433 SDL_PS3_RenderData *data =
428 (SDL_PS3_RenderData *) renderer->driverdata; 434 (SDL_PS3_RenderData *) renderer->driverdata;
429 SDL_Surface *target = data->screen[data->current_screen]; 435 SDL_Surface *target = data->screen;
430 int status; 436 int status;
431 437
432 if (renderer->blendMode == SDL_BLENDMODE_NONE || 438 if (renderer->blendMode == SDL_BLENDMODE_NONE ||
433 renderer->blendMode == SDL_BLENDMODE_MASK) { 439 renderer->blendMode == SDL_BLENDMODE_MASK) {
434 Uint32 color = 440 Uint32 color =
448 SDL_PS3_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect) 454 SDL_PS3_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect)
449 { 455 {
450 deprintf(1, "SDL_PS3_RenderFill()\n"); 456 deprintf(1, "SDL_PS3_RenderFill()\n");
451 SDL_PS3_RenderData *data = 457 SDL_PS3_RenderData *data =
452 (SDL_PS3_RenderData *) renderer->driverdata; 458 (SDL_PS3_RenderData *) renderer->driverdata;
453 SDL_Surface *target = data->screen[data->current_screen]; 459 SDL_Surface *target = data->screen;
454 SDL_Rect real_rect = *rect; 460 SDL_Rect real_rect = *rect;
455 int status; 461 int status;
456 462
457 if (renderer->blendMode == SDL_BLENDMODE_NONE) { 463 if (renderer->blendMode == SDL_BLENDMODE_NONE) {
458 Uint32 color = 464 Uint32 color =
489 deprintf(1, "dstrect->x = %u\n", dstrect->x); 495 deprintf(1, "dstrect->x = %u\n", dstrect->x);
490 deprintf(1, "dstrect->y = %u\n", dstrect->y); 496 deprintf(1, "dstrect->y = %u\n", dstrect->y);
491 497
492 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 498 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
493 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = true\n"); 499 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = true\n");
494 #if 1 500 if (txdata->accelerated) {
495 /* Not yet tested */ 501 deprintf(1, "Use SPE for scaling/converting\n");
496 Uint8 *lum, *Cr, *Cb; 502 if (srcrect-> != dstrect->w || srcrect->h != dstrect->h) {
497 SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) txdata->yuv; 503 // do scaling
498 switch (swdata->format) { 504 }
499 case SDL_PIXELFORMAT_YV12: 505
500 lum = swdata->planes[0]; 506 Uint8 *lum, *Cr, *Cb;
501 Cr = swdata->planes[1]; 507 SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) txdata->yuv;
502 Cb = swdata->planes[2]; 508 switch (swdata->format) {
503 break; 509 case SDL_PIXELFORMAT_YV12:
504 case SDL_PIXELFORMAT_IYUV: 510 lum = swdata->planes[0];
505 lum = swdata->planes[0]; 511 Cr = swdata->planes[1];
506 Cr = swdata->planes[2]; 512 Cb = swdata->planes[2];
507 Cb = swdata->planes[1]; 513 break;
508 break; 514 case SDL_PIXELFORMAT_IYUV:
509 default: 515 lum = swdata->planes[0];
510 return -1; 516 Cr = swdata->planes[2];
511 } 517 Cb = swdata->planes[1];
512 518 break;
513 data->converter_parms->y_plane = lum; 519 default:
514 data->converter_parms->v_plane = Cr; 520 return -1;
515 data->converter_parms->u_plane = Cb; 521 }
516 data->converter_parms->src_pixel_width = swdata->w;//dstrect->w; 522
517 data->converter_parms->src_pixel_height = swdata->h;//dstrect->h; 523 data->converter_parms->y_plane = lum;
518 data->converter_parms->dstBuffer = (Uint8 *)data->screen[0]->pixels; 524 data->converter_parms->v_plane = Cr;
519 data->converter_thread_data->argp = (void *)data->converter_parms; 525 data->converter_parms->u_plane = Cb;
520 526 data->converter_parms->src_pixel_width = swdata->w;
521 /* Convert YUV overlay to RGB */ 527 data->converter_parms->src_pixel_height = swdata->h;
522 SPE_SendMsg(data->converter_thread_data, SPU_START); 528 data->converter_parms->dstBuffer = (Uint8 *)data->screen->pixels;
523 SPE_SendMsg(data->converter_thread_data, (unsigned int)data->converter_thread_data->argp); 529 data->converter_thread_data->argp = (void *)data->converter_parms;
524 530
525 SPE_WaitForMsg(data->converter_thread_data, SPU_FIN); 531 /* Convert YUV overlay to RGB */
526 532 SPE_SendMsg(data->converter_thread_data, SPU_START);
527 return 0; 533 SPE_SendMsg(data->converter_thread_data, (unsigned int)data->converter_thread_data->argp);
528 #else 534
529 return SDL_SW_CopyYUVToRGB(txdata->yuv, srcrect, display->current_mode.format, 535 SPE_WaitForMsg(data->converter_thread_data, SPU_FIN);
530 dstrect->w, dstrect->h, data->screen[0]->pixels, 536 } else {
531 data->screen[0]->pitch); 537 deprintf(1, "Use software for scaling/converting\n");
532 #endif 538 return SDL_SW_CopyYUVToRGB(txdata->yuv, srcrect, display->current_mode.format,
539 dstrect->w, dstrect->h, data->screen->pixels,
540 data->screen->pitch);
541 }
533 } else { 542 } else {
534 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = false\n"); 543 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = false\n");
535 544
536 Uint8 *src, *dst; 545 Uint8 *src, *dst;
537 int row; 546 int row;
538 size_t length; 547 size_t length;
539 int dstpitch; 548 int dstpitch;
540 Uint8 *dstpixels; 549 Uint8 *dstpixels;
541 550
542 src = (Uint8 *) txdata->pixels; 551 src = (Uint8 *) txdata->pixels;
543 dst = (Uint8 *) data->screen[0]->pixels + dstrect->y * dstpitch + dstrect->x 552 dst = (Uint8 *) data->screen->pixels + dstrect->y * dstpitch + dstrect->x
544 * SDL_BYTESPERPIXEL(texture->format); 553 * SDL_BYTESPERPIXEL(texture->format);
545 length = dstrect->w * SDL_BYTESPERPIXEL(texture->format); 554 length = dstrect->w * SDL_BYTESPERPIXEL(texture->format);
546 for (row = 0; row < dstrect->h; ++row) { 555 for (row = 0; row < dstrect->h; ++row) {
556 //deprintf(1, "Copying texture to screen...\n");
547 SDL_memcpy(dst, src, length); 557 SDL_memcpy(dst, src, length);
548 src += dstpitch; 558 src += dstpitch;
549 dst += dstpitch; 559 dst += dstpitch;
550 } 560 }
551 //SDL_memcpy(data->screen[0]->pixels, (void *)txdata->pixels, texture->h * texture->w * 4);
552 } 561 }
553 562
554 deprintf(1, "-SDL_PS3_RenderCopy()\n"); 563 deprintf(1, "-SDL_PS3_RenderCopy()\n");
555 return 0; 564 return 0;
556 } 565 }
602 611
603 deprintf(1, "offset_left = %u\n", data->offset_left); 612 deprintf(1, "offset_left = %u\n", data->offset_left);
604 deprintf(1, "offset_top = %u\n", data->offset_top); 613 deprintf(1, "offset_top = %u\n", data->offset_top);
605 614
606 /* Set SPU parms for copying the surface to framebuffer */ 615 /* Set SPU parms for copying the surface to framebuffer */
607 devdata->fb_parms->data = (unsigned char *)data->screen[0]->pixels; 616 devdata->fb_parms->data = (unsigned char *)data->screen->pixels;
608 devdata->fb_parms->center = data->center[data->current_screen]; 617 devdata->fb_parms->center = data->center[data->current_screen];
609 devdata->fb_parms->out_line_stride = fb_finfo.line_length; 618 devdata->fb_parms->out_line_stride = fb_finfo.line_length;
610 devdata->fb_parms->in_line_stride = window->w * /*txdata->bpp / 8*/4; 619 devdata->fb_parms->in_line_stride = window->w * /*txdata->bpp / 8*/4;
611 devdata->fb_parms->bounded_input_height = data->bounded_height; 620 devdata->fb_parms->bounded_input_height = data->bounded_height;
612 devdata->fb_parms->bounded_input_width = data->bounded_width; 621 devdata->fb_parms->bounded_input_width = data->bounded_width;
647 (SDL_PS3_RenderData *) renderer->driverdata; 656 (SDL_PS3_RenderData *) renderer->driverdata;
648 int i; 657 int i;
649 658
650 if (data) { 659 if (data) {
651 for (i = 0; i < SDL_arraysize(data->screen); ++i) { 660 for (i = 0; i < SDL_arraysize(data->screen); ++i) {
652 if (data->screen[i]) { 661 if (data->screen) {
653 SDL_FreeSurface(data->screen[i]); 662 SDL_FreeSurface(data->screen);
654 } 663 }
655 } 664 }
656 665
657 /* Shutdown SPE and related resources */ 666 /* Shutdown SPE and related resources */
658 if (data->converter_thread_data) { 667 if (data->converter_thread_data) {