Mercurial > sdl-ios-xcode
comparison src/video/ps3/SDL_ps3render.c @ 3148:104786a909a2 gsoc2009_ps3
Scaling (bilinear) of YUV-Textures working.
author | Martin Lowinski <martin@goldtopf.org> |
---|---|
date | Fri, 19 Jun 2009 05:22:00 +0000 |
parents | a80760096937 |
children | 0cf7bff804ad |
comparison
equal
deleted
inserted
replaced
3147:a80760096937 | 3148:104786a909a2 |
---|---|
38 #include <asm/ps3fb.h> | 38 #include <asm/ps3fb.h> |
39 | 39 |
40 | 40 |
41 /* Stores the executable name */ | 41 /* Stores the executable name */ |
42 extern spe_program_handle_t yuv2rgb_spu; | 42 extern spe_program_handle_t yuv2rgb_spu; |
43 extern spe_program_handle_t bilin_scaler_spu; | |
43 | 44 |
44 /* SDL surface based renderer implementation */ | 45 /* SDL surface based renderer implementation */ |
45 | 46 |
46 static SDL_Renderer *SDL_PS3_CreateRenderer(SDL_Window * window, | 47 static SDL_Renderer *SDL_PS3_CreateRenderer(SDL_Window * window, |
47 Uint32 flags); | 48 Uint32 flags); |
101 | 102 |
102 /* Use two buffers in fb? res < 720p */ | 103 /* Use two buffers in fb? res < 720p */ |
103 unsigned int double_buffering; | 104 unsigned int double_buffering; |
104 | 105 |
105 /* SPE threading stuff */ | 106 /* SPE threading stuff */ |
106 spu_data_t * converter_thread_data; | 107 spu_data_t *converter_thread_data; |
108 spu_data_t *scaler_thread_data; | |
109 | |
107 /* YUV converting transfer data */ | 110 /* YUV converting transfer data */ |
108 volatile struct yuv2rgb_parms_t * converter_parms __attribute__((aligned(128))); | 111 volatile struct yuv2rgb_parms_t * converter_parms __attribute__((aligned(128))); |
112 /* Scaler transfer data */ | |
113 volatile struct scale_parms_t * scaler_parms __attribute__((aligned(128))); | |
109 } SDL_PS3_RenderData; | 114 } SDL_PS3_RenderData; |
110 | 115 |
111 typedef struct | 116 typedef struct |
112 { | 117 { |
113 //SDL_PixelFormat * format; | 118 //SDL_PixelFormat * format; |
205 | 210 |
206 data->current_screen = 0; | 211 data->current_screen = 0; |
207 | 212 |
208 /* Create SPU parms structure */ | 213 /* Create SPU parms structure */ |
209 data->converter_parms = (struct yuv2rgb_parms_t *) memalign(16, sizeof(struct yuv2rgb_parms_t)); | 214 data->converter_parms = (struct yuv2rgb_parms_t *) memalign(16, sizeof(struct yuv2rgb_parms_t)); |
210 if (data->converter_parms == NULL) { | 215 data->scaler_parms = (struct scale_parms_t *) memalign(16, sizeof(struct scale_parms_t)); |
216 if (data->converter_parms == NULL || data->scaler_parms == NULL) { | |
211 SDL_PS3_DestroyRenderer(renderer); | 217 SDL_PS3_DestroyRenderer(renderer); |
212 SDL_OutOfMemory(); | 218 SDL_OutOfMemory(); |
213 return NULL; | 219 return NULL; |
214 } | 220 } |
215 | 221 |
216 /* Set up the SPEs */ | 222 /* Set up the SPEs */ |
217 data->converter_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t)); | 223 data->converter_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t)); |
218 if (data->converter_thread_data == NULL) { | 224 data->scaler_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t)); |
225 if (data->converter_thread_data == NULL || data->scaler_thread_data == NULL) { | |
219 SDL_PS3_DestroyRenderer(renderer); | 226 SDL_PS3_DestroyRenderer(renderer); |
220 SDL_OutOfMemory(); | 227 SDL_OutOfMemory(); |
221 return NULL; | 228 return NULL; |
222 } | 229 } |
230 | |
231 data->scaler_thread_data->program = bilin_scaler_spu; | |
232 data->scaler_thread_data->program_name = "bilin_scaler_spu"; | |
233 data->scaler_thread_data->keepalive = 0; | |
234 data->scaler_thread_data->booted = 0; | |
223 | 235 |
224 data->converter_thread_data->program = yuv2rgb_spu; | 236 data->converter_thread_data->program = yuv2rgb_spu; |
225 data->converter_thread_data->program_name = "yuv2rgb_spu"; | 237 data->converter_thread_data->program_name = "yuv2rgb_spu"; |
226 data->converter_thread_data->keepalive = 1; | 238 data->converter_thread_data->keepalive = 1; |
227 data->converter_thread_data->booted = 0; | 239 data->converter_thread_data->booted = 0; |
287 default: | 299 default: |
288 /* We should never get here (caught above) */ | 300 /* We should never get here (caught above) */ |
289 break; | 301 break; |
290 } | 302 } |
291 if ((texture->format & SDL_PIXELFORMAT_YV12 || texture->format & SDL_PIXELFORMAT_IYUV) | 303 if ((texture->format & SDL_PIXELFORMAT_YV12 || texture->format & SDL_PIXELFORMAT_IYUV) |
292 && texture->w % 8 == 0 && texture->h % 8 == 0) { | 304 && texture->w % 16 == 0 && texture->h % 16 == 0) { |
293 data->accelerated = 1; | 305 data->accelerated = 1; |
294 } | 306 } |
295 } else { | 307 } else { |
296 data->pixels = NULL; | 308 data->pixels = NULL; |
297 data->pixels = SDL_malloc(texture->h * data->pitch); | 309 data->pixels = SDL_malloc(texture->h * data->pitch); |
335 return SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch); | 347 return SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch); |
336 } else { | 348 } else { |
337 Uint8 *src, *dst; | 349 Uint8 *src, *dst; |
338 int row; | 350 int row; |
339 size_t length; | 351 size_t length; |
340 int dstpitch; | |
341 Uint8 *dstpixels; | 352 Uint8 *dstpixels; |
342 | 353 |
343 src = (Uint8 *) pixels; | 354 src = (Uint8 *) pixels; |
344 dst = (Uint8 *) dstpixels + rect->y * dstpitch + rect->x | 355 dst = (Uint8 *) dstpixels + rect->y * data->pitch + rect->x |
345 * SDL_BYTESPERPIXEL(texture->format); | 356 * SDL_BYTESPERPIXEL(texture->format); |
346 length = rect->w * SDL_BYTESPERPIXEL(texture->format); | 357 length = rect->w * SDL_BYTESPERPIXEL(texture->format); |
347 for (row = 0; row < rect->h; ++row) { | 358 for (row = 0; row < rect->h; ++row) { |
348 SDL_memcpy(dst, src, length); | 359 SDL_memcpy(dst, src, length); |
349 src += pitch; | 360 src += pitch; |
350 dst += dstpitch; | 361 dst += data->pitch; |
351 } | 362 } |
352 } | 363 } |
353 deprintf(1, "-PS3_UpdateTexture()\n"); | 364 deprintf(1, "-PS3_UpdateTexture()\n"); |
354 return 0; | 365 return 0; |
355 } | 366 } |
493 deprintf(1, "dstrect->w = %u\n", dstrect->w); | 504 deprintf(1, "dstrect->w = %u\n", dstrect->w); |
494 deprintf(1, "dstrect->h = %u\n", dstrect->h); | 505 deprintf(1, "dstrect->h = %u\n", dstrect->h); |
495 deprintf(1, "dstrect->x = %u\n", dstrect->x); | 506 deprintf(1, "dstrect->x = %u\n", dstrect->x); |
496 deprintf(1, "dstrect->y = %u\n", dstrect->y); | 507 deprintf(1, "dstrect->y = %u\n", dstrect->y); |
497 | 508 |
509 deprintf(1, "texture->w = %u\n", texture->w); | |
510 deprintf(1, "texture->h = %u\n", texture->h); | |
511 | |
498 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | 512 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { |
499 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = true\n"); | 513 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = true\n"); |
500 if (txdata->accelerated) { | 514 if (txdata->accelerated) { |
501 deprintf(1, "Use SPE for scaling/converting\n"); | 515 deprintf(1, "Use SPE for scaling/converting\n"); |
502 if (srcrect-> != dstrect->w || srcrect->h != dstrect->h) { | 516 |
503 // do scaling | 517 SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) txdata->yuv; |
504 } | |
505 | |
506 Uint8 *lum, *Cr, *Cb; | 518 Uint8 *lum, *Cr, *Cb; |
507 SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) txdata->yuv; | 519 Uint8 *scaler_out = NULL; |
520 Uint8 *dstpixels; | |
508 switch (swdata->format) { | 521 switch (swdata->format) { |
509 case SDL_PIXELFORMAT_YV12: | 522 case SDL_PIXELFORMAT_YV12: |
510 lum = swdata->planes[0]; | 523 lum = swdata->planes[0]; |
511 Cr = swdata->planes[1]; | 524 Cr = swdata->planes[1]; |
512 Cb = swdata->planes[2]; | 525 Cb = swdata->planes[2]; |
518 break; | 531 break; |
519 default: | 532 default: |
520 return -1; | 533 return -1; |
521 } | 534 } |
522 | 535 |
523 data->converter_parms->y_plane = lum; | 536 if (srcrect->w != dstrect->w || srcrect->h != dstrect->h) { |
524 data->converter_parms->v_plane = Cr; | 537 /* Alloc mem for scaled YUV picture */ |
525 data->converter_parms->u_plane = Cb; | 538 scaler_out = (Uint8 *) memalign(16, dstrect->w * dstrect->h + ((dstrect->w * dstrect->h) >> 1)); |
526 data->converter_parms->src_pixel_width = swdata->w; | 539 if (scaler_out == NULL) { |
527 data->converter_parms->src_pixel_height = swdata->h; | 540 SDL_OutOfMemory(); |
528 data->converter_parms->dstBuffer = (Uint8 *)data->screen->pixels; | 541 return -1; |
542 } | |
543 | |
544 /* Set parms for scaling */ | |
545 data->scaler_parms->src_pixel_width = srcrect->w; | |
546 data->scaler_parms->src_pixel_height = srcrect->h; | |
547 data->scaler_parms->dst_pixel_width = dstrect->w; | |
548 data->scaler_parms->dst_pixel_height = dstrect->h; | |
549 data->scaler_parms->y_plane = lum; | |
550 data->scaler_parms->v_plane = Cr; | |
551 data->scaler_parms->u_plane = Cb; | |
552 data->scaler_parms->dstBuffer = scaler_out; | |
553 data->scaler_thread_data->argp = (void *)data->scaler_parms; | |
554 | |
555 /* Scale the YUV overlay to given size */ | |
556 SPE_Start(data->scaler_thread_data); | |
557 SPE_Stop(data->scaler_thread_data); | |
558 | |
559 /* Set parms for converting after scaling */ | |
560 data->converter_parms->y_plane = scaler_out; | |
561 data->converter_parms->v_plane = scaler_out + dstrect->w * dstrect->h; | |
562 data->converter_parms->u_plane = scaler_out + dstrect->w * dstrect->h + ((dstrect->w * dstrect->h) >> 2); | |
563 } else { | |
564 data->converter_parms->y_plane = lum; | |
565 data->converter_parms->v_plane = Cr; | |
566 data->converter_parms->u_plane = Cb; | |
567 } | |
568 | |
569 dstpixels = (Uint8 *) data->screen->pixels + dstrect->y * data->screen->pitch + dstrect->x | |
570 * SDL_BYTESPERPIXEL(texture->format); | |
571 data->converter_parms->src_pixel_width = dstrect->w; | |
572 data->converter_parms->src_pixel_height = dstrect->h; | |
573 data->converter_parms->dstBuffer = dstpixels/*(Uint8 *)data->screen->pixels*/; | |
529 data->converter_thread_data->argp = (void *)data->converter_parms; | 574 data->converter_thread_data->argp = (void *)data->converter_parms; |
530 | 575 |
531 /* Convert YUV overlay to RGB */ | 576 /* Convert YUV texture to RGB */ |
532 SPE_SendMsg(data->converter_thread_data, SPU_START); | 577 SPE_SendMsg(data->converter_thread_data, SPU_START); |
533 SPE_SendMsg(data->converter_thread_data, (unsigned int)data->converter_thread_data->argp); | 578 SPE_SendMsg(data->converter_thread_data, (unsigned int)data->converter_thread_data->argp); |
534 | 579 |
535 SPE_WaitForMsg(data->converter_thread_data, SPU_FIN); | 580 SPE_WaitForMsg(data->converter_thread_data, SPU_FIN); |
581 if (scaler_out) { | |
582 free(scaler_out); | |
583 } | |
536 } else { | 584 } else { |
537 deprintf(1, "Use software for scaling/converting\n"); | 585 deprintf(1, "Use software for scaling/converting\n"); |
586 Uint8 *dst; | |
587 /* FIXME: Not good */ | |
588 dst = (Uint8 *) data->screen->pixels + dstrect->y * data->screen->pitch + dstrect->x | |
589 * SDL_BYTESPERPIXEL(texture->format); | |
538 return SDL_SW_CopyYUVToRGB(txdata->yuv, srcrect, display->current_mode.format, | 590 return SDL_SW_CopyYUVToRGB(txdata->yuv, srcrect, display->current_mode.format, |
539 dstrect->w, dstrect->h, data->screen->pixels, | 591 dstrect->w, dstrect->h, dst/*data->screen->pixels*/, |
540 data->screen->pitch); | 592 data->screen->pitch); |
541 } | 593 } |
542 } else { | 594 } else { |
543 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = false\n"); | 595 deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = false\n"); |
544 | 596 |
545 Uint8 *src, *dst; | 597 Uint8 *src, *dst; |
546 int row; | 598 int row; |
547 size_t length; | 599 size_t length; |
548 int dstpitch; | |
549 Uint8 *dstpixels; | 600 Uint8 *dstpixels; |
550 | 601 |
551 src = (Uint8 *) txdata->pixels; | 602 src = (Uint8 *) txdata->pixels; |
552 dst = (Uint8 *) data->screen->pixels + dstrect->y * dstpitch + dstrect->x | 603 dst = (Uint8 *) data->screen->pixels + dstrect->y * data->screen->pitch + dstrect->x |
553 * SDL_BYTESPERPIXEL(texture->format); | 604 * SDL_BYTESPERPIXEL(texture->format); |
554 length = dstrect->w * SDL_BYTESPERPIXEL(texture->format); | 605 length = dstrect->w * SDL_BYTESPERPIXEL(texture->format); |
555 for (row = 0; row < dstrect->h; ++row) { | 606 for (row = 0; row < dstrect->h; ++row) { |
556 //deprintf(1, "Copying texture to screen...\n"); | |
557 SDL_memcpy(dst, src, length); | 607 SDL_memcpy(dst, src, length); |
558 src += dstpitch; | 608 src += txdata->pitch; |
559 dst += dstpitch; | 609 dst += data->screen->pitch; |
560 } | 610 } |
561 } | 611 } |
562 | 612 |
563 deprintf(1, "-SDL_PS3_RenderCopy()\n"); | 613 deprintf(1, "-SDL_PS3_RenderCopy()\n"); |
564 return 0; | 614 return 0; |
662 SDL_FreeSurface(data->screen); | 712 SDL_FreeSurface(data->screen); |
663 } | 713 } |
664 } | 714 } |
665 | 715 |
666 /* Shutdown SPE and related resources */ | 716 /* Shutdown SPE and related resources */ |
717 if (data->scaler_thread_data) { | |
718 free((void *)data->scaler_thread_data); | |
719 } | |
720 if (data->scaler_parms) { | |
721 free((void *)data->scaler_parms); | |
722 } | |
667 if (data->converter_thread_data) { | 723 if (data->converter_thread_data) { |
668 SPE_Shutdown(data->converter_thread_data); | 724 SPE_Shutdown(data->converter_thread_data); |
669 free((void *)data->converter_thread_data); | 725 free((void *)data->converter_thread_data); |
670 } | 726 } |
671 if (data->converter_parms) { | 727 if (data->converter_parms) { |