# HG changeset patch # User Sam Lantinga # Date 1297190292 28800 # Node ID 9c0c4d767ef60baa9942c5f486585d3245bdc0a8 # Parent 710d00cb3a6ac34634d9b59401a1e52e18792f64 Reduce duplicated code in the texture update code paths diff -r 710d00cb3a6a -r 9c0c4d767ef6 src/render/opengl/SDL_render_gl.c --- a/src/render/opengl/SDL_render_gl.c Tue Feb 08 10:04:09 2011 -0800 +++ b/src/render/opengl/SDL_render_gl.c Tue Feb 08 10:38:12 2011 -0800 @@ -106,6 +106,7 @@ GLenum formattype; void *pixels; int pitch; + SDL_Rect locked_rect; } GL_TextureData; @@ -448,15 +449,6 @@ return 0; } -static void -SetupTextureUpdate(GL_RenderData * renderdata, SDL_Texture * texture, - int pitch) -{ - renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, - (pitch / SDL_BYTESPERPIXEL(texture->format))); -} - static int GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) @@ -468,7 +460,9 @@ GL_ActivateRenderer(renderer); renderdata->glGetError(); - SetupTextureUpdate(renderdata, texture, pitch); + renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, + (pitch / SDL_BYTESPERPIXEL(texture->format))); renderdata->glEnable(data->type); renderdata->glBindTexture(data->type, data->texture); renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, @@ -489,7 +483,8 @@ { GL_TextureData *data = (GL_TextureData *) texture->driverdata; - *pixels = + data->locked_rect = *rect; + *pixels = (void *) ((Uint8 *) data->pixels + rect->y * data->pitch + rect->x * SDL_BYTESPERPIXEL(texture->format)); *pitch = data->pitch; @@ -499,17 +494,15 @@ static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; GL_TextureData *data = (GL_TextureData *) texture->driverdata; - - GL_ActivateRenderer(renderer); + const SDL_Rect *rect; + void *pixels; - SetupTextureUpdate(renderdata, texture, data->pitch); - renderdata->glEnable(data->type); - renderdata->glBindTexture(data->type, data->texture); - renderdata->glTexSubImage2D(data->type, 0, 0, 0, texture->w, texture->h, - data->format, data->formattype, data->pixels); - renderdata->glDisable(data->type); + rect = &data->locked_rect; + pixels = + (void *) ((Uint8 *) data->pixels + rect->y * data->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); + GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch); } static void diff -r 710d00cb3a6a -r 9c0c4d767ef6 src/render/opengles/SDL_render_gles.c --- a/src/render/opengles/SDL_render_gles.c Tue Feb 08 10:04:09 2011 -0800 +++ b/src/render/opengles/SDL_render_gles.c Tue Feb 08 10:38:12 2011 -0800 @@ -293,7 +293,6 @@ static int GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; GLES_TextureData *data; GLint internalFormat; GLenum format, type; @@ -370,46 +369,60 @@ GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { - GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; - GLenum result; - int bpp = SDL_BYTESPERPIXEL(texture->format); - void * temp_buffer; - void * temp_ptr; - int i; + Uint8 *blob = NULL; + Uint8 *src; + int srcPitch; + int y; GLES_ActivateRenderer(renderer); + /* Bail out if we're supposed to update an empty rectangle */ + if (rect->w <= 0 || rect->h <= 0) + return 0; + + /* Reformat the texture data into a tightly packed array */ + srcPitch = rect->w * SDL_BYTESPERPIXEL(texture->format); + src = (Uint8 *)pixels; + if (pitch != srcPitch) + { + blob = (Uint8 *)SDL_malloc(srcPitch * rect->h); + if (!blob) + { + SDL_OutOfMemory(); + return -1; + } + src = blob; + for (y = 0; y < rect->h; ++y) + { + SDL_memcpy(src, pixels, srcPitch); + src += srcPitch; + pixels = (Uint8 *)pixels + pitch; + } + src = blob; + } + + /* Create a texture subimage with the supplied data */ glGetError(); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glEnable(data->type); glBindTexture(data->type, data->texture); - - if( rect->w * bpp == pitch ) { - temp_buffer = (void *)pixels; /* No need to reformat */ - } else { - /* Reformatting of mem area required */ - temp_buffer = SDL_malloc(rect->w * rect->h * bpp); - temp_ptr = temp_buffer; - for (i = 0; i < rect->h; i++) { - SDL_memcpy(temp_ptr, pixels, rect->w * bpp); - temp_ptr += rect->w * bpp; - pixels += pitch; - } + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexSubImage2D(data->type, + 0, + rect->x, + rect->y, + rect->w, + rect->h, + data->format, + data->formattype, + src); + if (blob) { + SDL_free(blob); } - glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, - rect->h, data->format, data->formattype, - temp_buffer); - - if( temp_buffer != pixels ) { - SDL_free(temp_buffer); - } - - glDisable(data->type); - result = glGetError(); - if (result != GL_NO_ERROR) { - GLES_SetError("glTexSubImage2D()", result); + if (glGetError() != GL_NO_ERROR) + { + SDL_SetError("Failed to update texture"); return -1; } return 0; @@ -431,24 +444,21 @@ static void GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; - - GLES_ActivateRenderer(renderer); + SDL_Rect rect; - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glEnable(data->type); - glBindTexture(data->type, data->texture); - glTexSubImage2D(data->type, 0, 0, 0, texture->w, - texture->h, data->format, data->formattype, - data->pixels); - glDisable(data->type); + /* We do whole texture updates, at least for now */ + rect.x = 0; + rect.y = 0; + rect.w = texture->w; + rect.h = texture->h; + GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch); } static void GLES_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect) { - GL_ActivateRenderer(renderer); + GLES_ActivateRenderer(renderer); if (rect) { int w, h; diff -r 710d00cb3a6a -r 9c0c4d767ef6 src/render/opengles2/SDL_render_gles2.c --- a/src/render/opengles2/SDL_render_gles2.c Tue Feb 08 10:04:09 2011 -0800 +++ b/src/render/opengles2/SDL_render_gles2.c Tue Feb 08 10:38:12 2011 -0800 @@ -343,14 +343,14 @@ GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) { GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; - - GLES2_ActivateRenderer(renderer); + SDL_Rect rect; - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glActiveTexture(GL_TEXTURE0); - glBindTexture(tdata->texture_type, tdata->texture); - glTexSubImage2D(tdata->texture_type, 0, 0, 0, texture->w, texture->h, - tdata->pixel_format, tdata->pixel_type, tdata->pixel_data); + /* We do whole texture updates, at least for now */ + rect.x = 0; + rect.y = 0; + rect.w = texture->w; + rect.h = texture->h; + GLES2_UpdateTexture(renderer, texture, &rect, tdata->pixel_data, tdata->pitch); } static int @@ -361,7 +361,6 @@ Uint8 *blob = NULL; Uint8 *src; int srcPitch; - Uint8 *dest; int y; GLES2_ActivateRenderer(renderer); @@ -405,7 +404,9 @@ tdata->pixel_format, tdata->pixel_type, src); - SDL_free(blob); + if (blob) { + SDL_free(blob); + } if (glGetError() != GL_NO_ERROR) {