Reduce duplicated code in the texture update code paths
authorSam Lantinga <slouken@libsdl.org>
Tue, 08 Feb 2011 10:38:12 -0800
changeset 52279c0c4d767ef6
parent 5226 710d00cb3a6a
child 5228 811beeb698f9
Reduce duplicated code in the texture update code paths
src/render/opengl/SDL_render_gl.c
src/render/opengles/SDL_render_gles.c
src/render/opengles2/SDL_render_gles2.c
     1.1 --- a/src/render/opengl/SDL_render_gl.c	Tue Feb 08 10:04:09 2011 -0800
     1.2 +++ b/src/render/opengl/SDL_render_gl.c	Tue Feb 08 10:38:12 2011 -0800
     1.3 @@ -106,6 +106,7 @@
     1.4      GLenum formattype;
     1.5      void *pixels;
     1.6      int pitch;
     1.7 +    SDL_Rect locked_rect;
     1.8  } GL_TextureData;
     1.9  
    1.10  
    1.11 @@ -448,15 +449,6 @@
    1.12      return 0;
    1.13  }
    1.14  
    1.15 -static void
    1.16 -SetupTextureUpdate(GL_RenderData * renderdata, SDL_Texture * texture,
    1.17 -                   int pitch)
    1.18 -{
    1.19 -    renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    1.20 -    renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
    1.21 -                              (pitch / SDL_BYTESPERPIXEL(texture->format)));
    1.22 -}
    1.23 -
    1.24  static int
    1.25  GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
    1.26                   const SDL_Rect * rect, const void *pixels, int pitch)
    1.27 @@ -468,7 +460,9 @@
    1.28      GL_ActivateRenderer(renderer);
    1.29  
    1.30      renderdata->glGetError();
    1.31 -    SetupTextureUpdate(renderdata, texture, pitch);
    1.32 +    renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    1.33 +    renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
    1.34 +                              (pitch / SDL_BYTESPERPIXEL(texture->format)));
    1.35      renderdata->glEnable(data->type);
    1.36      renderdata->glBindTexture(data->type, data->texture);
    1.37      renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
    1.38 @@ -489,7 +483,8 @@
    1.39  {
    1.40      GL_TextureData *data = (GL_TextureData *) texture->driverdata;
    1.41  
    1.42 -    *pixels =
    1.43 +    data->locked_rect = *rect;
    1.44 +    *pixels = 
    1.45          (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
    1.46                    rect->x * SDL_BYTESPERPIXEL(texture->format));
    1.47      *pitch = data->pitch;
    1.48 @@ -499,17 +494,15 @@
    1.49  static void
    1.50  GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
    1.51  {
    1.52 -    GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
    1.53      GL_TextureData *data = (GL_TextureData *) texture->driverdata;
    1.54 +    const SDL_Rect *rect;
    1.55 +    void *pixels;
    1.56  
    1.57 -    GL_ActivateRenderer(renderer);
    1.58 -
    1.59 -    SetupTextureUpdate(renderdata, texture, data->pitch);
    1.60 -    renderdata->glEnable(data->type);
    1.61 -    renderdata->glBindTexture(data->type, data->texture);
    1.62 -    renderdata->glTexSubImage2D(data->type, 0, 0, 0, texture->w, texture->h,
    1.63 -                                data->format, data->formattype, data->pixels);
    1.64 -    renderdata->glDisable(data->type);
    1.65 +    rect = &data->locked_rect;
    1.66 +    pixels = 
    1.67 +        (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
    1.68 +                  rect->x * SDL_BYTESPERPIXEL(texture->format));
    1.69 +    GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch);
    1.70  }
    1.71  
    1.72  static void
     2.1 --- a/src/render/opengles/SDL_render_gles.c	Tue Feb 08 10:04:09 2011 -0800
     2.2 +++ b/src/render/opengles/SDL_render_gles.c	Tue Feb 08 10:38:12 2011 -0800
     2.3 @@ -293,7 +293,6 @@
     2.4  static int
     2.5  GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
     2.6  {
     2.7 -    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
     2.8      GLES_TextureData *data;
     2.9      GLint internalFormat;
    2.10      GLenum format, type;
    2.11 @@ -370,46 +369,60 @@
    2.12  GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
    2.13                     const SDL_Rect * rect, const void *pixels, int pitch)
    2.14  {
    2.15 -    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
    2.16      GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
    2.17 -    GLenum result;
    2.18 -    int bpp = SDL_BYTESPERPIXEL(texture->format);
    2.19 -    void * temp_buffer;
    2.20 -    void * temp_ptr;
    2.21 -    int i;
    2.22 +    Uint8 *blob = NULL;
    2.23 +    Uint8 *src;
    2.24 +    int srcPitch;
    2.25 +    int y;
    2.26  
    2.27      GLES_ActivateRenderer(renderer);
    2.28  
    2.29 +    /* Bail out if we're supposed to update an empty rectangle */
    2.30 +    if (rect->w <= 0 || rect->h <= 0)
    2.31 +        return 0;
    2.32 +
    2.33 +    /* Reformat the texture data into a tightly packed array */
    2.34 +    srcPitch = rect->w * SDL_BYTESPERPIXEL(texture->format);
    2.35 +    src = (Uint8 *)pixels;
    2.36 +    if (pitch != srcPitch)
    2.37 +    {
    2.38 +        blob = (Uint8 *)SDL_malloc(srcPitch * rect->h);
    2.39 +        if (!blob)
    2.40 +        {
    2.41 +            SDL_OutOfMemory();
    2.42 +            return -1;
    2.43 +        }
    2.44 +        src = blob;
    2.45 +        for (y = 0; y < rect->h; ++y)
    2.46 +        {
    2.47 +            SDL_memcpy(src, pixels, srcPitch);
    2.48 +            src += srcPitch;
    2.49 +            pixels = (Uint8 *)pixels + pitch;
    2.50 +        }
    2.51 +        src = blob;
    2.52 +    }
    2.53 +
    2.54 +    /* Create a texture subimage with the supplied data */
    2.55      glGetError();
    2.56 -    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    2.57      glEnable(data->type);
    2.58      glBindTexture(data->type, data->texture);
    2.59 -
    2.60 -    if( rect->w * bpp == pitch ) {
    2.61 -         temp_buffer = (void *)pixels; /* No need to reformat */
    2.62 -    } else {
    2.63 -         /* Reformatting of mem area required */
    2.64 -         temp_buffer = SDL_malloc(rect->w * rect->h * bpp);
    2.65 -         temp_ptr = temp_buffer;
    2.66 -         for (i = 0; i < rect->h; i++) {
    2.67 -             SDL_memcpy(temp_ptr, pixels, rect->w * bpp);
    2.68 -             temp_ptr += rect->w * bpp;
    2.69 -             pixels += pitch;
    2.70 -         }
    2.71 +    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    2.72 +    glTexSubImage2D(data->type,
    2.73 +                    0,
    2.74 +                    rect->x,
    2.75 +                    rect->y,
    2.76 +                    rect->w,
    2.77 +                    rect->h,
    2.78 +                    data->format,
    2.79 +                    data->formattype,
    2.80 +                    src);
    2.81 +    if (blob) {
    2.82 +        SDL_free(blob);
    2.83      }
    2.84  
    2.85 -    glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
    2.86 -                                rect->h, data->format, data->formattype,
    2.87 -                                temp_buffer);
    2.88 -
    2.89 -    if( temp_buffer != pixels ) {
    2.90 -        SDL_free(temp_buffer);
    2.91 -    }
    2.92 -
    2.93 -    glDisable(data->type);
    2.94 -    result = glGetError();
    2.95 -    if (result != GL_NO_ERROR) {
    2.96 -        GLES_SetError("glTexSubImage2D()", result);
    2.97 +    if (glGetError() != GL_NO_ERROR)
    2.98 +    {
    2.99 +        SDL_SetError("Failed to update texture");
   2.100          return -1;
   2.101      }
   2.102      return 0;
   2.103 @@ -431,24 +444,21 @@
   2.104  static void
   2.105  GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   2.106  {
   2.107 -    GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
   2.108      GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
   2.109 +    SDL_Rect rect;
   2.110  
   2.111 -    GLES_ActivateRenderer(renderer);
   2.112 -
   2.113 -    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2.114 -    glEnable(data->type);
   2.115 -    glBindTexture(data->type, data->texture);
   2.116 -    glTexSubImage2D(data->type, 0, 0, 0, texture->w,
   2.117 -                                texture->h, data->format, data->formattype,
   2.118 -                                data->pixels);
   2.119 -    glDisable(data->type);
   2.120 +    /* We do whole texture updates, at least for now */
   2.121 +    rect.x = 0;
   2.122 +    rect.y = 0;
   2.123 +    rect.w = texture->w;
   2.124 +    rect.h = texture->h;
   2.125 +    GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch);
   2.126  }
   2.127  
   2.128  static void
   2.129  GLES_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
   2.130  {
   2.131 -    GL_ActivateRenderer(renderer);
   2.132 +    GLES_ActivateRenderer(renderer);
   2.133  
   2.134      if (rect) {
   2.135          int w, h;
     3.1 --- a/src/render/opengles2/SDL_render_gles2.c	Tue Feb 08 10:04:09 2011 -0800
     3.2 +++ b/src/render/opengles2/SDL_render_gles2.c	Tue Feb 08 10:38:12 2011 -0800
     3.3 @@ -343,14 +343,14 @@
     3.4  GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
     3.5  {
     3.6      GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
     3.7 +    SDL_Rect rect;
     3.8  
     3.9 -    GLES2_ActivateRenderer(renderer);
    3.10 -
    3.11 -    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    3.12 -    glActiveTexture(GL_TEXTURE0);
    3.13 -    glBindTexture(tdata->texture_type, tdata->texture);
    3.14 -    glTexSubImage2D(tdata->texture_type, 0, 0, 0, texture->w, texture->h,
    3.15 -                    tdata->pixel_format, tdata->pixel_type, tdata->pixel_data);
    3.16 +    /* We do whole texture updates, at least for now */
    3.17 +    rect.x = 0;
    3.18 +    rect.y = 0;
    3.19 +    rect.w = texture->w;
    3.20 +    rect.h = texture->h;
    3.21 +    GLES2_UpdateTexture(renderer, texture, &rect, tdata->pixel_data, tdata->pitch);
    3.22  }
    3.23  
    3.24  static int
    3.25 @@ -361,7 +361,6 @@
    3.26      Uint8 *blob = NULL;
    3.27      Uint8 *src;
    3.28      int srcPitch;
    3.29 -    Uint8 *dest;
    3.30      int y;
    3.31  
    3.32      GLES2_ActivateRenderer(renderer);
    3.33 @@ -405,7 +404,9 @@
    3.34                      tdata->pixel_format,
    3.35                      tdata->pixel_type,
    3.36                      src);
    3.37 -    SDL_free(blob);
    3.38 +    if (blob) {
    3.39 +        SDL_free(blob);
    3.40 +    }
    3.41  
    3.42      if (glGetError() != GL_NO_ERROR)
    3.43      {