blob: 8202c4eaaecf1612297113c1b59d5834498daeaf [file] [log] [blame]
Cody Northrop68d10352018-10-15 07:22:09 -06001/*
2 ** Copyright 2018, The Android Open Source Project
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16
17#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18
19#include <EGL/egl.h>
20#include <EGL/eglext.h>
21
22#include "../egl_impl.h"
23
24#include "egl_layers.h"
25#include "egl_platform_entries.h"
26#include "egl_tls.h"
27#include "egl_trace.h"
28
29using namespace android;
30
31namespace android {
32
33extern EGLBoolean egl_init_drivers();
34
35} // namespace android
36
37static inline void clearError() {
38 egl_tls_t::clearError();
39}
40
41EGLDisplay eglGetDisplay(EGLNativeDisplayType display) {
42 ATRACE_CALL();
43 clearError();
44
45 if (egl_init_drivers() == EGL_FALSE) {
46 return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
47 }
48
49 // Call down the chain, which usually points directly to the impl
50 // but may also be routed through layers
51 egl_connection_t* const cnx = &gEGLImpl;
52 return cnx->platform.eglGetDisplay(display);
53}
54
55EGLBoolean eglInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) {
56 clearError();
57
58 egl_connection_t* const cnx = &gEGLImpl;
59 return cnx->platform.eglInitialize(dpy, major, minor);
60}
61
62EGLBoolean eglTerminate(EGLDisplay dpy) {
63 clearError();
64
65 egl_connection_t* const cnx = &gEGLImpl;
66 return cnx->platform.eglTerminate(dpy);
67}
68
69EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size,
70 EGLint* num_config) {
71 clearError();
72
73 egl_connection_t* const cnx = &gEGLImpl;
74 return cnx->platform.eglGetConfigs(dpy, configs, config_size, num_config);
75}
76
77EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs,
78 EGLint config_size, EGLint* num_config) {
79 clearError();
80
81 egl_connection_t* const cnx = &gEGLImpl;
82 return cnx->platform.eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);
83}
84
85EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value) {
86 clearError();
87
88 egl_connection_t* const cnx = &gEGLImpl;
89 return cnx->platform.eglGetConfigAttrib(dpy, config, attribute, value);
90}
91
92EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window,
93 const EGLint* attrib_list) {
94 clearError();
95
96 egl_connection_t* const cnx = &gEGLImpl;
97 return cnx->platform.eglCreateWindowSurface(dpy, config, window, attrib_list);
98}
99
100EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap,
101 const EGLint* attrib_list) {
102 clearError();
103
104 egl_connection_t* const cnx = &gEGLImpl;
105 return cnx->platform.eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);
106}
107
108EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list) {
109 clearError();
110
111 egl_connection_t* const cnx = &gEGLImpl;
112 return cnx->platform.eglCreatePbufferSurface(dpy, config, attrib_list);
113}
114
115EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) {
116 clearError();
117
118 egl_connection_t* const cnx = &gEGLImpl;
119 return cnx->platform.eglDestroySurface(dpy, surface);
120}
121
122EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value) {
123 clearError();
124
125 egl_connection_t* const cnx = &gEGLImpl;
126 return cnx->platform.eglQuerySurface(dpy, surface, attribute, value);
127}
128
129void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
130 ATRACE_CALL();
131 clearError();
132
133 egl_connection_t* const cnx = &gEGLImpl;
134 cnx->platform.eglBeginFrame(dpy, surface);
135}
136
137EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
138 const EGLint* attrib_list) {
139 clearError();
140
141 egl_connection_t* const cnx = &gEGLImpl;
142 return cnx->platform.eglCreateContext(dpy, config, share_list, attrib_list);
143}
144
145EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) {
146 clearError();
147
148 egl_connection_t* const cnx = &gEGLImpl;
149 return cnx->platform.eglDestroyContext(dpy, ctx);
150}
151
152EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) {
153 clearError();
154
155 egl_connection_t* const cnx = &gEGLImpl;
156 return cnx->platform.eglMakeCurrent(dpy, draw, read, ctx);
157}
158
159EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value) {
160 clearError();
161
162 egl_connection_t* const cnx = &gEGLImpl;
163 return cnx->platform.eglQueryContext(dpy, ctx, attribute, value);
164}
165
166EGLContext eglGetCurrentContext(void) {
167 clearError();
168
169 egl_connection_t* const cnx = &gEGLImpl;
170 return cnx->platform.eglGetCurrentContext();
171}
172
173EGLSurface eglGetCurrentSurface(EGLint readdraw) {
174 clearError();
175
176 egl_connection_t* const cnx = &gEGLImpl;
177 return cnx->platform.eglGetCurrentSurface(readdraw);
178}
179
180EGLDisplay eglGetCurrentDisplay(void) {
181 clearError();
182
183 egl_connection_t* const cnx = &gEGLImpl;
184 return cnx->platform.eglGetCurrentDisplay();
185}
186
187EGLBoolean eglWaitGL(void) {
188 clearError();
189
190 egl_connection_t* const cnx = &gEGLImpl;
191 return cnx->platform.eglWaitGL();
192}
193
194EGLBoolean eglWaitNative(EGLint engine) {
195 clearError();
196
197 egl_connection_t* const cnx = &gEGLImpl;
198 return cnx->platform.eglWaitNative(engine);
199}
200
201EGLint eglGetError(void) {
202 egl_connection_t* const cnx = &gEGLImpl;
203 if (cnx->platform.eglGetError) {
204 return cnx->platform.eglGetError();
205 } else {
206 return egl_tls_t::getError();
207 }
208}
209
210__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char* procname) {
211 // eglGetProcAddress() could be the very first function called
212 // in which case we must make sure we've initialized ourselves, this
213 // happens the first time egl_get_display() is called.
214
215 clearError();
216
217 if (egl_init_drivers() == EGL_FALSE) {
218 setError(EGL_BAD_PARAMETER, NULL);
219 return nullptr;
220 }
221
222 egl_connection_t* const cnx = &gEGLImpl;
223 return cnx->platform.eglGetProcAddress(procname);
224}
225
226EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw, EGLint* rects,
227 EGLint n_rects) {
228 ATRACE_CALL();
229 clearError();
230
231 egl_connection_t* const cnx = &gEGLImpl;
232 return cnx->platform.eglSwapBuffersWithDamageKHR(dpy, draw, rects, n_rects);
233}
234
235EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
236 ATRACE_CALL();
237 clearError();
238
239 egl_connection_t* const cnx = &gEGLImpl;
240 return cnx->platform.eglSwapBuffers(dpy, surface);
241}
242
243EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target) {
244 clearError();
245
246 egl_connection_t* const cnx = &gEGLImpl;
247 return cnx->platform.eglCopyBuffers(dpy, surface, target);
248}
249
250const char* eglQueryString(EGLDisplay dpy, EGLint name) {
251 clearError();
252
253 egl_connection_t* const cnx = &gEGLImpl;
254 return cnx->platform.eglQueryString(dpy, name);
255}
256
257extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name) {
258 clearError();
259
260 egl_connection_t* const cnx = &gEGLImpl;
261 return cnx->platform.eglQueryStringImplementationANDROID(dpy, name);
262}
263
264EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) {
265 clearError();
266
267 egl_connection_t* const cnx = &gEGLImpl;
268 return cnx->platform.eglSurfaceAttrib(dpy, surface, attribute, value);
269}
270
271EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
272 clearError();
273
274 egl_connection_t* const cnx = &gEGLImpl;
275 return cnx->platform.eglBindTexImage(dpy, surface, buffer);
276}
277
278EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) {
279 clearError();
280
281 egl_connection_t* const cnx = &gEGLImpl;
282 return cnx->platform.eglReleaseTexImage(dpy, surface, buffer);
283}
284
285EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) {
286 clearError();
287
288 egl_connection_t* const cnx = &gEGLImpl;
289 return cnx->platform.eglSwapInterval(dpy, interval);
290}
291
292EGLBoolean eglWaitClient(void) {
293 clearError();
294
295 egl_connection_t* const cnx = &gEGLImpl;
296 return cnx->platform.eglWaitClient();
297}
298
299EGLBoolean eglBindAPI(EGLenum api) {
300 clearError();
301
302 if (egl_init_drivers() == EGL_FALSE) {
303 return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
304 }
305
306 egl_connection_t* const cnx = &gEGLImpl;
307 return cnx->platform.eglBindAPI(api);
308}
309
310EGLenum eglQueryAPI(void) {
311 clearError();
312
313 if (egl_init_drivers() == EGL_FALSE) {
314 return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
315 }
316
317 egl_connection_t* const cnx = &gEGLImpl;
318 return cnx->platform.eglQueryAPI();
319}
320
321EGLBoolean eglReleaseThread(void) {
322 clearError();
323
324 egl_connection_t* const cnx = &gEGLImpl;
325 return cnx->platform.eglReleaseThread();
326}
327
328EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
329 EGLConfig config, const EGLint* attrib_list) {
330 clearError();
331
332 egl_connection_t* const cnx = &gEGLImpl;
333 return cnx->platform.eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config,
334 attrib_list);
335}
336
337EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface, const EGLint* attrib_list) {
338 clearError();
339
340 egl_connection_t* const cnx = &gEGLImpl;
341 return cnx->platform.eglLockSurfaceKHR(dpy, surface, attrib_list);
342}
343
344EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface) {
345 clearError();
346
347 egl_connection_t* const cnx = &gEGLImpl;
348 return cnx->platform.eglUnlockSurfaceKHR(dpy, surface);
349}
350
351EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
352 EGLClientBuffer buffer, const EGLint* attrib_list) {
353 clearError();
354
355 egl_connection_t* const cnx = &gEGLImpl;
356 return cnx->platform.eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
357}
358
359EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) {
360 clearError();
361
362 egl_connection_t* const cnx = &gEGLImpl;
363 return cnx->platform.eglDestroyImageKHR(dpy, img);
364}
365
366EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list) {
367 clearError();
368
369 egl_connection_t* const cnx = &gEGLImpl;
370 return cnx->platform.eglCreateSyncKHR(dpy, type, attrib_list);
371}
372
373EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) {
374 clearError();
375
376 egl_connection_t* const cnx = &gEGLImpl;
377 return cnx->platform.eglDestroySyncKHR(dpy, sync);
378}
379
380EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) {
381 clearError();
382
383 egl_connection_t* const cnx = &gEGLImpl;
384 return cnx->platform.eglSignalSyncKHR(dpy, sync, mode);
385}
386
387EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) {
388 clearError();
389
390 egl_connection_t* const cnx = &gEGLImpl;
391 return cnx->platform.eglClientWaitSyncKHR(dpy, sync, flags, timeout);
392}
393
394EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint* value) {
395 clearError();
396
397 egl_connection_t* const cnx = &gEGLImpl;
398 return cnx->platform.eglGetSyncAttribKHR(dpy, sync, attribute, value);
399}
400
401EGLStreamKHR eglCreateStreamKHR(EGLDisplay dpy, const EGLint* attrib_list) {
402 clearError();
403
404 egl_connection_t* const cnx = &gEGLImpl;
405 return cnx->platform.eglCreateStreamKHR(dpy, attrib_list);
406}
407
408EGLBoolean eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream) {
409 clearError();
410
411 egl_connection_t* const cnx = &gEGLImpl;
412 return cnx->platform.eglDestroyStreamKHR(dpy, stream);
413}
414
415EGLBoolean eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute,
416 EGLint value) {
417 clearError();
418
419 egl_connection_t* const cnx = &gEGLImpl;
420 return cnx->platform.eglStreamAttribKHR(dpy, stream, attribute, value);
421}
422
423EGLBoolean eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute,
424 EGLint* value) {
425 clearError();
426
427 egl_connection_t* const cnx = &gEGLImpl;
428 return cnx->platform.eglQueryStreamKHR(dpy, stream, attribute, value);
429}
430
431EGLBoolean eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute,
432 EGLuint64KHR* value) {
433 clearError();
434
435 egl_connection_t* const cnx = &gEGLImpl;
436 return cnx->platform.eglQueryStreamu64KHR(dpy, stream, attribute, value);
437}
438
439EGLBoolean eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute,
440 EGLTimeKHR* value) {
441 clearError();
442
443 egl_connection_t* const cnx = &gEGLImpl;
444 return cnx->platform.eglQueryStreamTimeKHR(dpy, stream, attribute, value);
445}
446
447EGLSurface eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream,
448 const EGLint* attrib_list) {
449 clearError();
450
451 egl_connection_t* const cnx = &gEGLImpl;
452 return cnx->platform.eglCreateStreamProducerSurfaceKHR(dpy, config, stream, attrib_list);
453}
454
455EGLBoolean eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream) {
456 clearError();
457
458 egl_connection_t* const cnx = &gEGLImpl;
459 return cnx->platform.eglStreamConsumerGLTextureExternalKHR(dpy, stream);
460}
461
462EGLBoolean eglStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream) {
463 clearError();
464
465 egl_connection_t* const cnx = &gEGLImpl;
466 return cnx->platform.eglStreamConsumerAcquireKHR(dpy, stream);
467}
468
469EGLBoolean eglStreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream) {
470 clearError();
471
472 egl_connection_t* const cnx = &gEGLImpl;
473 return cnx->platform.eglStreamConsumerReleaseKHR(dpy, stream);
474}
475
476EGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHR(EGLDisplay dpy, EGLStreamKHR stream) {
477 clearError();
478
479 egl_connection_t* const cnx = &gEGLImpl;
480 return cnx->platform.eglGetStreamFileDescriptorKHR(dpy, stream);
481}
482
483EGLStreamKHR eglCreateStreamFromFileDescriptorKHR(EGLDisplay dpy,
484 EGLNativeFileDescriptorKHR file_descriptor) {
485 clearError();
486
487 egl_connection_t* const cnx = &gEGLImpl;
488 return cnx->platform.eglCreateStreamFromFileDescriptorKHR(dpy, file_descriptor);
489}
490
491EGLint eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) {
492 clearError();
493 egl_connection_t* const cnx = &gEGLImpl;
494 return cnx->platform.eglWaitSyncKHR(dpy, sync, flags);
495}
496
497EGLint eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync) {
498 clearError();
499
500 egl_connection_t* const cnx = &gEGLImpl;
501 return cnx->platform.eglDupNativeFenceFDANDROID(dpy, sync);
502}
503
504EGLBoolean eglPresentationTimeANDROID(EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time) {
505 clearError();
506
507 egl_connection_t* const cnx = &gEGLImpl;
508 return cnx->platform.eglPresentationTimeANDROID(dpy, surface, time);
509}
510
511EGLClientBuffer eglGetNativeClientBufferANDROID(const AHardwareBuffer* buffer) {
512 clearError();
513 egl_connection_t* const cnx = &gEGLImpl;
514 return cnx->platform.eglGetNativeClientBufferANDROID(buffer);
515}
516
517EGLuint64NV eglGetSystemTimeFrequencyNV() {
518 clearError();
519
520 if (egl_init_drivers() == EGL_FALSE) {
521 return setError(EGL_BAD_PARAMETER, (EGLuint64NV)EGL_FALSE);
522 }
523
524 egl_connection_t* const cnx = &gEGLImpl;
525 return cnx->platform.eglGetSystemTimeFrequencyNV();
526}
527
528EGLuint64NV eglGetSystemTimeNV() {
529 clearError();
530
531 if (egl_init_drivers() == EGL_FALSE) {
532 return setError(EGL_BAD_PARAMETER, (EGLuint64NV)EGL_FALSE);
533 }
534
535 egl_connection_t* const cnx = &gEGLImpl;
536 return cnx->platform.eglGetSystemTimeNV();
537}
538
539EGLBoolean eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface, EGLint* rects,
540 EGLint n_rects) {
541 clearError();
542
543 egl_connection_t* const cnx = &gEGLImpl;
544 return cnx->platform.eglSetDamageRegionKHR(dpy, surface, rects, n_rects);
545}
546
547EGLBoolean eglGetNextFrameIdANDROID(EGLDisplay dpy, EGLSurface surface, EGLuint64KHR* frameId) {
548 clearError();
549
550 egl_connection_t* const cnx = &gEGLImpl;
551 return cnx->platform.eglGetNextFrameIdANDROID(dpy, surface, frameId);
552}
553
554EGLBoolean eglGetCompositorTimingANDROID(EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps,
555 const EGLint* names, EGLnsecsANDROID* values) {
556 clearError();
557
558 egl_connection_t* const cnx = &gEGLImpl;
559 return cnx->platform.eglGetCompositorTimingANDROID(dpy, surface, numTimestamps, names, values);
560}
561
562EGLBoolean eglGetCompositorTimingSupportedANDROID(EGLDisplay dpy, EGLSurface surface, EGLint name) {
563 clearError();
564
565 egl_connection_t* const cnx = &gEGLImpl;
566 return cnx->platform.eglGetCompositorTimingSupportedANDROID(dpy, surface, name);
567}
568
569EGLBoolean eglGetFrameTimestampsANDROID(EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId,
570 EGLint numTimestamps, const EGLint* timestamps,
571 EGLnsecsANDROID* values) {
572 clearError();
573
574 egl_connection_t* const cnx = &gEGLImpl;
575 return cnx->platform.eglGetFrameTimestampsANDROID(dpy, surface, frameId, numTimestamps,
576 timestamps, values);
577}
578
579EGLBoolean eglGetFrameTimestampSupportedANDROID(EGLDisplay dpy, EGLSurface surface,
580 EGLint timestamp) {
581 clearError();
582
583 egl_connection_t* const cnx = &gEGLImpl;
584 return cnx->platform.eglGetFrameTimestampSupportedANDROID(dpy, surface, timestamp);
585}