/* put state damages into surface */
if ((!ec->comp->nocomp) && (ec->frame))
{
- EINA_LIST_FREE(state->damages, dmg)
+ /* FIXME: workaround for bad wayland egl driver which doesn't send damage request */
+ if (!eina_list_count(state->damages))
{
- e_comp_object_damage(ec->frame, dmg->x, dmg->y, dmg->w, dmg->h);
- eina_rectangle_free(dmg);
+ if (ec->comp_data->buffer_ref.buffer->type == E_COMP_WL_BUFFER_TYPE_NATIVE)
+ {
+ e_comp_object_damage(ec->frame,
+ 0, 0,
+ ec->comp_data->buffer_ref.buffer->w,
+ ec->comp_data->buffer_ref.buffer->h);
+ }
+ }
+ else
+ {
+ EINA_LIST_FREE(state->damages, dmg)
+ {
+ e_comp_object_damage(ec->frame, dmg->x, dmg->y, dmg->w, dmg->h);
+ eina_rectangle_free(dmg);
+ }
}
}
wl_output_send_done(resource);
}
+static void
+_e_comp_wl_gl_init(E_Comp_Data *cdata)
+{
+ Evas_GL *evasgl = NULL;
+ Evas_GL_API *glapi = NULL;
+ Evas_GL_Context *ctx = NULL;
+ Evas_GL_Surface *sfc = NULL;
+ Evas_GL_Config *cfg = NULL;
+ Eina_Bool res;
+ const char *name;
+
+ if (!e_comp_gl_get()) return;
+
+ name = ecore_evas_engine_name_get(e_comp->ee);
+ if (!name) return;
+ if (strcmp(name, "gl_drm")) return;
+
+ /* create dummy evas gl to bind wayland display of enlightenment to egl display */
+ evasgl = evas_gl_new(e_comp->evas);
+ EINA_SAFETY_ON_NULL_GOTO(evasgl, err);
+
+ glapi = evas_gl_api_get(evasgl);
+ EINA_SAFETY_ON_NULL_GOTO(glapi, err);
+
+ cfg = evas_gl_config_new();
+ EINA_SAFETY_ON_NULL_GOTO(cfg, err);
+
+ sfc = evas_gl_surface_create(evasgl, cfg, 1, 1);
+ EINA_SAFETY_ON_NULL_GOTO(sfc, err);
+
+ ctx = evas_gl_context_create(evasgl, NULL);
+ EINA_SAFETY_ON_NULL_GOTO(ctx, err);
+
+ res = evas_gl_make_current(evasgl, sfc, ctx);
+ EINA_SAFETY_ON_FALSE_GOTO(res, err);
+
+ res = glapi->evasglBindWaylandDisplay(evasgl, cdata->wl.disp);
+ EINA_SAFETY_ON_FALSE_GOTO(res, err);
+
+ evas_gl_config_free(cfg);
+
+ cdata->gl.evasgl = evasgl;
+ cdata->gl.api = glapi;
+ cdata->gl.sfc = sfc;
+ cdata->gl.ctx = ctx;
+
+ /* for native surface */
+ e_comp->gl = 1;
+
+ return;
+
+err:
+ evas_gl_config_free(cfg);
+ evas_gl_make_current(evasgl, NULL, NULL);
+ evas_gl_context_destroy(evasgl, ctx);
+ evas_gl_surface_destroy(evasgl, sfc);
+ evas_gl_free(evasgl);
+}
+
+static void
+_e_comp_wl_gl_shutdown(E_Comp_Data *cdata)
+{
+ if (!cdata->gl.evasgl) return;
+
+ cdata->gl.api->evasglUnbindWaylandDisplay(cdata->gl.evasgl, cdata->wl.disp);
+
+ evas_gl_make_current(cdata->gl.evasgl, NULL, NULL);
+ evas_gl_context_destroy(cdata->gl.evasgl, cdata->gl.ctx);
+ evas_gl_surface_destroy(cdata->gl.evasgl, cdata->gl.sfc);
+ evas_gl_free(cdata->gl.evasgl);
+
+ cdata->gl.sfc = NULL;
+ cdata->gl.ctx = NULL;
+ cdata->gl.api = NULL;
+ cdata->gl.evasgl = NULL;
+}
+
static Eina_Bool
_e_comp_wl_compositor_create(void)
{
goto input_err;
}
+ _e_comp_wl_gl_init(cdata);
+
#ifndef HAVE_WAYLAND_ONLY
if (getenv("DISPLAY"))
{
EINTERN void
e_comp_wl_shutdown(void)
{
+ /* free evas gl */
+ E_Comp_Data *cdata;
+ if ((cdata = e_comp->wl_comp_data))
+ _e_comp_wl_gl_shutdown(cdata);
+
#ifndef HAVE_WAYLAND_ONLY
_e_comp_wl_compositor_cb_del(e_comp);
#endif
EAPI E_Comp_Wl_Buffer *
e_comp_wl_buffer_get(struct wl_resource *resource)
{
- E_Comp_Wl_Buffer *buffer;
+ E_Comp_Wl_Buffer *buffer = NULL;
struct wl_listener *listener;
struct wl_shm_buffer *shmbuff;
+ E_Comp_Data *cdata;
+ Eina_Bool res;
listener =
wl_resource_get_destroy_listener(resource, _e_comp_wl_buffer_cb_destroy);
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->type = E_COMP_WL_BUFFER_TYPE_SHM;
+
+ buffer->w = wl_shm_buffer_get_width(shmbuff);
+ buffer->h = wl_shm_buffer_get_height(shmbuff);
+ }
+ else
+ {
+ cdata = e_comp->wl_comp_data;
+ if (cdata->gl.api)
+ {
+ buffer->type = E_COMP_WL_BUFFER_TYPE_NATIVE;
+
+ res = cdata->gl.api->evasglQueryWaylandBuffer(cdata->gl.evasgl,
+ resource,
+ EVAS_GL_WIDTH,
+ &buffer->w);
+ EINA_SAFETY_ON_FALSE_GOTO(res, err);
+
+ res = cdata->gl.api->evasglQueryWaylandBuffer(cdata->gl.evasgl,
+ resource,
+ EVAS_GL_HEIGHT,
+ &buffer->h);
+ EINA_SAFETY_ON_FALSE_GOTO(res, err);
+ }
+ else
+ goto err;
+ }
buffer->resource = resource;
wl_signal_init(&buffer->destroy_signal);
wl_resource_add_destroy_listener(resource, &buffer->destroy_listener);
return buffer;
+
+err:
+ ERR("Invalid resource:%u", wl_resource_get_id(resource));
+ E_FREE(buffer);
+ return NULL;
}
/**
(type *)( (char *)__mptr - offsetof(type,member) ); \
})
+#include <Evas_GL.h>
+
typedef struct _E_Comp_Wl_Buffer E_Comp_Wl_Buffer;
typedef struct _E_Comp_Wl_Buffer_Ref E_Comp_Wl_Buffer_Ref;
typedef struct _E_Comp_Wl_Subsurf_Data E_Comp_Wl_Subsurf_Data;
typedef struct _E_Comp_Wl_Data E_Comp_Wl_Data;
typedef struct _E_Comp_Wl_Output E_Comp_Wl_Output;
+typedef enum _E_Comp_Wl_Buffer_Type
+{
+ E_COMP_WL_BUFFER_TYPE_NONE = 0,
+ E_COMP_WL_BUFFER_TYPE_SHM = 1,
+ E_COMP_WL_BUFFER_TYPE_NATIVE = 2
+} E_Comp_Wl_Buffer_Type;
+
struct _E_Comp_Wl_Buffer
{
+ E_Comp_Wl_Buffer_Type type;
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;
};
char *area;
} xkb;
+ struct
+ {
+ Evas_GL *evasgl;
+ Evas_GL_API *api;
+ Evas_GL_Surface *sfc;
+ Evas_GL_Context *ctx;
+ } gl;
+
Eina_List *outputs;
Ecore_Fd_Handler *fd_hdlr;
if (!buffer) return;
- if (!(shm_buffer = wl_shm_buffer_get(buffer->resource)))
+ if (buffer->type == E_COMP_WL_BUFFER_TYPE_SHM)
{
- WRN("Cannot get shm buffer from buffer resource");
- e_comp_wl_buffer_reference(&cp->buffer_ref, NULL);
- return;
- }
+ shm_buffer = wl_shm_buffer_get(buffer->resource);
+ if (!shm_buffer)
+ {
+ ERR("No shm_buffer resource:%u", wl_resource_get_id(buffer->resource));
+ e_comp_wl_buffer_reference(&cp->buffer_ref, NULL);
+ return;
+ }
- buffer->shm_buffer = shm_buffer;
- cp->w = buffer->w;
- cp->h = buffer->h;
- /* buffer->w = cp->w = wl_shm_buffer_get_width(shm_buffer); */
- /* buffer->h = cp->h = wl_shm_buffer_get_height(shm_buffer); */
+ buffer->shm_buffer = shm_buffer;
+ cp->w = buffer->w;
+ cp->h = buffer->h;
- switch (wl_shm_buffer_get_format(shm_buffer))
- {
- case WL_SHM_FORMAT_ARGB8888:
- cp->image_argb = EINA_TRUE;
- break;
- default:
- cp->image_argb = EINA_FALSE;
- break;
+ switch (wl_shm_buffer_get_format(shm_buffer))
+ {
+ case WL_SHM_FORMAT_ARGB8888:
+ cp->image_argb = EINA_TRUE;
+ break;
+ default:
+ cp->image_argb = EINA_FALSE;
+ break;
+ }
+
+ cp->data = wl_shm_buffer_get_data(shm_buffer);
}
+ else if (buffer->type == E_COMP_WL_BUFFER_TYPE_NATIVE)
+ {
+ if (e_comp->gl)
+ {
+ buffer->shm_buffer = NULL;
+ cp->w = buffer->w;
+ cp->h = buffer->h;
+ cp->image_argb = EINA_FALSE; /* TODO: format */
+ cp->data = NULL;
+ }
+ else
+ {
+ ERR("Invalid native buffer resource:%u", wl_resource_get_id(buffer->resource));
+ e_comp_wl_buffer_reference(&cp->buffer_ref, NULL);
+ return;
+ }
- cp->data = wl_shm_buffer_get_data(shm_buffer);
+ }
+ else
+ {
+ ERR("Invalid resource:%u", wl_resource_get_id(buffer->resource));
+ e_comp_wl_buffer_reference(&cp->buffer_ref, NULL);
+ return;
+ }
cp->buffer_destroy_listener.notify = _e_pixmap_cb_buffer_destroy;
wl_signal_add(&buffer->destroy_signal, &cp->buffer_destroy_listener);
break;
case E_PIXMAP_TYPE_WL:
#if defined(HAVE_WAYLAND_CLIENTS) || defined(HAVE_WAYLAND_ONLY)
- ns->type = EVAS_NATIVE_SURFACE_OPENGL;
- 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;
+ if (cp->buffer_ref.buffer->type == E_COMP_WL_BUFFER_TYPE_NATIVE)
+ {
+ ns->type = EVAS_NATIVE_SURFACE_WL;
+ ns->version = EVAS_NATIVE_SURFACE_VERSION;
+ ns->data.wl.legacy_buffer = cp->buffer_ref.buffer->resource;
+ ret = EINA_TRUE;
+ }
+ else
+ ret = EINA_FALSE;
#endif
break;
default:
e_modapi_init(E_Module *m)
{
E_Comp *comp;
- int w = 0, h = 0;
+ int w = 0, h = 0, scr_w = 0, scr_h = 0;
+ char *env_w, *env_h;
printf("LOAD WL_DRM MODULE\n");
- /* try to init ecore_drm */
- /* if (!ecore_drm_init()) */
- /* { */
- /* fprintf(stderr, "Could not initialize ecore_drm"); */
- /* return NULL; */
- /* } */
-
if (!(comp = e_comp))
{
comp = e_comp_new();
comp->comp_type = E_PIXMAP_TYPE_WL;
}
+ /* set gl available if we have ecore_evas support */
+ if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_WAYLAND_EGL) ||
+ ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_DRM))
+ e_comp_gl_set(EINA_TRUE);
+
+ if ((env_w = getenv("E_SCREEN_WIDTH"))) scr_w = atoi(env_w);
+ if ((env_h = getenv("E_SCREEN_HEIGHT"))) scr_h = atoi(env_h);
+
+ if (scr_w <= 0) scr_w = 1;
+ if (scr_h <= 0) scr_h = 1;
+
+ DBG("GL available:%d config engine:%d screen size:%dx%d",
+ e_comp_gl_get(), e_comp_config_get()->engine, scr_w, scr_h);
+
if ((e_comp_gl_get()) &&
(e_comp_config_get()->engine == E_COMP_ENGINE_GL))
{
- comp->ee = ecore_evas_gl_drm_new(NULL, 0, 0, 0, 1, 1);
+ comp->ee = ecore_evas_gl_drm_new(NULL, 0, 0, 0, scr_w, scr_h);
+ DBG("Create ecore_evas_gl_drm canvas:%p", comp->ee);
+
if (!comp->ee)
e_comp_gl_set(EINA_FALSE);
}
/* fallback to framebuffer drm (non-accel) */
if (!comp->ee)
- comp->ee = ecore_evas_drm_new(NULL, 0, 0, 0, 1, 1);
+ {
+ comp->ee = ecore_evas_drm_new(NULL, 0, 0, 0, scr_w, scr_h);
+ DBG("Create ecore_evas_drm canvas:%p", comp->ee);
+ }
if (!comp->ee)
{
ecore_evas_screen_geometry_get(comp->ee, NULL, NULL, &w, &h);
/* resize the canvas */
- ecore_evas_resize(comp->ee, w, h);
+ if (!((scr_w == w) && (scr_h == h)))
+ {
+ DBG("Change ecore_evas canvas size %dx%d -> %dx%d", scr_w, scr_h, w, h);
+ ecore_evas_resize(comp->ee, w, h);
+ }
/* TODO: hook ecore_evas_callback_resize_set */