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
33e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
34e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter#include <configstore/Utils.h>
35e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter
36e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchterusing namespace android::hardware::configstore;
37e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchterusing namespace android::hardware::configstore::V1_0;
38e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter
39518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
40518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiannamespace android {
41518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
42518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
434b9511c16195a646242eff833b0af212933b6ecaMathias Agopianstatic char const * const sVendorString     = "Android";
444b9511c16195a646242eff833b0af212933b6ecaMathias Agopianstatic char const * const sVersionString    = "1.4 Android META-EGL";
45cc2b1560e87369676a2d13f17bd1ff4021a91819Mathias Agopianstatic char const * const sClientApiString  = "OpenGL_ES";
464b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
4721558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hallextern char const * const gBuiltinExtensionString;
48e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopianextern char const * const gExtensionString;
494b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
50518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern void setGLHooksThreadSpecific(gl_hooks_t const *value);
51518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
52518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
53518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
54a1e59f106f84a95f8d27eb5116a88c122039fe1bCourtney Goeltzenleuchterbool findExtension(const char* exts, const char* name, size_t nameLen) {
55c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    if (exts) {
56a1e59f106f84a95f8d27eb5116a88c122039fe1bCourtney Goeltzenleuchter        if (!nameLen) {
57a1e59f106f84a95f8d27eb5116a88c122039fe1bCourtney Goeltzenleuchter            nameLen = strlen(name);
58a1e59f106f84a95f8d27eb5116a88c122039fe1bCourtney Goeltzenleuchter        }
597804aa25c1288002269d4bd29f535cad8b55f365Kalle Raita        for (const char* match = strstr(exts, name); match; match = strstr(match + nameLen, name)) {
607804aa25c1288002269d4bd29f535cad8b55f365Kalle Raita            if (match[nameLen] == '\0' || match[nameLen] == ' ') {
617804aa25c1288002269d4bd29f535cad8b55f365Kalle Raita                return true;
627804aa25c1288002269d4bd29f535cad8b55f365Kalle Raita            }
63c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        }
64c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    }
65c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    return false;
66c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall}
67c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall
68b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopianint egl_get_init_count(EGLDisplay dpy) {
69b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    egl_display_t* eglDisplay = egl_display_t::get(dpy);
70b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian    return eglDisplay ? eglDisplay->getRefsCount() : 0;
71b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian}
72b7f9a2400aaa2e0d29ffefd91576e90036d4cf83Mathias Agopian
73518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
74518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
75518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::egl_display_t() :
7654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    magic('_dpy'), finishOnSwap(false), traceGpuCompletion(false), refs(0), eglIsInitialized(false) {
77518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
78518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
79518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::~egl_display_t() {
80518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    magic = 0;
81766010858ea7696d64f1b559413670bdd8627595Jamie Gennis    egl_cache_t::get()->terminate();
82518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
83518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
84518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t* egl_display_t::get(EGLDisplay dpy) {
857025b54d8ac4b108c93b45958f7776c9098f6394Ivan Lozano    if (uintptr_t(dpy) == 0) {
867025b54d8ac4b108c93b45958f7776c9098f6394Ivan Lozano        return nullptr;
877025b54d8ac4b108c93b45958f7776c9098f6394Ivan Lozano    }
887025b54d8ac4b108c93b45958f7776c9098f6394Ivan Lozano
89518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    uintptr_t index = uintptr_t(dpy)-1U;
90d6e9946cdd57a92c9bc86ba97a4ca42078153008Jesse Hall    if (index >= NUM_DISPLAYS || !sDisplay[index].isValid()) {
91d6e9946cdd57a92c9bc86ba97a4ca42078153008Jesse Hall        return nullptr;
92d6e9946cdd57a92c9bc86ba97a4ca42078153008Jesse Hall    }
93d6e9946cdd57a92c9bc86ba97a4ca42078153008Jesse Hall    return &sDisplay[index];
94518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
95518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
96518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_display_t::addObject(egl_object_t* object) {
9765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::lock_guard<std::mutex> _l(lock);
9865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    objects.insert(object);
99518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
100518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
1015b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianvoid egl_display_t::removeObject(egl_object_t* object) {
10265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::lock_guard<std::mutex> _l(lock);
10365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    objects.erase(object);
104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
106f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopianbool egl_display_t::getObject(egl_object_t* object) const {
10765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::lock_guard<std::mutex> _l(lock);
10865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    if (objects.find(object) != objects.end()) {
109f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        if (object->getDisplay() == this) {
110f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian            object->incRef();
111f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian            return true;
112f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        }
113518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return false;
115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
116518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) {
118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (uintptr_t(disp) >= NUM_DISPLAYS)
119518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return NULL;
120518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
121518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return sDisplay[uintptr_t(disp)].getDisplay(disp);
122518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
123518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
124518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {
125518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
12665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    std::lock_guard<std::mutex> _l(lock);
1271508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall    ATRACE_CALL();
128518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
129518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // get our driver loader
130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Loader& loader(Loader::getInstance());
131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
132ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
133ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && disp.dpy == EGL_NO_DISPLAY) {
134ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
135ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        disp.dpy = dpy;
136ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        if (dpy == EGL_NO_DISPLAY) {
137ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            loader.close(cnx->dso);
138ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            cnx->dso = NULL;
139518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
142518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGLDisplay(uintptr_t(display) + 1U);
143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
146518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
14765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    { // scope for refLock
14865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::unique_lock<std::mutex> _l(refLock);
149518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs++;
15054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (refs > 1) {
15154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            if (major != NULL)
15254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                *major = VERSION_MAJOR;
15354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            if (minor != NULL)
15454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                *minor = VERSION_MINOR;
15565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            while(!eglIsInitialized) {
15665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian                refCond.wait(_l);
15765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            }
15854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            return EGL_TRUE;
15954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
16065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        while(eglIsInitialized) {
16165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian            refCond.wait(_l);
16265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        }
163518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
164518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
16565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    { // scope for lock
16665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::lock_guard<std::mutex> _l(lock);
16754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
16854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        setGLHooksThreadSpecific(&gHooksNoContext);
16954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
17054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // initialize each EGL and
17154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // build our own extension string first, based on the extension we know
17254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // and the extension supported by our client implementation
17354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
17454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        egl_connection_t* const cnx = &gEGLImpl;
17554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        cnx->major = -1;
17654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        cnx->minor = -1;
17754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (cnx->dso) {
17854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            EGLDisplay idpy = disp.dpy;
17954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
18054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                //ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
18154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                //        idpy, cnx->major, cnx->minor, cnx);
18254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
18354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                // display is now initialized
18454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.state = egl_display_t::INITIALIZED;
18554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
18654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                // get the query-strings for this display for each implementation
18754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.queryString.vendor = cnx->egl.eglQueryString(idpy,
18854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        EGL_VENDOR);
18954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.queryString.version = cnx->egl.eglQueryString(idpy,
19054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        EGL_VERSION);
19154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.queryString.extensions = cnx->egl.eglQueryString(idpy,
19254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        EGL_EXTENSIONS);
19354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.queryString.clientApi = cnx->egl.eglQueryString(idpy,
19454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        EGL_CLIENT_APIS);
19554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
19654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            } else {
19754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                ALOGW("eglInitialize(%p) failed (%s)", idpy,
19854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
19954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            }
200518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
201518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
20254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // the query strings are per-display
20365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        mVendorString = sVendorString;
20465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        mVersionString = sVersionString;
20565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        mClientApiString = sClientApiString;
20654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
20765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        mExtensionString = gBuiltinExtensionString;
208e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter
209f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        hasColorSpaceSupport = findExtension(disp.queryString.extensions, "EGL_KHR_gl_colorspace");
210f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński
211f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // Note: CDD requires that devices supporting wide color and/or HDR color also support
212f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        // the EGL_KHR_gl_colorspace extension.
213e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter        bool wideColorBoardConfig =
214e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(
215e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                        false);
216e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter
217e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter        // Add wide-color extensions if device can support wide-color
218f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        if (wideColorBoardConfig && hasColorSpaceSupport) {
219e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter            mExtensionString.append(
220e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    "EGL_EXT_gl_colorspace_scrgb EGL_EXT_gl_colorspace_scrgb_linear "
221e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter                    "EGL_EXT_gl_colorspace_display_p3_linear EGL_EXT_gl_colorspace_display_p3 ");
222e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter        }
223e5d6f994158d554c692afae0f547d89c75abde71Courtney Goeltzenleuchter
22412ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter        bool hasHdrBoardConfig =
22512ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter                getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false);
22612ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter
227f2fc4e9780bdfbf30511f44f6722b6af7bb3baa3Krzysztof Kosiński        if (hasHdrBoardConfig && hasColorSpaceSupport) {
22812ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter            // hasHDRBoardConfig indicates the system is capable of supporting HDR content.
22912ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter            // Typically that means there is an HDR capable display attached, but could be
23012ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter            // support for attaching an HDR display. In either case, advertise support for
23112ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter            // HDR color spaces.
23212ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter            mExtensionString.append(
23312ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter                    "EGL_EXT_gl_colorspace_bt2020_linear EGL_EXT_gl_colorspace_bt2020_pq ");
23412ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter        }
23512ffe0966f5969a16a90e7ead838b21b96283c16Courtney Goeltzenleuchter
23654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        char const* start = gExtensionString;
23754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        do {
238ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens            // length of the extension name
239ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens            size_t len = strcspn(start, " ");
240ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens            if (len) {
241ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                // NOTE: we could avoid the copy if we had strnstr.
24265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian                const std::string ext(start, len);
243b18333d93d5f19d73af2ff36e73e9f32ce3c59b4Krzysztof Kosiński                // Temporary hack: Adreno 530 driver exposes this extension under the draft
244b18333d93d5f19d73af2ff36e73e9f32ce3c59b4Krzysztof Kosiński                // KHR name, but during Khronos review it was decided to demote it to EXT.
245b18333d93d5f19d73af2ff36e73e9f32ce3c59b4Krzysztof Kosiński                if (ext == "EGL_EXT_image_gl_colorspace" &&
246b18333d93d5f19d73af2ff36e73e9f32ce3c59b4Krzysztof Kosiński                    findExtension(disp.queryString.extensions, "EGL_KHR_image_gl_colorspace")) {
247b18333d93d5f19d73af2ff36e73e9f32ce3c59b4Krzysztof Kosiński                    mExtensionString.append("EGL_EXT_image_gl_colorspace ");
248b18333d93d5f19d73af2ff36e73e9f32ce3c59b4Krzysztof Kosiński                }
24965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian                if (findExtension(disp.queryString.extensions, ext.c_str(), len)) {
250ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                    mExtensionString.append(ext + " ");
2514b9511c16195a646242eff833b0af212933b6ecaMathias Agopian                }
252ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                // advance to the next extension name, skipping the space.
253ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                start += len;
254ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                start += (*start == ' ') ? 1 : 0;
2554b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            }
256ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens        } while (*start != '\0');
25754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
25854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        egl_cache_t::get()->initialize(this);
25954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
26054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        char value[PROPERTY_VALUE_MAX];
26154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        property_get("debug.egl.finish", value, "0");
26254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (atoi(value)) {
26354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            finishOnSwap = true;
2644b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        }
2654b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
26654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        property_get("debug.egl.traceGpuCompletion", value, "0");
26754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (atoi(value)) {
26854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            traceGpuCompletion = true;
26954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
270aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis
27154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (major != NULL)
27254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            *major = VERSION_MAJOR;
27354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (minor != NULL)
27454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            *minor = VERSION_MINOR;
27528ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    }
27628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
27765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    { // scope for refLock
27865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::unique_lock<std::mutex> _l(refLock);
27954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        eglIsInitialized = true;
28065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        refCond.notify_all();
28154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    }
282a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
2837773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    return EGL_TRUE;
284518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
285518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
286518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::terminate() {
287518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
28865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    { // scope for refLock
28965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::unique_lock<std::mutex> _rl(refLock);
29054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (refs == 0) {
29154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            /*
29254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             * From the EGL spec (3.2):
29354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             * "Termination of a display that has already been terminated,
29454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             *  (...), is allowed, but the only effect of such a call is
29554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             *  to return EGL_TRUE (...)
29654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             */
29754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            return EGL_TRUE;
29854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
299518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
30054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // this is specific to Android, display termination is ref-counted.
301518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs--;
30254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (refs > 0) {
30354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            return EGL_TRUE;
30454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
305518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
306518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
307518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_FALSE;
30854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
30965421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    { // scope for lock
31065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::lock_guard<std::mutex> _l(lock);
31154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
31254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        egl_connection_t* const cnx = &gEGLImpl;
31354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
31454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
31554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
31654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
31754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            }
31854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            // REVISIT: it's unclear what to do if eglTerminate() fails
31954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            disp.state = egl_display_t::TERMINATED;
32054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            res = EGL_TRUE;
321ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        }
322518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
32354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // Reset the extension string since it will be regenerated if we get
32454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // reinitialized.
32565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        mExtensionString.clear();
326a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
32754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // Mark all objects remaining in the list as terminated, unless
32854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // there are no reference to them, it which case, we're free to
32954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // delete them.
33054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        size_t count = objects.size();
331eacd31f41ef1851bb420c65552b1aed6b74abe29Dan Albert        ALOGW_IF(count, "eglTerminate() called w/ %zu objects remaining", count);
33265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        for (auto o : objects) {
33354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            o->destroy();
33454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
335a08cf6e3a4ee045608bc8991a779dedb4f281a3fJamie Gennis
33654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // this marks all object handles are "terminated"
33754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        objects.clear();
3385b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    }
3395b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian
34065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    { // scope for refLock
34165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::unique_lock<std::mutex> _rl(refLock);
34254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        eglIsInitialized = false;
34365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        refCond.notify_all();
34454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    }
345518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
346518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
347518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
348518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
349fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopianvoid egl_display_t::loseCurrent(egl_context_t * cur_c)
350fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian{
351fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    if (cur_c) {
352a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        egl_display_t* display = cur_c->getDisplay();
353a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        if (display) {
354a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            display->loseCurrentImpl(cur_c);
355a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        }
356a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    }
357a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian}
358fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
359a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopianvoid egl_display_t::loseCurrentImpl(egl_context_t * cur_c)
360a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian{
361a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // by construction, these are either 0 or valid (possibly terminated)
362a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it should be impossible for these to be invalid
363a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    ContextRef _cur_c(cur_c);
364a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : NULL);
365a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : NULL);
366a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
367a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    { // scope for the lock
36865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::lock_guard<std::mutex> _l(lock);
369fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        cur_c->onLooseCurrent();
370fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
371fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    }
372a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
373a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // This cannot be called with the lock held because it might end-up
374a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // calling back into EGL (in particular when a surface is destroyed
375a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it calls ANativeWindow::disconnect
376a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_c.release();
377a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_r.release();
378a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_d.release();
379fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian}
380fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
381fb87e54a9af8bc5063ca4deebe81d90126992480Mathias AgopianEGLBoolean egl_display_t::makeCurrent(egl_context_t* c, egl_context_t* cur_c,
38292dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        EGLSurface draw, EGLSurface read, EGLContext /*ctx*/,
383fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        EGLSurface impl_draw, EGLSurface impl_read, EGLContext impl_ctx)
384fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian{
385fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    EGLBoolean result;
386a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
387a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // by construction, these are either 0 or valid (possibly terminated)
388a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it should be impossible for these to be invalid
389a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    ContextRef _cur_c(cur_c);
390a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : NULL);
391a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : NULL);
392a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
393a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    { // scope for the lock
39465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian        std::lock_guard<std::mutex> _l(lock);
395fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        if (c) {
396a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            result = c->cnx->egl.eglMakeCurrent(
397ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    disp.dpy, impl_draw, impl_read, impl_ctx);
398a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            if (result == EGL_TRUE) {
399a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian                c->onMakeCurrent(draw, read);
400a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            }
401a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        } else {
402a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            result = cur_c->cnx->egl.eglMakeCurrent(
403ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    disp.dpy, impl_draw, impl_read, impl_ctx);
404a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            if (result == EGL_TRUE) {
405a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian                cur_c->onLooseCurrent();
406a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            }
407fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        }
408fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    }
409a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
410a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    if (result == EGL_TRUE) {
411a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // This cannot be called with the lock held because it might end-up
412a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // calling back into EGL (in particular when a surface is destroyed
413a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // it calls ANativeWindow::disconnect
414a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_c.release();
415a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_r.release();
416a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_d.release();
417a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    }
418a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
419fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    return result;
420fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian}
421518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
422c2e41222bf02a6579763974f82d65875cfa43481Jesse Hallbool egl_display_t::haveExtension(const char* name, size_t nameLen) const {
423c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    if (!nameLen) {
424c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        nameLen = strlen(name);
425c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    }
42665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian    return findExtension(mExtensionString.c_str(), name, nameLen);
427c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall}
428c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall
429a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall// ----------------------------------------------------------------------------
430518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}; // namespace android
431518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
432