LayerRenderer.cpp revision 57066eb64c9a190d1afc87bb060bbb2d31e5b86c
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
21namespace android {
22namespace uirenderer {
23
24///////////////////////////////////////////////////////////////////////////////
25// Rendering
26///////////////////////////////////////////////////////////////////////////////
27
28void LayerRenderer::prepare(bool opaque) {
29    glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &mPreviousFbo);
30    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
31    OpenGLRenderer::prepare(opaque);
32}
33
34void LayerRenderer::finish() {
35    OpenGLRenderer::finish();
36    glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFbo);
37}
38
39///////////////////////////////////////////////////////////////////////////////
40// Static functions
41///////////////////////////////////////////////////////////////////////////////
42
43GLuint LayerRenderer::createLayer(uint32_t width, uint32_t height,
44        uint32_t* layerWidth, uint32_t* layerHeight, GLuint* texture) {
45    GLuint previousFbo;
46    glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo);
47
48    GLuint fbo = 0;
49    glGenFramebuffers(1, &fbo);
50    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
51
52    glActiveTexture(GL_TEXTURE0);
53    glGenTextures(1, texture);
54    glBindTexture(GL_TEXTURE_2D, *texture);
55
56    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
57
58    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
59    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
60
61    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
62    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
63
64    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
65            GL_RGBA, GL_UNSIGNED_BYTE, NULL);
66
67    if (glGetError() != GL_NO_ERROR) {
68        glDeleteBuffers(1, &fbo);
69        glDeleteTextures(1, texture);
70        glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
71        return 0;
72    }
73
74    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
75                *texture, 0);
76
77    if (glGetError() != GL_NO_ERROR) {
78        glDeleteBuffers(1, &fbo);
79        glDeleteTextures(1, texture);
80        glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
81        return 0;
82    }
83
84    glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
85
86    *layerWidth = width;
87    *layerHeight = height;
88
89    return fbo;
90}
91
92void LayerRenderer::resizeLayer(GLuint fbo, GLuint texture, uint32_t width, uint32_t height,
93        uint32_t* layerWidth, uint32_t* layerHeight) {
94    glActiveTexture(GL_TEXTURE0);
95    glBindTexture(GL_TEXTURE_2D, texture);
96
97    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
98            GL_RGBA, GL_UNSIGNED_BYTE, NULL);
99
100    if (glGetError() != GL_NO_ERROR) {
101        glDeleteBuffers(1, &fbo);
102        glDeleteTextures(1, &texture);
103
104        *layerWidth = 0;
105        *layerHeight = 0;
106
107        return;
108    }
109
110    *layerWidth = width;
111    *layerHeight = height;
112}
113
114void LayerRenderer::destroyLayer(GLuint fbo, GLuint texture) {
115    if (fbo) glDeleteFramebuffers(1, &fbo);
116    if (texture) glDeleteTextures(1, &texture);
117}
118
119void LayerRenderer::destroyLayerDeferred(GLuint fbo, GLuint texture) {
120    Caches& caches = Caches::getInstance();
121    if (fbo) caches.deleteFboDeferred(fbo);
122    if (texture) caches.deleteTextureDeferred(texture);
123}
124
125}; // namespace uirenderer
126}; // namespace android
127