Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/egl/main/eglcontext.c
4560 views
1
/**************************************************************************
2
*
3
* Copyright 2008 VMware, Inc.
4
* Copyright 2009-2010 Chia-I Wu <[email protected]>
5
* Copyright 2010-2011 LunarG, Inc.
6
* All Rights Reserved.
7
*
8
* Permission is hereby granted, free of charge, to any person obtaining a
9
* copy of this software and associated documentation files (the
10
* "Software"), to deal in the Software without restriction, including
11
* without limitation the rights to use, copy, modify, merge, publish,
12
* distribute, sub license, and/or sell copies of the Software, and to
13
* permit persons to whom the Software is furnished to do so, subject to
14
* the following conditions:
15
*
16
* The above copyright notice and this permission notice (including the
17
* next paragraph) shall be included in all copies or substantial portions
18
* of the Software.
19
*
20
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26
* DEALINGS IN THE SOFTWARE.
27
*
28
**************************************************************************/
29
30
31
#include <assert.h>
32
#include <stdlib.h>
33
#include <string.h>
34
#include "eglconfig.h"
35
#include "eglcontext.h"
36
#include "egldisplay.h"
37
#include "eglcurrent.h"
38
#include "eglsurface.h"
39
#include "egllog.h"
40
#include "util/macros.h"
41
42
43
/**
44
* Return the API bit (one of EGL_xxx_BIT) of the context.
45
*/
46
static EGLint
47
_eglGetContextAPIBit(_EGLContext *ctx)
48
{
49
EGLint bit = 0;
50
51
switch (ctx->ClientAPI) {
52
case EGL_OPENGL_ES_API:
53
switch (ctx->ClientMajorVersion) {
54
case 1:
55
bit = EGL_OPENGL_ES_BIT;
56
break;
57
case 2:
58
bit = EGL_OPENGL_ES2_BIT;
59
break;
60
case 3:
61
bit = EGL_OPENGL_ES3_BIT_KHR;
62
break;
63
default:
64
break;
65
}
66
break;
67
case EGL_OPENVG_API:
68
bit = EGL_OPENVG_BIT;
69
break;
70
case EGL_OPENGL_API:
71
bit = EGL_OPENGL_BIT;
72
break;
73
default:
74
break;
75
}
76
77
return bit;
78
}
79
80
81
/**
82
* Parse the list of context attributes and return the proper error code.
83
*/
84
static EGLint
85
_eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *disp,
86
const EGLint *attrib_list)
87
{
88
EGLenum api = ctx->ClientAPI;
89
EGLint i, err = EGL_SUCCESS;
90
91
if (!attrib_list)
92
return EGL_SUCCESS;
93
94
if (api == EGL_OPENVG_API && attrib_list[0] != EGL_NONE) {
95
_eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attrib_list[0]);
96
return EGL_BAD_ATTRIBUTE;
97
}
98
99
for (i = 0; attrib_list[i] != EGL_NONE; i++) {
100
EGLint attr = attrib_list[i++];
101
EGLint val = attrib_list[i];
102
103
switch (attr) {
104
case EGL_CONTEXT_CLIENT_VERSION:
105
/* The EGL 1.4 spec says:
106
*
107
* "attribute EGL_CONTEXT_CLIENT_VERSION is only valid when the
108
* current rendering API is EGL_OPENGL_ES_API"
109
*
110
* The EGL_KHR_create_context spec says:
111
*
112
* "EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
113
* (this token is an alias for EGL_CONTEXT_CLIENT_VERSION)"
114
*
115
* "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
116
* EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API
117
* version. They are only meaningful for OpenGL and OpenGL ES
118
* contexts, and specifying them for other types of contexts will
119
* generate an error."
120
*/
121
if ((api != EGL_OPENGL_ES_API &&
122
(!disp->Extensions.KHR_create_context || api != EGL_OPENGL_API))) {
123
err = EGL_BAD_ATTRIBUTE;
124
break;
125
}
126
127
ctx->ClientMajorVersion = val;
128
break;
129
130
case EGL_CONTEXT_MINOR_VERSION_KHR:
131
/* The EGL_KHR_create_context spec says:
132
*
133
* "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
134
* EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API
135
* version. They are only meaningful for OpenGL and OpenGL ES
136
* contexts, and specifying them for other types of contexts will
137
* generate an error."
138
*/
139
if (!disp->Extensions.KHR_create_context ||
140
(api != EGL_OPENGL_ES_API && api != EGL_OPENGL_API)) {
141
err = EGL_BAD_ATTRIBUTE;
142
break;
143
}
144
145
ctx->ClientMinorVersion = val;
146
break;
147
148
case EGL_CONTEXT_FLAGS_KHR:
149
if (!disp->Extensions.KHR_create_context) {
150
err = EGL_BAD_ATTRIBUTE;
151
break;
152
}
153
154
/* The EGL_KHR_create_context spec says:
155
*
156
* "If the EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR flag bit is set in
157
* EGL_CONTEXT_FLAGS_KHR, then a <debug context> will be created.
158
* [...]
159
* In some cases a debug context may be identical to a non-debug
160
* context. This bit is supported for OpenGL and OpenGL ES
161
* contexts."
162
*/
163
if ((val & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) &&
164
(api != EGL_OPENGL_API && api != EGL_OPENGL_ES_API)) {
165
err = EGL_BAD_ATTRIBUTE;
166
break;
167
}
168
169
/* The EGL_KHR_create_context spec says:
170
*
171
* "If the EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR flag bit
172
* is set in EGL_CONTEXT_FLAGS_KHR, then a <forward-compatible>
173
* context will be created. Forward-compatible contexts are
174
* defined only for OpenGL versions 3.0 and later. They must not
175
* support functionality marked as <deprecated> by that version of
176
* the API, while a non-forward-compatible context must support
177
* all functionality in that version, deprecated or not. This bit
178
* is supported for OpenGL contexts, and requesting a
179
* forward-compatible context for OpenGL versions less than 3.0
180
* will generate an error."
181
*
182
* Note: since the forward-compatible flag can be set more than one way,
183
* the OpenGL version check is performed once, below.
184
*/
185
if ((val & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) &&
186
api != EGL_OPENGL_API) {
187
err = EGL_BAD_ATTRIBUTE;
188
break;
189
}
190
191
if ((val & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) &&
192
api != EGL_OPENGL_API) {
193
/* The EGL_KHR_create_context spec says:
194
*
195
* 10) Which error should be generated if robust buffer access
196
* or reset notifications are requested under OpenGL ES?
197
*
198
* As per Issue 6, this extension does not support creating
199
* robust contexts for OpenGL ES. This is only supported via
200
* the EGL_EXT_create_context_robustness extension.
201
*
202
* Attempting to use this extension to create robust OpenGL
203
* ES context will generate an EGL_BAD_ATTRIBUTE error. This
204
* specific error is generated because this extension does
205
* not define the EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
206
* and EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR
207
* bits for OpenGL ES contexts. Thus, use of these bits fall
208
* under condition described by: "If an attribute is
209
* specified that is not meaningful for the client API
210
* type.." in the above specification.
211
*
212
* The spec requires that we emit the error even if the display
213
* supports EGL_EXT_create_context_robustness. To create a robust
214
* GLES context, the *attribute*
215
* EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT must be used, not the
216
* *flag* EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR.
217
*/
218
err = EGL_BAD_ATTRIBUTE;
219
break;
220
}
221
222
ctx->Flags |= val;
223
break;
224
225
case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
226
if (!disp->Extensions.KHR_create_context) {
227
err = EGL_BAD_ATTRIBUTE;
228
break;
229
}
230
231
/* The EGL_KHR_create_context spec says:
232
*
233
* "[EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR] is only meaningful for
234
* OpenGL contexts, and specifying it for other types of
235
* contexts, including OpenGL ES contexts, will generate an
236
* error."
237
*/
238
if (api != EGL_OPENGL_API) {
239
err = EGL_BAD_ATTRIBUTE;
240
break;
241
}
242
243
ctx->Profile = val;
244
break;
245
246
case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
247
/* The EGL_KHR_create_context spec says:
248
*
249
* "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR] is only
250
* meaningful for OpenGL contexts, and specifying it for other
251
* types of contexts, including OpenGL ES contexts, will generate
252
* an error."
253
*
254
* EGL 1.5 defines EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY
255
* (without a suffix) which has the same value as the KHR token,
256
* and specifies that it now works with both GL and ES contexts:
257
*
258
* "This attribute is supported only for OpenGL and OpenGL ES
259
* contexts."
260
*/
261
if (!(disp->Extensions.KHR_create_context && api == EGL_OPENGL_API)
262
&& !(disp->Version >= 15 && (api == EGL_OPENGL_API ||
263
api == EGL_OPENGL_ES_API))) {
264
err = EGL_BAD_ATTRIBUTE;
265
break;
266
}
267
268
ctx->ResetNotificationStrategy = val;
269
break;
270
271
case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
272
/* The EGL_EXT_create_context_robustness spec says:
273
*
274
* "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT] is only
275
* meaningful for OpenGL ES contexts, and specifying it for other
276
* types of contexts will generate an EGL_BAD_ATTRIBUTE error."
277
*/
278
if (!disp->Extensions.EXT_create_context_robustness
279
|| api != EGL_OPENGL_ES_API) {
280
err = EGL_BAD_ATTRIBUTE;
281
break;
282
}
283
284
ctx->ResetNotificationStrategy = val;
285
break;
286
287
case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
288
if (!disp->Extensions.EXT_create_context_robustness) {
289
err = EGL_BAD_ATTRIBUTE;
290
break;
291
}
292
293
if (val == EGL_TRUE)
294
ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
295
break;
296
297
case EGL_CONTEXT_OPENGL_ROBUST_ACCESS:
298
if (disp->Version < 15) {
299
err = EGL_BAD_ATTRIBUTE;
300
break;
301
}
302
303
if (val == EGL_TRUE)
304
ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
305
break;
306
307
case EGL_CONTEXT_OPENGL_DEBUG:
308
if (disp->Version < 15) {
309
err = EGL_BAD_ATTRIBUTE;
310
break;
311
}
312
313
if (val == EGL_TRUE)
314
ctx->Flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
315
break;
316
317
case EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE:
318
if (disp->Version < 15) {
319
err = EGL_BAD_ATTRIBUTE;
320
break;
321
}
322
323
if (val == EGL_TRUE)
324
ctx->Flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
325
break;
326
327
case EGL_CONTEXT_OPENGL_NO_ERROR_KHR:
328
if (disp->Version < 14 ||
329
!disp->Extensions.KHR_create_context_no_error) {
330
err = EGL_BAD_ATTRIBUTE;
331
break;
332
}
333
334
/* The KHR_no_error spec only applies against OpenGL 2.0+ and
335
* OpenGL ES 2.0+
336
*/
337
if (((api != EGL_OPENGL_API && api != EGL_OPENGL_ES_API) ||
338
ctx->ClientMajorVersion < 2) && val == EGL_TRUE) {
339
err = EGL_BAD_ATTRIBUTE;
340
break;
341
}
342
343
/* Canonicalize value to EGL_TRUE/EGL_FALSE definitions */
344
ctx->NoError = !!val;
345
break;
346
347
case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
348
/* The EGL_IMG_context_priority spec says:
349
*
350
* "EGL_CONTEXT_PRIORITY_LEVEL_IMG determines the priority level of
351
* the context to be created. This attribute is a hint, as an
352
* implementation may not support multiple contexts at some
353
* priority levels and system policy may limit access to high
354
* priority contexts to appropriate system privilege level. The
355
* default value for EGL_CONTEXT_PRIORITY_LEVEL_IMG is
356
* EGL_CONTEXT_PRIORITY_MEDIUM_IMG."
357
*/
358
{
359
int bit;
360
361
switch (val) {
362
case EGL_CONTEXT_PRIORITY_HIGH_IMG:
363
bit = __EGL_CONTEXT_PRIORITY_HIGH_BIT;
364
break;
365
case EGL_CONTEXT_PRIORITY_MEDIUM_IMG:
366
bit = __EGL_CONTEXT_PRIORITY_MEDIUM_BIT;
367
break;
368
case EGL_CONTEXT_PRIORITY_LOW_IMG:
369
bit = __EGL_CONTEXT_PRIORITY_LOW_BIT;
370
break;
371
default:
372
bit = -1;
373
break;
374
}
375
376
if (bit < 0) {
377
err = EGL_BAD_ATTRIBUTE;
378
break;
379
}
380
381
/* "This extension allows an EGLContext to be created with a
382
* priority hint. It is possible that an implementation will not
383
* honour the hint, especially if there are constraints on the
384
* number of high priority contexts available in the system, or
385
* system policy limits access to high priority contexts to
386
* appropriate system privilege level. A query is provided to find
387
* the real priority level assigned to the context after creation."
388
*
389
* We currently assume that the driver applies the priority hint
390
* and filters out any it cannot handle during the screen setup,
391
* e.g. dri2_setup_screen(). As such we can mask any change that
392
* the driver would fail, and ctx->ContextPriority matches the
393
* hint applied to the driver/hardware backend.
394
*/
395
if (disp->Extensions.IMG_context_priority & (1 << bit))
396
ctx->ContextPriority = val;
397
398
break;
399
}
400
401
case EGL_CONTEXT_RELEASE_BEHAVIOR_KHR:
402
if (val == EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR ||
403
val == EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR) {
404
ctx->ReleaseBehavior = val;
405
} else {
406
err = EGL_BAD_ATTRIBUTE;
407
}
408
break;
409
410
default:
411
err = EGL_BAD_ATTRIBUTE;
412
break;
413
}
414
415
if (err != EGL_SUCCESS) {
416
_eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attr);
417
break;
418
}
419
}
420
421
if (api == EGL_OPENGL_API) {
422
/* The EGL_KHR_create_context spec says:
423
*
424
* "If the requested OpenGL version is less than 3.2,
425
* EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR is ignored and the
426
* functionality of the context is determined solely by the
427
* requested version."
428
*
429
* Since the value is ignored, only validate the setting if the version
430
* is >= 3.2.
431
*/
432
if (ctx->ClientMajorVersion >= 4
433
|| (ctx->ClientMajorVersion == 3 && ctx->ClientMinorVersion >= 2)) {
434
switch (ctx->Profile) {
435
case EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR:
436
case EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR:
437
break;
438
439
default:
440
/* The EGL_KHR_create_context spec says:
441
*
442
* "* If an OpenGL context is requested, the requested version
443
* is greater than 3.2, and the value for attribute
444
* EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has
445
* any bits set other than EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR
446
* and EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has
447
* more than one of these bits set; or if the implementation does
448
* not support the requested profile, then an EGL_BAD_MATCH error
449
* is generated."
450
*/
451
err = EGL_BAD_MATCH;
452
break;
453
}
454
}
455
456
/* The EGL_KHR_create_context spec says:
457
*
458
* "* If an OpenGL context is requested and the values for
459
* attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
460
* EGL_CONTEXT_MINOR_VERSION_KHR, when considered together with
461
* the value for attribute
462
* EGL_CONTEXT_FORWARD_COMPATIBLE_BIT_KHR, specify an OpenGL
463
* version and feature set that are not defined, than an
464
* EGL_BAD_MATCH error is generated.
465
*
466
* ... Thus, examples of invalid combinations of attributes
467
* include:
468
*
469
* - Major version < 1 or > 4
470
* - Major version == 1 and minor version < 0 or > 5
471
* - Major version == 2 and minor version < 0 or > 1
472
* - Major version == 3 and minor version < 0 or > 2
473
* - Major version == 4 and minor version < 0 or > 2
474
* - Forward-compatible flag set and major version < 3"
475
*/
476
if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0)
477
err = EGL_BAD_MATCH;
478
479
switch (ctx->ClientMajorVersion) {
480
case 1:
481
if (ctx->ClientMinorVersion > 5
482
|| (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0)
483
err = EGL_BAD_MATCH;
484
break;
485
486
case 2:
487
if (ctx->ClientMinorVersion > 1
488
|| (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0)
489
err = EGL_BAD_MATCH;
490
break;
491
492
case 3:
493
/* Note: The text above is incorrect. There *is* an OpenGL 3.3!
494
*/
495
if (ctx->ClientMinorVersion > 3)
496
err = EGL_BAD_MATCH;
497
break;
498
499
case 4:
500
default:
501
/* Don't put additional version checks here. We don't know that
502
* there won't be versions > 4.2.
503
*/
504
break;
505
}
506
} else if (api == EGL_OPENGL_ES_API) {
507
/* The EGL_KHR_create_context spec says:
508
*
509
* "* If an OpenGL ES context is requested and the values for
510
* attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
511
* EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that
512
* is not defined, than an EGL_BAD_MATCH error is generated.
513
*
514
* ... Examples of invalid combinations of attributes include:
515
*
516
* - Major version < 1 or > 2
517
* - Major version == 1 and minor version < 0 or > 1
518
* - Major version == 2 and minor version != 0
519
*/
520
if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0)
521
err = EGL_BAD_MATCH;
522
523
switch (ctx->ClientMajorVersion) {
524
case 1:
525
if (ctx->ClientMinorVersion > 1)
526
err = EGL_BAD_MATCH;
527
break;
528
529
case 2:
530
if (ctx->ClientMinorVersion > 0)
531
err = EGL_BAD_MATCH;
532
break;
533
534
case 3:
535
/* Don't put additional version checks here. We don't know that
536
* there won't be versions > 3.0.
537
*/
538
break;
539
540
default:
541
err = EGL_BAD_MATCH;
542
break;
543
}
544
}
545
546
switch (ctx->ResetNotificationStrategy) {
547
case EGL_NO_RESET_NOTIFICATION_KHR:
548
case EGL_LOSE_CONTEXT_ON_RESET_KHR:
549
break;
550
551
default:
552
err = EGL_BAD_ATTRIBUTE;
553
break;
554
}
555
556
/* The EGL_KHR_create_context_no_error spec says:
557
*
558
* "BAD_MATCH is generated if the EGL_CONTEXT_OPENGL_NO_ERROR_KHR is TRUE at
559
* the same time as a debug or robustness context is specified."
560
*/
561
if (ctx->NoError && (ctx->Flags & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR ||
562
ctx->Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) {
563
err = EGL_BAD_MATCH;
564
}
565
566
if ((ctx->Flags & ~(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
567
| EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
568
| EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) != 0) {
569
err = EGL_BAD_ATTRIBUTE;
570
}
571
572
return err;
573
}
574
575
576
/**
577
* Initialize the given _EGLContext object to defaults and/or the values
578
* in the attrib_list.
579
*
580
* According to EGL 1.5 Section 3.7:
581
*
582
* "EGL_OPENGL_API and EGL_OPENGL_ES_API are interchangeable for all
583
* purposes except eglCreateContext."
584
*
585
* And since we only support GL and GLES, this is the only place where the
586
* bound API matters at all. We look up the current API from the current
587
* thread, and stash that in the context we're initializing. Our caller is
588
* responsible for determining whether that's an API it supports.
589
*/
590
EGLBoolean
591
_eglInitContext(_EGLContext *ctx, _EGLDisplay *disp, _EGLConfig *conf,
592
const EGLint *attrib_list)
593
{
594
const EGLenum api = eglQueryAPI();
595
EGLint err;
596
597
if (api == EGL_NONE)
598
return _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)");
599
600
_eglInitResource(&ctx->Resource, sizeof(*ctx), disp);
601
ctx->ClientAPI = api;
602
ctx->Config = conf;
603
ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
604
605
ctx->ClientMajorVersion = 1; /* the default, per EGL spec */
606
ctx->ClientMinorVersion = 0;
607
ctx->Flags = 0;
608
ctx->ResetNotificationStrategy = EGL_NO_RESET_NOTIFICATION_KHR;
609
ctx->ContextPriority = EGL_CONTEXT_PRIORITY_MEDIUM_IMG;
610
ctx->ReleaseBehavior = EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR;
611
612
err = _eglParseContextAttribList(ctx, disp, attrib_list);
613
if (err == EGL_SUCCESS && ctx->Config) {
614
EGLint api_bit;
615
616
api_bit = _eglGetContextAPIBit(ctx);
617
if (!(ctx->Config->RenderableType & api_bit)) {
618
_eglLog(_EGL_DEBUG, "context api is 0x%x while config supports 0x%x",
619
api_bit, ctx->Config->RenderableType);
620
err = EGL_BAD_CONFIG;
621
}
622
}
623
if (err != EGL_SUCCESS)
624
return _eglError(err, "eglCreateContext");
625
626
return EGL_TRUE;
627
}
628
629
630
static EGLint
631
_eglQueryContextRenderBuffer(_EGLContext *ctx)
632
{
633
_EGLSurface *surf = ctx->DrawSurface;
634
635
/* From the EGL 1.5 spec:
636
*
637
* - If the context is not bound to a surface, then EGL_NONE will be
638
* returned.
639
*/
640
if (!surf)
641
return EGL_NONE;
642
643
switch (surf->Type) {
644
default:
645
unreachable("bad EGLSurface type");
646
case EGL_PIXMAP_BIT:
647
/* - If the context is bound to a pixmap surface, then EGL_SINGLE_BUFFER
648
* will be returned.
649
*/
650
return EGL_SINGLE_BUFFER;
651
case EGL_PBUFFER_BIT:
652
/* - If the context is bound to a pbuffer surface, then EGL_BACK_BUFFER
653
* will be returned.
654
*/
655
return EGL_BACK_BUFFER;
656
case EGL_WINDOW_BIT:
657
/* - If the context is bound to a window surface, then either
658
* EGL_BACK_BUFFER or EGL_SINGLE_BUFFER may be returned. The value
659
* returned depends on both the buffer requested by the setting of the
660
* EGL_RENDER_BUFFER property of the surface [...], and on the client
661
* API (not all client APIs support single-buffer Rendering to window
662
* surfaces). Some client APIs allow control of whether rendering goes
663
* to the front or back buffer. This client API-specific choice is not
664
* reflected in the returned value, which only describes the buffer
665
* that will be rendered to by default if not overridden by the client
666
* API.
667
*/
668
return surf->ActiveRenderBuffer;
669
}
670
}
671
672
673
EGLBoolean
674
_eglQueryContext(_EGLContext *c, EGLint attribute, EGLint *value)
675
{
676
if (!value)
677
return _eglError(EGL_BAD_PARAMETER, "eglQueryContext");
678
679
switch (attribute) {
680
case EGL_CONFIG_ID:
681
/*
682
* From EGL_KHR_no_config_context:
683
*
684
* "Querying EGL_CONFIG_ID returns the ID of the EGLConfig with
685
* respect to which the context was created, or zero if created
686
* without respect to an EGLConfig."
687
*/
688
*value = c->Config ? c->Config->ConfigID : 0;
689
break;
690
case EGL_CONTEXT_CLIENT_VERSION:
691
*value = c->ClientMajorVersion;
692
break;
693
case EGL_CONTEXT_CLIENT_TYPE:
694
*value = c->ClientAPI;
695
break;
696
case EGL_RENDER_BUFFER:
697
*value = _eglQueryContextRenderBuffer(c);
698
break;
699
case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
700
*value = c->ContextPriority;
701
break;
702
default:
703
return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
704
}
705
706
return EGL_TRUE;
707
}
708
709
710
/**
711
* Bind the context to the thread and return the previous context.
712
*
713
* Note that the context may be NULL.
714
*/
715
_EGLContext *
716
_eglBindContextToThread(_EGLContext *ctx, _EGLThreadInfo *t)
717
{
718
_EGLContext *oldCtx;
719
720
oldCtx = t->CurrentContext;
721
if (ctx != oldCtx) {
722
if (oldCtx)
723
oldCtx->Binding = NULL;
724
if (ctx)
725
ctx->Binding = t;
726
727
t->CurrentContext = ctx;
728
}
729
730
return oldCtx;
731
}
732
733
734
/**
735
* Return true if the given context and surfaces can be made current.
736
*/
737
static EGLBoolean
738
_eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
739
{
740
_EGLThreadInfo *t = _eglGetCurrentThread();
741
_EGLDisplay *disp;
742
743
if (_eglIsCurrentThreadDummy())
744
return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");
745
746
/* this is easy */
747
if (!ctx) {
748
if (draw || read)
749
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
750
return EGL_TRUE;
751
}
752
753
disp = ctx->Resource.Display;
754
if (!disp->Extensions.KHR_surfaceless_context
755
&& (draw == NULL || read == NULL))
756
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
757
758
/*
759
* The spec says
760
*
761
* "If ctx is current to some other thread, or if either draw or read are
762
* bound to contexts in another thread, an EGL_BAD_ACCESS error is
763
* generated."
764
*
765
* and
766
*
767
* "at most one context may be bound to a particular surface at a given
768
* time"
769
*/
770
if (ctx->Binding && ctx->Binding != t)
771
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
772
if (draw && draw->CurrentContext && draw->CurrentContext != ctx) {
773
if (draw->CurrentContext->Binding != t)
774
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
775
}
776
if (read && read->CurrentContext && read->CurrentContext != ctx) {
777
if (read->CurrentContext->Binding != t)
778
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
779
}
780
781
/* If the context has a config then it must match that of the two
782
* surfaces */
783
if (ctx->Config) {
784
if ((draw && draw->Config != ctx->Config) ||
785
(read && read->Config != ctx->Config))
786
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
787
} else {
788
/* Otherwise we must be using the EGL_KHR_no_config_context
789
* extension */
790
assert(disp->Extensions.KHR_no_config_context);
791
792
/* The extension doesn't permit binding draw and read buffers with
793
* differing contexts */
794
if (draw && read && draw->Config != read->Config)
795
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
796
}
797
798
return EGL_TRUE;
799
}
800
801
802
/**
803
* Bind the context to the current thread and given surfaces. Return the
804
* previous bound context and surfaces. The caller should unreference the
805
* returned context and surfaces.
806
*
807
* Making a second call with the resources returned by the first call
808
* unsurprisingly undoes the first call, except for the resouce reference
809
* counts.
810
*/
811
EGLBoolean
812
_eglBindContext(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read,
813
_EGLContext **old_ctx,
814
_EGLSurface **old_draw, _EGLSurface **old_read)
815
{
816
_EGLThreadInfo *t = _eglGetCurrentThread();
817
_EGLContext *prev_ctx;
818
_EGLSurface *prev_draw, *prev_read;
819
820
if (!_eglCheckMakeCurrent(ctx, draw, read))
821
return EGL_FALSE;
822
823
/* increment refcounts before binding */
824
_eglGetContext(ctx);
825
_eglGetSurface(draw);
826
_eglGetSurface(read);
827
828
/* bind the new context */
829
prev_ctx = _eglBindContextToThread(ctx, t);
830
831
/* break previous bindings */
832
if (prev_ctx) {
833
prev_draw = prev_ctx->DrawSurface;
834
prev_read = prev_ctx->ReadSurface;
835
836
if (prev_draw)
837
prev_draw->CurrentContext = NULL;
838
if (prev_read)
839
prev_read->CurrentContext = NULL;
840
841
prev_ctx->DrawSurface = NULL;
842
prev_ctx->ReadSurface = NULL;
843
}
844
else {
845
prev_draw = prev_read = NULL;
846
}
847
848
/* establish new bindings */
849
if (ctx) {
850
if (draw)
851
draw->CurrentContext = ctx;
852
if (read)
853
read->CurrentContext = ctx;
854
855
ctx->DrawSurface = draw;
856
ctx->ReadSurface = read;
857
}
858
859
assert(old_ctx && old_draw && old_read);
860
*old_ctx = prev_ctx;
861
*old_draw = prev_draw;
862
*old_read = prev_read;
863
864
return EGL_TRUE;
865
}
866
867