diff options
author | Greg Hartman <ghartman@google.com> | 2018-08-17 12:43:34 -0700 |
---|---|---|
committer | Greg Hartman <ghartman@google.com> | 2018-08-23 17:24:52 -0700 |
commit | 8cf8f6b088cc014921e1a9b3d4ebc93c3b5de8b8 (patch) | |
tree | d4968732d8516f2940cfcb340bacdf7693e0ceb3 /distrib/android-emugl/host/libs/Translator/EGL/EglDisplay.cpp | |
parent | 182e4691d1c5e724fc60ed94b6de8a3356018cb6 (diff) | |
download | device_generic_opengl-transport-8cf8f6b088cc014921e1a9b3d4ebc93c3b5de8b8.tar.gz device_generic_opengl-transport-8cf8f6b088cc014921e1a9b3d4ebc93c3b5de8b8.tar.bz2 device_generic_opengl-transport-8cf8f6b088cc014921e1a9b3d4ebc93c3b5de8b8.zip |
distrib/android-emugl: Move Android GPU emulation sources here.
This patch is used to add the unmodified sources of the GPU
emulation libraries that are normally under sdk/emulator/opengl/.
These sources were originally built with the platform build system,
but this is no longer the case. Since they are only built through
the emulator's own build system (i.e. android-rebuild.sh), it's
easier to put them under external/qemu/ to ensure that they are
always in sync with the rest of the emulator.
Note that the encoder sources are still in the platform under
device/generic/goldfish/opengl/.
A future patch will update the emulator build system to pick
the sources from here, and another one will remove the sources
from sdk/ after that.
Note: these are the unmodified sources from the following
commit in https://android.googlesource.com/platform/sdk.git :
182e469 emulator/opengl: Fix Windows cross-build.
Change-Id: If2010577ef4af4c6755ab345f424af0b546f9282
Diffstat (limited to 'distrib/android-emugl/host/libs/Translator/EGL/EglDisplay.cpp')
-rw-r--r-- | distrib/android-emugl/host/libs/Translator/EGL/EglDisplay.cpp | 343 |
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 +} |