diff options
Diffstat (limited to 'src/glx/apple/apple_glx_drawable.c')
-rw-r--r-- | src/glx/apple/apple_glx_drawable.c | 542 |
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 55302243358..00000000000 --- 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; -} |