+
+
+/**
+ * Return EGL_TRUE if the given handle is a valid handle to a display.
+ */
+EGLBoolean
+_eglCheckDisplayHandle(EGLDisplay dpy)
+{
+ _EGLDisplay *cur;
+
+ mtx_lock(_eglGlobal.Mutex);
+ cur = _eglGlobal.DisplayList;
+ while (cur) {
+ if (cur == (_EGLDisplay *) dpy)
+ break;
+ cur = cur->Next;
+ }
+ mtx_unlock(_eglGlobal.Mutex);
+ return (cur != NULL);
+}
+
+
+/**
+ * Return EGL_TRUE if the given resource is valid. That is, the display does
+ * own the resource.
+ */
+EGLBoolean
+_eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *dpy)
+{
+ _EGLResource *list = dpy->ResourceLists[type];
+
+ if (!res)
+ return EGL_FALSE;
+
+ while (list) {
+ if (res == (void *) list) {
+ assert(list->Display == dpy);
+ break;
+ }
+ list = list->Next;
+ }
+
+ return (list != NULL);
+}
+
+
+/**
+ * Initialize a display resource. The size of the subclass object is
+ * specified.
+ *
+ * This is supposed to be called from the initializers of subclasses, such as
+ * _eglInitContext or _eglInitSurface.
+ */
+void
+_eglInitResource(_EGLResource *res, EGLint size, _EGLDisplay *dpy)
+{
+ memset(res, 0, size);
+ res->Display = dpy;
+ res->RefCount = 1;
+}
+
+
+/**
+ * Increment reference count for the resource.
+ */
+void
+_eglGetResource(_EGLResource *res)
+{
+ assert(res && res->RefCount > 0);
+ /* hopefully a resource is always manipulated with its display locked */
+ res->RefCount++;
+}
+
+
+/**
+ * Decrement reference count for the resource.
+ */
+EGLBoolean
+_eglPutResource(_EGLResource *res)
+{
+ assert(res && res->RefCount > 0);
+ res->RefCount--;
+ return (!res->RefCount);
+}
+
+
+/**
+ * Link a resource to its display.
+ */
+void
+_eglLinkResource(_EGLResource *res, _EGLResourceType type)
+{
+ assert(res->Display);
+
+ res->IsLinked = EGL_TRUE;
+ res->Next = res->Display->ResourceLists[type];
+ res->Display->ResourceLists[type] = res;
+ _eglGetResource(res);
+}
+
+
+/**
+ * Unlink a linked resource from its display.
+ */
+void
+_eglUnlinkResource(_EGLResource *res, _EGLResourceType type)
+{
+ _EGLResource *prev;
+
+ prev = res->Display->ResourceLists[type];
+ if (prev != res) {
+ while (prev) {
+ if (prev->Next == res)
+ break;
+ prev = prev->Next;
+ }
+ assert(prev);
+ prev->Next = res->Next;
+ }
+ else {
+ res->Display->ResourceLists[type] = res->Next;
+ }
+
+ res->Next = NULL;
+ res->IsLinked = EGL_FALSE;
+ _eglPutResource(res);
+
+ /* We always unlink before destroy. The driver still owns a reference */
+ assert(res->RefCount);
+}
+
+#ifdef HAVE_X11_PLATFORM
+static EGLBoolean
+_eglParseX11DisplayAttribList(const EGLint *attrib_list)
+{
+ int i;
+
+ if (attrib_list == NULL) {
+ return EGL_TRUE;
+ }
+
+ for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
+ EGLint attrib = attrib_list[i];
+ EGLint value = attrib_list[i + 1];
+
+ /* EGL_EXT_platform_x11 recognizes exactly one attribute,
+ * EGL_PLATFORM_X11_SCREEN_EXT, which is optional.
+ *
+ * Mesa supports connecting to only the default screen, so we reject
+ * screen != 0.
+ */
+ if (attrib != EGL_PLATFORM_X11_SCREEN_EXT || value != 0) {
+ _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
+ return EGL_FALSE;
+ }
+ }
+
+ return EGL_TRUE;
+}
+
+_EGLDisplay*
+_eglGetX11Display(Display *native_display,
+ const EGLint *attrib_list)
+{
+ if (!_eglParseX11DisplayAttribList(attrib_list)) {
+ return NULL;
+ }
+
+ return _eglFindDisplay(_EGL_PLATFORM_X11, native_display);
+}
+#endif /* HAVE_X11_PLATFORM */
+
+#ifdef HAVE_DRM_PLATFORM
+_EGLDisplay*
+_eglGetGbmDisplay(struct gbm_device *native_display,
+ const EGLint *attrib_list)
+{
+ /* EGL_MESA_platform_gbm recognizes no attributes. */
+ if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
+ _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
+ return NULL;
+ }
+
+ return _eglFindDisplay(_EGL_PLATFORM_DRM, native_display);
+}
+#endif /* HAVE_DRM_PLATFORM */
+
+#ifdef HAVE_WAYLAND_PLATFORM
+_EGLDisplay*
+_eglGetWaylandDisplay(struct wl_display *native_display,
+ const EGLint *attrib_list)
+{
+ /* EGL_EXT_platform_wayland recognizes no attributes. */
+ if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
+ _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
+ return NULL;
+ }
+
+ return _eglFindDisplay(_EGL_PLATFORM_WAYLAND, native_display);
+}
+#endif /* HAVE_WAYLAND_PLATFORM */
+
+#ifdef HAVE_SURFACELESS_PLATFORM
+_EGLDisplay*
+_eglGetSurfacelessDisplay(void *native_display,
+ const EGLint *attrib_list)
+{
+ /* This platform has no native display. */
+ if (native_display != NULL) {
+ _eglError(EGL_BAD_PARAMETER, "eglGetPlatformDisplay");
+ return NULL;
+ }
+
+ /* This platform recognizes no display attributes. */
+ if (attrib_list != NULL && attrib_list[0] != EGL_NONE) {
+ _eglError(EGL_BAD_ATTRIBUTE, "eglGetPlatformDisplay");
+ return NULL;
+ }
+
+ return _eglFindDisplay(_EGL_PLATFORM_SURFACELESS, native_display);
+}
+#endif /* HAVE_SURFACELESS_PLATFORM */