Mercurial > sdl-ios-xcode
comparison src/video/SDL_renderer_sw.c @ 1684:c4aa1a2f48f1 SDL-1.3
Software YUV texture support in progress...
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 18 Jun 2006 06:35:41 +0000 |
parents | 396a35389351 |
children | 1577404809f0 |
comparison
equal
deleted
inserted
replaced
1683:396a35389351 | 1684:c4aa1a2f48f1 |
---|---|
21 */ | 21 */ |
22 #include "SDL_config.h" | 22 #include "SDL_config.h" |
23 | 23 |
24 #include "SDL_video.h" | 24 #include "SDL_video.h" |
25 #include "SDL_sysvideo.h" | 25 #include "SDL_sysvideo.h" |
26 #include "SDL_yuv_sw_c.h" | |
26 | 27 |
27 | 28 |
28 /* SDL surface based renderer implementation */ | 29 /* SDL surface based renderer implementation */ |
29 | 30 |
30 static SDL_Renderer *SDL_SW_CreateRenderer(SDL_Window * window, Uint32 flags); | 31 static SDL_Renderer *SDL_SW_CreateRenderer(SDL_Window * window, Uint32 flags); |
203 } | 204 } |
204 | 205 |
205 static int | 206 static int |
206 SDL_SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) | 207 SDL_SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) |
207 { | 208 { |
208 SDL_Surface *surface; | 209 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { |
209 int bpp; | 210 if (texture->access == SDL_TextureAccess_Render) { |
210 Uint32 Rmask, Gmask, Bmask, Amask; | 211 SDL_SetError("Rendering to YUV format textures is not supported"); |
211 | 212 return -1; |
212 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | 213 } |
213 /* FIXME: implement this */ | 214 texture->driverdata = SDL_SW_CreateYUVTexture(texture); |
215 } else { | |
216 int bpp; | |
217 Uint32 Rmask, Gmask, Bmask, Amask; | |
218 | |
219 if (!SDL_PixelFormatEnumToMasks | |
220 (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { | |
221 SDL_SetError("Unknown texture format"); | |
222 return -1; | |
223 } | |
224 | |
225 texture->driverdata = | |
226 SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask, | |
227 Bmask, Amask); | |
228 } | |
229 | |
230 if (!texture->driverdata) { | |
214 return -1; | 231 return -1; |
215 } | 232 } |
216 | |
217 if (!SDL_PixelFormatEnumToMasks | |
218 (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { | |
219 SDL_SetError("Unknown texture format"); | |
220 return -1; | |
221 } | |
222 | |
223 surface = | |
224 SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask, | |
225 Bmask, Amask); | |
226 if (!surface) { | |
227 return -1; | |
228 } | |
229 | |
230 texture->driverdata = surface; | |
231 return 0; | 233 return 0; |
232 } | 234 } |
233 | 235 |
234 static int | 236 static int |
235 SDL_SW_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, | 237 SDL_SW_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, |
236 void **pixels, int *pitch) | 238 void **pixels, int *pitch) |
237 { | 239 { |
238 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | 240 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { |
239 | 241 return SDL_SW_QueryYUVTexturePixels((SDL_SW_YUVTexture *) texture-> |
240 *pixels = surface->pixels; | 242 driverdata, pixels, pitch); |
241 *pitch = surface->pitch; | 243 } else { |
242 return 0; | 244 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; |
245 | |
246 *pixels = surface->pixels; | |
247 *pitch = surface->pitch; | |
248 return 0; | |
249 } | |
243 } | 250 } |
244 | 251 |
245 static int | 252 static int |
246 SDL_SW_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, | 253 SDL_SW_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, |
247 const SDL_Color * colors, int firstcolor, | 254 const SDL_Color * colors, int firstcolor, |
248 int ncolors) | 255 int ncolors) |
249 { | 256 { |
250 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | 257 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { |
251 | 258 SDL_SetError("YUV textures don't have a palette"); |
252 return SDL_SetPaletteColors(surface->format->palette, colors, firstcolor, | 259 return -1; |
253 ncolors); | 260 } else { |
261 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
262 | |
263 return SDL_SetPaletteColors(surface->format->palette, colors, | |
264 firstcolor, ncolors); | |
265 } | |
254 } | 266 } |
255 | 267 |
256 static int | 268 static int |
257 SDL_SW_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, | 269 SDL_SW_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, |
258 SDL_Color * colors, int firstcolor, int ncolors) | 270 SDL_Color * colors, int firstcolor, int ncolors) |
259 { | 271 { |
260 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | 272 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { |
261 | 273 SDL_SetError("YUV textures don't have a palette"); |
262 SDL_memcpy(colors, &surface->format->palette->colors[firstcolor], | 274 return -1; |
263 ncolors * sizeof(*colors)); | 275 } else { |
264 return 0; | 276 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; |
277 | |
278 SDL_memcpy(colors, &surface->format->palette->colors[firstcolor], | |
279 ncolors * sizeof(*colors)); | |
280 return 0; | |
281 } | |
265 } | 282 } |
266 | 283 |
267 static int | 284 static int |
268 SDL_SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, | 285 SDL_SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, |
269 const SDL_Rect * rect, const void *pixels, int pitch) | 286 const SDL_Rect * rect, const void *pixels, int pitch) |
270 { | 287 { |
271 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | 288 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { |
289 return SDL_SW_UpdateYUVTexture((SDL_SW_YUVTexture *) texture-> | |
290 driverdata, rect, pixels, pitch); | |
291 } else { | |
292 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
293 Uint8 *src, *dst; | |
294 int row; | |
295 size_t length; | |
296 | |
297 src = (Uint8 *) pixels; | |
298 dst = | |
299 (Uint8 *) surface->pixels + rect->y * surface->pitch + | |
300 rect->x * surface->format->BytesPerPixel; | |
301 length = rect->w * surface->format->BytesPerPixel; | |
302 for (row = 0; row < rect->h; ++row) { | |
303 SDL_memcpy(dst, src, length); | |
304 src += pitch; | |
305 dst += surface->pitch; | |
306 } | |
307 return 0; | |
308 } | |
309 } | |
310 | |
311 static int | |
312 SDL_SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, | |
313 const SDL_Rect * rect, int markDirty, void **pixels, | |
314 int *pitch) | |
315 { | |
316 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | |
317 return SDL_SW_LockYUVTexture((SDL_SW_YUVTexture *) texture-> | |
318 driverdata, rect, markDirty, pixels, | |
319 pitch); | |
320 } else { | |
321 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
322 | |
323 *pixels = | |
324 (void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch + | |
325 rect->x * surface->format->BytesPerPixel); | |
326 *pitch = surface->pitch; | |
327 return 0; | |
328 } | |
329 } | |
330 | |
331 static void | |
332 SDL_SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) | |
333 { | |
334 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | |
335 SDL_SW_UnlockYUVTexture((SDL_SW_YUVTexture *) texture->driverdata); | |
336 } | |
337 } | |
338 | |
339 static void | |
340 SDL_SW_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, | |
341 int numrects, const SDL_Rect * rects) | |
342 { | |
343 } | |
344 | |
345 static void | |
346 SDL_SW_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture) | |
347 { | |
348 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | |
349 | |
350 if (texture) { | |
351 data->target = (SDL_Surface *) texture->driverdata; | |
352 } else { | |
353 data->target = data->screens[data->current_screen]; | |
354 } | |
355 } | |
356 | |
357 static void | |
358 SDL_SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, | |
359 Uint32 color) | |
360 { | |
361 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | |
362 SDL_Rect real_rect = *rect; | |
363 Uint8 r, g, b, a; | |
364 | |
365 a = (Uint8) ((color >> 24) & 0xFF); | |
366 r = (Uint8) ((color >> 16) & 0xFF); | |
367 g = (Uint8) ((color >> 8) & 0xFF); | |
368 b = (Uint8) (color & 0xFF); | |
369 color = SDL_MapRGBA(data->target->format, r, g, b, a); | |
370 | |
371 SDL_FillRect(data->target, &real_rect, color); | |
372 } | |
373 | |
374 static int | |
375 SDL_SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, | |
376 const SDL_Rect * srcrect, const SDL_Rect * dstrect, | |
377 int blendMode, int scaleMode) | |
378 { | |
379 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | |
380 | |
381 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | |
382 SDL_Surface *target = data->target; | |
383 void *pixels = | |
384 (Uint8 *) target->pixels + dstrect->y * target->pitch + | |
385 dstrect->x * target->format->BytesPerPixel; | |
386 return SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata, | |
387 srcrect, | |
388 renderer->window->display->current_mode. | |
389 format, dstrect->w, dstrect->h, pixels, | |
390 target->pitch); | |
391 } else { | |
392 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
393 SDL_Rect real_srcrect = *srcrect; | |
394 SDL_Rect real_dstrect = *dstrect; | |
395 | |
396 if (blendMode & | |
397 (SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend)) { | |
398 SDL_SetAlpha(surface, SDL_SRCALPHA, 0); | |
399 } else { | |
400 SDL_SetAlpha(surface, 0, 0); | |
401 } | |
402 if (scaleMode != SDL_TextureScaleMode_None && | |
403 (srcrect->w != dstrect->w || srcrect->h != dstrect->h)) { | |
404 return SDL_SoftStretch(surface, &real_srcrect, data->target, | |
405 &real_dstrect); | |
406 } else { | |
407 return SDL_LowerBlit(surface, &real_srcrect, data->target, | |
408 &real_dstrect); | |
409 } | |
410 } | |
411 } | |
412 | |
413 static int | |
414 SDL_SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
415 void *pixels, int pitch) | |
416 { | |
417 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | |
418 SDL_Surface *surface = data->target; | |
419 Uint8 *src, *dst; | |
420 int row; | |
421 size_t length; | |
422 | |
423 src = | |
424 (Uint8 *) surface->pixels + rect->y * surface->pitch + | |
425 rect->x * surface->format->BytesPerPixel; | |
426 dst = (Uint8 *) pixels; | |
427 length = rect->w * surface->format->BytesPerPixel; | |
428 for (row = 0; row < rect->h; ++row) { | |
429 SDL_memcpy(dst, src, length); | |
430 src += surface->pitch; | |
431 dst += pitch; | |
432 } | |
433 return 0; | |
434 } | |
435 | |
436 static int | |
437 SDL_SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
438 const void *pixels, int pitch) | |
439 { | |
440 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | |
441 SDL_Surface *surface = data->target; | |
272 Uint8 *src, *dst; | 442 Uint8 *src, *dst; |
273 int row; | 443 int row; |
274 size_t length; | 444 size_t length; |
275 | 445 |
276 src = (Uint8 *) pixels; | 446 src = (Uint8 *) pixels; |
284 dst += surface->pitch; | 454 dst += surface->pitch; |
285 } | 455 } |
286 return 0; | 456 return 0; |
287 } | 457 } |
288 | 458 |
289 static int | |
290 SDL_SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, | |
291 const SDL_Rect * rect, int markDirty, void **pixels, | |
292 int *pitch) | |
293 { | |
294 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
295 | |
296 *pixels = | |
297 (void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch + | |
298 rect->x * surface->format->BytesPerPixel); | |
299 *pitch = surface->pitch; | |
300 return 0; | |
301 } | |
302 | |
303 static void | |
304 SDL_SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) | |
305 { | |
306 } | |
307 | |
308 static void | |
309 SDL_SW_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, | |
310 int numrects, const SDL_Rect * rects) | |
311 { | |
312 } | |
313 | |
314 static void | |
315 SDL_SW_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture) | |
316 { | |
317 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | |
318 | |
319 if (texture) { | |
320 data->target = (SDL_Surface *) texture->driverdata; | |
321 } else { | |
322 data->target = data->screens[data->current_screen]; | |
323 } | |
324 } | |
325 | |
326 static void | |
327 SDL_SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, | |
328 Uint32 color) | |
329 { | |
330 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | |
331 SDL_Rect real_rect = *rect; | |
332 Uint8 r, g, b, a; | |
333 | |
334 a = (Uint8) ((color >> 24) & 0xFF); | |
335 r = (Uint8) ((color >> 16) & 0xFF); | |
336 g = (Uint8) ((color >> 8) & 0xFF); | |
337 b = (Uint8) (color & 0xFF); | |
338 color = SDL_MapRGBA(data->target->format, r, g, b, a); | |
339 | |
340 SDL_FillRect(data->target, &real_rect, color); | |
341 } | |
342 | |
343 static int | |
344 SDL_SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, | |
345 const SDL_Rect * srcrect, const SDL_Rect * dstrect, | |
346 int blendMode, int scaleMode) | |
347 { | |
348 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | |
349 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
350 SDL_Rect real_srcrect = *srcrect; | |
351 SDL_Rect real_dstrect = *dstrect; | |
352 | |
353 if (blendMode & (SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend)) { | |
354 SDL_SetAlpha(surface, SDL_SRCALPHA, 0); | |
355 } else { | |
356 SDL_SetAlpha(surface, 0, 0); | |
357 } | |
358 if (scaleMode != SDL_TextureScaleMode_None && | |
359 (srcrect->w != dstrect->w || srcrect->h != dstrect->h)) { | |
360 return SDL_SoftStretch(surface, &real_srcrect, data->target, | |
361 &real_dstrect); | |
362 } else { | |
363 return SDL_LowerBlit(surface, &real_srcrect, data->target, | |
364 &real_dstrect); | |
365 } | |
366 } | |
367 | |
368 static int | |
369 SDL_SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
370 void *pixels, int pitch) | |
371 { | |
372 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | |
373 SDL_Surface *surface = data->target; | |
374 Uint8 *src, *dst; | |
375 int row; | |
376 size_t length; | |
377 | |
378 src = | |
379 (Uint8 *) surface->pixels + rect->y * surface->pitch + | |
380 rect->x * surface->format->BytesPerPixel; | |
381 dst = (Uint8 *) pixels; | |
382 length = rect->w * surface->format->BytesPerPixel; | |
383 for (row = 0; row < rect->h; ++row) { | |
384 SDL_memcpy(dst, src, length); | |
385 src += surface->pitch; | |
386 dst += pitch; | |
387 } | |
388 return 0; | |
389 } | |
390 | |
391 static int | |
392 SDL_SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
393 const void *pixels, int pitch) | |
394 { | |
395 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | |
396 SDL_Surface *surface = data->target; | |
397 Uint8 *src, *dst; | |
398 int row; | |
399 size_t length; | |
400 | |
401 src = (Uint8 *) pixels; | |
402 dst = | |
403 (Uint8 *) surface->pixels + rect->y * surface->pitch + | |
404 rect->x * surface->format->BytesPerPixel; | |
405 length = rect->w * surface->format->BytesPerPixel; | |
406 for (row = 0; row < rect->h; ++row) { | |
407 SDL_memcpy(dst, src, length); | |
408 src += pitch; | |
409 dst += surface->pitch; | |
410 } | |
411 return 0; | |
412 } | |
413 | |
414 static void | 459 static void |
415 SDL_SW_RenderPresent(SDL_Renderer * renderer) | 460 SDL_SW_RenderPresent(SDL_Renderer * renderer) |
416 { | 461 { |
417 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | 462 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; |
418 SDL_Surface *surface = data->screens[data->current_screen]; | 463 SDL_Surface *surface = data->screens[data->current_screen]; |
444 } | 489 } |
445 | 490 |
446 static void | 491 static void |
447 SDL_SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) | 492 SDL_SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) |
448 { | 493 { |
449 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | 494 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { |
450 | 495 SDL_SW_DestroyYUVTexture((SDL_SW_YUVTexture *) texture->driverdata); |
451 SDL_FreeSurface(surface); | 496 } else { |
497 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
498 | |
499 SDL_FreeSurface(surface); | |
500 } | |
452 } | 501 } |
453 | 502 |
454 static void | 503 static void |
455 SDL_SW_DestroyRenderer(SDL_Renderer * renderer) | 504 SDL_SW_DestroyRenderer(SDL_Renderer * renderer) |
456 { | 505 { |