2015-06-03 09:56:35 -07:00
|
|
|
#include "config.h"
|
2014-08-21 02:22:16 -07:00
|
|
|
#include "evas_engine.h"
|
2015-09-30 15:12:13 -07:00
|
|
|
#include "../gl_common/evas_gl_define.h"
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
#include <wayland-client.h>
|
2014-08-21 02:22:16 -07:00
|
|
|
|
|
|
|
#ifdef HAVE_DLSYM
|
|
|
|
# include <dlfcn.h> /* dlopen,dlclose,etc */
|
|
|
|
#else
|
|
|
|
# error gl_drm should not get compiled if dlsym is not found on the system!
|
|
|
|
#endif
|
|
|
|
|
2015-06-04 08:52:22 -07:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
# include "evas_cs2_private.h"
|
|
|
|
#endif
|
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
#define EVAS_GL_NO_GL_H_CHECK 1
|
|
|
|
#include "Evas_GL.h"
|
|
|
|
|
|
|
|
#define EVAS_GL_UPDATE_TILE_SIZE 16
|
|
|
|
|
|
|
|
/* external variables */
|
|
|
|
int _evas_engine_gl_drm_log_dom = -1;
|
2015-06-03 09:56:35 -07:00
|
|
|
int _extn_have_buffer_age = 1;
|
|
|
|
|
|
|
|
/* local variables */
|
|
|
|
static Eina_Bool initted = EINA_FALSE;
|
|
|
|
static int gl_wins = 0;
|
|
|
|
|
|
|
|
/* local structures */
|
|
|
|
typedef struct _Native Native;
|
|
|
|
struct _Native
|
|
|
|
{
|
|
|
|
Evas_Native_Surface ns;
|
|
|
|
struct wl_buffer *wl_buf;
|
|
|
|
void *egl_surface;
|
|
|
|
};
|
2014-08-21 02:22:16 -07:00
|
|
|
|
2015-06-04 08:52:22 -07:00
|
|
|
/* local function prototype types */
|
|
|
|
typedef void (*_eng_fn)(void);
|
|
|
|
typedef _eng_fn (*glsym_func_eng_fn)();
|
|
|
|
typedef void (*glsym_func_void)();
|
|
|
|
typedef void *(*glsym_func_void_ptr)();
|
|
|
|
typedef int (*glsym_func_int)();
|
|
|
|
typedef unsigned int (*glsym_func_uint)();
|
|
|
|
typedef const char *(*glsym_func_const_char_ptr)();
|
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
/* external dynamic loaded Evas_GL function pointers */
|
|
|
|
Evas_GL_Common_Image_Call glsym_evas_gl_common_image_ref = NULL;
|
|
|
|
Evas_GL_Common_Image_Call glsym_evas_gl_common_image_unref = NULL;
|
|
|
|
Evas_GL_Common_Image_Call glsym_evas_gl_common_image_free = NULL;
|
|
|
|
Evas_GL_Common_Image_Call glsym_evas_gl_common_image_native_disable = NULL;
|
|
|
|
Evas_GL_Common_Image_Call glsym_evas_gl_common_image_native_enable = NULL;
|
|
|
|
Evas_GL_Common_Image_New_From_Data glsym_evas_gl_common_image_new_from_data = NULL;
|
|
|
|
Evas_GL_Common_Context_Call glsym_evas_gl_common_image_all_unload = NULL;
|
|
|
|
Evas_GL_Preload glsym_evas_gl_preload_init = NULL;
|
|
|
|
Evas_GL_Preload glsym_evas_gl_preload_shutdown = NULL;
|
|
|
|
EVGL_Engine_Call glsym_evgl_engine_shutdown = NULL;
|
2015-06-04 08:52:22 -07:00
|
|
|
EVGL_Current_Native_Context_Get_Call glsym_evgl_current_native_context_get = NULL;
|
2014-08-21 02:22:16 -07:00
|
|
|
Evas_Gl_Symbols glsym_evas_gl_symbols = NULL;
|
|
|
|
|
|
|
|
Evas_GL_Common_Context_New glsym_evas_gl_common_context_new = NULL;
|
|
|
|
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_flush = NULL;
|
|
|
|
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_free = NULL;
|
|
|
|
Evas_GL_Common_Context_Call glsym_evas_gl_common_context_use = NULL;
|
|
|
|
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_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;
|
|
|
|
|
2015-06-04 08:52:22 -07:00
|
|
|
glsym_func_void_ptr glsym_evas_gl_common_current_context_get = NULL;
|
2014-08-21 02:22:16 -07:00
|
|
|
|
|
|
|
/* dynamic loaded local egl function pointers */
|
|
|
|
_eng_fn (*glsym_eglGetProcAddress)(const char *a) = NULL;
|
|
|
|
void *(*glsym_eglCreateImage)(EGLDisplay a, EGLContext b, EGLenum c, EGLClientBuffer d, const int *e) = NULL;
|
|
|
|
void (*glsym_eglDestroyImage)(EGLDisplay a, void *b) = NULL;
|
2015-11-04 08:18:25 -08:00
|
|
|
void (*glsym_glEGLImageTargetTexture2DOES)(int a, void *b) = NULL;
|
2014-08-21 02:22:16 -07:00
|
|
|
unsigned int (*glsym_eglSwapBuffersWithDamage)(EGLDisplay a, void *b, const EGLint *d, EGLint c) = NULL;
|
2014-12-04 00:59:30 -08:00
|
|
|
unsigned int (*glsym_eglQueryWaylandBufferWL)(EGLDisplay a, struct wl_resource *b, EGLint c, EGLint *d) = NULL;
|
2015-11-04 08:18:25 -08:00
|
|
|
unsigned int (*glsym_eglSetDamageRegionKHR)(EGLDisplay a, EGLSurface b, EGLint *c, EGLint d) = NULL;
|
2014-08-21 02:22:16 -07:00
|
|
|
|
|
|
|
/* local function prototypes */
|
|
|
|
static void gl_symbols(void);
|
|
|
|
static void gl_extn_veto(Render_Engine *re);
|
|
|
|
|
|
|
|
static void *evgl_eng_display_get(void *data);
|
|
|
|
static void *evgl_eng_evas_surface_get(void *data);
|
|
|
|
static int evgl_eng_make_current(void *data, void *surface, void *context, int flush);
|
|
|
|
static void *evgl_eng_native_window_create(void *data);
|
|
|
|
static int evgl_eng_native_window_destroy(void *data, void *native_window);
|
|
|
|
static void *evgl_eng_window_surface_create(void *data, void *native_window);
|
|
|
|
static int evgl_eng_window_surface_destroy(void *data, void *surface);
|
2014-10-24 05:37:51 -07:00
|
|
|
static void *evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version version);
|
2014-08-21 02:22:16 -07:00
|
|
|
static int evgl_eng_context_destroy(void *data, void *context);
|
|
|
|
static const char *evgl_eng_string_get(void *data);
|
|
|
|
static void *evgl_eng_proc_address_get(const char *name);
|
|
|
|
static int evgl_eng_rotation_angle_get(void *data);
|
|
|
|
|
|
|
|
/* function tables - filled in later (func and parent func) */
|
|
|
|
static Evas_Func func, pfunc;
|
|
|
|
static const EVGL_Interface evgl_funcs =
|
|
|
|
{
|
|
|
|
evgl_eng_display_get,
|
|
|
|
evgl_eng_evas_surface_get,
|
|
|
|
evgl_eng_native_window_create,
|
|
|
|
evgl_eng_native_window_destroy,
|
|
|
|
evgl_eng_window_surface_create,
|
|
|
|
evgl_eng_window_surface_destroy,
|
|
|
|
evgl_eng_context_create,
|
|
|
|
evgl_eng_context_destroy,
|
|
|
|
evgl_eng_make_current,
|
|
|
|
evgl_eng_proc_address_get,
|
|
|
|
evgl_eng_string_get,
|
2014-09-22 23:33:16 -07:00
|
|
|
evgl_eng_rotation_angle_get,
|
|
|
|
NULL, // PBuffer
|
2014-10-06 05:26:11 -07:00
|
|
|
NULL, // PBuffer
|
2014-09-22 23:33:16 -07:00
|
|
|
NULL, // OpenGL-ES 1
|
|
|
|
NULL, // OpenGL-ES 1
|
2015-03-15 21:57:09 -07:00
|
|
|
NULL, // OpenGL-ES 1
|
2015-05-11 20:03:29 -07:00
|
|
|
NULL, // native_win_surface_config_get
|
2014-08-21 02:22:16 -07:00
|
|
|
};
|
|
|
|
|
2015-06-12 08:48:30 -07:00
|
|
|
Eina_Bool
|
|
|
|
eng_gbm_init(Evas_Engine_Info_GL_Drm *info)
|
|
|
|
{
|
|
|
|
Ecore_Drm_Device *dev;
|
|
|
|
|
|
|
|
if (!info) return EINA_FALSE;
|
|
|
|
if (!(dev = info->info.dev)) return EINA_FALSE;
|
|
|
|
|
|
|
|
if (!(info->info.gbm = gbm_create_device(dev->drm.fd)))
|
|
|
|
{
|
|
|
|
ERR("Coult not create gbm device: %m");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Eina_Bool
|
|
|
|
eng_gbm_shutdown(Evas_Engine_Info_GL_Drm *info)
|
|
|
|
{
|
|
|
|
if (!info) return EINA_TRUE;
|
|
|
|
|
|
|
|
if (info->info.gbm)
|
|
|
|
{
|
|
|
|
gbm_device_destroy(info->info.gbm);
|
|
|
|
info->info.gbm = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
/* local inline functions */
|
|
|
|
static inline Outbuf *
|
|
|
|
eng_get_ob(Render_Engine *re)
|
|
|
|
{
|
|
|
|
return re->generic.software.ob;
|
|
|
|
}
|
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
/* local functions */
|
|
|
|
static void
|
|
|
|
gl_symbols(void)
|
|
|
|
{
|
|
|
|
static Eina_Bool done = EINA_FALSE;
|
|
|
|
|
|
|
|
if (done) return;
|
|
|
|
|
|
|
|
#define LINK2GENERIC(sym) \
|
|
|
|
glsym_##sym = dlsym(RTLD_DEFAULT, #sym);
|
|
|
|
|
|
|
|
// Get function pointer to evas_gl_common that is now provided through the link of GL_Generic.
|
|
|
|
LINK2GENERIC(evas_gl_common_image_all_unload);
|
|
|
|
LINK2GENERIC(evas_gl_common_image_ref);
|
|
|
|
LINK2GENERIC(evas_gl_common_image_unref);
|
|
|
|
LINK2GENERIC(evas_gl_common_image_new_from_data);
|
|
|
|
LINK2GENERIC(evas_gl_common_image_native_disable);
|
|
|
|
LINK2GENERIC(evas_gl_common_image_free);
|
|
|
|
LINK2GENERIC(evas_gl_common_image_native_enable);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_new);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_flush);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_free);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_use);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_newframe);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_done);
|
|
|
|
LINK2GENERIC(evas_gl_common_context_resize);
|
|
|
|
LINK2GENERIC(evas_gl_common_buffer_dump);
|
|
|
|
LINK2GENERIC(evas_gl_preload_render_lock);
|
|
|
|
LINK2GENERIC(evas_gl_preload_render_unlock);
|
|
|
|
LINK2GENERIC(evas_gl_preload_render_relax);
|
|
|
|
LINK2GENERIC(evas_gl_preload_init);
|
|
|
|
LINK2GENERIC(evas_gl_preload_shutdown);
|
|
|
|
LINK2GENERIC(evgl_engine_shutdown);
|
|
|
|
LINK2GENERIC(evas_gl_symbols);
|
|
|
|
|
|
|
|
#define FINDSYM(dst, sym, typ) \
|
|
|
|
if (glsym_eglGetProcAddress) { \
|
|
|
|
if (!dst) dst = (typ)glsym_eglGetProcAddress(sym); \
|
|
|
|
} else { \
|
|
|
|
if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym); \
|
|
|
|
}
|
|
|
|
|
|
|
|
FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressKHR", glsym_func_eng_fn);
|
|
|
|
FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressEXT", glsym_func_eng_fn);
|
|
|
|
FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressARB", glsym_func_eng_fn);
|
|
|
|
FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddress", glsym_func_eng_fn);
|
|
|
|
|
|
|
|
glsym_evas_gl_symbols((void*)glsym_eglGetProcAddress);
|
|
|
|
|
|
|
|
FINDSYM(glsym_eglCreateImage, "eglCreateImageKHR", glsym_func_void_ptr);
|
|
|
|
FINDSYM(glsym_eglCreateImage, "eglCreateImageEXT", glsym_func_void_ptr);
|
|
|
|
FINDSYM(glsym_eglCreateImage, "eglCreateImageARB", glsym_func_void_ptr);
|
|
|
|
FINDSYM(glsym_eglCreateImage, "eglCreateImage", glsym_func_void_ptr);
|
|
|
|
|
|
|
|
FINDSYM(glsym_eglDestroyImage, "eglDestroyImageKHR", glsym_func_void);
|
|
|
|
FINDSYM(glsym_eglDestroyImage, "eglDestroyImageEXT", glsym_func_void);
|
|
|
|
FINDSYM(glsym_eglDestroyImage, "eglDestroyImageARB", glsym_func_void);
|
|
|
|
FINDSYM(glsym_eglDestroyImage, "eglDestroyImage", glsym_func_void);
|
|
|
|
|
|
|
|
FINDSYM(glsym_glEGLImageTargetTexture2DOES,
|
|
|
|
"glEGLImageTargetTexture2DOES", glsym_func_void);
|
|
|
|
|
|
|
|
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageEXT",
|
|
|
|
glsym_func_uint);
|
|
|
|
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageINTEL",
|
|
|
|
glsym_func_uint);
|
|
|
|
FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamage",
|
|
|
|
glsym_func_uint);
|
|
|
|
|
2015-11-04 08:18:25 -08:00
|
|
|
FINDSYM(glsym_eglSetDamageRegionKHR, "eglSetDamageRegionKHR",
|
|
|
|
glsym_func_uint);
|
|
|
|
|
2014-12-04 00:59:30 -08:00
|
|
|
FINDSYM(glsym_eglQueryWaylandBufferWL, "eglQueryWaylandBufferWL",
|
|
|
|
glsym_func_uint);
|
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
done = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gl_extn_veto(Render_Engine *re)
|
|
|
|
{
|
|
|
|
const char *str = NULL;
|
2015-06-03 09:56:35 -07:00
|
|
|
|
|
|
|
str = eglQueryString(eng_get_ob(re)->egl.disp, EGL_EXTENSIONS);
|
2014-08-21 02:22:16 -07:00
|
|
|
if (str)
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
const char *s = NULL;
|
|
|
|
|
|
|
|
if (getenv("EVAS_GL_INFO")) printf("EGL EXTN:\n%s\n", str);
|
|
|
|
|
2015-03-23 17:30:59 -07:00
|
|
|
// Disable Partial Rendering
|
2015-06-03 09:56:35 -07:00
|
|
|
s = getenv("EVAS_GL_PARTIAL_DISABLE");
|
|
|
|
if ((s) && (atoi(s)))
|
2015-03-23 17:30:59 -07:00
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
_extn_have_buffer_age = 0;
|
2015-03-23 17:30:59 -07:00
|
|
|
glsym_eglSwapBuffersWithDamage = NULL;
|
2015-11-04 08:18:25 -08:00
|
|
|
glsym_eglSetDamageRegionKHR = NULL;
|
|
|
|
}
|
|
|
|
if (!strstr(str, "EGL_EXT_buffer_age"))
|
|
|
|
{
|
|
|
|
if (!strstr(str, "EGL_KHR_partial_update"))
|
|
|
|
_extn_have_buffer_age = 0;
|
2015-03-23 17:30:59 -07:00
|
|
|
}
|
2015-11-04 08:18:25 -08:00
|
|
|
|
|
|
|
if (!strstr(str, "EGL_KHR_partial_update"))
|
|
|
|
glsym_eglSetDamageRegionKHR = NULL;
|
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!strstr(str, "EGL_EXT_swap_buffers_with_damage"))
|
2014-10-22 06:18:05 -07:00
|
|
|
glsym_eglSwapBuffersWithDamage = NULL;
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
if (getenv("EVAS_GL_INFO")) printf("NO EGL EXTN!\n");
|
|
|
|
_extn_have_buffer_age = 0;
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
evgl_eng_display_get(void *data)
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
Render_Engine *re;
|
2014-08-21 02:22:16 -07:00
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
re = (Render_Engine *)data;
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (eng_get_ob(re))
|
2015-06-04 08:52:22 -07:00
|
|
|
return (void *)eng_get_ob(re)->egl.disp;
|
2014-08-21 02:22:16 -07:00
|
|
|
else
|
2014-08-21 07:22:51 -07:00
|
|
|
return NULL;
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
evgl_eng_evas_surface_get(void *data)
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
Render_Engine *re;
|
2014-08-21 02:22:16 -07:00
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
re = (Render_Engine *)data;
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (eng_get_ob(re))
|
2015-06-04 08:52:22 -07:00
|
|
|
return (void *)eng_get_ob(re)->egl.surface[0];
|
2014-08-21 02:22:16 -07:00
|
|
|
else
|
2014-08-21 07:22:51 -07:00
|
|
|
return NULL;
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
evgl_eng_make_current(void *data, void *surface, void *context, int flush)
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
Render_Engine *re;
|
2014-08-21 02:22:16 -07:00
|
|
|
EGLContext ctx;
|
|
|
|
EGLSurface sfc;
|
|
|
|
EGLDisplay dpy;
|
|
|
|
int ret = 0;
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
re = (Render_Engine *)data;
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
dpy = eng_get_ob(re)->egl.disp;
|
2014-08-21 02:22:16 -07:00
|
|
|
ctx = (EGLContext)context;
|
|
|
|
sfc = (EGLSurface)surface;
|
|
|
|
|
|
|
|
if ((!context) && (!surface))
|
|
|
|
{
|
|
|
|
ret = eglMakeCurrent(dpy, EGL_NO_SURFACE,
|
|
|
|
EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
|
|
if (!ret)
|
|
|
|
{
|
|
|
|
ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError());
|
|
|
|
return 0;
|
|
|
|
}
|
2015-06-03 09:56:35 -07:00
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((eglGetCurrentContext() != ctx) ||
|
|
|
|
(eglGetCurrentSurface(EGL_READ) != sfc) ||
|
|
|
|
(eglGetCurrentSurface(EGL_DRAW) != sfc) )
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
if (flush) evas_outbuf_use(NULL);
|
2014-08-21 02:22:16 -07:00
|
|
|
|
|
|
|
ret = eglMakeCurrent(dpy, sfc, sfc, ctx);
|
|
|
|
if (!ret)
|
|
|
|
{
|
|
|
|
ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError());
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
evgl_eng_native_window_create(void *data)
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
Render_Engine *re;
|
2014-08-21 02:22:16 -07:00
|
|
|
struct gbm_surface *surface;
|
|
|
|
Evas_Engine_Info_GL_Drm *info;
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
re = (Render_Engine *)data;
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
info = eng_get_ob(re)->info;
|
|
|
|
if (!info)
|
|
|
|
{
|
|
|
|
ERR("Invalid Evas Engine GL_DRM Info!");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-06-12 08:48:30 -07:00
|
|
|
surface = gbm_surface_create(info->info.gbm,
|
|
|
|
eng_get_ob(re)->w, eng_get_ob(re)->h,
|
|
|
|
info->info.format, info->info.flags);
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!surface)
|
2015-06-03 09:56:35 -07:00
|
|
|
{
|
|
|
|
ERR("Could not create gl drm window: %m");
|
|
|
|
return NULL;
|
|
|
|
}
|
2014-08-21 02:22:16 -07:00
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
return (void *)surface;
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
evgl_eng_native_window_destroy(void *data, void *native_window)
|
|
|
|
{
|
|
|
|
Render_Engine *re = (Render_Engine *)data;
|
|
|
|
|
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!native_window)
|
|
|
|
{
|
|
|
|
ERR("Inavlid native surface.");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
gbm_surface_destroy((struct gbm_surface *)native_window);
|
2015-06-04 08:52:22 -07:00
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
evgl_eng_window_surface_create(void *data, void *native_window)
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
Render_Engine *re;
|
2014-08-21 02:22:16 -07:00
|
|
|
EGLSurface surface = EGL_NO_SURFACE;
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
re = (Render_Engine *)data;
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create resource surface for EGL
|
2015-06-03 09:56:35 -07:00
|
|
|
surface = eglCreateWindowSurface(eng_get_ob(re)->egl.disp,
|
|
|
|
eng_get_ob(re)->egl.config,
|
2014-08-21 02:22:16 -07:00
|
|
|
(EGLNativeWindowType)native_window,
|
|
|
|
NULL);
|
|
|
|
if (!surface)
|
|
|
|
{
|
|
|
|
ERR("Creating window surface failed. Error: %#x.", eglGetError());
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
return (void *)surface;
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
evgl_eng_window_surface_destroy(void *data, void *surface)
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
Render_Engine *re;
|
2014-08-21 02:22:16 -07:00
|
|
|
EGLBoolean ret = EGL_FALSE;
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
re = (Render_Engine *)data;
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!surface)
|
|
|
|
{
|
|
|
|
ERR("Invalid surface.");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
ret = eglDestroySurface(eng_get_ob(re)->egl.disp, (EGLSurface)surface);
|
2014-08-21 02:22:16 -07:00
|
|
|
if (ret == EGL_TRUE) return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2014-10-24 05:37:51 -07:00
|
|
|
evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version version)
|
2014-08-21 02:22:16 -07:00
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
Render_Engine *re;
|
2014-08-21 02:22:16 -07:00
|
|
|
EGLContext context = EGL_NO_CONTEXT;
|
|
|
|
int context_attrs[3];
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
re = (Render_Engine *)data;
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-09-22 03:15:37 -07:00
|
|
|
if (version != EVAS_GL_GLES_2_X)
|
|
|
|
{
|
|
|
|
ERR("This engine only supports OpenGL-ES 2.0 contexts for now!");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
|
|
|
|
context_attrs[1] = 2;
|
|
|
|
context_attrs[2] = EGL_NONE;
|
|
|
|
|
|
|
|
// Share context already assumes that it's sharing with evas' context
|
|
|
|
if (share_ctx)
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
context = eglCreateContext(eng_get_ob(re)->egl.disp,
|
|
|
|
eng_get_ob(re)->egl.config,
|
2014-08-21 02:22:16 -07:00
|
|
|
(EGLContext)share_ctx,
|
|
|
|
context_attrs);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
context = eglCreateContext(eng_get_ob(re)->egl.disp,
|
|
|
|
eng_get_ob(re)->egl.config,
|
|
|
|
eng_get_ob(re)->egl.context[0], // Evas' GL Context
|
2014-08-21 02:22:16 -07:00
|
|
|
context_attrs);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!context)
|
|
|
|
{
|
2015-06-04 08:52:22 -07:00
|
|
|
ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError());
|
2014-08-21 02:22:16 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
return (void *)context;
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
evgl_eng_context_destroy(void *data, void *context)
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
Render_Engine *re;
|
2014-08-21 02:22:16 -07:00
|
|
|
EGLBoolean ret = EGL_FALSE;
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
re = (Render_Engine *)data;
|
2014-08-21 02:22:16 -07:00
|
|
|
if ((!re) || (!context))
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
ERR("Invalid Render Input Data. Engine: %p, Context: %p",
|
|
|
|
data, context);
|
2014-08-21 02:22:16 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
ret = eglDestroyContext(eng_get_ob(re)->egl.disp, (EGLContext)context);
|
2014-08-21 02:22:16 -07:00
|
|
|
if (ret == EGL_TRUE) return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
evgl_eng_string_get(void *data)
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
Render_Engine *re;
|
2014-08-21 02:22:16 -07:00
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
re = (Render_Engine *)data;
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
return eglQueryString(eng_get_ob(re)->egl.disp, EGL_EXTENSIONS);
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
evgl_eng_proc_address_get(const char *name)
|
|
|
|
{
|
|
|
|
if (glsym_eglGetProcAddress) return glsym_eglGetProcAddress(name);
|
|
|
|
return dlsym(RTLD_DEFAULT, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
evgl_eng_rotation_angle_get(void *data)
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
Render_Engine *re;
|
2014-08-21 02:22:16 -07:00
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
re = (Render_Engine *)data;
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!re)
|
|
|
|
{
|
|
|
|
ERR("Invalid Render Engine Data!");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((eng_get_ob(re)) && (eng_get_ob(re)->gl_context))
|
2014-08-21 07:22:51 -07:00
|
|
|
return eng_get_ob(re)->gl_context->rot;
|
2014-08-21 02:22:16 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR("Unable to retrieve rotation angle.");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
static Eina_Bool
|
|
|
|
eng_preload_make_current(void *data, void *doit)
|
|
|
|
{
|
|
|
|
Outbuf *ob;
|
|
|
|
|
|
|
|
ob = (Outbuf *)data;
|
|
|
|
if (!ob) return EINA_FALSE;
|
|
|
|
|
|
|
|
if (doit)
|
|
|
|
{
|
|
|
|
if (!eglMakeCurrent(ob->egl.disp, ob->egl.surface[0],
|
|
|
|
ob->egl.surface[0], ob->egl.context[0]))
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!eglMakeCurrent(ob->egl.disp, EGL_NO_SURFACE,
|
|
|
|
EGL_NO_SURFACE, EGL_NO_CONTEXT))
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
static void
|
|
|
|
_re_winfree(Render_Engine *re)
|
|
|
|
{
|
|
|
|
if (!re) return;
|
|
|
|
if (!eng_get_ob(re)->surf) return;
|
|
|
|
glsym_evas_gl_preload_render_relax(eng_preload_make_current, eng_get_ob(re));
|
2015-06-03 09:56:35 -07:00
|
|
|
evas_outbuf_unsurf(eng_get_ob(re));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_native_cb_bind(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *img;
|
|
|
|
Native *n;
|
|
|
|
|
|
|
|
if (!(img = image)) return;
|
|
|
|
if (!(n = img->native.data)) return;
|
|
|
|
|
|
|
|
if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
|
|
|
|
{
|
|
|
|
if (n->egl_surface)
|
|
|
|
{
|
|
|
|
if (glsym_glEGLImageTargetTexture2DOES)
|
|
|
|
{
|
|
|
|
glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->egl_surface);
|
|
|
|
if (eglGetError() != EGL_SUCCESS)
|
|
|
|
ERR("glEGLImageTargetTexture2DOES() failed.");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
|
2015-06-04 08:52:22 -07:00
|
|
|
|
|
|
|
/* TODO: NATIVE_SURFACE_TBM and NATIVE_SURFACE_EVASGL */
|
2015-06-03 09:56:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_native_cb_unbind(void *data EINA_UNUSED, void *image)
|
|
|
|
{
|
|
|
|
Evas_GL_Image *img;
|
|
|
|
Native *n;
|
|
|
|
|
|
|
|
if (!(img = image)) return;
|
|
|
|
if (!(n = img->native.data)) return;
|
|
|
|
|
|
|
|
if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
|
|
|
|
{
|
|
|
|
//glBindTexture(GL_TEXTURE_2D, 0); //really need?
|
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
2015-06-04 08:52:22 -07:00
|
|
|
|
|
|
|
/* TODO: NATIVE_SURFACE_TBM and NATIVE_SURFACE_EVASGL */
|
2015-06-03 09:56:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_native_cb_free(void *data, void *image)
|
|
|
|
{
|
|
|
|
Render_Engine *re;
|
|
|
|
Outbuf *ob;
|
|
|
|
Evas_GL_Image *img;
|
|
|
|
Native *n;
|
|
|
|
uint32_t texid;
|
|
|
|
void *wlid;
|
|
|
|
|
|
|
|
if (!(re = (Render_Engine *)data)) return;
|
|
|
|
if (!(img = image)) return;
|
|
|
|
if (!(n = img->native.data)) return;
|
|
|
|
if (!(ob = eng_get_ob(re))) return;
|
|
|
|
|
|
|
|
if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
|
|
|
|
{
|
|
|
|
wlid = (void*)n->wl_buf;
|
|
|
|
eina_hash_del(ob->gl_context->shared->native_wl_hash, &wlid, img);
|
|
|
|
if (n->egl_surface)
|
|
|
|
{
|
|
|
|
if (glsym_eglDestroyImage)
|
|
|
|
{
|
|
|
|
glsym_eglDestroyImage(ob->egl.disp, n->egl_surface);
|
|
|
|
if (eglGetError() != EGL_SUCCESS)
|
|
|
|
ERR("eglDestroyImage() failed.");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ERR("Try eglDestroyImage on EGL with no support");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
texid = n->ns.data.opengl.texture_id;
|
|
|
|
eina_hash_del(ob->gl_context->shared->native_tex_hash, &texid, img);
|
|
|
|
}
|
|
|
|
|
|
|
|
img->native.data = NULL;
|
|
|
|
img->native.func.data = NULL;
|
|
|
|
img->native.func.bind = NULL;
|
|
|
|
img->native.func.unbind = NULL;
|
|
|
|
img->native.func.free = NULL;
|
|
|
|
|
|
|
|
free(n);
|
|
|
|
}
|
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
/* engine specific override functions */
|
|
|
|
static void *
|
|
|
|
eng_info(Evas *eo_e EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Evas_Engine_Info_GL_Drm *info;
|
|
|
|
|
|
|
|
/* try to allocate space for our engine info */
|
|
|
|
if (!(info = calloc(1, sizeof(Evas_Engine_Info_GL_Drm))))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
info->magic.magic = rand();
|
|
|
|
info->render_mode = EVAS_RENDER_MODE_BLOCKING;
|
|
|
|
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_info_free(Evas *eo_e EINA_UNUSED, void *in)
|
|
|
|
{
|
|
|
|
Evas_Engine_Info_GL_Drm *info;
|
|
|
|
|
2014-09-04 00:58:23 -07:00
|
|
|
if ((info = (Evas_Engine_Info_GL_Drm *)in))
|
2014-08-21 02:22:16 -07:00
|
|
|
free(info);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2015-06-03 09:56:35 -07:00
|
|
|
eng_setup(Evas *evas, void *in)
|
2014-08-21 02:22:16 -07:00
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
Evas_Engine_Info_GL_Drm *info;
|
|
|
|
Evas_Public_Data *epd;
|
|
|
|
Render_Engine *re;
|
2014-08-21 02:22:16 -07:00
|
|
|
Render_Engine_Swap_Mode swap_mode = MODE_FULL;
|
2015-06-03 09:56:35 -07:00
|
|
|
const char *s = NULL;
|
2014-08-21 02:22:16 -07:00
|
|
|
|
|
|
|
/* try to cast to our engine info structure */
|
|
|
|
if (!(info = (Evas_Engine_Info_GL_Drm *)in)) return 0;
|
|
|
|
|
|
|
|
/* try to get the evas public data */
|
2015-06-03 09:56:35 -07:00
|
|
|
if (!(epd = eo_data_scope_get(evas, EVAS_CANVAS_CLASS))) return 0;
|
2014-08-21 02:22:16 -07:00
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
s = getenv("EVAS_GL_SWAP_MODE");
|
|
|
|
if (s)
|
2014-08-21 02:22:16 -07:00
|
|
|
{
|
2014-08-21 07:22:51 -07:00
|
|
|
if ((!strcasecmp(s, "full")) || (!strcasecmp(s, "f")))
|
2014-08-21 02:22:16 -07:00
|
|
|
swap_mode = MODE_FULL;
|
2014-08-21 07:22:51 -07:00
|
|
|
else if ((!strcasecmp(s, "copy")) || (!strcasecmp(s, "c")))
|
2014-08-21 02:22:16 -07:00
|
|
|
swap_mode = MODE_COPY;
|
|
|
|
else if ((!strcasecmp(s, "double")) ||
|
2014-08-21 07:22:51 -07:00
|
|
|
(!strcasecmp(s, "d")) || (!strcasecmp(s, "2")))
|
2014-08-21 02:22:16 -07:00
|
|
|
swap_mode = MODE_DOUBLE;
|
|
|
|
else if ((!strcasecmp(s, "triple")) ||
|
2014-08-21 07:22:51 -07:00
|
|
|
(!strcasecmp(s, "t")) || (!strcasecmp(s, "3")))
|
2014-08-21 02:22:16 -07:00
|
|
|
swap_mode = MODE_TRIPLE;
|
|
|
|
else if ((!strcasecmp(s, "quadruple")) ||
|
2014-08-21 07:22:51 -07:00
|
|
|
(!strcasecmp(s, "q")) || (!strcasecmp(s, "4")))
|
2014-08-21 02:22:16 -07:00
|
|
|
swap_mode = MODE_QUADRUPLE;
|
|
|
|
}
|
2015-06-12 08:48:30 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// in most gl implementations - egl and glx here that we care about the TEND
|
|
|
|
// to either swap or copy backbuffer and front buffer, but strictly that is
|
|
|
|
// not true. technically backbuffer content is totally undefined after a swap
|
|
|
|
// and thus you MUST re-render all of it, thus MODE_FULL
|
|
|
|
swap_mode = MODE_FULL;
|
|
|
|
// BUT... reality is that lmost every implementation copies or swaps so
|
|
|
|
// triple buffer mode can be used as it is a superset of double buffer and
|
|
|
|
// copy (though using those explicitly is more efficient). so let's play with
|
|
|
|
// triple buffer mdoe as a default and see.
|
|
|
|
// re->mode = MODE_TRIPLE;
|
|
|
|
// XXX: note - the above seems to break on some older intel chipsets and
|
|
|
|
// drivers. it seems we CANT depend on backbuffer staying around. bugger!
|
|
|
|
switch (info->info.swap_mode)
|
|
|
|
{
|
|
|
|
case EVAS_ENGINE_GL_DRM_SWAP_MODE_FULL:
|
|
|
|
swap_mode = MODE_FULL;
|
|
|
|
break;
|
|
|
|
case EVAS_ENGINE_GL_DRM_SWAP_MODE_COPY:
|
|
|
|
swap_mode = MODE_COPY;
|
|
|
|
break;
|
|
|
|
case EVAS_ENGINE_GL_DRM_SWAP_MODE_DOUBLE:
|
|
|
|
swap_mode = MODE_DOUBLE;
|
|
|
|
break;
|
|
|
|
case EVAS_ENGINE_GL_DRM_SWAP_MODE_TRIPLE:
|
|
|
|
swap_mode = MODE_TRIPLE;
|
|
|
|
break;
|
|
|
|
case EVAS_ENGINE_GL_DRM_SWAP_MODE_QUADRUPLE:
|
|
|
|
swap_mode = MODE_QUADRUPLE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
swap_mode = MODE_AUTO;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-08-21 02:22:16 -07:00
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
if (!(re = epd->engine.data.output))
|
2014-08-21 02:22:16 -07:00
|
|
|
{
|
|
|
|
Outbuf *ob;
|
2015-10-01 06:00:44 -07:00
|
|
|
Render_Engine_Merge_Mode merge_mode = MERGE_SMART;
|
2014-08-21 02:22:16 -07:00
|
|
|
|
|
|
|
if (!initted)
|
|
|
|
{
|
2015-02-20 06:04:52 -08:00
|
|
|
evas_common_init();
|
2014-08-21 02:22:16 -07:00
|
|
|
glsym_evas_gl_preload_init();
|
|
|
|
}
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
if (!(re = calloc(1, sizeof(Render_Engine)))) return 0;
|
2014-08-21 02:22:16 -07:00
|
|
|
|
2015-06-12 08:48:30 -07:00
|
|
|
if (!eng_gbm_init(info))
|
2015-06-03 09:56:35 -07:00
|
|
|
{
|
|
|
|
free(re);
|
|
|
|
return 0;
|
|
|
|
}
|
2014-08-21 02:22:16 -07:00
|
|
|
|
|
|
|
/* try to create new outbuf */
|
2015-06-03 09:56:35 -07:00
|
|
|
ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode);
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!ob)
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
eng_gbm_shutdown(info);
|
2014-08-21 02:22:16 -07:00
|
|
|
free(re);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-06-03 11:30:10 -07:00
|
|
|
ob->evas = evas;
|
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!evas_render_engine_gl_generic_init(&re->generic, ob,
|
2015-06-03 09:56:35 -07:00
|
|
|
evas_outbuf_buffer_state_get,
|
|
|
|
evas_outbuf_rot_get,
|
|
|
|
evas_outbuf_reconfigure,
|
|
|
|
evas_outbuf_update_region_first_rect,
|
|
|
|
evas_outbuf_update_region_new,
|
|
|
|
evas_outbuf_update_region_push,
|
|
|
|
evas_outbuf_update_region_free,
|
2014-08-21 02:22:16 -07:00
|
|
|
NULL,
|
2015-06-03 09:56:35 -07:00
|
|
|
evas_outbuf_flush,
|
|
|
|
evas_outbuf_free,
|
|
|
|
evas_outbuf_use,
|
|
|
|
evas_outbuf_gl_context_get,
|
|
|
|
evas_outbuf_egl_display_get,
|
|
|
|
evas_outbuf_gl_context_new,
|
|
|
|
evas_outbuf_gl_context_use,
|
|
|
|
&evgl_funcs, ob->w, ob->h))
|
2014-08-21 02:22:16 -07:00
|
|
|
{
|
|
|
|
/* free outbuf */
|
2015-06-03 09:56:35 -07:00
|
|
|
evas_outbuf_free(ob);
|
2015-06-12 08:48:30 -07:00
|
|
|
eng_gbm_shutdown(info);
|
2014-08-21 02:22:16 -07:00
|
|
|
free(re);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
epd->engine.data.output = re;
|
|
|
|
gl_wins++;
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
s = getenv("EVAS_GL_PARTIAL_MERGE");
|
|
|
|
if (s)
|
2014-08-21 02:22:16 -07:00
|
|
|
{
|
2014-08-21 07:22:51 -07:00
|
|
|
if ((!strcmp(s, "bounding")) || (!strcmp(s, "b")))
|
2014-08-21 02:22:16 -07:00
|
|
|
merge_mode = MERGE_BOUNDING;
|
2014-08-21 07:22:51 -07:00
|
|
|
else if ((!strcmp(s, "full")) || (!strcmp(s, "f")))
|
2014-08-21 02:22:16 -07:00
|
|
|
merge_mode = MERGE_FULL;
|
2015-10-01 06:00:44 -07:00
|
|
|
else if ((!strcmp(s, "smart")) || (!strcmp(s, "s")))
|
|
|
|
merge_mode = MERGE_SMART;
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
evas_render_engine_software_generic_merge_mode_set(&re->generic.software, merge_mode);
|
|
|
|
|
|
|
|
if (!initted)
|
|
|
|
{
|
|
|
|
gl_extn_veto(re);
|
|
|
|
initted = EINA_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (eng_get_ob(re) && _re_wincheck(eng_get_ob(re)))
|
|
|
|
{
|
2015-06-12 08:48:30 -07:00
|
|
|
if ((info->info.depth != eng_get_ob(re)->depth) ||
|
2015-06-03 09:56:35 -07:00
|
|
|
(info->info.destination_alpha != eng_get_ob(re)->destination_alpha))
|
2014-08-21 02:22:16 -07:00
|
|
|
{
|
2015-06-04 08:52:22 -07:00
|
|
|
Outbuf *ob, *ob_old;
|
2014-08-21 02:22:16 -07:00
|
|
|
|
2015-06-04 08:52:22 -07:00
|
|
|
ob_old = re->generic.software.ob;
|
|
|
|
re->generic.software.ob = NULL;
|
2014-08-21 02:22:16 -07:00
|
|
|
gl_wins--;
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode);
|
2015-06-04 08:52:22 -07:00
|
|
|
if (!ob)
|
|
|
|
{
|
|
|
|
if (ob_old) evas_outbuf_free(ob_old);
|
|
|
|
free(re);
|
|
|
|
return 0;
|
|
|
|
}
|
2014-08-21 02:22:16 -07:00
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
evas_outbuf_use(ob);
|
2015-06-04 08:52:22 -07:00
|
|
|
if (ob_old) evas_outbuf_free(ob_old);
|
2015-06-03 11:30:10 -07:00
|
|
|
|
2015-06-04 08:52:22 -07:00
|
|
|
ob->evas = evas;
|
2014-08-21 02:22:16 -07:00
|
|
|
|
2015-06-04 08:52:22 -07:00
|
|
|
evas_render_engine_software_generic_update(&re->generic.software, ob,
|
|
|
|
epd->output.w, epd->output.h);
|
|
|
|
|
|
|
|
gl_wins++;
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
else if ((eng_get_ob(re)->w != epd->output.w) ||
|
|
|
|
(eng_get_ob(re)->h != epd->output.h) ||
|
2015-06-03 09:56:35 -07:00
|
|
|
(info->info.rotation != eng_get_ob(re)->rotation))
|
2014-08-21 02:22:16 -07:00
|
|
|
{
|
2015-06-04 08:52:22 -07:00
|
|
|
evas_outbuf_reconfigure(eng_get_ob(re),
|
|
|
|
epd->output.w, epd->output.h,
|
|
|
|
info->info.rotation,
|
|
|
|
info->info.depth);
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-08-21 07:22:51 -07:00
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
if (!eng_get_ob(re))
|
|
|
|
{
|
|
|
|
free(re);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!epd->engine.data.output)
|
|
|
|
{
|
|
|
|
if (eng_get_ob(re))
|
|
|
|
{
|
2015-06-03 09:56:35 -07:00
|
|
|
evas_outbuf_free(eng_get_ob(re));
|
2014-08-21 02:22:16 -07:00
|
|
|
gl_wins--;
|
2015-06-03 09:56:35 -07:00
|
|
|
eng_gbm_shutdown(info);
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
free(re);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-06-12 08:48:30 -07:00
|
|
|
if (re->generic.software.tb)
|
|
|
|
evas_common_tilebuf_free(re->generic.software.tb);
|
|
|
|
re->generic.software.tb =
|
|
|
|
evas_common_tilebuf_new(epd->output.w, epd->output.h);
|
|
|
|
if (re->generic.software.tb)
|
|
|
|
evas_common_tilebuf_set_tile_size(re->generic.software.tb,
|
|
|
|
TILESIZE, TILESIZE);
|
|
|
|
|
2015-06-04 08:52:22 -07:00
|
|
|
if (re->generic.software.tb)
|
|
|
|
evas_render_engine_software_generic_tile_strict_set(&re->generic.software, EINA_TRUE);
|
2014-08-21 02:22:16 -07:00
|
|
|
|
|
|
|
if (!epd->engine.data.context)
|
|
|
|
{
|
|
|
|
epd->engine.data.context =
|
|
|
|
epd->engine.func->context_new(epd->engine.data.output);
|
|
|
|
}
|
2014-08-21 07:22:51 -07:00
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
evas_outbuf_use(eng_get_ob(re));
|
2014-08-21 02:22:16 -07:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_output_free(void *data)
|
|
|
|
{
|
|
|
|
Render_Engine *re;
|
|
|
|
|
|
|
|
re = (Render_Engine *)data;
|
|
|
|
if (re)
|
|
|
|
{
|
2015-11-02 13:07:52 -08:00
|
|
|
Evas_Engine_Info_GL_Drm *info;
|
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
glsym_evas_gl_preload_render_relax(eng_preload_make_current, eng_get_ob(re));
|
|
|
|
|
|
|
|
if (gl_wins == 1) glsym_evgl_engine_shutdown(re);
|
|
|
|
|
2015-11-02 13:07:52 -08:00
|
|
|
info = eng_get_ob(re)->info;
|
2015-06-03 09:56:35 -07:00
|
|
|
/* NB: evas_render_engine_software_generic_clean() frees ob */
|
2014-08-21 02:22:16 -07:00
|
|
|
evas_render_engine_software_generic_clean(&re->generic.software);
|
|
|
|
|
2015-11-02 13:07:52 -08:00
|
|
|
eng_gbm_shutdown(info);
|
2014-08-21 02:22:16 -07:00
|
|
|
gl_wins--;
|
|
|
|
|
|
|
|
free(re);
|
|
|
|
}
|
2015-06-03 09:56:35 -07:00
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
if ((initted == EINA_TRUE) && (gl_wins == 0))
|
|
|
|
{
|
|
|
|
glsym_evas_gl_preload_shutdown();
|
2015-02-23 02:35:29 -08:00
|
|
|
evas_common_shutdown();
|
2014-08-21 02:22:16 -07:00
|
|
|
initted = EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
eng_canvas_alpha_get(void *data, void *info EINA_UNUSED)
|
|
|
|
{
|
2014-10-22 06:18:05 -07:00
|
|
|
Render_Engine *re;
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
re = (Render_Engine *)data;
|
|
|
|
if (!re) return EINA_FALSE;
|
2014-08-21 02:22:16 -07:00
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
return eng_get_ob(re)->destination_alpha;
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
eng_output_dump(void *data)
|
|
|
|
{
|
|
|
|
Render_Engine *re;
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
re = (Render_Engine *)data;
|
|
|
|
if (!re) return;
|
2014-10-22 06:18:05 -07:00
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
evas_common_image_image_all_unload();
|
|
|
|
evas_common_font_font_all_unload();
|
|
|
|
glsym_evas_gl_common_image_all_unload(eng_get_ob(re)->gl_context);
|
|
|
|
_re_winfree(re);
|
|
|
|
}
|
|
|
|
|
2014-12-04 00:59:30 -08:00
|
|
|
static void *
|
|
|
|
eng_image_native_set(void *data, void *image, void *native)
|
|
|
|
{
|
|
|
|
Render_Engine *re;
|
|
|
|
Outbuf *ob;
|
|
|
|
Native *n;
|
|
|
|
Evas_Native_Surface *ns;
|
|
|
|
Evas_GL_Image *img, *img2;
|
|
|
|
unsigned int tex = 0, fbo = 0;
|
|
|
|
uint32_t texid;
|
2015-06-03 09:56:35 -07:00
|
|
|
void *wlid, *wl_buf = NULL;
|
|
|
|
|
|
|
|
re = (Render_Engine *)data;
|
|
|
|
if (!re) return NULL;
|
2014-12-04 00:59:30 -08:00
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
ob = eng_get_ob(re);
|
|
|
|
if (!ob) return NULL;
|
2014-12-04 00:59:30 -08:00
|
|
|
|
|
|
|
ns = native;
|
|
|
|
|
|
|
|
if (!(img = image))
|
|
|
|
{
|
|
|
|
if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL))
|
|
|
|
{
|
|
|
|
img =
|
|
|
|
glsym_evas_gl_common_image_new_from_data(ob->gl_context,
|
|
|
|
ns->data.opengl.w,
|
|
|
|
ns->data.opengl.h,
|
|
|
|
NULL, 1,
|
|
|
|
EVAS_COLORSPACE_ARGB8888);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ns)
|
|
|
|
{
|
|
|
|
if (ns->type == EVAS_NATIVE_SURFACE_WL)
|
|
|
|
{
|
|
|
|
wl_buf = ns->data.wl.legacy_buffer;
|
|
|
|
if (img->native.data)
|
|
|
|
{
|
|
|
|
Evas_Native_Surface *ens;
|
|
|
|
|
|
|
|
ens = img->native.data;
|
|
|
|
if (ens->data.wl.legacy_buffer == wl_buf)
|
|
|
|
return img;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
tex = ns->data.opengl.texture_id;
|
|
|
|
fbo = ns->data.opengl.framebuffer_id;
|
|
|
|
if (img->native.data)
|
|
|
|
{
|
|
|
|
Evas_Native_Surface *ens;
|
|
|
|
|
|
|
|
ens = img->native.data;
|
|
|
|
if ((ens->data.opengl.texture_id == tex) &&
|
|
|
|
(ens->data.opengl.framebuffer_id == fbo))
|
|
|
|
return img;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((!ns) && (!img->native.data)) return img;
|
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
evas_outbuf_use(ob);
|
2014-12-04 00:59:30 -08:00
|
|
|
|
|
|
|
if (img->native.data)
|
|
|
|
{
|
|
|
|
if (img->native.func.free)
|
|
|
|
img->native.func.free(img->native.func.data, img);
|
|
|
|
glsym_evas_gl_common_image_native_disable(img);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ns) return img;
|
|
|
|
|
|
|
|
if (ns->type == EVAS_NATIVE_SURFACE_WL)
|
|
|
|
{
|
|
|
|
wlid = wl_buf;
|
|
|
|
img2 = eina_hash_find(ob->gl_context->shared->native_wl_hash, &wlid);
|
|
|
|
if (img2 == img) return img;
|
|
|
|
if (img2)
|
|
|
|
{
|
|
|
|
if((n = img2->native.data))
|
|
|
|
{
|
|
|
|
glsym_evas_gl_common_image_ref(img2);
|
|
|
|
glsym_evas_gl_common_image_free(img);
|
|
|
|
return img2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
texid = tex;
|
|
|
|
img2 = eina_hash_find(ob->gl_context->shared->native_tex_hash, &texid);
|
|
|
|
if (img2 == img) return img;
|
|
|
|
if (img2)
|
|
|
|
{
|
|
|
|
if ((n = img2->native.data))
|
|
|
|
{
|
|
|
|
glsym_evas_gl_common_image_ref(img2);
|
|
|
|
glsym_evas_gl_common_image_free(img);
|
|
|
|
return img2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
img2 = glsym_evas_gl_common_image_new_from_data(ob->gl_context, img->w,
|
|
|
|
img->h, NULL, img->alpha,
|
|
|
|
EVAS_COLORSPACE_ARGB8888);
|
|
|
|
glsym_evas_gl_common_image_free(img);
|
|
|
|
|
|
|
|
if (!(img = img2)) return NULL;
|
|
|
|
|
|
|
|
if (ns->type == EVAS_NATIVE_SURFACE_WL)
|
|
|
|
{
|
|
|
|
if (native)
|
|
|
|
{
|
|
|
|
if ((n = calloc(1, sizeof(Native))))
|
|
|
|
{
|
|
|
|
EGLint attribs[3];
|
2014-12-08 02:07:27 -08:00
|
|
|
int format, yinvert = 1;
|
2014-12-04 00:59:30 -08:00
|
|
|
|
2015-06-03 09:56:35 -07:00
|
|
|
glsym_eglQueryWaylandBufferWL(ob->egl.disp, wl_buf,
|
|
|
|
EGL_TEXTURE_FORMAT, &format);
|
|
|
|
if ((format != EGL_TEXTURE_RGB) &&
|
|
|
|
(format != EGL_TEXTURE_RGBA))
|
2014-12-04 00:59:30 -08:00
|
|
|
{
|
|
|
|
ERR("eglQueryWaylandBufferWL() %d format is not supported ", format);
|
|
|
|
glsym_evas_gl_common_image_free(img);
|
|
|
|
free(n);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
attribs[0] = EGL_WAYLAND_PLANE_WL;
|
|
|
|
attribs[1] = 0; //if plane is 1 then 0, if plane is 2 then 1
|
|
|
|
attribs[2] = EGL_NONE;
|
|
|
|
|
|
|
|
memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
|
2015-10-13 11:45:52 -07:00
|
|
|
if (glsym_eglQueryWaylandBufferWL(ob->egl.disp, wl_buf,
|
|
|
|
EGL_WAYLAND_Y_INVERTED_WL,
|
|
|
|
&yinvert) == EGL_FALSE)
|
|
|
|
yinvert = 1;
|
2015-06-03 09:56:35 -07:00
|
|
|
eina_hash_add(ob->gl_context->shared->native_wl_hash,
|
|
|
|
&wlid, img);
|
2014-12-04 00:59:30 -08:00
|
|
|
|
|
|
|
n->wl_buf = wl_buf;
|
|
|
|
if (glsym_eglCreateImage)
|
2015-06-03 09:56:35 -07:00
|
|
|
n->egl_surface = glsym_eglCreateImage(ob->egl.disp,
|
2014-12-04 00:59:30 -08:00
|
|
|
NULL,
|
|
|
|
EGL_WAYLAND_BUFFER_WL,
|
2015-06-03 09:56:35 -07:00
|
|
|
wl_buf, attribs);
|
2014-12-04 00:59:30 -08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR("Try eglCreateImage on EGL with no support");
|
2015-06-03 09:56:35 -07:00
|
|
|
eina_hash_del(ob->gl_context->shared->native_wl_hash,
|
|
|
|
&wlid, img);
|
2014-12-04 00:59:30 -08:00
|
|
|
glsym_evas_gl_common_image_free(img);
|
|
|
|
free(n);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!n->egl_surface)
|
|
|
|
{
|
2015-03-01 07:45:39 -08:00
|
|
|
ERR("eglCreatePixmapSurface() for %p failed", wl_buf);
|
2015-06-03 09:56:35 -07:00
|
|
|
eina_hash_del(ob->gl_context->shared->native_wl_hash,
|
|
|
|
&wlid, img);
|
2014-12-04 00:59:30 -08:00
|
|
|
glsym_evas_gl_common_image_free(img);
|
|
|
|
free(n);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//XXX: workaround for mesa-10.2.8
|
|
|
|
// mesa's eglQueryWaylandBufferWL() with EGL_WAYLAND_Y_INVERTED_WL works incorrect.
|
|
|
|
//img->native.yinvert = yinvert;
|
|
|
|
img->native.yinvert = 1;
|
|
|
|
img->native.loose = 0;
|
|
|
|
img->native.data = n;
|
|
|
|
img->native.func.data = re;
|
|
|
|
img->native.func.bind = _native_cb_bind;
|
|
|
|
img->native.func.unbind = _native_cb_unbind;
|
|
|
|
img->native.func.free = _native_cb_free;
|
|
|
|
img->native.target = GL_TEXTURE_2D;
|
|
|
|
img->native.mipmap = 0;
|
|
|
|
|
|
|
|
glsym_evas_gl_common_image_native_enable(img);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
|
|
|
|
{
|
|
|
|
if (native)
|
|
|
|
{
|
|
|
|
if ((n = calloc(1, sizeof(Native))))
|
|
|
|
{
|
|
|
|
memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
|
2015-06-03 09:56:35 -07:00
|
|
|
eina_hash_add(ob->gl_context->shared->native_tex_hash,
|
|
|
|
&texid, img);
|
2014-12-04 00:59:30 -08:00
|
|
|
|
|
|
|
n->egl_surface = 0;
|
|
|
|
|
|
|
|
img->native.yinvert = 0;
|
|
|
|
img->native.loose = 0;
|
|
|
|
img->native.data = n;
|
|
|
|
img->native.func.data = re;
|
|
|
|
img->native.func.bind = _native_cb_bind;
|
|
|
|
img->native.func.unbind = _native_cb_unbind;
|
|
|
|
img->native.func.free = _native_cb_free;
|
|
|
|
img->native.target = GL_TEXTURE_2D;
|
|
|
|
img->native.mipmap = 0;
|
|
|
|
|
|
|
|
glsym_evas_gl_common_image_native_enable(img);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-04 08:52:22 -07:00
|
|
|
/* TODO: NATIVE_SURFACE_TBM and NATIVE_SURFACE_EVASGL */
|
|
|
|
|
2014-12-04 00:59:30 -08:00
|
|
|
return img;
|
|
|
|
}
|
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
/* module api functions */
|
|
|
|
static int
|
|
|
|
module_open(Evas_Module *em)
|
|
|
|
{
|
|
|
|
/* check for valid evas module */
|
|
|
|
if (!em) return 0;
|
|
|
|
|
|
|
|
/* get whatever engine module we inherit from */
|
|
|
|
if (!_evas_module_engine_inherit(&pfunc, "gl_generic")) return 0;
|
|
|
|
|
|
|
|
/* try to create eina logging domain */
|
|
|
|
if (_evas_engine_gl_drm_log_dom < 0)
|
|
|
|
{
|
2014-08-21 07:22:51 -07:00
|
|
|
_evas_engine_gl_drm_log_dom =
|
|
|
|
eina_log_domain_register("evas-gl-drm", EVAS_DEFAULT_LOG_COLOR);
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* if we could not create a logging domain, error out */
|
|
|
|
if (_evas_engine_gl_drm_log_dom < 0)
|
|
|
|
{
|
|
|
|
EINA_LOG_ERR("Can not create a module log domain.");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* store it for later use */
|
|
|
|
func = pfunc;
|
|
|
|
|
|
|
|
/* now to override methods */
|
2015-06-03 09:56:35 -07:00
|
|
|
EVAS_API_OVERRIDE(info, &func, eng_);
|
|
|
|
EVAS_API_OVERRIDE(info_free, &func, eng_);
|
|
|
|
EVAS_API_OVERRIDE(setup, &func, eng_);
|
|
|
|
EVAS_API_OVERRIDE(canvas_alpha_get, &func, eng_);
|
|
|
|
EVAS_API_OVERRIDE(output_free, &func, eng_);
|
|
|
|
EVAS_API_OVERRIDE(output_dump, &func, eng_);
|
|
|
|
EVAS_API_OVERRIDE(image_native_set, &func, eng_);
|
2014-08-21 02:22:16 -07:00
|
|
|
|
|
|
|
/* Mesa's EGL driver loads wayland egl by default. (called by eglGetProcaddr() )
|
2014-08-21 07:22:51 -07:00
|
|
|
* implicit env set (EGL_PLATFORM=drm) prevent that. */
|
2014-08-21 02:22:16 -07:00
|
|
|
setenv("EGL_PLATFORM", "drm", 1);
|
2015-06-04 08:52:22 -07:00
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
gl_symbols();
|
|
|
|
|
|
|
|
/* now advertise out own api */
|
|
|
|
em->functions = (void *)(&func);
|
2015-06-03 09:56:35 -07:00
|
|
|
|
2014-08-21 02:22:16 -07:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
module_close(Evas_Module *em EINA_UNUSED)
|
|
|
|
{
|
|
|
|
/* unregister the eina log domain for this engine */
|
|
|
|
eina_log_domain_unregister(_evas_engine_gl_drm_log_dom);
|
2015-06-03 09:56:35 -07:00
|
|
|
_evas_engine_gl_drm_log_dom = -1;
|
2014-08-21 02:22:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Module_Api evas_modapi =
|
|
|
|
{
|
2014-08-21 07:22:51 -07:00
|
|
|
EVAS_MODULE_API_VERSION, "gl_drm", "none", { module_open, module_close }
|
2014-08-21 02:22:16 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, gl_drm);
|
|
|
|
|
|
|
|
#ifndef EVAS_STATIC_BUILD_DRM
|
|
|
|
EVAS_EINA_MODULE_DEFINE(engine, gl_drm);
|
|
|
|
#endif
|