Skip to content

Commit

Permalink
Fixed bug 3350 - GL renderers don't need to flip rows after reading b…
Browse files Browse the repository at this point in the history
…ack pixels from the target texture

Simon Hug

All OpenGL renderers always flip the rows of the pixels that come from glReadPixels. This is unnecessary for target textures since these are already top down.

Also, the rect->y value can be used directly for target textures for the same reason. I don't see any code that would handle the logical render size for target textures. Or am I missing something?

The attached patch makes the renderers only the flip rows if the data comes from the default framebuffer.
  • Loading branch information
slouken committed Oct 1, 2016
1 parent 9fff05f commit 51d6371
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 48 deletions.
34 changes: 18 additions & 16 deletions src/render/opengl/SDL_render_gl.c
Expand Up @@ -1439,28 +1439,30 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
data->glPixelStorei(GL_PACK_ROW_LENGTH,
(temp_pitch / SDL_BYTESPERPIXEL(temp_format)));

data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
format, type, temp_pixels);
data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h,
rect->w, rect->h, format, type, temp_pixels);

if (GL_CheckError("glReadPixels()", renderer) < 0) {
SDL_free(temp_pixels);
return -1;
}

/* Flip the rows to be top-down */
length = rect->w * SDL_BYTESPERPIXEL(temp_format);
src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
dst = (Uint8*)temp_pixels;
tmp = SDL_stack_alloc(Uint8, length);
rows = rect->h / 2;
while (rows--) {
SDL_memcpy(tmp, dst, length);
SDL_memcpy(dst, src, length);
SDL_memcpy(src, tmp, length);
dst += temp_pitch;
src -= temp_pitch;
}
SDL_stack_free(tmp);
/* Flip the rows to be top-down if necessary */
if (!renderer->target) {
length = rect->w * SDL_BYTESPERPIXEL(temp_format);
src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
dst = (Uint8*)temp_pixels;
tmp = SDL_stack_alloc(Uint8, length);
rows = rect->h / 2;
while (rows--) {
SDL_memcpy(tmp, dst, length);
SDL_memcpy(dst, src, length);
SDL_memcpy(src, tmp, length);
dst += temp_pitch;
src -= temp_pitch;
}
SDL_stack_free(tmp);
}

status = SDL_ConvertPixels(rect->w, rect->h,
temp_format, temp_pixels, temp_pitch,
Expand Down
34 changes: 18 additions & 16 deletions src/render/opengles/SDL_render_gles.c
Expand Up @@ -1088,23 +1088,25 @@ GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,

data->glPixelStorei(GL_PACK_ALIGNMENT, 1);

data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);

/* Flip the rows to be top-down */
length = rect->w * SDL_BYTESPERPIXEL(temp_format);
src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
dst = (Uint8*)temp_pixels;
tmp = SDL_stack_alloc(Uint8, length);
rows = rect->h / 2;
while (rows--) {
SDL_memcpy(tmp, dst, length);
SDL_memcpy(dst, src, length);
SDL_memcpy(src, tmp, length);
dst += temp_pitch;
src -= temp_pitch;
data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h,
rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);

/* Flip the rows to be top-down if necessary */
if (!renderer->target) {
length = rect->w * SDL_BYTESPERPIXEL(temp_format);
src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
dst = (Uint8*)temp_pixels;
tmp = SDL_stack_alloc(Uint8, length);
rows = rect->h / 2;
while (rows--) {
SDL_memcpy(tmp, dst, length);
SDL_memcpy(dst, src, length);
SDL_memcpy(src, tmp, length);
dst += temp_pitch;
src -= temp_pitch;
}
SDL_stack_free(tmp);
}
SDL_stack_free(tmp);

status = SDL_ConvertPixels(rect->w, rect->h,
temp_format, temp_pixels, temp_pitch,
Expand Down
34 changes: 18 additions & 16 deletions src/render/opengles2/SDL_render_gles2.c
Expand Up @@ -1834,26 +1834,28 @@ GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,

SDL_GetRendererOutputSize(renderer, &w, &h);

data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);
data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h,
rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);
if (GL_CheckError("glReadPixels()", renderer) < 0) {
return -1;
}

/* Flip the rows to be top-down */
length = rect->w * SDL_BYTESPERPIXEL(temp_format);
src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
dst = (Uint8*)temp_pixels;
tmp = SDL_stack_alloc(Uint8, length);
rows = rect->h / 2;
while (rows--) {
SDL_memcpy(tmp, dst, length);
SDL_memcpy(dst, src, length);
SDL_memcpy(src, tmp, length);
dst += temp_pitch;
src -= temp_pitch;
}
SDL_stack_free(tmp);
/* Flip the rows to be top-down if necessary */
if (!renderer->target) {
length = rect->w * SDL_BYTESPERPIXEL(temp_format);
src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
dst = (Uint8*)temp_pixels;
tmp = SDL_stack_alloc(Uint8, length);
rows = rect->h / 2;
while (rows--) {
SDL_memcpy(tmp, dst, length);
SDL_memcpy(dst, src, length);
SDL_memcpy(src, tmp, length);
dst += temp_pitch;
src -= temp_pitch;
}
SDL_stack_free(tmp);
}

status = SDL_ConvertPixels(rect->w, rect->h,
temp_format, temp_pixels, temp_pitch,
Expand Down

0 comments on commit 51d6371

Please sign in to comment.