165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/* 265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2011 The Android Open Source Project 365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License"); 565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License. 665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at 765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * http://www.apache.org/licenses/LICENSE-2.0 965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software 1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS, 1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and 1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License. 1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// #define LOG_NDEBUG 0 1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "base/logging.h" 1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "base/utilities.h" 2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "core/gl_env.h" 2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "core/shader_program.h" 2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "core/vertex_frame.h" 2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "system/window.h" 2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <map> 2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <string> 2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <EGL/eglext.h> 2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennnamespace android { 3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennnamespace filterfw { 3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennGLEnv::GLEnv() 3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn : display_(EGL_NO_DISPLAY), 3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn context_id_(0), 3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn surface_id_(0), 3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn max_surface_id_(0), 3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn created_context_(false), 3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn created_surface_(false), 3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn initialized_(false) { 4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennGLEnv::~GLEnv() { 4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Destroy surfaces 4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (std::map<int, SurfaceWindowPair>::iterator it = surfaces_.begin(); 4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn it != surfaces_.end(); 4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ++it) { 4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (it->first != 0 || created_surface_) { 4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglDestroySurface(display(), it->second.first); 4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (it->second.second) { 5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn it->second.second->Destroy(); 5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete it->second.second; 5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Destroy contexts 5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (std::map<int, EGLContext>::iterator it = contexts_.begin(); 5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn it != contexts_.end(); 5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ++it) { 6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (it->first != 0 || created_context_) 6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglDestroyContext(display(), it->second); 6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Destroy attached shaders and frames 6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn STLDeleteValues(&attached_shaders_); 6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn STLDeleteValues(&attached_vframes_); 6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Destroy display 6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (initialized_) 7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglTerminate(display()); 7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Log error if this did not work 7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (CheckEGLError("TearDown!")) 7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnv: Error tearing down GL Environment!"); 7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::IsInitialized() const { 7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return (contexts_.size() > 0 && 7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn surfaces_.size() > 0 && 8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn display_ != EGL_NO_DISPLAY); 8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::Deactivate() { 8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglMakeCurrent(display(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return !CheckEGLError("eglMakeCurrent"); 8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::Activate() { 8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGV("Activate()"); 9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (display() != eglGetCurrentDisplay() || 9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn context() != eglGetCurrentContext() || 9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn surface() != eglGetCurrentSurface(EGL_DRAW)) { 9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Make sure we are initialized 9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (context() == EGL_NO_CONTEXT || surface() == EGL_NO_SURFACE) 9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return false; 9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Make our context current 9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGV("eglMakeCurrent"); 9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglMakeCurrent(display(), surface(), surface(), context()); 10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return !CheckEGLMakeCurrentError(); 10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return true; 10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::SwapBuffers() { 10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const bool result = eglSwapBuffers(display(), surface()) == EGL_TRUE; 10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return !CheckEGLError("eglSwapBuffers") && result; 10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::InitWithCurrentContext() { 11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (IsInitialized()) 11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return true; 11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn display_ = eglGetCurrentDisplay(); 11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn contexts_[0] = eglGetCurrentContext(); 11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn surfaces_[0] = SurfaceWindowPair(eglGetCurrentSurface(EGL_DRAW), NULL); 11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return (context() != EGL_NO_CONTEXT) && 12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn (display() != EGL_NO_DISPLAY) && 12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn (surface() != EGL_NO_SURFACE); 12265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 12365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::InitWithNewContext() { 12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (IsInitialized()) { 12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnv: Attempting to reinitialize environment!"); 12765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return false; 12865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); 13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (CheckEGLError("eglGetDisplay")) return false; 13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint majorVersion; 13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint minorVersion; 13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglInitialize(display(), &majorVersion, &minorVersion); 13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (CheckEGLError("eglInitialize")) return false; 13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn initialized_ = true; 13865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 13965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Configure context/surface 14065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLConfig config; 14165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint numConfigs = -1; 14265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 14365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // TODO(renn): Do we need the window bit here? 14465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // TODO: Currently choosing the config that includes all 14565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // This is not needed if the encoding is not being used 14665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint configAttribs[] = { 14765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 14865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 14965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RED_SIZE, 8, 15065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_GREEN_SIZE, 8, 15165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_BLUE_SIZE, 8, 15265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_RECORDABLE_ANDROID, EGL_TRUE, 15365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_NONE 15465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn }; 15565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 15665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglChooseConfig(display(), configAttribs, &config, 1, &numConfigs); 15765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (numConfigs < 1) { 15865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GLEnv::Init: No suitable EGL configuration found!"); 15965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return false; 16065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 16165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create dummy surface using a SurfaceTexture 16365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn surfaceTexture_ = new SurfaceTexture(0); 16465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn window_ = new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >( 16565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn surfaceTexture_->getBufferQueue())); 16665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn surfaces_[0] = SurfaceWindowPair(eglCreateWindowSurface(display(), config, window_.get(), NULL), NULL); 16865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (CheckEGLError("eglCreateWindowSurface")) return false; 16965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 17065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create context 17165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; 17265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn contexts_[0] = eglCreateContext(display(), 17365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn config, 17465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn EGL_NO_CONTEXT, 17565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn context_attribs); 17665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (CheckEGLError("eglCreateContext")) return false; 17765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 17865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn created_context_ = created_surface_ = true; 17965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 18065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return true; 18165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 18265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 18365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::IsActive() const { 18465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGV("IsActive()"); 18565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return context() == eglGetCurrentContext() 18665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn && display() == eglGetCurrentDisplay() 18765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn && surface() == eglGetCurrentSurface(EGL_DRAW); 18865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 18965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 19065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::IsContextActive() const { 19165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return context() == eglGetCurrentContext(); 19265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 19365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 19465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::IsAnyContextActive() { 19565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return eglGetCurrentContext() != EGL_NO_CONTEXT; 19665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 19765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 19865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennint GLEnv::AddWindowSurface(const EGLSurface& surface, WindowHandle* window_handle) { 19965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const int id = ++max_surface_id_; 20065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn surfaces_[id] = SurfaceWindowPair(surface, window_handle); 20165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return id; 20265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 20365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 20465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennint GLEnv::AddSurface(const EGLSurface& surface) { 20565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return AddWindowSurface(surface, NULL); 20665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 20765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 20865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::SwitchToSurfaceId(int surface_id) { 20965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGV("SwitchToSurfaceId"); 21065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (surface_id_ != surface_id) { 21165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const SurfaceWindowPair* surface = FindOrNull(surfaces_, surface_id); 21265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (surface) { 21365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn bool wasActive = IsActive(); 21465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn surface_id_ = surface_id; 21565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return wasActive ? Activate() : true; 21665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 21765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return false; 21865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 21965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return true; 22065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 22165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 22265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::ReleaseSurfaceId(int surface_id) { 22365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (surface_id > 0) { 22465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const SurfaceWindowPair* surface_window_pair = FindOrNull(surfaces_, surface_id); 22565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (surface_window_pair) { 22665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (surface_id_ == surface_id) 22765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn SwitchToSurfaceId(0); 22865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglDestroySurface(display(), surface_window_pair->first); 22965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (surface_window_pair->second) { 23065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn surface_window_pair->second->Destroy(); 23165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete surface_window_pair->second; 23265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 23365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn surfaces_.erase(surface_id); 23465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return true; 23565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 23665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 23765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return false; 23865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 23965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 24065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::SetSurfaceTimestamp(int64_t timestamp) { 24165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (surface_id_ > 0) { 24265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const SurfaceWindowPair* surface_window_pair = FindOrNull(surfaces_, 24365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn surface_id_); 24465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (surface_window_pair) { 24565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ANativeWindow *window = static_cast<ANativeWindow*>( 24665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn surface_window_pair->second->InternalHandle()); 24765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn native_window_set_buffers_timestamp(window, timestamp); 24865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return true; 24965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 25065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 25165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return false; 25265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 25365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 25465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennint GLEnv::FindSurfaceIdForWindow(const WindowHandle* window_handle) { 25565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (std::map<int, SurfaceWindowPair>::iterator it = surfaces_.begin(); 25665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn it != surfaces_.end(); 25765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ++it) { 25865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const WindowHandle* my_handle = it->second.second; 25965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (my_handle && my_handle->Equals(window_handle)) { 26065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return it->first; 26165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 26265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 26365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return -1; 26465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 26565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennint GLEnv::AddContext(const EGLContext& context) { 26865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const int id = contexts_.size(); 26965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn contexts_[id] = context; 27065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return id; 27165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 27265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 27365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::SwitchToContextId(int context_id) { 27465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const EGLContext* context = FindOrNull(contexts_, context_id); 27565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (context) { 27665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (context_id_ != context_id) { 27765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn context_id_ = context_id; 27865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return Activate(); 27965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 28065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return true; 28165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 28265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return false; 28365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 28465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 28565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennvoid GLEnv::ReleaseContextId(int context_id) { 28665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (context_id > 0) { 28765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const EGLContext* context = FindOrNull(contexts_, context_id); 28865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (context) { 28965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn contexts_.erase(context_id); 29065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (context_id_ == context_id && IsActive()) 29165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn SwitchToContextId(0); 29265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn eglDestroyContext(display(), *context); 29365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 29465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 29565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 29665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 29765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::CheckGLError(const std::string& op) { 29865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn bool err = false; 29965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (GLint error = glGetError(); error; error = glGetError()) { 30065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("GL Error: Operation '%s' caused GL error (0x%x)\n", 30165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn op.c_str(), 30265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn error); 30365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn err = true; 30465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 30565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return err; 30665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 30765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 30865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::CheckEGLError(const std::string& op) { 30965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn bool err = false; 31065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (EGLint error = eglGetError(); 31165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn error != EGL_SUCCESS; 31265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn error = eglGetError()) { 31365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("EGL Error: Operation '%s' caused EGL error (0x%x)\n", 31465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn op.c_str(), 31565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn error); 31665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn err = true; 31765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 31865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return err; 31965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 32065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 32165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool GLEnv::CheckEGLMakeCurrentError() { 32265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn bool err = false; 32365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn for (EGLint error = eglGetError(); 32465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn error != EGL_SUCCESS; 32565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn error = eglGetError()) { 32665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn switch (error) { 32765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case EGL_BAD_DISPLAY: 32865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("EGL Error: Attempting to activate context with bad display!"); 32965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn break; 33065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case EGL_BAD_SURFACE: 33165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("EGL Error: Attempting to activate context with bad surface!"); 33265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn break; 33365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case EGL_BAD_ACCESS: 33465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("EGL Error: Attempting to activate context, which is " 33565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "already active in another thread!"); 33665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn break; 33765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn default: 33865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOGE("EGL Error: Making EGL rendering context current caused " 33965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "error: 0x%x\n", error); 34065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 34165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn err = true; 34265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 34365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return err; 34465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 34565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 34665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennGLuint GLEnv::GetCurrentProgram() { 34765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn GLint result; 34865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn glGetIntegerv(GL_CURRENT_PROGRAM, &result); 34965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ALOG_ASSERT(result >= 0); 35065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return static_cast<GLuint>(result); 35165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 35265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 35365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennEGLDisplay GLEnv::GetCurrentDisplay() { 35465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return eglGetCurrentDisplay(); 35565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 35665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 35765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennint GLEnv::NumberOfComponents(GLenum type) { 35865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn switch (type) { 35965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_BOOL: 36065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_FLOAT: 36165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_INT: 36265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return 1; 36365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_BOOL_VEC2: 36465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_FLOAT_VEC2: 36565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_INT_VEC2: 36665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return 2; 36765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_INT_VEC3: 36865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_FLOAT_VEC3: 36965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_BOOL_VEC3: 37065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return 3; 37165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_BOOL_VEC4: 37265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_FLOAT_VEC4: 37365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_INT_VEC4: 37465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_FLOAT_MAT2: 37565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return 4; 37665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_FLOAT_MAT3: 37765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return 9; 37865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn case GL_FLOAT_MAT4: 37965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return 16; 38065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn default: 38165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return 0; 38265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 38365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 38465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 38565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennvoid GLEnv::AttachShader(int key, ShaderProgram* shader) { 38665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ShaderProgram* existingShader = ShaderWithKey(key); 38765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (existingShader) 38865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete existingShader; 38965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn attached_shaders_[key] = shader; 39065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 39165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 39265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennvoid GLEnv::AttachVertexFrame(int key, VertexFrame* frame) { 39365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn VertexFrame* existingFrame = VertexFrameWithKey(key); 39465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (existingFrame) 39565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete existingFrame; 39665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn attached_vframes_[key] = frame; 39765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 39865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 39965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennShaderProgram* GLEnv::ShaderWithKey(int key) { 40065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return FindPtrOrNull(attached_shaders_, key); 40165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 40265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 40365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennVertexFrame* GLEnv::VertexFrameWithKey(int key) { 40465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return FindPtrOrNull(attached_vframes_, key); 40565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 40665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 40765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} // namespace filterfw 40865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} // namespace android 409