LayerRenderer.cpp revision 1fc883b271707c4206ae20cc9a935d7bd4a7485e
1/* 2 * Copyright (C) 2011 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 LOG_TAG "OpenGLRenderer" 18 19#include "LayerRenderer.h" 20#include "Properties.h" 21 22namespace android { 23namespace uirenderer { 24 25/////////////////////////////////////////////////////////////////////////////// 26// Rendering 27/////////////////////////////////////////////////////////////////////////////// 28 29void LayerRenderer::prepare(bool opaque) { 30 LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mFbo); 31 32 glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &mPreviousFbo); 33 glBindFramebuffer(GL_FRAMEBUFFER, mFbo); 34 35 OpenGLRenderer::prepare(opaque); 36} 37 38void LayerRenderer::finish() { 39 OpenGLRenderer::finish(); 40 glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFbo); 41 42 LAYER_RENDERER_LOGD("Finished rendering into layer, fbo = %d", mFbo); 43} 44 45/////////////////////////////////////////////////////////////////////////////// 46// Static functions 47/////////////////////////////////////////////////////////////////////////////// 48 49GLuint LayerRenderer::createLayer(uint32_t width, uint32_t height, 50 uint32_t* layerWidth, uint32_t* layerHeight, GLuint* texture) { 51 LAYER_RENDERER_LOGD("Creating new layer %dx%d", width, height); 52 53 GLuint previousFbo; 54 glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo); 55 56 GLuint fbo = 0; 57 glGenFramebuffers(1, &fbo); 58 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 59 60 if (glGetError() != GL_NO_ERROR) { 61 glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); 62 glDeleteBuffers(1, &fbo); 63 return 0; 64 } 65 66 glActiveTexture(GL_TEXTURE0); 67 glGenTextures(1, texture); 68 glBindTexture(GL_TEXTURE_2D, *texture); 69 70 glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 71 72 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 73 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 74 75 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 76 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 77 78 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, 79 GL_RGBA, GL_UNSIGNED_BYTE, NULL); 80 81 if (glGetError() != GL_NO_ERROR) { 82 glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); 83 glDeleteBuffers(1, &fbo); 84 glDeleteTextures(1, texture); 85 return 0; 86 } 87 88 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 89 *texture, 0); 90 91 if (glGetError() != GL_NO_ERROR) { 92 glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); 93 glDeleteBuffers(1, &fbo); 94 glDeleteTextures(1, texture); 95 return 0; 96 } 97 98 glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); 99 100 *layerWidth = width; 101 *layerHeight = height; 102 103 return fbo; 104} 105 106void LayerRenderer::resizeLayer(GLuint fbo, GLuint texture, uint32_t width, uint32_t height, 107 uint32_t* layerWidth, uint32_t* layerHeight) { 108 LAYER_RENDERER_LOGD("Resizing layer fbo = %d to %dx%d", fbo, width, height); 109 110 glActiveTexture(GL_TEXTURE0); 111 glBindTexture(GL_TEXTURE_2D, texture); 112 113 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, 114 GL_RGBA, GL_UNSIGNED_BYTE, NULL); 115 116 if (glGetError() != GL_NO_ERROR) { 117 glDeleteBuffers(1, &fbo); 118 glDeleteTextures(1, &texture); 119 120 *layerWidth = 0; 121 *layerHeight = 0; 122 123 return; 124 } 125 126 *layerWidth = width; 127 *layerHeight = height; 128} 129 130void LayerRenderer::destroyLayer(GLuint fbo, GLuint texture) { 131 LAYER_RENDERER_LOGD("Destroying layer, fbo = %d", fbo); 132 133 if (fbo) glDeleteFramebuffers(1, &fbo); 134 if (texture) glDeleteTextures(1, &texture); 135} 136 137void LayerRenderer::destroyLayerDeferred(GLuint fbo, GLuint texture) { 138 LAYER_RENDERER_LOGD("Deferring layer destruction, fbo = %d", fbo); 139 140 Caches& caches = Caches::getInstance(); 141 if (fbo) caches.deleteFboDeferred(fbo); 142 if (texture) caches.deleteTextureDeferred(texture); 143} 144 145}; // namespace uirenderer 146}; // namespace android 147