13464ebd5Sriastradh/* 23464ebd5Sriastradh Copyright (c) 2008, 2009 Apple Inc. 33464ebd5Sriastradh 43464ebd5Sriastradh Permission is hereby granted, free of charge, to any person 53464ebd5Sriastradh obtaining a copy of this software and associated documentation files 63464ebd5Sriastradh (the "Software"), to deal in the Software without restriction, 73464ebd5Sriastradh including without limitation the rights to use, copy, modify, merge, 83464ebd5Sriastradh publish, distribute, sublicense, and/or sell copies of the Software, 93464ebd5Sriastradh and to permit persons to whom the Software is furnished to do so, 103464ebd5Sriastradh subject to the following conditions: 113464ebd5Sriastradh 123464ebd5Sriastradh The above copyright notice and this permission notice shall be 133464ebd5Sriastradh included in all copies or substantial portions of the Software. 143464ebd5Sriastradh 153464ebd5Sriastradh THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 163464ebd5Sriastradh EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 173464ebd5Sriastradh MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 183464ebd5Sriastradh NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT 193464ebd5Sriastradh HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 203464ebd5Sriastradh WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 213464ebd5Sriastradh OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 223464ebd5Sriastradh DEALINGS IN THE SOFTWARE. 233464ebd5Sriastradh 243464ebd5Sriastradh Except as contained in this notice, the name(s) of the above 253464ebd5Sriastradh copyright holders shall not be used in advertising or otherwise to 263464ebd5Sriastradh promote the sale, use or other dealings in this Software without 273464ebd5Sriastradh prior written authorization. 283464ebd5Sriastradh*/ 293464ebd5Sriastradh 303464ebd5Sriastradh#include <stdbool.h> 313464ebd5Sriastradh#include <stdio.h> 323464ebd5Sriastradh#include <stdlib.h> 333464ebd5Sriastradh#include <assert.h> 343464ebd5Sriastradh#include <pthread.h> 35af69d88dSmrg#include <string.h> 363464ebd5Sriastradh#include "apple_glx.h" 373464ebd5Sriastradh#include "apple_glx_context.h" 383464ebd5Sriastradh#include "apple_glx_drawable.h" 393464ebd5Sriastradh#include "appledri.h" 403464ebd5Sriastradh 413464ebd5Sriastradhstatic pthread_mutex_t drawables_lock = PTHREAD_MUTEX_INITIALIZER; 423464ebd5Sriastradhstatic struct apple_glx_drawable *drawables_list = NULL; 433464ebd5Sriastradh 443464ebd5Sriastradhstatic void 453464ebd5Sriastradhlock_drawables_list(void) 463464ebd5Sriastradh{ 473464ebd5Sriastradh int err; 483464ebd5Sriastradh 493464ebd5Sriastradh err = pthread_mutex_lock(&drawables_lock); 503464ebd5Sriastradh 513464ebd5Sriastradh if (err) { 52af69d88dSmrg fprintf(stderr, "pthread_mutex_lock failure in %s: %s\n", 53af69d88dSmrg __func__, strerror(err)); 543464ebd5Sriastradh abort(); 553464ebd5Sriastradh } 563464ebd5Sriastradh} 573464ebd5Sriastradh 583464ebd5Sriastradhstatic void 593464ebd5Sriastradhunlock_drawables_list(void) 603464ebd5Sriastradh{ 613464ebd5Sriastradh int err; 623464ebd5Sriastradh 633464ebd5Sriastradh err = pthread_mutex_unlock(&drawables_lock); 643464ebd5Sriastradh 653464ebd5Sriastradh if (err) { 66af69d88dSmrg fprintf(stderr, "pthread_mutex_unlock failure in %s: %s\n", 67af69d88dSmrg __func__, strerror(err)); 683464ebd5Sriastradh abort(); 693464ebd5Sriastradh } 703464ebd5Sriastradh} 713464ebd5Sriastradh 723464ebd5Sriastradhstruct apple_glx_drawable * 733464ebd5Sriastradhapple_glx_find_drawable(Display * dpy, GLXDrawable drawable) 743464ebd5Sriastradh{ 753464ebd5Sriastradh struct apple_glx_drawable *i, *agd = NULL; 763464ebd5Sriastradh 773464ebd5Sriastradh lock_drawables_list(); 783464ebd5Sriastradh 793464ebd5Sriastradh for (i = drawables_list; i; i = i->next) { 803464ebd5Sriastradh if (i->drawable == drawable) { 813464ebd5Sriastradh agd = i; 823464ebd5Sriastradh break; 833464ebd5Sriastradh } 843464ebd5Sriastradh } 853464ebd5Sriastradh 863464ebd5Sriastradh unlock_drawables_list(); 873464ebd5Sriastradh 883464ebd5Sriastradh return agd; 893464ebd5Sriastradh} 903464ebd5Sriastradh 913464ebd5Sriastradhstatic void 923464ebd5Sriastradhdrawable_lock(struct apple_glx_drawable *agd) 933464ebd5Sriastradh{ 943464ebd5Sriastradh int err; 953464ebd5Sriastradh 963464ebd5Sriastradh err = pthread_mutex_lock(&agd->mutex); 973464ebd5Sriastradh 983464ebd5Sriastradh if (err) { 99af69d88dSmrg fprintf(stderr, "pthread_mutex_lock error: %s\n", strerror(err)); 1003464ebd5Sriastradh abort(); 1013464ebd5Sriastradh } 1023464ebd5Sriastradh} 1033464ebd5Sriastradh 1043464ebd5Sriastradhstatic void 1053464ebd5Sriastradhdrawable_unlock(struct apple_glx_drawable *d) 1063464ebd5Sriastradh{ 1073464ebd5Sriastradh int err; 1083464ebd5Sriastradh 1093464ebd5Sriastradh err = pthread_mutex_unlock(&d->mutex); 1103464ebd5Sriastradh 1113464ebd5Sriastradh if (err) { 112af69d88dSmrg fprintf(stderr, "pthread_mutex_unlock error: %s\n", strerror(err)); 1133464ebd5Sriastradh abort(); 1143464ebd5Sriastradh } 1153464ebd5Sriastradh} 1163464ebd5Sriastradh 1173464ebd5Sriastradh 1183464ebd5Sriastradhstatic void 1193464ebd5Sriastradhreference_drawable(struct apple_glx_drawable *d) 1203464ebd5Sriastradh{ 1213464ebd5Sriastradh d->lock(d); 1223464ebd5Sriastradh d->reference_count++; 1233464ebd5Sriastradh d->unlock(d); 1243464ebd5Sriastradh} 1253464ebd5Sriastradh 1263464ebd5Sriastradhstatic void 1273464ebd5Sriastradhrelease_drawable(struct apple_glx_drawable *d) 1283464ebd5Sriastradh{ 1293464ebd5Sriastradh d->lock(d); 1303464ebd5Sriastradh d->reference_count--; 1313464ebd5Sriastradh d->unlock(d); 1323464ebd5Sriastradh} 1333464ebd5Sriastradh 1343464ebd5Sriastradh/* The drawables list must be locked prior to calling this. */ 1353464ebd5Sriastradh/* Return true if the drawable was destroyed. */ 1363464ebd5Sriastradhstatic bool 1373464ebd5Sriastradhdestroy_drawable(struct apple_glx_drawable *d) 1383464ebd5Sriastradh{ 139af69d88dSmrg int err; 1403464ebd5Sriastradh 1413464ebd5Sriastradh d->lock(d); 1423464ebd5Sriastradh 1433464ebd5Sriastradh if (d->reference_count > 0) { 1443464ebd5Sriastradh d->unlock(d); 1453464ebd5Sriastradh return false; 1463464ebd5Sriastradh } 1473464ebd5Sriastradh 1483464ebd5Sriastradh d->unlock(d); 1493464ebd5Sriastradh 1503464ebd5Sriastradh if (d->previous) { 1513464ebd5Sriastradh d->previous->next = d->next; 1523464ebd5Sriastradh } 1533464ebd5Sriastradh else { 1543464ebd5Sriastradh /* 1553464ebd5Sriastradh * The item must be at the head of the list, if it 1563464ebd5Sriastradh * has no previous pointer. 1573464ebd5Sriastradh */ 1583464ebd5Sriastradh drawables_list = d->next; 1593464ebd5Sriastradh } 1603464ebd5Sriastradh 1613464ebd5Sriastradh if (d->next) 1623464ebd5Sriastradh d->next->previous = d->previous; 1633464ebd5Sriastradh 1643464ebd5Sriastradh unlock_drawables_list(); 1653464ebd5Sriastradh 1663464ebd5Sriastradh if (d->callbacks.destroy) { 1673464ebd5Sriastradh /* 1683464ebd5Sriastradh * Warning: this causes other routines to be called (potentially) 1693464ebd5Sriastradh * from surface_notify_handler. It's probably best to not have 1703464ebd5Sriastradh * any locks at this point locked. 1713464ebd5Sriastradh */ 1723464ebd5Sriastradh d->callbacks.destroy(d->display, d); 1733464ebd5Sriastradh } 1743464ebd5Sriastradh 1753464ebd5Sriastradh apple_glx_diagnostic("%s: freeing %p\n", __func__, (void *) d); 1763464ebd5Sriastradh 177af69d88dSmrg /* Stupid recursive locks */ 178af69d88dSmrg while (pthread_mutex_unlock(&d->mutex) == 0); 179af69d88dSmrg 180af69d88dSmrg err = pthread_mutex_destroy(&d->mutex); 181af69d88dSmrg if (err) { 182af69d88dSmrg fprintf(stderr, "pthread_mutex_destroy error: %s\n", strerror(err)); 183af69d88dSmrg abort(); 184af69d88dSmrg } 185af69d88dSmrg 1863464ebd5Sriastradh free(d); 1873464ebd5Sriastradh 1883464ebd5Sriastradh /* So that the locks are balanced and the caller correctly unlocks. */ 1893464ebd5Sriastradh lock_drawables_list(); 1903464ebd5Sriastradh 1913464ebd5Sriastradh return true; 1923464ebd5Sriastradh} 1933464ebd5Sriastradh 1943464ebd5Sriastradh/* 1953464ebd5Sriastradh * This is typically called when a context is destroyed or the current 1963464ebd5Sriastradh * drawable is made None. 1973464ebd5Sriastradh */ 1983464ebd5Sriastradhstatic bool 1993464ebd5Sriastradhdestroy_drawable_callback(struct apple_glx_drawable *d) 2003464ebd5Sriastradh{ 2013464ebd5Sriastradh bool result; 2023464ebd5Sriastradh 2033464ebd5Sriastradh d->lock(d); 2043464ebd5Sriastradh 2053464ebd5Sriastradh apple_glx_diagnostic("%s: %p ->reference_count before -- %d\n", __func__, 2063464ebd5Sriastradh (void *) d, d->reference_count); 2073464ebd5Sriastradh 2083464ebd5Sriastradh d->reference_count--; 2093464ebd5Sriastradh 2103464ebd5Sriastradh if (d->reference_count > 0) { 2113464ebd5Sriastradh d->unlock(d); 2123464ebd5Sriastradh return false; 2133464ebd5Sriastradh } 2143464ebd5Sriastradh 2153464ebd5Sriastradh d->unlock(d); 2163464ebd5Sriastradh 2173464ebd5Sriastradh lock_drawables_list(); 2183464ebd5Sriastradh 2193464ebd5Sriastradh result = destroy_drawable(d); 2203464ebd5Sriastradh 2213464ebd5Sriastradh unlock_drawables_list(); 2223464ebd5Sriastradh 2233464ebd5Sriastradh return result; 2243464ebd5Sriastradh} 2253464ebd5Sriastradh 2263464ebd5Sriastradhstatic bool 2273464ebd5Sriastradhis_pbuffer(struct apple_glx_drawable *d) 2283464ebd5Sriastradh{ 2293464ebd5Sriastradh return APPLE_GLX_DRAWABLE_PBUFFER == d->type; 2303464ebd5Sriastradh} 2313464ebd5Sriastradh 2323464ebd5Sriastradhstatic bool 2333464ebd5Sriastradhis_pixmap(struct apple_glx_drawable *d) 2343464ebd5Sriastradh{ 2353464ebd5Sriastradh return APPLE_GLX_DRAWABLE_PIXMAP == d->type; 2363464ebd5Sriastradh} 2373464ebd5Sriastradh 2383464ebd5Sriastradhstatic void 2393464ebd5Sriastradhcommon_init(Display * dpy, GLXDrawable drawable, struct apple_glx_drawable *d) 2403464ebd5Sriastradh{ 2413464ebd5Sriastradh int err; 2423464ebd5Sriastradh pthread_mutexattr_t attr; 2433464ebd5Sriastradh 2443464ebd5Sriastradh d->display = dpy; 2453464ebd5Sriastradh d->reference_count = 0; 2463464ebd5Sriastradh d->drawable = drawable; 2473464ebd5Sriastradh d->type = -1; 2483464ebd5Sriastradh 2493464ebd5Sriastradh err = pthread_mutexattr_init(&attr); 2503464ebd5Sriastradh 2513464ebd5Sriastradh if (err) { 252af69d88dSmrg fprintf(stderr, "pthread_mutexattr_init error: %s\n", strerror(err)); 2533464ebd5Sriastradh abort(); 2543464ebd5Sriastradh } 2553464ebd5Sriastradh 2563464ebd5Sriastradh /* 2573464ebd5Sriastradh * There are some patterns that require a recursive mutex, 2583464ebd5Sriastradh * when working with locks that protect the apple_glx_drawable, 2593464ebd5Sriastradh * and reference functions like ->reference, and ->release. 2603464ebd5Sriastradh */ 2613464ebd5Sriastradh err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 2623464ebd5Sriastradh 2633464ebd5Sriastradh if (err) { 264af69d88dSmrg fprintf(stderr, "error: setting pthread mutex type: %s\n", strerror(err)); 2653464ebd5Sriastradh abort(); 2663464ebd5Sriastradh } 2673464ebd5Sriastradh 2683464ebd5Sriastradh err = pthread_mutex_init(&d->mutex, &attr); 2693464ebd5Sriastradh 2703464ebd5Sriastradh if (err) { 271af69d88dSmrg fprintf(stderr, "pthread_mutex_init error: %s\n", strerror(err)); 2723464ebd5Sriastradh abort(); 2733464ebd5Sriastradh } 2743464ebd5Sriastradh 2753464ebd5Sriastradh (void) pthread_mutexattr_destroy(&attr); 2763464ebd5Sriastradh 2773464ebd5Sriastradh d->lock = drawable_lock; 2783464ebd5Sriastradh d->unlock = drawable_unlock; 2793464ebd5Sriastradh 2803464ebd5Sriastradh d->reference = reference_drawable; 2813464ebd5Sriastradh d->release = release_drawable; 2823464ebd5Sriastradh 2833464ebd5Sriastradh d->destroy = destroy_drawable_callback; 2843464ebd5Sriastradh 2853464ebd5Sriastradh d->is_pbuffer = is_pbuffer; 2863464ebd5Sriastradh d->is_pixmap = is_pixmap; 2873464ebd5Sriastradh 2883464ebd5Sriastradh d->width = -1; 2893464ebd5Sriastradh d->height = -1; 2903464ebd5Sriastradh d->row_bytes = 0; 2913464ebd5Sriastradh d->path[0] = '\0'; 2923464ebd5Sriastradh d->fd = -1; 2933464ebd5Sriastradh d->buffer = NULL; 2943464ebd5Sriastradh d->buffer_length = 0; 2953464ebd5Sriastradh 2963464ebd5Sriastradh d->previous = NULL; 2973464ebd5Sriastradh d->next = NULL; 2983464ebd5Sriastradh} 2993464ebd5Sriastradh 3003464ebd5Sriastradhstatic void 3013464ebd5Sriastradhlink_tail(struct apple_glx_drawable *agd) 3023464ebd5Sriastradh{ 3033464ebd5Sriastradh lock_drawables_list(); 3043464ebd5Sriastradh 3053464ebd5Sriastradh /* Link the new drawable into the global list. */ 3063464ebd5Sriastradh agd->next = drawables_list; 3073464ebd5Sriastradh 3083464ebd5Sriastradh if (drawables_list) 3093464ebd5Sriastradh drawables_list->previous = agd; 3103464ebd5Sriastradh 3113464ebd5Sriastradh drawables_list = agd; 3123464ebd5Sriastradh 3133464ebd5Sriastradh unlock_drawables_list(); 3143464ebd5Sriastradh} 3153464ebd5Sriastradh 3163464ebd5Sriastradh/*WARNING: this returns a locked and referenced object. */ 3173464ebd5Sriastradhbool 3183464ebd5Sriastradhapple_glx_drawable_create(Display * dpy, 3193464ebd5Sriastradh int screen, 3203464ebd5Sriastradh GLXDrawable drawable, 3213464ebd5Sriastradh struct apple_glx_drawable **agdResult, 3223464ebd5Sriastradh struct apple_glx_drawable_callbacks *callbacks) 3233464ebd5Sriastradh{ 3243464ebd5Sriastradh struct apple_glx_drawable *d; 3253464ebd5Sriastradh 3263464ebd5Sriastradh d = calloc(1, sizeof *d); 3273464ebd5Sriastradh 3283464ebd5Sriastradh if (NULL == d) { 3293464ebd5Sriastradh perror("malloc"); 3303464ebd5Sriastradh return true; 3313464ebd5Sriastradh } 3323464ebd5Sriastradh 3333464ebd5Sriastradh common_init(dpy, drawable, d); 3343464ebd5Sriastradh d->type = callbacks->type; 3353464ebd5Sriastradh d->callbacks = *callbacks; 3363464ebd5Sriastradh 3373464ebd5Sriastradh d->reference(d); 3383464ebd5Sriastradh d->lock(d); 3393464ebd5Sriastradh 3403464ebd5Sriastradh link_tail(d); 3413464ebd5Sriastradh 3423464ebd5Sriastradh apple_glx_diagnostic("%s: new drawable %p\n", __func__, (void *) d); 3433464ebd5Sriastradh 3443464ebd5Sriastradh *agdResult = d; 3453464ebd5Sriastradh 3463464ebd5Sriastradh return false; 3473464ebd5Sriastradh} 3483464ebd5Sriastradh 3493464ebd5Sriastradhstatic int error_count = 0; 3503464ebd5Sriastradh 3513464ebd5Sriastradhstatic int 3523464ebd5Sriastradherror_handler(Display * dpy, XErrorEvent * err) 3533464ebd5Sriastradh{ 3543464ebd5Sriastradh if (err->error_code == BadWindow) { 3553464ebd5Sriastradh ++error_count; 3563464ebd5Sriastradh } 3573464ebd5Sriastradh 3583464ebd5Sriastradh return 0; 3593464ebd5Sriastradh} 3603464ebd5Sriastradh 3613464ebd5Sriastradhvoid 3623464ebd5Sriastradhapple_glx_garbage_collect_drawables(Display * dpy) 3633464ebd5Sriastradh{ 3643464ebd5Sriastradh struct apple_glx_drawable *d, *dnext; 3653464ebd5Sriastradh Window root; 3663464ebd5Sriastradh int x, y; 3673464ebd5Sriastradh unsigned int width, height, bd, depth; 3683464ebd5Sriastradh int (*old_handler) (Display *, XErrorEvent *); 3693464ebd5Sriastradh 3703464ebd5Sriastradh 3713464ebd5Sriastradh if (NULL == drawables_list) 3723464ebd5Sriastradh return; 3733464ebd5Sriastradh 3743464ebd5Sriastradh old_handler = XSetErrorHandler(error_handler); 3753464ebd5Sriastradh 3763464ebd5Sriastradh XSync(dpy, False); 3773464ebd5Sriastradh 3783464ebd5Sriastradh lock_drawables_list(); 3793464ebd5Sriastradh 3803464ebd5Sriastradh for (d = drawables_list; d;) { 3813464ebd5Sriastradh dnext = d->next; 3823464ebd5Sriastradh 3833464ebd5Sriastradh d->lock(d); 3843464ebd5Sriastradh 3853464ebd5Sriastradh if (d->reference_count > 0) { 3863464ebd5Sriastradh /* 3873464ebd5Sriastradh * Skip this, because some context still retains a reference 3883464ebd5Sriastradh * to the drawable. 3893464ebd5Sriastradh */ 3903464ebd5Sriastradh d->unlock(d); 3913464ebd5Sriastradh d = dnext; 3923464ebd5Sriastradh continue; 3933464ebd5Sriastradh } 3943464ebd5Sriastradh 3953464ebd5Sriastradh d->unlock(d); 3963464ebd5Sriastradh 3973464ebd5Sriastradh error_count = 0; 3983464ebd5Sriastradh 3993464ebd5Sriastradh /* 4003464ebd5Sriastradh * Mesa uses XGetWindowAttributes, but some of these things are 4013464ebd5Sriastradh * most definitely not Windows, and that's against the rules. 4023464ebd5Sriastradh * XGetGeometry on the other hand is legal with a Pixmap and Window. 4033464ebd5Sriastradh */ 4043464ebd5Sriastradh XGetGeometry(dpy, d->drawable, &root, &x, &y, &width, &height, &bd, 4053464ebd5Sriastradh &depth); 4063464ebd5Sriastradh 4073464ebd5Sriastradh if (error_count > 0) { 4083464ebd5Sriastradh /* 4093464ebd5Sriastradh * Note: this may not actually destroy the drawable. 4103464ebd5Sriastradh * If another context retains a reference to the drawable 4113464ebd5Sriastradh * after the reference count test above. 4123464ebd5Sriastradh */ 4133464ebd5Sriastradh (void) destroy_drawable(d); 4143464ebd5Sriastradh error_count = 0; 4153464ebd5Sriastradh } 4163464ebd5Sriastradh 4173464ebd5Sriastradh d = dnext; 4183464ebd5Sriastradh } 4193464ebd5Sriastradh 4203464ebd5Sriastradh XSetErrorHandler(old_handler); 4213464ebd5Sriastradh 4223464ebd5Sriastradh unlock_drawables_list(); 4233464ebd5Sriastradh} 4243464ebd5Sriastradh 4253464ebd5Sriastradhunsigned int 4263464ebd5Sriastradhapple_glx_get_drawable_count(void) 4273464ebd5Sriastradh{ 4283464ebd5Sriastradh unsigned int result = 0; 4293464ebd5Sriastradh struct apple_glx_drawable *d; 4303464ebd5Sriastradh 4313464ebd5Sriastradh lock_drawables_list(); 4323464ebd5Sriastradh 4333464ebd5Sriastradh for (d = drawables_list; d; d = d->next) 4343464ebd5Sriastradh ++result; 4353464ebd5Sriastradh 4363464ebd5Sriastradh unlock_drawables_list(); 4373464ebd5Sriastradh 4383464ebd5Sriastradh return result; 4393464ebd5Sriastradh} 4403464ebd5Sriastradh 4413464ebd5Sriastradhstruct apple_glx_drawable * 4423464ebd5Sriastradhapple_glx_drawable_find_by_type(GLXDrawable drawable, int type, int flags) 4433464ebd5Sriastradh{ 4443464ebd5Sriastradh struct apple_glx_drawable *d; 4453464ebd5Sriastradh 4463464ebd5Sriastradh lock_drawables_list(); 4473464ebd5Sriastradh 4483464ebd5Sriastradh for (d = drawables_list; d; d = d->next) { 4493464ebd5Sriastradh if (d->type == type && d->drawable == drawable) { 4503464ebd5Sriastradh if (flags & APPLE_GLX_DRAWABLE_REFERENCE) 4513464ebd5Sriastradh d->reference(d); 4523464ebd5Sriastradh 4533464ebd5Sriastradh if (flags & APPLE_GLX_DRAWABLE_LOCK) 4543464ebd5Sriastradh d->lock(d); 4553464ebd5Sriastradh 4563464ebd5Sriastradh unlock_drawables_list(); 4573464ebd5Sriastradh 4583464ebd5Sriastradh return d; 4593464ebd5Sriastradh } 4603464ebd5Sriastradh } 4613464ebd5Sriastradh 4623464ebd5Sriastradh unlock_drawables_list(); 4633464ebd5Sriastradh 4643464ebd5Sriastradh return NULL; 4653464ebd5Sriastradh} 4663464ebd5Sriastradh 4673464ebd5Sriastradhstruct apple_glx_drawable * 4683464ebd5Sriastradhapple_glx_drawable_find(GLXDrawable drawable, int flags) 4693464ebd5Sriastradh{ 4703464ebd5Sriastradh struct apple_glx_drawable *d; 4713464ebd5Sriastradh 4723464ebd5Sriastradh lock_drawables_list(); 4733464ebd5Sriastradh 4743464ebd5Sriastradh for (d = drawables_list; d; d = d->next) { 4753464ebd5Sriastradh if (d->drawable == drawable) { 4763464ebd5Sriastradh if (flags & APPLE_GLX_DRAWABLE_REFERENCE) 4773464ebd5Sriastradh d->reference(d); 4783464ebd5Sriastradh 4793464ebd5Sriastradh if (flags & APPLE_GLX_DRAWABLE_LOCK) 4803464ebd5Sriastradh d->lock(d); 4813464ebd5Sriastradh 4823464ebd5Sriastradh unlock_drawables_list(); 4833464ebd5Sriastradh 4843464ebd5Sriastradh return d; 4853464ebd5Sriastradh } 4863464ebd5Sriastradh } 4873464ebd5Sriastradh 4883464ebd5Sriastradh unlock_drawables_list(); 4893464ebd5Sriastradh 4903464ebd5Sriastradh return NULL; 4913464ebd5Sriastradh} 4923464ebd5Sriastradh 4933464ebd5Sriastradh/* Return true if the type is valid for the drawable. */ 4943464ebd5Sriastradhbool 4953464ebd5Sriastradhapple_glx_drawable_destroy_by_type(Display * dpy, 4963464ebd5Sriastradh GLXDrawable drawable, int type) 4973464ebd5Sriastradh{ 4983464ebd5Sriastradh struct apple_glx_drawable *d; 4993464ebd5Sriastradh 5003464ebd5Sriastradh lock_drawables_list(); 5013464ebd5Sriastradh 5023464ebd5Sriastradh for (d = drawables_list; d; d = d->next) { 5033464ebd5Sriastradh if (drawable == d->drawable && type == d->type) { 5043464ebd5Sriastradh /* 5053464ebd5Sriastradh * The user has requested that we destroy this resource. 5063464ebd5Sriastradh * However, there may be references in the contexts to it, so 5073464ebd5Sriastradh * release it, and call destroy_drawable which doesn't destroy 5083464ebd5Sriastradh * if the reference_count is > 0. 5093464ebd5Sriastradh */ 5103464ebd5Sriastradh d->release(d); 5113464ebd5Sriastradh 5123464ebd5Sriastradh apple_glx_diagnostic("%s d->reference_count %d\n", 5133464ebd5Sriastradh __func__, d->reference_count); 5143464ebd5Sriastradh 5153464ebd5Sriastradh destroy_drawable(d); 5163464ebd5Sriastradh unlock_drawables_list(); 5173464ebd5Sriastradh return true; 5183464ebd5Sriastradh } 5193464ebd5Sriastradh } 5203464ebd5Sriastradh 5213464ebd5Sriastradh unlock_drawables_list(); 5223464ebd5Sriastradh 5233464ebd5Sriastradh return false; 5243464ebd5Sriastradh} 5253464ebd5Sriastradh 5263464ebd5Sriastradhstruct apple_glx_drawable * 5273464ebd5Sriastradhapple_glx_drawable_find_by_uid(unsigned int uid, int flags) 5283464ebd5Sriastradh{ 5293464ebd5Sriastradh struct apple_glx_drawable *d; 5303464ebd5Sriastradh 5313464ebd5Sriastradh lock_drawables_list(); 5323464ebd5Sriastradh 5333464ebd5Sriastradh for (d = drawables_list; d; d = d->next) { 5343464ebd5Sriastradh /* Only surfaces have a uid. */ 5353464ebd5Sriastradh if (APPLE_GLX_DRAWABLE_SURFACE == d->type) { 5363464ebd5Sriastradh if (d->types.surface.uid == uid) { 5373464ebd5Sriastradh if (flags & APPLE_GLX_DRAWABLE_REFERENCE) 5383464ebd5Sriastradh d->reference(d); 5393464ebd5Sriastradh 5403464ebd5Sriastradh if (flags & APPLE_GLX_DRAWABLE_LOCK) 5413464ebd5Sriastradh d->lock(d); 5423464ebd5Sriastradh 5433464ebd5Sriastradh unlock_drawables_list(); 5443464ebd5Sriastradh 5453464ebd5Sriastradh return d; 5463464ebd5Sriastradh } 5473464ebd5Sriastradh } 5483464ebd5Sriastradh } 5493464ebd5Sriastradh 5503464ebd5Sriastradh unlock_drawables_list(); 5513464ebd5Sriastradh 5523464ebd5Sriastradh return NULL; 5533464ebd5Sriastradh} 554