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 "GLcommon/GLutils.h"
23
24 #include <string.h>
25
26 namespace {
27
28 static EGLBoolean sEgl2Egl = false;
29
sSingleton()30 static EglGlobalInfo* sSingleton() {
31 static EglGlobalInfo* i = new EglGlobalInfo;
32 return i;
33 }
34
35 static bool sEgl2EglSyncSafeToUse = false;
36
37 } // namespace
38
setEgl2Egl(EGLBoolean enable)39 void EglGlobalInfo::setEgl2Egl(EGLBoolean enable) {
40 sEgl2Egl = enable;
41 setGles2Gles(enable);
42 sSingleton();
43 }
44
isEgl2Egl()45 bool EglGlobalInfo::isEgl2Egl() {
46 return isGles2Gles();
47 }
48
setEgl2EglSyncSafeToUse(EGLBoolean enable)49 void EglGlobalInfo::setEgl2EglSyncSafeToUse(EGLBoolean enable) {
50 sEgl2EglSyncSafeToUse = enable == EGL_TRUE ? true : false;
51 }
52
isEgl2EglSyncSafeToUse()53 bool EglGlobalInfo::isEgl2EglSyncSafeToUse() {
54 return !isGles2Gles() || sEgl2EglSyncSafeToUse;
55 }
56
57 // static
getInstance()58 EglGlobalInfo* EglGlobalInfo::getInstance() {
59 return sSingleton();
60 }
61
EglGlobalInfo()62 EglGlobalInfo::EglGlobalInfo() {
63 #ifdef ANDROID
64 sEgl2Egl = true;
65 sEgl2EglSyncSafeToUse = true;
66 m_engine = EglOS::getEgl2EglHostInstance();
67 #else
68 if (sEgl2Egl) {
69 m_engine = EglOS::getEgl2EglHostInstance();
70 } else {
71 m_engine = EglOS::Engine::getHostInstance();
72 }
73 #endif
74 m_display = m_engine->getDefaultDisplay();
75 }
76
~EglGlobalInfo()77 EglGlobalInfo::~EglGlobalInfo() {
78 for (size_t n = 0; n < m_displays.size(); ++n) {
79 delete m_displays[n];
80 }
81 }
82
addDisplay(EGLNativeDisplayType dpy,EglOS::Display * idpy)83 EglDisplay* EglGlobalInfo::addDisplay(EGLNativeDisplayType dpy,
84 EglOS::Display* idpy) {
85 //search if it already exists.
86 android::base::AutoLock mutex(m_lock);
87 for (size_t n = 0; n < m_displays.size(); ++n) {
88 if (m_displays[n]->getNativeDisplay() == dpy) {
89 return m_displays[n];
90 }
91 }
92
93 if (!idpy) {
94 return NULL;
95 }
96 EglDisplay* result = new EglDisplay(dpy, idpy);
97 m_displays.push_back(result);
98 return result;
99 }
100
removeDisplay(EGLDisplay dpy)101 bool EglGlobalInfo::removeDisplay(EGLDisplay dpy) {
102 android::base::AutoLock mutex(m_lock);
103 for (size_t n = 0; n < m_displays.size(); ++n) {
104 if (m_displays[n] == static_cast<EglDisplay*>(dpy)) {
105 delete m_displays[n];
106 m_displays.erase(m_displays.begin() + n);
107 return true;
108 }
109 }
110 return false;
111 }
112
getDisplay(EGLNativeDisplayType dpy) const113 EglDisplay* EglGlobalInfo::getDisplay(EGLNativeDisplayType dpy) const {
114 android::base::AutoLock mutex(m_lock);
115 for (size_t n = 0; n < m_displays.size(); ++n) {
116 if (m_displays[n]->getNativeDisplay() == dpy) {
117 return m_displays[n];
118 }
119 }
120 return NULL;
121 }
122
123 #ifndef ANDROID
124
getDisplay(EGLDisplay dpy) const125 EglDisplay* EglGlobalInfo::getDisplay(EGLDisplay dpy) const {
126 android::base::AutoLock mutex(m_lock);
127 for (size_t n = 0; n < m_displays.size(); ++n) {
128 if (m_displays[n] == static_cast<EglDisplay*>(dpy)) {
129 return m_displays[n];
130 }
131 }
132 return NULL;
133 }
134
135 #endif
136
initClientExtFuncTable(GLESVersion ver)137 void EglGlobalInfo::initClientExtFuncTable(GLESVersion ver) {
138 android::base::AutoLock mutex(m_lock);
139 if (!m_gles_extFuncs_inited[ver]) {
140 ClientAPIExts::initClientFuncs(m_gles_ifaces[ver], (int)ver - 1);
141 m_gles_extFuncs_inited[ver] = true;
142 }
143 }
144
markSurfaceForDestroy(EglDisplay * display,EGLSurface toDestroy)145 void EglGlobalInfo::markSurfaceForDestroy(EglDisplay* display,
146 EGLSurface toDestroy) {
147 android::base::AutoLock mutex(m_lock);
148 assert(display);
149 m_surfaceDestroyList.push_back(
150 std::make_pair(display, toDestroy));
151 }
152
sweepDestroySurfaces()153 void EglGlobalInfo::sweepDestroySurfaces() {
154 android::base::AutoLock mutex(m_lock);
155 for (auto elt : m_surfaceDestroyList) {
156 EglDisplay* dpy = elt.first;
157 assert(dpy);
158 EGLSurface surface = elt.second;
159 SurfacePtr surfacePtr = dpy->getSurface(surface);
160 if (surfacePtr) {
161 m_gles_ifaces[GLES_2_0]->deleteRbo(surfacePtr->glRboColor);
162 m_gles_ifaces[GLES_2_0]->deleteRbo(surfacePtr->glRboDepth);
163 }
164 dpy->removeSurface(surface);
165 }
166 m_surfaceDestroyList.clear();
167 }
168