Mercurial > sdl-ios-xcode
comparison src/render/opengles/SDL_render_gles.c @ 5232:9c0c4d767ef6
Reduce duplicated code in the texture update code paths
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 08 Feb 2011 10:38:12 -0800 |
parents | 710d00cb3a6a |
children | 7a963be087ef |
comparison
equal
deleted
inserted
replaced
5231:710d00cb3a6a | 5232:9c0c4d767ef6 |
---|---|
291 } | 291 } |
292 | 292 |
293 static int | 293 static int |
294 GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) | 294 GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) |
295 { | 295 { |
296 GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; | |
297 GLES_TextureData *data; | 296 GLES_TextureData *data; |
298 GLint internalFormat; | 297 GLint internalFormat; |
299 GLenum format, type; | 298 GLenum format, type; |
300 int texture_w, texture_h; | 299 int texture_w, texture_h; |
301 GLenum result; | 300 GLenum result; |
368 | 367 |
369 static int | 368 static int |
370 GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, | 369 GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, |
371 const SDL_Rect * rect, const void *pixels, int pitch) | 370 const SDL_Rect * rect, const void *pixels, int pitch) |
372 { | 371 { |
373 GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; | |
374 GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; | 372 GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; |
375 GLenum result; | 373 Uint8 *blob = NULL; |
376 int bpp = SDL_BYTESPERPIXEL(texture->format); | 374 Uint8 *src; |
377 void * temp_buffer; | 375 int srcPitch; |
378 void * temp_ptr; | 376 int y; |
379 int i; | 377 |
380 | 378 GLES_ActivateRenderer(renderer); |
381 GLES_ActivateRenderer(renderer); | 379 |
382 | 380 /* Bail out if we're supposed to update an empty rectangle */ |
381 if (rect->w <= 0 || rect->h <= 0) | |
382 return 0; | |
383 | |
384 /* Reformat the texture data into a tightly packed array */ | |
385 srcPitch = rect->w * SDL_BYTESPERPIXEL(texture->format); | |
386 src = (Uint8 *)pixels; | |
387 if (pitch != srcPitch) | |
388 { | |
389 blob = (Uint8 *)SDL_malloc(srcPitch * rect->h); | |
390 if (!blob) | |
391 { | |
392 SDL_OutOfMemory(); | |
393 return -1; | |
394 } | |
395 src = blob; | |
396 for (y = 0; y < rect->h; ++y) | |
397 { | |
398 SDL_memcpy(src, pixels, srcPitch); | |
399 src += srcPitch; | |
400 pixels = (Uint8 *)pixels + pitch; | |
401 } | |
402 src = blob; | |
403 } | |
404 | |
405 /* Create a texture subimage with the supplied data */ | |
383 glGetError(); | 406 glGetError(); |
384 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | |
385 glEnable(data->type); | 407 glEnable(data->type); |
386 glBindTexture(data->type, data->texture); | 408 glBindTexture(data->type, data->texture); |
387 | 409 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
388 if( rect->w * bpp == pitch ) { | 410 glTexSubImage2D(data->type, |
389 temp_buffer = (void *)pixels; /* No need to reformat */ | 411 0, |
390 } else { | 412 rect->x, |
391 /* Reformatting of mem area required */ | 413 rect->y, |
392 temp_buffer = SDL_malloc(rect->w * rect->h * bpp); | 414 rect->w, |
393 temp_ptr = temp_buffer; | 415 rect->h, |
394 for (i = 0; i < rect->h; i++) { | 416 data->format, |
395 SDL_memcpy(temp_ptr, pixels, rect->w * bpp); | 417 data->formattype, |
396 temp_ptr += rect->w * bpp; | 418 src); |
397 pixels += pitch; | 419 if (blob) { |
398 } | 420 SDL_free(blob); |
399 } | 421 } |
400 | 422 |
401 glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, | 423 if (glGetError() != GL_NO_ERROR) |
402 rect->h, data->format, data->formattype, | 424 { |
403 temp_buffer); | 425 SDL_SetError("Failed to update texture"); |
404 | |
405 if( temp_buffer != pixels ) { | |
406 SDL_free(temp_buffer); | |
407 } | |
408 | |
409 glDisable(data->type); | |
410 result = glGetError(); | |
411 if (result != GL_NO_ERROR) { | |
412 GLES_SetError("glTexSubImage2D()", result); | |
413 return -1; | 426 return -1; |
414 } | 427 } |
415 return 0; | 428 return 0; |
416 } | 429 } |
417 | 430 |
429 } | 442 } |
430 | 443 |
431 static void | 444 static void |
432 GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) | 445 GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) |
433 { | 446 { |
434 GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; | |
435 GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; | 447 GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; |
436 | 448 SDL_Rect rect; |
437 GLES_ActivateRenderer(renderer); | 449 |
438 | 450 /* We do whole texture updates, at least for now */ |
439 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | 451 rect.x = 0; |
440 glEnable(data->type); | 452 rect.y = 0; |
441 glBindTexture(data->type, data->texture); | 453 rect.w = texture->w; |
442 glTexSubImage2D(data->type, 0, 0, 0, texture->w, | 454 rect.h = texture->h; |
443 texture->h, data->format, data->formattype, | 455 GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch); |
444 data->pixels); | |
445 glDisable(data->type); | |
446 } | 456 } |
447 | 457 |
448 static void | 458 static void |
449 GLES_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect) | 459 GLES_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect) |
450 { | 460 { |
451 GL_ActivateRenderer(renderer); | 461 GLES_ActivateRenderer(renderer); |
452 | 462 |
453 if (rect) { | 463 if (rect) { |
454 int w, h; | 464 int w, h; |
455 | 465 |
456 SDL_GetWindowSize(renderer->window, &w, &h); | 466 SDL_GetWindowSize(renderer->window, &w, &h); |