egl_display.cpp revision a08cf6e3a4ee045608bc8991a779dedb4f281a3f
1518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian/*
2518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** Copyright 2007, The Android Open Source Project
3518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
4518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** Licensed under the Apache License, Version 2.0 (the "License");
5518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** you may not use this file except in compliance with the License.
6518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** You may obtain a copy of the License at
7518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
8518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **     http://www.apache.org/licenses/LICENSE-2.0
9518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian **
10518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** Unless required by applicable law or agreed to in writing, software
11518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** distributed under the License is distributed on an "AS IS" BASIS,
12518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** See the License for the specific language governing permissions and
14518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian ** limitations under the License.
15518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian */
16518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
17b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall#define __STDC_LIMIT_MACROS 1
18b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall
194b9511c16195a646242eff833b0af212933b6ecaMathias Agopian#include <string.h>
204b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
21aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis#include "egl_cache.h"
22518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_display.h"
23518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_object.h"
24518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_tls.h"
25518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "egl_impl.h"
26518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#include "Loader.h"
277db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian#include <cutils/properties.h>
28518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
29518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
30518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopiannamespace android {
31518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
32518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
334b9511c16195a646242eff833b0af212933b6ecaMathias Agopianstatic char const * const sVendorString     = "Android";
344b9511c16195a646242eff833b0af212933b6ecaMathias Agopianstatic char const * const sVersionString    = "1.4 Android META-EGL";
35cc2b1560e87369676a2d13f17bd1ff4021a91819Mathias Agopianstatic char const * const sClientApiString  = "OpenGL_ES";
364b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
374b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// this is the list of EGL extensions that are exposed to applications
384b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// some of them are mandatory because used by the ANDROID system.
394b9511c16195a646242eff833b0af212933b6ecaMathias Agopian//
404b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// mandatory extensions are required per the CDD and not explicitly
414b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// checked during EGL initialization. the system *assumes* these extensions
424b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// are present. the system may not function properly if some mandatory
434b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// extensions are missing.
444b9511c16195a646242eff833b0af212933b6ecaMathias Agopian//
454b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// NOTE: sExtensionString MUST be have a single space as the last character.
464b9511c16195a646242eff833b0af212933b6ecaMathias Agopian//
474b9511c16195a646242eff833b0af212933b6ecaMathias Agopianstatic char const * const sExtensionString  =
484b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_image "                        // mandatory
494b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_image_base "                   // mandatory
504b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_image_pixmap "
514b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_gl_texture_2D_image "
524b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_gl_texture_cubemap_image "
534b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_gl_renderbuffer_image "
544b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_KHR_fence_sync "
554b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_NV_system_time "
564b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        "EGL_ANDROID_image_native_buffer "      // mandatory
574b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        ;
584b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
594b9511c16195a646242eff833b0af212933b6ecaMathias Agopian// extensions not exposed to applications but used by the ANDROID system
604b9511c16195a646242eff833b0af212933b6ecaMathias Agopian//      "EGL_ANDROID_recordable "               // mandatory
614b9511c16195a646242eff833b0af212933b6ecaMathias Agopian//      "EGL_ANDROID_blob_cache "               // strongly recommended
62331841b96b92646c93c87627c03f77b892f711cdJamie Gennis//      "EGL_ANDROID_native_fence_sync "        // strongly recommended
63258385978c517a47626161b1e644c48bcee28de1Jesse Hall//      "EGL_IMG_hibernate_process "            // optional
644b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
65518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern void initEglTraceLevel();
66b13c78f8520ef5a96effdee977bbacb881236c66Siva Velusamyextern void initEglDebugLevel();
67518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianextern void setGLHooksThreadSpecific(gl_hooks_t const *value);
68518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
69518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
70518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
71518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
72518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
73518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::egl_display_t() :
74a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    magic('_dpy'), finishOnSwap(false), traceGpuCompletion(false), refs(0) {
75518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
76518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
77518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t::~egl_display_t() {
78518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    magic = 0;
79766010858ea7696d64f1b559413670bdd8627595Jamie Gennis    egl_cache_t::get()->terminate();
80518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
81518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
82518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianegl_display_t* egl_display_t::get(EGLDisplay dpy) {
83518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    uintptr_t index = uintptr_t(dpy)-1U;
84518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return (index >= NUM_DISPLAYS) ? NULL : &sDisplay[index];
85518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
86518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
87518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopianvoid egl_display_t::addObject(egl_object_t* object) {
88518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
89518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    objects.add(object);
90518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
91518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
925b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopianvoid egl_display_t::removeObject(egl_object_t* object) {
93518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
945b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    objects.remove(object);
95518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
96518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
97f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopianbool egl_display_t::getObject(egl_object_t* object) const {
98518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
995b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    if (objects.indexOf(object) >= 0) {
100f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        if (object->getDisplay() == this) {
101f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian            object->incRef();
102f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian            return true;
103f0480de37492597a5c5cf1e6f8346f1467e3a552Mathias Agopian        }
104518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
105518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return false;
106518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
107518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
108518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) {
109518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (uintptr_t(disp) >= NUM_DISPLAYS)
110518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return NULL;
111518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
112518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return sDisplay[uintptr_t(disp)].getDisplay(disp);
113518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
114518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
115518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {
116518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
117518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
118518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
119518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // get our driver loader
120518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Loader& loader(Loader::getInstance());
121518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
122ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
123ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && disp.dpy == EGL_NO_DISPLAY) {
124ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
125ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        disp.dpy = dpy;
126ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        if (dpy == EGL_NO_DISPLAY) {
127ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            loader.close(cnx->dso);
128ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            cnx->dso = NULL;
129518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
130518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
131518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
132518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return EGLDisplay(uintptr_t(display) + 1U);
133518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
134518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
135518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
136518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
137518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
138518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
139518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (refs > 0) {
140518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (major != NULL)
141518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            *major = VERSION_MAJOR;
142518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (minor != NULL)
143518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            *minor = VERSION_MINOR;
144518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs++;
145518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_TRUE;
146518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
147518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
148518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#if EGL_TRACE
149518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
150518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // Called both at early_init time and at this time. (Early_init is pre-zygote, so
151518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // the information from that call may be stale.)
152518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    initEglTraceLevel();
153b13c78f8520ef5a96effdee977bbacb881236c66Siva Velusamy    initEglDebugLevel();
154518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
155518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#endif
156518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
157518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    setGLHooksThreadSpecific(&gHooksNoContext);
158518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
159518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // initialize each EGL and
160518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // build our own extension string first, based on the extension we know
161518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // and the extension supported by our client implementation
162ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian
163ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
164ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    cnx->major = -1;
165ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    cnx->minor = -1;
166ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso) {
167518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
168518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#if defined(ADRENO130)
169518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#warning "Adreno-130 eglInitialize() workaround"
170518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        /*
171518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * The ADRENO 130 driver returns a different EGLDisplay each time
172518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * eglGetDisplay() is called, but also makes the EGLDisplay invalid
173518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * after eglTerminate() has been called, so that eglInitialize()
174518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * cannot be called again. Therefore, we need to make sure to call
175518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         * eglGetDisplay() before calling eglInitialize();
176518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian         */
177518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (i == IMPL_HARDWARE) {
178ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            disp[i].dpy = cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
179518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
180518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian#endif
181518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
182ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        EGLDisplay idpy = disp.dpy;
183518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
184ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            //ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
185ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            //        idpy, cnx->major, cnx->minor, cnx);
186518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
187518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // display is now initialized
188ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            disp.state = egl_display_t::INITIALIZED;
189518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
190518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian            // get the query-strings for this display for each implementation
191ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            disp.queryString.vendor = cnx->egl.eglQueryString(idpy,
192518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_VENDOR);
193ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            disp.queryString.version = cnx->egl.eglQueryString(idpy,
194518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_VERSION);
195ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            disp.queryString.extensions = cnx->egl.eglQueryString(idpy,
196518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_EXTENSIONS);
197ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            disp.queryString.clientApi = cnx->egl.eglQueryString(idpy,
198518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    EGL_CLIENT_APIS);
199518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
200518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        } else {
201ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            ALOGW("eglInitialize(%p) failed (%s)", idpy,
202518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian                    egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
203518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        }
204518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
205518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
2064b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    // the query strings are per-display
2074b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    mVendorString.setTo(sVendorString);
2084b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    mVersionString.setTo(sVersionString);
2094b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    mClientApiString.setTo(sClientApiString);
2104b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
2117773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    // we only add extensions that exist in the implementation
2124b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    char const* start = sExtensionString;
2134b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    char const* end;
2144b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    do {
2154b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        // find the space separating this extension for the next one
2164b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        end = strchr(start, ' ');
2174b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        if (end) {
2184b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            // length of the extension string
2194b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            const size_t len = end - start;
220f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian            if (len) {
221f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                // NOTE: we could avoid the copy if we had strnstr.
222f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                const String8 ext(start, len);
223ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                // now look for this extension
224ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                if (disp.queryString.extensions) {
225ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    // if we find it, add this extension string to our list
226ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    // (and don't forget the space)
227ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    const char* match = strstr(disp.queryString.extensions, ext.string());
228ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    if (match && (match[len] == ' ' || match[len] == 0)) {
229ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                        mExtensionString.append(start, len+1);
230f3ae82d8134e7f5a2f0432ef809569bfa418883bMathias Agopian                    }
2314b9511c16195a646242eff833b0af212933b6ecaMathias Agopian                }
2324b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            }
2334b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            // process the next extension string, and skip the space.
2344b9511c16195a646242eff833b0af212933b6ecaMathias Agopian            start = end + 1;
2354b9511c16195a646242eff833b0af212933b6ecaMathias Agopian        }
2364b9511c16195a646242eff833b0af212933b6ecaMathias Agopian    } while (end);
2374b9511c16195a646242eff833b0af212933b6ecaMathias Agopian
238aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis    egl_cache_t::get()->initialize(this);
239aca51c06f38155f1435fbc6944d7fc0a9bf1e4e9Jamie Gennis
2407db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian    char value[PROPERTY_VALUE_MAX];
2417db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian    property_get("debug.egl.finish", value, "0");
2427db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian    if (atoi(value)) {
2437db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian        finishOnSwap = true;
2447db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian    }
2457db993a98b9239bd4e384cc4aa128262fe3cf52cMathias Agopian
24628ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    property_get("debug.egl.traceGpuCompletion", value, "0");
24728ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    if (atoi(value)) {
24828ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis        traceGpuCompletion = true;
24928ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis    }
25028ef8d7911dbfd1bf8256fb43acba894d87fc07aJamie Gennis
2517773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    refs++;
2527773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    if (major != NULL)
2537773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian        *major = VERSION_MAJOR;
2547773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    if (minor != NULL)
2557773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian        *minor = VERSION_MINOR;
256a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
257a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    mHibernation.setDisplayValid(true);
258a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
2597773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian    return EGL_TRUE;
260518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
261518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
262518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias AgopianEGLBoolean egl_display_t::terminate() {
263518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
264518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    Mutex::Autolock _l(lock);
265518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
266518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (refs == 0) {
267fe98127eaaf82686ba750001e2b771abece44e97Mathias Agopian        /*
268fe98127eaaf82686ba750001e2b771abece44e97Mathias Agopian         * From the EGL spec (3.2):
269fe98127eaaf82686ba750001e2b771abece44e97Mathias Agopian         * "Termination of a display that has already been terminated,
270fe98127eaaf82686ba750001e2b771abece44e97Mathias Agopian         *  (...), is allowed, but the only effect of such a call is
271fe98127eaaf82686ba750001e2b771abece44e97Mathias Agopian         *  to return EGL_TRUE (...)
272fe98127eaaf82686ba750001e2b771abece44e97Mathias Agopian         */
273fe98127eaaf82686ba750001e2b771abece44e97Mathias Agopian        return EGL_TRUE;
274518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
275518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
276518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    // this is specific to Android, display termination is ref-counted.
277518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    if (refs > 1) {
278518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        refs--;
279518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian        return EGL_TRUE;
280518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
281518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
282518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    EGLBoolean res = EGL_FALSE;
283ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    egl_connection_t* const cnx = &gEGLImpl;
284ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian    if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
285ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
286ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian            ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
287ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
288ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        }
289ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        // REVISIT: it's unclear what to do if eglTerminate() fails
290ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        disp.state = egl_display_t::TERMINATED;
291ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian        res = EGL_TRUE;
292518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    }
293518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
294a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    mHibernation.setDisplayValid(false);
295a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
296a08cf6e3a4ee045608bc8991a779dedb4f281a3fJamie Gennis    // Reset the extension string since it will be regenerated if we get
297a08cf6e3a4ee045608bc8991a779dedb4f281a3fJamie Gennis    // reinitialized.
298a08cf6e3a4ee045608bc8991a779dedb4f281a3fJamie Gennis    mExtensionString.setTo("");
299a08cf6e3a4ee045608bc8991a779dedb4f281a3fJamie Gennis
3005b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // Mark all objects remaining in the list as terminated, unless
3015b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // there are no reference to them, it which case, we're free to
3025b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // delete them.
3035b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    size_t count = objects.size();
30432397c1cd3327905173b36baa6fd1c579bc328ffSteve Block    ALOGW_IF(count, "eglTerminate() called w/ %d objects remaining", count);
3055b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
3065b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        egl_object_t* o = objects.itemAt(i);
3075b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian        o->destroy();
3085b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    }
3095b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian
3105b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    // this marks all object handles are "terminated"
3115b287a6ea8dfac7ab3e03ae1e98f9e2214cbae09Mathias Agopian    objects.clear();
312518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
313518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    refs--;
314518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian    return res;
315518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}
316518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
317fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopianvoid egl_display_t::loseCurrent(egl_context_t * cur_c)
318fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian{
319fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    if (cur_c) {
320a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        egl_display_t* display = cur_c->getDisplay();
321a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        if (display) {
322a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            display->loseCurrentImpl(cur_c);
323a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        }
324a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    }
325a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian}
326fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
327a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopianvoid egl_display_t::loseCurrentImpl(egl_context_t * cur_c)
328a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian{
329a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // by construction, these are either 0 or valid (possibly terminated)
330a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it should be impossible for these to be invalid
331a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    ContextRef _cur_c(cur_c);
332a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : NULL);
333a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : NULL);
334a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
335a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    { // scope for the lock
336a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        Mutex::Autolock _l(lock);
337fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        cur_c->onLooseCurrent();
338fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
339fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    }
340a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
341a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // This cannot be called with the lock held because it might end-up
342a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // calling back into EGL (in particular when a surface is destroyed
343a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it calls ANativeWindow::disconnect
344a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_c.release();
345a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_r.release();
346a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    _cur_d.release();
347fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian}
348fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian
349fb87e54a9af8bc5063ca4deebe81d90126992480Mathias AgopianEGLBoolean egl_display_t::makeCurrent(egl_context_t* c, egl_context_t* cur_c,
350fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        EGLSurface draw, EGLSurface read, EGLContext ctx,
351fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        EGLSurface impl_draw, EGLSurface impl_read, EGLContext impl_ctx)
352fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian{
353fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    EGLBoolean result;
354a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
355a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // by construction, these are either 0 or valid (possibly terminated)
356a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    // it should be impossible for these to be invalid
357a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    ContextRef _cur_c(cur_c);
358a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_r(cur_c ? get_surface(cur_c->read) : NULL);
359a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    SurfaceRef _cur_d(cur_c ? get_surface(cur_c->draw) : NULL);
360a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
361a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    { // scope for the lock
362a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        Mutex::Autolock _l(lock);
363fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        if (c) {
364a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            result = c->cnx->egl.eglMakeCurrent(
365ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    disp.dpy, impl_draw, impl_read, impl_ctx);
366a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            if (result == EGL_TRUE) {
367a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian                c->onMakeCurrent(draw, read);
368258385978c517a47626161b1e644c48bcee28de1Jesse Hall                if (!cur_c) {
369a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall                    mHibernation.incWakeCount(HibernationMachine::STRONG);
370258385978c517a47626161b1e644c48bcee28de1Jesse Hall                }
371a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            }
372a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        } else {
373a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            result = cur_c->cnx->egl.eglMakeCurrent(
374ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopian                    disp.dpy, impl_draw, impl_read, impl_ctx);
375a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            if (result == EGL_TRUE) {
376a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian                cur_c->onLooseCurrent();
377a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall                mHibernation.decWakeCount(HibernationMachine::STRONG);
378a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian            }
379fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian        }
380fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    }
381a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
382a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    if (result == EGL_TRUE) {
383a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // This cannot be called with the lock held because it might end-up
384a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // calling back into EGL (in particular when a surface is destroyed
385a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        // it calls ANativeWindow::disconnect
386a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_c.release();
387a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_r.release();
388a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian        _cur_d.release();
389a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian    }
390a4b2c041828d1074dca3b999407e7dd85568c5aaMathias Agopian
391fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian    return result;
392fb87e54a9af8bc5063ca4deebe81d90126992480Mathias Agopian}
393518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian
394a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall// ----------------------------------------------------------------------------
395a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
396a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hallbool egl_display_t::HibernationMachine::incWakeCount(WakeRefStrength strength) {
397a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    Mutex::Autolock _l(mLock);
398b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    ALOGE_IF(mWakeCount < 0 || mWakeCount == INT32_MAX,
399b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall             "Invalid WakeCount (%d) on enter\n", mWakeCount);
400a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
401b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    mWakeCount++;
402a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    if (strength == STRONG)
403a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall        mAttemptHibernation = false;
404a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
405258385978c517a47626161b1e644c48bcee28de1Jesse Hall    if (CC_UNLIKELY(mHibernating)) {
406258385978c517a47626161b1e644c48bcee28de1Jesse Hall        ALOGV("Awakening\n");
407258385978c517a47626161b1e644c48bcee28de1Jesse Hall        egl_connection_t* const cnx = &gEGLImpl;
408a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
409a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall        // These conditions should be guaranteed before entering hibernation;
410a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall        // we don't want to get into a state where we can't wake up.
411a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall        ALOGD_IF(!mDpyValid || !cnx->egl.eglAwakenProcessIMG,
412a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall                 "Invalid hibernation state, unable to awaken\n");
413a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
414258385978c517a47626161b1e644c48bcee28de1Jesse Hall        if (!cnx->egl.eglAwakenProcessIMG()) {
415258385978c517a47626161b1e644c48bcee28de1Jesse Hall            ALOGE("Failed to awaken EGL implementation\n");
416258385978c517a47626161b1e644c48bcee28de1Jesse Hall            return false;
417258385978c517a47626161b1e644c48bcee28de1Jesse Hall        }
418258385978c517a47626161b1e644c48bcee28de1Jesse Hall        mHibernating = false;
419258385978c517a47626161b1e644c48bcee28de1Jesse Hall    }
420b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    return true;
421b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall}
422b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall
423a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hallvoid egl_display_t::HibernationMachine::decWakeCount(WakeRefStrength strength) {
424a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    Mutex::Autolock _l(mLock);
425b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall    ALOGE_IF(mWakeCount <= 0, "Invalid WakeCount (%d) on leave\n", mWakeCount);
426a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
427a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    mWakeCount--;
428a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    if (strength == STRONG)
429a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall        mAttemptHibernation = true;
430a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall
431a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    if (mWakeCount == 0 && CC_UNLIKELY(mAttemptHibernation)) {
432258385978c517a47626161b1e644c48bcee28de1Jesse Hall        egl_connection_t* const cnx = &gEGLImpl;
433258385978c517a47626161b1e644c48bcee28de1Jesse Hall        mAttemptHibernation = false;
434201f3b2da572eb27b9d4b3131e6d8c3c92a13de8Jesse Hall        if (mAllowHibernation && mDpyValid &&
435a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall                cnx->egl.eglHibernateProcessIMG &&
436a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall                cnx->egl.eglAwakenProcessIMG) {
437258385978c517a47626161b1e644c48bcee28de1Jesse Hall            ALOGV("Hibernating\n");
438258385978c517a47626161b1e644c48bcee28de1Jesse Hall            if (!cnx->egl.eglHibernateProcessIMG()) {
439258385978c517a47626161b1e644c48bcee28de1Jesse Hall                ALOGE("Failed to hibernate EGL implementation\n");
440258385978c517a47626161b1e644c48bcee28de1Jesse Hall                return;
441258385978c517a47626161b1e644c48bcee28de1Jesse Hall            }
442258385978c517a47626161b1e644c48bcee28de1Jesse Hall            mHibernating = true;
443258385978c517a47626161b1e644c48bcee28de1Jesse Hall        }
444258385978c517a47626161b1e644c48bcee28de1Jesse Hall    }
445258385978c517a47626161b1e644c48bcee28de1Jesse Hall}
446258385978c517a47626161b1e644c48bcee28de1Jesse Hall
447a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hallvoid egl_display_t::HibernationMachine::setDisplayValid(bool valid) {
448a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    Mutex::Autolock _l(mLock);
449a0fef1c8bb22443402fb3aeda7ce70f7d5775b0aJesse Hall    mDpyValid = valid;
450b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall}
451b29e5e8c2682ae145e8c56d9afb061f8da7f854cJesse Hall
452518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
453518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian}; // namespace android
454518ec112f468eb67bf681b3eec896d7bfb4ff98dMathias Agopian// ----------------------------------------------------------------------------
455