summaryrefslogtreecommitdiff
path: root/src/glx/apple/apple_glx_drawable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/glx/apple/apple_glx_drawable.c')
-rw-r--r--src/glx/apple/apple_glx_drawable.c542
1 files changed, 0 insertions, 542 deletions
diff --git a/src/glx/apple/apple_glx_drawable.c b/src/glx/apple/apple_glx_drawable.c
deleted file mode 100644
index 5530224335..0000000000
--- a/src/glx/apple/apple_glx_drawable.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- Copyright (c) 2008, 2009 Apple Inc.
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation files
- (the "Software"), to deal in the Software without restriction,
- including without limitation the rights to use, copy, modify, merge,
- publish, distribute, sublicense, and/or sell copies of the Software,
- and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
- HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
-
- Except as contained in this notice, the name(s) of the above
- copyright holders shall not be used in advertising or otherwise to
- promote the sale, use or other dealings in this Software without
- prior written authorization.
-*/
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <pthread.h>
-#include "apple_glx.h"
-#include "apple_glx_context.h"
-#include "apple_glx_drawable.h"
-#include "appledri.h"
-
-static pthread_mutex_t drawables_lock = PTHREAD_MUTEX_INITIALIZER;
-static struct apple_glx_drawable *drawables_list = NULL;
-
-static void
-lock_drawables_list(void)
-{
- int err;
-
- err = pthread_mutex_lock(&drawables_lock);
-
- if (err) {
- fprintf(stderr, "pthread_mutex_lock failure in %s: %d\n",
- __func__, err);
- abort();
- }
-}
-
-static void
-unlock_drawables_list(void)
-{
- int err;
-
- err = pthread_mutex_unlock(&drawables_lock);
-
- if (err) {
- fprintf(stderr, "pthread_mutex_unlock failure in %s: %d\n",
- __func__, err);
- abort();
- }
-}
-
-struct apple_glx_drawable *
-apple_glx_find_drawable(Display * dpy, GLXDrawable drawable)
-{
- struct apple_glx_drawable *i, *agd = NULL;
-
- lock_drawables_list();
-
- for (i = drawables_list; i; i = i->next) {
- if (i->drawable == drawable) {
- agd = i;
- break;
- }
- }
-
- unlock_drawables_list();
-
- return agd;
-}
-
-static void
-drawable_lock(struct apple_glx_drawable *agd)
-{
- int err;
-
- err = pthread_mutex_lock(&agd->mutex);
-
- if (err) {
- fprintf(stderr, "pthread_mutex_lock error: %d\n", err);
- abort();
- }
-}
-
-static void
-drawable_unlock(struct apple_glx_drawable *d)
-{
- int err;
-
- err = pthread_mutex_unlock(&d->mutex);
-
- if (err) {
- fprintf(stderr, "pthread_mutex_unlock error: %d\n", err);
- abort();
- }
-}
-
-
-static void
-reference_drawable(struct apple_glx_drawable *d)
-{
- d->lock(d);
- d->reference_count++;
- d->unlock(d);
-}
-
-static void
-release_drawable(struct apple_glx_drawable *d)
-{
- d->lock(d);
- d->reference_count--;
- d->unlock(d);
-}
-
-/* The drawables list must be locked prior to calling this. */
-/* Return true if the drawable was destroyed. */
-static bool
-destroy_drawable(struct apple_glx_drawable *d)
-{
-
- d->lock(d);
-
- if (d->reference_count > 0) {
- d->unlock(d);
- return false;
- }
-
- d->unlock(d);
-
- if (d->previous) {
- d->previous->next = d->next;
- }
- else {
- /*
- * The item must be at the head of the list, if it
- * has no previous pointer.
- */
- drawables_list = d->next;
- }
-
- if (d->next)
- d->next->previous = d->previous;
-
- unlock_drawables_list();
-
- if (d->callbacks.destroy) {
- /*
- * Warning: this causes other routines to be called (potentially)
- * from surface_notify_handler. It's probably best to not have
- * any locks at this point locked.
- */
- d->callbacks.destroy(d->display, d);
- }
-
- apple_glx_diagnostic("%s: freeing %p\n", __func__, (void *) d);
-
- free(d);
-
- /* So that the locks are balanced and the caller correctly unlocks. */
- lock_drawables_list();
-
- return true;
-}
-
-/*
- * This is typically called when a context is destroyed or the current
- * drawable is made None.
- */
-static bool
-destroy_drawable_callback(struct apple_glx_drawable *d)
-{
- bool result;
-
- d->lock(d);
-
- apple_glx_diagnostic("%s: %p ->reference_count before -- %d\n", __func__,
- (void *) d, d->reference_count);
-
- d->reference_count--;
-
- if (d->reference_count > 0) {
- d->unlock(d);
- return false;
- }
-
- d->unlock(d);
-
- lock_drawables_list();
-
- result = destroy_drawable(d);
-
- unlock_drawables_list();
-
- return result;
-}
-
-static bool
-is_pbuffer(struct apple_glx_drawable *d)
-{
- return APPLE_GLX_DRAWABLE_PBUFFER == d->type;
-}
-
-static bool
-is_pixmap(struct apple_glx_drawable *d)
-{
- return APPLE_GLX_DRAWABLE_PIXMAP == d->type;
-}
-
-static void
-common_init(Display * dpy, GLXDrawable drawable, struct apple_glx_drawable *d)
-{
- int err;
- pthread_mutexattr_t attr;
-
- d->display = dpy;
- d->reference_count = 0;
- d->drawable = drawable;
- d->type = -1;
-
- err = pthread_mutexattr_init(&attr);
-
- if (err) {
- fprintf(stderr, "pthread_mutexattr_init error: %d\n", err);
- abort();
- }
-
- /*
- * There are some patterns that require a recursive mutex,
- * when working with locks that protect the apple_glx_drawable,
- * and reference functions like ->reference, and ->release.
- */
- err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-
- if (err) {
- fprintf(stderr, "error: setting pthread mutex type: %d\n", err);
- abort();
- }
-
- err = pthread_mutex_init(&d->mutex, &attr);
-
- if (err) {
- fprintf(stderr, "pthread_mutex_init error: %d\n", err);
- abort();
- }
-
- (void) pthread_mutexattr_destroy(&attr);
-
- d->lock = drawable_lock;
- d->unlock = drawable_unlock;
-
- d->reference = reference_drawable;
- d->release = release_drawable;
-
- d->destroy = destroy_drawable_callback;
-
- d->is_pbuffer = is_pbuffer;
- d->is_pixmap = is_pixmap;
-
- d->width = -1;
- d->height = -1;
- d->row_bytes = 0;
- d->path[0] = '\0';
- d->fd = -1;
- d->buffer = NULL;
- d->buffer_length = 0;
-
- d->previous = NULL;
- d->next = NULL;
-}
-
-static void
-link_tail(struct apple_glx_drawable *agd)
-{
- lock_drawables_list();
-
- /* Link the new drawable into the global list. */
- agd->next = drawables_list;
-
- if (drawables_list)
- drawables_list->previous = agd;
-
- drawables_list = agd;
-
- unlock_drawables_list();
-}
-
-/*WARNING: this returns a locked and referenced object. */
-bool
-apple_glx_drawable_create(Display * dpy,
- int screen,
- GLXDrawable drawable,
- struct apple_glx_drawable **agdResult,
- struct apple_glx_drawable_callbacks *callbacks)
-{
- struct apple_glx_drawable *d;
-
- d = calloc(1, sizeof *d);
-
- if (NULL == d) {
- perror("malloc");
- return true;
- }
-
- common_init(dpy, drawable, d);
- d->type = callbacks->type;
- d->callbacks = *callbacks;
-
- d->reference(d);
- d->lock(d);
-
- link_tail(d);
-
- apple_glx_diagnostic("%s: new drawable %p\n", __func__, (void *) d);
-
- *agdResult = d;
-
- return false;
-}
-
-static int error_count = 0;
-
-static int
-error_handler(Display * dpy, XErrorEvent * err)
-{
- if (err->error_code == BadWindow) {
- ++error_count;
- }
-
- return 0;
-}
-
-void
-apple_glx_garbage_collect_drawables(Display * dpy)
-{
- struct apple_glx_drawable *d, *dnext;
- Window root;
- int x, y;
- unsigned int width, height, bd, depth;
- int (*old_handler) (Display *, XErrorEvent *);
-
-
- if (NULL == drawables_list)
- return;
-
- old_handler = XSetErrorHandler(error_handler);
-
- XSync(dpy, False);
-
- lock_drawables_list();
-
- for (d = drawables_list; d;) {
- dnext = d->next;
-
- d->lock(d);
-
- if (d->reference_count > 0) {
- /*
- * Skip this, because some context still retains a reference
- * to the drawable.
- */
- d->unlock(d);
- d = dnext;
- continue;
- }
-
- d->unlock(d);
-
- error_count = 0;
-
- /*
- * Mesa uses XGetWindowAttributes, but some of these things are
- * most definitely not Windows, and that's against the rules.
- * XGetGeometry on the other hand is legal with a Pixmap and Window.
- */
- XGetGeometry(dpy, d->drawable, &root, &x, &y, &width, &height, &bd,
- &depth);
-
- if (error_count > 0) {
- /*
- * Note: this may not actually destroy the drawable.
- * If another context retains a reference to the drawable
- * after the reference count test above.
- */
- (void) destroy_drawable(d);
- error_count = 0;
- }
-
- d = dnext;
- }
-
- XSetErrorHandler(old_handler);
-
- unlock_drawables_list();
-}
-
-unsigned int
-apple_glx_get_drawable_count(void)
-{
- unsigned int result = 0;
- struct apple_glx_drawable *d;
-
- lock_drawables_list();
-
- for (d = drawables_list; d; d = d->next)
- ++result;
-
- unlock_drawables_list();
-
- return result;
-}
-
-struct apple_glx_drawable *
-apple_glx_drawable_find_by_type(GLXDrawable drawable, int type, int flags)
-{
- struct apple_glx_drawable *d;
-
- lock_drawables_list();
-
- for (d = drawables_list; d; d = d->next) {
- if (d->type == type && d->drawable == drawable) {
- if (flags & APPLE_GLX_DRAWABLE_REFERENCE)
- d->reference(d);
-
- if (flags & APPLE_GLX_DRAWABLE_LOCK)
- d->lock(d);
-
- unlock_drawables_list();
-
- return d;
- }
- }
-
- unlock_drawables_list();
-
- return NULL;
-}
-
-struct apple_glx_drawable *
-apple_glx_drawable_find(GLXDrawable drawable, int flags)
-{
- struct apple_glx_drawable *d;
-
- lock_drawables_list();
-
- for (d = drawables_list; d; d = d->next) {
- if (d->drawable == drawable) {
- if (flags & APPLE_GLX_DRAWABLE_REFERENCE)
- d->reference(d);
-
- if (flags & APPLE_GLX_DRAWABLE_LOCK)
- d->lock(d);
-
- unlock_drawables_list();
-
- return d;
- }
- }
-
- unlock_drawables_list();
-
- return NULL;
-}
-
-/* Return true if the type is valid for the drawable. */
-bool
-apple_glx_drawable_destroy_by_type(Display * dpy,
- GLXDrawable drawable, int type)
-{
- struct apple_glx_drawable *d;
-
- lock_drawables_list();
-
- for (d = drawables_list; d; d = d->next) {
- if (drawable == d->drawable && type == d->type) {
- /*
- * The user has requested that we destroy this resource.
- * However, there may be references in the contexts to it, so
- * release it, and call destroy_drawable which doesn't destroy
- * if the reference_count is > 0.
- */
- d->release(d);
-
- apple_glx_diagnostic("%s d->reference_count %d\n",
- __func__, d->reference_count);
-
- destroy_drawable(d);
- unlock_drawables_list();
- return true;
- }
- }
-
- unlock_drawables_list();
-
- return false;
-}
-
-struct apple_glx_drawable *
-apple_glx_drawable_find_by_uid(unsigned int uid, int flags)
-{
- struct apple_glx_drawable *d;
-
- lock_drawables_list();
-
- for (d = drawables_list; d; d = d->next) {
- /* Only surfaces have a uid. */
- if (APPLE_GLX_DRAWABLE_SURFACE == d->type) {
- if (d->types.surface.uid == uid) {
- if (flags & APPLE_GLX_DRAWABLE_REFERENCE)
- d->reference(d);
-
- if (flags & APPLE_GLX_DRAWABLE_LOCK)
- d->lock(d);
-
- unlock_drawables_list();
-
- return d;
- }
- }
- }
-
- unlock_drawables_list();
-
- return NULL;
-}