121558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall/*
2518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** Copyright 2007, The Android Open Source Project
3518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
421558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall ** Licensed under the Apache License, Version 2.0 (the "License");
521558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall ** you may not use this file except in compliance with the License.
621558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall ** You may obtain a copy of the License at
7518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
821558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall **     http://www.apache.org/licenses/LICENSE-2.0
9518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
1021558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall ** Unless required by applicable law or agreed to in writing, software
1121558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall ** distributed under the License is distributed on an "AS IS" BASIS,
1221558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1321558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hall ** See the License for the specific language governing permissions and
14518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** limitations under the License.
15518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */
16518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
17b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall#define __STDC_LIMIT_MACROS 1
181508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall#define ATRACE_TAG ATRACE_TAG_GRAPHICS
19b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall
20311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian#include "egl_display.h"
214b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
2239c24a20bbc697630d2b92c251b70c04d6f9d00cMathias Agopian#include "../egl_impl.h"
2339c24a20bbc697630d2b92c251b70c04d6f9d00cMathias Agopian
24b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian#include <private/EGL/display.h>
25b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
26aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis#include "egl_cache.h"
27518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_object.h"
28518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_tls.h"
2965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#include "egl_trace.h"
30518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "Loader.h"
317db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian#include <cutils/properties.h>
32311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian
33518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
34518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiannamespace android {
35518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
36518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
374b9511c16195a646242eff833b0af212933b6ecaMathias Agopianstatic char const * const sVendorString     = "Android";
384b9511c16195a646242eff833b0af212933b6ecaMathias Agopianstatic char const * const sVersionString    = "1.4 Android META-EGL";
39cc2b1560e87369676a2d13f17bd1ff4021a91819Mathias Agopianstatic char const * const sClientApiString  = "OpenGL_ES";
404b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
4121558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hallextern char const * const gBuiltinExtensionString;
42e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopianextern char const * const gExtensionString;
434b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
44518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern void setGLHooksThreadSpecific(gl_hooks_t const *value);
45518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
46518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
47518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
48c2e41222bf02a6579763974f82d65875cfa43481Jesse Hallstatic bool findExtension(const char* exts, const char* name, size_t nameLen) {
49c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    if (exts) {
507804aa25c1288002269d4bd29f535cad8b55f365Kalle Raita        for (const char* match = strstr(exts, name); match; match = strstr(match + nameLen, name)) {
517804aa25c1288002269d4bd29f535cad8b55f365Kalle Raita            if (match[nameLen] == '\0' || match[nameLen] == ' ') {
527804aa25c1288002269d4bd29f535cad8b55f365Kalle Raita                return true;
537804aa25c1288002269d4bd29f535cad8b55f365Kalle Raita            }
54c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        }
55c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    }
56c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    return false;
57c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall}
58c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall
59b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopianint egl_get_init_count(EGLDisplay dpy) {
60b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    egl_display_t* eglDisplay = egl_display_t::get(dpy);
61b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    return eglDisplay ? eglDisplay->getRefsCount() : 0;
62b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
63b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
64518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
65518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
66518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::egl_display_t() :
6754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    magic('_dpy'), finishOnSwap(false), traceGpuCompletion(false), refs(0), eglIsInitialized(false) {
68518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
69518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
70518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::~egl_display_t() {
71518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    magic = 0;
72766010858ea7696d64f1b559413670bdd8627595Jamie Gennis    egl_cache_t::get()->terminate();
73518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
74518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
75518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t* egl_display_t::get(EGLDisplay dpy) {
76518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    uintptr_t index = uintptr_t(dpy)-1U;
77d6e9946cdd57a92c9bc86ba97a4ca42078153008Jesse Hall    if (index >= NUM_DISPLAYS || !sDisplay[index].isValid()) {
78d6e9946cdd57a92c9bc86ba97a4ca42078153008Jesse Hall        return nullptr;
79d6e9946cdd57a92c9bc86ba97a4ca42078153008Jesse Hall    }
80d6e9946cdd57a92c9bc86ba97a4ca42078153008Jesse Hall    return &sDisplay[index];
81518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
82518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
83518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_display_t::addObject(egl_object_t* object) {
8465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::lock_guard<std::mutex> _l(lock);
8565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    objects.insert(object);
86518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
87518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
885b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianvoid egl_display_t::removeObject(egl_object_t* object) {
8965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::lock_guard<std::mutex> _l(lock);
9065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    objects.erase(object);
91518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
92518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
93f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopianbool egl_display_t::getObject(egl_object_t* object) const {
9465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::lock_guard<std::mutex> _l(lock);
9565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    if (objects.find(object) != objects.end()) {
96f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        if (object->getDisplay() == this) {
97f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian            object->incRef();
98f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian            return true;
99f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        }
100518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
101518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return false;
102518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
103518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) {
105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (uintptr_t(disp) >= NUM_DISPLAYS)
106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return NULL;
107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
108518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return sDisplay[uintptr_t(disp)].getDisplay(disp);
109518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
110518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
111518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {
112518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
11365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::lock_guard<std::mutex> _l(lock);
1141508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall    ATRACE_CALL();
115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
116518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // get our driver loader
117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Loader& loader(Loader::getInstance());
118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
119ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
120ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && disp.dpy == EGL_NO_DISPLAY) {
121ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
122ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        disp.dpy = dpy;
123ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        if (dpy == EGL_NO_DISPLAY) {
124ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            loader.close(cnx->dso);
125ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            cnx->dso = NULL;
126518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
127518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
128518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
129518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGLDisplay(uintptr_t(display) + 1U);
130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
132518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
133518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
13465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    { // scope for refLock
13565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::unique_lock<std::mutex> _l(refLock);
136518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs++;
13754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (refs > 1) {
13854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            if (major != NULL)
13954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                *major = VERSION_MAJOR;
14054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            if (minor != NULL)
14154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                *minor = VERSION_MINOR;
14265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            while(!eglIsInitialized) {
14365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian                refCond.wait(_l);
14465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            }
14554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            return EGL_TRUE;
14654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
14765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        while(eglIsInitialized) {
14865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            refCond.wait(_l);
14965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        }
150518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
151518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
15265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    { // scope for lock
15365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::lock_guard<std::mutex> _l(lock);
15454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
15554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        setGLHooksThreadSpecific(&gHooksNoContext);
15654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
15754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // initialize each EGL and
15854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // build our own extension string first, based on the extension we know
15954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // and the extension supported by our client implementation
16054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
16154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        egl_connection_t* const cnx = &gEGLImpl;
16254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        cnx->major = -1;
16354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        cnx->minor = -1;
16454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (cnx->dso) {
16554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            EGLDisplay idpy = disp.dpy;
16654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
16754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                //ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
16854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                //        idpy, cnx->major, cnx->minor, cnx);
16954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
17054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                // display is now initialized
17154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.state = egl_display_t::INITIALIZED;
17254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
17354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                // get the query-strings for this display for each implementation
17454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.queryString.vendor = cnx->egl.eglQueryString(idpy,
17554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        EGL_VENDOR);
17654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.queryString.version = cnx->egl.eglQueryString(idpy,
17754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        EGL_VERSION);
17854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.queryString.extensions = cnx->egl.eglQueryString(idpy,
17954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        EGL_EXTENSIONS);
18054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.queryString.clientApi = cnx->egl.eglQueryString(idpy,
18154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        EGL_CLIENT_APIS);
18254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
18354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            } else {
18454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                ALOGW("eglInitialize(%p) failed (%s)", idpy,
18554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
18654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            }
187518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
188518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
18954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // the query strings are per-display
19065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        mVendorString = sVendorString;
19165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        mVersionString = sVersionString;
19265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        mClientApiString = sClientApiString;
19354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
19465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        mExtensionString = gBuiltinExtensionString;
19554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        char const* start = gExtensionString;
19654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        do {
197ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens            // length of the extension name
198ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens            size_t len = strcspn(start, " ");
199ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens            if (len) {
200ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                // NOTE: we could avoid the copy if we had strnstr.
20165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian                const std::string ext(start, len);
20265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian                if (findExtension(disp.queryString.extensions, ext.c_str(), len)) {
203ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                    mExtensionString.append(ext + " ");
2044b9511c16195a646242eff833b0af212933b6ecaMathias Agopian                }
205ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                // advance to the next extension name, skipping the space.
206ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                start += len;
207ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                start += (*start == ' ') ? 1 : 0;
2084b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            }
209ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens        } while (*start != '\0');
21054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
21154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        egl_cache_t::get()->initialize(this);
21254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
21354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        char value[PROPERTY_VALUE_MAX];
21454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        property_get("debug.egl.finish", value, "0");
21554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (atoi(value)) {
21654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            finishOnSwap = true;
2174b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        }
2184b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
21954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        property_get("debug.egl.traceGpuCompletion", value, "0");
22054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (atoi(value)) {
22154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            traceGpuCompletion = true;
22254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
223aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis
22454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (major != NULL)
22554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            *major = VERSION_MAJOR;
22654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (minor != NULL)
22754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            *minor = VERSION_MINOR;
22828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    }
22928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
23065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    { // scope for refLock
23165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::unique_lock<std::mutex> _l(refLock);
23254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        eglIsInitialized = true;
23365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        refCond.notify_all();
23454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    }
235a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
2367773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    return EGL_TRUE;
237518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
238518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
239518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::terminate() {
240518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
24165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    { // scope for refLock
24265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::unique_lock<std::mutex> _rl(refLock);
24354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (refs == 0) {
24454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            /*
24554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             * From the EGL spec (3.2):
24654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             * "Termination of a display that has already been terminated,
24754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             *  (...), is allowed, but the only effect of such a call is
24854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             *  to return EGL_TRUE (...)
24954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             */
25054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            return EGL_TRUE;
25154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
252518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
25354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // this is specific to Android, display termination is ref-counted.
254518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs--;
25554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (refs > 0) {
25654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            return EGL_TRUE;
25754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
258518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
259518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
260518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_FALSE;
26154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
26265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    { // scope for lock
26365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::lock_guard<std::mutex> _l(lock);
26454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
26554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        egl_connection_t* const cnx = &gEGLImpl;
26654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
26754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
26854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
26954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
27054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            }
27154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            // REVISIT: it's unclear what to do if eglTerminate() fails
27254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            disp.state = egl_display_t::TERMINATED;
27354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            res = EGL_TRUE;
274ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        }
275518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
27654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // Reset the extension string since it will be regenerated if we get
27754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // reinitialized.
27865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        mExtensionString.clear();
279a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
28054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // Mark all objects remaining in the list as terminated, unless
28154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // there are no reference to them, it which case, we're free to
28254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // delete them.
28354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        size_t count = objects.size();
284eacd31f41ef1851bb420c65552b1aed6b74abe29Dan Albert        ALOGW_IF(count, "eglTerminate() called w/ %zu objects remaining", count);
28565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        for (auto o : objects) {
28654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            o->destroy();
28754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
288a08cf6e3a4ee045608bc8991a779dedb4f281a3fJamie Gennis
28954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // this marks all object handles are "terminated"
29054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        objects.clear();
2915b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    }
2925b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian
29365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    { // scope for refLock
29465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::unique_lock<std::mutex> _rl(refLock);
29554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        eglIsInitialized = false;
29665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        refCond.notify_all();
29754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    }
298518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
299518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
300518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
301518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
302fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopianvoid egl_display_t::loseCurrent(egl_context_t * cur_c)
303fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian{
304fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    if (cur_c) {
305a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        egl_display_t* display = cur_c->getDisplay();
306a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        if (display) {
307a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            display->loseCurrentImpl(cur_c);
308a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        }
309a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    }
310a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian}
311fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
312a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopianvoid egl_display_t::loseCurrentImpl(egl_context_t * cur_c)
313a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian{
314a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // by construction, these are either 0 or valid (possibly terminated)
315a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it should be impossible for these to be invalid
316a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    ContextRef _cur_c(cur_c);
317a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : NULL);
318a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : NULL);
319a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
320a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    { // scope for the lock
32165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::lock_guard<std::mutex> _l(lock);
322fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        cur_c->onLooseCurrent();
323fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
324fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    }
325a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
326a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // This cannot be called with the lock held because it might end-up
327a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // calling back into EGL (in particular when a surface is destroyed
328a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it calls ANativeWindow::disconnect
329a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_c.release();
330a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_r.release();
331a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_d.release();
332fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian}
333fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
334fb87e54a9af8bc5063ca4deebe81d90126992480Mathias AgopianEGLBoolean egl_display_t::makeCurrent(egl_context_t* c, egl_context_t* cur_c,
33592dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        EGLSurface draw, EGLSurface read, EGLContext /*ctx*/,
336fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        EGLSurface impl_draw, EGLSurface impl_read, EGLContext impl_ctx)
337fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian{
338fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    EGLBoolean result;
339a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
340a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // by construction, these are either 0 or valid (possibly terminated)
341a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it should be impossible for these to be invalid
342a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    ContextRef _cur_c(cur_c);
343a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : NULL);
344a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : NULL);
345a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
346a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    { // scope for the lock
34765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::lock_guard<std::mutex> _l(lock);
348fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        if (c) {
349a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            result = c->cnx->egl.eglMakeCurrent(
350ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    disp.dpy, impl_draw, impl_read, impl_ctx);
351a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            if (result == EGL_TRUE) {
352a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian                c->onMakeCurrent(draw, read);
353a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            }
354a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        } else {
355a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            result = cur_c->cnx->egl.eglMakeCurrent(
356ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    disp.dpy, impl_draw, impl_read, impl_ctx);
357a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            if (result == EGL_TRUE) {
358a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian                cur_c->onLooseCurrent();
359a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            }
360fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        }
361fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    }
362a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
363a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    if (result == EGL_TRUE) {
364a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // This cannot be called with the lock held because it might end-up
365a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // calling back into EGL (in particular when a surface is destroyed
366a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // it calls ANativeWindow::disconnect
367a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_c.release();
368a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_r.release();
369a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_d.release();
370a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    }
371a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
372fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    return result;
373fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian}
374518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
375c2e41222bf02a6579763974f82d65875cfa43481Jesse Hallbool egl_display_t::haveExtension(const char* name, size_t nameLen) const {
376c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    if (!nameLen) {
377c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        nameLen = strlen(name);
378c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    }
37965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    return findExtension(mExtensionString.c_str(), name, nameLen);
380c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall}
381c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall
382a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall// ----------------------------------------------------------------------------
383518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}; // namespace android
384518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
385