annotate src/video/ps3/SDL_ps3yuv.c @ 4355:9b464226e541 SDL-1.2

Fixed bug #855 Ludwig Nussel 2009-10-18 06:31:52 PDT an mprotect call was added to fix bug 528. However that results in a buffer that allows writing and code execution. Ie the no-execute security features of modern operating systems are defeated this way. Two mprotect calls are needed. One to make the buffer executable but not writeable when done and another one to make the buffer writeable again if the content needs to be changed.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 18 Oct 2009 17:31:37 +0000
parents 3b8ac3d311a2
children
rev   line source
4165
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
1 /*
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
2 * SDL - Simple DirectMedia Layer
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
3 * CELL BE Support for PS3 Framebuffer
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
4 * Copyright (C) 2008, 2009 International Business Machines Corporation
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
5 *
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
6 * This library is free software; you can redistribute it and/or modify it
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
7 * under the terms of the GNU Lesser General Public License as published
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
8 * by the Free Software Foundation; either version 2.1 of the License, or
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
9 * (at your option) any later version.
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
10 *
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
11 * This library is distributed in the hope that it will be useful, but
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
14 * Lesser General Public License for more details.
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
15 *
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
16 * You should have received a copy of the GNU Lesser General Public
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
17 * License along with this library; if not, write to the Free Software
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
19 * USA
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
20 *
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
21 * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com>
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
22 * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com>
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
23 * SPE code based on research by:
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
24 * Rene Becker
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
25 * Thimo Emmerich
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
26 */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
27
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
28 #include "SDL_config.h"
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
29
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
30 #include "SDL_video.h"
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
31 #include "SDL_ps3video.h"
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
32 #include "SDL_ps3yuv_c.h"
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
33 #include "../SDL_yuvfuncs.h"
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
34 #include "spulibs/spu_common.h"
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
35
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
36 /* Stores the executable name */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
37 extern spe_program_handle_t yuv2rgb_spu;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
38 extern spe_program_handle_t bilin_scaler_spu;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
39
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
40 int SPE_Start(_THIS, spu_data_t * spe_data);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
41 int SPE_Stop(_THIS, spu_data_t * spe_data);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
42 int SPE_Boot(_THIS, spu_data_t * spe_data);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
43 int SPE_Shutdown(_THIS, spu_data_t * spe_data);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
44 int SPE_SendMsg(_THIS, spu_data_t * spe_data, unsigned int msg);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
45 int SPE_WaitForMsg(_THIS, spu_data_t * spe_data, unsigned int msg);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
46 void SPE_RunContext(void *thread_argp);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
47
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
48
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
49 /* The functions used to manipulate software video overlays */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
50 static struct private_yuvhwfuncs ps3_yuvfuncs = {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
51 PS3_LockYUVOverlay,
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
52 PS3_UnlockYUVOverlay,
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
53 PS3_DisplayYUVOverlay,
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
54 PS3_FreeYUVOverlay
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
55 };
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
56
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
57
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
58 struct private_yuvhwdata {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
59 SDL_Surface *display;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
60 SDL_Surface *stretch;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
61 volatile void * pixels __attribute__((aligned(128)));
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
62
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
63 /* These are just so we don't have to allocate them separately */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
64 Uint16 pitches[3];
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
65 Uint8 * planes[3];
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
66
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
67 unsigned int scale;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
68
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
69 /* Scaled YUV picture */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
70 Uint8 * scaler_out __attribute__((aligned(128)));
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
71
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
72 /* YUV2RGB converter data */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
73 volatile struct yuv2rgb_parms_t * converter_parms __attribute__((aligned(128)));
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
74
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
75 /* Scaler data */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
76 volatile struct scale_parms_t * scaler_parms __attribute__((aligned(128)));
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
77
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
78 Uint8 locked;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
79 };
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
80
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
81
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
82 SDL_Overlay *PS3_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
83 /* Only RGB packed pixel conversion supported */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
84 if ((display->format->BytesPerPixel != 2) &&
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
85 (display->format->BytesPerPixel != 3) &&
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
86 (display->format->BytesPerPixel != 4))
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
87 {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
88 SDL_SetError ("Can't use YUV data on non 16/24/32 bit surfaces");
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
89 return NULL;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
90 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
91
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
92 /* Double-check the requested format. We'll only support YV12 */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
93 switch (format) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
94 case SDL_IYUV_OVERLAY:
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
95 case SDL_YV12_OVERLAY:
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
96 /* Supported YUV format */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
97 break;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
98 default:
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
99 SDL_SetError("Unsupported YUV format");
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
100 return NULL;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
101 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
102
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
103 SDL_Overlay* overlay;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
104 struct private_yuvhwdata* hwdata;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
105
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
106 /* Create the overlay structure */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
107 overlay = (SDL_Overlay *) SDL_calloc(1, sizeof(SDL_Overlay));
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
108 if (overlay == NULL) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
109 SDL_OutOfMemory();
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
110 return NULL;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
111 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
112 SDL_memset(overlay, 0, (sizeof *overlay));
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
113
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
114 /* Set the basic attributes */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
115 overlay->format = format;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
116 overlay->w = width;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
117 overlay->h = height;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
118 overlay->hwdata = NULL;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
119
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
120 /* Set up the PS3 YUV surface function structure */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
121 overlay->hwfuncs = &ps3_yuvfuncs;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
122
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
123 /* Create the pixel data and lookup tables */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
124 hwdata = (struct private_yuvhwdata *) SDL_calloc(1, sizeof(struct private_yuvhwdata));
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
125 if (hwdata == NULL) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
126 SDL_OutOfMemory();
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
127 SDL_FreeYUVOverlay(overlay);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
128 return NULL;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
129 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
130 overlay->hwdata = hwdata;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
131
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
132 hwdata->stretch = NULL;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
133 hwdata->display = display;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
134
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
135 /* Create SPU parms structure */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
136 hwdata->converter_parms = (struct yuv2rgb_parms_t *) memalign(16, sizeof(struct yuv2rgb_parms_t));
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
137 hwdata->scaler_parms = (struct scale_parms_t *) memalign(16, sizeof(struct scale_parms_t));
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
138 if (hwdata->converter_parms == NULL || hwdata->scaler_parms == NULL) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
139 SDL_FreeYUVOverlay(overlay);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
140 SDL_OutOfMemory();
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
141 return(NULL);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
142 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
143
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
144 /* Set up the SPEs */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
145 scaler_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t));
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
146 converter_thread_data = (spu_data_t *) malloc(sizeof(spu_data_t));
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
147 if (converter_thread_data == NULL || scaler_thread_data == NULL) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
148 SDL_FreeYUVOverlay(overlay);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
149 SDL_OutOfMemory();
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
150 return(NULL);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
151 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
152
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
153 scaler_thread_data->program = bilin_scaler_spu;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
154 scaler_thread_data->program_name = "bilin_scaler_spu";
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
155 scaler_thread_data->keepalive = 0;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
156 scaler_thread_data->booted = 0;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
157
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
158 converter_thread_data->program = yuv2rgb_spu;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
159 converter_thread_data->program_name = "yuv2rgb_spu";
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
160 converter_thread_data->keepalive = 1;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
161 converter_thread_data->booted = 0;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
162
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
163 SPE_Start(this, converter_thread_data);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
164
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
165 hwdata->pixels = (Uint8 *) memalign(16, width * height + ((width * height) >> 1));
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
166 if (hwdata->pixels == NULL) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
167 SDL_FreeYUVOverlay(overlay);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
168 SDL_OutOfMemory();
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
169 return(NULL);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
170 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
171
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
172 /* Find the pitch and offset values for the overlay */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
173 overlay->pitches = hwdata->pitches;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
174 overlay->pixels = hwdata->planes;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
175 switch (format) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
176 case SDL_YV12_OVERLAY:
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
177 case SDL_IYUV_OVERLAY:
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
178 overlay->pitches[0] = overlay->w;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
179 overlay->pitches[1] = overlay->pitches[0] / 2;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
180 overlay->pitches[2] = overlay->pitches[0] / 2;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
181 overlay->pixels[0] = (Uint8 *)hwdata->pixels;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
182 overlay->pixels[1] = overlay->pixels[0] +
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
183 overlay->pitches[0] * overlay->h;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
184 overlay->pixels[2] = overlay->pixels[1] +
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
185 overlay->pitches[1] * overlay->h / 2;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
186 overlay->planes = 3;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
187 break;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
188 default:
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
189 /* We should never get here (caught above) */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
190 break;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
191 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
192
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
193 /* We're all done.. */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
194 return overlay;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
195 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
196
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
197
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
198 int PS3_LockYUVOverlay(_THIS, SDL_Overlay *overlay) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
199 if (overlay == NULL) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
200 return -1;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
201 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
202 overlay->hwdata->locked = 1;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
203
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
204 return 0;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
205 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
206
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
207
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
208 void PS3_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
209 if (overlay == NULL) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
210 return;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
211 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
212 overlay->hwdata->locked = 0;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
213
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
214 return;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
215 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
216
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
217
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
218 int PS3_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
219 if ((overlay == NULL) || (overlay->hwdata == NULL)) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
220 return -1;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
221 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
222
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
223 Uint8 *lum, *Cr, *Cb;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
224 struct private_yuvhwdata *hwdata;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
225 SDL_Surface *display;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
226
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
227 hwdata = overlay->hwdata;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
228 display = hwdata->display;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
229
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
230 /* Do we have to scale? */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
231 if ((src->w != dst->w) || (src->h != dst->h) ) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
232 hwdata->scale = 1;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
233 deprintf(1, "[PS3] We need to scale\n");
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
234 } else {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
235 hwdata->scale = 0;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
236 deprintf(1, "[PS3] No scaling\n");
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
237 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
238
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
239 /* Find out where the various portions of the image are */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
240 switch (overlay->format) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
241 case SDL_YV12_OVERLAY:
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
242 lum = (Uint8 *)overlay->pixels[0];
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
243 Cr = (Uint8 *)overlay->pixels[1];
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
244 Cb = (Uint8 *)overlay->pixels[2];
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
245 break;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
246 case SDL_IYUV_OVERLAY:
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
247 lum = (Uint8 *)overlay->pixels[0];
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
248 Cr = (Uint8 *)overlay->pixels[2];
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
249 Cb = (Uint8 *)overlay->pixels[1];
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
250 break;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
251 default:
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
252 SDL_SetError("Unsupported YUV format in blit");
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
253 return -1;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
254 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
255
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
256 if (hwdata->scale) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
257 /* Alloc mem for scaled YUV picture */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
258 hwdata->scaler_out = (Uint8 *) memalign(16, dst->w * dst->h + ((dst->w * dst->h) >> 1));
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
259 if (hwdata->scaler_out == NULL) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
260 SDL_FreeYUVOverlay(overlay);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
261 SDL_OutOfMemory();
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
262 return -1;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
263 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
264
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
265 /* Set parms for scaling */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
266 hwdata->scaler_parms->src_pixel_width = src->w;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
267 hwdata->scaler_parms->src_pixel_height = src->h;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
268 hwdata->scaler_parms->dst_pixel_width = dst->w;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
269 hwdata->scaler_parms->dst_pixel_height = dst->h;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
270 hwdata->scaler_parms->y_plane = lum;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
271 hwdata->scaler_parms->v_plane = Cr;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
272 hwdata->scaler_parms->u_plane = Cb;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
273 hwdata->scaler_parms->dstBuffer = hwdata->scaler_out;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
274 scaler_thread_data->argp = (void *)hwdata->scaler_parms;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
275
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
276 /* Scale the YUV overlay to given size */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
277 SPE_Start(this, scaler_thread_data);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
278 SPE_Stop(this, scaler_thread_data);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
279
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
280 /* Set parms for converting after scaling */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
281 hwdata->converter_parms->y_plane = hwdata->scaler_out;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
282 hwdata->converter_parms->v_plane = hwdata->scaler_out + dst->w * dst->h;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
283 hwdata->converter_parms->u_plane = hwdata->scaler_out + dst->w * dst->h + ((dst->w * dst->h) >> 2);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
284 } else {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
285 /* Set parms for converting */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
286 hwdata->converter_parms->y_plane = lum;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
287 hwdata->converter_parms->v_plane = Cr;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
288 hwdata->converter_parms->u_plane = Cb;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
289 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
290
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
291 hwdata->converter_parms->src_pixel_width = dst->w;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
292 hwdata->converter_parms->src_pixel_height = dst->h;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
293 hwdata->converter_parms->dstBuffer = (Uint8 *) s_pixels;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
294 converter_thread_data->argp = (void *)hwdata->converter_parms;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
295
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
296 /* Convert YUV overlay to RGB */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
297 SPE_SendMsg(this, converter_thread_data, SPU_START);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
298 SPE_SendMsg(this, converter_thread_data, (unsigned int)converter_thread_data->argp);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
299
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
300 /* Centering */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
301 s_bounded_input_width = dst->w;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
302 s_bounded_input_height = dst->h;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
303
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
304 /* UpdateRects() will do the rest.. */
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
305 SDL_UpdateRects(display, 1, dst);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
306
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
307 if (hwdata->scale)
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
308 SDL_free((void *)hwdata->scaler_out);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
309
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
310 return 0;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
311 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
312
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
313
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
314 void PS3_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
315 if (overlay == NULL) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
316 return;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
317 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
318
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
319 if (overlay->hwdata == NULL) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
320 return;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
321 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
322
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
323 struct private_yuvhwdata * hwdata;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
324 hwdata = overlay->hwdata;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
325
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
326 if (scaler_thread_data)
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
327 SDL_free(scaler_thread_data);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
328 if (converter_thread_data) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
329 SPE_Shutdown(this, converter_thread_data);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
330 SDL_free(converter_thread_data);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
331 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
332
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
333 if (hwdata) {
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
334 if (hwdata->pixels)
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
335 SDL_free((void *)hwdata->pixels);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
336 SDL_free(hwdata);
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
337 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
338 return;
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
339 }
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
340