Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Reduce duplicated code in the texture update code paths
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Feb 8, 2011
1 parent b0d2e83 commit 503a6e3
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 76 deletions.
33 changes: 13 additions & 20 deletions src/render/opengl/SDL_render_gl.c
Expand Up @@ -106,6 +106,7 @@ typedef struct
GLenum formattype;
void *pixels;
int pitch;
SDL_Rect locked_rect;
} GL_TextureData;


Expand Down Expand Up @@ -448,15 +449,6 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
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)
Expand All @@ -468,7 +460,9 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
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,
Expand All @@ -489,7 +483,8 @@ GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
{
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;
Expand All @@ -499,17 +494,15 @@ GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
static void
GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
GL_TextureData *data = (GL_TextureData *) texture->driverdata;
const SDL_Rect *rect;
void *pixels;

GL_ActivateRenderer(renderer);

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
Expand Down
102 changes: 56 additions & 46 deletions src/render/opengles/SDL_render_gles.c
Expand Up @@ -293,7 +293,6 @@ power_of_2(int input)
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;
Expand Down Expand Up @@ -370,46 +369,60 @@ static int
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);

glGetError();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glEnable(data->type);
glBindTexture(data->type, data->texture);
/* Bail out if we're supposed to update an empty rectangle */
if (rect->w <= 0 || rect->h <= 0)
return 0;

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;
}
}

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);
/* 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;
}

glDisable(data->type);
result = glGetError();
if (result != GL_NO_ERROR) {
GLES_SetError("glTexSubImage2D()", result);
/* Create a texture subimage with the supplied data */
glGetError();
glEnable(data->type);
glBindTexture(data->type, data->texture);
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);
}

if (glGetError() != GL_NO_ERROR)
{
SDL_SetError("Failed to update texture");
return -1;
}
return 0;
Expand All @@ -431,24 +444,21 @@ GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
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);

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);
SDL_Rect rect;

/* 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;
Expand Down
21 changes: 11 additions & 10 deletions src/render/opengles2/SDL_render_gles2.c
Expand Up @@ -343,14 +343,14 @@ static void
GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{
GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;

GLES2_ActivateRenderer(renderer);

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);
SDL_Rect rect;

/* 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
Expand All @@ -361,7 +361,6 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect
Uint8 *blob = NULL;
Uint8 *src;
int srcPitch;
Uint8 *dest;
int y;

GLES2_ActivateRenderer(renderer);
Expand Down Expand Up @@ -405,7 +404,9 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect
tdata->pixel_format,
tdata->pixel_type,
src);
SDL_free(blob);
if (blob) {
SDL_free(blob);
}

if (glGetError() != GL_NO_ERROR)
{
Expand Down

0 comments on commit 503a6e3

Please sign in to comment.