Fixed bug 3350 - GL renderers don't need to flip rows after reading back 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c
index d8aa66b..971b317 100644
--- a/src/render/opengl/SDL_render_gl.c
+++ b/src/render/opengl/SDL_render_gl.c
@@ -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,
diff --git a/src/render/opengles/SDL_render_gles.c b/src/render/opengles/SDL_render_gles.c
index 1d82e59..9d13bfe 100644
--- a/src/render/opengles/SDL_render_gles.c
+++ b/src/render/opengles/SDL_render_gles.c
@@ -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,
diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c
index e41ab62..7ff22b4 100644
--- a/src/render/opengles2/SDL_render_gles2.c
+++ b/src/render/opengles2/SDL_render_gles2.c
@@ -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,