apple_glx_drawable.c revision 1a33c1b2b895566299ec76643659adacc239a3dc
1ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston/*
2ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston Copyright (c) 2008, 2009 Apple Inc.
3ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
4ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston Permission is hereby granted, free of charge, to any person
5ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston obtaining a copy of this software and associated documentation files
6ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston (the "Software"), to deal in the Software without restriction,
7ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston including without limitation the rights to use, copy, modify, merge,
8ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston publish, distribute, sublicense, and/or sell copies of the Software,
9ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston and to permit persons to whom the Software is furnished to do so,
10ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston subject to the following conditions:
11ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
12ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston The above copyright notice and this permission notice shall be
13ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston included in all copies or substantial portions of the Software.
14ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
15ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston NONINFRINGEMENT.  IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
19ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston DEALINGS IN THE SOFTWARE.
23ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
24ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston Except as contained in this notice, the name(s) of the above
25ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston copyright holders shall not be used in advertising or otherwise to
26ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston promote the sale, use or other dealings in this Software without
27ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston prior written authorization.
28ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston*/
29ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
30ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <stdbool.h>
31ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <stdio.h>
32ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <stdlib.h>
33ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <assert.h>
34ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include <pthread.h>
35ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include "apple_glx.h"
36ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include "apple_glx_context.h"
37ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include "apple_glx_drawable.h"
38ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston#include "appledri.h"
39ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
40ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic pthread_mutex_t drawables_lock = PTHREAD_MUTEX_INITIALIZER;
41ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic struct apple_glx_drawable *drawables_list = NULL;
42ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
43ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
44ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonlock_drawables_list(void)
45ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
46ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int err;
47ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
48ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutex_lock(&drawables_lock);
49ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
50ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
51ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      fprintf(stderr, "pthread_mutex_lock failure in %s: %d\n",
52ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston              __func__, err);
53ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
54ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
55ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
56ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
57ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
58ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonunlock_drawables_list(void)
59ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
60ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int err;
61ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
62ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutex_unlock(&drawables_lock);
63ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
64ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
65ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      fprintf(stderr, "pthread_mutex_unlock failure in %s: %d\n",
66ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston              __func__, err);
67ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
68ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
69ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
70ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
71ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstruct apple_glx_drawable *
72ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_find_drawable(Display * dpy, GLXDrawable drawable)
73ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
74ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *i, *agd = NULL;
75ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
76ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
77ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
78ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (i = drawables_list; i; i = i->next) {
79ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (i->drawable == drawable) {
80ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         agd = i;
81ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         break;
82ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
83ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
84ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
85ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
86ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
87ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return agd;
88ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
89ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
90ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
91ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestondrawable_lock(struct apple_glx_drawable *agd)
92ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
93ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int err;
94ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
95ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutex_lock(&agd->mutex);
96ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
97ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
98ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      fprintf(stderr, "pthread_mutex_lock error: %d\n", err);
99ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
100ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
101ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
102ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
103ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
104ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestondrawable_unlock(struct apple_glx_drawable *d)
105ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
106ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int err;
107ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
108ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutex_unlock(&d->mutex);
109ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
110ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
111ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      fprintf(stderr, "pthread_mutex_unlock error: %d\n", err);
112ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
113ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
114ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
115ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
116ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
117ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
118ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonreference_drawable(struct apple_glx_drawable *d)
119ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
120ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->lock(d);
121ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->reference_count++;
122ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->unlock(d);
123ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
124ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
125ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
126ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonrelease_drawable(struct apple_glx_drawable *d)
127ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
128ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->lock(d);
129ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->reference_count--;
130ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->unlock(d);
131ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
132ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
133ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston/* The drawables list must be locked prior to calling this. */
134ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston/* Return true if the drawable was destroyed. */
135ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic bool
136ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestondestroy_drawable(struct apple_glx_drawable *d)
137ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
1381a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston   int err;
139ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
140ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->lock(d);
141ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
142ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (d->reference_count > 0) {
143ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->unlock(d);
144ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      return false;
145ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
146ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
147ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->unlock(d);
148ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
149ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (d->previous) {
150ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->previous->next = d->next;
151ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
152ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   else {
153ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      /*
154ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * The item must be at the head of the list, if it
155ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * has no previous pointer.
156ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       */
157ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      drawables_list = d->next;
158ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
159ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
160ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (d->next)
161ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->next->previous = d->previous;
162ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
163ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
164ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
165ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (d->callbacks.destroy) {
166ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      /*
167ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * Warning: this causes other routines to be called (potentially)
168ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * from surface_notify_handler.  It's probably best to not have
169ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * any locks at this point locked.
170ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       */
171ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->callbacks.destroy(d->display, d);
172ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
173ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
174ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   apple_glx_diagnostic("%s: freeing %p\n", __func__, (void *) d);
175ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
1761a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston   err = pthread_mutex_destroy(&d->mutex);
1771a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston   if (err) {
1781a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston      fprintf(stderr, "pthread_mutex_destroy error: %s\n", strerror(err));
1791a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston      abort();
1801a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston   }
1811a33c1b2b895566299ec76643659adacc239a3dcJeremy Huddleston
182ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   free(d);
183ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
184ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   /* So that the locks are balanced and the caller correctly unlocks. */
185ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
186ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
187ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return true;
188ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
189ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
190ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston/*
191ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston * This is typically called when a context is destroyed or the current
192ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston * drawable is made None.
193ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston */
194ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic bool
195ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestondestroy_drawable_callback(struct apple_glx_drawable *d)
196ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
197ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   bool result;
198ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
199ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->lock(d);
200ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
201ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   apple_glx_diagnostic("%s: %p ->reference_count before -- %d\n", __func__,
202ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                        (void *) d, d->reference_count);
203ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
204ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->reference_count--;
205ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
206ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (d->reference_count > 0) {
207ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->unlock(d);
208ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      return false;
209ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
210ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
211ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->unlock(d);
212ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
213ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
214ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
215ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   result = destroy_drawable(d);
216ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
217ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
218ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
219ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return result;
220ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
221ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
222ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic bool
223ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonis_pbuffer(struct apple_glx_drawable *d)
224ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
225ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return APPLE_GLX_DRAWABLE_PBUFFER == d->type;
226ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
227ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
228ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic bool
229ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonis_pixmap(struct apple_glx_drawable *d)
230ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
231ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return APPLE_GLX_DRAWABLE_PIXMAP == d->type;
232ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
233ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
234ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
235ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestoncommon_init(Display * dpy, GLXDrawable drawable, struct apple_glx_drawable *d)
236ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
237ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int err;
238ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   pthread_mutexattr_t attr;
239ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
240ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->display = dpy;
241ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->reference_count = 0;
242ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->drawable = drawable;
243ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->type = -1;
244ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
245ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutexattr_init(&attr);
246ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
247ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
248ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      fprintf(stderr, "pthread_mutexattr_init error: %d\n", err);
249ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
250ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
251ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
252ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   /*
253ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston    * There are some patterns that require a recursive mutex,
254ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston    * when working with locks that protect the apple_glx_drawable,
255ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston    * and reference functions like ->reference, and ->release.
256ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston    */
257ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
258ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
259ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
260ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      fprintf(stderr, "error: setting pthread mutex type: %d\n", err);
261ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
262ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
263ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
264ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   err = pthread_mutex_init(&d->mutex, &attr);
265ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
266ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err) {
267ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      fprintf(stderr, "pthread_mutex_init error: %d\n", err);
268ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      abort();
269ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
270ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
271ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   (void) pthread_mutexattr_destroy(&attr);
272ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
273ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->lock = drawable_lock;
274ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->unlock = drawable_unlock;
275ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
276ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->reference = reference_drawable;
277ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->release = release_drawable;
278ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
279ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->destroy = destroy_drawable_callback;
280ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
281ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->is_pbuffer = is_pbuffer;
282ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->is_pixmap = is_pixmap;
283ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
284ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->width = -1;
285ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->height = -1;
286ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->row_bytes = 0;
287ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->path[0] = '\0';
288ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->fd = -1;
289ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->buffer = NULL;
290ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->buffer_length = 0;
291ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
292ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->previous = NULL;
293ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->next = NULL;
294ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
295ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
296ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic void
297ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonlink_tail(struct apple_glx_drawable *agd)
298ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
299ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
300ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
301ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   /* Link the new drawable into the global list. */
302ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   agd->next = drawables_list;
303ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
304ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (drawables_list)
305ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      drawables_list->previous = agd;
306ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
307ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   drawables_list = agd;
308ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
309ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
310ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
311ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
312ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston/*WARNING: this returns a locked and referenced object. */
313ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonbool
314ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_drawable_create(Display * dpy,
315ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                          int screen,
316ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                          GLXDrawable drawable,
317ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                          struct apple_glx_drawable **agdResult,
318ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                          struct apple_glx_drawable_callbacks *callbacks)
319ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
320ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d;
321ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
322ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d = calloc(1, sizeof *d);
323ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
324ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (NULL == d) {
325ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      perror("malloc");
326ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      return true;
327ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
328ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
329ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   common_init(dpy, drawable, d);
330ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->type = callbacks->type;
331ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->callbacks = *callbacks;
332ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
333ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->reference(d);
334ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   d->lock(d);
335ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
336ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   link_tail(d);
337ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
338ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   apple_glx_diagnostic("%s: new drawable %p\n", __func__, (void *) d);
339ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
340ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   *agdResult = d;
341ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
342ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return false;
343ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
344ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
345ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic int error_count = 0;
346ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
347ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstatic int
348ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonerror_handler(Display * dpy, XErrorEvent * err)
349ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
350ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (err->error_code == BadWindow) {
351ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      ++error_count;
352ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
353ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
354ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return 0;
355ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
356ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
357ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonvoid
358ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_garbage_collect_drawables(Display * dpy)
359ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
360ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d, *dnext;
361ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   Window root;
362ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int x, y;
363ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unsigned int width, height, bd, depth;
364ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   int (*old_handler) (Display *, XErrorEvent *);
365ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
366ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
367ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   if (NULL == drawables_list)
368ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      return;
369ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
370ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   old_handler = XSetErrorHandler(error_handler);
371ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
372ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   XSync(dpy, False);
373ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
374ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
375ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
376ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (d = drawables_list; d;) {
377ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      dnext = d->next;
378ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
379ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->lock(d);
380ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
381ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (d->reference_count > 0) {
382ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         /*
383ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * Skip this, because some context still retains a reference
384ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * to the drawable.
385ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          */
386ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         d->unlock(d);
387ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         d = dnext;
388ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         continue;
389ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
390ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
391ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d->unlock(d);
392ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
393ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      error_count = 0;
394ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
395ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      /*
396ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * Mesa uses XGetWindowAttributes, but some of these things are
397ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * most definitely not Windows, and that's against the rules.
398ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       * XGetGeometry on the other hand is legal with a Pixmap and Window.
399ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston       */
400ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      XGetGeometry(dpy, d->drawable, &root, &x, &y, &width, &height, &bd,
401ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                   &depth);
402ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
403ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (error_count > 0) {
404ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         /*
405ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * Note: this may not actually destroy the drawable.
406ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * If another context retains a reference to the drawable
407ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * after the reference count test above.
408ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          */
409ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         (void) destroy_drawable(d);
410ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         error_count = 0;
411ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
412ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
413ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      d = dnext;
414ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
415ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
416ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   XSetErrorHandler(old_handler);
417ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
418ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
419ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
420ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
421ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonunsigned int
422ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_get_drawable_count(void)
423ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
424ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unsigned int result = 0;
425ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d;
426ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
427ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
428ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
429ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (d = drawables_list; d; d = d->next)
430ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      ++result;
431ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
432ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
433ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
434ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return result;
435ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
436ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
437ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstruct apple_glx_drawable *
438ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_drawable_find_by_type(GLXDrawable drawable, int type, int flags)
439ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
440ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d;
441ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
442ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
443ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
444ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (d = drawables_list; d; d = d->next) {
445ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (d->type == type && d->drawable == drawable) {
446ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         if (flags & APPLE_GLX_DRAWABLE_REFERENCE)
447ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            d->reference(d);
448ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
449ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         if (flags & APPLE_GLX_DRAWABLE_LOCK)
450ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            d->lock(d);
451ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
452ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         unlock_drawables_list();
453ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
454ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         return d;
455ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
456ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
457ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
458ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
459ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
460ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return NULL;
461ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
462ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
463ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstruct apple_glx_drawable *
464ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_drawable_find(GLXDrawable drawable, int flags)
465ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
466ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d;
467ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
468ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
469ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
470ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (d = drawables_list; d; d = d->next) {
471ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (d->drawable == drawable) {
472ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         if (flags & APPLE_GLX_DRAWABLE_REFERENCE)
473ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            d->reference(d);
474ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
475ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         if (flags & APPLE_GLX_DRAWABLE_LOCK)
476ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            d->lock(d);
477ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
478ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         unlock_drawables_list();
479ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
480ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         return d;
481ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
482ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
483ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
484ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
485ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
486ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return NULL;
487ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
488ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
489ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston/* Return true if the type is valid for the drawable. */
490ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonbool
491ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_drawable_destroy_by_type(Display * dpy,
492ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                                   GLXDrawable drawable, int type)
493ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
494ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d;
495ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
496ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
497ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
498ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (d = drawables_list; d; d = d->next) {
499ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (drawable == d->drawable && type == d->type) {
500ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         /*
501ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * The user has requested that we destroy this resource.
502ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * However, there may be references in the contexts to it, so
503ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * release it, and call destroy_drawable which doesn't destroy
504ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          * if the reference_count is > 0.
505ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston          */
506ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         d->release(d);
507ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
508ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         apple_glx_diagnostic("%s d->reference_count %d\n",
509ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston                              __func__, d->reference_count);
510ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
511ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         destroy_drawable(d);
512ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         unlock_drawables_list();
513ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         return true;
514ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
515ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
516ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
517ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
518ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
519ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return false;
520ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
521ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
522ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonstruct apple_glx_drawable *
523ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddlestonapple_glx_drawable_find_by_uid(unsigned int uid, int flags)
524ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston{
525ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   struct apple_glx_drawable *d;
526ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
527ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   lock_drawables_list();
528ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
529ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   for (d = drawables_list; d; d = d->next) {
530ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      /* Only surfaces have a uid. */
531ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      if (APPLE_GLX_DRAWABLE_SURFACE == d->type) {
532ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         if (d->types.surface.uid == uid) {
533ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            if (flags & APPLE_GLX_DRAWABLE_REFERENCE)
534ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston               d->reference(d);
535ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
536ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            if (flags & APPLE_GLX_DRAWABLE_LOCK)
537ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston               d->lock(d);
538ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
539ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            unlock_drawables_list();
540ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
541ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston            return d;
542ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston         }
543ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston      }
544ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   }
545ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
546ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   unlock_drawables_list();
547ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston
548ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston   return NULL;
549ad503c41557606d15b0420c824369456f6d20a8fJeremy Huddleston}
550