add wayland egl client support

definitely not a feature, I promise™
This commit is contained in:
Mike Blumenkrantz 2015-11-02 16:23:20 -05:00
parent 35d0279d4f
commit ae6416c27c
3 changed files with 71 additions and 34 deletions

View File

@ -11,6 +11,13 @@
E_API int E_EVENT_WAYLAND_GLOBAL_ADD = -1;
#include "session-recovery-server-protocol.h"
#ifndef EGL_HEIGHT
# define EGL_HEIGHT 0x3056
#endif
#ifndef EGL_WIDTH
# define EGL_WIDTH 0x3057
#endif
/* Resource Data Mapping: (wl_resource_get_user_data)
*
* wl_surface == e_pixmap
@ -2638,6 +2645,20 @@ _e_comp_wl_desklock_hide(void)
e_comp_ungrab_input(1, 1);
}
static void
_e_comp_wl_gl_init(void *d EINA_UNUSED)
{
e_comp_wl->wl.gl = evas_gl_new(e_comp->evas);
e_comp->gl = !!e_comp_wl->wl.gl;
if (!e_comp->gl) return;
e_comp_wl->wl.glctx = evas_gl_context_create(e_comp_wl->wl.gl, NULL);
e_comp_wl->wl.glcfg = evas_gl_config_new();
e_comp_wl->wl.glsfc = evas_gl_surface_create(e_comp_wl->wl.gl, e_comp_wl->wl.glcfg, 1, 1);
evas_gl_make_current(e_comp_wl->wl.gl, e_comp_wl->wl.glsfc, e_comp_wl->wl.glctx);
e_comp_wl->wl.glapi = evas_gl_context_api_get(e_comp_wl->wl.gl, e_comp_wl->wl.glctx);
e_comp_wl->wl.glapi->evasglBindWaylandDisplay(e_comp_wl->wl.gl, e_comp_wl->wl.disp);
}
/* public functions */
/**
@ -2682,6 +2703,8 @@ e_comp_wl_init(void)
elm_config_preferred_engine_set("wayland_shm");
}
e_util_env_set("ELM_DISPLAY", "wl");
if (e_comp_gl_get())
ecore_job_add(_e_comp_wl_gl_init, NULL);
E_LIST_HANDLER_APPEND(handlers, E_EVENT_RANDR_CHANGE,
_e_comp_wl_cb_randr_change, NULL);
@ -2751,6 +2774,14 @@ e_comp_wl_shutdown(void)
free(global);
}
if (e_comp_wl->wl.shm) wl_shm_destroy(e_comp_wl->wl.shm);
if (e_comp->gl)
{
e_comp_wl->wl.glapi->evasglUnbindWaylandDisplay(e_comp_wl->wl.gl, e_comp_wl->wl.disp);
evas_gl_surface_destroy(e_comp_wl->wl.gl, e_comp_wl->wl.glsfc);
evas_gl_context_destroy(e_comp_wl->wl.gl, e_comp_wl->wl.glctx);
evas_gl_free(e_comp_wl->wl.gl);
evas_gl_config_free(e_comp_wl->wl.glcfg);
}
/* shutdown ecore_wayland */
ecore_wl_shutdown();
@ -2902,11 +2933,19 @@ e_comp_wl_buffer_get(struct wl_resource *resource)
if (listener)
return container_of(listener, E_Comp_Wl_Buffer, destroy_listener);
if (!(shmbuff = wl_shm_buffer_get(resource))) return NULL;
if (!(buffer = E_NEW(E_Comp_Wl_Buffer, 1))) return NULL;
buffer->w = wl_shm_buffer_get_width(shmbuff);
buffer->h = wl_shm_buffer_get_height(shmbuff);
shmbuff = wl_shm_buffer_get(resource);
if (shmbuff)
{
buffer->w = wl_shm_buffer_get_width(shmbuff);
buffer->h = wl_shm_buffer_get_height(shmbuff);
}
else if (e_comp->gl)
{
e_comp_wl->wl.glapi->evasglQueryWaylandBuffer(e_comp_wl->wl.gl, resource, EGL_WIDTH, &buffer->w);
e_comp_wl->wl.glapi->evasglQueryWaylandBuffer(e_comp_wl->wl.gl, resource, EGL_HEIGHT, &buffer->h);
}
buffer->shm_buffer = shmbuff;
buffer->resource = resource;
wl_signal_init(&buffer->destroy_signal);

View File

@ -55,11 +55,7 @@ struct _E_Comp_Wl_Buffer
struct wl_resource *resource;
struct wl_signal destroy_signal;
struct wl_listener destroy_listener;
union
{
struct wl_shm_buffer *shm_buffer;
void *legacy_buffer;
};
struct wl_shm_buffer *shm_buffer;
int32_t w, h;
uint32_t busy;
};
@ -109,6 +105,11 @@ struct _E_Comp_Wl_Data
struct wl_event_loop *loop;
Eina_Inlist *globals; // only used for nested wl compositors
struct wl_shm *shm; // only used for nested wl compositors
Evas_GL *gl;
Evas_GL_Config *glcfg;
Evas_GL_Context *glctx;
Evas_GL_Surface *glsfc;
Evas_GL_API *glapi;
} wl;
struct

View File

@ -2,6 +2,12 @@
#ifdef HAVE_WAYLAND
# include "e_comp_wl.h"
# ifndef EGL_TEXTURE_FORMAT
# define EGL_TEXTURE_FORMAT 0x3080
# endif
# ifndef EGL_TEXTURE_RGBA
# define EGL_TEXTURE_RGBA 0x305E
# endif
#endif
#ifndef HAVE_WAYLAND_ONLY
# include "e_comp_x.h"
@ -404,25 +410,25 @@ e_pixmap_refresh(E_Pixmap *cp)
{
E_Comp_Wl_Buffer *buffer = cp->buffer;
struct wl_shm_buffer *shm_buffer;
int format;
cp->w = cp->h = 0;
cp->image_argb = EINA_FALSE;
if (!buffer) return EINA_FALSE;
shm_buffer = wl_shm_buffer_get(buffer->resource);
if (!shm_buffer)
{
WRN("Cannot get shm buffer from buffer resource");
return EINA_FALSE;
}
shm_buffer = buffer->shm_buffer;
cp->w = buffer->w;
cp->h = buffer->h;
switch (wl_shm_buffer_get_format(shm_buffer))
if (shm_buffer)
format = wl_shm_buffer_get_format(shm_buffer);
else
e_comp_wl->wl.glapi->evasglQueryWaylandBuffer(e_comp_wl->wl.gl, buffer->resource, EGL_TEXTURE_FORMAT, &format);
switch (format)
{
case WL_SHM_FORMAT_ARGB8888:
case EGL_TEXTURE_RGBA:
cp->image_argb = EINA_TRUE;
break;
default:
@ -574,15 +580,10 @@ e_pixmap_native_surface_init(E_Pixmap *cp, Evas_Native_Surface *ns)
break;
case E_PIXMAP_TYPE_WL:
#ifdef HAVE_WAYLAND
ns->type = EVAS_NATIVE_SURFACE_OPENGL;
ns->type = EVAS_NATIVE_SURFACE_WL;
ns->version = EVAS_NATIVE_SURFACE_VERSION;
ns->data.opengl.texture_id = 0;
ns->data.opengl.framebuffer_id = 0;
ns->data.opengl.x = 0;
ns->data.opengl.y = 0;
ns->data.opengl.w = cp->w;
ns->data.opengl.h = cp->h;
ret = EINA_TRUE;
ns->data.wl.legacy_buffer = cp->buffer->resource;
ret = !cp->buffer->shm_buffer;
#endif
break;
default:
@ -690,12 +691,7 @@ e_pixmap_image_refresh(E_Pixmap *cp)
E_Comp_Wl_Buffer *buffer = cp->buffer;
struct wl_shm_buffer *shm_buffer;
shm_buffer = wl_shm_buffer_get(buffer->resource);
if (!shm_buffer)
{
WRN("Cannot get shm buffer from buffer resource");
return EINA_FALSE;
}
shm_buffer = buffer->shm_buffer;
if (cp->buffer_ref.buffer && (cp->buffer_ref.buffer != buffer))
{
/* FIXME: wtf? */
@ -711,7 +707,8 @@ e_pixmap_image_refresh(E_Pixmap *cp)
cp->buffer_destroy_listener.notify = _e_pixmap_cb_buffer_destroy;
wl_signal_add(&buffer->destroy_signal, &cp->buffer_destroy_listener);
cp->data = wl_shm_buffer_get_data(shm_buffer);
if (shm_buffer)
cp->data = wl_shm_buffer_get_data(shm_buffer);
return EINA_TRUE;
}
#endif
@ -733,7 +730,7 @@ e_pixmap_image_exists(const E_Pixmap *cp)
return !!cp->image;
#endif
#ifdef HAVE_WAYLAND
return !!cp->data; /* FIXME: egl */
return (!!cp->data) || (e_comp->gl && (!cp->buffer->shm_buffer));
#endif
return EINA_FALSE;
@ -811,7 +808,7 @@ e_pixmap_image_data_argb_convert(E_Pixmap *cp, void *pix, void *ipix, Eina_Recta
int i, x, y;
unsigned int *src, *dst;
shm_buffer = wl_shm_buffer_get(cp->buffer_ref.buffer->resource);
shm_buffer = cp->buffer_ref.buffer->shm_buffer;
if (!shm_buffer) return EINA_FALSE;
format = wl_shm_buffer_get_format(shm_buffer);