eglApi.cpp revision ada798b7ca7cabc255aa159964b64975e7fdb2df
1518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian/*
2518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** Copyright 2007, The Android Open Source Project
3518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
4518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** Licensed under the Apache License, Version 2.0 (the "License");
5518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** you may not use this file except in compliance with the License.
6518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** You may obtain a copy of the License at
7518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
8518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **     http://www.apache.org/licenses/LICENSE-2.0
9518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
10518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** Unless required by applicable law or agreed to in writing, software
11518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** distributed under the License is distributed on an "AS IS" BASIS,
12518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** See the License for the specific language governing permissions and
14518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** limitations under the License.
15518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */
16518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
17518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <ctype.h>
18518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <stdlib.h>
19518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <string.h>
20518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
21518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <hardware/gralloc.h>
22518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <system/window.h>
23518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
24518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <EGL/egl.h>
25518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <EGL/eglext.h>
26518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <GLES/gl.h>
27518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <GLES/glext.h>
28518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
29518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <cutils/log.h>
30518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <cutils/atomic.h>
31518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <cutils/properties.h>
32518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <cutils/memory.h>
33518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
34518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <utils/KeyedVector.h>
35518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <utils/SortedVector.h>
36518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include <utils/String8.h>
37518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
38518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_impl.h"
39518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_tls.h"
400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "glestrace.h"
41518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "hooks.h"
42518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
43518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_display.h"
44518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_impl.h"
45518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_object.h"
46518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_tls.h"
47ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian#include "egldefs.h"
48518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
49518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianusing namespace android;
50518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
51518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
52518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
53bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian#define EGL_VERSION_HW_ANDROID  0x3143
54bc2d79ed7ada6243f3690f94ab512c0ddcdbed12Mathias Agopian
55518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstruct extention_map_t {
56518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    const char* name;
57518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    __eglMustCastToProperFunctionPointerType address;
58518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian};
59518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
60518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic const extention_map_t sExtentionMap[] = {
61518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    { "eglLockSurfaceKHR",
62518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR },
63518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    { "eglUnlockSurfaceKHR",
64518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR },
65518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    { "eglCreateImageKHR",
66518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR },
67518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    { "eglDestroyImageKHR",
68518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR },
691c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    { "eglGetSystemTimeFrequencyNV",
701c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang            (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeFrequencyNV },
711c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    { "eglGetSystemTimeNV",
721c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang            (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeNV },
73518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian};
74518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
75518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// accesses protected by sExtensionMapMutex
76518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic DefaultKeyedVector<String8, __eglMustCastToProperFunctionPointerType> sGLExtentionMap;
77518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic int sGLExtentionSlot = 0;
78518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic pthread_mutex_t sExtensionMapMutex = PTHREAD_MUTEX_INITIALIZER;
79518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
80518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic void(*findProcAddress(const char* name,
81518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        const extention_map_t* map, size_t n))() {
82518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    for (uint32_t i=0 ; i<n ; i++) {
83518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!strcmp(name, map[i].name)) {
84518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return map[i].address;
85518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
86518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
87518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return NULL;
88518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
89518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
90518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
91518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
92518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiantemplate<typename T>
93518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic __attribute__((noinline))
94518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianint binarySearch(T const sortedArray[], int first, int last, T key) {
95518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    while (first <= last) {
96518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        int mid = (first + last) / 2;
97518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (sortedArray[mid] < key) {
98518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            first = mid + 1;
99518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        } else if (key < sortedArray[mid]) {
100518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            last = mid - 1;
101518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        } else {
102518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return mid;
103518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return -1;
106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
108518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
109518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
110518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiannamespace android {
111518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern void setGLHooksThreadSpecific(gl_hooks_t const *value);
112518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern EGLBoolean egl_init_drivers();
113518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern int gEGLDebugLevel;
115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern gl_hooks_t gHooksTrace;
116518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian} // namespace android;
117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
119518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
120518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic inline void clearError() { egl_tls_t::clearError(); }
121518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic inline EGLContext getContext() { return egl_tls_t::getContext(); }
122518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
123518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
124518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
125518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay eglGetDisplay(EGLNativeDisplayType display)
126518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
127518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
128518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
129518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    uint32_t index = uint32_t(display);
130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (index >= NUM_DISPLAYS) {
131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
132518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
133518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
134518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (egl_init_drivers() == EGL_FALSE) {
135518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
136518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
137518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
138518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display);
139518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return dpy;
140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
142518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// Initialization
144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
146518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
147518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
148518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
149518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
150518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t * const dp = get_display(dpy);
151518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
152518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
153518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = dp->initialize(major, minor);
154518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
155518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
156518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
157518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
158518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglTerminate(EGLDisplay dpy)
159518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
160518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // NOTE: don't unload the drivers b/c some APIs can be called
161518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // after eglTerminate() has been called. eglTerminate() only
162518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // terminates an EGLDisplay, not a EGL itself.
163518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
164518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
165518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
166518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t* const dp = get_display(dpy);
167518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
168518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
169518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = dp->terminate();
170518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
171518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
172518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
173518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
174518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
175518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// configuration
176518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
177518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
178518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglGetConfigs(   EGLDisplay dpy,
179518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLConfig *configs,
180518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLint config_size, EGLint *num_config)
181518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
182518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
183518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
184518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
185518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
186518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
187518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    GLint numConfigs = dp->numTotalConfigs;
188518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!configs) {
189518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        *num_config = numConfigs;
190518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_TRUE;
191518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
192518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
193518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    GLint n = 0;
194518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    for (intptr_t i=0 ; i<dp->numTotalConfigs && config_size ; i++) {
195518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        *configs++ = EGLConfig(i);
196518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        config_size--;
197518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        n++;
198518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
199518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
200518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    *num_config = n;
201518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_TRUE;
202518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
203518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
204518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
205518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLConfig *configs, EGLint config_size,
206518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLint *num_config)
207518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
208518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
209518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
210518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
211518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
212518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
213518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (num_config==0) {
214518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
215518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
216518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
217518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLint n;
218518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_FALSE;
219518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    *num_config = 0;
220518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
221518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
222518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // It is unfortunate, but we need to remap the EGL_CONFIG_IDs,
223518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // to do this, we have to go through the attrib_list array once
224518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // to figure out both its size and if it contains an EGL_CONFIG_ID
225518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // key. If so, the full array is copied and patched.
226518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // NOTE: we assume that there can be only one occurrence
227518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // of EGL_CONFIG_ID.
228518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
229518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLint patch_index = -1;
230518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    GLint attr;
231518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    size_t size = 0;
232518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (attrib_list) {
233518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        while ((attr=attrib_list[size]) != EGL_NONE) {
234518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (attr == EGL_CONFIG_ID)
235518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                patch_index = size;
236518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            size += 2;
237518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
238518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
239518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (patch_index >= 0) {
240518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        size += 2; // we need copy the sentinel as well
241518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLint* new_list = (EGLint*)malloc(size*sizeof(EGLint));
242518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (new_list == 0)
243518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return setError(EGL_BAD_ALLOC, EGL_FALSE);
244518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        memcpy(new_list, attrib_list, size*sizeof(EGLint));
245518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
246518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // patch the requested EGL_CONFIG_ID
247518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        bool found = false;
248518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLConfig ourConfig(0);
249518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLint& configId(new_list[patch_index+1]);
250518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        for (intptr_t i=0 ; i<dp->numTotalConfigs ; i++) {
251518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (dp->configs[i].configId == configId) {
252518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                ourConfig = EGLConfig(i);
253518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                configId = dp->configs[i].implConfigId;
254518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                found = true;
255518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                break;
256518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
257518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
258518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
259ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        egl_connection_t* const cnx = &gEGLImpl;
260518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (found && cnx->dso) {
261518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // and switch to the new list
262518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            attrib_list = const_cast<const EGLint *>(new_list);
263518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
264518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // At this point, the only configuration that can match is
265518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // dp->configs[i][index], however, we don't know if it would be
266518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // rejected because of the other attributes, so we do have to call
267518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // cnx->egl.eglChooseConfig() -- but we don't have to loop
268518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // through all the EGLimpl[].
269518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // We also know we can only get a single config back, and we know
270518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // which one.
271518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
272518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            res = cnx->egl.eglChooseConfig(
273ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    dp->disp.dpy,
274518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    attrib_list, configs, config_size, &n);
275518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (res && n>0) {
276518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                // n has to be 0 or 1, by construction, and we already know
277518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                // which config it will return (since there can be only one).
278518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                if (configs) {
279518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    configs[0] = ourConfig;
280518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                }
281518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                *num_config = 1;
282518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
283518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
284518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
285518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        free(const_cast<EGLint *>(attrib_list));
286518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return res;
287518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
288518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
289518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
290ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
291ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso) {
292ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        if (cnx->egl.eglChooseConfig(
293ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, attrib_list, configs, config_size, &n)) {
294ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            if (configs) {
295ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                // now we need to convert these client EGLConfig to our
296ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                // internal EGLConfig format.
297ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                // This is done in O(n Log(n)) time.
298ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                for (int j=0 ; j<n ; j++) {
299ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    egl_config_t key(configs[j]);
300ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    intptr_t index = binarySearch<egl_config_t>(
301ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                            dp->configs, 0, dp->numTotalConfigs, key);
302ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    if (index >= 0) {
303ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                        configs[j] = EGLConfig(index);
304ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    } else {
305ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                        return setError(EGL_BAD_CONFIG, EGL_FALSE);
306518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    }
307518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                }
308ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                configs += n;
309ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                config_size -= n;
310518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
311ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            *num_config += n;
312ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            res = EGL_TRUE;
313518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
314518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
315ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
316518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
317518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
318518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
319518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
320518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLint attribute, EGLint *value)
321518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
322518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
323518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
324518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const* dp = 0;
325518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
326518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!cnx) return EGL_FALSE;
327518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
328518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (attribute == EGL_CONFIG_ID) {
329518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        *value = dp->configs[intptr_t(config)].configId;
330518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_TRUE;
331518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
332518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return cnx->egl.eglGetConfigAttrib(
333ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            dp->disp.dpy,
334518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            dp->configs[intptr_t(config)].config, attribute, value);
335518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
336518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
337518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
338518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// surfaces
339518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
340518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
341518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
342518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    NativeWindowType window,
343518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    const EGLint *attrib_list)
344518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
345518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
346518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
347518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const* dp = 0;
348518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
349518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (cnx) {
350ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        EGLDisplay iDpy = dp->disp.dpy;
351518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLConfig iConfig = dp->configs[intptr_t(config)].config;
352518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLint format;
353518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
35481a63350527cafce6929309533c58586878f10b5Mathias Agopian        if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != OK) {
355e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("EGLNativeWindowType %p already connected to another API",
35681a63350527cafce6929309533c58586878f10b5Mathias Agopian                    window);
35781a63350527cafce6929309533c58586878f10b5Mathias Agopian            return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
35881a63350527cafce6929309533c58586878f10b5Mathias Agopian        }
35981a63350527cafce6929309533c58586878f10b5Mathias Agopian
360518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // set the native window's buffers format to match this config
361518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cnx->egl.eglGetConfigAttrib(iDpy,
362518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                iConfig, EGL_NATIVE_VISUAL_ID, &format)) {
363518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (format != 0) {
364bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis                int err = native_window_set_buffers_format(window, format);
365bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis                if (err != 0) {
366e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block                    ALOGE("error setting native window pixel format: %s (%d)",
367bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis                            strerror(-err), err);
36881a63350527cafce6929309533c58586878f10b5Mathias Agopian                    native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
369bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis                    return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
370bee205fd58a27c10a0895de5339e76025d429d2bJamie Gennis                }
371518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
372518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
373518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
37459769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        // the EGL spec requires that a new EGLSurface default to swap interval
37559769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        // 1, so explicitly set that on the window here.
37659769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        ANativeWindow* anw = reinterpret_cast<ANativeWindow*>(window);
37759769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis        anw->setSwapInterval(anw, 1);
37859769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis
379518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLSurface surface = cnx->egl.eglCreateWindowSurface(
380518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                iDpy, iConfig, window, attrib_list);
381518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (surface != EGL_NO_SURFACE) {
382ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            egl_surface_t* s = new egl_surface_t(dpy, config, window, surface, cnx);
383518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return s;
384518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
38581a63350527cafce6929309533c58586878f10b5Mathias Agopian
38681a63350527cafce6929309533c58586878f10b5Mathias Agopian        // EGLSurface creation failed
38781a63350527cafce6929309533c58586878f10b5Mathias Agopian        native_window_set_buffers_format(window, 0);
38881a63350527cafce6929309533c58586878f10b5Mathias Agopian        native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
389518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
390518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_SURFACE;
391518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
392518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
393518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
394518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    NativePixmapType pixmap,
395518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    const EGLint *attrib_list)
396518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
397518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
398518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
399518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const* dp = 0;
400518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
401518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (cnx) {
402518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
403ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy,
404518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                dp->configs[intptr_t(config)].config, pixmap, attrib_list);
405518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (surface != EGL_NO_SURFACE) {
406ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface, cnx);
407518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return s;
408518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
409518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
410518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_SURFACE;
411518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
412518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
413518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
414518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                                    const EGLint *attrib_list)
415518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
416518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
417518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
418518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const* dp = 0;
419518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
420518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (cnx) {
421518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
422ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy,
423518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                dp->configs[intptr_t(config)].config, attrib_list);
424518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (surface != EGL_NO_SURFACE) {
425ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface, cnx);
426518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return s;
427518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
428518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
429518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_SURFACE;
430518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
431518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
432518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
433518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
434518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
435518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
436518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
437518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
438518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
439f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SurfaceRef _s(dp, surface);
4405b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
4415b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_SURFACE, EGL_FALSE);
442518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
443518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t * const s = get_surface(surface);
444ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
445518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (result == EGL_TRUE) {
446518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        _s.terminate();
447518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
448518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
449518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
450518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
451518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
452518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLint attribute, EGLint *value)
453518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
454518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
455518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
456518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
457518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
458518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
459f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SurfaceRef _s(dp, surface);
4605b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
4615b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_SURFACE, EGL_FALSE);
462518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
463518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
464518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean result(EGL_TRUE);
465518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (attribute == EGL_CONFIG_ID) {
466518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // We need to remap EGL_CONFIG_IDs
467518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        *value = dp->configs[intptr_t(s->config)].configId;
468518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    } else {
469518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        result = s->cnx->egl.eglQuerySurface(
470ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, s->surface, attribute, value);
471518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
472518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
473518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
474518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
475518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
476e8696a40e09b24b634214684d18526187b316a2fJamie Gennisvoid EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
477e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    clearError();
478e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
479e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    egl_display_t const * const dp = validate_display(dpy);
480e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    if (!dp) {
481e8696a40e09b24b634214684d18526187b316a2fJamie Gennis        return;
482e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
483e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
484e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    SurfaceRef _s(dp, surface);
485e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    if (!_s.get()) {
486e8696a40e09b24b634214684d18526187b316a2fJamie Gennis        setError(EGL_BAD_SURFACE, EGL_FALSE);
487e8696a40e09b24b634214684d18526187b316a2fJamie Gennis        return;
488e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    }
489e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
490e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    int64_t timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
491e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
492e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    egl_surface_t const * const s = get_surface(surface);
493e8696a40e09b24b634214684d18526187b316a2fJamie Gennis    native_window_set_buffers_timestamp(s->win.get(), timestamp);
494e8696a40e09b24b634214684d18526187b316a2fJamie Gennis}
495e8696a40e09b24b634214684d18526187b316a2fJamie Gennis
496518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
497518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// Contexts
498518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
499518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
500518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
501518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLContext share_list, const EGLint *attrib_list)
502518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
503518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
504518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
505518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const* dp = 0;
506518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
507518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (cnx) {
508518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (share_list != EGL_NO_CONTEXT) {
509518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            egl_context_t* const c = get_context(share_list);
510518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            share_list = c->context;
511518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
512518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLContext context = cnx->egl.eglCreateContext(
513ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy,
514518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                dp->configs[intptr_t(config)].config,
515518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                share_list, attrib_list);
516518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (context != EGL_NO_CONTEXT) {
517518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // figure out if it's a GLESv1 or GLESv2
518518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            int version = 0;
519518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (attrib_list) {
520518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                while (*attrib_list != EGL_NONE) {
521518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    GLint attr = *attrib_list++;
522518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    GLint value = *attrib_list++;
523518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    if (attr == EGL_CONTEXT_CLIENT_VERSION) {
524518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                        if (value == 1) {
525518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            version = GLESv1_INDEX;
526518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                        } else if (value == 2) {
527518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            version = GLESv2_INDEX;
528518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                        }
529518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    }
530518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                };
531518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
532ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            egl_context_t* c = new egl_context_t(dpy, context, config, cnx, version);
5330469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#if EGL_TRACE
5340469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy            if (gEGLDebugLevel > 0)
5350469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy                GLTrace_eglCreateContext(version, c);
5360469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#endif
537518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return c;
538518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
539518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
540518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_CONTEXT;
541518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
542518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
543518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
544518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
545518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
546518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
547518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
5485b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!dp)
5495b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return EGL_FALSE;
550518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
551f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    ContextRef _c(dp, ctx);
5525b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_c.get())
5535b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
554518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
555518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t * const c = get_context(ctx);
556ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context);
557518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (result == EGL_TRUE) {
558518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        _c.terminate();
559518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
560518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
561518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
562518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
563518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
564518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLSurface read, EGLContext ctx)
565518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
566518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
567518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
568518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = get_display(dpy);
569518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
570518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
5715b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not
5725b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is
5735b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // a valid but uninitialized display.
574518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if ( (ctx != EGL_NO_CONTEXT) || (read != EGL_NO_SURFACE) ||
575518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         (draw != EGL_NO_SURFACE) ) {
576518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
577518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
578518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
579518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // get a reference to the object passed in
580f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    ContextRef _c(dp, ctx);
581f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SurfaceRef _d(dp, draw);
582f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SurfaceRef _r(dp, read);
583518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
584518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // validate the context (if not EGL_NO_CONTEXT)
5855b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
586518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // EGL_NO_CONTEXT is valid
587518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_FALSE;
588518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
589518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
590518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // these are the underlying implementation's object
591518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext impl_ctx  = EGL_NO_CONTEXT;
592518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLSurface impl_draw = EGL_NO_SURFACE;
593518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLSurface impl_read = EGL_NO_SURFACE;
594518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
595518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // these are our objects structs passed in
596518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t       * c = NULL;
597518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * d = NULL;
598518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * r = NULL;
599518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
600518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // these are the current objects structs
601518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t * cur_c = get_context(getContext());
602518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
603518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (ctx != EGL_NO_CONTEXT) {
604518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        c = get_context(ctx);
605518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        impl_ctx = c->context;
606518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    } else {
607518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // no context given, use the implementation of the current context
608518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cur_c == NULL) {
609518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // no current context
610518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
611518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                // calling eglMakeCurrent( ..., !=0, !=0, EGL_NO_CONTEXT);
612518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                return setError(EGL_BAD_MATCH, EGL_FALSE);
613518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
614518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // not an error, there is just no current context.
615518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return EGL_TRUE;
616518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
617518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
618518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
619518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // retrieve the underlying implementation's draw EGLSurface
620518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (draw != EGL_NO_SURFACE) {
621518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        d = get_surface(draw);
622518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        impl_draw = d->surface;
623518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
624518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
625518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // retrieve the underlying implementation's read EGLSurface
626518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (read != EGL_NO_SURFACE) {
627518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        r = get_surface(read);
628518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        impl_read = r->surface;
629518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
630518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
631518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
632fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    EGLBoolean result = const_cast<egl_display_t*>(dp)->makeCurrent(c, cur_c,
633fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian            draw, read, ctx,
634fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian            impl_draw, impl_read, impl_ctx);
635518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
636518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (result == EGL_TRUE) {
637fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        if (c) {
638518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
639518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            egl_tls_t::setContext(ctx);
6400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#if EGL_TRACE
6410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy            if (gEGLDebugLevel > 0)
64293a826f78f6313db791e6fc880439189897651b3Siva Velusamy                GLTrace_eglMakeCurrent(c->version, c->cnx->hooks[c->version], ctx);
6430469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#endif
644518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            _c.acquire();
645518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            _r.acquire();
646518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            _d.acquire();
647518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        } else {
648518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            setGLHooksThreadSpecific(&gHooksNoContext);
649518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            egl_tls_t::setContext(EGL_NO_CONTEXT);
650518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
6515fecea776a5f093c21ac1a0ad3552b847d4be23eMathias Agopian    } else {
652e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        // this will ALOGE the error
6535fecea776a5f093c21ac1a0ad3552b847d4be23eMathias Agopian        result = setError(c->cnx->egl.eglGetError(), EGL_FALSE);
654518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
655518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
656518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
657518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
658518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
659518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
660518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGLint attribute, EGLint *value)
661518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
662518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
663518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
664518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
665518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
666518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
667f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    ContextRef _c(dp, ctx);
668518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
669518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
670518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t * const c = get_context(ctx);
671518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
672518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean result(EGL_TRUE);
673518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (attribute == EGL_CONFIG_ID) {
674518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        *value = dp->configs[intptr_t(c->config)].configId;
675518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    } else {
676518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // We need to remap EGL_CONFIG_IDs
677518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        result = c->cnx->egl.eglQueryContext(
678ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, c->context, attribute, value);
679518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
680518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
681518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
682518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
683518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
684518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLContext eglGetCurrentContext(void)
685518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
686518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // could be called before eglInitialize(), but we wouldn't have a context
687518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // then, and this function would correctly return EGL_NO_CONTEXT.
688518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
689518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
690518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
691518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext ctx = getContext();
692518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return ctx;
693518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
694518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
695518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglGetCurrentSurface(EGLint readdraw)
696518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
697518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // could be called before eglInitialize(), but we wouldn't have a context
698518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // then, and this function would correctly return EGL_NO_SURFACE.
699518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
700518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
701518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
702518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext ctx = getContext();
703518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (ctx) {
704518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_context_t const * const c = get_context(ctx);
705518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
706518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        switch (readdraw) {
707518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            case EGL_READ: return c->read;
708518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            case EGL_DRAW: return c->draw;
709518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            default: return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
710518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
711518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
712518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_SURFACE;
713518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
714518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
715518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay eglGetCurrentDisplay(void)
716518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
717518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // could be called before eglInitialize(), but we wouldn't have a context
718518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // then, and this function would correctly return EGL_NO_DISPLAY.
719518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
720518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
721518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
722518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext ctx = getContext();
723518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (ctx) {
724518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_context_t const * const c = get_context(ctx);
725518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE);
726518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return c->dpy;
727518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
728518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_NO_DISPLAY;
729518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
730518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
731518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglWaitGL(void)
732518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
733518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
734518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
735ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
736ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (!cnx->dso)
737ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
738ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
739ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    return cnx->egl.eglWaitGL();
740518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
741518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
742518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglWaitNative(EGLint engine)
743518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
744518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
745518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
746ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
747ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (!cnx->dso)
748ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
749ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
750ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    return cnx->egl.eglWaitNative(engine);
751518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
752518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
753518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLint eglGetError(void)
754518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
755ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    EGLint err = EGL_SUCCESS;
756ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
757ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso) {
758ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        err = cnx->egl.eglGetError();
759518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
760ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (err == EGL_SUCCESS) {
761ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        err = egl_tls_t::getError();
762ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    }
763ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    return err;
764518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
765518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
766518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// Note: Similar implementations of these functions also exist in
767518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// gl2.cpp and gl.cpp, and are used by applications that call the
768518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// exported entry points directly.
769518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiantypedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
770518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiantypedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
771518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
772518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES_impl = NULL;
773518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES_impl = NULL;
774518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
775518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic void glEGLImageTargetTexture2DOES_wrapper(GLenum target, GLeglImageOES image)
776518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
777518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    GLeglImageOES implImage =
778518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
779518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    glEGLImageTargetTexture2DOES_impl(target, implImage);
780518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
781518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
782518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic void glEGLImageTargetRenderbufferStorageOES_wrapper(GLenum target, GLeglImageOES image)
783518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
784518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    GLeglImageOES implImage =
785518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
786518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    glEGLImageTargetRenderbufferStorageOES_impl(target, implImage);
787518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
788518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
789518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
790518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
791518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // eglGetProcAddress() could be the very first function called
792518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // in which case we must make sure we've initialized ourselves, this
793518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // happens the first time egl_get_display() is called.
794518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
795518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
796518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
797518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (egl_init_drivers() == EGL_FALSE) {
798518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        setError(EGL_BAD_PARAMETER, NULL);
799518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return  NULL;
800518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
801518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
802aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis    // The EGL_ANDROID_blob_cache extension should not be exposed to
803aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis    // applications.  It is used internally by the Android EGL layer.
804c42fcf05ce253d5342993b28c412be16e61efffbJamie Gennis    if (!strcmp(procname, "eglSetBlobCacheFuncsANDROID")) {
805aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis        return NULL;
806aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis    }
807aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis
808518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    __eglMustCastToProperFunctionPointerType addr;
809518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    addr = findProcAddress(procname, sExtentionMap, NELEM(sExtentionMap));
810518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (addr) return addr;
811518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
812aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis
813518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // this protects accesses to sGLExtentionMap and sGLExtentionSlot
814518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    pthread_mutex_lock(&sExtensionMapMutex);
815518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
816518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        /*
817518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * Since eglGetProcAddress() is not associated to anything, it needs
818518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * to return a function pointer that "works" regardless of what
819518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * the current context is.
820518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         *
821518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * For this reason, we return a "forwarder", a small stub that takes
822518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * care of calling the function associated with the context
823518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * currently bound.
824518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         *
825518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * We first look for extensions we've already resolved, if we're seeing
826518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * this extension for the first time, we go through all our
827518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * implementations and call eglGetProcAddress() and record the
828518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * result in the appropriate implementation hooks and return the
829518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * address of the forwarder corresponding to that hook set.
830518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         *
831518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         */
832518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
833518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        const String8 name(procname);
834518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        addr = sGLExtentionMap.valueFor(name);
835518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        const int slot = sGLExtentionSlot;
836518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
837e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE_IF(slot >= MAX_NUMBER_OF_GL_EXTENSIONS,
838518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                "no more slots for eglGetProcAddress(\"%s\")",
839518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                procname);
840518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
8410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#if EGL_TRACE
8420469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        gl_hooks_t *debugHooks = GLTrace_getGLHooks();
8430469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#endif
8440469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
845518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) {
846518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            bool found = false;
847ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
848ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            egl_connection_t* const cnx = &gEGLImpl;
849ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            if (cnx->dso && cnx->egl.eglGetProcAddress) {
850ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                found = true;
851ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                // Extensions are independent of the bound context
852ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] =
853ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] =
854518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#if EGL_TRACE
855ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                debugHooks->ext.extensions[slot] =
856ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                gHooksTrace.ext.extensions[slot] =
857518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#endif
858ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                        cnx->egl.eglGetProcAddress(procname);
859518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
860ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
861518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (found) {
862518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                addr = gExtensionForwarders[slot];
863518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
864518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                if (!strcmp(procname, "glEGLImageTargetTexture2DOES")) {
865518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    glEGLImageTargetTexture2DOES_impl = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)addr;
866518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    addr = (__eglMustCastToProperFunctionPointerType)glEGLImageTargetTexture2DOES_wrapper;
867518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                }
868518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                if (!strcmp(procname, "glEGLImageTargetRenderbufferStorageOES")) {
869518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    glEGLImageTargetRenderbufferStorageOES_impl = (PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC)addr;
870518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    addr = (__eglMustCastToProperFunctionPointerType)glEGLImageTargetRenderbufferStorageOES_wrapper;
871518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                }
872518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
873518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                sGLExtentionMap.add(name, addr);
874518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                sGLExtentionSlot++;
875518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
876518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
877518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
878518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    pthread_mutex_unlock(&sExtensionMapMutex);
879518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return addr;
880518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
881518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
882518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
883518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
884518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
885518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
886518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
887518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
888518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
889f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SurfaceRef _s(dp, draw);
8905b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
8915b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_SURFACE, EGL_FALSE);
892518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
8930469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#if EGL_TRACE
8940469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    if (gEGLDebugLevel > 0)
8950469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        GLTrace_eglSwapBuffers(dpy, draw);
8960469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#endif
8970469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
898518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(draw);
899ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
900518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
901518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
902518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
903518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            NativePixmapType target)
904518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
905518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
906518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
907518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
908518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
909518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
910f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SurfaceRef _s(dp, surface);
9115b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
9125b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_SURFACE, EGL_FALSE);
913518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
914518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
915ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    return s->cnx->egl.eglCopyBuffers(dp->disp.dpy, s->surface, target);
916518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
917518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
918518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianconst char* eglQueryString(EGLDisplay dpy, EGLint name)
919518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
920518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
921518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
922518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
923518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return (const char *) NULL;
924518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
925518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    switch (name) {
926518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        case EGL_VENDOR:
9274b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            return dp->getVendorString();
928518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        case EGL_VERSION:
9294b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            return dp->getVersionString();
930518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        case EGL_EXTENSIONS:
9314b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            return dp->getExtensionString();
932518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        case EGL_CLIENT_APIS:
9334b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            return dp->getClientApiString();
934ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        case EGL_VERSION_HW_ANDROID:
935ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            return dp->disp.queryString.version;
936518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
937518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return setError(EGL_BAD_PARAMETER, (const char *)0);
938518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
939518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
940518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
941518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
942518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// EGL 1.1
943518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
944518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
945518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglSurfaceAttrib(
946518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
947518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
948518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
949518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
950518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
951518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
952518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
953f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SurfaceRef _s(dp, surface);
9545b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
9555b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_SURFACE, EGL_FALSE);
956518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
957518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
958518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglSurfaceAttrib) {
959518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return s->cnx->egl.eglSurfaceAttrib(
960ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, s->surface, attribute, value);
961518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
962518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return setError(EGL_BAD_SURFACE, EGL_FALSE);
963518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
964518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
965518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglBindTexImage(
966518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
967518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
968518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
969518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
970518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
971518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
972518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
973f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SurfaceRef _s(dp, surface);
9745b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
9755b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_SURFACE, EGL_FALSE);
976518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
977518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
978518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglBindTexImage) {
979518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return s->cnx->egl.eglBindTexImage(
980ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, s->surface, buffer);
981518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
982518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return setError(EGL_BAD_SURFACE, EGL_FALSE);
983518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
984518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
985518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglReleaseTexImage(
986518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
987518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
988518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
989518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
990518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
991518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
992518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
993f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SurfaceRef _s(dp, surface);
9945b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
9955b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_SURFACE, EGL_FALSE);
996518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
997518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
998518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglReleaseTexImage) {
999518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return s->cnx->egl.eglReleaseTexImage(
1000ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, s->surface, buffer);
1001518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1002518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return setError(EGL_BAD_SURFACE, EGL_FALSE);
1003518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1004518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1005518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
1006518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1007518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1008518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1009518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
1010518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1011518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1012518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_TRUE;
1013ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1014ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglSwapInterval) {
1015ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = cnx->egl.eglSwapInterval(dp->disp.dpy, interval);
1016518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1017ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1018518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
1019518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1020518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1021518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1022518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1023518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// EGL 1.2
1024518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1025518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1026518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglWaitClient(void)
1027518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1028518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1029518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1030ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1031ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (!cnx->dso)
1032ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
1033ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1034ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    EGLBoolean res;
1035ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->egl.eglWaitClient) {
1036ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = cnx->egl.eglWaitClient();
1037ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    } else {
1038ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = cnx->egl.eglWaitGL();
1039518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1040518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
1041518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1042518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1043518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglBindAPI(EGLenum api)
1044518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1045518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1046518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1047518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (egl_init_drivers() == EGL_FALSE) {
1048518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1049518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1050518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1051518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // bind this API on all EGLs
1052518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_TRUE;
1053ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1054ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglBindAPI) {
1055ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = cnx->egl.eglBindAPI(api);
1056518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1057518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
1058518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1059518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1060518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLenum eglQueryAPI(void)
1061518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1062518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1063518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1064518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (egl_init_drivers() == EGL_FALSE) {
1065518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1066518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1067518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1068ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1069ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglQueryAPI) {
1070ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return cnx->egl.eglQueryAPI();
1071518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1072ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1073518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // or, it can only be OpenGL ES
1074518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_OPENGL_ES_API;
1075518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1076518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1077518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglReleaseThread(void)
1078518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1079518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1080518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1081518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // If there is context bound to the thread, release it
1082fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    egl_display_t::loseCurrent(get_context(getContext()));
1083518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1084ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1085ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglReleaseThread) {
1086ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        cnx->egl.eglReleaseThread();
1087518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1088ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1089518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_tls_t::clearTLS();
10900469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#if EGL_TRACE
10910469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    if (gEGLDebugLevel > 0)
10920469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        GLTrace_eglReleaseThread();
10930469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#endif
1094518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_TRUE;
1095518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1096518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1097518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSurface eglCreatePbufferFromClientBuffer(
1098518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian          EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
1099518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian          EGLConfig config, const EGLint *attrib_list)
1100518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1101518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1102518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1103518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const* dp = 0;
1104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
1105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!cnx) return EGL_FALSE;
1106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (cnx->egl.eglCreatePbufferFromClientBuffer) {
1107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return cnx->egl.eglCreatePbufferFromClientBuffer(
1108ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy,
1109518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                buftype, buffer,
1110518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                dp->configs[intptr_t(config)].config, attrib_list);
1111518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1112518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
1113518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1116518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// EGL_EGLEXT_VERSION 3
1117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1119518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
1120518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        const EGLint *attrib_list)
1121518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1122518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1123518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1124518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
1125518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1126518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1127f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SurfaceRef _s(dp, surface);
11285b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
11295b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_SURFACE, EGL_FALSE);
1130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
1132518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglLockSurfaceKHR) {
1133518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return s->cnx->egl.eglLockSurfaceKHR(
1134ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, s->surface, attrib_list);
1135518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1136518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return setError(EGL_BAD_DISPLAY, EGL_FALSE);
1137518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1138518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1139518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
1140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1142518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
1144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1146f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SurfaceRef _s(dp, surface);
11475b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
11485b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_SURFACE, EGL_FALSE);
1149518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1150518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_surface_t const * const s = get_surface(surface);
1151518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (s->cnx->egl.eglUnlockSurfaceKHR) {
1152ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return s->cnx->egl.eglUnlockSurfaceKHR(dp->disp.dpy, s->surface);
1153518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1154518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return setError(EGL_BAD_DISPLAY, EGL_FALSE);
1155518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1156518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1157518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1158518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLClientBuffer buffer, const EGLint *attrib_list)
1159518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1160518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1161518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1162518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
1163518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_NO_IMAGE_KHR;
1164518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1165518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (ctx != EGL_NO_CONTEXT) {
1166f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        ContextRef _c(dp, ctx);
11675b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        if (!_c.get())
11685b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian            return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
1169518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_context_t * const c = get_context(ctx);
1170518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // since we have an EGLContext, we know which implementation to use
1171518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLImageKHR image = c->cnx->egl.eglCreateImageKHR(
1172ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, c->context, target, buffer, attrib_list);
1173518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (image == EGL_NO_IMAGE_KHR)
1174518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return image;
1175518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1176518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_image_t* result = new egl_image_t(dpy, ctx);
1177ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        result->image = image;
1178518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return (EGLImageKHR)result;
1179518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    } else {
1180518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // EGL_NO_CONTEXT is a valid parameter
1181518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1182518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        /* Since we don't have a way to know which implementation to call,
1183518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * we're calling all of them. If at least one of the implementation
1184518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * succeeded, this is a success.
1185518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         */
1186518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1187518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLint currentError = eglGetError();
1188518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1189ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        EGLImageKHR implImage = EGL_NO_IMAGE_KHR;
1190ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        egl_connection_t* const cnx = &gEGLImpl;
1191ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        if (cnx->dso && cnx->egl.eglCreateImageKHR) {
1192ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            implImage = cnx->egl.eglCreateImageKHR(
1193ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    dp->disp.dpy, ctx, target, buffer, attrib_list);
1194518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
1195518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1196ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        if (implImage == EGL_NO_IMAGE_KHR) {
1197518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // failure, if there was an error when we entered this function,
1198518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // the error flag must not be updated.
1199518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // Otherwise, the error is whatever happened in the implementation
1200518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // that faulted.
1201518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (currentError != EGL_SUCCESS) {
1202518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                setError(currentError, EGL_NO_IMAGE_KHR);
1203518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
1204518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return EGL_NO_IMAGE_KHR;
1205518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        } else {
1206518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // In case of success, we need to clear all error flags
1207518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // (especially those caused by the implementation that didn't
1208ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            // succeed).
1209518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            eglGetError();
1210518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
1211518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1212518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_image_t* result = new egl_image_t(dpy, ctx);
1213ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        result->image = implImage;
1214518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return (EGLImageKHR)result;
1215518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1216518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1217518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1218518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
1219518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1220518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1221518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1222518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
1223518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1224518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1225f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    ImageRef _i(dp, img);
1226518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!_i.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1227518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1228518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_image_t* image = get_image(img);
1229518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    bool success = false;
1230ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1231ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
1232ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (image->image != EGL_NO_IMAGE_KHR) {
1233ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        if (cnx->dso && cnx->egl.eglDestroyImageKHR) {
1234ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            if (cnx->egl.eglDestroyImageKHR(
1235ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    dp->disp.dpy, image->image)) {
1236ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                success = true;
1237518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
1238518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
1239518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1240ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
1241518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!success)
1242518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_FALSE;
1243518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1244518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    _i.terminate();
1245518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1246518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_TRUE;
1247518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1248518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1249518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1250518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// EGL_EGLEXT_VERSION 5
1251518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1252518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1253518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1254518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1255518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1256518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1257518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1258518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
1259518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_NO_SYNC_KHR;
1260518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1261518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext ctx = eglGetCurrentContext();
1262f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    ContextRef _c(dp, ctx);
12635b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_c.get())
12645b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_CONTEXT, EGL_NO_SYNC_KHR);
12655b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian
1266518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t * const c = get_context(ctx);
1267518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLSyncKHR result = EGL_NO_SYNC_KHR;
1268518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (c->cnx->egl.eglCreateSyncKHR) {
1269518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLSyncKHR sync = c->cnx->egl.eglCreateSyncKHR(
1270ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, type, attrib_list);
1271518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (sync == EGL_NO_SYNC_KHR)
1272518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            return sync;
1273518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        result = (egl_sync_t*)new egl_sync_t(dpy, ctx, sync);
1274518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1275518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return (EGLSyncKHR)result;
1276518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1277518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1278518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1279518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1280518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1281518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1282518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
1283518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1284518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1285f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SyncRef _s(dp, sync);
1286518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1287518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_sync_t* syncObject = get_sync(sync);
1288518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1289518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext ctx = syncObject->context;
1290f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    ContextRef _c(dp, ctx);
12915b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_c.get())
12925b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
1293518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1294518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean result = EGL_FALSE;
1295518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t * const c = get_context(ctx);
1296518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (c->cnx->egl.eglDestroySyncKHR) {
1297518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        result = c->cnx->egl.eglDestroySyncKHR(
1298ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, syncObject->sync);
1299518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (result)
1300518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            _s.terminate();
1301518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1302518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return result;
1303518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1304518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1305518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
1306518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1307518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1308518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1309518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
1310518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1311518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1312f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SyncRef _s(dp, sync);
1313518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1314518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_sync_t* syncObject = get_sync(sync);
1315518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1316518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext ctx = syncObject->context;
1317f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    ContextRef _c(dp, ctx);
13185b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_c.get())
13195b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
1320518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1321518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t * const c = get_context(ctx);
1322518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (c->cnx->egl.eglClientWaitSyncKHR) {
1323518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return c->cnx->egl.eglClientWaitSyncKHR(
1324ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, syncObject->sync, flags, timeout);
1325518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1326518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1327518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_FALSE;
1328518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1329518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1330518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
1331518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian{
1332518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    clearError();
1333518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1334518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_display_t const * const dp = validate_display(dpy);
1335518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (!dp) return EGL_FALSE;
1336518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1337f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    SyncRef _s(dp, sync);
13385b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_s.get())
13395b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
1340518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
13415b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    egl_sync_t* syncObject = get_sync(sync);
1342518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLContext ctx = syncObject->context;
1343f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian    ContextRef _c(dp, ctx);
13445b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (!_c.get())
13455b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
1346518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1347518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    egl_context_t * const c = get_context(ctx);
1348518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (c->cnx->egl.eglGetSyncAttribKHR) {
1349518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return c->cnx->egl.eglGetSyncAttribKHR(
1350ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                dp->disp.dpy, syncObject->sync, attribute, value);
1351518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
1352518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1353518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGL_FALSE;
1354518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
1355518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1356518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1357518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ANDROID extensions
1358518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
1359518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
13604b9511c16195a646242eff833b0af212933b6ecaMathias Agopian/* ANDROID extensions entry-point go here */
13611c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
13621c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang// ----------------------------------------------------------------------------
13631c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang// NVIDIA extensions
13641c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang// ----------------------------------------------------------------------------
13651c3d72a2291827fb15e2ef311a571c860e0dba41Jonas YangEGLuint64NV eglGetSystemTimeFrequencyNV()
13661c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang{
13671c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    clearError();
13681c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
13691c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    if (egl_init_drivers() == EGL_FALSE) {
13701c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
13711c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    }
13721c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
13731c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    EGLuint64NV ret = 0;
1374ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
13751c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
1376ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglGetSystemTimeFrequencyNV) {
1377ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return cnx->egl.eglGetSystemTimeFrequencyNV();
13781c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    }
13791c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
13800e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian    return setErrorQuiet(EGL_BAD_DISPLAY, 0);
13811c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang}
13821c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
13831c3d72a2291827fb15e2ef311a571c860e0dba41Jonas YangEGLuint64NV eglGetSystemTimeNV()
13841c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang{
13851c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    clearError();
13861c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
13871c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    if (egl_init_drivers() == EGL_FALSE) {
13881c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
13891c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    }
13901c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
13911c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    EGLuint64NV ret = 0;
1392ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
13931c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
1394ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && cnx->egl.eglGetSystemTimeNV) {
1395ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        return cnx->egl.eglGetSystemTimeNV();
13961c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang    }
13971c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang
13980e8bbee5775d81c7bbc479b995496cac9238559fMathias Agopian    return setErrorQuiet(EGL_BAD_DISPLAY, 0);
13991c3d72a2291827fb15e2ef311a571c860e0dba41Jonas Yang}
1400