GLES20RenderEngine.cpp revision 19733a32799f792125913e746e8644d16f8dc223
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(1.0f); 120 mState.setPremultipliedAlpha(true); 121 mState.setOpaque(false); 122 mState.setColor(0, 0, 0, alpha/255.0f); 123 mState.disableTexture(); 124 125 if (alpha == 0xFF) { 126 glDisable(GL_BLEND); 127 } else { 128 glEnable(GL_BLEND); 129 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 130 } 131} 132 133void GLES20RenderEngine::setupLayerTexturing(const Texture& texture) { 134 GLuint target = texture.getTextureTarget(); 135 glBindTexture(target, texture.getTextureName()); 136 GLenum filter = GL_NEAREST; 137 if (texture.getFiltering()) { 138 filter = GL_LINEAR; 139 } 140 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 141 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 142 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter); 143 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter); 144 145 mState.setTexture(texture); 146} 147 148void GLES20RenderEngine::setupLayerBlackedOut() { 149 glBindTexture(GL_TEXTURE_2D, mProtectedTexName); 150 Texture texture(Texture::TEXTURE_2D, mProtectedTexName); 151 texture.setDimensions(1, 1); // FIXME: we should get that from somewhere 152 mState.setTexture(texture); 153} 154 155void GLES20RenderEngine::disableTexturing() { 156 mState.disableTexture(); 157} 158 159void GLES20RenderEngine::disableBlending() { 160 glDisable(GL_BLEND); 161} 162 163 164void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image, 165 uint32_t* texName, uint32_t* fbName, uint32_t* status) { 166 GLuint tname, name; 167 // turn our EGLImage into a texture 168 glGenTextures(1, &tname); 169 glBindTexture(GL_TEXTURE_2D, tname); 170 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image); 171 172 // create a Framebuffer Object to render into 173 glGenFramebuffers(1, &name); 174 glBindFramebuffer(GL_FRAMEBUFFER, name); 175 glFramebufferTexture2D(GL_FRAMEBUFFER, 176 GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0); 177 178 *status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 179 *texName = tname; 180 *fbName = name; 181} 182 183void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) { 184 glBindFramebuffer(GL_FRAMEBUFFER, 0); 185 glDeleteFramebuffers(1, &fbName); 186 glDeleteTextures(1, &texName); 187} 188 189void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) { 190 mState.setPlaneAlpha(1.0f); 191 mState.setPremultipliedAlpha(true); 192 mState.setOpaque(false); 193 mState.setColor(r, g, b, a); 194 mState.disableTexture(); 195 glDisable(GL_BLEND); 196} 197 198void GLES20RenderEngine::drawMesh(const Mesh& mesh) { 199 200 ProgramCache::getInstance().useProgram(mState); 201 202 if (mesh.getTexCoordsSize()) { 203 glEnableVertexAttribArray(Program::texCoords); 204 glVertexAttribPointer(Program::texCoords, 205 mesh.getTexCoordsSize(), 206 GL_FLOAT, GL_FALSE, 207 mesh.getByteStride(), 208 mesh.getTexCoords()); 209 } 210 211 glVertexAttribPointer(Program::position, 212 mesh.getVertexSize(), 213 GL_FLOAT, GL_FALSE, 214 mesh.getByteStride(), 215 mesh.getPositions()); 216 217 glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount()); 218 219 if (mesh.getTexCoordsSize()) { 220 glDisableVertexAttribArray(Program::texCoords); 221 } 222} 223 224void GLES20RenderEngine::dump(String8& result) { 225 RenderEngine::dump(result); 226} 227 228// --------------------------------------------------------------------------- 229}; // namespace android 230// --------------------------------------------------------------------------- 231 232#if defined(__gl_h_) 233#error "don't include gl/gl.h in this file" 234#endif 235