RenderEngine.cpp revision 05f8c703d4a050669ff8f406be3a9dc2357935f7
1875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian/* 2875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian * Copyright 2013 The Android Open Source Project 3875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian * 4875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian * you may not use this file except in compliance with the License. 6875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian * You may obtain a copy of the License at 7875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian * 8875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian * 10875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian * Unless required by applicable law or agreed to in writing, software 11875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian * See the License for the specific language governing permissions and 14875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian * limitations under the License. 15875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian */ 16875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 17875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include <cutils/log.h> 183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include <ui/Rect.h> 193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include <ui/Region.h> 20875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 21875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine.h" 22875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "GLES10RenderEngine.h" 23875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "GLES11RenderEngine.h" 243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include "GLES20RenderEngine.h" 25875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "GLExtensions.h" 263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include "Mesh.h" 27875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 28875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian// --------------------------------------------------------------------------- 29875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopiannamespace android { 30875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian// --------------------------------------------------------------------------- 31875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 3205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse HallRenderEngine* RenderEngine::create(EGLDisplay display, int hwcFormat) { 3305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLConfig config = chooseEglConfig(display, hwcFormat); 3405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 352185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian EGLint renderableType = 0; 362185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian EGLint contextClientVersion = 0; 372185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian 382185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian // query the renderable type, setting the EGL_CONTEXT_CLIENT_VERSION accordingly 392185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian if (!eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType)) { 402185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian LOG_ALWAYS_FATAL("can't query EGLConfig RENDERABLE_TYPE"); 412185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian } 422185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian 432185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian if (renderableType & EGL_OPENGL_ES2_BIT) { 442185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian contextClientVersion = 2; 452185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian } else if (renderableType & EGL_OPENGL_ES_BIT) { 462185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian contextClientVersion = 1; 472185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian } else { 482185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian LOG_ALWAYS_FATAL("no supported EGL_RENDERABLE_TYPEs"); 492185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian } 502185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian 51875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // Also create our EGLContext 52875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian EGLint contextAttributes[] = { 532185f8b420ee1b150f761893a9c47cffff645cdeMathias Agopian EGL_CONTEXT_CLIENT_VERSION, contextClientVersion, // MUST be first 54875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#ifdef EGL_IMG_context_priority 55875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#ifdef HAS_CONTEXT_PRIORITY 56875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#warning "using EGL_IMG_context_priority" 57875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, 58875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#endif 59875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#endif 60875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian EGL_NONE, EGL_NONE 61875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian }; 62458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes); 63875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 64875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // if can't create a GL context, we can only abort. 65875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian LOG_ALWAYS_FATAL_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed"); 66875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 67875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 68875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // now figure out what version of GL did we actually get 69875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // NOTE: a dummy surface is not needed if KHR_create_context is supported 70875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 71875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE }; 72875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian EGLSurface dummy = eglCreatePbufferSurface(display, config, attribs); 73875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian LOG_ALWAYS_FATAL_IF(dummy==EGL_NO_SURFACE, "can't create dummy pbuffer"); 74875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt); 75875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian LOG_ALWAYS_FATAL_IF(!success, "can't make dummy pbuffer current"); 76875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 77875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian GLExtensions& extensions(GLExtensions::getInstance()); 78875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian extensions.initWithGLStrings( 79875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian glGetString(GL_VENDOR), 80875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian glGetString(GL_RENDERER), 81875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian glGetString(GL_VERSION), 82875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian glGetString(GL_EXTENSIONS)); 83875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 84875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian GlesVersion version = parseGlesVersion( extensions.getVersion() ); 85875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 86875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // initialize the renderer while GL is current 87875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 88875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian RenderEngine* engine = NULL; 89875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian switch (version) { 90875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian case GLES_VERSION_1_0: 91875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine = new GLES10RenderEngine(); 92875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian break; 93875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian case GLES_VERSION_1_1: 94875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian engine = new GLES11RenderEngine(); 95875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian break; 96875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian case GLES_VERSION_2_0: 97875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian case GLES_VERSION_3_0: 983f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian engine = new GLES20RenderEngine(); 99875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian break; 100875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian } 10105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall engine->setEGLHandles(config, ctxt); 102875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 103875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian ALOGI("OpenGL ES informations:"); 104875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian ALOGI("vendor : %s", extensions.getVendor()); 105875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian ALOGI("renderer : %s", extensions.getRenderer()); 106875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian ALOGI("version : %s", extensions.getVersion()); 107875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian ALOGI("extensions: %s", extensions.getExtension()); 108875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian ALOGI("GL_MAX_TEXTURE_SIZE = %d", engine->getMaxTextureSize()); 109875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian ALOGI("GL_MAX_VIEWPORT_DIMS = %d", engine->getMaxViewportDims()); 110875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 111875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 112875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian eglDestroySurface(display, dummy); 113875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 114875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return engine; 115875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian} 116875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 117875d8e1323536e16dcfc90c9674d7ad32116a69aMathias AgopianRenderEngine::RenderEngine() : mEGLContext(EGL_NO_CONTEXT) { 118875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian} 119875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 120875d8e1323536e16dcfc90c9674d7ad32116a69aMathias AgopianRenderEngine::~RenderEngine() { 121875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian} 122875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 12305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hallvoid RenderEngine::setEGLHandles(EGLConfig config, EGLContext ctxt) { 12405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mEGLConfig = config; 125875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian mEGLContext = ctxt; 126875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian} 127875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 12805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse HallEGLContext RenderEngine::getEGLConfig() const { 12905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall return mEGLConfig; 13005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall} 13105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 132875d8e1323536e16dcfc90c9674d7ad32116a69aMathias AgopianEGLContext RenderEngine::getEGLContext() const { 133875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return mEGLContext; 134875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian} 135875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 136875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopianvoid RenderEngine::checkErrors() const { 137875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian do { 138875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian // there could be more than one error flag 139875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian GLenum error = glGetError(); 140875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian if (error == GL_NO_ERROR) 141875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian break; 142875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian ALOGE("GL error 0x%04x", int(error)); 143875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian } while (true); 144875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian} 145875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 146875d8e1323536e16dcfc90c9674d7ad32116a69aMathias AgopianRenderEngine::GlesVersion RenderEngine::parseGlesVersion(const char* str) { 147875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian int major, minor; 148875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian if (sscanf(str, "OpenGL ES-CM %d.%d", &major, &minor) != 2) { 149875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian if (sscanf(str, "OpenGL ES %d.%d", &major, &minor) != 2) { 150875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian ALOGW("Unable to parse GL_VERSION string: \"%s\"", str); 151875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return GLES_VERSION_1_0; 152875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian } 153875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian } 154875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 155875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian if (major == 1 && minor == 0) return GLES_VERSION_1_0; 156875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian if (major == 1 && minor >= 1) return GLES_VERSION_1_1; 157875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian if (major == 2 && minor >= 0) return GLES_VERSION_2_0; 158875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian if (major == 3 && minor >= 0) return GLES_VERSION_3_0; 159875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 160875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian ALOGW("Unrecognized OpenGL ES version: %d.%d", major, minor); 161875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian return GLES_VERSION_1_0; 162875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian} 163875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian 1643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid RenderEngine::fillRegionWithColor(const Region& region, uint32_t height, 1653f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian float red, float green, float blue, float alpha) { 1663f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian size_t c; 1673f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian Rect const* r = region.getArray(&c); 1683f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian Mesh mesh(Mesh::TRIANGLES, c*6, 2); 169ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>()); 1703f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian for (size_t i=0 ; i<c ; i++, r++) { 1715cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i*6 + 0].x = r->left; 1725cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i*6 + 0].y = height - r->top; 1735cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i*6 + 1].x = r->left; 1745cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i*6 + 1].y = height - r->bottom; 1755cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i*6 + 2].x = r->right; 1765cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i*6 + 2].y = height - r->bottom; 1775cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i*6 + 3].x = r->left; 1785cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i*6 + 3].y = height - r->top; 1795cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i*6 + 4].x = r->right; 1805cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i*6 + 4].y = height - r->bottom; 1815cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i*6 + 5].x = r->right; 1825cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian position[i*6 + 5].y = height - r->top; 1833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian } 18419733a32799f792125913e746e8644d16f8dc223Mathias Agopian setupFillWithColor(red, green, blue, alpha); 18519733a32799f792125913e746e8644d16f8dc223Mathias Agopian drawMesh(mesh); 1863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian} 1873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 1883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid RenderEngine::clearWithColor(float red, float green, float blue, float alpha) { 1893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian glClearColor(red, green, blue, alpha); 1903f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian glClear(GL_COLOR_BUFFER_BIT); 1913f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian} 1923f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 1933f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid RenderEngine::setScissor( 1943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian uint32_t left, uint32_t bottom, uint32_t right, uint32_t top) { 1953f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian glScissor(left, bottom, right, top); 1963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian glEnable(GL_SCISSOR_TEST); 1973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian} 1983f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 1993f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid RenderEngine::disableScissor() { 2003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian glDisable(GL_SCISSOR_TEST); 2013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian} 2023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 2033f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid RenderEngine::genTextures(size_t count, uint32_t* names) { 2043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian glGenTextures(count, names); 2053f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian} 2063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 2073f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid RenderEngine::deleteTextures(size_t count, uint32_t const* names) { 2083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian glDeleteTextures(count, names); 2093f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian} 2103f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 211d555684cb36dfb959694db76962e570184f98838Mathias Agopianvoid RenderEngine::readPixels(size_t l, size_t b, size_t w, size_t h, uint32_t* pixels) { 212d555684cb36dfb959694db76962e570184f98838Mathias Agopian glReadPixels(l, b, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 213d555684cb36dfb959694db76962e570184f98838Mathias Agopian} 214d555684cb36dfb959694db76962e570184f98838Mathias Agopian 215458197de008be8fe561286b09f4edddb2f5c540aMathias Agopianvoid RenderEngine::dump(String8& result) { 216458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian const GLExtensions& extensions(GLExtensions::getInstance()); 217458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian result.appendFormat("GLES: %s, %s, %s\n", 218458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian extensions.getVendor(), 219458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian extensions.getRenderer(), 220458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian extensions.getVersion()); 221458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian result.appendFormat("%s\n", extensions.getExtension()); 222458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian} 223458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian 2243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian// --------------------------------------------------------------------------- 2253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 2263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias AgopianRenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer( 2273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian RenderEngine& engine, EGLImageKHR image) : mEngine(engine) 2283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian{ 229458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus); 230458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian 2313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES, 2323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian "glCheckFramebufferStatusOES error %d", mStatus); 2333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian} 2343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 2353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias AgopianRenderEngine::BindImageAsFramebuffer::~BindImageAsFramebuffer() { 2363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian // back to main framebuffer 237458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian mEngine.unbindFramebuffer(mTexName, mFbName); 2383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian} 2393f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 2403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t RenderEngine::BindImageAsFramebuffer::getStatus() const { 2413f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian return mStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE; 2423f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian} 2433f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian 244875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian// --------------------------------------------------------------------------- 24505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 24605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hallstatic status_t selectConfigForAttribute(EGLDisplay dpy, EGLint const* attrs, 24705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLint attribute, EGLint wanted, EGLConfig* outConfig) { 24805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLConfig config = NULL; 24905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLint numConfigs = -1, n = 0; 25005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall eglGetConfigs(dpy, NULL, 0, &numConfigs); 25105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLConfig* const configs = new EGLConfig[numConfigs]; 25205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall eglChooseConfig(dpy, attrs, configs, numConfigs, &n); 25305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 25405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall if (n) { 25505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall if (attribute != EGL_NONE) { 25605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall for (int i=0 ; i<n ; i++) { 25705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLint value = 0; 25805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall eglGetConfigAttrib(dpy, configs[i], attribute, &value); 25905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall if (wanted == value) { 26005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall *outConfig = configs[i]; 26105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall delete [] configs; 26205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall return NO_ERROR; 26305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 26405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 26505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } else { 26605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall // just pick the first one 26705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall *outConfig = configs[0]; 26805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall delete [] configs; 26905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall return NO_ERROR; 27005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 27105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 27205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall delete [] configs; 27305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall return NAME_NOT_FOUND; 27405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall} 27505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 27605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hallclass EGLAttributeVector { 27705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall struct Attribute; 27805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall class Adder; 27905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall friend class Adder; 28005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall KeyedVector<Attribute, EGLint> mList; 28105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall struct Attribute { 28205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall Attribute() {}; 28305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall Attribute(EGLint v) : v(v) { } 28405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLint v; 28505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall bool operator < (const Attribute& other) const { 28605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall // this places EGL_NONE at the end 28705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLint lhs(v); 28805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLint rhs(other.v); 28905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall if (lhs == EGL_NONE) lhs = 0x7FFFFFFF; 29005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall if (rhs == EGL_NONE) rhs = 0x7FFFFFFF; 29105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall return lhs < rhs; 29205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 29305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall }; 29405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall class Adder { 29505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall friend class EGLAttributeVector; 29605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLAttributeVector& v; 29705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLint attribute; 29805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall Adder(EGLAttributeVector& v, EGLint attribute) 29905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall : v(v), attribute(attribute) { 30005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 30105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall public: 30205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall void operator = (EGLint value) { 30305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall if (attribute != EGL_NONE) { 30405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall v.mList.add(attribute, value); 30505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 30605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 30705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall operator EGLint () const { return v.mList[attribute]; } 30805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall }; 30905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hallpublic: 31005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLAttributeVector() { 31105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mList.add(EGL_NONE, EGL_NONE); 31205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 31305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall void remove(EGLint attribute) { 31405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall if (attribute != EGL_NONE) { 31505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall mList.removeItem(attribute); 31605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 31705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 31805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall Adder operator [] (EGLint attribute) { 31905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall return Adder(*this, attribute); 32005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 32105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLint operator [] (EGLint attribute) const { 32205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall return mList[attribute]; 32305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 32405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall // cast-operator to (EGLint const*) 32505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall operator EGLint const* () const { return &mList.keyAt(0).v; } 32605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall}; 32705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 32805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 32905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hallstatic status_t selectEGLConfig(EGLDisplay display, EGLint format, 33005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLint renderableType, EGLConfig* config) { 33105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if 33205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall // it is to be used with WIFI displays 33305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall status_t err; 33405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLint wantedAttribute; 33505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLint wantedAttributeValue; 33605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 33705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLAttributeVector attribs; 33805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall if (renderableType) { 33905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall attribs[EGL_RENDERABLE_TYPE] = renderableType; 34005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall attribs[EGL_RECORDABLE_ANDROID] = EGL_TRUE; 34105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall attribs[EGL_SURFACE_TYPE] = EGL_WINDOW_BIT|EGL_PBUFFER_BIT; 34205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall attribs[EGL_FRAMEBUFFER_TARGET_ANDROID] = EGL_TRUE; 34305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall attribs[EGL_RED_SIZE] = 8; 34405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall attribs[EGL_GREEN_SIZE] = 8; 34505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall attribs[EGL_BLUE_SIZE] = 8; 34605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall wantedAttribute = EGL_NONE; 34705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall wantedAttributeValue = EGL_NONE; 34805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } else { 34905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall // if no renderable type specified, fallback to a simplified query 35005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall wantedAttribute = EGL_NATIVE_VISUAL_ID; 35105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall wantedAttributeValue = format; 35205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 35305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 35405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall err = selectConfigForAttribute(display, attribs, 35505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall wantedAttribute, wantedAttributeValue, config); 35605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall if (err == NO_ERROR) { 35705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLint caveat; 35805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall if (eglGetConfigAttrib(display, *config, EGL_CONFIG_CAVEAT, &caveat)) 35905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall ALOGW_IF(caveat == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!"); 36005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 36105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 36205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall return err; 36305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall} 36405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 36505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse HallEGLConfig RenderEngine::chooseEglConfig(EGLDisplay display, int format) { 36605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall status_t err; 36705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLConfig config; 36805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 36905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall // First try to get an ES2 config 37005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall err = selectEGLConfig(display, format, EGL_OPENGL_ES2_BIT, &config); 37105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall if (err != NO_ERROR) { 37205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall // If ES2 fails, try ES1 37305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall err = selectEGLConfig(display, format, EGL_OPENGL_ES_BIT, &config); 37405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall if (err != NO_ERROR) { 37505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall // still didn't work, probably because we're on the emulator... 37605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall // try a simplified query 37705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall ALOGW("no suitable EGLConfig found, trying a simpler query"); 37805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall err = selectEGLConfig(display, format, 0, &config); 37905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall if (err != NO_ERROR) { 38005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall // this EGL is too lame for android 38105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall LOG_ALWAYS_FATAL("no suitable EGLConfig found, giving up"); 38205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 38305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 38405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall } 38505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 38605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall // print some debugging info 38705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall EGLint r,g,b,a; 38805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall eglGetConfigAttrib(display, config, EGL_RED_SIZE, &r); 38905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g); 39005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &b); 39105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a); 39205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall ALOGI("EGL information:"); 39305f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall ALOGI("vendor : %s", eglQueryString(display, EGL_VENDOR)); 39405f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall ALOGI("version : %s", eglQueryString(display, EGL_VERSION)); 39505f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall ALOGI("extensions: %s", eglQueryString(display, EGL_EXTENSIONS)); 39605f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); 39705f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config); 39805f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 39905f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall return config; 40005f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall} 40105f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall 40205f8c703d4a050669ff8f406be3a9dc2357935f7Jesse Hall// --------------------------------------------------------------------------- 403875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian}; // namespace android 404875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian// --------------------------------------------------------------------------- 405