summaryrefslogtreecommitdiffstats
path: root/distrib/android-emugl/host/libs/Translator/EGL/EglDisplay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'distrib/android-emugl/host/libs/Translator/EGL/EglDisplay.cpp')
-rw-r--r--distrib/android-emugl/host/libs/Translator/EGL/EglDisplay.cpp343
1 files changed, 343 insertions, 0 deletions
diff --git a/distrib/android-emugl/host/libs/Translator/EGL/EglDisplay.cpp b/distrib/android-emugl/host/libs/Translator/EGL/EglDisplay.cpp
new file mode 100644
index 000000000..24b9a0d6b
--- /dev/null
+++ b/distrib/android-emugl/host/libs/Translator/EGL/EglDisplay.cpp
@@ -0,0 +1,343 @@
+/*
+* Copyright (C) 2011 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#include "EglDisplay.h"
+#include "EglOsApi.h"
+#include <GLcommon/GLutils.h>
+
+EglDisplay::EglDisplay(EGLNativeInternalDisplayType dpy,bool isDefault) :
+ m_dpy(dpy),
+ m_initialized(false),
+ m_configInitialized(false),
+ m_isDefault(isDefault),
+ m_nextEglImageId(0),
+ m_globalSharedContext(NULL)
+{
+ m_manager[GLES_1_1] = new ObjectNameManager(&m_globalNameSpace);
+ m_manager[GLES_2_0] = new ObjectNameManager(&m_globalNameSpace);
+};
+
+EglDisplay::~EglDisplay() {
+ emugl::Mutex::AutoLock mutex(m_lock);
+
+ //
+ // Destroy the global context if one was created.
+ // (should be true for windows platform only)
+ //
+ if (m_globalSharedContext != NULL) {
+ EglOS::destroyContext( m_dpy, m_globalSharedContext);
+ }
+
+ if(m_isDefault) {
+ EglOS::releaseDisplay(m_dpy);
+ }
+
+
+ for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end(); it++) {
+ EglConfig* pConfig = *it;
+ if(pConfig) delete pConfig;
+ }
+
+ delete m_manager[GLES_1_1];
+ delete m_manager[GLES_2_0];
+ EglOS::deleteDisplay(m_dpy);
+}
+
+EGLNativeInternalDisplayType EglDisplay::nativeType(){return m_dpy;}
+
+void EglDisplay::initialize(int renderableType) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+ m_initialized = true;
+ initConfigurations(renderableType);
+ m_configInitialized = true;
+}
+
+bool EglDisplay::isInitialize() { return m_initialized;}
+
+void EglDisplay::terminate(){
+ emugl::Mutex::AutoLock mutex(m_lock);
+ m_contexts.clear();
+ m_surfaces.clear();
+ m_initialized = false;
+}
+
+static bool compareEglConfigsPtrs(EglConfig* first,EglConfig* second) {
+ return *first < *second ;
+}
+
+void EglDisplay::addMissingConfigs(void)
+{
+ m_configs.sort(compareEglConfigsPtrs);
+
+ EGLConfig match;
+ EGLNativePixelFormatType tmpfrmt = PIXEL_FORMAT_INITIALIZER;
+ EglConfig dummy(5, 6, 5, 0, // RGB_565
+ EGL_DONT_CARE,EGL_DONT_CARE,
+ 16, // Depth
+ 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,
+ EGL_DONT_CARE, EGL_DONT_CARE,EGL_DONT_CARE,EGL_DONT_CARE,EGL_DONT_CARE,EGL_DONT_CARE,tmpfrmt);
+
+ if(!doChooseConfigs(dummy, &match, 1))
+ {
+ return;
+ }
+
+ const EglConfig* config = (EglConfig*)match;
+
+ int bSize;
+ config->getConfAttrib(EGL_BUFFER_SIZE,&bSize);
+
+ if(bSize == 16)
+ {
+ return;
+ }
+
+ int max_config_id = 0;
+
+ for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end() ;it++) {
+ EGLint id;
+ (*it)->getConfAttrib(EGL_CONFIG_ID, &id);
+ if(id > max_config_id)
+ max_config_id = id;
+ }
+
+ EglConfig* newConfig = new EglConfig(*config,max_config_id+1,5,6,5,0);
+
+ m_configs.push_back(newConfig);
+}
+
+void EglDisplay::initConfigurations(int renderableType) {
+ if(m_configInitialized) return;
+ EglOS::queryConfigs(m_dpy,renderableType,m_configs);
+
+ addMissingConfigs();
+ m_configs.sort(compareEglConfigsPtrs);
+}
+
+EglConfig* EglDisplay::getConfig(EGLConfig conf) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+
+ for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end() ;it++) {
+ if(static_cast<EGLConfig>(*it) == conf) {
+ return (*it);
+
+ }
+ }
+ return NULL;
+}
+
+SurfacePtr EglDisplay::getSurface(EGLSurface surface) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+ /* surface is "key" in map<unsigned int, SurfacePtr>. */
+ unsigned int hndl = SafeUIntFromPointer(surface);
+ SurfacesHndlMap::iterator it = m_surfaces.find(hndl);
+ return it != m_surfaces.end() ?
+ (*it).second :
+ SurfacePtr(NULL);
+}
+
+ContextPtr EglDisplay::getContext(EGLContext ctx) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+ /* ctx is "key" in map<unsigned int, ContextPtr>. */
+ unsigned int hndl = SafeUIntFromPointer(ctx);
+ ContextsHndlMap::iterator it = m_contexts.find(hndl);
+ return it != m_contexts.end() ?
+ (*it).second :
+ ContextPtr(NULL);
+}
+
+bool EglDisplay::removeSurface(EGLSurface s) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+ /* s is "key" in map<unsigned int, SurfacePtr>. */
+ unsigned int hndl = SafeUIntFromPointer(s);
+ SurfacesHndlMap::iterator it = m_surfaces.find(hndl);
+ if(it != m_surfaces.end()) {
+ m_surfaces.erase(it);
+ return true;
+ }
+ return false;
+}
+
+bool EglDisplay::removeSurface(SurfacePtr s) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+
+ SurfacesHndlMap::iterator it;
+ for(it = m_surfaces.begin(); it!= m_surfaces.end();it++)
+ {
+ if((*it).second.Ptr() == s.Ptr()) {
+ break;
+ }
+ }
+ if(it != m_surfaces.end()) {
+ m_surfaces.erase(it);
+ return true;
+ }
+ return false;
+}
+
+bool EglDisplay::removeContext(EGLContext ctx) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+ /* ctx is "key" in map<unsigned int, ContextPtr>. */
+ unsigned int hndl = SafeUIntFromPointer(ctx);
+ ContextsHndlMap::iterator it = m_contexts.find(hndl);
+ if(it != m_contexts.end()) {
+ m_contexts.erase(it);
+ return true;
+ }
+ return false;
+}
+
+bool EglDisplay::removeContext(ContextPtr ctx) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+
+ ContextsHndlMap::iterator it;
+ for(it = m_contexts.begin(); it != m_contexts.end();it++) {
+ if((*it).second.Ptr() == ctx.Ptr()){
+ break;
+ }
+ }
+ if(it != m_contexts.end()) {
+ m_contexts.erase(it);
+ return true;
+ }
+ return false;
+}
+
+EglConfig* EglDisplay::getConfig(EGLint id) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+
+ for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end() ;it++) {
+ if((*it)->id() == id) {
+ return (*it);
+
+ }
+ }
+ return NULL;
+}
+
+int EglDisplay::getConfigs(EGLConfig* configs,int config_size) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+ int i = 0;
+ for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end() && i < config_size ;i++,it++) {
+ configs[i] = static_cast<EGLConfig>(*it);
+ }
+ return i;
+}
+
+int EglDisplay::chooseConfigs(const EglConfig& dummy,EGLConfig* configs,int config_size) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+ return doChooseConfigs(dummy, configs, config_size);
+}
+
+int EglDisplay::doChooseConfigs(const EglConfig& dummy,EGLConfig* configs,int config_size) {
+ int added = 0;
+ for(ConfigsList::iterator it = m_configs.begin(); it != m_configs.end() && (added < config_size || !configs);it++) {
+
+ if( (*it)->choosen(dummy)){
+ if(configs) {
+ configs[added] = static_cast<EGLConfig>(*it);
+ }
+ added++;
+ }
+ }
+ //no need to sort since the configurations are saved already in sorted maner
+ return added;
+}
+
+EGLSurface EglDisplay::addSurface(SurfacePtr s ) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+ unsigned int hndl = s.Ptr()->getHndl();
+ EGLSurface ret =reinterpret_cast<EGLSurface> (hndl);
+
+ if(m_surfaces.find(hndl) != m_surfaces.end()) {
+ return ret;
+ }
+
+ m_surfaces[hndl] = s;
+ return ret;
+}
+
+EGLContext EglDisplay::addContext(ContextPtr ctx ) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+
+ unsigned int hndl = ctx.Ptr()->getHndl();
+ EGLContext ret = reinterpret_cast<EGLContext> (hndl);
+
+ if(m_contexts.find(hndl) != m_contexts.end()) {
+ return ret;
+ }
+ m_contexts[hndl] = ctx;
+ return ret;
+}
+
+
+EGLImageKHR EglDisplay::addImageKHR(ImagePtr img) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+ do { ++m_nextEglImageId; } while(m_nextEglImageId == 0);
+ img->imageId = m_nextEglImageId;
+ m_eglImages[m_nextEglImageId] = img;
+ return reinterpret_cast<EGLImageKHR>(m_nextEglImageId);
+}
+
+ImagePtr EglDisplay::getImage(EGLImageKHR img) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+ /* img is "key" in map<unsigned int, ImagePtr>. */
+ unsigned int hndl = SafeUIntFromPointer(img);
+ ImagesHndlMap::iterator i( m_eglImages.find(hndl) );
+ return (i != m_eglImages.end()) ? (*i).second :ImagePtr(NULL);
+}
+
+bool EglDisplay:: destroyImageKHR(EGLImageKHR img) {
+ emugl::Mutex::AutoLock mutex(m_lock);
+ /* img is "key" in map<unsigned int, ImagePtr>. */
+ unsigned int hndl = SafeUIntFromPointer(img);
+ ImagesHndlMap::iterator i( m_eglImages.find(hndl) );
+ if (i != m_eglImages.end())
+ {
+ m_eglImages.erase(i);
+ return true;
+ }
+ return false;
+}
+
+EGLNativeContextType EglDisplay::getGlobalSharedContext(){
+ emugl::Mutex::AutoLock mutex(m_lock);
+#ifndef _WIN32
+ // find an existing OpenGL context to share with, if exist
+ EGLNativeContextType ret =
+ (EGLNativeContextType)m_manager[GLES_1_1]->getGlobalContext();
+ if (!ret)
+ ret = (EGLNativeContextType)m_manager[GLES_2_0]->getGlobalContext();
+ return ret;
+#else
+ if (!m_globalSharedContext) {
+ //
+ // On windows we create a dummy context to serve as the
+ // "global context" which all contexts share with.
+ // This is because on windows it is not possible to share
+ // with a context which is already current. This dummy context
+ // will never be current to any thread so it is safe to share with.
+ // Create that context using the first config
+ if (m_configs.size() < 1) {
+ // Should not happen! config list should be initialized at this point
+ return NULL;
+ }
+ EglConfig *cfg = (*m_configs.begin());
+ m_globalSharedContext = EglOS::createContext(m_dpy,cfg,NULL);
+ }
+
+ return m_globalSharedContext;
+#endif
+}