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
18b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall
194b9511c16195a646242eff833b0af212933b6ecaMathias Agopian#include <string.h>
204b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
2139c24a20bbc697630d2b92c251b70c04d6f9d00cMathias Agopian#include "../egl_impl.h"
2239c24a20bbc697630d2b92c251b70c04d6f9d00cMathias Agopian
23aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis#include "egl_cache.h"
24518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_display.h"
25518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_object.h"
26518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_tls.h"
27518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "Loader.h"
287db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian#include <cutils/properties.h>
29518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
30518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
31518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiannamespace android {
32518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
33518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
344b9511c16195a646242eff833b0af212933b6ecaMathias Agopianstatic char const * const sVendorString     = "Android";
354b9511c16195a646242eff833b0af212933b6ecaMathias Agopianstatic char const * const sVersionString    = "1.4 Android META-EGL";
36cc2b1560e87369676a2d13f17bd1ff4021a91819Mathias Agopianstatic char const * const sClientApiString  = "OpenGL_ES";
374b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
3821558daf691dbcdff4a41e659fd013273db4d0b7Jesse Hallextern char const * const gBuiltinExtensionString;
39e9b3dfb7d5cc233747407381a51a081c335dc076Mathias Agopianextern char const * const gExtensionString;
404b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
41518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern void setGLHooksThreadSpecific(gl_hooks_t const *value);
42518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
43518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
44518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
45c2e41222bf02a6579763974f82d65875cfa43481Jesse Hallstatic bool findExtension(const char* exts, const char* name, size_t nameLen) {
46c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    if (exts) {
477804aa25c1288002269d4bd29f535cad8b55f365Kalle Raita        for (const char* match = strstr(exts, name); match; match = strstr(match + nameLen, name)) {
487804aa25c1288002269d4bd29f535cad8b55f365Kalle Raita            if (match[nameLen] == '\0' || match[nameLen] == ' ') {
497804aa25c1288002269d4bd29f535cad8b55f365Kalle Raita                return true;
507804aa25c1288002269d4bd29f535cad8b55f365Kalle Raita            }
51c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        }
52c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    }
53c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    return false;
54c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall}
55c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall
56518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
57518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
58518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::egl_display_t() :
5954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    magic('_dpy'), finishOnSwap(false), traceGpuCompletion(false), refs(0), eglIsInitialized(false) {
60518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
61518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
62518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::~egl_display_t() {
63518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    magic = 0;
64766010858ea7696d64f1b559413670bdd8627595Jamie Gennis    egl_cache_t::get()->terminate();
65518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
66518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
67518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t* egl_display_t::get(EGLDisplay dpy) {
68518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    uintptr_t index = uintptr_t(dpy)-1U;
69d6e9946cdd57a92c9bc86ba97a4ca42078153008Jesse Hall    if (index >= NUM_DISPLAYS || !sDisplay[index].isValid()) {
70d6e9946cdd57a92c9bc86ba97a4ca42078153008Jesse Hall        return nullptr;
71d6e9946cdd57a92c9bc86ba97a4ca42078153008Jesse Hall    }
72d6e9946cdd57a92c9bc86ba97a4ca42078153008Jesse Hall    return &sDisplay[index];
73518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
74518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
75518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_display_t::addObject(egl_object_t* object) {
76518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
77518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    objects.add(object);
78518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
79518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
805b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianvoid egl_display_t::removeObject(egl_object_t* object) {
81518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
825b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    objects.remove(object);
83518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
84518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
85f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopianbool egl_display_t::getObject(egl_object_t* object) const {
86518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
875b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (objects.indexOf(object) >= 0) {
88f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        if (object->getDisplay() == this) {
89f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian            object->incRef();
90f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian            return true;
91f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        }
92518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
93518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return false;
94518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
95518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
96518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) {
97518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (uintptr_t(disp) >= NUM_DISPLAYS)
98518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return NULL;
99518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
100518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return sDisplay[uintptr_t(disp)].getDisplay(disp);
101518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
102518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
103518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {
104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // get our driver loader
108518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Loader& loader(Loader::getInstance());
109518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
110ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
111ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && disp.dpy == EGL_NO_DISPLAY) {
112ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
113ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        disp.dpy = dpy;
114ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        if (dpy == EGL_NO_DISPLAY) {
115ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            loader.close(cnx->dso);
116ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            cnx->dso = NULL;
117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
119518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
120518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGLDisplay(uintptr_t(display) + 1U);
121518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
122518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
123518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
124518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
12554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    {
12654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        Mutex::Autolock _rf(refLock);
127518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
128518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs++;
12954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (refs > 1) {
13054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            if (major != NULL)
13154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                *major = VERSION_MAJOR;
13254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            if (minor != NULL)
13354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                *minor = VERSION_MINOR;
13454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            while(!eglIsInitialized) refCond.wait(refLock);
13554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            return EGL_TRUE;
13654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
13754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
13854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        while(eglIsInitialized) refCond.wait(refLock);
139518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
14154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    {
14254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        Mutex::Autolock _l(lock);
14354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
14454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        setGLHooksThreadSpecific(&gHooksNoContext);
14554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
14654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // initialize each EGL and
14754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // build our own extension string first, based on the extension we know
14854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // and the extension supported by our client implementation
14954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
15054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        egl_connection_t* const cnx = &gEGLImpl;
15154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        cnx->major = -1;
15254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        cnx->minor = -1;
15354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (cnx->dso) {
15454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            EGLDisplay idpy = disp.dpy;
15554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
15654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                //ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
15754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                //        idpy, cnx->major, cnx->minor, cnx);
15854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
15954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                // display is now initialized
16054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.state = egl_display_t::INITIALIZED;
16154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
16254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                // get the query-strings for this display for each implementation
16354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.queryString.vendor = cnx->egl.eglQueryString(idpy,
16454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        EGL_VENDOR);
16554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.queryString.version = cnx->egl.eglQueryString(idpy,
16654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        EGL_VERSION);
16754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.queryString.extensions = cnx->egl.eglQueryString(idpy,
16854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        EGL_EXTENSIONS);
16954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                disp.queryString.clientApi = cnx->egl.eglQueryString(idpy,
17054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        EGL_CLIENT_APIS);
17154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
17254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            } else {
17354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                ALOGW("eglInitialize(%p) failed (%s)", idpy,
17454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
17554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            }
176518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
177518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
17854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // the query strings are per-display
17954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        mVendorString.setTo(sVendorString);
18054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        mVersionString.setTo(sVersionString);
18154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        mClientApiString.setTo(sClientApiString);
18254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
18354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        mExtensionString.setTo(gBuiltinExtensionString);
18454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        char const* start = gExtensionString;
18554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        do {
186ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens            // length of the extension name
187ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens            size_t len = strcspn(start, " ");
188ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens            if (len) {
189ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                // NOTE: we could avoid the copy if we had strnstr.
190ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                const String8 ext(start, len);
191ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                if (findExtension(disp.queryString.extensions, ext.string(),
192ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                        len)) {
193ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                    mExtensionString.append(ext + " ");
1944b9511c16195a646242eff833b0af212933b6ecaMathias Agopian                }
195ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                // advance to the next extension name, skipping the space.
196ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                start += len;
197ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens                start += (*start == ' ') ? 1 : 0;
1984b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            }
199ecc0c9aa412aaf463d91bedcf53f881536a6d560Nicolas Capens        } while (*start != '\0');
20054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
20154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        egl_cache_t::get()->initialize(this);
20254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
20354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        char value[PROPERTY_VALUE_MAX];
20454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        property_get("debug.egl.finish", value, "0");
20554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (atoi(value)) {
20654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            finishOnSwap = true;
2074b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        }
2084b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
20954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        property_get("debug.egl.traceGpuCompletion", value, "0");
21054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (atoi(value)) {
21154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            traceGpuCompletion = true;
21254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
213aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis
21454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (major != NULL)
21554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            *major = VERSION_MAJOR;
21654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (minor != NULL)
21754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            *minor = VERSION_MINOR;
2187db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian
21954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        mHibernation.setDisplayValid(true);
22028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    }
22128ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
22254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    {
22354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        Mutex::Autolock _rf(refLock);
22454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        eglIsInitialized = true;
22554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        refCond.broadcast();
22654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    }
227a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
2287773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    return EGL_TRUE;
229518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
230518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
231518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::terminate() {
232518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
23354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    {
23454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        Mutex::Autolock _rl(refLock);
23554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (refs == 0) {
23654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            /*
23754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             * From the EGL spec (3.2):
23854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             * "Termination of a display that has already been terminated,
23954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             *  (...), is allowed, but the only effect of such a call is
24054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             *  to return EGL_TRUE (...)
24154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine             */
24254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            return EGL_TRUE;
24354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
244518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
24554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // this is specific to Android, display termination is ref-counted.
246518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs--;
24754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (refs > 0) {
24854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            return EGL_TRUE;
24954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
250518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
251518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
252518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_FALSE;
25354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
25454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    {
25554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        Mutex::Autolock _l(lock);
25654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
25754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        egl_connection_t* const cnx = &gEGLImpl;
25854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
25954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
26054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
26154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine                        egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
26254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            }
26354466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            // REVISIT: it's unclear what to do if eglTerminate() fails
26454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            disp.state = egl_display_t::TERMINATED;
26554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            res = EGL_TRUE;
266ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        }
267518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
26854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        mHibernation.setDisplayValid(false);
26954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine
27054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // Reset the extension string since it will be regenerated if we get
27154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // reinitialized.
27254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        mExtensionString.setTo("");
273a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
27454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // Mark all objects remaining in the list as terminated, unless
27554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // there are no reference to them, it which case, we're free to
27654466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // delete them.
27754466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        size_t count = objects.size();
278eacd31f41ef1851bb420c65552b1aed6b74abe29Dan Albert        ALOGW_IF(count, "eglTerminate() called w/ %zu objects remaining", count);
27954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        for (size_t i=0 ; i<count ; i++) {
28054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            egl_object_t* o = objects.itemAt(i);
28154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine            o->destroy();
28254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        }
283a08cf6e3a4ee045608bc8991a779dedb4f281a3fJamie Gennis
28454466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        // this marks all object handles are "terminated"
28554466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        objects.clear();
2865b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    }
2875b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian
28854466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    {
28954466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        Mutex::Autolock _rl(refLock);
29054466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        eglIsInitialized = false;
29154466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine        refCond.broadcast();
29254466bc4412acf33a59af59d9eadde54c22b2ebeMichael Lentine    }
293518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
294518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
295518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
296518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
297fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopianvoid egl_display_t::loseCurrent(egl_context_t * cur_c)
298fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian{
299fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    if (cur_c) {
300a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        egl_display_t* display = cur_c->getDisplay();
301a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        if (display) {
302a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            display->loseCurrentImpl(cur_c);
303a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        }
304a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    }
305a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian}
306fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
307a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopianvoid egl_display_t::loseCurrentImpl(egl_context_t * cur_c)
308a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian{
309a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // by construction, these are either 0 or valid (possibly terminated)
310a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it should be impossible for these to be invalid
311a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    ContextRef _cur_c(cur_c);
312a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : NULL);
313a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : NULL);
314a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
315a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    { // scope for the lock
316a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        Mutex::Autolock _l(lock);
317fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        cur_c->onLooseCurrent();
318fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
319fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    }
320a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
321a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // This cannot be called with the lock held because it might end-up
322a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // calling back into EGL (in particular when a surface is destroyed
323a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it calls ANativeWindow::disconnect
324a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_c.release();
325a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_r.release();
326a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_d.release();
327fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian}
328fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
329fb87e54a9af8bc5063ca4deebe81d90126992480Mathias AgopianEGLBoolean egl_display_t::makeCurrent(egl_context_t* c, egl_context_t* cur_c,
33092dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        EGLSurface draw, EGLSurface read, EGLContext /*ctx*/,
331fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        EGLSurface impl_draw, EGLSurface impl_read, EGLContext impl_ctx)
332fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian{
333fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    EGLBoolean result;
334a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
335a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // by construction, these are either 0 or valid (possibly terminated)
336a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it should be impossible for these to be invalid
337a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    ContextRef _cur_c(cur_c);
338a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : NULL);
339a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : NULL);
340a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
341a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    { // scope for the lock
342a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        Mutex::Autolock _l(lock);
343fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        if (c) {
344a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            result = c->cnx->egl.eglMakeCurrent(
345ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    disp.dpy, impl_draw, impl_read, impl_ctx);
346a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            if (result == EGL_TRUE) {
347a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian                c->onMakeCurrent(draw, read);
348258385978c517a47626161b1e644c48bcee28de1Jesse Hall                if (!cur_c) {
349a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall                    mHibernation.incWakeCount(HibernationMachine::STRONG);
350258385978c517a47626161b1e644c48bcee28de1Jesse Hall                }
351a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            }
352a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        } else {
353a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            result = cur_c->cnx->egl.eglMakeCurrent(
354ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    disp.dpy, impl_draw, impl_read, impl_ctx);
355a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            if (result == EGL_TRUE) {
356a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian                cur_c->onLooseCurrent();
357a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall                mHibernation.decWakeCount(HibernationMachine::STRONG);
358a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            }
359fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        }
360fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    }
361a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
362a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    if (result == EGL_TRUE) {
363a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // This cannot be called with the lock held because it might end-up
364a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // calling back into EGL (in particular when a surface is destroyed
365a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // it calls ANativeWindow::disconnect
366a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_c.release();
367a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_r.release();
368a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_d.release();
369a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    }
370a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
371fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    return result;
372fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian}
373518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
374c2e41222bf02a6579763974f82d65875cfa43481Jesse Hallbool egl_display_t::haveExtension(const char* name, size_t nameLen) const {
375c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    if (!nameLen) {
376c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall        nameLen = strlen(name);
377c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    }
378c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall    return findExtension(mExtensionString.string(), name, nameLen);
379c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall}
380c2e41222bf02a6579763974f82d65875cfa43481Jesse Hall
381a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall// ----------------------------------------------------------------------------
382a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
383a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hallbool egl_display_t::HibernationMachine::incWakeCount(WakeRefStrength strength) {
384a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    Mutex::Autolock _l(mLock);
385b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    ALOGE_IF(mWakeCount < 0 || mWakeCount == INT32_MAX,
386b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall             "Invalid WakeCount (%d) on enter\n", mWakeCount);
387a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
388b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    mWakeCount++;
389a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    if (strength == STRONG)
390a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall        mAttemptHibernation = false;
391a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
392258385978c517a47626161b1e644c48bcee28de1Jesse Hall    if (CC_UNLIKELY(mHibernating)) {
393258385978c517a47626161b1e644c48bcee28de1Jesse Hall        ALOGV("Awakening\n");
394258385978c517a47626161b1e644c48bcee28de1Jesse Hall        egl_connection_t* const cnx = &gEGLImpl;
395a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
396a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall        // These conditions should be guaranteed before entering hibernation;
397a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall        // we don't want to get into a state where we can't wake up.
398a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall        ALOGD_IF(!mDpyValid || !cnx->egl.eglAwakenProcessIMG,
399a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall                 "Invalid hibernation state, unable to awaken\n");
400a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
401258385978c517a47626161b1e644c48bcee28de1Jesse Hall        if (!cnx->egl.eglAwakenProcessIMG()) {
402258385978c517a47626161b1e644c48bcee28de1Jesse Hall            ALOGE("Failed to awaken EGL implementation\n");
403258385978c517a47626161b1e644c48bcee28de1Jesse Hall            return false;
404258385978c517a47626161b1e644c48bcee28de1Jesse Hall        }
405258385978c517a47626161b1e644c48bcee28de1Jesse Hall        mHibernating = false;
406258385978c517a47626161b1e644c48bcee28de1Jesse Hall    }
407b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    return true;
408b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall}
409b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall
410a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hallvoid egl_display_t::HibernationMachine::decWakeCount(WakeRefStrength strength) {
411a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    Mutex::Autolock _l(mLock);
412b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    ALOGE_IF(mWakeCount <= 0, "Invalid WakeCount (%d) on leave\n", mWakeCount);
413a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
414a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    mWakeCount--;
415a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    if (strength == STRONG)
416a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall        mAttemptHibernation = true;
417a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
418a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    if (mWakeCount == 0 && CC_UNLIKELY(mAttemptHibernation)) {
419258385978c517a47626161b1e644c48bcee28de1Jesse Hall        egl_connection_t* const cnx = &gEGLImpl;
420258385978c517a47626161b1e644c48bcee28de1Jesse Hall        mAttemptHibernation = false;
421201f3b2da572eb27b9d4b3131e6d8c3c92a13de8Jesse Hall        if (mAllowHibernation && mDpyValid &&
422a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall                cnx->egl.eglHibernateProcessIMG &&
423a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall                cnx->egl.eglAwakenProcessIMG) {
424258385978c517a47626161b1e644c48bcee28de1Jesse Hall            ALOGV("Hibernating\n");
425258385978c517a47626161b1e644c48bcee28de1Jesse Hall            if (!cnx->egl.eglHibernateProcessIMG()) {
426258385978c517a47626161b1e644c48bcee28de1Jesse Hall                ALOGE("Failed to hibernate EGL implementation\n");
427258385978c517a47626161b1e644c48bcee28de1Jesse Hall                return;
428258385978c517a47626161b1e644c48bcee28de1Jesse Hall            }
429258385978c517a47626161b1e644c48bcee28de1Jesse Hall            mHibernating = true;
430258385978c517a47626161b1e644c48bcee28de1Jesse Hall        }
431258385978c517a47626161b1e644c48bcee28de1Jesse Hall    }
432258385978c517a47626161b1e644c48bcee28de1Jesse Hall}
433258385978c517a47626161b1e644c48bcee28de1Jesse Hall
434a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hallvoid egl_display_t::HibernationMachine::setDisplayValid(bool valid) {
435a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    Mutex::Autolock _l(mLock);
436a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    mDpyValid = valid;
437b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall}
438b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall
439518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
440518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}; // namespace android
441518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
442