--- /dev/null
+#include "evas_engine.h"
+
+/* local function prototypes */
+
+/* local variables */
+static Evas_GL_Wl_Window *_evas_gl_wl_window = NULL;
+static EGLContext context = EGL_NO_CONTEXT;
+static int win_count = 0;
+
+Evas_GL_Wl_Window *
+eng_window_new(struct wl_display *display, struct wl_surface *surface, int screen, int depth, int w, int h, int indirect EINA_UNUSED, int alpha, int rot)
+{
+ Evas_GL_Wl_Window *gw;
+ int context_attrs[3];
+ int config_attrs[40];
+ int major_version, minor_version;
+ int num_config, n = 0;
+ const GLubyte *vendor, *renderer, *version;
+ Eina_Bool blacklist = EINA_FALSE;
+
+ /* try to allocate space for our window */
+ if (!(gw = calloc(1, sizeof(Evas_GL_Wl_Window))))
+ return NULL;
+
+ win_count++;
+ gw->disp = display;
+ gw->surface = surface;
+ gw->screen = screen;
+ gw->depth = depth;
+ gw->w = w;
+ gw->h = h;
+ gw->alpha = alpha;
+ gw->rot = rot;
+
+ context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
+ context_attrs[1] = 2;
+ context_attrs[2] = EGL_NONE;
+
+ config_attrs[n++] = EGL_SURFACE_TYPE;
+ config_attrs[n++] = EGL_WINDOW_BIT;
+ config_attrs[n++] = EGL_RENDERABLE_TYPE;
+ config_attrs[n++] = 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 */
+# endif
+ config_attrs[n++] = EGL_ALPHA_SIZE;
+ config_attrs[n++] = gw->alpha;
+ config_attrs[n++] = EGL_DEPTH_SIZE;
+ config_attrs[n++] = 0;
+ config_attrs[n++] = EGL_STENCIL_SIZE;
+ config_attrs[n++] = 0;
+ config_attrs[n++] = EGL_NONE;
+
+ /* FIXME: Remove this line as soon as eglGetDisplay() autodetection
+ * gets fixed. Currently it is incorrectly detecting wl_display and
+ * returning _EGL_PLATFORM_X11 instead of _EGL_PLATFORM_WAYLAND.
+ *
+ * See ticket #1972 for more info.
+ */
+
+ setenv("EGL_PLATFORM", "wayland", 1);
+
+ gw->egl_disp = eglGetDisplay((EGLNativeDisplayType)gw->disp);
+ if (!gw->egl_disp)
+ {
+ ERR("eglGetDisplay() fail. code=%#x", eglGetError());
+ eng_window_free(gw);
+ return NULL;
+ }
+ if (!eglInitialize(gw->egl_disp, &major_version, &minor_version))
+ {
+ ERR("eglInitialize() fail. code=%#x", eglGetError());
+ eng_window_free(gw);
+ return NULL;
+ }
+ eglBindAPI(EGL_OPENGL_ES_API);
+ if (eglGetError() != EGL_SUCCESS)
+ {
+ ERR("eglBindAPI() fail. code=%#x", eglGetError());
+ eng_window_free(gw);
+ return NULL;
+ }
+
+ num_config = 0;
+ if (!eglChooseConfig(gw->egl_disp, config_attrs, &gw->egl_config,
+ 1, &num_config) || (num_config != 1))
+ {
+ ERR("eglChooseConfig() fail. code=%#x", eglGetError());
+ eng_window_free(gw);
+ return NULL;
+ }
+
+ if ((gw->rot == 0) || (gw->rot == 180))
+ gw->win = wl_egl_window_create(gw->surface, gw->w, gw->h);
+ else if ((gw->rot == 90) || (gw->rot == 270))
+ gw->win = wl_egl_window_create(gw->surface, gw->h, gw->w);
+
+ gw->egl_surface[0] =
+ eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
+ (EGLNativeWindowType)gw->win, NULL);
+ if (gw->egl_surface[0] == EGL_NO_SURFACE)
+ {
+ ERR("eglCreateWindowSurface() fail for %p. code=%#x",
+ gw->win, eglGetError());
+ eng_window_free(gw);
+ return NULL;
+ }
+
+ gw->egl_context[0] =
+ eglCreateContext(gw->egl_disp, gw->egl_config, context, context_attrs);
+ if (gw->egl_context[0] == EGL_NO_CONTEXT)
+ {
+ ERR("eglCreateContext() fail. code=%#x", eglGetError());
+ eng_window_free(gw);
+ return NULL;
+ }
+
+ if (context == EGL_NO_CONTEXT) context = gw->egl_context[0];
+
+ if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0],
+ gw->egl_surface[0], gw->egl_context[0]) == EGL_FALSE)
+ {
+ ERR("eglMakeCurrent() fail. code=%#x", eglGetError());
+ eng_window_free(gw);
+ return NULL;
+ }
+
+ vendor = glGetString(GL_VENDOR);
+ renderer = glGetString(GL_RENDERER);
+ version = glGetString(GL_VERSION);
+ if (!vendor) vendor = (unsigned char *)"-UNKNOWN-";
+ if (!renderer) renderer = (unsigned char *)"-UNKNOWN-";
+ if (!version) version = (unsigned char *)"-UNKNOWN-";
+ if (getenv("EVAS_GL_INFO"))
+ {
+ fprintf(stderr, "vendor: %s\n", vendor);
+ fprintf(stderr, "renderer: %s\n", renderer);
+ fprintf(stderr, "version: %s\n", version);
+ }
+
+ if (strstr((const char *)vendor, "Mesa Project"))
+ {
+ if (strstr((const char *)renderer, "Software Rasterizer"))
+ blacklist = EINA_TRUE;
+ }
+ if (strstr((const char *)renderer, "softpipe"))
+ blacklist = EINA_TRUE;
+ if (strstr((const char *)renderer, "llvmpipe"))
+ blacklist = EINA_TRUE;
+ if ((blacklist) && (!getenv("EVAS_GL_NO_BLACKLIST")))
+ {
+ ERR("OpenGL Driver blacklisted:");
+ ERR("Vendor: %s", (const char *)vendor);
+ ERR("Renderer: %s", (const char *)renderer);
+ ERR("Version: %s", (const char *)version);
+ eng_window_free(gw);
+ return NULL;
+ }
+
+ if (!(gw->gl_context = evas_gl_common_context_new()))
+ {
+ eng_window_free(gw);
+ return NULL;
+ }
+
+ gw->gl_context->egldisp = gw->egl_disp;
+ gw->gl_context->eglctxt = gw->egl_context[0];
+
+ eng_window_use(gw);
+ evas_gl_common_context_resize(gw->gl_context, w, h, rot);
+
+ gw->surf = EINA_TRUE;
+
+ return gw;
+}
+
+void
+eng_window_free(Evas_GL_Wl_Window *gw)
+{
+ int ref = 0;
+
+ win_count--;
+ eng_window_use(gw);
+
+ if (gw == _evas_gl_wl_window) _evas_gl_wl_window = NULL;
+
+ if (gw->gl_context)
+ {
+ ref = gw->gl_context->references - 1;
+ evas_gl_common_context_free(gw->gl_context);
+ }
+
+ eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE,
+ EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ if (gw->egl_context[0] != context)
+ eglDestroyContext(gw->egl_disp, gw->egl_context[0]);
+
+ if (gw->egl_surface[0] != EGL_NO_SURFACE)
+ eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
+
+ if (gw->win) wl_egl_window_destroy(gw->win);
+
+ if (ref == 0)
+ {
+ if (context) eglDestroyContext(gw->egl_disp, context);
+ eglTerminate(gw->egl_disp);
+ context = EGL_NO_CONTEXT;
+ }
+
+ free(gw);
+}
+
+void
+eng_window_use(Evas_GL_Wl_Window *gw)
+{
+ Eina_Bool force = EINA_FALSE;
+
+ if (_evas_gl_wl_window)
+ {
+ if ((eglGetCurrentContext() !=
+ _evas_gl_wl_window->egl_context[0]) ||
+ (eglGetCurrentSurface(EGL_READ) !=
+ _evas_gl_wl_window->egl_surface[0]) ||
+ (eglGetCurrentSurface(EGL_DRAW) !=
+ _evas_gl_wl_window->egl_surface[0]))
+ force = EINA_TRUE;
+ }
+
+ if ((_evas_gl_wl_window != gw) || (force))
+ {
+ if (_evas_gl_wl_window)
+ {
+ evas_gl_common_context_use(_evas_gl_wl_window->gl_context);
+ evas_gl_common_context_flush(_evas_gl_wl_window->gl_context);
+ }
+
+ _evas_gl_wl_window = gw;
+
+ if (gw)
+ {
+ if (gw->egl_surface[0] != EGL_NO_SURFACE)
+ {
+ if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0],
+ gw->egl_surface[0],
+ gw->egl_context[0]) == EGL_FALSE)
+ ERR("eglMakeCurrent() failed!");
+ }
+ }
+ }
+
+ if (gw) evas_gl_common_context_use(gw->gl_context);
+}
+
+void
+eng_window_unsurf(Evas_GL_Wl_Window *gw)
+{
+ if (!gw->surf) return;
+ if (!getenv("EVAS_GL_WIN_RESURF")) return;
+ if (getenv("EVAS_GL_INFO")) printf("unsurf %p\n", gw);
+
+ if (_evas_gl_wl_window)
+ evas_gl_common_context_flush(_evas_gl_wl_window->gl_context);
+ if (_evas_gl_wl_window == gw)
+ {
+ eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE,
+ EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (gw->egl_surface[0] != EGL_NO_SURFACE)
+ eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
+ gw->egl_surface[0] = EGL_NO_SURFACE;
+
+ _evas_gl_wl_window = NULL;
+ }
+
+ gw->surf = EINA_FALSE;
+}
+
+void
+eng_window_resurf(Evas_GL_Wl_Window *gw)
+{
+ if (gw->surf) return;
+ if (getenv("EVAS_GL_INFO")) printf("resurf %p\n", gw);
+
+ gw->egl_surface[0] =
+ eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
+ (EGLNativeWindowType)gw->win, NULL);
+
+ if (gw->egl_surface[0] == EGL_NO_SURFACE)
+ {
+ ERR("eglCreateWindowSurface() fail for %p. code=%#x",
+ gw->win, eglGetError());
+ return;
+ }
+
+ if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], gw->egl_surface[0],
+ gw->egl_context[0]) == EGL_FALSE)
+ ERR("eglMakeCurrent() failed!");
+
+ gw->surf = EINA_TRUE;
+}