Mercurial > sdl-ios-xcode
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) { |