Reduce duplicated code in the texture update code paths

This commit is contained in:
Sam Lantinga 2011-02-08 10:38:12 -08:00
parent 7133afac5f
commit e455951633
3 changed files with 76 additions and 72 deletions

View file

@ -106,6 +106,7 @@ typedef struct
GLenum formattype; GLenum formattype;
void *pixels; void *pixels;
int pitch; int pitch;
SDL_Rect locked_rect;
} GL_TextureData; } GL_TextureData;
@ -448,15 +449,6 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
return 0; 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 static int
GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels, int pitch) const SDL_Rect * rect, const void *pixels, int pitch)
@ -468,7 +460,9 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
GL_ActivateRenderer(renderer); GL_ActivateRenderer(renderer);
renderdata->glGetError(); 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->glEnable(data->type);
renderdata->glBindTexture(data->type, data->texture); renderdata->glBindTexture(data->type, data->texture);
renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
@ -489,7 +483,8 @@ GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
{ {
GL_TextureData *data = (GL_TextureData *) texture->driverdata; GL_TextureData *data = (GL_TextureData *) texture->driverdata;
*pixels = data->locked_rect = *rect;
*pixels =
(void *) ((Uint8 *) data->pixels + rect->y * data->pitch + (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
rect->x * SDL_BYTESPERPIXEL(texture->format)); rect->x * SDL_BYTESPERPIXEL(texture->format));
*pitch = data->pitch; *pitch = data->pitch;
@ -499,17 +494,15 @@ GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
static void static void
GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{ {
GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
GL_TextureData *data = (GL_TextureData *) texture->driverdata; GL_TextureData *data = (GL_TextureData *) texture->driverdata;
const SDL_Rect *rect;
void *pixels;
GL_ActivateRenderer(renderer); rect = &data->locked_rect;
pixels =
SetupTextureUpdate(renderdata, texture, data->pitch); (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
renderdata->glEnable(data->type); rect->x * SDL_BYTESPERPIXEL(texture->format));
renderdata->glBindTexture(data->type, data->texture); GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch);
renderdata->glTexSubImage2D(data->type, 0, 0, 0, texture->w, texture->h,
data->format, data->formattype, data->pixels);
renderdata->glDisable(data->type);
} }
static void static void

View file

@ -293,7 +293,6 @@ power_of_2(int input)
static int static int
GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{ {
GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
GLES_TextureData *data; GLES_TextureData *data;
GLint internalFormat; GLint internalFormat;
GLenum format, type; GLenum format, type;
@ -370,46 +369,60 @@ static int
GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels, int pitch) const SDL_Rect * rect, const void *pixels, int pitch)
{ {
GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
GLenum result; Uint8 *blob = NULL;
int bpp = SDL_BYTESPERPIXEL(texture->format); Uint8 *src;
void * temp_buffer; int srcPitch;
void * temp_ptr; int y;
int i;
GLES_ActivateRenderer(renderer); 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(); glGetError();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glEnable(data->type); glEnable(data->type);
glBindTexture(data->type, data->texture); glBindTexture(data->type, data->texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if( rect->w * bpp == pitch ) { glTexSubImage2D(data->type,
temp_buffer = (void *)pixels; /* No need to reformat */ 0,
} else { rect->x,
/* Reformatting of mem area required */ rect->y,
temp_buffer = SDL_malloc(rect->w * rect->h * bpp); rect->w,
temp_ptr = temp_buffer; rect->h,
for (i = 0; i < rect->h; i++) { data->format,
SDL_memcpy(temp_ptr, pixels, rect->w * bpp); data->formattype,
temp_ptr += rect->w * bpp; src);
pixels += pitch; if (blob) {
} SDL_free(blob);
} }
glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, if (glGetError() != GL_NO_ERROR)
rect->h, data->format, data->formattype, {
temp_buffer); SDL_SetError("Failed to update texture");
if( temp_buffer != pixels ) {
SDL_free(temp_buffer);
}
glDisable(data->type);
result = glGetError();
if (result != GL_NO_ERROR) {
GLES_SetError("glTexSubImage2D()", result);
return -1; return -1;
} }
return 0; return 0;
@ -431,24 +444,21 @@ GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
static void static void
GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{ {
GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
SDL_Rect rect;
GLES_ActivateRenderer(renderer); /* We do whole texture updates, at least for now */
rect.x = 0;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); rect.y = 0;
glEnable(data->type); rect.w = texture->w;
glBindTexture(data->type, data->texture); rect.h = texture->h;
glTexSubImage2D(data->type, 0, 0, 0, texture->w, GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch);
texture->h, data->format, data->formattype,
data->pixels);
glDisable(data->type);
} }
static void static void
GLES_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect) GLES_SetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
{ {
GL_ActivateRenderer(renderer); GLES_ActivateRenderer(renderer);
if (rect) { if (rect) {
int w, h; int w, h;

View file

@ -343,14 +343,14 @@ static void
GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{ {
GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
SDL_Rect rect;
GLES2_ActivateRenderer(renderer); /* We do whole texture updates, at least for now */
rect.x = 0;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); rect.y = 0;
glActiveTexture(GL_TEXTURE0); rect.w = texture->w;
glBindTexture(tdata->texture_type, tdata->texture); rect.h = texture->h;
glTexSubImage2D(tdata->texture_type, 0, 0, 0, texture->w, texture->h, GLES2_UpdateTexture(renderer, texture, &rect, tdata->pixel_data, tdata->pitch);
tdata->pixel_format, tdata->pixel_type, tdata->pixel_data);
} }
static int static int
@ -361,7 +361,6 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect
Uint8 *blob = NULL; Uint8 *blob = NULL;
Uint8 *src; Uint8 *src;
int srcPitch; int srcPitch;
Uint8 *dest;
int y; int y;
GLES2_ActivateRenderer(renderer); GLES2_ActivateRenderer(renderer);
@ -405,7 +404,9 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect
tdata->pixel_format, tdata->pixel_format,
tdata->pixel_type, tdata->pixel_type,
src); src);
SDL_free(blob); if (blob) {
SDL_free(blob);
}
if (glGetError() != GL_NO_ERROR) if (glGetError() != GL_NO_ERROR)
{ {