GLES20RenderEngine.cpp revision 49457ac092071a8f964f7f69156093657ccdc3d0
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#define ATRACE_TAG ATRACE_TAG_GRAPHICS 18 19#include <GLES2/gl2.h> 20#include <GLES2/gl2ext.h> 21 22#include <utils/String8.h> 23#include <utils/Trace.h> 24 25#include <cutils/compiler.h> 26 27#include "GLES20RenderEngine.h" 28#include "Program.h" 29#include "ProgramCache.h" 30#include "Description.h" 31#include "Mesh.h" 32#include "Texture.h" 33 34// --------------------------------------------------------------------------- 35namespace android { 36// --------------------------------------------------------------------------- 37 38GLES20RenderEngine::GLES20RenderEngine() { 39 40 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); 41 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); 42 43 glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 44 glPixelStorei(GL_PACK_ALIGNMENT, 4); 45 46 struct pack565 { 47 inline uint16_t operator() (int r, int g, int b) const { 48 return (r<<11)|(g<<5)|b; 49 } 50 } pack565; 51 52 const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; 53 glGenTextures(1, &mProtectedTexName); 54 glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 55 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 56 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 57 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 58 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 59 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, 60 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); 61} 62 63GLES20RenderEngine::~GLES20RenderEngine() { 64} 65 66 67size_t GLES20RenderEngine::getMaxTextureSize() const { 68 return mMaxTextureSize; 69} 70 71size_t GLES20RenderEngine::getMaxViewportDims() const { 72 return 73 mMaxViewportDims[0] < mMaxViewportDims[1] ? 74 mMaxViewportDims[0] : mMaxViewportDims[1]; 75} 76 77void GLES20RenderEngine::setViewportAndProjection( 78 size_t vpw, size_t vph, size_t w, size_t h, bool yswap) { 79 80 struct ortho { 81 inline void operator() (GLfloat *m, 82 GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, 83 GLfloat near, GLfloat far) const { 84 memset(m, 0, 16*sizeof(GLfloat)); 85 m[ 0] = 2.0f / (right - left); 86 m[ 5] = 2.0f / (top - bottom); 87 m[10] =-2.0f / (far - near); 88 m[15] = 1.0f; 89 m[12] = -(right + left) / (right - left); 90 m[13] = -(top + bottom) / (top - bottom); 91 m[14] = -(far + near) / (far - near); 92 } 93 } ortho; 94 95 GLfloat m[16]; 96 if (yswap) ortho(m, 0, w, h, 0, 0, 1); 97 else ortho(m, 0, w, 0, h, 0, 1); 98 99 glViewport(0, 0, vpw, vph); 100 mState.setProjectionMatrix(m); 101} 102 103void GLES20RenderEngine::setupLayerBlending( 104 bool premultipliedAlpha, bool opaque, int alpha) { 105 106 mState.setPremultipliedAlpha(premultipliedAlpha); 107 mState.setOpaque(opaque); 108 mState.setPlaneAlpha(alpha / 255.0f); 109 110 if (alpha < 0xFF || !opaque) { 111 glEnable(GL_BLEND); 112 glBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 113 } else { 114 glDisable(GL_BLEND); 115 } 116} 117 118void GLES20RenderEngine::setupDimLayerBlending(int alpha) { 119 mState.setPlaneAlpha(alpha / 255.0f); 120 121 if (alpha == 0xFF) { 122 glDisable(GL_BLEND); 123 } else { 124 glEnable(GL_BLEND); 125 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 126 } 127 disableTexturing(); 128} 129 130void GLES20RenderEngine::setupLayerTexturing(const Texture& texture) { 131 GLuint target = texture.getTextureTarget(); 132 glBindTexture(target, texture.getTextureName()); 133 GLenum filter = GL_NEAREST; 134 if (texture.getFiltering()) { 135 filter = GL_LINEAR; 136 } 137 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 138 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 139 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter); 140 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter); 141 142 mState.setTexture(texture); 143} 144 145void GLES20RenderEngine::setupLayerBlackedOut() { 146 glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 147 Texture texture(Texture::TEXTURE_2D, mProtectedTexName); 148 texture.setDimensions(1, 1); // FIXME: we should get that from somewhere 149 mState.setTexture(texture); 150} 151 152void GLES20RenderEngine::disableTexturing() { 153 mState.disableTexture(); 154} 155 156void GLES20RenderEngine::disableBlending() { 157 glDisable(GL_BLEND); 158} 159 160 161void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image, 162 uint32_t* texName, uint32_t* fbName, uint32_t* status) { 163 GLuint tname, name; 164 // turn our EGLImage into a texture 165 glGenTextures(1, &tname); 166 glBindTexture(GL_TEXTURE_2D, tname); 167 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image); 168 169 // create a Framebuffer Object to render into 170 glGenFramebuffers(1, &name); 171 glBindFramebuffer(GL_FRAMEBUFFER, name); 172 glFramebufferTexture2D(GL_FRAMEBUFFER, 173 GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0); 174 175 *status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 176 *texName = tname; 177 *fbName = name; 178} 179 180void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) { 181 glBindFramebuffer(GL_FRAMEBUFFER, 0); 182 glDeleteFramebuffers(1, &fbName); 183 glDeleteTextures(1, &texName); 184} 185 186void GLES20RenderEngine::fillWithColor(const Mesh& mesh, float r, float g, float b, float a) { 187 mState.setColor(r, g, b, a); 188 disableTexturing(); 189 glDisable(GL_BLEND); 190 191 ProgramCache::getInstance().useProgram(mState); 192 193 glVertexAttribPointer(Program::position, 194 mesh.getVertexSize(), 195 GL_FLOAT, GL_FALSE, 196 mesh.getByteStride(), 197 mesh.getPositions()); 198 199 glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount()); 200} 201 202void GLES20RenderEngine::drawMesh(const Mesh& mesh) { 203 204 ProgramCache::getInstance().useProgram(mState); 205 206 if (mesh.getTexCoordsSize()) { 207 glEnableVertexAttribArray(Program::texCoords); 208 glVertexAttribPointer(Program::texCoords, 209 mesh.getTexCoordsSize(), 210 GL_FLOAT, GL_FALSE, 211 mesh.getByteStride(), 212 mesh.getTexCoords()); 213 } 214 215 glVertexAttribPointer(Program::position, 216 mesh.getVertexSize(), 217 GL_FLOAT, GL_FALSE, 218 mesh.getByteStride(), 219 mesh.getPositions()); 220 221 glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount()); 222 223 if (mesh.getTexCoordsSize()) { 224 glDisableVertexAttribArray(Program::texCoords); 225 } 226} 227 228void GLES20RenderEngine::dump(String8& result) { 229 RenderEngine::dump(result); 230} 231 232// --------------------------------------------------------------------------- 233}; // namespace android 234// --------------------------------------------------------------------------- 235 236#if defined(__gl_h_) 237#error "don't include gl/gl.h in this file" 238#endif 239