Evas gl_x11: Fix usage of glReadPixels

It is not necessary to dynamically link to glReadPixels since
this is not an extension. This code wouldn't even work on some
devices.

Also, the pixels returned are not premultiplied (yeah >_<)

And some devices (EGL) don't support GL_BGRA... so glReadPixels
would just fail and not fill in the pixels. Conversion is required.
This commit is contained in:
Jean-Philippe Andre 2014-03-13 15:54:58 +09:00
parent 7e6c21c44b
commit 7ad4a269e0
3 changed files with 23 additions and 6 deletions

View File

@ -839,8 +839,6 @@ extern void (*glsym_glReleaseShaderCompiler)(void);
extern void *(*glsym_glMapBuffer) (GLenum a, GLenum b);
extern GLboolean (*glsym_glUnmapBuffer) (GLenum a);
extern void (*glsym_glReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *data);
#ifdef GL_GLES
extern void *(*secsym_eglCreateImage) (void *a, void *b, GLenum c, void *d, const int *e);
extern unsigned int (*secsym_eglDestroyImage) (void *a, void *b);

View File

@ -29,7 +29,6 @@ void *(*glsym_glMapBuffer) (GLenum a, GLenum b) = NULL;
GLboolean (*glsym_glUnmapBuffer) (GLenum a) = NULL;
void (*glsym_glStartTiling) (GLuint a, GLuint b, GLuint c, GLuint d, GLuint e) = NULL;
void (*glsym_glEndTiling) (GLuint a) = NULL;
void (*glsym_glReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *data) = NULL;
#ifdef GL_GLES
// just used for finding symbols :)
@ -212,8 +211,6 @@ gl_symbols(void)
FINDSYM(secsym_eglGetImageAttribSEC, "eglGetImageAttribSEC", secsym_func_uint);
#endif
FINDSYM(glsym_glReadPixels, "glReadPixels", glsym_func_void);
}
static void shader_array_flush(Evas_Engine_GL_Context *gc);

View File

@ -3435,9 +3435,31 @@ eng_gl_surface_read_pixels(void *data, void *surface,
# endif
#endif
/* Since this is an FBO, the pixels are already in the right Y order.
* But some devices don't support GL_BGRA, so we still need to convert.
*/
glsym_glBindFramebuffer(GL_FRAMEBUFFER, im->tex->pt->fb);
glsym_glReadPixels(x, y, w, h, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
if (im->tex->pt->format == GL_BGRA)
glReadPixels(x, y, w, h, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
else
{
DATA32 *ptr = pixels;
int k;
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
for (k = w * h; k; --k)
{
const DATA32 v = *ptr;
*ptr++ = (v & 0xFF00FF00)
| ((v & 0x00FF0000) >> 16)
| ((v & 0x000000FF) << 16);
}
}
glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
evas_common_convert_argb_premul(pixels, w * h);
return EINA_TRUE;
}
//--------------------------------//