LayerRenderer.cpp revision 1fc883b271707c4206ae20cc9a935d7bd4a7485e
16c319ca1275c8db892c39b48fc54864c949f9171Romain Guy/*
26c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * Copyright (C) 2011 The Android Open Source Project
36c319ca1275c8db892c39b48fc54864c949f9171Romain Guy *
46c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
56c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * you may not use this file except in compliance with the License.
66c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * You may obtain a copy of the License at
76c319ca1275c8db892c39b48fc54864c949f9171Romain Guy *
86c319ca1275c8db892c39b48fc54864c949f9171Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
96c319ca1275c8db892c39b48fc54864c949f9171Romain Guy *
106c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * Unless required by applicable law or agreed to in writing, software
116c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
126c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * See the License for the specific language governing permissions and
146c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * limitations under the License.
156c319ca1275c8db892c39b48fc54864c949f9171Romain Guy */
166c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
176c319ca1275c8db892c39b48fc54864c949f9171Romain Guy#define LOG_TAG "OpenGLRenderer"
186c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
196c319ca1275c8db892c39b48fc54864c949f9171Romain Guy#include "LayerRenderer.h"
201fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy#include "Properties.h"
216c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
226c319ca1275c8db892c39b48fc54864c949f9171Romain Guynamespace android {
236c319ca1275c8db892c39b48fc54864c949f9171Romain Guynamespace uirenderer {
246c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
256c319ca1275c8db892c39b48fc54864c949f9171Romain Guy///////////////////////////////////////////////////////////////////////////////
266c319ca1275c8db892c39b48fc54864c949f9171Romain Guy// Rendering
276c319ca1275c8db892c39b48fc54864c949f9171Romain Guy///////////////////////////////////////////////////////////////////////////////
286c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
296c319ca1275c8db892c39b48fc54864c949f9171Romain Guyvoid LayerRenderer::prepare(bool opaque) {
301fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy    LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mFbo);
311fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy
326c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &mPreviousFbo);
336c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
341fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy
356c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    OpenGLRenderer::prepare(opaque);
366c319ca1275c8db892c39b48fc54864c949f9171Romain Guy}
376c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
386c319ca1275c8db892c39b48fc54864c949f9171Romain Guyvoid LayerRenderer::finish() {
396c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    OpenGLRenderer::finish();
406c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFbo);
411fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy
421fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy    LAYER_RENDERER_LOGD("Finished rendering into layer, fbo = %d", mFbo);
436c319ca1275c8db892c39b48fc54864c949f9171Romain Guy}
446c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
456c319ca1275c8db892c39b48fc54864c949f9171Romain Guy///////////////////////////////////////////////////////////////////////////////
466c319ca1275c8db892c39b48fc54864c949f9171Romain Guy// Static functions
476c319ca1275c8db892c39b48fc54864c949f9171Romain Guy///////////////////////////////////////////////////////////////////////////////
486c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
496c319ca1275c8db892c39b48fc54864c949f9171Romain GuyGLuint LayerRenderer::createLayer(uint32_t width, uint32_t height,
506c319ca1275c8db892c39b48fc54864c949f9171Romain Guy        uint32_t* layerWidth, uint32_t* layerHeight, GLuint* texture) {
511fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy    LAYER_RENDERER_LOGD("Creating new layer %dx%d", width, height);
521fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy
536c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    GLuint previousFbo;
546c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo);
556c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
566c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    GLuint fbo = 0;
576c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glGenFramebuffers(1, &fbo);
586c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
596c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
601fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy    if (glGetError() != GL_NO_ERROR) {
611fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy        glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
621fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy        glDeleteBuffers(1, &fbo);
631fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy        return 0;
641fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy    }
651fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy
666c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glActiveTexture(GL_TEXTURE0);
676c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glGenTextures(1, texture);
686c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glBindTexture(GL_TEXTURE_2D, *texture);
696c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
706c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
716c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
726c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
736c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
746c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
756c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
766c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
776c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
786c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
796c319ca1275c8db892c39b48fc54864c949f9171Romain Guy            GL_RGBA, GL_UNSIGNED_BYTE, NULL);
806c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
816c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    if (glGetError() != GL_NO_ERROR) {
821fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy        glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
836c319ca1275c8db892c39b48fc54864c949f9171Romain Guy        glDeleteBuffers(1, &fbo);
846c319ca1275c8db892c39b48fc54864c949f9171Romain Guy        glDeleteTextures(1, texture);
856c319ca1275c8db892c39b48fc54864c949f9171Romain Guy        return 0;
866c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    }
876c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
886c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
896c319ca1275c8db892c39b48fc54864c949f9171Romain Guy                *texture, 0);
906c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
916c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    if (glGetError() != GL_NO_ERROR) {
921fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy        glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
936c319ca1275c8db892c39b48fc54864c949f9171Romain Guy        glDeleteBuffers(1, &fbo);
946c319ca1275c8db892c39b48fc54864c949f9171Romain Guy        glDeleteTextures(1, texture);
956c319ca1275c8db892c39b48fc54864c949f9171Romain Guy        return 0;
966c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    }
976c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
986c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
996c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
1006c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    *layerWidth = width;
1016c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    *layerHeight = height;
1026c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
1036c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    return fbo;
1046c319ca1275c8db892c39b48fc54864c949f9171Romain Guy}
1056c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
1066c319ca1275c8db892c39b48fc54864c949f9171Romain Guyvoid LayerRenderer::resizeLayer(GLuint fbo, GLuint texture, uint32_t width, uint32_t height,
1076c319ca1275c8db892c39b48fc54864c949f9171Romain Guy        uint32_t* layerWidth, uint32_t* layerHeight) {
1081fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy    LAYER_RENDERER_LOGD("Resizing layer fbo = %d to %dx%d", fbo, width, height);
1091fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy
1106c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glActiveTexture(GL_TEXTURE0);
1116c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glBindTexture(GL_TEXTURE_2D, texture);
1126c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
1136c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
1146c319ca1275c8db892c39b48fc54864c949f9171Romain Guy            GL_RGBA, GL_UNSIGNED_BYTE, NULL);
1156c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
1166c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    if (glGetError() != GL_NO_ERROR) {
1176c319ca1275c8db892c39b48fc54864c949f9171Romain Guy        glDeleteBuffers(1, &fbo);
118a9d0711392689a94b9f76eb0c16d0718c005603eRomain Guy        glDeleteTextures(1, &texture);
1196c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
1206c319ca1275c8db892c39b48fc54864c949f9171Romain Guy        *layerWidth = 0;
1216c319ca1275c8db892c39b48fc54864c949f9171Romain Guy        *layerHeight = 0;
1226c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
1236c319ca1275c8db892c39b48fc54864c949f9171Romain Guy        return;
1246c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    }
1256c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
1266c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    *layerWidth = width;
1276c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    *layerHeight = height;
1286c319ca1275c8db892c39b48fc54864c949f9171Romain Guy}
1296c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
1306c319ca1275c8db892c39b48fc54864c949f9171Romain Guyvoid LayerRenderer::destroyLayer(GLuint fbo, GLuint texture) {
1311fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy    LAYER_RENDERER_LOGD("Destroying layer, fbo = %d", fbo);
1321fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy
1336c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    if (fbo) glDeleteFramebuffers(1, &fbo);
1346c319ca1275c8db892c39b48fc54864c949f9171Romain Guy    if (texture) glDeleteTextures(1, &texture);
1356c319ca1275c8db892c39b48fc54864c949f9171Romain Guy}
1366c319ca1275c8db892c39b48fc54864c949f9171Romain Guy
13757066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guyvoid LayerRenderer::destroyLayerDeferred(GLuint fbo, GLuint texture) {
1381fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy    LAYER_RENDERER_LOGD("Deferring layer destruction, fbo = %d", fbo);
1391fc883b271707c4206ae20cc9a935d7bd4a7485eRomain Guy
14057066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    Caches& caches = Caches::getInstance();
14157066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    if (fbo) caches.deleteFboDeferred(fbo);
14257066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy    if (texture) caches.deleteTextureDeferred(texture);
14357066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy}
14457066eb64c9a190d1afc87bb060bbb2d31e5b86cRomain Guy
1456c319ca1275c8db892c39b48fc54864c949f9171Romain Guy}; // namespace uirenderer
1466c319ca1275c8db892c39b48fc54864c949f9171Romain Guy}; // namespace android
147