changeset 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 811beeb698f9
files src/render/opengl/SDL_render_gl.c src/render/opengles/SDL_render_gles.c src/render/opengles2/SDL_render_gles2.c
diffstat 3 files changed, 76 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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;
--- 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)
     {