2012-05-15 06:13:05 -07:00
|
|
|
#include "evas_engine.h"
|
2015-09-30 15:12:13 -07:00
|
|
|
#include "../gl_common/evas_gl_define.h"
|
2015-11-05 22:28:12 -08:00
|
|
|
#include <dlfcn.h>
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2015-11-05 22:28:12 -08:00
|
|
|
# define SET_RESTORE_CONTEXT() do { if (glsym_evas_gl_common_context_restore_set) glsym_evas_gl_common_context_restore_set(EINA_TRUE); } while(0)
|
2015-08-18 01:35:40 -07:00
|
|
|
|
2014-09-01 03:40:07 -07:00
|
|
|
static Eina_TLS _outbuf_key = 0;
|
|
|
|
static Eina_TLS _context_key = 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2015-11-05 22:28:12 -08:00
|
|
|
typedef void (*glsym_func_void) ();
|
|
|
|
glsym_func_void glsym_evas_gl_common_context_restore_set = NULL;
|
|
|
|
|
2017-08-25 10:51:59 -07:00
|
|
|
Eina_Bool gles3_supported = EINA_FALSE;
|
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2014-09-01 03:40:07 -07:00
|
|
|
typedef EGLContext GLContext;
|
2015-04-06 05:57:32 -07:00
|
|
|
typedef EGLConfig GLConfig;
|
2017-08-25 10:51:59 -07:00
|
|
|
static Eina_Bool gles3_probed = EINA_FALSE;
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
|
|
|
// FIXME: this will only work for 1 display connection (glx land can have > 1)
|
2014-09-01 03:40:07 -07:00
|
|
|
typedef GLXContext GLContext;
|
2015-04-06 05:57:32 -07:00
|
|
|
typedef GLXFBConfig GLConfig;
|
2014-09-01 03:40:07 -07:00
|
|
|
static Eina_TLS _rgba_context_key = 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
#endif
|
|
|
|
|
2015-04-06 05:57:32 -07:00
|
|
|
typedef struct _Evas_GL_X11_Visual Evas_GL_X11_Visual;
|
|
|
|
struct _Evas_GL_X11_Visual
|
|
|
|
{
|
|
|
|
XVisualInfo info;
|
|
|
|
GLConfig config;
|
|
|
|
Colormap cmap;
|
2015-11-17 01:36:31 -08:00
|
|
|
Display *disp;
|
2015-04-06 05:57:32 -07:00
|
|
|
Eina_Bool alpha;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* index (_visuals_hash_index_get) -> Evas_GL_X11_Visual */
|
|
|
|
static Eina_Hash *_evas_gl_visuals = NULL;
|
2012-05-15 06:13:05 -07:00
|
|
|
|
|
|
|
static int win_count = 0;
|
2014-09-01 03:40:07 -07:00
|
|
|
static Eina_Bool initted = EINA_FALSE;
|
|
|
|
|
2018-10-09 06:04:05 -07:00
|
|
|
#if 0
|
|
|
|
static double
|
|
|
|
_time_get(void)
|
|
|
|
{
|
|
|
|
struct timespec t;
|
|
|
|
|
|
|
|
if (clock_gettime(CLOCK_MONOTONIC, &t))
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Failed to get monotonic clock time...");
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (double)t.tv_sec + (((double)t.tv_nsec) / 1000000000.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
measure(int inout, const char *what)
|
|
|
|
{
|
|
|
|
static double t0 = 0.0;
|
|
|
|
double t;
|
|
|
|
|
|
|
|
if (inout == 0) t0 = _time_get();
|
|
|
|
else if (inout ==1)
|
|
|
|
{
|
|
|
|
t = _time_get() - t0;
|
|
|
|
printf("%s: %1.2f\n", what, t * 1000.0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
# define measure(x, y)
|
|
|
|
#endif
|
|
|
|
|
2014-09-01 03:40:07 -07:00
|
|
|
Eina_Bool
|
|
|
|
eng_init(void)
|
|
|
|
{
|
|
|
|
if (initted)
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
2015-11-05 22:28:12 -08:00
|
|
|
#define LINK2GENERIC(sym) \
|
|
|
|
glsym_##sym = dlsym(RTLD_DEFAULT, #sym); \
|
|
|
|
if (!glsym_##sym) ERR("Could not find function '%s'", #sym);
|
|
|
|
|
|
|
|
LINK2GENERIC(evas_gl_common_context_restore_set);
|
|
|
|
|
2014-09-01 03:40:07 -07:00
|
|
|
// FIXME: These resources are never released
|
|
|
|
if (!eina_tls_new(&_outbuf_key))
|
|
|
|
goto error;
|
|
|
|
if (!eina_tls_new(&_context_key))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
eina_tls_set(_outbuf_key, NULL);
|
|
|
|
eina_tls_set(_context_key, NULL);
|
|
|
|
|
|
|
|
#ifndef GL_GLES
|
|
|
|
if (!eina_tls_new(&_rgba_context_key))
|
|
|
|
goto error;
|
|
|
|
eina_tls_set(_rgba_context_key, NULL);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
initted = EINA_TRUE;
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
|
|
|
error:
|
|
|
|
ERR("Could not create TLS key!");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline Outbuf *
|
2014-09-19 01:44:56 -07:00
|
|
|
_tls_outbuf_get(void)
|
2014-09-01 03:40:07 -07:00
|
|
|
{
|
|
|
|
if (!initted) eng_init();
|
|
|
|
return eina_tls_get(_outbuf_key);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline Eina_Bool
|
2014-09-19 01:44:56 -07:00
|
|
|
_tls_outbuf_set(Outbuf *xwin)
|
2014-09-01 03:40:07 -07:00
|
|
|
{
|
|
|
|
if (!initted) eng_init();
|
|
|
|
return eina_tls_set(_outbuf_key, xwin);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline GLContext
|
|
|
|
_tls_context_get(void)
|
|
|
|
{
|
|
|
|
if (!initted) eng_init();
|
|
|
|
return eina_tls_get(_context_key);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline Eina_Bool
|
|
|
|
_tls_context_set(GLContext ctx)
|
|
|
|
{
|
|
|
|
if (!initted) eng_init();
|
|
|
|
return eina_tls_set(_context_key, ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef GL_GLES
|
|
|
|
static inline GLXContext
|
|
|
|
_tls_rgba_context_get(void)
|
|
|
|
{
|
|
|
|
if (!initted) eng_init();
|
|
|
|
return eina_tls_get(_rgba_context_key);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline Eina_Bool
|
|
|
|
_tls_rgba_context_set(GLXContext ctx)
|
|
|
|
{
|
|
|
|
if (!initted) eng_init();
|
|
|
|
return eina_tls_set(_rgba_context_key, ctx);
|
|
|
|
}
|
2014-10-25 04:04:52 -07:00
|
|
|
|
|
|
|
Eina_Bool
|
|
|
|
__glXMakeContextCurrent(Display *disp, GLXDrawable glxwin, GLXContext context)
|
|
|
|
{
|
|
|
|
if (!glXMakeContextCurrent(disp, glxwin, glxwin, context)) return EINA_FALSE;
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
2014-09-01 03:40:07 -07:00
|
|
|
#endif
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2015-04-06 05:57:32 -07:00
|
|
|
static void
|
|
|
|
_visuals_hash_del_cb(void *data)
|
|
|
|
{
|
2015-11-17 01:36:31 -08:00
|
|
|
Evas_GL_X11_Visual *evis = data;
|
|
|
|
if (evis && evis->cmap && evis->disp)
|
|
|
|
XFreeColormap(evis->disp, evis->cmap);
|
|
|
|
free(evis);
|
2015-04-06 05:57:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
_visuals_hash_index_get(int alpha, int zdepth, int stencil, int msaa)
|
|
|
|
{
|
|
|
|
if (!_evas_gl_visuals)
|
|
|
|
_evas_gl_visuals = eina_hash_int32_new(_visuals_hash_del_cb);
|
|
|
|
return alpha | (zdepth << 8) | (stencil << 16) | (msaa << 24);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
_visuals_hash_index_get_from_info(Evas_Engine_Info_GL_X11 *info)
|
|
|
|
{
|
|
|
|
if (!info) return -1;
|
|
|
|
return _visuals_hash_index_get(info->info.destination_alpha,
|
|
|
|
info->depth_bits, info->stencil_bits,
|
|
|
|
info->msaa_bits);
|
|
|
|
}
|
|
|
|
|
2016-11-30 22:26:11 -08:00
|
|
|
#ifdef GL_GLES
|
|
|
|
|
|
|
|
static EGLDisplay *
|
|
|
|
_x11_eglGetDisplay(Display *x11_display)
|
|
|
|
{
|
|
|
|
EGLDisplay (*eglsym_eglGetPlatformDisplay)
|
|
|
|
(EGLenum platform, void *native_display, const EGLAttrib *attrib_list) = NULL;
|
|
|
|
EGLDisplay *egldisp = EGL_NO_DISPLAY;
|
|
|
|
|
|
|
|
eglsym_eglGetPlatformDisplay = dlsym(RTLD_DEFAULT, "eglGetPlatformDisplay");
|
|
|
|
if (eglsym_eglGetPlatformDisplay)
|
|
|
|
{
|
|
|
|
egldisp = eglsym_eglGetPlatformDisplay(EGL_PLATFORM_X11_KHR,
|
|
|
|
(EGLNativeDisplayType) x11_display, NULL);
|
|
|
|
if (egldisp) return egldisp;
|
|
|
|
}
|
|
|
|
|
|
|
|
return eglGetDisplay((EGLNativeDisplayType) x11_display);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2014-06-30 23:43:27 -07:00
|
|
|
Outbuf *
|
2014-07-04 04:51:32 -07:00
|
|
|
eng_window_new(Evas_Engine_Info_GL_X11 *info,
|
|
|
|
Display *disp,
|
2012-08-21 04:32:18 -07:00
|
|
|
Window win,
|
|
|
|
int screen,
|
|
|
|
Visual *vis,
|
|
|
|
Colormap cmap,
|
|
|
|
int depth,
|
2016-12-02 15:30:02 -08:00
|
|
|
unsigned int w,
|
|
|
|
unsigned int h,
|
2014-08-14 04:21:19 -07:00
|
|
|
int indirect EINA_UNUSED,
|
2014-10-21 00:22:49 -07:00
|
|
|
int alpha,
|
2014-07-04 04:51:32 -07:00
|
|
|
int rot,
|
2017-08-25 10:49:15 -07:00
|
|
|
Render_Output_Swap_Mode swap_mode,
|
2015-03-15 21:57:09 -07:00
|
|
|
int depth_bits,
|
|
|
|
int stencil_bits,
|
|
|
|
int msaa_bits)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2014-06-30 23:43:27 -07:00
|
|
|
Outbuf *gw;
|
2014-09-01 03:40:07 -07:00
|
|
|
GLContext context;
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2012-05-15 06:13:05 -07:00
|
|
|
int context_attrs[3];
|
|
|
|
int major_version, minor_version;
|
2014-09-01 03:40:07 -07:00
|
|
|
#else
|
|
|
|
GLXContext rgbactx;
|
2015-04-06 05:57:32 -07:00
|
|
|
Evas_GL_X11_Visual *evis2 = NULL;
|
|
|
|
int tmp;
|
2012-05-15 06:13:05 -07:00
|
|
|
#endif
|
2014-11-27 00:09:22 -08:00
|
|
|
const GLubyte *vendor, *renderer, *version, *glslversion;
|
2012-06-25 03:01:03 -07:00
|
|
|
int blacklist = 0;
|
2015-04-06 05:57:32 -07:00
|
|
|
int val = 0, idx;
|
|
|
|
Evas_GL_X11_Visual *evis;
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2015-04-06 05:57:32 -07:00
|
|
|
idx = _visuals_hash_index_get_from_info(info);
|
|
|
|
evis = eina_hash_find(_evas_gl_visuals, &idx);
|
|
|
|
if (!evis)
|
|
|
|
{
|
|
|
|
eng_best_visual_get(info);
|
|
|
|
evis = eina_hash_find(_evas_gl_visuals, &idx);
|
|
|
|
if (!evis) return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
vis = evis->info.visual;
|
|
|
|
if (!vis) return NULL;
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2014-06-30 23:43:27 -07:00
|
|
|
gw = calloc(1, sizeof(Outbuf));
|
2012-05-15 06:13:05 -07:00
|
|
|
if (!gw) return NULL;
|
|
|
|
|
|
|
|
win_count++;
|
|
|
|
gw->disp = disp;
|
|
|
|
gw->win = win;
|
|
|
|
gw->screen = screen;
|
|
|
|
gw->visual = vis;
|
|
|
|
gw->colormap = cmap;
|
|
|
|
gw->depth = depth;
|
2014-10-21 00:22:49 -07:00
|
|
|
gw->alpha = alpha;
|
2012-05-15 06:13:05 -07:00
|
|
|
gw->w = w;
|
|
|
|
gw->h = h;
|
|
|
|
gw->rot = rot;
|
2014-07-04 04:51:32 -07:00
|
|
|
gw->swap_mode = swap_mode;
|
|
|
|
gw->info = info;
|
2015-03-15 21:57:09 -07:00
|
|
|
gw->depth_bits = depth_bits;
|
|
|
|
gw->stencil_bits = stencil_bits;
|
|
|
|
gw->msaa_bits = msaa_bits;
|
2015-04-06 05:57:32 -07:00
|
|
|
gw->visualinfo = &evis->info;
|
2012-05-15 06:13:05 -07:00
|
|
|
|
|
|
|
// EGL / GLES
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2016-11-30 22:26:11 -08:00
|
|
|
gw->egl_disp = _x11_eglGetDisplay(gw->disp);
|
2012-05-15 06:13:05 -07:00
|
|
|
if (!gw->egl_disp)
|
|
|
|
{
|
|
|
|
ERR("eglGetDisplay() fail. code=%#x", eglGetError());
|
2012-08-21 04:32:18 -07:00
|
|
|
eng_window_free(gw);
|
2012-05-15 06:13:05 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (!eglInitialize(gw->egl_disp, &major_version, &minor_version))
|
|
|
|
{
|
|
|
|
ERR("eglInitialize() fail. code=%#x", eglGetError());
|
2012-08-21 04:32:18 -07:00
|
|
|
eng_window_free(gw);
|
2012-05-15 06:13:05 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
2015-02-17 07:34:35 -08:00
|
|
|
if (!eglBindAPI(EGL_OPENGL_ES_API))
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
|
|
|
ERR("eglBindAPI() fail. code=%#x", eglGetError());
|
2012-08-21 04:32:18 -07:00
|
|
|
eng_window_free(gw);
|
2012-05-15 06:13:05 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-04-06 05:57:32 -07:00
|
|
|
gw->egl_config = evis->config;
|
2014-10-25 04:04:52 -07:00
|
|
|
|
2016-12-16 07:12:30 -08:00
|
|
|
gw->egl_surface = eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
|
2012-05-15 06:13:05 -07:00
|
|
|
(EGLNativeWindowType)gw->win,
|
|
|
|
NULL);
|
2016-12-16 07:12:30 -08:00
|
|
|
if (gw->egl_surface == EGL_NO_SURFACE)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2015-03-01 23:21:22 -08:00
|
|
|
int err = eglGetError();
|
|
|
|
printf("surf creat fail! %x\n", err);
|
2012-05-15 06:13:05 -07:00
|
|
|
ERR("eglCreateWindowSurface() fail for %#x. code=%#x",
|
2015-03-01 23:21:22 -08:00
|
|
|
(unsigned int)gw->win, err);
|
2012-08-21 04:32:18 -07:00
|
|
|
eng_window_free(gw);
|
2012-05-15 06:13:05 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
2015-03-05 02:21:24 -08:00
|
|
|
|
|
|
|
try_gles2:
|
|
|
|
context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
|
2017-08-25 10:51:59 -07:00
|
|
|
context_attrs[1] = gles3_supported ? 3 : 2;
|
2015-03-05 02:21:24 -08:00
|
|
|
context_attrs[2] = EGL_NONE;
|
|
|
|
|
2014-09-01 03:40:07 -07:00
|
|
|
context = _tls_context_get();
|
2016-12-16 07:12:30 -08:00
|
|
|
gw->egl_context = eglCreateContext
|
2012-09-05 03:11:48 -07:00
|
|
|
(gw->egl_disp, gw->egl_config, context, context_attrs);
|
2016-12-16 07:12:30 -08:00
|
|
|
if (gw->egl_context == EGL_NO_CONTEXT)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
|
|
|
ERR("eglCreateContext() fail. code=%#x", eglGetError());
|
2017-08-25 10:51:59 -07:00
|
|
|
if (gles3_supported)
|
2015-03-05 02:21:24 -08:00
|
|
|
{
|
|
|
|
/* Note: this shouldn't happen */
|
|
|
|
ERR("Trying again with an Open GL ES 2 context (fallback).");
|
2017-08-25 10:51:59 -07:00
|
|
|
gles3_supported = EINA_FALSE;
|
2015-03-05 02:21:24 -08:00
|
|
|
goto try_gles2;
|
|
|
|
}
|
2012-08-21 04:32:18 -07:00
|
|
|
eng_window_free(gw);
|
2012-05-15 06:13:05 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
2014-09-01 03:40:07 -07:00
|
|
|
if (context == EGL_NO_CONTEXT)
|
2016-12-16 07:12:30 -08:00
|
|
|
_tls_context_set(gw->egl_context);
|
2012-09-05 03:11:48 -07:00
|
|
|
|
2015-08-18 01:35:40 -07:00
|
|
|
SET_RESTORE_CONTEXT();
|
2015-11-06 00:50:22 -08:00
|
|
|
if (evas_eglMakeCurrent(gw->egl_disp,
|
2016-12-16 07:12:30 -08:00
|
|
|
gw->egl_surface,
|
|
|
|
gw->egl_surface,
|
|
|
|
gw->egl_context) == EGL_FALSE)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2015-11-06 00:50:22 -08:00
|
|
|
ERR("evas_eglMakeCurrent() fail. code=%#x", eglGetError());
|
2012-08-21 04:32:18 -07:00
|
|
|
eng_window_free(gw);
|
2012-05-15 06:13:05 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
vendor = glGetString(GL_VENDOR);
|
|
|
|
renderer = glGetString(GL_RENDERER);
|
|
|
|
version = glGetString(GL_VERSION);
|
2014-11-27 00:09:22 -08:00
|
|
|
glslversion = glGetString(GL_SHADING_LANGUAGE_VERSION);
|
2012-05-15 06:13:05 -07:00
|
|
|
if (!vendor) vendor = (unsigned char *)"-UNKNOWN-";
|
|
|
|
if (!renderer) renderer = (unsigned char *)"-UNKNOWN-";
|
|
|
|
if (!version) version = (unsigned char *)"-UNKNOWN-";
|
2014-11-27 00:09:22 -08:00
|
|
|
if (!glslversion) glslversion = (unsigned char *)"-UNKNOWN-";
|
2012-05-15 06:13:05 -07:00
|
|
|
if (getenv("EVAS_GL_INFO"))
|
|
|
|
{
|
2014-11-27 00:09:22 -08:00
|
|
|
fprintf(stderr, "vendor : %s\n", vendor);
|
2012-05-15 06:13:05 -07:00
|
|
|
fprintf(stderr, "renderer: %s\n", renderer);
|
2014-11-27 00:09:22 -08:00
|
|
|
fprintf(stderr, "version : %s\n", version);
|
|
|
|
fprintf(stderr, "glsl ver: %s\n", glslversion);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2012-06-25 03:01:03 -07:00
|
|
|
|
|
|
|
if (strstr((const char *)vendor, "Mesa Project"))
|
|
|
|
{
|
|
|
|
if (strstr((const char *)renderer, "Software Rasterizer"))
|
|
|
|
blacklist = 1;
|
|
|
|
}
|
|
|
|
if (strstr((const char *)renderer, "softpipe"))
|
|
|
|
blacklist = 1;
|
2012-09-08 07:31:18 -07:00
|
|
|
if (strstr((const char *)renderer, "llvmpipe"))
|
|
|
|
blacklist = 1;
|
2012-09-14 00:33:03 -07:00
|
|
|
if ((blacklist) && (!getenv("EVAS_GL_NO_BLACKLIST")))
|
2012-06-25 03:01:03 -07:00
|
|
|
{
|
2013-11-21 01:43:17 -08:00
|
|
|
WRN("OpenGL Driver blacklisted:");
|
|
|
|
WRN("Vendor: %s", (const char *)vendor);
|
|
|
|
WRN("Renderer: %s", (const char *)renderer);
|
|
|
|
WRN("Version: %s", (const char *)version);
|
2012-06-25 03:01:03 -07:00
|
|
|
eng_window_free(gw);
|
|
|
|
return NULL;
|
|
|
|
}
|
2018-07-10 00:04:01 -07:00
|
|
|
// nvidia drivers in egl/gles mode dont need re-creating of the
|
|
|
|
// eglimage ... and doign so is super slow on them, so avoid the
|
|
|
|
// multi buffer path - as it's only for nvidia and this fixes
|
|
|
|
// the performance regression there, it's fairly safe to do
|
|
|
|
// as it's not universal across all drivers.
|
|
|
|
if (strstr((const char *)vendor, "NVIDIA"))
|
|
|
|
gw->detected.no_multi_buffer_native = 1;
|
2015-03-15 21:57:09 -07:00
|
|
|
|
|
|
|
eglGetConfigAttrib(gw->egl_disp, gw->egl_config, EGL_DEPTH_SIZE, &val);
|
|
|
|
gw->detected.depth_buffer_size = val;
|
|
|
|
DBG("Detected depth size %d", val);
|
|
|
|
eglGetConfigAttrib(gw->egl_disp, gw->egl_config, EGL_STENCIL_SIZE, &val);
|
|
|
|
gw->detected.stencil_buffer_size = val;
|
|
|
|
DBG("Detected stencil size %d", val);
|
|
|
|
eglGetConfigAttrib(gw->egl_disp, gw->egl_config, EGL_SAMPLES, &val);
|
|
|
|
gw->detected.msaa = val;
|
|
|
|
DBG("Detected msaa %d", val);
|
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
// GLX
|
|
|
|
#else
|
2014-09-01 03:40:07 -07:00
|
|
|
context = _tls_context_get();
|
2012-05-15 06:13:05 -07:00
|
|
|
if (!context)
|
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
if (!evis->alpha)
|
|
|
|
evis2 = evis;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tmp = info->info.destination_alpha;
|
|
|
|
info->info.destination_alpha = 0;
|
|
|
|
evis2 = eng_best_visual_get(info);
|
|
|
|
info->info.destination_alpha = tmp;
|
|
|
|
if (!evis2)
|
|
|
|
{
|
|
|
|
ERR("Could not find visual! (rgb only)");
|
|
|
|
evis2 = evis;
|
|
|
|
}
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
if (indirect)
|
2015-04-06 05:57:32 -07:00
|
|
|
context = glXCreateNewContext(gw->disp, evis2->config,
|
2012-05-15 06:13:05 -07:00
|
|
|
GLX_RGBA_TYPE, NULL,
|
|
|
|
GL_FALSE);
|
|
|
|
else
|
2015-04-06 05:57:32 -07:00
|
|
|
context = glXCreateNewContext(gw->disp, evis2->config,
|
2012-05-15 06:13:05 -07:00
|
|
|
GLX_RGBA_TYPE, NULL,
|
|
|
|
GL_TRUE);
|
2014-10-06 17:57:31 -07:00
|
|
|
_tls_context_set(context);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2014-09-01 03:40:07 -07:00
|
|
|
rgbactx = _tls_rgba_context_get();
|
|
|
|
if ((gw->alpha) && (!rgbactx))
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
if (evis->alpha)
|
|
|
|
evis2 = evis;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tmp = info->info.destination_alpha;
|
|
|
|
info->info.destination_alpha = 1;
|
|
|
|
evis2 = eng_best_visual_get(info);
|
|
|
|
info->info.destination_alpha = tmp;
|
|
|
|
if (!evis2)
|
|
|
|
{
|
|
|
|
ERR("Could not find visual! (rgba)");
|
|
|
|
evis2 = evis;
|
|
|
|
}
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
if (indirect)
|
2015-04-06 05:57:32 -07:00
|
|
|
rgbactx = glXCreateNewContext(gw->disp, evis2->config,
|
2014-09-01 03:40:07 -07:00
|
|
|
GLX_RGBA_TYPE, context,
|
|
|
|
GL_FALSE);
|
2012-05-15 06:13:05 -07:00
|
|
|
else
|
2015-04-06 05:57:32 -07:00
|
|
|
rgbactx = glXCreateNewContext(gw->disp, evis2->config,
|
2014-09-01 03:40:07 -07:00
|
|
|
GLX_RGBA_TYPE, context,
|
|
|
|
GL_TRUE);
|
|
|
|
_tls_rgba_context_set(rgbactx);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2015-04-06 05:57:32 -07:00
|
|
|
|
|
|
|
if (gw->alpha != info->info.destination_alpha)
|
|
|
|
{
|
|
|
|
tmp = info->info.destination_alpha;
|
|
|
|
info->info.destination_alpha = gw->alpha;
|
|
|
|
evis2 = eng_best_visual_get(info);
|
|
|
|
info->info.destination_alpha = tmp;
|
|
|
|
if (!evis2)
|
|
|
|
{
|
|
|
|
ERR("Could not find visual! (alpha: %d)", gw->alpha);
|
|
|
|
evis2 = evis;
|
|
|
|
}
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
else
|
2015-04-06 05:57:32 -07:00
|
|
|
evis2 = evis;
|
|
|
|
gw->glxwin = glXCreateWindow(gw->disp, evis2->config, gw->win, NULL);
|
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
if (!gw->glxwin)
|
|
|
|
{
|
2014-09-30 09:31:51 -07:00
|
|
|
ERR("glXCreateWindow failed.");
|
2012-08-21 04:32:18 -07:00
|
|
|
eng_window_free(gw);
|
2012-05-15 06:13:05 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-09-01 03:40:07 -07:00
|
|
|
if (gw->alpha) gw->context = rgbactx;
|
2012-05-15 06:13:05 -07:00
|
|
|
else gw->context = context;
|
|
|
|
|
|
|
|
if (!gw->context)
|
|
|
|
{
|
2014-09-30 09:31:51 -07:00
|
|
|
ERR("Failed to create a context.");
|
2012-08-21 04:32:18 -07:00
|
|
|
eng_window_free(gw);
|
2012-05-15 06:13:05 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
2014-10-25 04:04:52 -07:00
|
|
|
if (!__glXMakeContextCurrent(gw->disp, gw->glxwin, gw->context))
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2014-10-25 04:04:52 -07:00
|
|
|
ERR("glXMakeContextCurrent(%p, %p, %p, %p)\n", (void *)gw->disp, (void *)gw->glxwin, (void *)gw->win, (void *)gw->context);
|
|
|
|
eng_window_free(gw);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
// FIXME: move this up to context creation
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2014-10-25 04:04:52 -07:00
|
|
|
vendor = glGetString(GL_VENDOR);
|
|
|
|
renderer = glGetString(GL_RENDERER);
|
|
|
|
version = glGetString(GL_VERSION);
|
2014-11-27 00:09:22 -08:00
|
|
|
glslversion = glGetString(GL_SHADING_LANGUAGE_VERSION);
|
|
|
|
if (!vendor) vendor = (unsigned char *)"-UNKNOWN-";
|
|
|
|
if (!renderer) renderer = (unsigned char *)"-UNKNOWN-";
|
|
|
|
if (!version) version = (unsigned char *)"-UNKNOWN-";
|
|
|
|
if (!glslversion) glslversion = (unsigned char *)"-UNKNOWN-";
|
2014-10-25 04:04:52 -07:00
|
|
|
if (getenv("EVAS_GL_INFO"))
|
|
|
|
{
|
2014-11-27 00:09:22 -08:00
|
|
|
fprintf(stderr, "vendor : %s\n", vendor);
|
2014-10-25 04:04:52 -07:00
|
|
|
fprintf(stderr, "renderer: %s\n", renderer);
|
2014-11-27 00:09:22 -08:00
|
|
|
fprintf(stderr, "version : %s\n", version);
|
|
|
|
fprintf(stderr, "glsl ver: %s\n", glslversion);
|
2014-10-25 04:04:52 -07:00
|
|
|
}
|
2014-11-27 00:09:22 -08:00
|
|
|
|
2014-10-25 04:04:52 -07:00
|
|
|
// examples:
|
|
|
|
// vendor: NVIDIA Corporation
|
|
|
|
// renderer: NVIDIA Tegra
|
|
|
|
// version: OpenGL ES 2.0
|
|
|
|
// or
|
|
|
|
// vendor: Imagination Technologies
|
|
|
|
// renderer: PowerVR SGX 540
|
|
|
|
// version: OpenGL ES 2.0
|
|
|
|
// or
|
|
|
|
// vendor: NVIDIA Corporation
|
|
|
|
// renderer: GeForce GT 330M/PCI/SSE2
|
|
|
|
// version: 3.3.0 NVIDIA 256.53
|
|
|
|
// or
|
|
|
|
// vendor: NVIDIA Corporation
|
|
|
|
// renderer: GeForce GT 220/PCI/SSE2
|
|
|
|
// version: 3.2.0 NVIDIA 195.36.24
|
|
|
|
// or
|
|
|
|
// vendor: NVIDIA Corporation
|
|
|
|
// renderer: GeForce 8600 GTS/PCI/SSE2
|
|
|
|
// version: 3.3.0 NVIDIA 260.19.36
|
|
|
|
// or
|
|
|
|
// vendor: ATI Technologies Inc.
|
|
|
|
// renderer: ATI Mobility Radeon HD 4650
|
|
|
|
// version: 3.2.9756 Compatibility Profile Context
|
|
|
|
// or
|
|
|
|
// vendor: Tungsten Graphics, Inc
|
|
|
|
// renderer: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20100330 DEVELOPMENT x86/MMX/SSE2
|
|
|
|
// version: 2.1 Mesa 7.9-devel
|
|
|
|
// or
|
|
|
|
// vendor: Advanced Micro Devices, Inc.
|
|
|
|
// renderer: Mesa DRI R600 (RS780 9610) 20090101 TCL DRI2
|
|
|
|
// version: 2.1 Mesa 7.9-devel
|
|
|
|
// or
|
|
|
|
// vendor: NVIDIA Corporation
|
|
|
|
// renderer: GeForce 9600 GT/PCI/SSE2
|
|
|
|
// version: 3.3.0 NVIDIA 260.19.29
|
|
|
|
// or
|
|
|
|
// vendor: ATI Technologies Inc.
|
|
|
|
// renderer: ATI Radeon HD 4800 Series
|
|
|
|
// version: 3.3.10237 Compatibility Profile Context
|
|
|
|
// or
|
|
|
|
// vendor: Advanced Micro Devices, Inc.
|
|
|
|
// renderer: Mesa DRI R600 (RV770 9442) 20090101 TCL DRI2
|
|
|
|
// version: 2.0 Mesa 7.8.2
|
|
|
|
// or
|
|
|
|
// vendor: Tungsten Graphics, Inc
|
|
|
|
// renderer: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20100330 DEVELOPMENT
|
|
|
|
// version: 2.1 Mesa 7.9-devel
|
|
|
|
// or (bad - software renderer)
|
|
|
|
// vendor: Mesa Project
|
|
|
|
// renderer: Software Rasterizer
|
|
|
|
// version: 2.1 Mesa 7.9-devel
|
|
|
|
// or (bad - software renderer)
|
|
|
|
// vendor: VMware, Inc.
|
|
|
|
// renderer: Gallium 0.4 on softpipe
|
|
|
|
// version: 2.1 Mesa 7.9-devel
|
2015-11-03 01:13:59 -08:00
|
|
|
//
|
2014-10-25 04:04:52 -07:00
|
|
|
if (strstr((const char *)vendor, "Mesa Project"))
|
|
|
|
{
|
|
|
|
if (strstr((const char *)renderer, "Software Rasterizer"))
|
2012-09-08 07:31:18 -07:00
|
|
|
blacklist = 1;
|
2014-10-25 04:04:52 -07:00
|
|
|
}
|
|
|
|
if (strstr((const char *)renderer, "softpipe"))
|
|
|
|
blacklist = 1;
|
|
|
|
if (strstr((const char *)renderer, "llvmpipe"))
|
|
|
|
blacklist = 1;
|
|
|
|
if ((blacklist) && (!getenv("EVAS_GL_NO_BLACKLIST")))
|
|
|
|
{
|
|
|
|
WRN("OpenGL Driver blacklisted:");
|
|
|
|
WRN("Vendor: %s", (const char *)vendor);
|
|
|
|
WRN("Renderer: %s", (const char *)renderer);
|
|
|
|
WRN("Version: %s", (const char *)version);
|
|
|
|
eng_window_free(gw);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (strstr((const char *)vendor, "NVIDIA"))
|
|
|
|
{
|
|
|
|
if (!strstr((const char *)renderer, "NVIDIA Tegra"))
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2014-10-25 04:04:52 -07:00
|
|
|
int v1 = 0, v2 = 0, v3 = 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2014-10-25 04:04:52 -07:00
|
|
|
if (sscanf((const char *)version,
|
|
|
|
"%*s %*s %i.%i.%i",
|
|
|
|
&v1, &v2, &v3) != 3)
|
|
|
|
{
|
|
|
|
v1 = v2 = v3 = 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
if (sscanf((const char *)version,
|
2014-10-25 04:04:52 -07:00
|
|
|
"%*s %*s %i.%i",
|
|
|
|
&v1, &v2) != 2)
|
|
|
|
v1 = 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2014-10-25 04:04:52 -07:00
|
|
|
// ALSO as of some nvidia driver version loose binding is
|
|
|
|
// probably not needed
|
|
|
|
if (v1 < 195) gw->detected.loose_binding = 1;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2014-10-25 04:04:52 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// noothing yet. add more cases and options over time
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2015-03-15 21:57:09 -07:00
|
|
|
|
|
|
|
glXGetConfig(gw->disp, gw->visualinfo, GLX_DEPTH_SIZE, &val);
|
|
|
|
gw->detected.depth_buffer_size = val;
|
|
|
|
glXGetConfig(gw->disp, gw->visualinfo, GLX_STENCIL_SIZE, &val);
|
|
|
|
gw->detected.stencil_buffer_size = val;
|
|
|
|
glXGetConfig(gw->disp, gw->visualinfo, GLX_SAMPLES, &val);
|
|
|
|
gw->detected.msaa = val;
|
2012-05-15 06:13:05 -07:00
|
|
|
#endif
|
|
|
|
|
2016-08-03 19:49:33 -07:00
|
|
|
eng_gl_symbols(gw);
|
2014-07-11 06:16:03 -07:00
|
|
|
gw->gl_context = glsym_evas_gl_common_context_new();
|
2012-05-15 06:13:05 -07:00
|
|
|
if (!gw->gl_context)
|
|
|
|
{
|
2014-10-20 20:08:42 -07:00
|
|
|
ERR("Unable to get a new context.");
|
2012-08-21 04:32:18 -07:00
|
|
|
eng_window_free(gw);
|
|
|
|
return NULL;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2012-05-15 06:13:05 -07:00
|
|
|
gw->gl_context->egldisp = gw->egl_disp;
|
2016-12-16 07:12:30 -08:00
|
|
|
gw->gl_context->eglctxt = gw->egl_context;
|
2015-11-17 00:18:57 -08:00
|
|
|
#else
|
|
|
|
glXGetFBConfigAttrib(gw->disp, evis->config, GLX_FBCONFIG_ID, &gw->gl_context->glxcfg_rgb);
|
|
|
|
glXGetFBConfigAttrib(gw->disp, evis2->config, GLX_FBCONFIG_ID, &gw->gl_context->glxcfg_rgba);
|
2012-05-15 06:13:05 -07:00
|
|
|
#endif
|
evas gl: move to floating point coordinate system.
Summary:
GL engine has used integer coordinates system since it's born though
OpenGL basically uses floating point vertex coordinates system.
There were many dissatisfaction, complaints about this
since object's transition is jiggled, not perfectly smooth.
It's obvious because Positioning must be stepping with integer units
without any subpixel rendering.
Our gl engine currently supports msaa options and evas map allows to
have double precivion coordinates system, our engine must do handle this over as well,
to work together.
If you don't like change,
We could switch behaviors optionally (turn on, only when msaa is enabled)
But I think it's pointless using integer coordinates system in GL thesedays.
It just make code complex to maintain.
There will be an additional patch coming for SW backend map behavior soon.
Left: before patch
Right: after patch
{F3694624}
Reviewers: #committers, raster
Reviewed By: #committers, raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D8552
2019-04-18 04:08:16 -07:00
|
|
|
gw->gl_context->msaa = (Eina_Bool) msaa_bits;
|
2012-05-15 06:13:05 -07:00
|
|
|
eng_window_use(gw);
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_common_context_resize(gw->gl_context, w, h, rot);
|
2012-05-15 06:13:05 -07:00
|
|
|
gw->surf = 1;
|
|
|
|
return gw;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-06-30 23:43:27 -07:00
|
|
|
eng_window_free(Outbuf *gw)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2014-09-01 03:40:07 -07:00
|
|
|
Outbuf *xwin;
|
|
|
|
GLContext context;
|
2012-05-15 06:13:05 -07:00
|
|
|
int ref = 0;
|
|
|
|
win_count--;
|
|
|
|
eng_window_use(gw);
|
2014-09-01 03:40:07 -07:00
|
|
|
|
2016-04-11 20:47:30 -07:00
|
|
|
if (win_count == 0) evas_common_font_ext_clear();
|
|
|
|
|
2014-09-01 03:40:07 -07:00
|
|
|
context = _tls_context_get();
|
2014-09-19 01:44:56 -07:00
|
|
|
xwin = _tls_outbuf_get();
|
2014-09-01 03:40:07 -07:00
|
|
|
|
2014-09-19 01:44:56 -07:00
|
|
|
if (gw == xwin) _tls_outbuf_set(NULL);
|
2012-05-15 06:13:05 -07:00
|
|
|
if (gw->gl_context)
|
|
|
|
{
|
|
|
|
ref = gw->gl_context->references - 1;
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_common_context_free(gw->gl_context);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2015-08-18 01:35:40 -07:00
|
|
|
SET_RESTORE_CONTEXT();
|
2015-11-06 00:50:22 -08:00
|
|
|
evas_eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
2016-12-16 07:12:30 -08:00
|
|
|
if (gw->egl_surface != EGL_NO_SURFACE)
|
|
|
|
eglDestroySurface(gw->egl_disp, gw->egl_surface);
|
|
|
|
if (gw->egl_context != context)
|
|
|
|
eglDestroyContext(gw->egl_disp, gw->egl_context);
|
2012-05-15 06:13:05 -07:00
|
|
|
if (ref == 0)
|
|
|
|
{
|
|
|
|
if (context) eglDestroyContext(gw->egl_disp, context);
|
2015-04-06 05:57:32 -07:00
|
|
|
eina_hash_free(_evas_gl_visuals);
|
|
|
|
_evas_gl_visuals = NULL;
|
2015-11-17 01:36:31 -08:00
|
|
|
eglTerminate(gw->egl_disp);
|
|
|
|
eglReleaseThread();
|
2014-09-01 03:40:07 -07:00
|
|
|
_tls_context_set(EGL_NO_CONTEXT);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
#else
|
2014-10-25 04:04:52 -07:00
|
|
|
glXDestroyWindow(gw->disp, gw->glxwin);
|
2012-05-15 06:13:05 -07:00
|
|
|
if (ref == 0)
|
|
|
|
{
|
2014-09-01 03:40:07 -07:00
|
|
|
GLXContext rgbactx = _tls_rgba_context_get();
|
2012-05-15 06:13:05 -07:00
|
|
|
if (context) glXDestroyContext(gw->disp, context);
|
2014-09-01 03:40:07 -07:00
|
|
|
if (rgbactx) glXDestroyContext(gw->disp, rgbactx);
|
2015-04-06 05:57:32 -07:00
|
|
|
eina_hash_free(_evas_gl_visuals);
|
|
|
|
_evas_gl_visuals = NULL;
|
2014-09-01 03:40:07 -07:00
|
|
|
_tls_context_set(0);
|
|
|
|
_tls_rgba_context_set(0);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
free(gw);
|
|
|
|
}
|
|
|
|
|
2013-06-23 19:41:32 -07:00
|
|
|
static Eina_Bool
|
|
|
|
eng_window_make_current(void *data, void *doit)
|
|
|
|
{
|
2014-06-30 23:43:27 -07:00
|
|
|
Outbuf *gw = data;
|
2013-06-23 19:41:32 -07:00
|
|
|
|
|
|
|
#ifdef GL_GLES
|
2015-08-18 01:35:40 -07:00
|
|
|
SET_RESTORE_CONTEXT();
|
2013-06-23 19:41:32 -07:00
|
|
|
if (doit)
|
|
|
|
{
|
2016-12-16 07:12:30 -08:00
|
|
|
if (!evas_eglMakeCurrent(gw->egl_disp, gw->egl_surface, gw->egl_surface, gw->egl_context))
|
2013-06-23 19:41:32 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-11-06 00:50:22 -08:00
|
|
|
if (!evas_eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
|
2013-06-23 19:41:32 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if (doit)
|
|
|
|
{
|
2014-10-25 04:04:52 -07:00
|
|
|
if (!__glXMakeContextCurrent(gw->disp, gw->glxwin, gw->context))
|
2013-06-23 19:41:32 -07:00
|
|
|
{
|
2014-10-25 04:04:52 -07:00
|
|
|
ERR("glXMakeContextCurrent(%p, %p, %p, %p)", (void *)gw->disp, (void *)gw->glxwin, (void *)gw->win, (void *)gw->context);
|
|
|
|
return EINA_FALSE;
|
2013-06-23 19:41:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-10-25 04:04:52 -07:00
|
|
|
if (!__glXMakeContextCurrent(gw->disp, 0, NULL))
|
2013-06-23 19:41:32 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
void
|
2014-06-30 23:43:27 -07:00
|
|
|
eng_window_use(Outbuf *gw)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
|
|
|
Eina_Bool force_use = EINA_FALSE;
|
2014-09-01 03:40:07 -07:00
|
|
|
Outbuf *xwin;
|
|
|
|
|
2014-09-19 01:44:56 -07:00
|
|
|
xwin = _tls_outbuf_get();
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_preload_render_lock(eng_window_make_current, gw);
|
2016-07-04 23:56:43 -07:00
|
|
|
if ((gw) && (!gw->gl_context)) return;
|
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2019-03-28 17:16:22 -07:00
|
|
|
if (xwin)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2015-11-06 00:50:22 -08:00
|
|
|
if ((evas_eglGetCurrentDisplay() != xwin->egl_disp) ||
|
2016-12-16 07:12:30 -08:00
|
|
|
(evas_eglGetCurrentContext() != xwin->egl_context))
|
2014-09-01 03:40:07 -07:00
|
|
|
force_use = EINA_TRUE;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
#else
|
2019-03-28 17:16:22 -07:00
|
|
|
if (xwin)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2014-09-01 03:40:07 -07:00
|
|
|
if (glXGetCurrentContext() != xwin->context)
|
2012-05-15 06:13:05 -07:00
|
|
|
force_use = EINA_TRUE;
|
|
|
|
}
|
|
|
|
#endif
|
2014-09-01 03:40:07 -07:00
|
|
|
if ((xwin != gw) || (force_use))
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2014-09-01 03:40:07 -07:00
|
|
|
if (xwin)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2014-09-01 03:40:07 -07:00
|
|
|
glsym_evas_gl_common_context_use(xwin->gl_context);
|
|
|
|
glsym_evas_gl_common_context_flush(xwin->gl_context);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2014-09-19 01:44:56 -07:00
|
|
|
_tls_outbuf_set(gw);
|
2012-05-15 06:13:05 -07:00
|
|
|
if (gw)
|
|
|
|
{
|
|
|
|
// EGL / GLES
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2016-12-16 07:12:30 -08:00
|
|
|
if (gw->egl_surface != EGL_NO_SURFACE)
|
2013-04-10 17:21:42 -07:00
|
|
|
{
|
2015-08-18 01:35:40 -07:00
|
|
|
SET_RESTORE_CONTEXT();
|
2015-11-06 00:50:22 -08:00
|
|
|
if (evas_eglMakeCurrent(gw->egl_disp,
|
2016-12-16 07:12:30 -08:00
|
|
|
gw->egl_surface,
|
|
|
|
gw->egl_surface,
|
|
|
|
gw->egl_context) == EGL_FALSE)
|
2013-04-10 17:21:42 -07:00
|
|
|
{
|
2015-11-06 00:50:22 -08:00
|
|
|
ERR("evas_eglMakeCurrent() failed!");
|
2013-04-10 17:21:42 -07:00
|
|
|
}
|
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
// GLX
|
|
|
|
#else
|
2014-10-25 04:04:52 -07:00
|
|
|
if (!__glXMakeContextCurrent(gw->disp, gw->glxwin, gw->context))
|
2013-04-10 17:21:42 -07:00
|
|
|
{
|
2014-10-25 04:04:52 -07:00
|
|
|
ERR("glXMakeContextCurrent(%p, %p, %p, %p)", (void *)gw->disp, (void *)gw->glxwin, (void *)gw->win, (void *)gw->context);
|
2013-04-10 17:21:42 -07:00
|
|
|
}
|
2012-05-15 06:13:05 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
2014-07-11 06:16:03 -07:00
|
|
|
if (gw) glsym_evas_gl_common_context_use(gw->gl_context);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-06-30 23:43:27 -07:00
|
|
|
eng_window_unsurf(Outbuf *gw)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
|
|
|
if (!gw->surf) return;
|
|
|
|
if (!getenv("EVAS_GL_WIN_RESURF")) return;
|
2014-10-25 04:04:52 -07:00
|
|
|
if (getenv("EVAS_GL_INFO")) printf("unsurf %p\n", gw);
|
2014-09-01 03:40:07 -07:00
|
|
|
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2014-09-01 03:40:07 -07:00
|
|
|
Outbuf *xwin;
|
|
|
|
|
2014-09-19 01:44:56 -07:00
|
|
|
xwin = _tls_outbuf_get();
|
2014-09-01 03:40:07 -07:00
|
|
|
if (xwin)
|
2014-09-19 01:44:56 -07:00
|
|
|
glsym_evas_gl_common_context_flush(xwin->gl_context);
|
2014-09-01 03:40:07 -07:00
|
|
|
if (xwin == gw)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2015-08-18 01:35:40 -07:00
|
|
|
SET_RESTORE_CONTEXT();
|
2015-11-06 00:50:22 -08:00
|
|
|
evas_eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
2016-12-16 07:12:30 -08:00
|
|
|
if (gw->egl_surface != EGL_NO_SURFACE)
|
|
|
|
eglDestroySurface(gw->egl_disp, gw->egl_surface);
|
|
|
|
gw->egl_surface = EGL_NO_SURFACE;
|
2014-09-19 01:44:56 -07:00
|
|
|
_tls_outbuf_set(NULL);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
if (gw->glxwin)
|
|
|
|
{
|
2014-10-25 04:04:52 -07:00
|
|
|
glXDestroyWindow(gw->disp, gw->glxwin);
|
|
|
|
gw->glxwin = 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
gw->surf = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-06-30 23:43:27 -07:00
|
|
|
eng_window_resurf(Outbuf *gw)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
|
|
|
if (gw->surf) return;
|
2014-10-25 04:04:52 -07:00
|
|
|
if (getenv("EVAS_GL_INFO")) printf("resurf %p\n", gw);
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2016-12-16 07:12:30 -08:00
|
|
|
gw->egl_surface = eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
|
2012-05-15 06:13:05 -07:00
|
|
|
(EGLNativeWindowType)gw->win,
|
|
|
|
NULL);
|
2016-12-16 07:12:30 -08:00
|
|
|
if (gw->egl_surface == EGL_NO_SURFACE)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
|
|
|
ERR("eglCreateWindowSurface() fail for %#x. code=%#x",
|
|
|
|
(unsigned int)gw->win, eglGetError());
|
|
|
|
return;
|
|
|
|
}
|
2015-08-18 01:35:40 -07:00
|
|
|
SET_RESTORE_CONTEXT();
|
2015-11-06 00:50:22 -08:00
|
|
|
if (evas_eglMakeCurrent(gw->egl_disp,
|
2016-12-16 07:12:30 -08:00
|
|
|
gw->egl_surface,
|
|
|
|
gw->egl_surface,
|
|
|
|
gw->egl_context) == EGL_FALSE)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2015-11-06 00:50:22 -08:00
|
|
|
ERR("evas_eglMakeCurrent() failed!");
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
#else
|
2015-04-06 05:57:32 -07:00
|
|
|
Evas_GL_X11_Visual *evis;
|
|
|
|
int idx = _visuals_hash_index_get(gw->alpha, gw->depth_bits, gw->stencil_bits, gw->msaa_bits);
|
|
|
|
evis = eina_hash_find(_evas_gl_visuals, &idx);
|
|
|
|
if (!evis)
|
|
|
|
{
|
|
|
|
eng_best_visual_get(gw->info);
|
|
|
|
evis = eina_hash_find(_evas_gl_visuals, &idx);
|
|
|
|
if (!evis)
|
|
|
|
{
|
|
|
|
ERR("Could not find matching visual! Resurf failed.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gw->glxwin = glXCreateWindow(gw->disp, evis->config, gw->win, NULL);
|
2014-10-25 04:04:52 -07:00
|
|
|
if (!__glXMakeContextCurrent(gw->disp, gw->glxwin, gw->context))
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2014-10-25 04:04:52 -07:00
|
|
|
ERR("glXMakeContextCurrent(%p, %p, %p, %p)", (void *)gw->disp, (void *)gw->glxwin, (void *)gw->win, (void *)gw->context);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
gw->surf = 1;
|
|
|
|
}
|
|
|
|
|
2013-01-08 14:47:40 -08:00
|
|
|
void *
|
2012-05-15 06:13:05 -07:00
|
|
|
eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo)
|
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
Evas_GL_X11_Visual *evis;
|
2015-04-12 18:04:10 -07:00
|
|
|
int alpha;
|
|
|
|
int depth_bits;
|
|
|
|
int stencil_bits;
|
|
|
|
int msaa_samples;
|
2015-04-06 05:57:32 -07:00
|
|
|
int config_attrs[40], i, num, idx;
|
|
|
|
Eina_Bool found;
|
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
if (!einfo) return NULL;
|
|
|
|
if (!einfo->info.display) return NULL;
|
2015-04-06 05:57:32 -07:00
|
|
|
|
2015-04-12 18:04:10 -07:00
|
|
|
alpha = einfo->info.destination_alpha;
|
|
|
|
depth_bits = einfo->depth_bits;
|
|
|
|
stencil_bits = einfo->stencil_bits;
|
|
|
|
msaa_samples = einfo->msaa_bits;
|
|
|
|
|
2015-04-06 05:57:32 -07:00
|
|
|
idx = _visuals_hash_index_get_from_info(einfo);
|
|
|
|
evis = eina_hash_find(_evas_gl_visuals, &idx);
|
|
|
|
if (evis)
|
|
|
|
return evis->info.visual;
|
|
|
|
|
|
|
|
evis = calloc(1, sizeof(Evas_GL_X11_Visual));
|
|
|
|
if (!evis) return NULL;
|
|
|
|
|
|
|
|
evis->alpha = alpha;
|
|
|
|
|
|
|
|
// EGL / GLES
|
2012-09-23 20:33:43 -07:00
|
|
|
#ifdef GL_GLES
|
2015-04-06 05:57:32 -07:00
|
|
|
EGLDisplay *egl_disp;
|
|
|
|
EGLConfig configs[200];
|
|
|
|
int major_version, minor_version;
|
|
|
|
const char *eglexts, *s;
|
|
|
|
int depth = DefaultDepth(einfo->info.display, einfo->info.screen);
|
2014-10-25 04:04:52 -07:00
|
|
|
|
2016-11-30 22:26:11 -08:00
|
|
|
egl_disp = _x11_eglGetDisplay(einfo->info.display);
|
2015-04-06 05:57:32 -07:00
|
|
|
if (!egl_disp)
|
|
|
|
{
|
|
|
|
free(evis);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (!eglInitialize(egl_disp, &major_version, &minor_version))
|
|
|
|
{
|
|
|
|
free(evis);
|
|
|
|
return NULL;
|
|
|
|
}
|
2014-10-25 04:04:52 -07:00
|
|
|
|
2015-04-06 05:57:32 -07:00
|
|
|
/* detect GLES 3.x support */
|
2017-08-25 10:51:59 -07:00
|
|
|
if (gles3_probed == EINA_FALSE)
|
2015-04-06 05:57:32 -07:00
|
|
|
{
|
2017-08-25 10:51:59 -07:00
|
|
|
gles3_probed = EINA_TRUE;
|
2015-03-05 02:21:24 -08:00
|
|
|
eglexts = eglQueryString(egl_disp, EGL_EXTENSIONS);
|
|
|
|
if (eglexts && strstr(eglexts, "EGL_KHR_create_context"))
|
|
|
|
{
|
|
|
|
int k, numconfigs = 0, value;
|
|
|
|
EGLConfig *eglconfigs;
|
|
|
|
|
|
|
|
if (eglGetConfigs(egl_disp, NULL, 0, &numconfigs) &&
|
|
|
|
(numconfigs > 0))
|
|
|
|
{
|
|
|
|
eglconfigs = alloca(numconfigs * sizeof(EGLConfig));
|
|
|
|
eglGetConfigs(egl_disp, eglconfigs, numconfigs, &numconfigs);
|
|
|
|
for (k = 0; k < numconfigs; k++)
|
|
|
|
{
|
|
|
|
value = 0;
|
|
|
|
if (eglGetConfigAttrib(egl_disp, eglconfigs[k], EGL_RENDERABLE_TYPE, &value) &&
|
|
|
|
((value & EGL_OPENGL_ES3_BIT_KHR) != 0) &&
|
|
|
|
eglGetConfigAttrib(egl_disp, eglconfigs[k], EGL_SURFACE_TYPE, &value) &&
|
|
|
|
((value & EGL_WINDOW_BIT) != 0))
|
|
|
|
{
|
|
|
|
INF("OpenGL ES 3.x is supported!");
|
|
|
|
gles3_supported = EINA_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gles3_supported &&
|
2015-03-17 18:04:27 -07:00
|
|
|
((s = getenv("EVAS_GL_DISABLE_GLES3")) && (atoi(s) == 1)))
|
2015-03-05 02:21:24 -08:00
|
|
|
{
|
|
|
|
INF("Disabling OpenGL ES 3.x support.");
|
|
|
|
gles3_supported = EINA_FALSE;
|
|
|
|
}
|
2015-04-06 05:57:32 -07:00
|
|
|
}
|
2015-03-05 02:21:24 -08:00
|
|
|
|
2015-04-06 05:57:32 -07:00
|
|
|
/* Find matching config & visual */
|
2015-03-16 20:12:19 -07:00
|
|
|
try_again:
|
2015-04-06 05:57:32 -07:00
|
|
|
i = 0;
|
|
|
|
config_attrs[i++] = EGL_SURFACE_TYPE;
|
|
|
|
config_attrs[i++] = EGL_WINDOW_BIT;
|
|
|
|
config_attrs[i++] = EGL_RENDERABLE_TYPE;
|
|
|
|
if (gles3_supported)
|
|
|
|
config_attrs[i++] = EGL_OPENGL_ES3_BIT_KHR;
|
|
|
|
else
|
|
|
|
config_attrs[i++] = EGL_OPENGL_ES2_BIT;
|
2014-10-25 04:04:52 -07:00
|
|
|
# if 0
|
2015-04-06 05:57:32 -07:00
|
|
|
// FIXME: n900 - omap3 sgx libs break here
|
|
|
|
config_attrs[n++] = EGL_RED_SIZE;
|
|
|
|
config_attrs[n++] = 1;
|
|
|
|
config_attrs[n++] = EGL_GREEN_SIZE;
|
|
|
|
config_attrs[n++] = 1;
|
|
|
|
config_attrs[n++] = EGL_BLUE_SIZE;
|
|
|
|
config_attrs[n++] = 1;
|
|
|
|
// FIXME: end n900 breakage
|
2014-10-25 04:04:52 -07:00
|
|
|
# endif
|
2019-04-24 00:39:23 -07:00
|
|
|
config_attrs[i++] = EGL_ALPHA_SIZE;
|
|
|
|
config_attrs[i++] = (alpha ? 1 : 0);
|
2015-03-15 21:57:09 -07:00
|
|
|
|
2015-04-06 05:57:32 -07:00
|
|
|
if (depth_bits)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = EGL_DEPTH_SIZE;
|
|
|
|
config_attrs[i++] = depth_bits;
|
|
|
|
}
|
2015-03-15 21:57:09 -07:00
|
|
|
|
2015-04-06 05:57:32 -07:00
|
|
|
if (stencil_bits)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = EGL_STENCIL_SIZE;
|
|
|
|
config_attrs[i++] = stencil_bits;
|
|
|
|
}
|
2015-03-15 21:57:09 -07:00
|
|
|
|
2015-04-06 05:57:32 -07:00
|
|
|
if (msaa_samples)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = EGL_SAMPLE_BUFFERS;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
config_attrs[i++] = EGL_SAMPLES;
|
|
|
|
config_attrs[i++] = msaa_samples;
|
|
|
|
}
|
|
|
|
config_attrs[i++] = EGL_NONE;
|
|
|
|
num = 0;
|
|
|
|
if ((!eglChooseConfig(egl_disp, config_attrs, configs, 200, &num))
|
|
|
|
|| (num < 1))
|
|
|
|
{
|
|
|
|
ERR("eglChooseConfig() can't find any configs (gles%d, alpha: %d, depth: %d, stencil: %d, msaa: %d)",
|
|
|
|
gles3_supported ? 3 : 2, alpha, depth_bits, stencil_bits, msaa_samples);
|
|
|
|
if ((depth_bits > 24) || (stencil_bits > 8))
|
|
|
|
{
|
|
|
|
WRN("Please note that your driver might not support 32-bit depth or "
|
|
|
|
"16-bit stencil buffers, so depth24, stencil8 are the maximum "
|
|
|
|
"recommended values.");
|
|
|
|
if (depth_bits > 24) depth_bits = 24;
|
|
|
|
if (stencil_bits > 8) stencil_bits = 8;
|
|
|
|
DBG("Trying again with depth:%d, stencil:%d", depth_bits, stencil_bits);
|
|
|
|
goto try_again;
|
|
|
|
}
|
|
|
|
else if (msaa_samples)
|
|
|
|
{
|
|
|
|
msaa_samples /= 2;
|
|
|
|
DBG("Trying again with msaa_samples: %d", msaa_samples);
|
|
|
|
goto try_again;
|
|
|
|
}
|
|
|
|
else if (depth_bits || stencil_bits)
|
|
|
|
{
|
|
|
|
depth_bits = 0;
|
|
|
|
stencil_bits = 0;
|
|
|
|
DBG("Trying again without any depth or stencil buffer");
|
|
|
|
goto try_again;
|
|
|
|
}
|
|
|
|
free(evis);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
found = EINA_FALSE;
|
|
|
|
for (i = 0; (i < num) && (!found); i++)
|
|
|
|
{
|
|
|
|
EGLint val = 0;
|
|
|
|
VisualID visid = 0;
|
|
|
|
XVisualInfo *xvi, vi_in;
|
|
|
|
int nvi, j;
|
|
|
|
|
|
|
|
if (!eglGetConfigAttrib(egl_disp, configs[i],
|
|
|
|
EGL_NATIVE_VISUAL_ID, &val))
|
|
|
|
continue;
|
|
|
|
visid = val;
|
|
|
|
vi_in.screen = einfo->info.screen;
|
|
|
|
vi_in.visualid = visid;
|
|
|
|
xvi = XGetVisualInfo(einfo->info.display,
|
|
|
|
VisualScreenMask |
|
|
|
|
VisualIDMask,
|
|
|
|
&vi_in, &nvi);
|
|
|
|
for (j = 0; j < nvi; j++)
|
|
|
|
{
|
|
|
|
if (!alpha)
|
2014-10-25 04:04:52 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
if (xvi[j].depth == depth)
|
2015-03-16 20:12:19 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
memcpy(&evis->info, &(xvi[j]), sizeof(XVisualInfo));
|
|
|
|
evis->config = configs[i];
|
|
|
|
found = EINA_TRUE;
|
|
|
|
break;
|
2015-03-16 20:12:19 -07:00
|
|
|
}
|
2014-10-25 04:04:52 -07:00
|
|
|
}
|
2015-04-06 05:57:32 -07:00
|
|
|
else
|
2014-10-25 04:04:52 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
XRenderPictFormat *fmt;
|
|
|
|
|
|
|
|
fmt = XRenderFindVisualFormat
|
|
|
|
(einfo->info.display, xvi[j].visual);
|
|
|
|
if ((fmt->direct.alphaMask > 0) &&
|
|
|
|
(fmt->type == PictTypeDirect))
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
memcpy(&evis->info, &(xvi[j]), sizeof(XVisualInfo));
|
|
|
|
evis->config = configs[i];
|
|
|
|
found = EINA_TRUE;
|
|
|
|
break;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
}
|
2015-04-06 05:57:32 -07:00
|
|
|
}
|
|
|
|
if (xvi) XFree(xvi);
|
|
|
|
}
|
|
|
|
if (!found)
|
|
|
|
{
|
|
|
|
// this is a less correct fallback if the above fails to
|
|
|
|
// find the right visuals/configs
|
|
|
|
if (!alpha)
|
|
|
|
{
|
|
|
|
evis->config = configs[0];
|
|
|
|
XMatchVisualInfo(einfo->info.display,
|
|
|
|
einfo->info.screen, depth, TrueColor,
|
|
|
|
&evis->info);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
XVisualInfo *xvi, vi_in;
|
|
|
|
int nvi, j;
|
|
|
|
XRenderPictFormat *fmt;
|
|
|
|
|
|
|
|
evis->config = configs[0];
|
|
|
|
vi_in.screen = einfo->info.screen;
|
|
|
|
vi_in.depth = 32;
|
|
|
|
vi_in.class = TrueColor;
|
|
|
|
xvi = XGetVisualInfo(einfo->info.display,
|
|
|
|
VisualScreenMask | VisualDepthMask |
|
|
|
|
VisualClassMask,
|
|
|
|
&vi_in, &nvi);
|
|
|
|
if (xvi)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
for (j = 0; j < nvi; j++)
|
2014-10-25 04:04:52 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
fmt = XRenderFindVisualFormat(einfo->info.display,
|
|
|
|
xvi[j].visual);
|
|
|
|
if ((fmt->type == PictTypeDirect) &&
|
|
|
|
(fmt->direct.alphaMask))
|
2014-10-25 04:04:52 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
memcpy(&evis->info, &(xvi[j]), sizeof(XVisualInfo));
|
|
|
|
break;
|
2014-10-25 04:04:52 -07:00
|
|
|
}
|
|
|
|
}
|
2015-04-06 05:57:32 -07:00
|
|
|
XFree(xvi);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
}
|
2015-04-06 05:57:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// GLX
|
2012-05-15 06:13:05 -07:00
|
|
|
#else
|
2015-04-06 05:57:32 -07:00
|
|
|
GLXFBConfig *configs = NULL, config = 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
|
2015-03-16 20:21:00 -07:00
|
|
|
try_again:
|
2015-04-06 05:57:32 -07:00
|
|
|
i = 0;
|
|
|
|
config_attrs[i++] = GLX_DRAWABLE_TYPE;
|
|
|
|
config_attrs[i++] = GLX_WINDOW_BIT;
|
|
|
|
config_attrs[i++] = GLX_DOUBLEBUFFER;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
config_attrs[i++] = GLX_RED_SIZE;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
config_attrs[i++] = GLX_GREEN_SIZE;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
config_attrs[i++] = GLX_BLUE_SIZE;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
if (alpha)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = GLX_RENDER_TYPE;
|
|
|
|
config_attrs[i++] = GLX_RGBA_BIT;
|
|
|
|
config_attrs[i++] = GLX_ALPHA_SIZE;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
config_attrs[i++] = GLX_ALPHA_SIZE;
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
}
|
|
|
|
if (depth_bits)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = GLX_DEPTH_SIZE;
|
|
|
|
config_attrs[i++] = depth_bits;
|
|
|
|
}
|
|
|
|
if (stencil_bits)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = GLX_STENCIL_SIZE;
|
|
|
|
config_attrs[i++] = stencil_bits;
|
|
|
|
}
|
|
|
|
if (msaa_samples)
|
|
|
|
{
|
|
|
|
config_attrs[i++] = GLX_SAMPLE_BUFFERS;
|
|
|
|
config_attrs[i++] = 1;
|
|
|
|
config_attrs[i++] = GLX_SAMPLES;
|
|
|
|
config_attrs[i++] = msaa_samples;
|
|
|
|
}
|
|
|
|
config_attrs[i++] = GLX_AUX_BUFFERS;
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
config_attrs[i++] = GLX_STEREO;
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
config_attrs[i++] = GLX_TRANSPARENT_TYPE;
|
|
|
|
config_attrs[i++] = GLX_NONE;//GLX_TRANSPARENT_INDEX,GLX_TRANSPARENT_RGB
|
|
|
|
config_attrs[i++] = 0;
|
|
|
|
|
|
|
|
configs = glXChooseFBConfig(einfo->info.display,
|
|
|
|
einfo->info.screen,
|
|
|
|
config_attrs, &num);
|
|
|
|
if ((!configs) || (num < 1))
|
|
|
|
{
|
|
|
|
ERR("glXChooseFBConfig() can't find any configs (alpha: %d, depth: %d, stencil: %d, msaa: %d)",
|
|
|
|
alpha, depth_bits, stencil_bits, msaa_samples);
|
2015-04-19 19:44:27 -07:00
|
|
|
if (configs) XFree(configs);
|
2015-04-06 05:57:32 -07:00
|
|
|
if ((depth_bits > 24) || (stencil_bits > 8))
|
|
|
|
{
|
|
|
|
WRN("Please note that your driver might not support 32-bit depth or "
|
|
|
|
"16-bit stencil buffers, so depth24, stencil8 are the maximum "
|
|
|
|
"recommended values.");
|
|
|
|
if (depth_bits > 24) depth_bits = 24;
|
|
|
|
if (stencil_bits > 8) stencil_bits = 8;
|
|
|
|
DBG("Trying again with depth:%d, stencil:%d", depth_bits, stencil_bits);
|
|
|
|
goto try_again;
|
|
|
|
}
|
|
|
|
else if (msaa_samples)
|
|
|
|
{
|
|
|
|
msaa_samples /= 2;
|
|
|
|
DBG("Trying again with msaa_samples: %d", msaa_samples);
|
|
|
|
goto try_again;
|
|
|
|
}
|
|
|
|
else if (depth_bits || stencil_bits)
|
|
|
|
{
|
|
|
|
depth_bits = 0;
|
|
|
|
stencil_bits = 0;
|
|
|
|
DBG("Trying again without any depth or stencil buffer");
|
|
|
|
goto try_again;
|
|
|
|
}
|
|
|
|
free(evis);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
found = EINA_FALSE;
|
|
|
|
for (i = 0; (i < num) && !found; i++)
|
|
|
|
{
|
|
|
|
XVisualInfo *visinfo;
|
|
|
|
XRenderPictFormat *format = NULL;
|
|
|
|
|
|
|
|
visinfo = glXGetVisualFromFBConfig(einfo->info.display,
|
|
|
|
configs[i]);
|
|
|
|
if (!visinfo) continue;
|
|
|
|
if (visinfo->visual->class != TrueColor)
|
|
|
|
{
|
|
|
|
XFree(visinfo);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!alpha)
|
|
|
|
{
|
|
|
|
config = configs[i];
|
|
|
|
// ensure depth matches default depth!
|
|
|
|
if (DefaultDepth(einfo->info.display, 0) ==
|
|
|
|
visinfo->depth)
|
2015-03-16 20:21:00 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
memcpy(&evis->info, visinfo, sizeof(XVisualInfo));
|
|
|
|
evis->config = config;
|
|
|
|
found = EINA_TRUE;
|
|
|
|
XFree(visinfo);
|
|
|
|
break;
|
2015-03-16 20:21:00 -07:00
|
|
|
}
|
2015-04-06 05:57:32 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
format = XRenderFindVisualFormat
|
|
|
|
(einfo->info.display, visinfo->visual);
|
|
|
|
if (!format)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
XFree(visinfo);
|
|
|
|
continue;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2015-04-06 05:57:32 -07:00
|
|
|
if ((format->direct.alphaMask > 0) &&
|
|
|
|
(format->type == PictTypeDirect))
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
memcpy(&evis->info, visinfo, sizeof(XVisualInfo));
|
|
|
|
evis->config = configs[i];
|
|
|
|
evis->cmap = format->colormap;
|
|
|
|
found = EINA_TRUE;
|
2012-05-15 06:13:05 -07:00
|
|
|
XFree(visinfo);
|
2015-04-06 05:57:32 -07:00
|
|
|
break;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
}
|
2015-04-06 05:57:32 -07:00
|
|
|
XFree(visinfo);
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2015-04-06 05:57:32 -07:00
|
|
|
|
2015-04-19 19:44:27 -07:00
|
|
|
XFree(configs);
|
2015-04-06 05:57:32 -07:00
|
|
|
if (!found)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
ERR("Could not find a matching config. Now what?");
|
|
|
|
free(evis);
|
|
|
|
return NULL;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2015-04-06 05:57:32 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!evis->cmap)
|
|
|
|
{
|
|
|
|
/* save colormap now */
|
2015-11-17 01:36:31 -08:00
|
|
|
evis->disp = einfo->info.display;
|
2015-04-06 05:57:32 -07:00
|
|
|
evis->cmap = XCreateColormap(einfo->info.display,
|
|
|
|
RootWindow(einfo->info.display,
|
|
|
|
einfo->info.screen),
|
|
|
|
evis->info.visual, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
eina_hash_add(_evas_gl_visuals, &idx, evis);
|
|
|
|
return evis->info.visual;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Colormap
|
|
|
|
eng_best_colormap_get(Evas_Engine_Info_GL_X11 *einfo)
|
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
Evas_GL_X11_Visual *evis;
|
|
|
|
int idx;
|
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
if (!einfo) return 0;
|
|
|
|
if (!einfo->info.display) return 0;
|
2015-04-06 05:57:32 -07:00
|
|
|
idx = _visuals_hash_index_get_from_info(einfo);
|
|
|
|
evis = eina_hash_find(_evas_gl_visuals, &idx);
|
|
|
|
if (!evis)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
eng_best_visual_get(einfo);
|
|
|
|
evis = eina_hash_find(_evas_gl_visuals, &idx);
|
|
|
|
if (!evis) return 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2015-04-06 05:57:32 -07:00
|
|
|
return evis->cmap;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
eng_best_depth_get(Evas_Engine_Info_GL_X11 *einfo)
|
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
Evas_GL_X11_Visual *evis;
|
|
|
|
int idx;
|
|
|
|
|
2012-05-15 06:13:05 -07:00
|
|
|
if (!einfo) return 0;
|
|
|
|
if (!einfo->info.display) return 0;
|
2015-04-06 05:57:32 -07:00
|
|
|
idx = _visuals_hash_index_get_from_info(einfo);
|
|
|
|
evis = eina_hash_find(_evas_gl_visuals, &idx);
|
|
|
|
if (!evis)
|
2012-05-15 06:13:05 -07:00
|
|
|
{
|
2015-04-06 05:57:32 -07:00
|
|
|
eng_best_visual_get(einfo);
|
|
|
|
evis = eina_hash_find(_evas_gl_visuals, &idx);
|
|
|
|
if (!evis) return 0;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2015-04-06 05:57:32 -07:00
|
|
|
return evis->info.depth;
|
2012-05-15 06:13:05 -07:00
|
|
|
}
|
2013-12-26 23:56:30 -08:00
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
Context_3D *
|
2014-06-30 23:43:27 -07:00
|
|
|
eng_gl_context_new(Outbuf *win)
|
2013-12-26 23:56:30 -08:00
|
|
|
{
|
2014-07-11 06:16:03 -07:00
|
|
|
Context_3D *ctx;
|
2013-12-26 23:56:30 -08:00
|
|
|
#if GL_GLES
|
|
|
|
int context_attrs[3] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!win) return NULL;
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
ctx = calloc(1, sizeof(Context_3D));
|
2013-12-26 23:56:30 -08:00
|
|
|
if (!ctx) return NULL;
|
|
|
|
|
|
|
|
#if GL_GLES
|
2017-08-25 10:51:59 -07:00
|
|
|
if (gles3_supported)
|
2015-03-05 02:21:24 -08:00
|
|
|
context_attrs[1] = 3;
|
2013-12-26 23:56:30 -08:00
|
|
|
ctx->context = eglCreateContext(win->egl_disp, win->egl_config,
|
2016-12-16 07:12:30 -08:00
|
|
|
win->egl_context, context_attrs);
|
2013-12-26 23:56:30 -08:00
|
|
|
|
|
|
|
if (!ctx->context)
|
|
|
|
{
|
|
|
|
ERR("EGL context creation failed.");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx->display = win->egl_disp;
|
2016-12-16 07:12:30 -08:00
|
|
|
ctx->surface = win->egl_surface;
|
2013-12-26 23:56:30 -08:00
|
|
|
#else
|
|
|
|
ctx->context = glXCreateContext(win->disp, win->visualinfo, win->context, 1);
|
|
|
|
|
|
|
|
if (!ctx->context)
|
|
|
|
{
|
|
|
|
ERR("GLX context creation failed.");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx->display = win->disp;
|
|
|
|
ctx->glxwin = win->glxwin;
|
|
|
|
ctx->win = win->win;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return ctx;
|
|
|
|
|
|
|
|
error:
|
|
|
|
free(ctx);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-07-11 06:16:03 -07:00
|
|
|
eng_gl_context_free(Context_3D *ctx)
|
2013-12-26 23:56:30 -08:00
|
|
|
{
|
|
|
|
#if GL_GLES
|
|
|
|
eglDestroyContext(ctx->display, ctx->context);
|
|
|
|
#else
|
|
|
|
glXDestroyContext(ctx->display, ctx->context);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
free(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-07-11 06:16:03 -07:00
|
|
|
eng_gl_context_use(Context_3D *ctx)
|
2013-12-26 23:56:30 -08:00
|
|
|
{
|
|
|
|
#if GL_GLES
|
2015-08-18 01:35:40 -07:00
|
|
|
SET_RESTORE_CONTEXT();
|
2015-11-06 00:50:22 -08:00
|
|
|
if (evas_eglMakeCurrent(ctx->display, ctx->surface,
|
2013-12-26 23:56:30 -08:00
|
|
|
ctx->surface, ctx->context) == EGL_FALSE)
|
|
|
|
{
|
2015-11-06 00:50:22 -08:00
|
|
|
ERR("evas_eglMakeCurrent() failed.");
|
2013-12-26 23:56:30 -08:00
|
|
|
}
|
|
|
|
#else
|
2014-10-25 04:04:52 -07:00
|
|
|
if (!__glXMakeContextCurrent(ctx->display, ctx->glxwin, ctx->context))
|
2013-12-26 23:56:30 -08:00
|
|
|
{
|
2017-12-13 09:53:33 -08:00
|
|
|
ERR("glXMakeContextCurrent(%p, %p, %p, %p) failed.",
|
2014-10-25 04:04:52 -07:00
|
|
|
(void *)ctx->display, (void *)ctx->glxwin,
|
|
|
|
(void *)ctx->win, (void *)ctx->context);
|
2013-12-26 23:56:30 -08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
2014-07-04 04:51:32 -07:00
|
|
|
|
|
|
|
void
|
|
|
|
eng_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth EINA_UNUSED)
|
|
|
|
{
|
|
|
|
ob->w = w;
|
|
|
|
ob->h = h;
|
|
|
|
ob->rot = rot;
|
|
|
|
eng_window_use(ob);
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_common_context_resize(ob->gl_context, w, h, rot);
|
2014-07-04 04:51:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
eng_outbuf_get_rot(Outbuf *ob)
|
|
|
|
{
|
|
|
|
return ob->rot;
|
|
|
|
}
|
|
|
|
|
2017-08-25 10:49:15 -07:00
|
|
|
Render_Output_Swap_Mode
|
2014-07-04 04:51:32 -07:00
|
|
|
eng_outbuf_swap_mode(Outbuf *ob)
|
|
|
|
{
|
|
|
|
if (ob->swap_mode == MODE_AUTO && extn_have_buffer_age)
|
|
|
|
{
|
2017-08-25 10:49:15 -07:00
|
|
|
Render_Output_Swap_Mode swap_mode;
|
2016-11-06 18:47:46 -08:00
|
|
|
eina_evlog("+gl_query_surf_swap_mode", ob, 0.0, NULL);
|
2018-10-09 06:04:05 -07:00
|
|
|
measure(0, "query age");
|
2014-07-04 04:51:32 -07:00
|
|
|
#ifdef GL_GLES
|
|
|
|
EGLint age = 0;
|
|
|
|
|
2016-12-16 07:12:30 -08:00
|
|
|
if (!eglQuerySurface(ob->egl_disp, ob->egl_surface,
|
2014-07-04 04:51:32 -07:00
|
|
|
EGL_BUFFER_AGE_EXT, &age))
|
|
|
|
age = 0;
|
|
|
|
#else
|
|
|
|
unsigned int age = 0;
|
|
|
|
|
|
|
|
if (glsym_glXQueryDrawable)
|
2018-10-09 07:08:59 -07:00
|
|
|
glsym_glXQueryDrawable(ob->disp, ob->glxwin,
|
|
|
|
GLX_BACK_BUFFER_AGE_EXT, &age);
|
2014-07-04 04:51:32 -07:00
|
|
|
#endif
|
2018-10-09 06:04:05 -07:00
|
|
|
measure(1, "query age");
|
2014-07-04 04:51:32 -07:00
|
|
|
if (age == 1) swap_mode = MODE_COPY;
|
|
|
|
else if (age == 2) swap_mode = MODE_DOUBLE;
|
|
|
|
else if (age == 3) swap_mode = MODE_TRIPLE;
|
|
|
|
else if (age == 4) swap_mode = MODE_QUADRUPLE;
|
|
|
|
else swap_mode = MODE_FULL;
|
2016-11-06 18:45:08 -08:00
|
|
|
if ((int)age != ob->prev_age)
|
|
|
|
{
|
|
|
|
char buf[16];
|
|
|
|
snprintf(buf, sizeof(buf), "! %i", (int)age);
|
|
|
|
eina_evlog("!gl_buffer_age", ob, 0.0, buf);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char buf[16];
|
|
|
|
snprintf(buf, sizeof(buf), "%i", (int)age);
|
|
|
|
eina_evlog("!gl_buffer_age", ob, 0.0, buf);
|
|
|
|
}
|
2014-07-04 04:51:32 -07:00
|
|
|
ob->prev_age = age;
|
|
|
|
|
2016-11-06 18:47:46 -08:00
|
|
|
eina_evlog("-gl_query_surf_swap_mode", ob, 0.0, NULL);
|
2014-07-04 04:51:32 -07:00
|
|
|
return swap_mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ob->swap_mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
Eina_Bool
|
|
|
|
eng_outbuf_region_first_rect(Outbuf *ob)
|
|
|
|
{
|
|
|
|
ob->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM;
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_preload_render_lock(eng_preload_make_current, ob);
|
2014-07-04 04:51:32 -07:00
|
|
|
#ifdef GL_GLES
|
2014-10-25 04:04:52 -07:00
|
|
|
// dont need to for egl - eng_window_use() can check for other ctxt's
|
2014-07-04 04:51:32 -07:00
|
|
|
#else
|
|
|
|
eng_window_use(NULL);
|
|
|
|
#endif
|
|
|
|
eng_window_use(ob);
|
|
|
|
if (!_re_wincheck(ob)) return EINA_TRUE;
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_common_context_resize(ob->gl_context,
|
2014-07-09 06:10:08 -07:00
|
|
|
ob->w, ob->h,
|
|
|
|
ob->rot);
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_common_context_flush(ob->gl_context);
|
|
|
|
glsym_evas_gl_common_context_newframe(ob->gl_context);
|
2014-07-04 04:51:32 -07:00
|
|
|
if (partial_render_debug == 1)
|
|
|
|
{
|
|
|
|
glClearColor(0.2, 0.5, 1.0, 1.0);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2015-07-29 14:12:35 -07:00
|
|
|
#ifdef GL_GLES
|
|
|
|
static void
|
|
|
|
_convert_to_glcoords(int *result, Outbuf *ob, int x, int y, int w, int h)
|
|
|
|
{
|
|
|
|
|
|
|
|
switch (ob->rot)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
result[0] = x;
|
|
|
|
result[1] = ob->gl_context->h - (y + h);
|
|
|
|
result[2] = w;
|
|
|
|
result[3] = h;
|
|
|
|
break;
|
|
|
|
case 90:
|
|
|
|
result[0] = y;
|
|
|
|
result[1] = x;
|
|
|
|
result[2] = h;
|
|
|
|
result[3] = w;
|
|
|
|
break;
|
|
|
|
case 180:
|
|
|
|
result[0] = ob->gl_context->w - (x + w);
|
|
|
|
result[1] = y;
|
|
|
|
result[2] = w;
|
|
|
|
result[3] = h;
|
|
|
|
break;
|
|
|
|
case 270:
|
|
|
|
result[0] = ob->gl_context->h - (y + h);
|
|
|
|
result[1] = ob->gl_context->w - (x + w);
|
|
|
|
result[2] = h;
|
|
|
|
result[3] = w;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
result[0] = x;
|
|
|
|
result[1] = ob->gl_context->h - (y + h);
|
|
|
|
result[2] = w;
|
|
|
|
result[3] = h;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-20 12:13:49 -07:00
|
|
|
void
|
|
|
|
eng_outbuf_damage_region_set(Outbuf *ob, Tilebuf_Rect *damage)
|
2015-07-29 14:12:35 -07:00
|
|
|
{
|
2016-10-20 12:13:49 -07:00
|
|
|
if (glsym_eglSetDamageRegionKHR)
|
2015-07-29 14:12:35 -07:00
|
|
|
{
|
2016-10-20 12:13:49 -07:00
|
|
|
Tilebuf_Rect *tr;
|
|
|
|
int *rect, *rects, count;
|
2015-07-29 14:12:35 -07:00
|
|
|
|
2016-10-20 12:13:49 -07:00
|
|
|
count = eina_inlist_count(EINA_INLIST_GET(damage));
|
|
|
|
rects = alloca(sizeof(int) * 4 * count);
|
|
|
|
rect = rects;
|
|
|
|
EINA_INLIST_FOREACH(damage, tr)
|
|
|
|
{
|
|
|
|
_convert_to_glcoords(rect, ob, tr->x, tr->y, tr->w, tr->h);
|
|
|
|
rect += 4;
|
|
|
|
}
|
2016-12-16 07:12:30 -08:00
|
|
|
glsym_eglSetDamageRegionKHR(ob->egl_disp, ob->egl_surface, rects, count);
|
2016-10-20 12:13:49 -07:00
|
|
|
}
|
2015-07-29 14:12:35 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-07-04 04:51:32 -07:00
|
|
|
void*
|
|
|
|
eng_outbuf_new_region_for_update(Outbuf *ob,
|
|
|
|
int x, int y, int w, int h,
|
|
|
|
int *cx EINA_UNUSED, int *cy EINA_UNUSED,
|
|
|
|
int *cw EINA_UNUSED, int *ch EINA_UNUSED)
|
|
|
|
{
|
2016-12-02 15:30:02 -08:00
|
|
|
if (w == (int) ob->w && h == (int) ob->h)
|
2014-07-04 04:51:32 -07:00
|
|
|
{
|
|
|
|
ob->gl_context->master_clip.enabled = EINA_FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ob->gl_context->master_clip.enabled = EINA_TRUE;
|
|
|
|
ob->gl_context->master_clip.x = x;
|
|
|
|
ob->gl_context->master_clip.y = y;
|
|
|
|
ob->gl_context->master_clip.w = w;
|
|
|
|
ob->gl_context->master_clip.h = h;
|
|
|
|
}
|
|
|
|
return ob->gl_context->def_surface;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
eng_outbuf_push_updated_region(Outbuf *ob, RGBA_Image *update EINA_UNUSED,
|
|
|
|
int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED)
|
|
|
|
{
|
|
|
|
/* Is it really necessary to flush per region ? Shouldn't we be able to
|
|
|
|
still do that for the full canvas when doing partial update */
|
|
|
|
if (!_re_wincheck(ob)) return;
|
|
|
|
ob->draw.drew = 1;
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_common_context_flush(ob->gl_context);
|
2014-07-04 04:51:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-10-19 13:33:09 -07:00
|
|
|
eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *surface_damage EINA_UNUSED, Tilebuf_Rect *buffer_damage, Evas_Render_Mode render_mode)
|
2014-07-04 04:51:32 -07:00
|
|
|
{
|
2016-10-19 13:33:09 -07:00
|
|
|
Tilebuf_Rect *rects = buffer_damage;
|
|
|
|
|
2014-07-04 04:51:32 -07:00
|
|
|
if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end;
|
|
|
|
|
|
|
|
if (!_re_wincheck(ob)) goto end;
|
|
|
|
if (!ob->draw.drew) goto end;
|
|
|
|
|
|
|
|
ob->draw.drew = 0;
|
|
|
|
eng_window_use(ob);
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_common_context_done(ob->gl_context);
|
2014-07-04 04:51:32 -07:00
|
|
|
|
|
|
|
// Save contents of the framebuffer to a file
|
|
|
|
if (swap_buffer_debug_mode == 1)
|
|
|
|
{
|
|
|
|
if (swap_buffer_debug)
|
|
|
|
{
|
|
|
|
char fname[100];
|
|
|
|
int ret = 0;
|
|
|
|
snprintf(fname, sizeof(fname), "%p", (void*)ob);
|
|
|
|
|
2014-07-11 06:16:03 -07:00
|
|
|
ret = glsym_evas_gl_common_buffer_dump(ob->gl_context,
|
|
|
|
(const char*)debug_dir,
|
|
|
|
(const char*)fname,
|
|
|
|
ob->frame_cnt,
|
|
|
|
NULL);
|
2014-07-04 04:51:32 -07:00
|
|
|
if (!ret) swap_buffer_debug_mode = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef GL_GLES
|
|
|
|
if (!ob->vsync)
|
|
|
|
{
|
|
|
|
if (ob->info->vsync) eglSwapInterval(ob->egl_disp, 1);
|
|
|
|
else eglSwapInterval(ob->egl_disp, 0);
|
|
|
|
ob->vsync = 1;
|
|
|
|
}
|
2015-10-05 22:37:10 -07:00
|
|
|
if ((glsym_eglSwapBuffersWithDamage) && (rects) &&
|
|
|
|
(ob->swap_mode != MODE_FULL))
|
2014-07-04 04:51:32 -07:00
|
|
|
{
|
|
|
|
EGLint num = 0, *result = NULL, i = 0;
|
|
|
|
Tilebuf_Rect *r;
|
|
|
|
|
|
|
|
// if partial swaps can be done use re->rects
|
|
|
|
num = eina_inlist_count(EINA_INLIST_GET(rects));
|
|
|
|
if (num > 0)
|
|
|
|
{
|
|
|
|
result = alloca(sizeof(EGLint) * 4 * num);
|
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
|
|
|
|
{
|
2015-07-29 14:12:35 -07:00
|
|
|
_convert_to_glcoords(&result[i], ob, r->x, r->y, r->w, r->h);
|
2014-07-04 04:51:32 -07:00
|
|
|
i += 4;
|
|
|
|
}
|
2018-10-09 06:04:05 -07:00
|
|
|
measure(0, "swap with damage");
|
2014-07-04 04:51:32 -07:00
|
|
|
glsym_eglSwapBuffersWithDamage(ob->egl_disp,
|
2016-12-16 07:12:30 -08:00
|
|
|
ob->egl_surface,
|
2014-07-06 09:16:10 -07:00
|
|
|
result, num);
|
2018-10-09 06:04:05 -07:00
|
|
|
measure(1, "swap with damage");
|
2014-07-04 04:51:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2018-10-09 06:04:05 -07:00
|
|
|
{
|
|
|
|
measure(0, "swap");
|
|
|
|
eglSwapBuffers(ob->egl_disp, ob->egl_surface);
|
|
|
|
measure(1, "swap");
|
|
|
|
}
|
2014-07-04 04:51:32 -07:00
|
|
|
|
|
|
|
//xx if (!safe_native) eglWaitGL();
|
|
|
|
// if (eglGetError() != EGL_SUCCESS)
|
|
|
|
// {
|
|
|
|
// printf("Error: eglSwapBuffers() fail.\n");
|
|
|
|
// }
|
|
|
|
#else
|
|
|
|
(void)rects;
|
|
|
|
#ifdef VSYNC_TO_SCREEN
|
|
|
|
if (ob->info->vsync)
|
|
|
|
{
|
|
|
|
if (glsym_glXSwapIntervalEXT)
|
|
|
|
{
|
|
|
|
if (!ob->vsync)
|
|
|
|
{
|
|
|
|
if (ob->info->vsync) glsym_glXSwapIntervalEXT(ob->disp, ob->win, 1);
|
|
|
|
else glsym_glXSwapIntervalEXT(ob->disp, ob->win, 0);
|
|
|
|
ob->vsync = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (glsym_glXSwapIntervalSGI)
|
|
|
|
{
|
|
|
|
if (!ob->vsync)
|
|
|
|
{
|
|
|
|
if (ob->info->vsync) glsym_glXSwapIntervalSGI(1);
|
|
|
|
else glsym_glXSwapIntervalSGI(0);
|
|
|
|
ob->vsync = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((glsym_glXGetVideoSync) && (glsym_glXWaitVideoSync))
|
|
|
|
{
|
|
|
|
unsigned int rc;
|
|
|
|
|
|
|
|
glsym_glXGetVideoSync(&rc);
|
|
|
|
glsym_glXWaitVideoSync(1, 0, &rc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
// XXX: if partial swaps can be done use re->rects
|
2018-10-09 06:04:05 -07:00
|
|
|
measure(0, "swap");
|
2014-10-25 04:04:52 -07:00
|
|
|
glXSwapBuffers(ob->disp, ob->glxwin);
|
2018-10-09 06:04:05 -07:00
|
|
|
measure(1, "swap");
|
2014-07-04 04:51:32 -07:00
|
|
|
#endif
|
|
|
|
// clear out rects after swap as we may use them during swap
|
|
|
|
|
|
|
|
ob->frame_cnt++;
|
|
|
|
|
|
|
|
end:
|
2014-07-11 06:16:03 -07:00
|
|
|
glsym_evas_gl_preload_render_unlock(eng_preload_make_current, ob);
|
|
|
|
}
|
|
|
|
|
|
|
|
Evas_Engine_GL_Context *
|
|
|
|
eng_outbuf_gl_context_get(Outbuf *ob)
|
|
|
|
{
|
|
|
|
return ob->gl_context;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
|
|
|
eng_outbuf_egl_display_get(Outbuf *ob)
|
|
|
|
{
|
|
|
|
#ifdef GL_GLES
|
|
|
|
return ob->egl_disp;
|
|
|
|
#else
|
|
|
|
(void) ob;
|
|
|
|
return NULL;
|
|
|
|
#endif
|
2014-07-04 04:51:32 -07:00
|
|
|
}
|