forked from enlightenment/efl
Evas gl_x11: Add support for glReadPixels
This will be needed by the filters for proxy rendering, for textures and maps (displacement). Add new engine functions to unleash the (sluggish) power of glReadPixels. The idea is to be able to bypass glReadPixels later, so 3 new APIs are added: - surface_lock - surface_read_pixels - surface_unlock They must be called in that order. Note (for history): glReadPixels was always getting the wrong data during first draw, but the right data during a redraw... Why? Well simply because for OpenGL itself, the image had never been drawn in teh first place! Only the Evas GL context knew about the image drawing, as it was queued somewhere in the pipe. One line solution: Call evas_gl_common_context_flush before doing anything else.
This commit is contained in:
parent
688c9c3676
commit
59f5216391
|
@ -907,8 +907,11 @@ struct _Evas_Func
|
|||
void *(*gl_proc_address_get) (void *data, const char *name);
|
||||
int (*gl_native_surface_get) (void *data, void *surface, void *native_surface);
|
||||
void *(*gl_api_get) (void *data);
|
||||
void (*gl_direct_override_get) (void *data, int *override, int *force_off);
|
||||
void (*gl_direct_override_get) (void *data, int *override, int *force_off);
|
||||
void (*gl_get_pixels_set) (void *data, void *get_pixels, void *get_pixels_data, void *obj);
|
||||
Eina_Bool (*gl_surface_lock) (void *data, void *surface);
|
||||
Eina_Bool (*gl_surface_read_pixels) (void *data, void *surface, int x, int y, int w, int h, Evas_Colorspace cspace, void *pixels);
|
||||
Eina_Bool (*gl_surface_unlock) (void *data, void *surface);
|
||||
|
||||
int (*image_load_error_get) (void *data, void *image);
|
||||
int (*font_run_end_get) (void *data, Evas_Font_Set *font, Evas_Font_Instance **script_fi, Evas_Font_Instance **cur_fi, Evas_Script_Type script, const Eina_Unicode *text, int run_len);
|
||||
|
|
|
@ -628,6 +628,7 @@ struct _Evas_GL_Image
|
|||
unsigned char cached : 1;
|
||||
unsigned char alpha : 1;
|
||||
unsigned char tex_only : 1;
|
||||
unsigned char locked : 1; // gl_surface_lock/unlock
|
||||
};
|
||||
|
||||
struct _Evas_GL_Font_Texture
|
||||
|
@ -838,6 +839,8 @@ 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);
|
||||
|
|
|
@ -29,6 +29,7 @@ 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 :)
|
||||
|
@ -211,6 +212,8 @@ 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);
|
||||
|
|
|
@ -3371,6 +3371,65 @@ eng_gl_get_pixels_set(void *data, void *get_pixels, void *get_pixels_data, void
|
|||
re->func.get_pixels_data = get_pixels_data;
|
||||
re->func.obj = (Evas_Object*)obj;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
eng_gl_surface_lock(void *data, void *surface)
|
||||
{
|
||||
Render_Engine *re = data;
|
||||
Evas_GL_Image *im = surface;
|
||||
|
||||
EVGLINIT(re, EINA_FALSE);
|
||||
if (!im->tex || !im->tex->pt)
|
||||
{
|
||||
ERR("Can not lock image that is not a surface!");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
evas_gl_common_context_flush(im->gc);
|
||||
im->locked = EINA_TRUE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
eng_gl_surface_unlock(void *data, void *surface)
|
||||
{
|
||||
Render_Engine *re = data;
|
||||
Evas_GL_Image *im = surface;
|
||||
|
||||
EVGLINIT(re, EINA_FALSE);
|
||||
im->locked = EINA_FALSE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
eng_gl_surface_read_pixels(void *data, void *surface,
|
||||
int x, int y, int w, int h,
|
||||
Evas_Colorspace cspace, void *pixels)
|
||||
{
|
||||
Render_Engine *re = data;
|
||||
Evas_GL_Image *im = surface;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(pixels, EINA_FALSE);
|
||||
|
||||
EVGLINIT(re, EINA_FALSE);
|
||||
if (!im->locked)
|
||||
{
|
||||
// For now, this is useless, but let's force clients to lock :)
|
||||
CRI("The surface must be locked before reading its pixels!");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (cspace != EVAS_COLORSPACE_ARGB8888)
|
||||
{
|
||||
ERR("Conversion to colorspace %d is not supported!", (int) cspace);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
glsym_glBindFramebuffer(GL_READ_FRAMEBUFFER, im->tex->pt->fb);
|
||||
glsym_glReadPixels(x, y, w, h, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
|
||||
glsym_glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
//--------------------------------//
|
||||
|
||||
static int
|
||||
|
@ -3696,6 +3755,9 @@ module_open(Evas_Module *em)
|
|||
ORD(gl_api_get);
|
||||
ORD(gl_direct_override_get);
|
||||
ORD(gl_get_pixels_set);
|
||||
ORD(gl_surface_lock);
|
||||
ORD(gl_surface_read_pixels);
|
||||
ORD(gl_surface_unlock);
|
||||
|
||||
ORD(image_load_error_get);
|
||||
|
||||
|
|
|
@ -2692,6 +2692,9 @@ static Evas_Func func =
|
|||
NULL, // need software mesa for gl rendering <- gl_api_get
|
||||
NULL, // need software mesa for gl rendering <- gl_direct_override
|
||||
NULL, // need software mesa for gl rendering <- gl_get_pixels_set
|
||||
NULL, // need software mesa for gl rendering <- gl_surface_lock
|
||||
NULL, // need software mesa for gl rendering <- gl_surface_read_pixels
|
||||
NULL, // need software mesa for gl rendering <- gl_surface_unlock
|
||||
eng_image_load_error_get,
|
||||
eng_font_run_font_end_get,
|
||||
eng_image_animated_get,
|
||||
|
|
Loading…
Reference in New Issue