Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/egl/main/eglsurface.c
4560 views
1
/**************************************************************************
2
*
3
* Copyright 2008 VMware, Inc.
4
* Copyright 2009-2010 Chia-I Wu <[email protected]>
5
* Copyright 2010 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
/**
32
* Surface-related functions.
33
*/
34
35
36
#include <assert.h>
37
#include <stdlib.h>
38
#include <string.h>
39
#include "egldefines.h"
40
#include "egldisplay.h"
41
#include "egldriver.h"
42
#include "eglcontext.h"
43
#include "eglconfig.h"
44
#include "eglcurrent.h"
45
#include "egllog.h"
46
#include "eglsurface.h"
47
48
#include "util/macros.h"
49
50
/**
51
* Parse the list of surface attributes and return the proper error code.
52
*/
53
static EGLint
54
_eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
55
{
56
_EGLDisplay *disp = surf->Resource.Display;
57
EGLint type = surf->Type;
58
EGLint texture_type = EGL_PBUFFER_BIT;
59
EGLint i, err = EGL_SUCCESS;
60
EGLint attr = EGL_NONE;
61
EGLint val = EGL_NONE;
62
63
if (!attrib_list)
64
return EGL_SUCCESS;
65
66
if (disp->Extensions.NOK_texture_from_pixmap)
67
texture_type |= EGL_PIXMAP_BIT;
68
69
for (i = 0; attrib_list[i] != EGL_NONE; i++) {
70
attr = attrib_list[i++];
71
val = attrib_list[i];
72
73
switch (attr) {
74
/* common attributes */
75
case EGL_GL_COLORSPACE_KHR:
76
if (!disp->Extensions.KHR_gl_colorspace) {
77
err = EGL_BAD_ATTRIBUTE;
78
break;
79
}
80
switch (val) {
81
case EGL_GL_COLORSPACE_SRGB_KHR:
82
case EGL_GL_COLORSPACE_LINEAR_KHR:
83
break;
84
default:
85
err = EGL_BAD_ATTRIBUTE;
86
}
87
if (err != EGL_SUCCESS)
88
break;
89
surf->GLColorspace = val;
90
break;
91
case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
92
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
93
err = EGL_BAD_ATTRIBUTE;
94
break;
95
}
96
surf->HdrMetadata.display_primary_r.x = val;
97
break;
98
case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
99
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
100
err = EGL_BAD_ATTRIBUTE;
101
break;
102
}
103
surf->HdrMetadata.display_primary_r.y = val;
104
break;
105
case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
106
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
107
err = EGL_BAD_ATTRIBUTE;
108
break;
109
}
110
surf->HdrMetadata.display_primary_g.x = val;
111
break;
112
case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
113
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
114
err = EGL_BAD_ATTRIBUTE;
115
break;
116
}
117
surf->HdrMetadata.display_primary_g.y = val;
118
break;
119
case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
120
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
121
err = EGL_BAD_ATTRIBUTE;
122
break;
123
}
124
surf->HdrMetadata.display_primary_b.x = val;
125
break;
126
case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
127
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
128
err = EGL_BAD_ATTRIBUTE;
129
break;
130
}
131
surf->HdrMetadata.display_primary_b.y = val;
132
break;
133
case EGL_SMPTE2086_WHITE_POINT_X_EXT:
134
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
135
err = EGL_BAD_ATTRIBUTE;
136
break;
137
}
138
surf->HdrMetadata.white_point.x = val;
139
break;
140
case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
141
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
142
err = EGL_BAD_ATTRIBUTE;
143
break;
144
}
145
surf->HdrMetadata.white_point.y = val;
146
break;
147
case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
148
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
149
err = EGL_BAD_ATTRIBUTE;
150
break;
151
}
152
surf->HdrMetadata.max_luminance = val;
153
break;
154
case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
155
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
156
err = EGL_BAD_ATTRIBUTE;
157
break;
158
}
159
surf->HdrMetadata.min_luminance = val;
160
break;
161
case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
162
if (!disp->Extensions.EXT_surface_CTA861_3_metadata) {
163
err = EGL_BAD_ATTRIBUTE;
164
break;
165
}
166
surf->HdrMetadata.max_cll = val;
167
break;
168
case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
169
if (!disp->Extensions.EXT_surface_CTA861_3_metadata) {
170
err = EGL_BAD_ATTRIBUTE;
171
break;
172
}
173
surf->HdrMetadata.max_fall = val;
174
break;
175
case EGL_VG_COLORSPACE:
176
switch (val) {
177
case EGL_VG_COLORSPACE_sRGB:
178
case EGL_VG_COLORSPACE_LINEAR:
179
break;
180
default:
181
err = EGL_BAD_ATTRIBUTE;
182
break;
183
}
184
if (err != EGL_SUCCESS)
185
break;
186
surf->VGColorspace = val;
187
break;
188
case EGL_VG_ALPHA_FORMAT:
189
switch (val) {
190
case EGL_VG_ALPHA_FORMAT_NONPRE:
191
case EGL_VG_ALPHA_FORMAT_PRE:
192
break;
193
default:
194
err = EGL_BAD_ATTRIBUTE;
195
break;
196
}
197
if (err != EGL_SUCCESS)
198
break;
199
surf->VGAlphaFormat = val;
200
break;
201
/* window surface attributes */
202
case EGL_RENDER_BUFFER:
203
if (type != EGL_WINDOW_BIT) {
204
err = EGL_BAD_ATTRIBUTE;
205
break;
206
}
207
if (val != EGL_BACK_BUFFER && val != EGL_SINGLE_BUFFER) {
208
err = EGL_BAD_ATTRIBUTE;
209
break;
210
}
211
surf->RequestedRenderBuffer = val;
212
if (surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR) {
213
/* Unlike normal EGLSurfaces, one with a mutable render buffer
214
* uses the application-chosen render buffer.
215
*/
216
surf->ActiveRenderBuffer = val;
217
}
218
break;
219
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
220
if (!disp->Extensions.NV_post_sub_buffer ||
221
type != EGL_WINDOW_BIT) {
222
err = EGL_BAD_ATTRIBUTE;
223
break;
224
}
225
if (val != EGL_TRUE && val != EGL_FALSE) {
226
err = EGL_BAD_PARAMETER;
227
break;
228
}
229
surf->PostSubBufferSupportedNV = val;
230
break;
231
/* pbuffer surface attributes */
232
case EGL_WIDTH:
233
if (type != EGL_PBUFFER_BIT) {
234
err = EGL_BAD_ATTRIBUTE;
235
break;
236
}
237
if (val < 0) {
238
err = EGL_BAD_PARAMETER;
239
break;
240
}
241
surf->Width = val;
242
break;
243
case EGL_HEIGHT:
244
if (type != EGL_PBUFFER_BIT) {
245
err = EGL_BAD_ATTRIBUTE;
246
break;
247
}
248
if (val < 0) {
249
err = EGL_BAD_PARAMETER;
250
break;
251
}
252
surf->Height = val;
253
break;
254
case EGL_LARGEST_PBUFFER:
255
if (type != EGL_PBUFFER_BIT) {
256
err = EGL_BAD_ATTRIBUTE;
257
break;
258
}
259
surf->LargestPbuffer = !!val;
260
break;
261
/* for eglBindTexImage */
262
case EGL_TEXTURE_FORMAT:
263
if (!(type & texture_type)) {
264
err = EGL_BAD_ATTRIBUTE;
265
break;
266
}
267
268
switch (val) {
269
case EGL_TEXTURE_RGB:
270
case EGL_TEXTURE_RGBA:
271
case EGL_NO_TEXTURE:
272
break;
273
default:
274
err = EGL_BAD_ATTRIBUTE;
275
break;
276
}
277
if (err != EGL_SUCCESS)
278
break;
279
surf->TextureFormat = val;
280
break;
281
case EGL_TEXTURE_TARGET:
282
if (!(type & texture_type)) {
283
err = EGL_BAD_ATTRIBUTE;
284
break;
285
}
286
287
switch (val) {
288
case EGL_TEXTURE_2D:
289
case EGL_NO_TEXTURE:
290
break;
291
default:
292
err = EGL_BAD_ATTRIBUTE;
293
break;
294
}
295
if (err != EGL_SUCCESS)
296
break;
297
surf->TextureTarget = val;
298
break;
299
case EGL_MIPMAP_TEXTURE:
300
if (!(type & texture_type)) {
301
err = EGL_BAD_ATTRIBUTE;
302
break;
303
}
304
surf->MipmapTexture = !!val;
305
break;
306
case EGL_PROTECTED_CONTENT_EXT:
307
if (!disp->Extensions.EXT_protected_surface) {
308
err = EGL_BAD_ATTRIBUTE;
309
break;
310
}
311
surf->ProtectedContent = val;
312
break;
313
314
/* no pixmap surface specific attributes */
315
default:
316
err = EGL_BAD_ATTRIBUTE;
317
break;
318
}
319
320
if (err != EGL_SUCCESS)
321
break;
322
}
323
324
if (err == EGL_SUCCESS && type == EGL_PBUFFER_BIT) {
325
if ((surf->TextureTarget == EGL_NO_TEXTURE && surf->TextureFormat != EGL_NO_TEXTURE) ||
326
(surf->TextureFormat == EGL_NO_TEXTURE && surf->TextureTarget != EGL_NO_TEXTURE)) {
327
attr = surf->TextureTarget == EGL_NO_TEXTURE ? EGL_TEXTURE_TARGET : EGL_TEXTURE_FORMAT;
328
err = EGL_BAD_MATCH;
329
}
330
}
331
332
if (err != EGL_SUCCESS)
333
_eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
334
335
return err;
336
}
337
338
339
/**
340
* Do error check on parameters and initialize the given _EGLSurface object.
341
* \return EGL_TRUE if no errors, EGL_FALSE otherwise.
342
*/
343
EGLBoolean
344
_eglInitSurface(_EGLSurface *surf, _EGLDisplay *disp, EGLint type,
345
_EGLConfig *conf, const EGLint *attrib_list,
346
void *native_surface)
347
{
348
const char *func;
349
EGLint renderBuffer = EGL_BACK_BUFFER;
350
EGLint swapBehavior = EGL_BUFFER_DESTROYED;
351
EGLint err;
352
353
/* Swap behavior can be preserved only if config supports this. */
354
if (conf->SurfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
355
swapBehavior = EGL_BUFFER_PRESERVED;
356
357
switch (type) {
358
case EGL_WINDOW_BIT:
359
func = "eglCreateWindowSurface";
360
swapBehavior = EGL_BUFFER_DESTROYED;
361
break;
362
case EGL_PIXMAP_BIT:
363
func = "eglCreatePixmapSurface";
364
renderBuffer = EGL_SINGLE_BUFFER;
365
break;
366
case EGL_PBUFFER_BIT:
367
func = "eglCreatePBufferSurface";
368
break;
369
default:
370
_eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
371
return EGL_FALSE;
372
}
373
374
if ((conf->SurfaceType & type) == 0)
375
/* The config can't be used to create a surface of this type */
376
return _eglError(EGL_BAD_MATCH, func);
377
378
_eglInitResource(&surf->Resource, sizeof(*surf), disp);
379
surf->Type = type;
380
surf->Config = conf;
381
surf->Lost = EGL_FALSE;
382
383
surf->Width = 0;
384
surf->Height = 0;
385
surf->TextureFormat = EGL_NO_TEXTURE;
386
surf->TextureTarget = EGL_NO_TEXTURE;
387
surf->MipmapTexture = EGL_FALSE;
388
surf->LargestPbuffer = EGL_FALSE;
389
surf->RequestedRenderBuffer = renderBuffer;
390
surf->ActiveRenderBuffer = renderBuffer;
391
surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
392
surf->VGColorspace = EGL_VG_COLORSPACE_sRGB;
393
surf->GLColorspace = EGL_GL_COLORSPACE_LINEAR_KHR;
394
surf->ProtectedContent = EGL_FALSE;
395
396
surf->MipmapLevel = 0;
397
surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
398
surf->SwapBehavior = swapBehavior;
399
400
surf->HorizontalResolution = EGL_UNKNOWN;
401
surf->VerticalResolution = EGL_UNKNOWN;
402
surf->AspectRatio = EGL_UNKNOWN;
403
404
surf->PostSubBufferSupportedNV = EGL_FALSE;
405
surf->SetDamageRegionCalled = EGL_FALSE;
406
surf->BufferAgeRead = EGL_FALSE;
407
408
/* the default swap interval is 1 */
409
surf->SwapInterval = 1;
410
411
surf->HdrMetadata.display_primary_r.x = EGL_DONT_CARE;
412
surf->HdrMetadata.display_primary_r.y = EGL_DONT_CARE;
413
surf->HdrMetadata.display_primary_g.x = EGL_DONT_CARE;
414
surf->HdrMetadata.display_primary_g.y = EGL_DONT_CARE;
415
surf->HdrMetadata.display_primary_b.x = EGL_DONT_CARE;
416
surf->HdrMetadata.display_primary_b.y = EGL_DONT_CARE;
417
surf->HdrMetadata.white_point.x = EGL_DONT_CARE;
418
surf->HdrMetadata.white_point.y = EGL_DONT_CARE;
419
surf->HdrMetadata.max_luminance = EGL_DONT_CARE;
420
surf->HdrMetadata.min_luminance = EGL_DONT_CARE;
421
surf->HdrMetadata.max_cll = EGL_DONT_CARE;
422
surf->HdrMetadata.max_fall = EGL_DONT_CARE;
423
424
err = _eglParseSurfaceAttribList(surf, attrib_list);
425
if (err != EGL_SUCCESS)
426
return _eglError(err, func);
427
428
/* if EGL_LARGEST_PBUFFER in use, clamp width and height */
429
if (surf->LargestPbuffer) {
430
surf->Width = MIN2(surf->Width, _EGL_MAX_PBUFFER_WIDTH);
431
surf->Height = MIN2(surf->Height, _EGL_MAX_PBUFFER_HEIGHT);
432
}
433
434
surf->NativeSurface = native_surface;
435
436
return EGL_TRUE;
437
}
438
439
440
EGLBoolean
441
_eglQuerySurface(_EGLDisplay *disp, _EGLSurface *surface,
442
EGLint attribute, EGLint *value)
443
{
444
switch (attribute) {
445
case EGL_WIDTH:
446
*value = surface->Width;
447
break;
448
case EGL_HEIGHT:
449
*value = surface->Height;
450
break;
451
case EGL_CONFIG_ID:
452
*value = surface->Config->ConfigID;
453
break;
454
case EGL_LARGEST_PBUFFER:
455
if (surface->Type == EGL_PBUFFER_BIT)
456
*value = surface->LargestPbuffer;
457
break;
458
case EGL_TEXTURE_FORMAT:
459
/* texture attributes: only for pbuffers, no error otherwise */
460
if (surface->Type == EGL_PBUFFER_BIT)
461
*value = surface->TextureFormat;
462
break;
463
case EGL_TEXTURE_TARGET:
464
if (surface->Type == EGL_PBUFFER_BIT)
465
*value = surface->TextureTarget;
466
break;
467
case EGL_MIPMAP_TEXTURE:
468
if (surface->Type == EGL_PBUFFER_BIT)
469
*value = surface->MipmapTexture;
470
break;
471
case EGL_MIPMAP_LEVEL:
472
if (surface->Type == EGL_PBUFFER_BIT)
473
*value = surface->MipmapLevel;
474
break;
475
case EGL_SWAP_BEHAVIOR:
476
*value = surface->SwapBehavior;
477
break;
478
case EGL_RENDER_BUFFER:
479
/* From the EGL_KHR_mutable_render_buffer spec (v12):
480
*
481
* Querying EGL_RENDER_BUFFER returns the buffer which client API
482
* rendering is requested to use. For a window surface, this is the
483
* attribute value specified when the surface was created or last set
484
* via eglSurfaceAttrib.
485
*
486
* In other words, querying a window surface returns the value most
487
* recently *requested* by the user.
488
*
489
* The paragraph continues in the EGL 1.5 spec (2014.08.27):
490
*
491
* For a pbuffer surface, it is always EGL_BACK_BUFFER . For a pixmap
492
* surface, it is always EGL_SINGLE_BUFFER . To determine the actual
493
* buffer being rendered to by a context, call eglQueryContext.
494
*/
495
switch (surface->Type) {
496
default:
497
unreachable("bad EGLSurface type");
498
case EGL_WINDOW_BIT:
499
*value = surface->RequestedRenderBuffer;
500
break;
501
case EGL_PBUFFER_BIT:
502
*value = EGL_BACK_BUFFER;
503
break;
504
case EGL_PIXMAP_BIT:
505
*value = EGL_SINGLE_BUFFER;
506
break;
507
}
508
break;
509
case EGL_PIXEL_ASPECT_RATIO:
510
*value = surface->AspectRatio;
511
break;
512
case EGL_HORIZONTAL_RESOLUTION:
513
*value = surface->HorizontalResolution;
514
break;
515
case EGL_VERTICAL_RESOLUTION:
516
*value = surface->VerticalResolution;
517
break;
518
case EGL_MULTISAMPLE_RESOLVE:
519
*value = surface->MultisampleResolve;
520
break;
521
case EGL_VG_ALPHA_FORMAT:
522
*value = surface->VGAlphaFormat;
523
break;
524
case EGL_VG_COLORSPACE:
525
*value = surface->VGColorspace;
526
break;
527
case EGL_GL_COLORSPACE_KHR:
528
if (!disp->Extensions.KHR_gl_colorspace)
529
return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
530
531
*value = surface->GLColorspace;
532
break;
533
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
534
*value = surface->PostSubBufferSupportedNV;
535
break;
536
case EGL_BUFFER_AGE_EXT:
537
/* Both EXT_buffer_age and KHR_partial_update accept EGL_BUFFER_AGE_EXT.
538
* To be precise, the KHR one accepts EGL_BUFFER_AGE_KHR which is an
539
* alias with the same numeric value.
540
*/
541
if (!disp->Extensions.EXT_buffer_age &&
542
!disp->Extensions.KHR_partial_update)
543
return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
544
545
_EGLContext *ctx = _eglGetCurrentContext();
546
EGLint result = disp->Driver->QueryBufferAge(disp, surface);
547
/* error happened */
548
if (result < 0)
549
return EGL_FALSE;
550
if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
551
ctx->DrawSurface != surface)
552
return _eglError(EGL_BAD_SURFACE, "eglQuerySurface");
553
554
*value = result;
555
surface->BufferAgeRead = EGL_TRUE;
556
break;
557
case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
558
*value = surface->HdrMetadata.display_primary_r.x;
559
break;
560
case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
561
*value = surface->HdrMetadata.display_primary_r.y;
562
break;
563
case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
564
*value = surface->HdrMetadata.display_primary_g.x;
565
break;
566
case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
567
*value = surface->HdrMetadata.display_primary_g.y;
568
break;
569
case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
570
*value = surface->HdrMetadata.display_primary_b.x;
571
break;
572
case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
573
*value = surface->HdrMetadata.display_primary_b.y;
574
break;
575
case EGL_SMPTE2086_WHITE_POINT_X_EXT:
576
*value = surface->HdrMetadata.white_point.x;
577
break;
578
case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
579
*value = surface->HdrMetadata.white_point.y;
580
break;
581
case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
582
*value = surface->HdrMetadata.max_luminance;
583
break;
584
case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
585
*value = surface->HdrMetadata.min_luminance;
586
break;
587
case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
588
*value = surface->HdrMetadata.max_cll;
589
break;
590
case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
591
*value = surface->HdrMetadata.max_fall;
592
break;
593
case EGL_PROTECTED_CONTENT_EXT:
594
if (!disp->Extensions.EXT_protected_surface)
595
return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
596
*value = surface->ProtectedContent;
597
break;
598
default:
599
return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
600
}
601
602
return EGL_TRUE;
603
}
604
605
606
/**
607
* Default fallback routine - drivers might override this.
608
*/
609
EGLBoolean
610
_eglSurfaceAttrib(_EGLDisplay *disp, _EGLSurface *surface,
611
EGLint attribute, EGLint value)
612
{
613
EGLint confval;
614
EGLint err = EGL_SUCCESS;
615
EGLint all_es_bits = EGL_OPENGL_ES_BIT |
616
EGL_OPENGL_ES2_BIT |
617
EGL_OPENGL_ES3_BIT_KHR;
618
619
switch (attribute) {
620
case EGL_MIPMAP_LEVEL:
621
confval = surface->Config->RenderableType;
622
if (!(confval & all_es_bits)) {
623
err = EGL_BAD_PARAMETER;
624
break;
625
}
626
surface->MipmapLevel = value;
627
break;
628
case EGL_MULTISAMPLE_RESOLVE:
629
switch (value) {
630
case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
631
break;
632
case EGL_MULTISAMPLE_RESOLVE_BOX:
633
confval = surface->Config->SurfaceType;
634
if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT))
635
err = EGL_BAD_MATCH;
636
break;
637
default:
638
err = EGL_BAD_ATTRIBUTE;
639
break;
640
}
641
if (err != EGL_SUCCESS)
642
break;
643
surface->MultisampleResolve = value;
644
break;
645
case EGL_RENDER_BUFFER:
646
if (!disp->Extensions.KHR_mutable_render_buffer) {
647
err = EGL_BAD_ATTRIBUTE;
648
break;
649
}
650
651
if (value != EGL_BACK_BUFFER && value != EGL_SINGLE_BUFFER) {
652
err = EGL_BAD_PARAMETER;
653
break;
654
}
655
656
/* From the EGL_KHR_mutable_render_buffer spec (v12):
657
*
658
* If attribute is EGL_RENDER_BUFFER, and the EGL_SURFACE_TYPE
659
* attribute of the EGLConfig used to create surface does not contain
660
* EGL_MUTABLE_RENDER_BUFFER_BIT_KHR, [...] an EGL_BAD_MATCH error is
661
* generated [...].
662
*/
663
if (!(surface->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR)) {
664
err = EGL_BAD_MATCH;
665
break;
666
}
667
668
surface->RequestedRenderBuffer = value;
669
break;
670
case EGL_SWAP_BEHAVIOR:
671
switch (value) {
672
case EGL_BUFFER_DESTROYED:
673
break;
674
case EGL_BUFFER_PRESERVED:
675
confval = surface->Config->SurfaceType;
676
if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
677
err = EGL_BAD_MATCH;
678
break;
679
default:
680
err = EGL_BAD_ATTRIBUTE;
681
break;
682
}
683
if (err != EGL_SUCCESS)
684
break;
685
surface->SwapBehavior = value;
686
break;
687
case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
688
surface->HdrMetadata.display_primary_r.x = value;
689
break;
690
case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
691
surface->HdrMetadata.display_primary_r.y = value;
692
break;
693
case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
694
surface->HdrMetadata.display_primary_g.x = value;
695
break;
696
case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
697
surface->HdrMetadata.display_primary_g.y = value;
698
break;
699
case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
700
surface->HdrMetadata.display_primary_b.x = value;
701
break;
702
case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
703
surface->HdrMetadata.display_primary_b.y = value;
704
break;
705
case EGL_SMPTE2086_WHITE_POINT_X_EXT:
706
surface->HdrMetadata.white_point.x = value;
707
break;
708
case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
709
surface->HdrMetadata.white_point.y = value;
710
break;
711
case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
712
surface->HdrMetadata.max_luminance = value;
713
break;
714
case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
715
surface->HdrMetadata.min_luminance = value;
716
break;
717
case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
718
surface->HdrMetadata.max_cll = value;
719
break;
720
case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
721
surface->HdrMetadata.max_fall = value;
722
break;
723
default:
724
err = EGL_BAD_ATTRIBUTE;
725
break;
726
}
727
728
if (err != EGL_SUCCESS)
729
return _eglError(err, "eglSurfaceAttrib");
730
return EGL_TRUE;
731
}
732
733
734
EGLBoolean
735
_eglBindTexImage(_EGLDisplay *disp, _EGLSurface *surface, EGLint buffer)
736
{
737
EGLint texture_type = EGL_PBUFFER_BIT;
738
739
/* Just do basic error checking and return success/fail.
740
* Drivers must implement the real stuff.
741
*/
742
743
if (disp->Extensions.NOK_texture_from_pixmap)
744
texture_type |= EGL_PIXMAP_BIT;
745
746
if (!(surface->Type & texture_type))
747
return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
748
749
if (surface->TextureFormat == EGL_NO_TEXTURE)
750
return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
751
752
if (surface->TextureTarget == EGL_NO_TEXTURE)
753
return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
754
755
if (buffer != EGL_BACK_BUFFER)
756
return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
757
758
surface->BoundToTexture = EGL_TRUE;
759
760
return EGL_TRUE;
761
}
762
763
EGLBoolean
764
_eglReleaseTexImage(_EGLDisplay *disp, _EGLSurface *surf, EGLint buffer)
765
{
766
/* Just do basic error checking and return success/fail.
767
* Drivers must implement the real stuff.
768
*/
769
770
EGLint texture_type = EGL_PBUFFER_BIT;
771
772
if (surf == EGL_NO_SURFACE)
773
return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
774
775
if (!surf->BoundToTexture)
776
{
777
/* Not an error, simply nothing to do */
778
return EGL_TRUE;
779
}
780
781
if (surf->TextureFormat == EGL_NO_TEXTURE)
782
return _eglError(EGL_BAD_MATCH, "eglReleaseTexImage");
783
784
if (buffer != EGL_BACK_BUFFER)
785
return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
786
787
if (disp->Extensions.NOK_texture_from_pixmap)
788
texture_type |= EGL_PIXMAP_BIT;
789
790
if (!(surf->Type & texture_type))
791
return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
792
793
surf->BoundToTexture = EGL_FALSE;
794
795
return EGL_TRUE;
796
}
797
798
EGLBoolean
799
_eglSurfaceHasMutableRenderBuffer(_EGLSurface *surf)
800
{
801
return surf->Type == EGL_WINDOW_BIT &&
802
surf->Config &&
803
(surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR);
804
}
805
806
EGLBoolean
807
_eglSurfaceInSharedBufferMode(_EGLSurface *surf)
808
{
809
return _eglSurfaceHasMutableRenderBuffer(surf) &&
810
surf->ActiveRenderBuffer == EGL_SINGLE_BUFFER;
811
}
812
813