Layer.cpp revision 2055abaa0a590c35e27e1ae2e7d7cfccdfb98b59
1/* 2 * Copyright (C) 2012 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 <utils/Log.h> 20 21#include "Layer.h" 22#include "LayerRenderer.h" 23#include "OpenGLRenderer.h" 24#include "Caches.h" 25 26namespace android { 27namespace uirenderer { 28 29Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight) { 30 mesh = NULL; 31 meshIndices = NULL; 32 meshElementCount = 0; 33 cacheable = true; 34 dirty = false; 35 textureLayer = false; 36 renderTarget = GL_TEXTURE_2D; 37 texture.width = layerWidth; 38 texture.height = layerHeight; 39 colorFilter = NULL; 40 deferredUpdateScheduled = false; 41 renderer = NULL; 42 displayList = NULL; 43 fbo = 0; 44 stencil = 0; 45 debugDrawUpdate = false; 46 Caches::getInstance().resourceCache.incrementRefcount(this); 47} 48 49Layer::~Layer() { 50 if (mesh) delete mesh; 51 if (meshIndices) delete meshIndices; 52 if (colorFilter) Caches::getInstance().resourceCache.decrementRefcount(colorFilter); 53 removeFbo(); 54 deleteTexture(); 55} 56 57uint32_t Layer::computeIdealWidth(uint32_t layerWidth) { 58 return uint32_t(ceilf(layerWidth / float(LAYER_SIZE)) * LAYER_SIZE); 59} 60 61uint32_t Layer::computeIdealHeight(uint32_t layerHeight) { 62 return uint32_t(ceilf(layerHeight / float(LAYER_SIZE)) * LAYER_SIZE); 63} 64 65bool Layer::resize(const uint32_t width, const uint32_t height) { 66 uint32_t desiredWidth = computeIdealWidth(width); 67 uint32_t desiredHeight = computeIdealWidth(height); 68 69 if (desiredWidth <= getWidth() && desiredHeight <= getHeight()) { 70 return true; 71 } 72 73 uint32_t oldWidth = getWidth(); 74 uint32_t oldHeight = getHeight(); 75 76 setSize(desiredWidth, desiredHeight); 77 78 if (fbo) { 79 Caches::getInstance().activeTexture(0); 80 bindTexture(); 81 allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE); 82 83 if (glGetError() != GL_NO_ERROR) { 84 setSize(oldWidth, oldHeight); 85 return false; 86 } 87 } 88 89 if (stencil) { 90 bindStencilRenderBuffer(); 91 allocateStencilRenderBuffer(); 92 93 if (glGetError() != GL_NO_ERROR) { 94 setSize(oldWidth, oldHeight); 95 return false; 96 } 97 } 98 99 return true; 100} 101 102void Layer::removeFbo(bool flush) { 103 if (stencil) { 104 // TODO: recycle & cache instead of simply deleting 105 GLuint previousFbo; 106 glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo); 107 if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, fbo); 108 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); 109 if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); 110 111 glDeleteRenderbuffers(1, &stencil); 112 stencil = 0; 113 } 114 115 if (fbo) { 116 if (flush) LayerRenderer::flushLayer(this); 117 // If put fails the cache will delete the FBO 118 Caches::getInstance().fboCache.put(fbo); 119 fbo = 0; 120 } 121} 122 123void Layer::setPaint(SkPaint* paint) { 124 OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode); 125} 126 127void Layer::setColorFilter(SkiaColorFilter* filter) { 128 if (colorFilter) { 129 Caches::getInstance().resourceCache.decrementRefcount(colorFilter); 130 } 131 colorFilter = filter; 132 if (colorFilter) { 133 Caches::getInstance().resourceCache.incrementRefcount(colorFilter); 134 } 135} 136 137}; // namespace uirenderer 138}; // namespace android 139