• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "EglGlobalInfo.h"
17 
18 #include "ClientAPIExts.h"
19 #include "EglDisplay.h"
20 #include "EglOsApi.h"
21 
22 #include "host-common/GfxstreamFatalError.h"
23 #include "GLcommon/GLutils.h"
24 
25 #include <string.h>
26 
27 using emugl::ABORT_REASON_OTHER;
28 using emugl::FatalError;
29 
30 namespace {
31 
32 static EGLBoolean sEgl2Egl = false;
33 
sSingleton(bool nullEgl=false)34 static EglGlobalInfo* sSingleton(bool nullEgl = false) {
35     static EglGlobalInfo* i = new EglGlobalInfo(nullEgl);
36     return i;
37 }
38 
39 static bool sEgl2EglSyncSafeToUse = false;
40 
41 }  // namespace
42 
setEgl2Egl(EGLBoolean enable,bool nullEgl)43 void EglGlobalInfo::setEgl2Egl(EGLBoolean enable, bool nullEgl) {
44     if (nullEgl && enable == EGL_FALSE) {
45         // No point in nullEgl backend for non egl2egl cases.
46         GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER));
47     }
48     sEgl2Egl = enable;
49     setGles2Gles(enable);
50     sSingleton(nullEgl);
51 }
52 
isEgl2Egl()53 bool EglGlobalInfo::isEgl2Egl() {
54     return isGles2Gles();
55 }
56 
setEgl2EglSyncSafeToUse(EGLBoolean enable)57 void EglGlobalInfo::setEgl2EglSyncSafeToUse(EGLBoolean enable) {
58     sEgl2EglSyncSafeToUse = enable == EGL_TRUE ? true : false;
59 }
60 
isEgl2EglSyncSafeToUse()61 bool EglGlobalInfo::isEgl2EglSyncSafeToUse() {
62     return !isGles2Gles() || sEgl2EglSyncSafeToUse;
63 }
64 
65 // static
getInstance(bool nullEgl)66 EglGlobalInfo* EglGlobalInfo::getInstance(bool nullEgl) {
67     return sSingleton(nullEgl);
68 }
69 
EglGlobalInfo(bool nullEgl)70 EglGlobalInfo::EglGlobalInfo(bool nullEgl) {
71 #if defined(ANDROID) || defined(__QNX__)
72     sEgl2Egl = true;
73     sEgl2EglSyncSafeToUse = true;
74     m_engine = EglOS::
75         getEgl2EglHostInstance(nullEgl);
76 #else
77     if (sEgl2Egl) {
78         m_engine = EglOS::getEgl2EglHostInstance(nullEgl);
79     } else {
80         m_engine = EglOS::Engine::getHostInstance();
81     }
82 #endif
83     m_display = m_engine->getDefaultDisplay();
84 }
85 
~EglGlobalInfo()86 EglGlobalInfo::~EglGlobalInfo() {
87     for (size_t n = 0; n < m_displays.size(); ++n) {
88         delete m_displays[n];
89     }
90 }
91 
addDisplay(EGLNativeDisplayType dpy,EglOS::Display * idpy)92 EglDisplay* EglGlobalInfo::addDisplay(EGLNativeDisplayType dpy,
93                                       EglOS::Display* idpy) {
94     //search if it already exists.
95     android::base::AutoLock mutex(m_lock);
96     for (size_t n = 0; n < m_displays.size(); ++n) {
97         if (m_displays[n]->getEglOsEngineDisplay() == dpy) {
98             return m_displays[n];
99         }
100     }
101 
102     if (!idpy) {
103         return NULL;
104     }
105     EglDisplay* result = new EglDisplay(dpy, idpy);
106     m_displays.push_back(result);
107     return result;
108 }
109 
removeDisplay(EGLDisplay dpy)110 bool  EglGlobalInfo::removeDisplay(EGLDisplay dpy) {
111     android::base::AutoLock mutex(m_lock);
112     for (size_t n = 0; n < m_displays.size(); ++n) {
113         if (m_displays[n] == static_cast<EglDisplay*>(dpy)) {
114             delete m_displays[n];
115             m_displays.erase(m_displays.begin() + n);
116             return true;
117         }
118     }
119     return false;
120 }
121 
getDisplayFromDisplayType(EGLNativeDisplayType dpy) const122 EglDisplay* EglGlobalInfo::getDisplayFromDisplayType(EGLNativeDisplayType dpy) const {
123     android::base::AutoLock mutex(m_lock);
124     for (size_t n = 0; n < m_displays.size(); ++n) {
125         if (m_displays[n]->getEglOsEngineDisplay() == dpy) {
126             return m_displays[n];
127         }
128     }
129     return NULL;
130 }
131 
getDisplay(EGLDisplay dpy) const132 EglDisplay* EglGlobalInfo::getDisplay(EGLDisplay dpy) const {
133     android::base::AutoLock mutex(m_lock);
134     for (size_t n = 0; n < m_displays.size(); ++n) {
135         if (m_displays[n] == static_cast<EglDisplay*>(dpy)) {
136             return m_displays[n];
137         }
138     }
139     return NULL;
140 }
141 
initClientExtFuncTable(GLESVersion ver)142 void EglGlobalInfo::initClientExtFuncTable(GLESVersion ver) {
143     android::base::AutoLock mutex(m_lock);
144     if (!m_gles_extFuncs_inited[ver]) {
145         ClientAPIExts::initClientFuncs(m_gles_ifaces[ver], (int)ver - 1);
146         m_gles_extFuncs_inited[ver] = true;
147     }
148 }
149 
markSurfaceForDestroy(EglDisplay * display,EGLSurface toDestroy)150 void EglGlobalInfo::markSurfaceForDestroy(EglDisplay* display,
151                                           EGLSurface toDestroy) {
152     android::base::AutoLock mutex(m_lock);
153     assert(display);
154     m_surfaceDestroyList.push_back(
155         std::make_pair(display, toDestroy));
156 }
157 
sweepDestroySurfaces()158 void EglGlobalInfo::sweepDestroySurfaces() {
159     android::base::AutoLock mutex(m_lock);
160     for (auto elt : m_surfaceDestroyList) {
161         EglDisplay* dpy = elt.first;
162         assert(dpy);
163         EGLSurface surface = elt.second;
164         SurfacePtr surfacePtr = dpy->getSurface(surface);
165         if (surfacePtr) {
166             m_gles_ifaces[GLES_2_0]->deleteRbo(surfacePtr->glRboColor);
167             m_gles_ifaces[GLES_2_0]->deleteRbo(surfacePtr->glRboDepth);
168         }
169         dpy->removeSurface(surface);
170     }
171     m_surfaceDestroyList.clear();
172 }
173