• 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 "EglDisplay.h"
17 #include "EglOsApi.h"
18 #include <GLcommon/GLutils.h>
19 #include <utils/threads.h>
20 
EglDisplay(EGLNativeInternalDisplayType dpy,bool isDefault)21 EglDisplay::EglDisplay(EGLNativeInternalDisplayType dpy,bool isDefault) :
22     m_dpy(dpy),
23     m_initialized(false),
24     m_configInitialized(false),
25     m_isDefault(isDefault),
26     m_nextEglImageId(0),
27     m_globalSharedContext(NULL)
28 {
29     m_manager[GLES_1_1] = new ObjectNameManager(&m_globalNameSpace);
30     m_manager[GLES_2_0] = new ObjectNameManager(&m_globalNameSpace);
31 };
32 
~EglDisplay()33 EglDisplay::~EglDisplay() {
34     android::Mutex::Autolock mutex(m_lock);
35 
36     //
37     // Destroy the global context if one was created.
38     // (should be true for windows platform only)
39     //
40     if (m_globalSharedContext != NULL) {
41         EglOS::destroyContext( m_dpy, m_globalSharedContext);
42     }
43 
44     if(m_isDefault) {
45         EglOS::releaseDisplay(m_dpy);
46     }
47 
48 
49     for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end(); it++) {
50         EglConfig* pConfig = *it;
51         if(pConfig) delete pConfig;
52     }
53 
54     delete m_manager[GLES_1_1];
55     delete m_manager[GLES_2_0];
56     EglOS::deleteDisplay(m_dpy);
57 }
58 
nativeType()59 EGLNativeInternalDisplayType EglDisplay::nativeType(){return m_dpy;}
60 
initialize(int renderableType)61 void EglDisplay::initialize(int renderableType) {
62     android::Mutex::Autolock mutex(m_lock);
63     m_initialized = true;
64     initConfigurations(renderableType);
65     m_configInitialized = true;
66 }
67 
isInitialize()68 bool EglDisplay::isInitialize() { return m_initialized;}
69 
terminate()70 void EglDisplay::terminate(){
71     android::Mutex::Autolock mutex(m_lock);
72      m_contexts.clear();
73      m_surfaces.clear();
74      m_initialized = false;
75 }
76 
compareEglConfigsPtrs(EglConfig * first,EglConfig * second)77 static bool compareEglConfigsPtrs(EglConfig* first,EglConfig* second) {
78     return *first < *second ;
79 }
80 
addMissingConfigs(void)81 void EglDisplay::addMissingConfigs(void)
82 {
83     m_configs.sort(compareEglConfigsPtrs);
84 
85     EGLConfig match;
86     EGLNativePixelFormatType tmpfrmt = PIXEL_FORMAT_INITIALIZER;
87     EglConfig dummy(5, 6, 5, 0,  // RGB_565
88                     EGL_DONT_CARE,EGL_DONT_CARE,
89                     16, // Depth
90                     EGL_DONT_CARE,EGL_DONT_CARE,EGL_DONT_CARE,EGL_DONT_CARE,EGL_DONT_CARE,EGL_DONT_CARE,EGL_DONT_CARE,EGL_DONT_CARE,EGL_DONT_CARE,
91                     EGL_DONT_CARE, EGL_DONT_CARE,EGL_DONT_CARE,EGL_DONT_CARE,EGL_DONT_CARE,EGL_DONT_CARE,tmpfrmt);
92 
93     if(!doChooseConfigs(dummy, &match, 1))
94     {
95         return;
96     }
97 
98     const EglConfig* config = (EglConfig*)match;
99 
100     int bSize;
101     config->getConfAttrib(EGL_BUFFER_SIZE,&bSize);
102 
103     if(bSize == 16)
104     {
105         return;
106     }
107 
108     int max_config_id = 0;
109 
110     for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end() ;it++) {
111         EGLint id;
112         (*it)->getConfAttrib(EGL_CONFIG_ID, &id);
113         if(id > max_config_id)
114             max_config_id = id;
115     }
116 
117     EglConfig* newConfig = new EglConfig(*config,max_config_id+1,5,6,5,0);
118 
119     m_configs.push_back(newConfig);
120 }
121 
initConfigurations(int renderableType)122 void EglDisplay::initConfigurations(int renderableType) {
123     if(m_configInitialized) return;
124     EglOS::queryConfigs(m_dpy,renderableType,m_configs);
125 
126     addMissingConfigs();
127     m_configs.sort(compareEglConfigsPtrs);
128 }
129 
getConfig(EGLConfig conf)130 EglConfig* EglDisplay::getConfig(EGLConfig conf) {
131     android::Mutex::Autolock mutex(m_lock);
132 
133     for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end() ;it++) {
134         if(static_cast<EGLConfig>(*it) == conf) {
135             return (*it);
136 
137         }
138     }
139     return NULL;
140 }
141 
getSurface(EGLSurface surface)142 SurfacePtr EglDisplay::getSurface(EGLSurface surface) {
143     android::Mutex::Autolock mutex(m_lock);
144     /* surface is "key" in map<unsigned int, SurfacePtr>. */
145     unsigned int hndl = ToTargetCompatibleHandle((uintptr_t)surface);
146     SurfacesHndlMap::iterator it = m_surfaces.find(hndl);
147     return it != m_surfaces.end() ?
148                                   (*it).second :
149                                    SurfacePtr(NULL);
150 }
151 
getContext(EGLContext ctx)152 ContextPtr EglDisplay::getContext(EGLContext ctx) {
153     android::Mutex::Autolock mutex(m_lock);
154     /* ctx is "key" in map<unsigned int, ContextPtr>. */
155     unsigned int hndl = ToTargetCompatibleHandle((uintptr_t)ctx);
156     ContextsHndlMap::iterator it = m_contexts.find(hndl);
157     return it != m_contexts.end() ?
158                                   (*it).second :
159                                    ContextPtr(NULL);
160 }
161 
removeSurface(EGLSurface s)162 bool EglDisplay::removeSurface(EGLSurface s) {
163     android::Mutex::Autolock mutex(m_lock);
164     /* s is "key" in map<unsigned int, SurfacePtr>. */
165     unsigned int hndl = ToTargetCompatibleHandle((uintptr_t)s);
166     SurfacesHndlMap::iterator it = m_surfaces.find(hndl);
167     if(it != m_surfaces.end()) {
168         m_surfaces.erase(it);
169         return true;
170     }
171     return false;
172 }
173 
removeSurface(SurfacePtr s)174 bool EglDisplay::removeSurface(SurfacePtr s) {
175     android::Mutex::Autolock mutex(m_lock);
176 
177     SurfacesHndlMap::iterator it;
178     for(it = m_surfaces.begin(); it!= m_surfaces.end();it++)
179     {
180         if((*it).second.Ptr() == s.Ptr()) {
181             break;
182         }
183     }
184     if(it != m_surfaces.end()) {
185         m_surfaces.erase(it);
186         return true;
187     }
188     return false;
189 }
190 
removeContext(EGLContext ctx)191 bool EglDisplay::removeContext(EGLContext ctx) {
192     android::Mutex::Autolock mutex(m_lock);
193     /* ctx is "key" in map<unsigned int, ContextPtr>. */
194     unsigned int hndl = ToTargetCompatibleHandle((uintptr_t)ctx);
195     ContextsHndlMap::iterator it = m_contexts.find(hndl);
196     if(it != m_contexts.end()) {
197         m_contexts.erase(it);
198         return true;
199     }
200     return false;
201 }
202 
removeContext(ContextPtr ctx)203 bool EglDisplay::removeContext(ContextPtr ctx) {
204     android::Mutex::Autolock mutex(m_lock);
205 
206     ContextsHndlMap::iterator it;
207     for(it = m_contexts.begin(); it != m_contexts.end();it++) {
208         if((*it).second.Ptr() == ctx.Ptr()){
209             break;
210         }
211     }
212     if(it != m_contexts.end()) {
213         m_contexts.erase(it);
214         return true;
215     }
216     return false;
217 }
218 
getConfig(EGLint id)219 EglConfig* EglDisplay::getConfig(EGLint id) {
220     android::Mutex::Autolock mutex(m_lock);
221 
222     for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end() ;it++) {
223         if((*it)->id() == id) {
224             return (*it);
225 
226         }
227     }
228     return NULL;
229 }
230 
getConfigs(EGLConfig * configs,int config_size)231 int EglDisplay::getConfigs(EGLConfig* configs,int config_size) {
232     android::Mutex::Autolock mutex(m_lock);
233     int i = 0;
234     for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end() && i < config_size ;i++,it++) {
235         configs[i] = static_cast<EGLConfig>(*it);
236     }
237     return i;
238 }
239 
chooseConfigs(const EglConfig & dummy,EGLConfig * configs,int config_size)240 int EglDisplay::chooseConfigs(const EglConfig& dummy,EGLConfig* configs,int config_size) {
241     android::Mutex::Autolock mutex(m_lock);
242     return doChooseConfigs(dummy, configs, config_size);
243 }
244 
doChooseConfigs(const EglConfig & dummy,EGLConfig * configs,int config_size)245 int EglDisplay::doChooseConfigs(const EglConfig& dummy,EGLConfig* configs,int config_size) {
246     int added = 0;
247     for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end() && (added < config_size || !configs);it++) {
248 
249        if( (*it)->choosen(dummy)){
250             if(configs) {
251                 configs[added] = static_cast<EGLConfig>(*it);
252             }
253             added++;
254        }
255     }
256     //no need to sort since the configurations are saved already in sorted maner
257     return added;
258 }
259 
addSurface(SurfacePtr s)260 EGLSurface EglDisplay::addSurface(SurfacePtr s ) {
261    android::Mutex::Autolock mutex(m_lock);
262    unsigned int hndl = s.Ptr()->getHndl();
263    EGLSurface ret =reinterpret_cast<EGLSurface> (hndl);
264 
265    if(m_surfaces.find(hndl) != m_surfaces.end()) {
266        return ret;
267    }
268 
269    m_surfaces[hndl] = s;
270    return ret;
271 }
272 
addContext(ContextPtr ctx)273 EGLContext EglDisplay::addContext(ContextPtr ctx ) {
274     android::Mutex::Autolock mutex(m_lock);
275 
276    unsigned int hndl = ctx.Ptr()->getHndl();
277    EGLContext ret    = reinterpret_cast<EGLContext> (hndl);
278 
279    if(m_contexts.find(hndl) != m_contexts.end()) {
280        return ret;
281    }
282    m_contexts[hndl] = ctx;
283    return ret;
284 }
285 
286 
addImageKHR(ImagePtr img)287 EGLImageKHR EglDisplay::addImageKHR(ImagePtr img) {
288     android::Mutex::Autolock mutex(m_lock);
289     do { ++m_nextEglImageId; } while(m_nextEglImageId == 0);
290     img->imageId = m_nextEglImageId;
291     m_eglImages[m_nextEglImageId] = img;
292     return reinterpret_cast<EGLImageKHR>(m_nextEglImageId);
293 }
294 
getImage(EGLImageKHR img)295 ImagePtr EglDisplay::getImage(EGLImageKHR img) {
296     android::Mutex::Autolock mutex(m_lock);
297     /* img is "key" in map<unsigned int, ImagePtr>. */
298     unsigned int hndl = ToTargetCompatibleHandle((uintptr_t)img);
299     ImagesHndlMap::iterator i( m_eglImages.find(hndl) );
300     return (i != m_eglImages.end()) ? (*i).second :ImagePtr(NULL);
301 }
302 
destroyImageKHR(EGLImageKHR img)303 bool EglDisplay:: destroyImageKHR(EGLImageKHR img) {
304     android::Mutex::Autolock mutex(m_lock);
305     /* img is "key" in map<unsigned int, ImagePtr>. */
306     unsigned int hndl = ToTargetCompatibleHandle((uintptr_t)img);
307     ImagesHndlMap::iterator i( m_eglImages.find(hndl) );
308     if (i != m_eglImages.end())
309     {
310         m_eglImages.erase(i);
311         return true;
312     }
313     return false;
314 }
315 
getGlobalSharedContext()316 EGLNativeContextType EglDisplay::getGlobalSharedContext(){
317     android::Mutex::Autolock mutex(m_lock);
318 #ifndef _WIN32
319     // find an existing OpenGL context to share with, if exist
320     EGLNativeContextType ret =
321         (EGLNativeContextType)m_manager[GLES_1_1]->getGlobalContext();
322     if (!ret)
323         ret = (EGLNativeContextType)m_manager[GLES_2_0]->getGlobalContext();
324     return ret;
325 #else
326     if (!m_globalSharedContext) {
327         //
328         // On windows we create a dummy context to serve as the
329         // "global context" which all contexts share with.
330         // This is because on windows it is not possible to share
331         // with a context which is already current. This dummy context
332         // will never be current to any thread so it is safe to share with.
333         // Create that context using the first config
334         if (m_configs.size() < 1) {
335             // Should not happen! config list should be initialized at this point
336             return NULL;
337         }
338         EglConfig *cfg = (*m_configs.begin());
339         m_globalSharedContext = EglOS::createContext(m_dpy,cfg,NULL);
340     }
341 
342     return m_globalSharedContext;
343 #endif
344 }
345