1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Copyright (c) 2009 Apple Inc.
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Permission is hereby granted, free of charge, to any person
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org obtaining a copy of this software and associated documentation files
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (the "Software"), to deal in the Software without restriction,
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org including without limitation the rights to use, copy, modify, merge,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org publish, distribute, sublicense, and/or sell copies of the Software,
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org and to permit persons to whom the Software is furnished to do so,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org subject to the following conditions:
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org The above copyright notice and this permission notice shall be
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org included in all copies or substantial portions of the Software.
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NONINFRINGEMENT.  IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DEALINGS IN THE SOFTWARE.
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Except as contained in this notice, the name(s) of the above
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org copyright holders shall not be used in advertising or otherwise to
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org promote the sale, use or other dealings in this Software without
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prior written authorization.
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org*/
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <assert.h>
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glxclient.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "apple_glx.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "appledri.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "apple_glx_drawable.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool surface_make_current(struct apple_glx_context *ac,
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 struct apple_glx_drawable *d);
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void surface_destroy(Display * dpy, struct apple_glx_drawable *d);
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct apple_glx_drawable_callbacks callbacks = {
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   .type = APPLE_GLX_DRAWABLE_SURFACE,
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   .make_current = surface_make_current,
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   .destroy = surface_destroy
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgupdate_viewport_and_scissor(Display * dpy, GLXDrawable drawable)
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Window root;
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int x, y;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int width = 0, height = 0, bd, depth;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XGetGeometry(dpy, drawable, &root, &x, &y, &width, &height, &bd, &depth);
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   apple_glapi_oglfw_viewport_scissor(0, 0, width, height);
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsurface_make_current(struct apple_glx_context *ac,
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     struct apple_glx_drawable *d)
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct apple_glx_surface *s = &d->types.surface;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xp_error error;
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(APPLE_GLX_DRAWABLE_SURFACE == d->type);
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   apple_glx_diagnostic("%s: ac->context_obj %p s->surface_id %u\n",
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        __func__, (void *) ac->context_obj, s->surface_id);
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   error = xp_attach_gl_context(ac->context_obj, s->surface_id);
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (error) {
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fprintf(stderr, "error: xp_attach_gl_context returned: %d\n", error);
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ac->made_current) {
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * The first time a new context is made current the glViewport
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * and glScissor should be updated.
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      update_viewport_and_scissor(ac->drawable->display,
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  ac->drawable->drawable);
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ac->made_current = true;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   apple_glx_diagnostic("%s: drawable 0x%lx\n", __func__, d->drawable);
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return false;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsurface_destroy(Display * dpy, struct apple_glx_drawable *d)
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct apple_glx_surface *s = &d->types.surface;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   apple_glx_diagnostic("%s: s->surface_id %u\n", __func__, s->surface_id);
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xp_error error = xp_destroy_surface(s->surface_id);
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (error) {
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fprintf(stderr, "xp_destroy_surface error: %d\n", (int) error);
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Check if this surface destroy came from the surface being destroyed
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * on the server.  If s->pending_destroy is true, then it did, and
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * we don't want to try to destroy the surface on the server.
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!s->pending_destroy) {
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Warning: this causes other routines to be called (potentially)
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * from surface_notify_handler.  It's probably best to not have
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * any locks at this point locked.
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XAppleDRIDestroySurface(d->display, DefaultScreen(d->display),
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              d->drawable);
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      apple_glx_diagnostic
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ("%s: destroyed a surface for drawable 0x%lx uid %u\n", __func__,
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          d->drawable, s->uid);
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Return true if an error occured. */
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcreate_surface(Display * dpy, int screen, struct apple_glx_drawable *d)
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct apple_glx_surface *s = &d->types.surface;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int key[2];
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   xp_client_id id;
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   id = apple_glx_get_client_id();
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (0 == id)
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(None != d->drawable);
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   s->pending_destroy = false;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (XAppleDRICreateSurface(dpy, screen, d->drawable, id, key, &s->uid)) {
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      xp_error error;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      error = xp_import_surface(key, &s->surface_id);
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (error) {
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         fprintf(stderr, "error: xp_import_surface returned: %d\n", error);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return true;
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      apple_glx_diagnostic("%s: created a surface for drawable 0x%lx"
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           " with uid %u\n", __func__, d->drawable, s->uid);
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;             /*success */
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;                 /* unable to create a surface. */
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Return true if an error occured. */
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* This returns a referenced object via resultptr. */
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgapple_glx_surface_create(Display * dpy, int screen,
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         GLXDrawable drawable,
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         struct apple_glx_drawable ** resultptr)
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct apple_glx_drawable *d;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (apple_glx_drawable_create(dpy, screen, drawable, &d, &callbacks))
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* apple_glx_drawable_create creates a locked and referenced object. */
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (create_surface(dpy, screen, d)) {
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      d->unlock(d);
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      d->destroy(d);
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *resultptr = d;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   d->unlock(d);
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return false;
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All surfaces are reference counted, and surfaces are only created
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * when the window is made current.  When all contexts no longer reference
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a surface drawable the apple_glx_drawable gets destroyed, and thus
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * its surface is destroyed.
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * However we can make the destruction occur a bit sooner by setting
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pending_destroy, which is then checked for in glViewport by
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * apple_glx_context_update.
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgapple_glx_surface_destroy(unsigned int uid)
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct apple_glx_drawable *d;
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   d = apple_glx_drawable_find_by_uid(uid, APPLE_GLX_DRAWABLE_REFERENCE
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      | APPLE_GLX_DRAWABLE_LOCK);
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (d) {
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      d->types.surface.pending_destroy = true;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      d->release(d);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * We release 2 references to the surface.  One was acquired by
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the find, and the other was leftover from a context, or
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * the surface being displayed, so the destroy() will decrease it
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * once more.
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * If the surface is in a context, it will take one d->destroy(d);
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * to actually destroy it when the pending_destroy is processed
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * by a glViewport callback (see apple_glx_context_update()).
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!d->destroy(d)) {
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          /* apple_glx_drawable_find_by_uid returns a locked drawable */
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          d->unlock(d);
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
226