egl_display.cpp revision 32397c1cd3327905173b36baa6fd1c579bc328ff
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
174b9511c16195a646242eff833b0af212933b6ecaMathias Agopian#include <string.h>
184b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
19aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis#include "egl_cache.h"
20518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_display.h"
21518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_object.h"
22518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_tls.h"
23518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_impl.h"
24518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "Loader.h"
25518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
26518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
27518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiannamespace android {
28518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
29518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
304b9511c16195a646242eff833b0af212933b6ecaMathias Agopianstatic char const * const sVendorString     = "Android";
314b9511c16195a646242eff833b0af212933b6ecaMathias Agopianstatic char const * const sVersionString    = "1.4 Android META-EGL";
324b9511c16195a646242eff833b0af212933b6ecaMathias Agopianstatic char const * const sClientApiString  = "OpenGL ES";
334b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
344b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// this is the list of EGL extensions that are exposed to applications
354b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// some of them are mandatory because used by the ANDROID system.
364b9511c16195a646242eff833b0af212933b6ecaMathias Agopian//
374b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// mandatory extensions are required per the CDD and not explicitly
384b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// checked during EGL initialization. the system *assumes* these extensions
394b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// are present. the system may not function properly if some mandatory
404b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// extensions are missing.
414b9511c16195a646242eff833b0af212933b6ecaMathias Agopian//
424b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// NOTE: sExtensionString MUST be have a single space as the last character.
434b9511c16195a646242eff833b0af212933b6ecaMathias Agopian//
444b9511c16195a646242eff833b0af212933b6ecaMathias Agopianstatic char const * const sExtensionString  =
454b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_image "                        // mandatory
464b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_image_base "                   // mandatory
474b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_image_pixmap "
484b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_gl_texture_2D_image "
494b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_gl_texture_cubemap_image "
504b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_gl_renderbuffer_image "
514b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_fence_sync "
524b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_NV_system_time "
534b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_ANDROID_image_native_buffer "      // mandatory
544b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        ;
554b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
564b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// extensions not exposed to applications but used by the ANDROID system
574b9511c16195a646242eff833b0af212933b6ecaMathias Agopian//      "EGL_ANDROID_recordable "               // mandatory
584b9511c16195a646242eff833b0af212933b6ecaMathias Agopian//      "EGL_ANDROID_blob_cache "               // strongly recommended
594b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
60518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern void initEglTraceLevel();
61518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern void setGLHooksThreadSpecific(gl_hooks_t const *value);
62518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
63518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianstatic int cmp_configs(const void* a, const void *b) {
64518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    const egl_config_t& c0 = *(egl_config_t const *)a;
65518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    const egl_config_t& c1 = *(egl_config_t const *)b;
66518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return c0<c1 ? -1 : (c1<c0 ? 1 : 0);
67518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
68518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
69518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
70518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
71518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
72518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
73518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::egl_display_t() :
74518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    magic('_dpy'), numTotalConfigs(0), configs(0), refs(0) {
75518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
76518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
77518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::~egl_display_t() {
78518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    magic = 0;
79766010858ea7696d64f1b559413670bdd8627595Jamie Gennis    egl_cache_t::get()->terminate();
80518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
81518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
82518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t* egl_display_t::get(EGLDisplay dpy) {
83518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    uintptr_t index = uintptr_t(dpy)-1U;
84518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return (index >= NUM_DISPLAYS) ? NULL : &sDisplay[index];
85518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
86518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
87518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_display_t::addObject(egl_object_t* object) {
88518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
89518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    objects.add(object);
90518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
91518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
925b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianvoid egl_display_t::removeObject(egl_object_t* object) {
93518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
945b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    objects.remove(object);
95518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
96518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
97f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopianbool egl_display_t::getObject(egl_object_t* object) const {
98518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
995b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (objects.indexOf(object) >= 0) {
100f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        if (object->getDisplay() == this) {
101f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian            object->incRef();
102f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian            return true;
103f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        }
104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return false;
106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
108518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) {
109518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (uintptr_t(disp) >= NUM_DISPLAYS)
110518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return NULL;
111518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
112518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return sDisplay[uintptr_t(disp)].getDisplay(disp);
113518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {
116518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
119518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // get our driver loader
120518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Loader& loader(Loader::getInstance());
121518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
122518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
123518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_connection_t* const cnx = &gEGLImpl[i];
124518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cnx->dso && disp[i].dpy == EGL_NO_DISPLAY) {
125518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
126518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].dpy = dpy;
127518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (dpy == EGL_NO_DISPLAY) {
128518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                loader.close(cnx->dso);
129518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                cnx->dso = NULL;
130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
132518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
133518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
134518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGLDisplay(uintptr_t(display) + 1U);
135518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
136518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
137518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
138518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
139518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (refs > 0) {
142518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (major != NULL)
143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            *major = VERSION_MAJOR;
144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (minor != NULL)
145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            *minor = VERSION_MINOR;
146518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs++;
147518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_TRUE;
148518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
149518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
150518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#if EGL_TRACE
151518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
152518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // Called both at early_init time and at this time. (Early_init is pre-zygote, so
153518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // the information from that call may be stale.)
154518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    initEglTraceLevel();
155518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
156518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#endif
157518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
158518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    setGLHooksThreadSpecific(&gHooksNoContext);
159518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
160518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // initialize each EGL and
161518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // build our own extension string first, based on the extension we know
162518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // and the extension supported by our client implementation
163518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
164518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_connection_t* const cnx = &gEGLImpl[i];
165518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        cnx->major = -1;
166518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        cnx->minor = -1;
167518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (!cnx->dso)
168518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            continue;
169518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
170518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#if defined(ADRENO130)
171518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#warning "Adreno-130 eglInitialize() workaround"
172518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        /*
173518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * The ADRENO 130 driver returns a different EGLDisplay each time
174518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * eglGetDisplay() is called, but also makes the EGLDisplay invalid
175518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * after eglTerminate() has been called, so that eglInitialize()
176518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * cannot be called again. Therefore, we need to make sure to call
177518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * eglGetDisplay() before calling eglInitialize();
178518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         */
179518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (i == IMPL_HARDWARE) {
180518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].dpy =
181518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
182518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
183518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#endif
184518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
185518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        EGLDisplay idpy = disp[i].dpy;
186518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
1879d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block            //ALOGD("initialized %d dpy=%p, ver=%d.%d, cnx=%p",
188518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            //        i, idpy, cnx->major, cnx->minor, cnx);
189518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
190518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // display is now initialized
191518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].state = egl_display_t::INITIALIZED;
192518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
193518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // get the query-strings for this display for each implementation
194518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].queryString.vendor = cnx->egl.eglQueryString(idpy,
195518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_VENDOR);
196518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].queryString.version = cnx->egl.eglQueryString(idpy,
197518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_VERSION);
198518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].queryString.extensions = cnx->egl.eglQueryString(idpy,
199518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_EXTENSIONS);
200518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].queryString.clientApi = cnx->egl.eglQueryString(idpy,
201518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_CLIENT_APIS);
202518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
203518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        } else {
20432397c1cd3327905173b36baa6fd1c579bc328ffSteve Block            ALOGW("%d: eglInitialize(%p) failed (%s)", i, idpy,
205518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
206518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
207518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
208518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
2094b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    // the query strings are per-display
2104b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    mVendorString.setTo(sVendorString);
2114b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    mVersionString.setTo(sVersionString);
2124b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    mClientApiString.setTo(sClientApiString);
2134b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
2144b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    // we only add extensions that exist in at least one implementation
2154b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    char const* start = sExtensionString;
2164b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    char const* end;
2174b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    do {
2184b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        // find the space separating this extension for the next one
2194b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        end = strchr(start, ' ');
2204b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        if (end) {
2214b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            // length of the extension string
2224b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            const size_t len = end - start;
223f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian            if (len) {
224f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                // NOTE: we could avoid the copy if we had strnstr.
225f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                const String8 ext(start, len);
226f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                // now go through all implementations and look for this extension
227f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
228f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                    if (disp[i].queryString.extensions) {
229f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                        // if we find it, add this extension string to our list
230f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                        // (and don't forget the space)
231f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                        const char* match = strstr(disp[i].queryString.extensions, ext.string());
232f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                        if (match && (match[len] == ' ' || match[len] == 0)) {
233f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                            mExtensionString.append(start, len+1);
234f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                        }
235f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                    }
2364b9511c16195a646242eff833b0af212933b6ecaMathias Agopian                }
2374b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            }
2384b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            // process the next extension string, and skip the space.
2394b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            start = end + 1;
2404b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        }
2414b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    } while (end);
2424b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
243aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis    egl_cache_t::get()->initialize(this);
244aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis
245518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_FALSE;
246518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
247518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_connection_t* const cnx = &gEGLImpl[i];
248518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
249518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            EGLint n;
250518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (cnx->egl.eglGetConfigs(disp[i].dpy, 0, 0, &n)) {
251518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                disp[i].config = (EGLConfig*) malloc(sizeof(EGLConfig) * n);
252518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                if (disp[i].config) {
253518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    if (cnx->egl.eglGetConfigs(disp[i].dpy, disp[i].config, n,
254518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            &disp[i].numConfigs)) {
255518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                        numTotalConfigs += n;
256518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                        res = EGL_TRUE;
257518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    }
258518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                }
259518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
260518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
261518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
262518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
263518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (res == EGL_TRUE) {
264518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        configs = new egl_config_t[numTotalConfigs];
265518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        for (int i = 0, k = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
266518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            egl_connection_t* const cnx = &gEGLImpl[i];
267518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
268518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                for (int j = 0; j < disp[i].numConfigs; j++) {
269518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    configs[k].impl = i;
270518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    configs[k].config = disp[i].config[j];
271518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    configs[k].configId = k + 1; // CONFIG_ID start at 1
272518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    // store the implementation's CONFIG_ID
273518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    cnx->egl.eglGetConfigAttrib(disp[i].dpy, disp[i].config[j],
274518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                            EGL_CONFIG_ID, &configs[k].implConfigId);
275518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    k++;
276518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                }
277518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
278518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
279518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
280518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        // sort our configurations so we can do binary-searches
281518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        qsort(configs, numTotalConfigs, sizeof(egl_config_t), cmp_configs);
282518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
283518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs++;
284518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (major != NULL)
285518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            *major = VERSION_MAJOR;
286518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (minor != NULL)
287518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            *minor = VERSION_MINOR;
288518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_TRUE;
289518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
290518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
291518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
292518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
293518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::terminate() {
294518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
295518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
296518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
297518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (refs == 0) {
298518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
299518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
300518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
301518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // this is specific to Android, display termination is ref-counted.
302518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (refs > 1) {
303518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs--;
304518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_TRUE;
305518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
306518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
307518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_FALSE;
308518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
309518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        egl_connection_t* const cnx = &gEGLImpl[i];
310518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cnx->dso && disp[i].state == egl_display_t::INITIALIZED) {
311518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            if (cnx->egl.eglTerminate(disp[i].dpy) == EGL_FALSE) {
31232397c1cd3327905173b36baa6fd1c579bc328ffSteve Block                ALOGW("%d: eglTerminate(%p) failed (%s)", i, disp[i].dpy,
313518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                        egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
314518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            }
315518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // REVISIT: it's unclear what to do if eglTerminate() fails
316518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            free(disp[i].config);
317518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
318518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].numConfigs = 0;
319518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].config = 0;
320518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            disp[i].state = egl_display_t::TERMINATED;
321518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
322518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            res = EGL_TRUE;
323518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
324518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
325518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
3265b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // Mark all objects remaining in the list as terminated, unless
3275b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // there are no reference to them, it which case, we're free to
3285b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // delete them.
3295b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    size_t count = objects.size();
33032397c1cd3327905173b36baa6fd1c579bc328ffSteve Block    ALOGW_IF(count, "eglTerminate() called w/ %d objects remaining", count);
3315b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
3325b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        egl_object_t* o = objects.itemAt(i);
3335b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        o->destroy();
3345b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    }
3355b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian
3365b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // this marks all object handles are "terminated"
3375b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    objects.clear();
338518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
339518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    refs--;
340518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    numTotalConfigs = 0;
341518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    delete[] configs;
342518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
343518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
344518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
345518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
346518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
347518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}; // namespace android
348518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
349