return EGL_FALSE;
}
- memset(ctx, 0, sizeof(_EGLContext));
- ctx->Resource.Display = dpy;
+ _eglInitResource(&ctx->Resource, sizeof(*ctx), dpy);
ctx->ClientAPI = api;
ctx->Config = conf;
ctx->WindowRenderBuffer = EGL_NONE;
_eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read);
+/**
+ * Increment reference count for the context.
+ */
+static INLINE _EGLContext *
+_eglGetContext(_EGLContext *ctx)
+{
+ if (ctx)
+ _eglGetResource(&ctx->Resource);
+ return ctx;
+}
+
+
+/**
+ * Decrement reference count for the context.
+ */
+static INLINE EGLBoolean
+_eglPutContext(_EGLContext *ctx)
+{
+ return (ctx) ? _eglPutResource(&ctx->Resource) : EGL_FALSE;
+}
+
+
/**
* Return true if the context is bound to a thread.
*
}
+/**
+ * Initialize a display resource.
+ */
+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.
*/
res->IsLinked = EGL_TRUE;
res->Next = res->Display->ResourceLists[type];
res->Display->ResourceLists[type] = res;
+ _eglGetResource(res);
}
}
res->Next = NULL;
- /* do not reset res->Display */
res->IsLinked = EGL_FALSE;
+ _eglPutResource(res);
+
+ /* We always unlink before destroy. The driver still owns a reference */
+ assert(res->RefCount);
}
/* which display the resource belongs to */
_EGLDisplay *Display;
EGLBoolean IsLinked;
+ EGLint RefCount;
/* used to link resources of the same type */
_EGLResource *Next;
}
+extern void
+_eglInitResource(_EGLResource *res, EGLint size, _EGLDisplay *dpy);
+
+
+PUBLIC void
+_eglGetResource(_EGLResource *res);
+
+
+PUBLIC EGLBoolean
+_eglPutResource(_EGLResource *res);
+
+
extern void
_eglLinkResource(_EGLResource *res, _EGLResourceType type);
EGLBoolean
_eglInitImage(_EGLImage *img, _EGLDisplay *dpy)
{
- memset(img, 0, sizeof(_EGLImage));
- img->Resource.Display = dpy;
+ _eglInitResource(&img->Resource, sizeof(*img), dpy);
return EGL_TRUE;
}
_eglInitImage(_EGLImage *img, _EGLDisplay *dpy);
+/**
+ * Increment reference count for the image.
+ */
+static INLINE _EGLImage *
+_eglGetImage(_EGLImage *img)
+{
+ if (img)
+ _eglGetResource(&img->Resource);
+ return img;
+}
+
+
+/**
+ * Decrement reference count for the image.
+ */
+static INLINE EGLBoolean
+_eglPutImage(_EGLImage *img)
+{
+ return (img) ? _eglPutResource(&img->Resource) : EGL_FALSE;
+}
+
+
/**
* Link an image to its display and return the handle of the link.
* The handle can be passed to client directly.
return EGL_FALSE;
}
- memset(surf, 0, sizeof(_EGLSurface));
- surf->Resource.Display = dpy;
+ _eglInitResource(&surf->Resource, sizeof(*surf), dpy);
surf->Type = type;
surf->Config = conf;
}
+/**
+ * Increment reference count for the surface.
+ */
+static INLINE _EGLSurface *
+_eglGetSurface(_EGLSurface *surf)
+{
+ if (surf)
+ _eglGetResource(&surf->Resource);
+ return surf;
+}
+
+
+/**
+ * Decrement reference count for the surface.
+ */
+static INLINE EGLBoolean
+_eglPutSurface(_EGLSurface *surf)
+{
+ return (surf) ? _eglPutResource(&surf->Resource) : EGL_FALSE;
+}
+
+
/**
* Link a surface to its display and return the handle of the link.
* The handle can be passed to client directly.
!(type == EGL_SYNC_FENCE_KHR && dpy->Extensions.KHR_fence_sync))
return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR");
- memset(sync, 0, sizeof(*sync));
-
- sync->Resource.Display = dpy;
-
+ _eglInitResource(&sync->Resource, sizeof(*sync), dpy);
sync->Type = type;
sync->SyncStatus = EGL_UNSIGNALED_KHR;
sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
EGLint attribute, EGLint *value);
+/**
+ * Increment reference count for the sync.
+ */
+static INLINE _EGLSync *
+_eglGetSync(_EGLSync *sync)
+{
+ if (sync)
+ _eglGetResource(&sync->Resource);
+ return sync;
+}
+
+
+/**
+ * Decrement reference count for the sync.
+ */
+static INLINE EGLBoolean
+_eglPutSync(_EGLSync *sync)
+{
+ return (sync) ? _eglPutResource(&sync->Resource) : EGL_FALSE;
+}
+
+
/**
* Link a sync to its display and return the handle of the link.
* The handle can be passed to client directly.