1 /* 2 * Copyright 2013 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 17 #include <cutils/log.h> 18 #include <ui/Rect.h> 19 #include <ui/Region.h> 20 21 #include "RenderEngine.h" 22 #include "GLES10RenderEngine.h" 23 #include "GLES11RenderEngine.h" 24 #include "GLES20RenderEngine.h" 25 #include "GLExtensions.h" 26 #include "Mesh.h" 27 28 // --------------------------------------------------------------------------- 29 namespace android { 30 // --------------------------------------------------------------------------- 31 32 RenderEngine* RenderEngine::create(EGLDisplay display, EGLConfig config) { 33 EGLint renderableType = 0; 34 EGLint contextClientVersion = 0; 35 36 // query the renderable type, setting the EGL_CONTEXT_CLIENT_VERSION accordingly 37 if (!eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType)) { 38 LOG_ALWAYS_FATAL("can't query EGLConfig RENDERABLE_TYPE"); 39 } 40 41 if (renderableType & EGL_OPENGL_ES2_BIT) { 42 contextClientVersion = 2; 43 } else if (renderableType & EGL_OPENGL_ES_BIT) { 44 contextClientVersion = 1; 45 } else { 46 LOG_ALWAYS_FATAL("no supported EGL_RENDERABLE_TYPEs"); 47 } 48 49 // Also create our EGLContext 50 EGLint contextAttributes[] = { 51 EGL_CONTEXT_CLIENT_VERSION, contextClientVersion, // MUST be first 52 #ifdef EGL_IMG_context_priority 53 #ifdef HAS_CONTEXT_PRIORITY 54 #warning "using EGL_IMG_context_priority" 55 EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, 56 #endif 57 #endif 58 EGL_NONE, EGL_NONE 59 }; 60 EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes); 61 62 // if can't create a GL context, we can only abort. 63 LOG_ALWAYS_FATAL_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed"); 64 65 66 // now figure out what version of GL did we actually get 67 // NOTE: a dummy surface is not needed if KHR_create_context is supported 68 69 EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE }; 70 EGLSurface dummy = eglCreatePbufferSurface(display, config, attribs); 71 LOG_ALWAYS_FATAL_IF(dummy==EGL_NO_SURFACE, "can't create dummy pbuffer"); 72 EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt); 73 LOG_ALWAYS_FATAL_IF(!success, "can't make dummy pbuffer current"); 74 75 GLExtensions& extensions(GLExtensions::getInstance()); 76 extensions.initWithGLStrings( 77 glGetString(GL_VENDOR), 78 glGetString(GL_RENDERER), 79 glGetString(GL_VERSION), 80 glGetString(GL_EXTENSIONS)); 81 82 GlesVersion version = parseGlesVersion( extensions.getVersion() ); 83 84 // initialize the renderer while GL is current 85 86 RenderEngine* engine = NULL; 87 switch (version) { 88 case GLES_VERSION_1_0: 89 engine = new GLES10RenderEngine(); 90 break; 91 case GLES_VERSION_1_1: 92 engine = new GLES11RenderEngine(); 93 break; 94 case GLES_VERSION_2_0: 95 case GLES_VERSION_3_0: 96 engine = new GLES20RenderEngine(); 97 break; 98 } 99 engine->setEGLContext(ctxt); 100 101 ALOGI("OpenGL ES informations:"); 102 ALOGI("vendor : %s", extensions.getVendor()); 103 ALOGI("renderer : %s", extensions.getRenderer()); 104 ALOGI("version : %s", extensions.getVersion()); 105 ALOGI("extensions: %s", extensions.getExtension()); 106 ALOGI("GL_MAX_TEXTURE_SIZE = %d", engine->getMaxTextureSize()); 107 ALOGI("GL_MAX_VIEWPORT_DIMS = %d", engine->getMaxViewportDims()); 108 109 eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 110 eglDestroySurface(display, dummy); 111 112 return engine; 113 } 114 115 RenderEngine::RenderEngine() : mEGLContext(EGL_NO_CONTEXT) { 116 } 117 118 RenderEngine::~RenderEngine() { 119 } 120 121 void RenderEngine::setEGLContext(EGLContext ctxt) { 122 mEGLContext = ctxt; 123 } 124 125 EGLContext RenderEngine::getEGLContext() const { 126 return mEGLContext; 127 } 128 129 void RenderEngine::checkErrors() const { 130 do { 131 // there could be more than one error flag 132 GLenum error = glGetError(); 133 if (error == GL_NO_ERROR) 134 break; 135 ALOGE("GL error 0x%04x", int(error)); 136 } while (true); 137 } 138 139 RenderEngine::GlesVersion RenderEngine::parseGlesVersion(const char* str) { 140 int major, minor; 141 if (sscanf(str, "OpenGL ES-CM %d.%d", &major, &minor) != 2) { 142 if (sscanf(str, "OpenGL ES %d.%d", &major, &minor) != 2) { 143 ALOGW("Unable to parse GL_VERSION string: \"%s\"", str); 144 return GLES_VERSION_1_0; 145 } 146 } 147 148 if (major == 1 && minor == 0) return GLES_VERSION_1_0; 149 if (major == 1 && minor >= 1) return GLES_VERSION_1_1; 150 if (major == 2 && minor >= 0) return GLES_VERSION_2_0; 151 if (major == 3 && minor >= 0) return GLES_VERSION_3_0; 152 153 ALOGW("Unrecognized OpenGL ES version: %d.%d", major, minor); 154 return GLES_VERSION_1_0; 155 } 156 157 void RenderEngine::fillRegionWithColor(const Region& region, uint32_t height, 158 float red, float green, float blue, float alpha) { 159 size_t c; 160 Rect const* r = region.getArray(&c); 161 Mesh mesh(Mesh::TRIANGLES, c*6, 2); 162 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>()); 163 for (size_t i=0 ; i<c ; i++, r++) { 164 position[i*6 + 0].x = r->left; 165 position[i*6 + 0].y = height - r->top; 166 position[i*6 + 1].x = r->left; 167 position[i*6 + 1].y = height - r->bottom; 168 position[i*6 + 2].x = r->right; 169 position[i*6 + 2].y = height - r->bottom; 170 position[i*6 + 3].x = r->left; 171 position[i*6 + 3].y = height - r->top; 172 position[i*6 + 4].x = r->right; 173 position[i*6 + 4].y = height - r->bottom; 174 position[i*6 + 5].x = r->right; 175 position[i*6 + 5].y = height - r->top; 176 } 177 setupFillWithColor(red, green, blue, alpha); 178 drawMesh(mesh); 179 } 180 181 void RenderEngine::clearWithColor(float red, float green, float blue, float alpha) { 182 glClearColor(red, green, blue, alpha); 183 glClear(GL_COLOR_BUFFER_BIT); 184 } 185 186 void RenderEngine::setScissor( 187 uint32_t left, uint32_t bottom, uint32_t right, uint32_t top) { 188 glScissor(left, bottom, right, top); 189 glEnable(GL_SCISSOR_TEST); 190 } 191 192 void RenderEngine::disableScissor() { 193 glDisable(GL_SCISSOR_TEST); 194 } 195 196 void RenderEngine::genTextures(size_t count, uint32_t* names) { 197 glGenTextures(count, names); 198 } 199 200 void RenderEngine::deleteTextures(size_t count, uint32_t const* names) { 201 glDeleteTextures(count, names); 202 } 203 204 void RenderEngine::readPixels(size_t l, size_t b, size_t w, size_t h, uint32_t* pixels) { 205 glReadPixels(l, b, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 206 } 207 208 void RenderEngine::dump(String8& result) { 209 const GLExtensions& extensions(GLExtensions::getInstance()); 210 result.appendFormat("GLES: %s, %s, %s\n", 211 extensions.getVendor(), 212 extensions.getRenderer(), 213 extensions.getVersion()); 214 result.appendFormat("%s\n", extensions.getExtension()); 215 } 216 217 // --------------------------------------------------------------------------- 218 219 RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer( 220 RenderEngine& engine, EGLImageKHR image) : mEngine(engine) 221 { 222 mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus); 223 224 ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES, 225 "glCheckFramebufferStatusOES error %d", mStatus); 226 } 227 228 RenderEngine::BindImageAsFramebuffer::~BindImageAsFramebuffer() { 229 // back to main framebuffer 230 mEngine.unbindFramebuffer(mTexName, mFbName); 231 } 232 233 status_t RenderEngine::BindImageAsFramebuffer::getStatus() const { 234 return mStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE; 235 } 236 237 // --------------------------------------------------------------------------- 238 }; // namespace android 239 // --------------------------------------------------------------------------- 240