forked from enlightenment/efl
wayland_egl: Fix redirect to texture
Previous redirect to texture approach broke multiple window applications by having only a single redirect per context. This approach allows multiple redirections.
This commit is contained in:
parent
0ed9d246e5
commit
c937248eac
|
@ -62,6 +62,7 @@
|
|||
typedef struct _Evas_GL_Program Evas_GL_Program;
|
||||
typedef struct _Evas_GL_Shared Evas_GL_Shared;
|
||||
typedef struct _Evas_Engine_GL_Context Evas_Engine_GL_Context;
|
||||
typedef struct _Evas_GL_Redirect Evas_GL_Redirect;
|
||||
typedef struct _Evas_GL_Texture_Pool Evas_GL_Texture_Pool;
|
||||
typedef struct _Evas_GL_Texture_Alloca Evas_GL_Texture_Alloca;
|
||||
typedef struct _Evas_GL_Texture Evas_GL_Texture;
|
||||
|
@ -349,12 +350,16 @@ struct _Evas_Engine_GL_Context
|
|||
|
||||
RGBA_Image *font_surface;
|
||||
|
||||
struct {
|
||||
GLuint current_fb;
|
||||
};
|
||||
|
||||
struct _Evas_GL_Redirect
|
||||
{
|
||||
Evas_Engine_GL_Context *gc;
|
||||
GLuint fb;
|
||||
GLuint texture;
|
||||
GLuint depth_buffer;
|
||||
Eina_Bool active : 1;
|
||||
} redirect;
|
||||
};
|
||||
|
||||
struct _Evas_GL_Texture_Pool
|
||||
|
@ -532,7 +537,6 @@ EAPI void *evas_gl_common_current_context_get(void);
|
|||
typedef int (*Evas_GL_Preload)(void);
|
||||
typedef void (*Evas_GL_Common_Image_Call)(Evas_GL_Image *im);
|
||||
typedef void (*Evas_GL_Common_Context_Call)(Evas_Engine_GL_Context *gc);
|
||||
typedef GLuint (*Evas_GL_Common_Context_Call_GLuint_Return)(Evas_Engine_GL_Context *gc);
|
||||
typedef Evas_GL_Image *(*Evas_GL_Common_Image_New_From_Data)(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, Evas_Colorspace cspace);
|
||||
typedef void (*Evas_GL_Preload_Render_Call)(evas_gl_make_current_cb make_current, void *engine_data);
|
||||
typedef Evas_Engine_GL_Context *(*Evas_GL_Common_Context_New)(void);
|
||||
|
@ -542,11 +546,11 @@ typedef void (*Evas_Gl_Symbols)(void *(*GetProcAddress)(const char *sym));
|
|||
|
||||
EAPI void __evas_gl_err(int err, const char *file, const char *func, int line, const char *op);
|
||||
|
||||
EAPI void evas_gl_common_context_unredirect(Evas_Engine_GL_Context *gc);
|
||||
EAPI void evas_gl_common_context_redirect(Evas_Engine_GL_Context *gc);
|
||||
EAPI GLuint evas_gl_common_context_redirect_texture_get(Evas_Engine_GL_Context *gc);
|
||||
EAPI void evas_gl_common_context_redirect_bind(Evas_Engine_GL_Context *gc);
|
||||
EAPI void evas_gl_common_context_redirect_unbind(Evas_Engine_GL_Context *gc);
|
||||
EAPI Evas_GL_Redirect *evas_gl_common_context_redirect(Evas_Engine_GL_Context *gc);
|
||||
EAPI void evas_gl_common_context_unredirect(Evas_GL_Redirect *re);
|
||||
EAPI GLuint evas_gl_common_context_redirect_texture_get(Evas_GL_Redirect *re);
|
||||
EAPI void evas_gl_common_context_redirect_bind(Evas_GL_Redirect *re);
|
||||
EAPI void evas_gl_common_context_redirect_unbind(Evas_GL_Redirect *re);
|
||||
|
||||
|
||||
void evas_gl_common_tiling_start(Evas_Engine_GL_Context *gc,
|
||||
|
|
|
@ -1164,7 +1164,6 @@ EAPI void
|
|||
evas_gl_common_context_resize(Evas_Engine_GL_Context *gc, int w, int h, int rot)
|
||||
{
|
||||
if ((gc->w == w) && (gc->h == h) && (gc->rot == rot)) return;
|
||||
if (gc->redirect.active) evas_gl_common_context_redirect(gc);
|
||||
evas_gl_common_context_flush(gc);
|
||||
gc->change.size = 1;
|
||||
gc->rot = rot;
|
||||
|
@ -1174,23 +1173,27 @@ evas_gl_common_context_resize(Evas_Engine_GL_Context *gc, int w, int h, int rot)
|
|||
}
|
||||
|
||||
EAPI void
|
||||
evas_gl_common_context_unredirect(Evas_Engine_GL_Context *gc)
|
||||
evas_gl_common_context_unredirect(Evas_GL_Redirect *re)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteTextures(1, &gc->redirect.texture);
|
||||
glDeleteRenderbuffers(1, &gc->redirect.depth_buffer);
|
||||
glDeleteFramebuffers(1, &gc->redirect.fb);
|
||||
gc->redirect.active = EINA_FALSE;
|
||||
glDeleteTextures(1, &re->texture);
|
||||
glDeleteRenderbuffers(1, &re->depth_buffer);
|
||||
glDeleteFramebuffers(1, &re->fb);
|
||||
re->gc->current_fb = 0;
|
||||
re->active = EINA_FALSE;
|
||||
free(re);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
EAPI Evas_GL_Redirect *
|
||||
evas_gl_common_context_redirect(Evas_Engine_GL_Context *gc)
|
||||
{
|
||||
if (gc->redirect.active) evas_gl_common_context_unredirect(gc);
|
||||
Evas_GL_Redirect *out;
|
||||
|
||||
out = calloc(1, sizeof(Evas_GL_Redirect));
|
||||
|
||||
/* Create a framebuffer object for RTT */
|
||||
glGenTextures(1, &gc->redirect.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, gc->redirect.texture);
|
||||
glGenTextures(1, &out->texture);
|
||||
glBindTexture(GL_TEXTURE_2D, out->texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
@ -1199,40 +1202,49 @@ evas_gl_common_context_redirect(Evas_Engine_GL_Context *gc)
|
|||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, gc->w, gc->h,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
glGenFramebuffers(1, &gc->redirect.fb);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gc->redirect.fb);
|
||||
glGenFramebuffers(1, &out->fb);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, out->fb);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D, gc->redirect.texture, 0);
|
||||
GL_TEXTURE_2D, out->texture, 0);
|
||||
|
||||
glGenRenderbuffers(1, &gc->redirect.depth_buffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, gc->redirect.depth_buffer);
|
||||
glGenRenderbuffers(1, &out->depth_buffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, out->depth_buffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, gc->w, gc->h);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
GL_RENDERBUFFER, gc->redirect.depth_buffer);
|
||||
GL_RENDERBUFFER, out->depth_buffer);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gc->redirect.fb);
|
||||
gc->redirect.active = EINA_TRUE;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, out->fb);
|
||||
out->gc = gc;
|
||||
gc->current_fb = out->fb;
|
||||
out->active = EINA_TRUE;
|
||||
return out;
|
||||
}
|
||||
|
||||
EAPI GLuint
|
||||
evas_gl_common_context_redirect_texture_get(Evas_Engine_GL_Context *gc)
|
||||
evas_gl_common_context_redirect_texture_get(Evas_GL_Redirect *re)
|
||||
{
|
||||
if (!gc->redirect.active) return 0;
|
||||
return gc->redirect.texture;
|
||||
return re->texture;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_gl_common_context_redirect_bind(Evas_Engine_GL_Context *gc)
|
||||
evas_gl_common_context_redirect_bind(Evas_GL_Redirect *re)
|
||||
{
|
||||
if (!gc->redirect.active) return;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gc->redirect.fb);
|
||||
if (re->active) return;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, re->fb);
|
||||
re->gc->current_fb = re->fb;
|
||||
re->active = EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_gl_common_context_redirect_unbind(Evas_Engine_GL_Context *gc EINA_UNUSED)
|
||||
evas_gl_common_context_redirect_unbind(Evas_GL_Redirect *re EINA_UNUSED)
|
||||
{
|
||||
if (!re->active) return;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
re->active = EINA_FALSE;
|
||||
re->gc->current_fb = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1325,10 +1337,7 @@ evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc,
|
|||
# endif
|
||||
#endif
|
||||
if (gc->pipe[0].shader.surface == gc->def_surface)
|
||||
{
|
||||
if (gc->redirect.active) glBindFramebuffer(GL_FRAMEBUFFER, gc->redirect.fb);
|
||||
else glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
glsym_glBindFramebuffer(GL_FRAMEBUFFER, gc->current_fb);
|
||||
else
|
||||
glsym_glBindFramebuffer(GL_FRAMEBUFFER, surface->tex->pt->fb);
|
||||
_evas_gl_common_viewport_set(gc);
|
||||
|
|
|
@ -62,11 +62,11 @@ Evas_GL_Common_Context_Call glsym_evas_gl_common_context_newframe = NULL;
|
|||
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_done = NULL;
|
||||
Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize = NULL;
|
||||
Evas_GL_Common_Buffer_Dump_Call glsym_evas_gl_common_buffer_dump = NULL;
|
||||
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_unredirect = NULL;
|
||||
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_redirect = NULL;
|
||||
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_redirect_bind = NULL;
|
||||
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_redirect_unbind = NULL;
|
||||
Evas_GL_Common_Context_Call_GLuint_Return glsym_evas_gl_common_context_redirect_texture_get = NULL;
|
||||
Evas_GL_Redirect *(*glsym_evas_gl_common_context_redirect) (Evas_Engine_GL_Context *gc) = NULL;
|
||||
void (*glsym_evas_gl_common_context_unredirect) (Evas_GL_Redirect *re) = NULL;
|
||||
GLuint (*glsym_evas_gl_common_context_redirect_texture_get) (Evas_GL_Redirect *re) = NULL;
|
||||
void (*glsym_evas_gl_common_context_redirect_bind) (Evas_GL_Redirect *re) = NULL;
|
||||
void (*glsym_evas_gl_common_context_redirect_unbind) (Evas_GL_Redirect *re) = NULL;
|
||||
Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock = NULL;
|
||||
Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock = NULL;
|
||||
Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_relax = NULL;
|
||||
|
|
|
@ -85,9 +85,10 @@ struct _Outbuf
|
|||
Eina_Bool surf : 1;
|
||||
|
||||
Model *model;
|
||||
Eina_Bool redirected : 1;
|
||||
|
||||
float offset_x, offset_y;
|
||||
|
||||
Evas_GL_Redirect *redirect;
|
||||
};
|
||||
|
||||
struct _Context_3D
|
||||
|
@ -107,15 +108,16 @@ extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_use;
|
|||
extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_newframe;
|
||||
extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_done;
|
||||
extern Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize;
|
||||
extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_unredirect;
|
||||
extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_redirect;
|
||||
extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_redirect_bind;
|
||||
extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_redirect_unbind;
|
||||
extern Evas_GL_Common_Context_Call_GLuint_Return glsym_evas_gl_common_context_redirect_texture_get;
|
||||
extern Evas_GL_Common_Buffer_Dump_Call glsym_evas_gl_common_buffer_dump;
|
||||
extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock;
|
||||
extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock;
|
||||
|
||||
extern Evas_GL_Redirect *(*glsym_evas_gl_common_context_redirect) (Evas_Engine_GL_Context *gc);
|
||||
extern void (*glsym_evas_gl_common_context_unredirect) (Evas_GL_Redirect *re);
|
||||
extern GLuint (*glsym_evas_gl_common_context_redirect_texture_get) (Evas_GL_Redirect *re);
|
||||
extern void (*glsym_evas_gl_common_context_redirect_bind) (Evas_GL_Redirect *re);
|
||||
extern void (*glsym_evas_gl_common_context_redirect_unbind) (Evas_GL_Redirect *re);
|
||||
|
||||
extern unsigned int (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGLint *d, EGLint c);
|
||||
extern unsigned int (*glsym_eglSetDamageRegionKHR) (EGLDisplay a, EGLSurface b, EGLint *c, EGLint d);
|
||||
|
||||
|
|
|
@ -241,6 +241,7 @@ eng_window_use(Outbuf *gw)
|
|||
{
|
||||
glsym_evas_gl_common_context_use(_evas_gl_wl_window->gl_context);
|
||||
glsym_evas_gl_common_context_flush(_evas_gl_wl_window->gl_context);
|
||||
if (_evas_gl_wl_window->redirect) glsym_evas_gl_common_context_redirect_unbind(_evas_gl_wl_window->redirect);
|
||||
}
|
||||
|
||||
_evas_gl_wl_window = gw;
|
||||
|
@ -261,6 +262,7 @@ eng_window_use(Outbuf *gw)
|
|||
{
|
||||
glsym_evas_gl_common_context_use(gw->gl_context);
|
||||
glsym_evas_gl_common_context_resize(gw->gl_context, gw->w, gw->h, gw->rot);
|
||||
if (gw->redirect) glsym_evas_gl_common_context_redirect_bind(gw->redirect);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,14 +319,16 @@ eng_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth EIN
|
|||
{
|
||||
if (!ob->model) ob->model = wobbly_create(0, 0, w, h);
|
||||
wobbly_resize(ob->model, w, h);
|
||||
glsym_evas_gl_common_context_unredirect(ob->gl_context);
|
||||
ob->redirected = EINA_FALSE;
|
||||
if (ob->redirect)
|
||||
glsym_evas_gl_common_context_unredirect(ob->redirect);
|
||||
|
||||
ob->w = w;
|
||||
ob->h = h;
|
||||
ob->rot = rot;
|
||||
eng_window_use(ob);
|
||||
glsym_evas_gl_common_context_resize(ob->gl_context, w, h, rot);
|
||||
if (ob->redirect)
|
||||
ob->redirect = glsym_evas_gl_common_context_redirect(ob->gl_context);
|
||||
|
||||
if (ob->win)
|
||||
{
|
||||
|
@ -367,7 +371,7 @@ eng_outbuf_rotation_get(Outbuf *ob)
|
|||
Render_Engine_Swap_Mode
|
||||
eng_outbuf_swap_mode_get(Outbuf *ob)
|
||||
{
|
||||
if (ob->redirected)
|
||||
if (ob->redirect)
|
||||
{
|
||||
ob->prev_age = 0;
|
||||
return MODE_FULL;
|
||||
|
@ -522,9 +526,9 @@ eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode)
|
|||
|
||||
if (ob->model) effect_continues = wobbly_process(ob->model, ob->info,
|
||||
ob->w, ob->h,
|
||||
ob->redirected);
|
||||
!!ob->redirect);
|
||||
|
||||
if (ob->redirected)
|
||||
if (ob->redirect)
|
||||
{
|
||||
float tlx, tly, brx, bry;
|
||||
int w, h;
|
||||
|
@ -538,12 +542,12 @@ eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode)
|
|||
tly - ob->offset_y);
|
||||
ob->offset_x = tlx;
|
||||
ob->offset_y = tly;
|
||||
glsym_evas_gl_common_context_redirect_unbind(ob->gl_context);
|
||||
glsym_evas_gl_common_context_redirect_unbind(ob->redirect);
|
||||
glViewport(0, 0, w, h);
|
||||
wobbly_draw(ob->gl_context, ob->model);
|
||||
wobbly_draw(ob->redirect, ob->model);
|
||||
wl_surface_set_opaque_region(ob->info->info.surface, NULL);
|
||||
eglSwapBuffers(ob->egl_disp, ob->egl_surface[0]);
|
||||
glsym_evas_gl_common_context_redirect_bind(ob->gl_context);
|
||||
glsym_evas_gl_common_context_redirect_bind(ob->redirect);
|
||||
glViewport(0, 0, ob->w, ob->h);
|
||||
}
|
||||
else if ((glsym_eglSwapBuffersWithDamage) && (rects) &&
|
||||
|
@ -569,20 +573,22 @@ eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode)
|
|||
else
|
||||
eglSwapBuffers(ob->egl_disp, ob->egl_surface[0]);
|
||||
|
||||
if (ob->redirected && !effect_continues) ob->info->wobbling = EINA_TRUE;
|
||||
if (ob->redirect && !effect_continues) ob->info->wobbling = EINA_TRUE;
|
||||
else ob->info->wobbling = effect_continues;
|
||||
|
||||
if (effect_continues)
|
||||
{
|
||||
glsym_evas_gl_common_context_redirect(ob->gl_context);
|
||||
ob->redirected = EINA_TRUE;
|
||||
if (ob->redirect)
|
||||
glsym_evas_gl_common_context_unredirect(ob->redirect);
|
||||
ob->redirect = glsym_evas_gl_common_context_redirect(ob->gl_context);
|
||||
}
|
||||
else
|
||||
{
|
||||
ob->offset_x = 0;
|
||||
ob->offset_y = 0;
|
||||
glsym_evas_gl_common_context_unredirect(ob->gl_context);
|
||||
ob->redirected = EINA_FALSE;
|
||||
if (ob->redirect)
|
||||
glsym_evas_gl_common_context_unredirect(ob->redirect);
|
||||
ob->redirect = NULL;
|
||||
}
|
||||
if (ob->info->callback.post_swap)
|
||||
ob->info->callback.post_swap(ob->info->callback.data, ob->evas);
|
||||
|
|
|
@ -812,14 +812,14 @@ wobbly_resize(Model *m, int dwidth, int dheight)
|
|||
}
|
||||
|
||||
void
|
||||
wobbly_draw(Evas_Engine_GL_Context *gl_context, Model *m)
|
||||
wobbly_draw(Evas_GL_Redirect *re, Model *m)
|
||||
{
|
||||
GLuint tex;
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glUseProgram(m->prog);
|
||||
tex = glsym_evas_gl_common_context_redirect_texture_get(gl_context);
|
||||
tex = glsym_evas_gl_common_context_redirect_texture_get(re);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), m->vertices);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), m->vertices + 2);
|
||||
|
|
|
@ -41,7 +41,7 @@ void
|
|||
wobbly_resize(Model *m, int dw, int dh);
|
||||
|
||||
void
|
||||
wobbly_draw(Evas_Engine_GL_Context *gl_context, Model *m);
|
||||
wobbly_draw(Evas_GL_Redirect *re, Model *m);
|
||||
|
||||
Eina_Bool
|
||||
wobbly_process(Model *m, Evas_Engine_Info_Wayland_Egl *info, int w, int h, Eina_Bool redirected);
|
||||
|
|
Loading…
Reference in New Issue