19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * SDL - Simple DirectMedia Layer 39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * CELL BE Support for PS3 Framebuffer 49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Copyright (C) 2008, 2009 International Business Machines Corporation 59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * 69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * This library is free software; you can redistribute it and/or modify it 79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * under the terms of the GNU Lesser General Public License as published 89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * by the Free Software Foundation; either version 2.1 of the License, or 99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * (at your option) any later version. 109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * 119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * This library is distributed in the hope that it will be useful, but 129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * WITHOUT ANY WARRANTY; without even the implied warranty of 139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Lesser General Public License for more details. 159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * 169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * You should have received a copy of the GNU Lesser General Public 179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * License along with this library; if not, write to the Free Software 189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * USA 209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * 219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com> 229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com> 239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * SPE code based on research by: 249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Rene Becker 259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Thimo Emmerich 269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_config.h" 299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_video.h" 319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_ps3video.h" 329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_ps3yuv_c.h" 339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "../SDL_yuvfuncs.h" 349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "spulibs/spu_common.h" 359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Stores the executable name */ 379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallextern spe_program_handle_t yuv2rgb_spu; 389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallextern spe_program_handle_t bilin_scaler_spu; 399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint SPE_Start(_THIS, spu_data_t * spe_data); 419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint SPE_Stop(_THIS, spu_data_t * spe_data); 429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint SPE_Boot(_THIS, spu_data_t * spe_data); 439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint SPE_Shutdown(_THIS, spu_data_t * spe_data); 449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint SPE_SendMsg(_THIS, spu_data_t * spe_data, unsigned int msg); 459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint SPE_WaitForMsg(_THIS, spu_data_t * spe_data, unsigned int msg); 469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid SPE_RunContext(void *thread_argp); 479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* The functions used to manipulate software video overlays */ 509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic struct private_yuvhwfuncs ps3_yuvfuncs = { 519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall PS3_LockYUVOverlay, 529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall PS3_UnlockYUVOverlay, 539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall PS3_DisplayYUVOverlay, 549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall PS3_FreeYUVOverlay 559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstruct private_yuvhwdata { 599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface *display; 609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface *stretch; 619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall volatile void * pixels __attribute__((aligned(128))); 629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* These are just so we don't have to allocate them separately */ 649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint16 pitches[3]; 659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 * planes[3]; 669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int scale; 689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Scaled YUV picture */ 709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 * scaler_out __attribute__((aligned(128))); 719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* YUV2RGB converter data */ 739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall volatile struct yuv2rgb_parms_t * converter_parms __attribute__((aligned(128))); 749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Scaler data */ 769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall volatile struct scale_parms_t * scaler_parms __attribute__((aligned(128))); 779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 locked; 799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; 809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallSDL_Overlay *PS3_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) { 839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Only RGB packed pixel conversion supported */ 849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((display->format->BytesPerPixel != 2) && 859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (display->format->BytesPerPixel != 3) && 869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (display->format->BytesPerPixel != 4)) 879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall { 889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError ("Can't use YUV data on non 16/24/32 bit surfaces"); 899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Double-check the requested format. We'll only support YV12 */ 939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall switch (format) { 949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SDL_IYUV_OVERLAY: 959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SDL_YV12_OVERLAY: 969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Supported YUV format */ 979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall default: 999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Unsupported YUV format"); 1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Overlay* overlay; 1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct private_yuvhwdata* hwdata; 1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Create the overlay structure */ 1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay = (SDL_Overlay *) SDL_calloc(1, sizeof(SDL_Overlay)); 1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (overlay == NULL) { 1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory(); 1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_memset(overlay, 0, (sizeof *overlay)); 1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set the basic attributes */ 1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->format = format; 1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->w = width; 1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->h = height; 1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->hwdata = NULL; 1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set up the PS3 YUV surface function structure */ 1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->hwfuncs = &ps3_yuvfuncs; 1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Create the pixel data and lookup tables */ 1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata = (struct private_yuvhwdata *) SDL_calloc(1, sizeof(struct private_yuvhwdata)); 1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (hwdata == NULL) { 1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory(); 1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_FreeYUVOverlay(overlay); 1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return NULL; 1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->hwdata = hwdata; 1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->stretch = NULL; 1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->display = display; 1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Create SPU parms structure */ 1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->converter_parms = (struct yuv2rgb_parms_t *) memalign(16, sizeof(struct yuv2rgb_parms_t)); 1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->scaler_parms = (struct scale_parms_t *) memalign(16, sizeof(struct scale_parms_t)); 1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (hwdata->converter_parms == NULL || hwdata->scaler_parms == NULL) { 1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_FreeYUVOverlay(overlay); 1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory(); 1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set up the SPEs */ 1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scaler_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t)); 1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall converter_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t)); 1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (converter_thread_data == NULL || scaler_thread_data == NULL) { 1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_FreeYUVOverlay(overlay); 1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory(); 1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scaler_thread_data->program = bilin_scaler_spu; 1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scaler_thread_data->program_name = "bilin_scaler_spu"; 1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scaler_thread_data->keepalive = 0; 1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scaler_thread_data->booted = 0; 1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall converter_thread_data->program = yuv2rgb_spu; 1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall converter_thread_data->program_name = "yuv2rgb_spu"; 1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall converter_thread_data->keepalive = 1; 1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall converter_thread_data->booted = 0; 1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SPE_Start(this, converter_thread_data); 1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->pixels = (Uint8 *) memalign(16, width * height + ((width * height) >> 1)); 1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (hwdata->pixels == NULL) { 1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_FreeYUVOverlay(overlay); 1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory(); 1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return(NULL); 1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Find the pitch and offset values for the overlay */ 1739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->pitches = hwdata->pitches; 1749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->pixels = hwdata->planes; 1759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall switch (format) { 1769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SDL_YV12_OVERLAY: 1779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SDL_IYUV_OVERLAY: 1789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->pitches[0] = overlay->w; 1799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->pitches[1] = overlay->pitches[0] / 2; 1809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->pitches[2] = overlay->pitches[0] / 2; 1819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->pixels[0] = (Uint8 *)hwdata->pixels; 1829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->pixels[1] = overlay->pixels[0] + 1839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->pitches[0] * overlay->h; 1849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->pixels[2] = overlay->pixels[1] + 1859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->pitches[1] * overlay->h / 2; 1869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->planes = 3; 1879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 1889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall default: 1899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* We should never get here (caught above) */ 1909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 1919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* We're all done.. */ 1949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return overlay; 1959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 1969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint PS3_LockYUVOverlay(_THIS, SDL_Overlay *overlay) { 1999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (overlay == NULL) { 2009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -1; 2019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->hwdata->locked = 1; 2039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 2059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 2069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid PS3_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) { 2099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (overlay == NULL) { 2109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; 2119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall overlay->hwdata->locked = 0; 2139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; 2159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 2169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint PS3_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst) { 2199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((overlay == NULL) || (overlay->hwdata == NULL)) { 2209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -1; 2219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Uint8 *lum, *Cr, *Cb; 2249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct private_yuvhwdata *hwdata; 2259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_Surface *display; 2269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata = overlay->hwdata; 2289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall display = hwdata->display; 2299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Do we have to scale? */ 2319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if ((src->w != dst->w) || (src->h != dst->h) ) { 2329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->scale = 1; 2339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf(1, "[PS3] We need to scale\n"); 2349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 2359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->scale = 0; 2369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf(1, "[PS3] No scaling\n"); 2379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Find out where the various portions of the image are */ 2409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall switch (overlay->format) { 2419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SDL_YV12_OVERLAY: 2429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall lum = (Uint8 *)overlay->pixels[0]; 2439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Cr = (Uint8 *)overlay->pixels[1]; 2449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Cb = (Uint8 *)overlay->pixels[2]; 2459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 2469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SDL_IYUV_OVERLAY: 2479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall lum = (Uint8 *)overlay->pixels[0]; 2489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Cr = (Uint8 *)overlay->pixels[2]; 2499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall Cb = (Uint8 *)overlay->pixels[1]; 2509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 2519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall default: 2529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_SetError("Unsupported YUV format in blit"); 2539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -1; 2549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (hwdata->scale) { 2579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Alloc mem for scaled YUV picture */ 2589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->scaler_out = (Uint8 *) memalign(16, dst->w * dst->h + ((dst->w * dst->h) >> 1)); 2599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (hwdata->scaler_out == NULL) { 2609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_FreeYUVOverlay(overlay); 2619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_OutOfMemory(); 2629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return -1; 2639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set parms for scaling */ 2669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->scaler_parms->src_pixel_width = src->w; 2679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->scaler_parms->src_pixel_height = src->h; 2689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->scaler_parms->dst_pixel_width = dst->w; 2699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->scaler_parms->dst_pixel_height = dst->h; 2709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->scaler_parms->y_plane = lum; 2719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->scaler_parms->v_plane = Cr; 2729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->scaler_parms->u_plane = Cb; 2739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->scaler_parms->dstBuffer = hwdata->scaler_out; 2749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall scaler_thread_data->argp = (void *)hwdata->scaler_parms; 2759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Scale the YUV overlay to given size */ 2779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SPE_Start(this, scaler_thread_data); 2789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SPE_Stop(this, scaler_thread_data); 2799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set parms for converting after scaling */ 2819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->converter_parms->y_plane = hwdata->scaler_out; 2829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->converter_parms->v_plane = hwdata->scaler_out + dst->w * dst->h; 2839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->converter_parms->u_plane = hwdata->scaler_out + dst->w * dst->h + ((dst->w * dst->h) >> 2); 2849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } else { 2859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Set parms for converting */ 2869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->converter_parms->y_plane = lum; 2879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->converter_parms->v_plane = Cr; 2889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->converter_parms->u_plane = Cb; 2899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 2909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->converter_parms->src_pixel_width = dst->w; 2929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->converter_parms->src_pixel_height = dst->h; 2939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata->converter_parms->dstBuffer = (Uint8 *) s_pixels; 2949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall converter_thread_data->argp = (void *)hwdata->converter_parms; 2959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 2969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Convert YUV overlay to RGB */ 2979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SPE_SendMsg(this, converter_thread_data, SPU_START); 2989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SPE_SendMsg(this, converter_thread_data, (unsigned int)converter_thread_data->argp); 2999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Centering */ 3019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s_bounded_input_width = dst->w; 3029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall s_bounded_input_height = dst->h; 3039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* UpdateRects() will do the rest.. */ 3059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_UpdateRects(display, 1, dst); 3069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (hwdata->scale) 3089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free((void *)hwdata->scaler_out); 3099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 3119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 3129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid PS3_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) { 3159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (overlay == NULL) { 3169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; 3179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (overlay->hwdata == NULL) { 3209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; 3219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall struct private_yuvhwdata * hwdata; 3249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall hwdata = overlay->hwdata; 3259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (scaler_thread_data) 3279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free(scaler_thread_data); 3289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (converter_thread_data) { 3299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SPE_Shutdown(this, converter_thread_data); 3309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free(converter_thread_data); 3319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 3339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (hwdata) { 3349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (hwdata->pixels) 3359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free((void *)hwdata->pixels); 3369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall SDL_free(hwdata); 3379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 3389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return; 3399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 3409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 341