LayerRenderer.cpp revision ada830f639591b99c3e40de22b07296c7932a33f
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", mLayer->fbo); 31 32 glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &mPreviousFbo); 33 glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo); 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", mLayer->mFbo); 43} 44 45/////////////////////////////////////////////////////////////////////////////// 46// Static functions 47/////////////////////////////////////////////////////////////////////////////// 48 49Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque) { 50 LAYER_RENDERER_LOGD("Creating new layer %dx%d", width, height); 51 52 Layer* layer = new Layer(width, height); 53 54 GLuint previousFbo; 55 glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo); 56 57 glGenFramebuffers(1, &layer->fbo); 58 glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo); 59 60 if (glGetError() != GL_NO_ERROR) { 61 glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); 62 glDeleteBuffers(1, &layer->fbo); 63 return 0; 64 } 65 66 glActiveTexture(GL_TEXTURE0); 67 glGenTextures(1, &layer->texture); 68 glBindTexture(GL_TEXTURE_2D, layer->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, &layer->fbo); 84 glDeleteTextures(1, &layer->texture); 85 delete layer; 86 return 0; 87 } 88 89 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 90 layer->texture, 0); 91 92 if (glGetError() != GL_NO_ERROR) { 93 glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); 94 glDeleteBuffers(1, &layer->fbo); 95 glDeleteTextures(1, &layer->texture); 96 delete layer; 97 return 0; 98 } 99 100 glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); 101 102 layer->layer.set(0.0f, 0.0f, width, height); 103 layer->texCoords.set(0.0f, 1.0f, 1.0f, 0.0f); 104 layer->alpha = 255; 105 layer->mode = SkXfermode::kSrcOver_Mode; 106 layer->blend = !isOpaque; 107 layer->empty = false; 108 layer->colorFilter = NULL; 109 110 return layer; 111} 112 113bool LayerRenderer::resizeLayer(Layer* layer, uint32_t width, uint32_t height) { 114 if (layer) { 115 LAYER_RENDERER_LOGD("Resizing layer fbo = %d to %dx%d", layer->fbo, width, height); 116 117 glActiveTexture(GL_TEXTURE0); 118 glBindTexture(GL_TEXTURE_2D, layer->texture); 119 120 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, 121 GL_RGBA, GL_UNSIGNED_BYTE, NULL); 122 123 if (glGetError() != GL_NO_ERROR) { 124 glDeleteBuffers(1, &layer->fbo); 125 glDeleteTextures(1, &layer->texture); 126 127 layer->width = 0; 128 layer->height = 0; 129 layer->fbo = 0; 130 layer->texture = 0; 131 132 return false; 133 } 134 135 layer->width = width; 136 layer->height = height; 137 } 138 return true; 139} 140 141void LayerRenderer::destroyLayer(Layer* layer) { 142 if (layer) { 143 LAYER_RENDERER_LOGD("Destroying layer, fbo = %d", layer->fbo); 144 145 if (layer->fbo) glDeleteFramebuffers(1, &layer->fbo); 146 if (layer->texture) glDeleteTextures(1, &layer->texture); 147 148 delete layer; 149 } 150} 151 152void LayerRenderer::destroyLayerDeferred(Layer* layer) { 153 if (layer) { 154 LAYER_RENDERER_LOGD("Deferring layer destruction, fbo = %d", layer->fbo); 155 156 Caches::getInstance().deleteLayerDeferred(layer); 157 } 158} 159 160}; // namespace uirenderer 161}; // namespace android 162