Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/glx/apple/apple_glx_pbuffer.c
4560 views
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
}
347
348