#ifdef GL_GLES
typedef EGLContext GLContext;
-static EGLConfig fbconf = 0;
-static EGLConfig rgba_fbconf = 0;
-static Eina_Bool gles3_supported = EINA_FALSE;
+typedef EGLConfig GLConfig;
+static int gles3_supported = -1;
#else
// FIXME: this will only work for 1 display connection (glx land can have > 1)
typedef GLXContext GLContext;
+typedef GLXFBConfig GLConfig;
static Eina_TLS _rgba_context_key = 0;
-static GLXFBConfig fbconf = 0;
-static GLXFBConfig rgba_fbconf = 0;
#endif
-static XVisualInfo *_evas_gl_x11_vi = NULL;
-static XVisualInfo *_evas_gl_x11_rgba_vi = NULL;
-static Colormap _evas_gl_x11_cmap = 0;
-static Colormap _evas_gl_x11_rgba_cmap = 0;
+typedef struct _Evas_GL_X11_Visual Evas_GL_X11_Visual;
+struct _Evas_GL_X11_Visual
+{
+ XVisualInfo info;
+ GLConfig config;
+ Colormap cmap;
+ Eina_Bool alpha;
+};
+
+/* index (_visuals_hash_index_get) -> Evas_GL_X11_Visual */
+static Eina_Hash *_evas_gl_visuals = NULL;
static int win_count = 0;
static Eina_Bool initted = EINA_FALSE;
}
#endif
+static void
+_visuals_hash_del_cb(void *data)
+{
+ free(data);
+}
+
+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);
+}
+
Outbuf *
eng_window_new(Evas_Engine_Info_GL_X11 *info,
Evas *e,
int major_version, minor_version;
#else
GLXContext rgbactx;
+ Evas_GL_X11_Visual *evis2 = NULL;
+ int tmp;
#endif
const GLubyte *vendor, *renderer, *version, *glslversion;
int blacklist = 0;
- int val = 0;
+ int val = 0, idx;
+ Evas_GL_X11_Visual *evis;
+
+ 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;
+ }
- if (!fbconf) eng_best_visual_get(info);
- if (!_evas_gl_x11_vi) return NULL;
+ vis = evis->info.visual;
+ if (!vis) return NULL;
gw = calloc(1, sizeof(Outbuf));
if (!gw) return NULL;
gw->depth_bits = depth_bits;
gw->stencil_bits = stencil_bits;
gw->msaa_bits = msaa_bits;
-
- if (gw->alpha && _evas_gl_x11_rgba_vi)
- gw->visualinfo = _evas_gl_x11_rgba_vi;
- else
- gw->visualinfo = _evas_gl_x11_vi;
+ gw->visualinfo = &evis->info;
// EGL / GLES
#ifdef GL_GLES
return NULL;
}
- if (gw->alpha) gw->egl_config = rgba_fbconf;
- else gw->egl_config = fbconf;
+ gw->egl_config = evis->config;
gw->egl_surface[0] = eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
(EGLNativeWindowType)gw->win,
context = _tls_context_get();
if (!context)
{
+ 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;
+ }
+ }
if (indirect)
- context = glXCreateNewContext(gw->disp, fbconf,
+ context = glXCreateNewContext(gw->disp, evis2->config,
GLX_RGBA_TYPE, NULL,
GL_FALSE);
else
- context = glXCreateNewContext(gw->disp, fbconf,
+ context = glXCreateNewContext(gw->disp, evis2->config,
GLX_RGBA_TYPE, NULL,
GL_TRUE);
_tls_context_set(context);
rgbactx = _tls_rgba_context_get();
if ((gw->alpha) && (!rgbactx))
{
+ 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;
+ }
+ }
if (indirect)
- rgbactx = glXCreateNewContext(gw->disp, rgba_fbconf,
+ rgbactx = glXCreateNewContext(gw->disp, evis2->config,
GLX_RGBA_TYPE, context,
GL_FALSE);
else
- rgbactx = glXCreateNewContext(gw->disp, rgba_fbconf,
+ rgbactx = glXCreateNewContext(gw->disp, evis2->config,
GLX_RGBA_TYPE, context,
GL_TRUE);
_tls_rgba_context_set(rgbactx);
}
- if (gw->alpha)
- gw->glxwin = glXCreateWindow(gw->disp, rgba_fbconf, gw->win, NULL);
+
+ 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;
+ }
+ }
else
- gw->glxwin = glXCreateWindow(gw->disp, fbconf, gw->win, NULL);
+ evis2 = evis;
+ gw->glxwin = glXCreateWindow(gw->disp, evis2->config, gw->win, NULL);
+
if (!gw->glxwin)
{
ERR("glXCreateWindow failed.");
if (context) eglDestroyContext(gw->egl_disp, context);
eglTerminate(gw->egl_disp);
eglReleaseThread();
+ eina_hash_free(_evas_gl_visuals);
+ _evas_gl_visuals = NULL;
_tls_context_set(EGL_NO_CONTEXT);
- free(_evas_gl_x11_vi);
- free(_evas_gl_x11_rgba_vi);
- fbconf = 0;
- rgba_fbconf = 0;
- _evas_gl_x11_vi = NULL;
- _evas_gl_x11_rgba_vi = NULL;
}
#else
glXDestroyWindow(gw->disp, gw->glxwin);
GLXContext rgbactx = _tls_rgba_context_get();
if (context) glXDestroyContext(gw->disp, context);
if (rgbactx) glXDestroyContext(gw->disp, rgbactx);
- free(_evas_gl_x11_vi);
- free(_evas_gl_x11_rgba_vi);
+ eina_hash_free(_evas_gl_visuals);
+ _evas_gl_visuals = NULL;
_tls_context_set(0);
_tls_rgba_context_set(0);
- fbconf = 0;
- rgba_fbconf = 0;
- _evas_gl_x11_vi = NULL;
- _evas_gl_x11_rgba_vi = NULL;
}
#endif
free(gw);
ERR("eglMakeCurrent() failed!");
}
#else
- if (gw->alpha)
- gw->glxwin = glXCreateWindow(gw->disp, rgba_fbconf, gw->win, NULL);
- else
- gw->glxwin = glXCreateWindow(gw->disp, fbconf, gw->win, NULL);
+ 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);
if (!__glXMakeContextCurrent(gw->disp, gw->glxwin, gw->context))
{
ERR("glXMakeContextCurrent(%p, %p, %p, %p)", (void *)gw->disp, (void *)gw->glxwin, (void *)gw->win, (void *)gw->context);
void *
eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo)
{
+ Evas_GL_X11_Visual *evis;
+ int alpha = einfo->info.destination_alpha;
+ int depth_bits = einfo->depth_bits;
+ int stencil_bits = einfo->stencil_bits;
+ int msaa_samples = einfo->msaa_bits;
+ int config_attrs[40], i, num, idx;
+ Eina_Bool found;
+
if (!einfo) return NULL;
if (!einfo->info.display) return NULL;
- if (!_evas_gl_x11_vi)
- {
- int alpha;
-// EGL / GLES
+
+ 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
#ifdef GL_GLES
- EGLDisplay *egl_disp;
- EGLConfig configs[200];
- int major_version, minor_version;
- const char *eglexts, *s;
+ EGLDisplay *egl_disp;
+ EGLConfig configs[200];
+ int major_version, minor_version;
+ const char *eglexts, *s;
+ int depth = DefaultDepth(einfo->info.display, einfo->info.screen);
- egl_disp = eglGetDisplay((EGLNativeDisplayType)(einfo->info.display));
- if (!egl_disp) return NULL;
- if (!eglInitialize(egl_disp, &major_version, &minor_version)) return NULL;
+ egl_disp = eglGetDisplay((EGLNativeDisplayType)(einfo->info.display));
+ if (!egl_disp)
+ {
+ free(evis);
+ return NULL;
+ }
+ if (!eglInitialize(egl_disp, &major_version, &minor_version))
+ {
+ free(evis);
+ return NULL;
+ }
+ /* detect GLES 3.x support */
+ if (gles3_supported == -1)
+ {
eglexts = eglQueryString(egl_disp, EGL_EXTENSIONS);
if (eglexts && strstr(eglexts, "EGL_KHR_create_context"))
{
INF("Disabling OpenGL ES 3.x support.");
gles3_supported = EINA_FALSE;
}
+ }
- for (alpha = 0; alpha < 2; alpha++)
- {
- Eina_Bool found;
- int config_attrs[40], i, n, num;
- int depth = DefaultDepth(einfo->info.display,
- einfo->info.screen);
- int depth_bits = einfo->depth_bits;
- int stencil_bits = einfo->stencil_bits;
- int msaa_samples = einfo->msaa_bits;
-
+ /* Find matching config & visual */
try_again:
- n = 0;
- config_attrs[n++] = EGL_SURFACE_TYPE;
- config_attrs[n++] = EGL_WINDOW_BIT;
- config_attrs[n++] = EGL_RENDERABLE_TYPE;
- if (gles3_supported)
- config_attrs[n++] = EGL_OPENGL_ES3_BIT_KHR;
- else
- config_attrs[n++] = EGL_OPENGL_ES2_BIT;
+ 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;
# if 0
- // 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
+ // 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
# endif
- if (alpha)
- {
- config_attrs[n++] = EGL_ALPHA_SIZE;
- config_attrs[n++] = 1;
- }
- else
- {
- config_attrs[n++] = EGL_ALPHA_SIZE;
- config_attrs[n++] = 0;
- }
+ if (alpha)
+ {
+ config_attrs[i++] = EGL_ALPHA_SIZE;
+ config_attrs[i++] = 1;
+ }
+ else
+ {
+ config_attrs[i++] = EGL_ALPHA_SIZE;
+ config_attrs[i++] = 0;
+ }
- if (depth_bits)
- {
- config_attrs[n++] = EGL_DEPTH_SIZE;
- config_attrs[n++] = depth_bits;
- }
+ if (depth_bits)
+ {
+ config_attrs[i++] = EGL_DEPTH_SIZE;
+ config_attrs[i++] = depth_bits;
+ }
- if (stencil_bits)
- {
- config_attrs[n++] = EGL_STENCIL_SIZE;
- config_attrs[n++] = stencil_bits;
- }
+ if (stencil_bits)
+ {
+ config_attrs[i++] = EGL_STENCIL_SIZE;
+ config_attrs[i++] = stencil_bits;
+ }
- if (msaa_samples)
- {
- config_attrs[n++] = EGL_SAMPLE_BUFFERS;
- config_attrs[n++] = 1;
- config_attrs[n++] = EGL_SAMPLES;
- config_attrs[n++] = msaa_samples;
- }
- config_attrs[n++] = EGL_NONE;
- num = 0;
- if ((!eglChooseConfig(egl_disp, config_attrs, configs, 200, &num))
- || (num < 1))
+ 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)
{
- 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)
+ if (xvi[j].depth == depth)
{
- depth_bits = 0;
- stencil_bits = 0;
- DBG("Trying again without any depth or stencil buffer");
- goto try_again;
+ memcpy(&evis->info, &(xvi[j]), sizeof(XVisualInfo));
+ evis->config = configs[i];
+ found = EINA_TRUE;
+ break;
}
- return NULL;
}
- found = EINA_FALSE;
- for (i = 0; (i < num) && (!found); i++)
+ else
{
- 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++)
+ XRenderPictFormat *fmt;
+
+ fmt = XRenderFindVisualFormat
+ (einfo->info.display, xvi[j].visual);
+ if ((fmt->direct.alphaMask > 0) &&
+ (fmt->type == PictTypeDirect))
{
- if (!alpha)
- {
- if (xvi[j].depth == depth)
- {
- _evas_gl_x11_vi = malloc(sizeof(XVisualInfo));
- if (_evas_gl_x11_vi)
- memcpy(_evas_gl_x11_vi, &(xvi[j]), sizeof(XVisualInfo));
- fbconf = configs[i];
- found = EINA_TRUE;
- break;
- }
- }
- else
- {
- XRenderPictFormat *fmt;
-
- fmt = XRenderFindVisualFormat
- (einfo->info.display, xvi[j].visual);
- if ((fmt->direct.alphaMask > 0) &&
- (fmt->type == PictTypeDirect))
- {
- _evas_gl_x11_rgba_vi = malloc(sizeof(XVisualInfo));
- if (_evas_gl_x11_rgba_vi)
- memcpy(_evas_gl_x11_rgba_vi, &(xvi[j]), sizeof(XVisualInfo));
- rgba_fbconf = configs[i];
- found = EINA_TRUE;
- break;
- }
- }
+ memcpy(&evis->info, &(xvi[j]), sizeof(XVisualInfo));
+ evis->config = configs[i];
+ found = EINA_TRUE;
+ break;
}
- if (xvi) XFree(xvi);
}
- if (!found)
+ }
+ 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)
{
- // this is a less correct fallback if the above fails to
- // find the right visuals/configs
- if (!alpha)
- {
- fbconf = configs[0];
- _evas_gl_x11_vi = calloc(1, sizeof(XVisualInfo));
- if (_evas_gl_x11_vi)
- XMatchVisualInfo(einfo->info.display,
- einfo->info.screen, depth, TrueColor,
- _evas_gl_x11_vi);
- }
- else
+ for (j = 0; j < nvi; j++)
{
- XVisualInfo *xvi, vi_in;
- int nvi, j;
- XRenderPictFormat *fmt;
-
- rgba_fbconf = 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)
+ fmt = XRenderFindVisualFormat(einfo->info.display,
+ xvi[j].visual);
+ if ((fmt->type == PictTypeDirect) &&
+ (fmt->direct.alphaMask))
{
- for (j = 0; j < nvi; j++)
- {
- fmt = XRenderFindVisualFormat(einfo->info.display,
- xvi[j].visual);
- if ((fmt->type == PictTypeDirect) &&
- (fmt->direct.alphaMask))
- {
- _evas_gl_x11_rgba_vi =
- malloc(sizeof(XVisualInfo));
- if (_evas_gl_x11_rgba_vi)
- memcpy(_evas_gl_x11_rgba_vi,
- &(xvi[j]), sizeof(XVisualInfo));
- break;
- }
- }
- XFree(xvi);
+ memcpy(&evis->info, &(xvi[j]), sizeof(XVisualInfo));
+ break;
}
}
+ XFree(xvi);
}
}
-// GLX
+ }
+
+ // GLX
#else
- for (alpha = 0; alpha < 2; alpha++)
- {
- int config_attrs[40];
- GLXFBConfig *configs = NULL, config = 0;
- int i, num;
- int depth_bits = einfo->depth_bits;
- int stencil_bits = einfo->stencil_bits;
- int msaa_samples = einfo->msaa_bits;
+ GLXFBConfig *configs = NULL, config = 0;
try_again:
- 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;
- }
- config_attrs[i++] = GLX_DEPTH_SIZE;
- config_attrs[i++] = depth_bits;
- config_attrs[i++] = GLX_STENCIL_SIZE;
- config_attrs[i++] = stencil_bits;
- if (msaa_samples)
+ 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);
+ 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)
{
- config_attrs[i++] = GLX_SAMPLE_BUFFERS;
- config_attrs[i++] = 1;
- config_attrs[i++] = GLX_SAMPLES;
- config_attrs[i++] = msaa_samples;
+ memcpy(&evis->info, visinfo, sizeof(XVisualInfo));
+ evis->config = config;
+ found = EINA_TRUE;
+ XFree(visinfo);
+ break;
}
- 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_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))
+ }
+ else
+ {
+ format = XRenderFindVisualFormat
+ (einfo->info.display, visinfo->visual);
+ if (!format)
{
- ERR("glXChooseFBConfig() can't find any configs (alpha: %d, depth: %d, stencil: %d, msaa: %d)",
- 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;
- }
- return NULL;
+ XFree(visinfo);
+ continue;
}
- for (i = 0; i < num; i++)
+ if ((format->direct.alphaMask > 0) &&
+ (format->type == PictTypeDirect))
{
- 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)
- {
- _evas_gl_x11_vi = malloc(sizeof(XVisualInfo));
- if (_evas_gl_x11_vi)
- memcpy(_evas_gl_x11_vi, visinfo, sizeof(XVisualInfo));
- fbconf = config;
- XFree(visinfo);
- break;
- }
- }
- else
- {
- format = XRenderFindVisualFormat
- (einfo->info.display, visinfo->visual);
- if (!format)
- {
- XFree(visinfo);
- continue;
- }
- if ((format->direct.alphaMask > 0) &&
- (format->type == PictTypeDirect))
- {
- config = configs[i];
- _evas_gl_x11_rgba_vi = malloc(sizeof(XVisualInfo));
- if (_evas_gl_x11_rgba_vi)
- memcpy(_evas_gl_x11_rgba_vi, visinfo, sizeof(XVisualInfo));
- rgba_fbconf = config;
- _evas_gl_x11_rgba_cmap = format->colormap;
- XFree(visinfo);
- break;
- }
- }
+ memcpy(&evis->info, visinfo, sizeof(XVisualInfo));
+ evis->config = configs[i];
+ evis->cmap = format->colormap;
+ found = EINA_TRUE;
XFree(visinfo);
+ break;
}
}
-#endif
+ XFree(visinfo);
}
- if (!_evas_gl_x11_vi) return NULL;
- if (einfo->info.destination_alpha)
+
+ if (!found)
+ {
+ ERR("Could not find a matching config. Now what?");
+ free(evis);
+ return NULL;
+ }
+#endif
+
+ if (!evis->cmap)
{
- if (_evas_gl_x11_rgba_vi) return _evas_gl_x11_rgba_vi->visual;
+ /* save colormap now */
+ evis->cmap = XCreateColormap(einfo->info.display,
+ RootWindow(einfo->info.display,
+ einfo->info.screen),
+ evis->info.visual, 0);
}
- return _evas_gl_x11_vi->visual;
+
+ eina_hash_add(_evas_gl_visuals, &idx, evis);
+ return evis->info.visual;
}
Colormap
eng_best_colormap_get(Evas_Engine_Info_GL_X11 *einfo)
{
+ Evas_GL_X11_Visual *evis;
+ int idx;
+
if (!einfo) return 0;
if (!einfo->info.display) return 0;
- if (!_evas_gl_x11_vi) eng_best_visual_get(einfo);
- if (!_evas_gl_x11_vi) return 0;
- if ((einfo->info.destination_alpha) && (_evas_gl_x11_rgba_vi))
- {
- if (!_evas_gl_x11_rgba_cmap)
- _evas_gl_x11_rgba_cmap =
- XCreateColormap(einfo->info.display,
- RootWindow(einfo->info.display,
- einfo->info.screen),
- _evas_gl_x11_rgba_vi->visual,
- 0);
- return _evas_gl_x11_rgba_cmap;
- }
- if (!_evas_gl_x11_cmap)
- _evas_gl_x11_cmap =
- XCreateColormap(einfo->info.display,
- RootWindow(einfo->info.display,
- einfo->info.screen),
- _evas_gl_x11_vi->visual,
- 0);
- return _evas_gl_x11_cmap;
+ idx = _visuals_hash_index_get_from_info(einfo);
+ evis = eina_hash_find(_evas_gl_visuals, &idx);
+ if (!evis)
+ {
+ eng_best_visual_get(einfo);
+ evis = eina_hash_find(_evas_gl_visuals, &idx);
+ if (!evis) return 0;
+ }
+ return evis->cmap;
}
int
eng_best_depth_get(Evas_Engine_Info_GL_X11 *einfo)
{
+ Evas_GL_X11_Visual *evis;
+ int idx;
+
if (!einfo) return 0;
if (!einfo->info.display) return 0;
- if (!_evas_gl_x11_vi) eng_best_visual_get(einfo);
- if (!_evas_gl_x11_vi) return 0;
- if (einfo->info.destination_alpha)
+ idx = _visuals_hash_index_get_from_info(einfo);
+ evis = eina_hash_find(_evas_gl_visuals, &idx);
+ if (!evis)
{
- if (_evas_gl_x11_rgba_vi) return _evas_gl_x11_rgba_vi->depth;
+ eng_best_visual_get(einfo);
+ evis = eina_hash_find(_evas_gl_visuals, &idx);
+ if (!evis) return 0;
}
- return _evas_gl_x11_vi->depth;
+ return evis->info.depth;
}
Context_3D *