Mercurial > sdl-ios-xcode
diff 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 |
line wrap: on
line diff
--- a/src/video/ps3/SDL_ps3render.c Thu Jun 18 03:27:12 2009 +0000 +++ b/src/video/ps3/SDL_ps3render.c Fri Jun 19 05:22:00 2009 +0000 @@ -40,6 +40,7 @@ /* Stores the executable name */ extern spe_program_handle_t yuv2rgb_spu; +extern spe_program_handle_t bilin_scaler_spu; /* SDL surface based renderer implementation */ @@ -103,9 +104,13 @@ unsigned int double_buffering; /* SPE threading stuff */ - spu_data_t * converter_thread_data; + spu_data_t *converter_thread_data; + spu_data_t *scaler_thread_data; + /* YUV converting transfer data */ volatile struct yuv2rgb_parms_t * converter_parms __attribute__((aligned(128))); + /* Scaler transfer data */ + volatile struct scale_parms_t * scaler_parms __attribute__((aligned(128))); } SDL_PS3_RenderData; typedef struct @@ -207,7 +212,8 @@ /* Create SPU parms structure */ data->converter_parms = (struct yuv2rgb_parms_t *) memalign(16, sizeof(struct yuv2rgb_parms_t)); - if (data->converter_parms == NULL) { + data->scaler_parms = (struct scale_parms_t *) memalign(16, sizeof(struct scale_parms_t)); + if (data->converter_parms == NULL || data->scaler_parms == NULL) { SDL_PS3_DestroyRenderer(renderer); SDL_OutOfMemory(); return NULL; @@ -215,12 +221,18 @@ /* Set up the SPEs */ data->converter_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t)); - if (data->converter_thread_data == NULL) { + data->scaler_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t)); + if (data->converter_thread_data == NULL || data->scaler_thread_data == NULL) { SDL_PS3_DestroyRenderer(renderer); SDL_OutOfMemory(); return NULL; } + data->scaler_thread_data->program = bilin_scaler_spu; + data->scaler_thread_data->program_name = "bilin_scaler_spu"; + data->scaler_thread_data->keepalive = 0; + data->scaler_thread_data->booted = 0; + data->converter_thread_data->program = yuv2rgb_spu; data->converter_thread_data->program_name = "yuv2rgb_spu"; data->converter_thread_data->keepalive = 1; @@ -289,7 +301,7 @@ break; } if ((texture->format & SDL_PIXELFORMAT_YV12 || texture->format & SDL_PIXELFORMAT_IYUV) - && texture->w % 8 == 0 && texture->h % 8 == 0) { + && texture->w % 16 == 0 && texture->h % 16 == 0) { data->accelerated = 1; } } else { @@ -337,17 +349,16 @@ Uint8 *src, *dst; int row; size_t length; - int dstpitch; Uint8 *dstpixels; src = (Uint8 *) pixels; - dst = (Uint8 *) dstpixels + rect->y * dstpitch + rect->x + dst = (Uint8 *) dstpixels + rect->y * data->pitch + rect->x * SDL_BYTESPERPIXEL(texture->format); length = rect->w * SDL_BYTESPERPIXEL(texture->format); for (row = 0; row < rect->h; ++row) { SDL_memcpy(dst, src, length); src += pitch; - dst += dstpitch; + dst += data->pitch; } } deprintf(1, "-PS3_UpdateTexture()\n"); @@ -495,16 +506,18 @@ deprintf(1, "dstrect->x = %u\n", dstrect->x); deprintf(1, "dstrect->y = %u\n", dstrect->y); + deprintf(1, "texture->w = %u\n", texture->w); + deprintf(1, "texture->h = %u\n", texture->h); + if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { deprintf(1, "SDL_ISPIXELFORMAT_FOURCC = true\n"); if (txdata->accelerated) { deprintf(1, "Use SPE for scaling/converting\n"); - if (srcrect-> != dstrect->w || srcrect->h != dstrect->h) { - // do scaling - } + SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) txdata->yuv; Uint8 *lum, *Cr, *Cb; - SDL_SW_YUVTexture *swdata = (SDL_SW_YUVTexture *) txdata->yuv; + Uint8 *scaler_out = NULL; + Uint8 *dstpixels; switch (swdata->format) { case SDL_PIXELFORMAT_YV12: lum = swdata->planes[0]; @@ -520,23 +533,62 @@ return -1; } - data->converter_parms->y_plane = lum; - data->converter_parms->v_plane = Cr; - data->converter_parms->u_plane = Cb; - data->converter_parms->src_pixel_width = swdata->w; - data->converter_parms->src_pixel_height = swdata->h; - data->converter_parms->dstBuffer = (Uint8 *)data->screen->pixels; + if (srcrect->w != dstrect->w || srcrect->h != dstrect->h) { + /* Alloc mem for scaled YUV picture */ + scaler_out = (Uint8 *) memalign(16, dstrect->w * dstrect->h + ((dstrect->w * dstrect->h) >> 1)); + if (scaler_out == NULL) { + SDL_OutOfMemory(); + return -1; + } + + /* Set parms for scaling */ + data->scaler_parms->src_pixel_width = srcrect->w; + data->scaler_parms->src_pixel_height = srcrect->h; + data->scaler_parms->dst_pixel_width = dstrect->w; + data->scaler_parms->dst_pixel_height = dstrect->h; + data->scaler_parms->y_plane = lum; + data->scaler_parms->v_plane = Cr; + data->scaler_parms->u_plane = Cb; + data->scaler_parms->dstBuffer = scaler_out; + data->scaler_thread_data->argp = (void *)data->scaler_parms; + + /* Scale the YUV overlay to given size */ + SPE_Start(data->scaler_thread_data); + SPE_Stop(data->scaler_thread_data); + + /* Set parms for converting after scaling */ + data->converter_parms->y_plane = scaler_out; + data->converter_parms->v_plane = scaler_out + dstrect->w * dstrect->h; + data->converter_parms->u_plane = scaler_out + dstrect->w * dstrect->h + ((dstrect->w * dstrect->h) >> 2); + } else { + data->converter_parms->y_plane = lum; + data->converter_parms->v_plane = Cr; + data->converter_parms->u_plane = Cb; + } + + dstpixels = (Uint8 *) data->screen->pixels + dstrect->y * data->screen->pitch + dstrect->x + * SDL_BYTESPERPIXEL(texture->format); + data->converter_parms->src_pixel_width = dstrect->w; + data->converter_parms->src_pixel_height = dstrect->h; + data->converter_parms->dstBuffer = dstpixels/*(Uint8 *)data->screen->pixels*/; data->converter_thread_data->argp = (void *)data->converter_parms; - /* Convert YUV overlay to RGB */ + /* Convert YUV texture to RGB */ SPE_SendMsg(data->converter_thread_data, SPU_START); SPE_SendMsg(data->converter_thread_data, (unsigned int)data->converter_thread_data->argp); SPE_WaitForMsg(data->converter_thread_data, SPU_FIN); + if (scaler_out) { + free(scaler_out); + } } else { deprintf(1, "Use software for scaling/converting\n"); + Uint8 *dst; + /* FIXME: Not good */ + dst = (Uint8 *) data->screen->pixels + dstrect->y * data->screen->pitch + dstrect->x + * SDL_BYTESPERPIXEL(texture->format); return SDL_SW_CopyYUVToRGB(txdata->yuv, srcrect, display->current_mode.format, - dstrect->w, dstrect->h, data->screen->pixels, + dstrect->w, dstrect->h, dst/*data->screen->pixels*/, data->screen->pitch); } } else { @@ -545,18 +597,16 @@ Uint8 *src, *dst; int row; size_t length; - int dstpitch; Uint8 *dstpixels; src = (Uint8 *) txdata->pixels; - dst = (Uint8 *) data->screen->pixels + dstrect->y * dstpitch + dstrect->x + dst = (Uint8 *) data->screen->pixels + dstrect->y * data->screen->pitch + dstrect->x * SDL_BYTESPERPIXEL(texture->format); length = dstrect->w * SDL_BYTESPERPIXEL(texture->format); for (row = 0; row < dstrect->h; ++row) { - //deprintf(1, "Copying texture to screen...\n"); SDL_memcpy(dst, src, length); - src += dstpitch; - dst += dstpitch; + src += txdata->pitch; + dst += data->screen->pitch; } } @@ -664,6 +714,12 @@ } /* Shutdown SPE and related resources */ + if (data->scaler_thread_data) { + free((void *)data->scaler_thread_data); + } + if (data->scaler_parms) { + free((void *)data->scaler_parms); + } if (data->converter_thread_data) { SPE_Shutdown(data->converter_thread_data); free((void *)data->converter_thread_data);