egl_display.cpp revision 518ec112f468eb67bf681b3eec896d7bfb4ff98d
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 "egl_display.h"
18518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_object.h"
19518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_tls.h"
20518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_impl.h"
21518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "Loader.h"
22518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
23518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
24518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiannamespace android {
25518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
26518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
27518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern void initEglTraceLevel();
28518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern void setGLHooksThreadSpecific(gl_hooks_t const *value);
29518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
30518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic int cmp_configs(const void* a, const void *b) {
31518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    const egl_config_t& c0 = *(egl_config_t const *)a;
32518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    const egl_config_t& c1 = *(egl_config_t const *)b;
33518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return c0<c1 ? -1 : (c1<c0 ? 1 : 0);
34518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
35518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
36518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
37518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
38518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
39518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
40518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::egl_display_t() :
41518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    magic('_dpy'), numTotalConfigs(0), configs(0), refs(0) {
42518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
43518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
44518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::~egl_display_t() {
45518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    magic = 0;
46518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
47518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
48518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t* egl_display_t::get(EGLDisplay dpy) {
49518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    uintptr_t index = uintptr_t(dpy)-1U;
50518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return (index >= NUM_DISPLAYS) ? NULL : &sDisplay[index];
51518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
52518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
53518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_display_t::addObject(egl_object_t* object) {
54518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
55518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    objects.add(object);
56518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
57518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
58518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianbool egl_display_t::getObject(egl_object_t* object) {
59518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
60518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (objects.indexOf(object) >= 0) {
61518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        object->incRef();
62518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return true;
63518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
64518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return false;
65518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
66518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
67518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianbool egl_display_t::removeObject(egl_object_t* object) {
68518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
69518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (object->decRef() == 1) {
70518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        objects.remove(object);
71518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return true;
72518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
73518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return false;
74518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
75518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
76518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) {
77518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (uintptr_t(disp) >= NUM_DISPLAYS)
78518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return NULL;
79518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
80518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return sDisplay[uintptr_t(disp)].getDisplay(disp);
81518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
82518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
83518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {
84518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
85518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
86518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
87518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // get our driver loader
88518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Loader& loader(Loader::getInstance());
89518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
90518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
91518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_connection_t* const cnx = &gEGLImpl[i];
92518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cnx->dso && disp[i].dpy == EGL_NO_DISPLAY) {
93518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
94518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].dpy = dpy;
95518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (dpy == EGL_NO_DISPLAY) {
96518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                loader.close(cnx->dso);
97518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                cnx->dso = NULL;
98518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
99518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
100518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
101518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
102518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGLDisplay(uintptr_t(display) + 1U);
103518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
108518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
109518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (refs > 0) {
110518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (major != NULL)
111518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            *major = VERSION_MAJOR;
112518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (minor != NULL)
113518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            *minor = VERSION_MINOR;
114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs++;
115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_TRUE;
116518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#if EGL_TRACE
119518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
120518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // Called both at early_init time and at this time. (Early_init is pre-zygote, so
121518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // the information from that call may be stale.)
122518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    initEglTraceLevel();
123518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
124518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#endif
125518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
126518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    setGLHooksThreadSpecific(&gHooksNoContext);
127518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
128518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // initialize each EGL and
129518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // build our own extension string first, based on the extension we know
130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // and the extension supported by our client implementation
131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
132518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_connection_t* const cnx = &gEGLImpl[i];
133518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        cnx->major = -1;
134518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        cnx->minor = -1;
135518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!cnx->dso)
136518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            continue;
137518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
138518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#if defined(ADRENO130)
139518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#warning "Adreno-130 eglInitialize() workaround"
140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        /*
141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * The ADRENO 130 driver returns a different EGLDisplay each time
142518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * eglGetDisplay() is called, but also makes the EGLDisplay invalid
143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * after eglTerminate() has been called, so that eglInitialize()
144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * cannot be called again. Therefore, we need to make sure to call
145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * eglGetDisplay() before calling eglInitialize();
146518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         */
147518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (i == IMPL_HARDWARE) {
148518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].dpy =
149518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
150518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
151518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#endif
152518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
153518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLDisplay idpy = disp[i].dpy;
154518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
155518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            //LOGD("initialized %d dpy=%p, ver=%d.%d, cnx=%p",
156518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            //        i, idpy, cnx->major, cnx->minor, cnx);
157518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
158518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // display is now initialized
159518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].state = egl_display_t::INITIALIZED;
160518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
161518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // get the query-strings for this display for each implementation
162518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].queryString.vendor = cnx->egl.eglQueryString(idpy,
163518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_VENDOR);
164518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].queryString.version = cnx->egl.eglQueryString(idpy,
165518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_VERSION);
166518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].queryString.extensions = cnx->egl.eglQueryString(idpy,
167518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_EXTENSIONS);
168518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].queryString.clientApi = cnx->egl.eglQueryString(idpy,
169518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_CLIENT_APIS);
170518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
171518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        } else {
172518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            LOGW("%d: eglInitialize(%p) failed (%s)", i, idpy,
173518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
174518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
175518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
176518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
177518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_FALSE;
178518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
179518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_connection_t* const cnx = &gEGLImpl[i];
180518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
181518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            EGLint n;
182518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (cnx->egl.eglGetConfigs(disp[i].dpy, 0, 0, &n)) {
183518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                disp[i].config = (EGLConfig*) malloc(sizeof(EGLConfig) * n);
184518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                if (disp[i].config) {
185518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    if (cnx->egl.eglGetConfigs(disp[i].dpy, disp[i].config, n,
186518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            &disp[i].numConfigs)) {
187518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                        numTotalConfigs += n;
188518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                        res = EGL_TRUE;
189518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    }
190518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                }
191518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
192518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
193518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
194518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
195518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (res == EGL_TRUE) {
196518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        configs = new egl_config_t[numTotalConfigs];
197518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        for (int i = 0, k = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
198518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            egl_connection_t* const cnx = &gEGLImpl[i];
199518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
200518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                for (int j = 0; j < disp[i].numConfigs; j++) {
201518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    configs[k].impl = i;
202518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    configs[k].config = disp[i].config[j];
203518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    configs[k].configId = k + 1; // CONFIG_ID start at 1
204518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    // store the implementation's CONFIG_ID
205518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    cnx->egl.eglGetConfigAttrib(disp[i].dpy, disp[i].config[j],
206518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGL_CONFIG_ID, &configs[k].implConfigId);
207518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    k++;
208518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                }
209518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
210518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
211518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
212518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // sort our configurations so we can do binary-searches
213518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        qsort(configs, numTotalConfigs, sizeof(egl_config_t), cmp_configs);
214518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
215518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs++;
216518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (major != NULL)
217518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            *major = VERSION_MAJOR;
218518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (minor != NULL)
219518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            *minor = VERSION_MINOR;
220518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_TRUE;
221518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
222518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
223518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
224518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
225518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::terminate() {
226518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
227518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
228518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
229518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (refs == 0) {
230518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
231518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
232518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
233518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // this is specific to Android, display termination is ref-counted.
234518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (refs > 1) {
235518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs--;
236518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_TRUE;
237518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
238518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
239518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_FALSE;
240518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
241518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_connection_t* const cnx = &gEGLImpl[i];
242518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cnx->dso && disp[i].state == egl_display_t::INITIALIZED) {
243518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (cnx->egl.eglTerminate(disp[i].dpy) == EGL_FALSE) {
244518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                LOGW("%d: eglTerminate(%p) failed (%s)", i, disp[i].dpy,
245518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                        egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
246518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
247518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // REVISIT: it's unclear what to do if eglTerminate() fails
248518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            free(disp[i].config);
249518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
250518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].numConfigs = 0;
251518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].config = 0;
252518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].state = egl_display_t::TERMINATED;
253518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
254518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            res = EGL_TRUE;
255518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
256518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
257518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
258518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // TODO: all egl_object_t should be marked for termination
259518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
260518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    refs--;
261518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    numTotalConfigs = 0;
262518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    delete[] configs;
263518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
264518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
265518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
266518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
267518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
268518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}; // namespace android
269518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
270