summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-I Wu <olv@lunarg.com>2010-10-23 11:59:03 +0800
committerChia-I Wu <olv@lunarg.com>2010-10-23 15:19:34 +0800
commitdc4f845c37a8446de19036e24fd397a0aa864c02 (patch)
tree7b1d125da53a1a6f932eae5cdbbdbcf489474601
parent662e098b560c6983f5ac320cc5ff7a82ecdc5f8a (diff)
egl: Add reference count for resources.
This is a really simple mechanism. There is no atomicity and the caller is expected to hold the display lock.
-rw-r--r--src/egl/main/eglcontext.c3
-rw-r--r--src/egl/main/eglcontext.h22
-rw-r--r--src/egl/main/egldisplay.c42
-rw-r--r--src/egl/main/egldisplay.h13
-rw-r--r--src/egl/main/eglimage.c3
-rw-r--r--src/egl/main/eglimage.h22
-rw-r--r--src/egl/main/eglsurface.c3
-rw-r--r--src/egl/main/eglsurface.h22
-rw-r--r--src/egl/main/eglsync.c5
-rw-r--r--src/egl/main/eglsync.h22
10 files changed, 146 insertions, 11 deletions
diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c
index 113e4e48fb..b4cc743958 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -103,8 +103,7 @@ _eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf,
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;
diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h
index c2b8280b67..9c1e2184c6 100644
--- a/src/egl/main/eglcontext.h
+++ b/src/egl/main/eglcontext.h
@@ -43,6 +43,28 @@ _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.
*
* The binding is considered a reference to the context. Drivers should not
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
index 47dcc3e05a..565e44d2d2 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -233,6 +233,42 @@ _eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *dpy)
/**
+ * 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.
*/
void
@@ -243,6 +279,7 @@ _eglLinkResource(_EGLResource *res, _EGLResourceType type)
res->IsLinked = EGL_TRUE;
res->Next = res->Display->ResourceLists[type];
res->Display->ResourceLists[type] = res;
+ _eglGetResource(res);
}
@@ -269,6 +306,9 @@ _eglUnlinkResource(_EGLResource *res, _EGLResourceType type)
}
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);
}
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index f99721e698..bcba05480a 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -40,6 +40,7 @@ struct _egl_resource
/* which display the resource belongs to */
_EGLDisplay *Display;
EGLBoolean IsLinked;
+ EGLint RefCount;
/* used to link resources of the same type */
_EGLResource *Next;
@@ -162,6 +163,18 @@ _eglGetDisplayHandle(_EGLDisplay *dpy)
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);
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c
index af4a29fb0e..9625d2ae84 100644
--- a/src/egl/main/eglimage.c
+++ b/src/egl/main/eglimage.c
@@ -81,8 +81,7 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *dpy,
EGLBoolean
_eglInitImage(_EGLImage *img, _EGLDisplay *dpy)
{
- memset(img, 0, sizeof(_EGLImage));
- img->Resource.Display = dpy;
+ _eglInitResource(&img->Resource, sizeof(*img), dpy);
return EGL_TRUE;
}
diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h
index 161230f900..bdc325a7f3 100644
--- a/src/egl/main/eglimage.h
+++ b/src/egl/main/eglimage.h
@@ -43,6 +43,28 @@ _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.
*/
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index 74f10230ea..cc505045e1 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -269,8 +269,7 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
return EGL_FALSE;
}
- memset(surf, 0, sizeof(_EGLSurface));
- surf->Resource.Display = dpy;
+ _eglInitResource(&surf->Resource, sizeof(*surf), dpy);
surf->Type = type;
surf->Config = conf;
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index 2812dc36ab..b833258bf6 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -81,6 +81,28 @@ _eglIsSurfaceBound(_EGLSurface *surf)
/**
+ * 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.
*/
diff --git a/src/egl/main/eglsync.c b/src/egl/main/eglsync.c
index b9cd99a332..95e97c7354 100644
--- a/src/egl/main/eglsync.c
+++ b/src/egl/main/eglsync.c
@@ -50,10 +50,7 @@ _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
!(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;
diff --git a/src/egl/main/eglsync.h b/src/egl/main/eglsync.h
index 09d799ba5f..97ae67cf86 100644
--- a/src/egl/main/eglsync.h
+++ b/src/egl/main/eglsync.h
@@ -34,6 +34,28 @@ _eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
/**
+ * 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.
*/