rsdFrameBufferObj.cpp revision 2382aba4a55c6ae74789c478eead8fbd96593321
1a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk/*
2a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * Copyright (C) 2011 The Android Open Source Project
3a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk *
4a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * Licensed under the Apache License, Version 2.0 (the "License");
5a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * you may not use this file except in compliance with the License.
6a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * You may obtain a copy of the License at
7a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk *
8a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk *      http://www.apache.org/licenses/LICENSE-2.0
9a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk *
10a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * Unless required by applicable law or agreed to in writing, software
11a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * distributed under the License is distributed on an "AS IS" BASIS,
12a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * See the License for the specific language governing permissions and
14a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk * limitations under the License.
15a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk */
16a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
17a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
18a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk#include "rsdFrameBufferObj.h"
19a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk#include "rsdAllocation.h"
202382aba4a55c6ae74789c478eead8fbd96593321Jason Sams#include "rsdGL.h"
21a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
22a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk#include <GLES2/gl2.h>
23a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk#include <GLES2/gl2ext.h>
24a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
25a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukusing namespace android;
26a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukusing namespace android::renderscript;
27a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
28a94952436aeb251f587c1bccdf94c7f75285dfe2Alex SakhartchoukRsdFrameBufferObj::RsdFrameBufferObj() {
29a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    mFBOId = 0;
30a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    mWidth = 0;
31a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    mHeight = 0;
32a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    mColorTargetsCount = 1;
33a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    mColorTargets = new DrvAllocation*[mColorTargetsCount];
34a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    for (uint32_t i = 0; i < mColorTargetsCount; i ++) {
35a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        mColorTargets[i] = 0;
36a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
37a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    mDepthTarget = NULL;
38a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    mDirty = true;
39a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk}
40a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
41a94952436aeb251f587c1bccdf94c7f75285dfe2Alex SakhartchoukRsdFrameBufferObj::~RsdFrameBufferObj() {
42a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if(mFBOId != 0) {
43a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        glDeleteFramebuffers(1, &mFBOId);
44a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
45a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    delete [] mColorTargets;
46a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk}
47a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
48a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukvoid RsdFrameBufferObj::checkError(const Context *rsc) {
49a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    GLenum status;
50a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
51a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    switch (status) {
52a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    case GL_FRAMEBUFFER_COMPLETE:
53a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        break;
54a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
55a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        rsc->setError(RS_ERROR_BAD_VALUE,
56a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                      "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT");
57a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        break;
58a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
59a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        rsc->setError(RS_ERROR_BAD_VALUE,
60a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                      "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
61a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        break;
62a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
63a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        rsc->setError(RS_ERROR_BAD_VALUE,
64a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                      "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
65a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        break;
66a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    case GL_FRAMEBUFFER_UNSUPPORTED:
67a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        rsc->setError(RS_ERROR_BAD_VALUE,
68a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                      "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED");
69a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        break;
70a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
71a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk}
72a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
73a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
74a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukvoid RsdFrameBufferObj::setDepthAttachment() {
75a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (mDepthTarget != NULL) {
76a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        if (mDepthTarget->textureID) {
77a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
78a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                   GL_TEXTURE_2D, mDepthTarget->textureID, 0);
79a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        } else {
80a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
81a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      GL_RENDERBUFFER, mDepthTarget->renderTargetID);
82a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        }
83a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    } else {
84a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        // Reset last attachment
85a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
86a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
87a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
88a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk}
89a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
90a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukvoid RsdFrameBufferObj::setColorAttachment() {
91a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    // Now attach color targets
92a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    for (uint32_t i = 0; i < mColorTargetsCount; i ++) {
93a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        if (mColorTargets[i] != NULL) {
94a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            if (mColorTargets[i]->textureID) {
95a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
96a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                       GL_TEXTURE_2D, mColorTargets[i]->textureID, 0);
97a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            } else {
98a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
99a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                          GL_RENDERBUFFER, mColorTargets[i]->renderTargetID);
100a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            }
101a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        } else {
102a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            // Reset last attachment
103a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
104a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                      GL_RENDERBUFFER, 0);
105a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
106a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk                                   GL_TEXTURE_2D, 0, 0);
107a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        }
108a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
109a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk}
110a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
111a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukbool RsdFrameBufferObj::renderToFramebuffer() {
112a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (mDepthTarget != NULL) {
113a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        return false;
114a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
115a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
116a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    for (uint32_t i = 0; i < mColorTargetsCount; i ++) {
117a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        if (mColorTargets[i] != NULL) {
118a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            return false;
119a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        }
120a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
121a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    return true;
122a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk}
123a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
124a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchoukvoid RsdFrameBufferObj::setActive(const Context *rsc) {
125a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    bool framebuffer = renderToFramebuffer();
126a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    if (!framebuffer) {
127a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        if(mFBOId == 0) {
1282382aba4a55c6ae74789c478eead8fbd96593321Jason Sams            RSD_CALL_GL(glGenFramebuffers, 1, &mFBOId);
129a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        }
1302382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glBindFramebuffer, GL_FRAMEBUFFER, mFBOId);
131a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
132a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        if (mDirty) {
133a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            setDepthAttachment();
134a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            setColorAttachment();
135a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk            mDirty = false;
136a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        }
137a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk
1382382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glViewport, 0, 0, mWidth, mHeight);
139a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk        checkError(rsc);
140a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    } else {
1412382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glBindFramebuffer, GL_FRAMEBUFFER, 0);
1422382aba4a55c6ae74789c478eead8fbd96593321Jason Sams        RSD_CALL_GL(glViewport, 0, 0, rsc->getWidth(), rsc->getHeight());
143a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk    }
144a94952436aeb251f587c1bccdf94c7f75285dfe2Alex Sakhartchouk}
145