~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/glx/apple/apple_glx_pbuffer.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 Copyright (c) 2009 Apple Inc.
3
 
 
4
 
 Permission is hereby granted, free of charge, to any person
5
 
 obtaining a copy of this software and associated documentation files
6
 
 (the "Software"), to deal in the Software without restriction,
7
 
 including without limitation the rights to use, copy, modify, merge,
8
 
 publish, distribute, sublicense, and/or sell copies of the Software,
9
 
 and to permit persons to whom the Software is furnished to do so,
10
 
 subject to the following conditions:
11
 
 
12
 
 The above copyright notice and this permission notice shall be
13
 
 included in all copies or substantial portions of the Software.
14
 
 
15
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
 
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
 
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
 
 NONINFRINGEMENT.  IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
19
 
 HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
 
 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 
 DEALINGS IN THE SOFTWARE.
23
 
 
24
 
 Except as contained in this notice, the name(s) of the above
25
 
 copyright holders shall not be used in advertising or otherwise to
26
 
 promote the sale, use or other dealings in this Software without
27
 
 prior written authorization.
28
 
*/
29
 
 
30
 
/* Must be before OpenGL.framework is included.  Remove once fixed:
31
 
 * <rdar://problem/7872773>
32
 
 */
33
 
#include <GL/gl.h>
34
 
#include <GL/glext.h>
35
 
#define __gltypes_h_ 1
36
 
 
37
 
/* Must be first for:
38
 
 * <rdar://problem/6953344>
39
 
 */
40
 
#include "apple_glx_context.h"
41
 
#include "apple_glx_drawable.h"
42
 
 
43
 
#include <stdbool.h>
44
 
#include <stdlib.h>
45
 
#include <pthread.h>
46
 
#include <assert.h>
47
 
#include "glxclient.h"
48
 
#include "apple_glx.h"
49
 
#include "glxconfig.h"
50
 
#include "apple_cgl.h"
51
 
#include "util/debug.h"
52
 
 
53
 
/* mesa defines in glew.h, Apple in glext.h.
54
 
 * Due to namespace nightmares, just do it here.
55
 
 */
56
 
#ifndef GL_TEXTURE_RECTANGLE_EXT
57
 
#define GL_TEXTURE_RECTANGLE_EXT 0x84F5
58
 
#endif
59
 
 
60
 
static bool pbuffer_make_current(struct apple_glx_context *ac,
61
 
                                 struct apple_glx_drawable *d);
62
 
 
63
 
static void pbuffer_destroy(Display * dpy, struct apple_glx_drawable *d);
64
 
 
65
 
static struct apple_glx_drawable_callbacks callbacks = {
66
 
   .type = APPLE_GLX_DRAWABLE_PBUFFER,
67
 
   .make_current = pbuffer_make_current,
68
 
   .destroy = pbuffer_destroy
69
 
};
70
 
 
71
 
 
72
 
/* Return true if an error occurred. */
73
 
bool
74
 
pbuffer_make_current(struct apple_glx_context *ac,
75
 
                     struct apple_glx_drawable *d)
76
 
{
77
 
   struct apple_glx_pbuffer *pbuf = &d->types.pbuffer;
78
 
   CGLError cglerr;
79
 
 
80
 
   assert(APPLE_GLX_DRAWABLE_PBUFFER == d->type);
81
 
 
82
 
   cglerr = apple_cgl.set_pbuffer(ac->context_obj, pbuf->buffer_obj, 0, 0, 0);
83
 
 
84
 
   if (kCGLNoError != cglerr) {
85
 
      fprintf(stderr, "set_pbuffer: %s\n", apple_cgl.error_string(cglerr));
86
 
      return true;
87
 
   }
88
 
 
89
 
   if (!ac->made_current) {
90
 
      apple_glapi_oglfw_viewport_scissor(0, 0, pbuf->width, pbuf->height);
91
 
      ac->made_current = true;
92
 
   }
93
 
 
94
 
   apple_glx_diagnostic("made pbuffer drawable 0x%lx current\n", d->drawable);
95
 
 
96
 
   return false;
97
 
}
98
 
 
99
 
void
100
 
pbuffer_destroy(Display * dpy, struct apple_glx_drawable *d)
101
 
{
102
 
   struct apple_glx_pbuffer *pbuf = &d->types.pbuffer;
103
 
 
104
 
   assert(APPLE_GLX_DRAWABLE_PBUFFER == d->type);
105
 
 
106
 
   apple_glx_diagnostic("destroying pbuffer for drawable 0x%lx\n",
107
 
                        d->drawable);
108
 
 
109
 
   apple_cgl.destroy_pbuffer(pbuf->buffer_obj);
110
 
   XFreePixmap(dpy, pbuf->xid);
111
 
}
112
 
 
113
 
/* Return true if an error occurred. */
114
 
bool
115
 
apple_glx_pbuffer_destroy(Display * dpy, GLXPbuffer pbuf)
116
 
{
117
 
   return !apple_glx_drawable_destroy_by_type(dpy, pbuf,
118
 
                                              APPLE_GLX_DRAWABLE_PBUFFER);
119
 
}
120
 
 
121
 
/* Return true if an error occurred. */
122
 
bool
123
 
apple_glx_pbuffer_create(Display * dpy, GLXFBConfig config,
124
 
                         int width, int height, int *errorcode,
125
 
                         GLXPbuffer * result)
126
 
{
127
 
   struct apple_glx_drawable *d;
128
 
   struct apple_glx_pbuffer *pbuf = NULL;
129
 
   CGLError err;
130
 
   Window root;
131
 
   int screen;
132
 
   Pixmap xid;
133
 
   struct glx_config *modes = (struct glx_config *) config;
134
 
 
135
 
   root = DefaultRootWindow(dpy);
136
 
   screen = DefaultScreen(dpy);
137
 
 
138
 
   /*
139
 
    * This pixmap is only used for a persistent XID.
140
 
    * The XC-MISC extension cleans up XIDs and reuses them transparently,
141
 
    * so we need to retain a server-side reference.
142
 
    */
143
 
   xid = XCreatePixmap(dpy, root, (unsigned int) 1,
144
 
                       (unsigned int) 1, DefaultDepth(dpy, screen));
145
 
 
146
 
   if (None == xid) {
147
 
      *errorcode = BadAlloc;
148
 
      return true;
149
 
   }
150
 
 
151
 
   if (apple_glx_drawable_create(dpy, screen, xid, &d, &callbacks)) {
152
 
      *errorcode = BadAlloc;
153
 
      return true;
154
 
   }
155
 
 
156
 
   /* The lock is held in d from create onward. */
157
 
   pbuf = &d->types.pbuffer;
158
 
 
159
 
   pbuf->xid = xid;
160
 
   pbuf->width = width;
161
 
   pbuf->height = height;
162
 
 
163
 
   err = apple_cgl.create_pbuffer(width, height, GL_TEXTURE_RECTANGLE_EXT,
164
 
                                  (modes->alphaBits > 0) ? GL_RGBA : GL_RGB,
165
 
                                  0, &pbuf->buffer_obj);
166
 
 
167
 
   if (kCGLNoError != err) {
168
 
      d->unlock(d);
169
 
      d->destroy(d);
170
 
      *errorcode = BadMatch;
171
 
      return true;
172
 
   }
173
 
 
174
 
   pbuf->fbconfigID = modes->fbconfigID;
175
 
 
176
 
   pbuf->event_mask = 0;
177
 
 
178
 
   *result = pbuf->xid;
179
 
 
180
 
   d->unlock(d);
181
 
 
182
 
   return false;
183
 
}
184
 
 
185
 
 
186
 
 
187
 
/* Return true if an error occurred. */
188
 
static bool
189
 
get_max_size(int *widthresult, int *heightresult)
190
 
{
191
 
   CGLContextObj oldcontext;
192
 
   GLint ar[2];
193
 
 
194
 
   oldcontext = apple_cgl.get_current_context();
195
 
 
196
 
   if (!oldcontext) {
197
 
      /* 
198
 
       * There is no current context, so we need to make one in order
199
 
       * to call glGetInteger.
200
 
       */
201
 
      CGLPixelFormatObj pfobj;
202
 
      CGLError err;
203
 
      CGLPixelFormatAttribute attr[10];
204
 
      int c = 0;
205
 
      GLint vsref = 0;
206
 
      CGLContextObj newcontext;
207
 
 
208
 
      attr[c++] = kCGLPFAColorSize;
209
 
      attr[c++] = 32;
210
 
      attr[c++] = 0;
211
 
 
212
 
      err = apple_cgl.choose_pixel_format(attr, &pfobj, &vsref);
213
 
      if (kCGLNoError != err) {
214
 
            DebugMessageF("choose_pixel_format error in %s: %s\n", __func__,
215
 
                          apple_cgl.error_string(err));
216
 
 
217
 
         return true;
218
 
      }
219
 
 
220
 
 
221
 
      err = apple_cgl.create_context(pfobj, NULL, &newcontext);
222
 
 
223
 
      if (kCGLNoError != err) {
224
 
         DebugMessageF("create_context error in %s: %s\n", __func__,
225
 
                       apple_cgl.error_string(err));
226
 
 
227
 
         apple_cgl.destroy_pixel_format(pfobj);
228
 
 
229
 
         return true;
230
 
      }
231
 
 
232
 
      err = apple_cgl.set_current_context(newcontext);
233
 
 
234
 
      if (kCGLNoError != err) {
235
 
         DebugMessageF("set_current_context error in %s: %s\n", __func__,
236
 
                       apple_cgl.error_string(err));
237
 
         return true;
238
 
      }
239
 
 
240
 
 
241
 
      glGetIntegerv(GL_MAX_VIEWPORT_DIMS, ar);
242
 
 
243
 
      apple_cgl.set_current_context(oldcontext);
244
 
      apple_cgl.destroy_context(newcontext);
245
 
      apple_cgl.destroy_pixel_format(pfobj);
246
 
   }
247
 
   else {
248
 
      /* We have a valid context. */
249
 
 
250
 
      glGetIntegerv(GL_MAX_VIEWPORT_DIMS, ar);
251
 
   }
252
 
 
253
 
   *widthresult = ar[0];
254
 
   *heightresult = ar[1];
255
 
 
256
 
   return false;
257
 
}
258
 
 
259
 
bool
260
 
apple_glx_pbuffer_query(GLXPbuffer p, int attr, unsigned int *value)
261
 
{
262
 
   bool result = false;
263
 
   struct apple_glx_drawable *d;
264
 
   struct apple_glx_pbuffer *pbuf;
265
 
 
266
 
   d = apple_glx_drawable_find_by_type(p, APPLE_GLX_DRAWABLE_PBUFFER,
267
 
                                       APPLE_GLX_DRAWABLE_LOCK);
268
 
 
269
 
   if (d) {
270
 
      pbuf = &d->types.pbuffer;
271
 
 
272
 
      switch (attr) {
273
 
      case GLX_WIDTH:
274
 
         *value = pbuf->width;
275
 
         result = true;
276
 
         break;
277
 
 
278
 
      case GLX_HEIGHT:
279
 
         *value = pbuf->height;
280
 
         result = true;
281
 
         break;
282
 
 
283
 
      case GLX_PRESERVED_CONTENTS:
284
 
         *value = true;
285
 
         result = true;
286
 
         break;
287
 
 
288
 
      case GLX_LARGEST_PBUFFER:{
289
 
            int width, height;
290
 
            if (get_max_size(&width, &height)) {
291
 
               fprintf(stderr, "internal error: "
292
 
                       "unable to find the largest pbuffer!\n");
293
 
            }
294
 
            else {
295
 
               *value = width;
296
 
               result = true;
297
 
            }
298
 
         }
299
 
         break;
300
 
 
301
 
      case GLX_FBCONFIG_ID:
302
 
         *value = pbuf->fbconfigID;
303
 
         result = true;
304
 
         break;
305
 
      }
306
 
 
307
 
      d->unlock(d);
308
 
   }
309
 
 
310
 
   return result;
311
 
}
312
 
 
313
 
bool
314
 
apple_glx_pbuffer_set_event_mask(GLXDrawable drawable, unsigned long mask)
315
 
{
316
 
   struct apple_glx_drawable *d;
317
 
   bool result = false;
318
 
 
319
 
   d = apple_glx_drawable_find_by_type(drawable, APPLE_GLX_DRAWABLE_PBUFFER,
320
 
                                       APPLE_GLX_DRAWABLE_LOCK);
321
 
 
322
 
   if (d) {
323
 
      d->types.pbuffer.event_mask = mask;
324
 
      result = true;
325
 
      d->unlock(d);
326
 
   }
327
 
 
328
 
   return result;
329
 
}
330
 
 
331
 
bool
332
 
apple_glx_pbuffer_get_event_mask(GLXDrawable drawable, unsigned long *mask)
333
 
{
334
 
   struct apple_glx_drawable *d;
335
 
   bool result = false;
336
 
 
337
 
   d = apple_glx_drawable_find_by_type(drawable, APPLE_GLX_DRAWABLE_PBUFFER,
338
 
                                       APPLE_GLX_DRAWABLE_LOCK);
339
 
   if (d) {
340
 
      *mask = d->types.pbuffer.event_mask;
341
 
      result = true;
342
 
      d->unlock(d);
343
 
   }
344
 
 
345
 
   return result;
346
 
}