Layer.cpp revision 8d4aeb7111afac0c3c7e56d4ad5d92f9cfce2ffd
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 = NULL;
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        stencil->bind();
91        stencil->resize(desiredWidth, desiredHeight);
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        GLuint previousFbo;
105        glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo);
106        if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, fbo);
107        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
108        if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
109
110        Caches::getInstance().renderBufferCache.put(stencil);
111        stencil = NULL;
112    }
113
114    if (fbo) {
115        if (flush) LayerRenderer::flushLayer(this);
116        // If put fails the cache will delete the FBO
117        Caches::getInstance().fboCache.put(fbo);
118        fbo = 0;
119    }
120}
121
122void Layer::setPaint(SkPaint* paint) {
123    OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
124}
125
126void Layer::setColorFilter(SkiaColorFilter* filter) {
127    if (colorFilter) {
128        Caches::getInstance().resourceCache.decrementRefcount(colorFilter);
129    }
130    colorFilter = filter;
131    if (colorFilter) {
132        Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
133    }
134}
135
136}; // namespace uirenderer
137}; // namespace android
138