egl_display.cpp revision 7773c435bc5da8217433e1b242d3a6712a17b5f7
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 Agopian// ----------------------------------------------------------------------------
64518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
65518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
66518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
67518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::egl_display_t() :
687773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    magic('_dpy'), refs(0) {
69518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
70518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
71518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::~egl_display_t() {
72518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    magic = 0;
73766010858ea7696d64f1b559413670bdd8627595Jamie Gennis    egl_cache_t::get()->terminate();
74518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
75518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
76518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t* egl_display_t::get(EGLDisplay dpy) {
77518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    uintptr_t index = uintptr_t(dpy)-1U;
78518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return (index >= NUM_DISPLAYS) ? NULL : &sDisplay[index];
79518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
80518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
81518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_display_t::addObject(egl_object_t* object) {
82518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
83518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    objects.add(object);
84518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
85518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
865b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianvoid egl_display_t::removeObject(egl_object_t* object) {
87518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
885b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    objects.remove(object);
89518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
90518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
91f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopianbool egl_display_t::getObject(egl_object_t* object) const {
92518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
935b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (objects.indexOf(object) >= 0) {
94f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        if (object->getDisplay() == this) {
95f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian            object->incRef();
96f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian            return true;
97f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        }
98518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
99518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return false;
100518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
101518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
102518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) {
103518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (uintptr_t(disp) >= NUM_DISPLAYS)
104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return NULL;
105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return sDisplay[uintptr_t(disp)].getDisplay(disp);
107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
108518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
109518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {
110518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
111518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
112518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
113518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // get our driver loader
114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Loader& loader(Loader::getInstance());
115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
116ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
117ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && disp.dpy == EGL_NO_DISPLAY) {
118ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
119ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        disp.dpy = dpy;
120ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        if (dpy == EGL_NO_DISPLAY) {
121ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            loader.close(cnx->dso);
122ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            cnx->dso = NULL;
123518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
124518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
125518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
126518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGLDisplay(uintptr_t(display) + 1U);
127518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
128518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
129518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
132518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
133518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (refs > 0) {
134518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (major != NULL)
135518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            *major = VERSION_MAJOR;
136518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (minor != NULL)
137518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            *minor = VERSION_MINOR;
138518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs++;
139518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_TRUE;
140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
142518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#if EGL_TRACE
143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // Called both at early_init time and at this time. (Early_init is pre-zygote, so
145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // the information from that call may be stale.)
146518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    initEglTraceLevel();
147518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
148518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#endif
149518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
150518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    setGLHooksThreadSpecific(&gHooksNoContext);
151518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
152518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // initialize each EGL and
153518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // build our own extension string first, based on the extension we know
154518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // and the extension supported by our client implementation
155ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
156ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
157ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    cnx->major = -1;
158ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    cnx->minor = -1;
159ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso) {
160518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
161518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#if defined(ADRENO130)
162518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#warning "Adreno-130 eglInitialize() workaround"
163518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        /*
164518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * The ADRENO 130 driver returns a different EGLDisplay each time
165518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * eglGetDisplay() is called, but also makes the EGLDisplay invalid
166518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * after eglTerminate() has been called, so that eglInitialize()
167518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * cannot be called again. Therefore, we need to make sure to call
168518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * eglGetDisplay() before calling eglInitialize();
169518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         */
170518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (i == IMPL_HARDWARE) {
171ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            disp[i].dpy = cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
172518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
173518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#endif
174518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
175ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        EGLDisplay idpy = disp.dpy;
176518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
177ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            //ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
178ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            //        idpy, cnx->major, cnx->minor, cnx);
179518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
180518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // display is now initialized
181ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            disp.state = egl_display_t::INITIALIZED;
182518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
183518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // get the query-strings for this display for each implementation
184ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            disp.queryString.vendor = cnx->egl.eglQueryString(idpy,
185518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_VENDOR);
186ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            disp.queryString.version = cnx->egl.eglQueryString(idpy,
187518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_VERSION);
188ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            disp.queryString.extensions = cnx->egl.eglQueryString(idpy,
189518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_EXTENSIONS);
190ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            disp.queryString.clientApi = cnx->egl.eglQueryString(idpy,
191518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_CLIENT_APIS);
192518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
193518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        } else {
194ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            ALOGW("eglInitialize(%p) failed (%s)", idpy,
195518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
196518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
197518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
198518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1994b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    // the query strings are per-display
2004b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    mVendorString.setTo(sVendorString);
2014b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    mVersionString.setTo(sVersionString);
2024b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    mClientApiString.setTo(sClientApiString);
2034b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
2047773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    // we only add extensions that exist in the implementation
2054b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    char const* start = sExtensionString;
2064b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    char const* end;
2074b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    do {
2084b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        // find the space separating this extension for the next one
2094b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        end = strchr(start, ' ');
2104b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        if (end) {
2114b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            // length of the extension string
2124b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            const size_t len = end - start;
213f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian            if (len) {
214f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                // NOTE: we could avoid the copy if we had strnstr.
215f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                const String8 ext(start, len);
216ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                // now look for this extension
217ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                if (disp.queryString.extensions) {
218ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    // if we find it, add this extension string to our list
219ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    // (and don't forget the space)
220ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    const char* match = strstr(disp.queryString.extensions, ext.string());
221ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    if (match && (match[len] == ' ' || match[len] == 0)) {
222ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                        mExtensionString.append(start, len+1);
223f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                    }
2244b9511c16195a646242eff833b0af212933b6ecaMathias Agopian                }
2254b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            }
2264b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            // process the next extension string, and skip the space.
2274b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            start = end + 1;
2284b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        }
2294b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    } while (end);
2304b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
231aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis    egl_cache_t::get()->initialize(this);
232aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis
2337773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    refs++;
2347773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    if (major != NULL)
2357773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian        *major = VERSION_MAJOR;
2367773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    if (minor != NULL)
2377773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian        *minor = VERSION_MINOR;
2387773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    return EGL_TRUE;
239518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
240518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
241518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::terminate() {
242518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
243518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
244518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
245518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (refs == 0) {
246518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
247518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
248518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
249518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // this is specific to Android, display termination is ref-counted.
250518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (refs > 1) {
251518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs--;
252518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_TRUE;
253518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
254518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
255518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_FALSE;
256ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
257ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
258ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
259ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
260ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
261ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        }
262ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        // REVISIT: it's unclear what to do if eglTerminate() fails
263ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        disp.state = egl_display_t::TERMINATED;
264ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = EGL_TRUE;
265518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
266518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
2675b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // Mark all objects remaining in the list as terminated, unless
2685b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // there are no reference to them, it which case, we're free to
2695b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // delete them.
2705b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    size_t count = objects.size();
27132397c1cd3327905173b36baa6fd1c579bc328ffSteve Block    ALOGW_IF(count, "eglTerminate() called w/ %d objects remaining", count);
2725b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2735b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        egl_object_t* o = objects.itemAt(i);
2745b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        o->destroy();
2755b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    }
2765b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian
2775b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // this marks all object handles are "terminated"
2785b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    objects.clear();
279518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
280518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    refs--;
281518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
282518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
283518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
284fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopianvoid egl_display_t::loseCurrent(egl_context_t * cur_c)
285fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian{
286fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    if (cur_c) {
287a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        egl_display_t* display = cur_c->getDisplay();
288a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        if (display) {
289a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            display->loseCurrentImpl(cur_c);
290a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        }
291a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    }
292a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian}
293fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
294a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopianvoid egl_display_t::loseCurrentImpl(egl_context_t * cur_c)
295a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian{
296a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // by construction, these are either 0 or valid (possibly terminated)
297a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it should be impossible for these to be invalid
298a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    ContextRef _cur_c(cur_c);
299a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : NULL);
300a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : NULL);
301a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
302a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    { // scope for the lock
303a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        Mutex::Autolock _l(lock);
304fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        cur_c->onLooseCurrent();
305fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
306fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    }
307a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
308a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // This cannot be called with the lock held because it might end-up
309a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // calling back into EGL (in particular when a surface is destroyed
310a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it calls ANativeWindow::disconnect
311a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_c.release();
312a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_r.release();
313a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_d.release();
314fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian}
315fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
316fb87e54a9af8bc5063ca4deebe81d90126992480Mathias AgopianEGLBoolean egl_display_t::makeCurrent(egl_context_t* c, egl_context_t* cur_c,
317fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        EGLSurface draw, EGLSurface read, EGLContext ctx,
318fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        EGLSurface impl_draw, EGLSurface impl_read, EGLContext impl_ctx)
319fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian{
320fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    EGLBoolean result;
321a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
322a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // by construction, these are either 0 or valid (possibly terminated)
323a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it should be impossible for these to be invalid
324a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    ContextRef _cur_c(cur_c);
325a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : NULL);
326a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : NULL);
327a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
328a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    { // scope for the lock
329a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        Mutex::Autolock _l(lock);
330fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        if (c) {
331a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            result = c->cnx->egl.eglMakeCurrent(
332ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    disp.dpy, impl_draw, impl_read, impl_ctx);
333a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            if (result == EGL_TRUE) {
334a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian                c->onMakeCurrent(draw, read);
335a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            }
336a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        } else {
337a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            result = cur_c->cnx->egl.eglMakeCurrent(
338ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    disp.dpy, impl_draw, impl_read, impl_ctx);
339a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            if (result == EGL_TRUE) {
340a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian                cur_c->onLooseCurrent();
341a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            }
342fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        }
343fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    }
344a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
345a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    if (result == EGL_TRUE) {
346a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // This cannot be called with the lock held because it might end-up
347a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // calling back into EGL (in particular when a surface is destroyed
348a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // it calls ANativeWindow::disconnect
349a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_c.release();
350a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_r.release();
351a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_d.release();
352a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    }
353a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
354fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    return result;
355fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian}
356518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
357518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
358518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}; // namespace android
359518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
360