blob: 145bf34e290b4f869b8eb5ea31c6954aec198ef8 [file] [log] [blame]
Alex Sakhartchouk8650c322011-06-16 11:05:13 -07001/*
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
18#include "rsdFrameBufferObj.h"
19#include "rsdAllocation.h"
20
21#include <GLES2/gl2.h>
22#include <GLES2/gl2ext.h>
23
24using namespace android;
25using namespace android::renderscript;
26
27RsdFrameBufferObj::RsdFrameBufferObj() {
28 mFBOId = 0;
29 mWidth = 0;
30 mHeight = 0;
31 mColorTargetsCount = 1;
32 mColorTargets = new DrvAllocation*[mColorTargetsCount];
33 for (uint32_t i = 0; i < mColorTargetsCount; i ++) {
34 mColorTargets[i] = 0;
35 }
36 mDepthTarget = NULL;
37 mDirty = true;
38}
39
40RsdFrameBufferObj::~RsdFrameBufferObj() {
41 if(mFBOId != 0) {
42 glDeleteFramebuffers(1, &mFBOId);
43 }
44 delete [] mColorTargets;
45}
46
47void RsdFrameBufferObj::checkError(const Context *rsc) {
48 GLenum status;
49 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
50 switch (status) {
51 case GL_FRAMEBUFFER_COMPLETE:
52 break;
53 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
54 rsc->setError(RS_ERROR_BAD_VALUE,
55 "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT");
56 break;
57 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
58 rsc->setError(RS_ERROR_BAD_VALUE,
59 "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
60 break;
61 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
62 rsc->setError(RS_ERROR_BAD_VALUE,
63 "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
64 break;
65 case GL_FRAMEBUFFER_UNSUPPORTED:
66 rsc->setError(RS_ERROR_BAD_VALUE,
67 "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED");
68 break;
69 }
70}
71
72
73void RsdFrameBufferObj::setDepthAttachment() {
74 if (mDepthTarget != NULL) {
75 if (mDepthTarget->textureID) {
76 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
77 GL_TEXTURE_2D, mDepthTarget->textureID, 0);
78 } else {
79 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
80 GL_RENDERBUFFER, mDepthTarget->renderTargetID);
81 }
82 } else {
83 // Reset last attachment
84 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
85 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
86 }
87}
88
89void RsdFrameBufferObj::setColorAttachment() {
90 // Now attach color targets
91 for (uint32_t i = 0; i < mColorTargetsCount; i ++) {
92 if (mColorTargets[i] != NULL) {
93 if (mColorTargets[i]->textureID) {
94 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
95 GL_TEXTURE_2D, mColorTargets[i]->textureID, 0);
96 } else {
97 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
98 GL_RENDERBUFFER, mColorTargets[i]->renderTargetID);
99 }
100 } else {
101 // Reset last attachment
102 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
103 GL_RENDERBUFFER, 0);
104 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
105 GL_TEXTURE_2D, 0, 0);
106 }
107 }
108}
109
110bool RsdFrameBufferObj::renderToFramebuffer() {
111 if (mDepthTarget != NULL) {
112 return false;
113 }
114
115 for (uint32_t i = 0; i < mColorTargetsCount; i ++) {
116 if (mColorTargets[i] != NULL) {
117 return false;
118 }
119 }
120 return true;
121}
122
123void RsdFrameBufferObj::setActive(const Context *rsc) {
124 bool framebuffer = renderToFramebuffer();
125 if (!framebuffer) {
126 if(mFBOId == 0) {
127 glGenFramebuffers(1, &mFBOId);
128 }
129 glBindFramebuffer(GL_FRAMEBUFFER, mFBOId);
130
131 if (mDirty) {
132 setDepthAttachment();
133 setColorAttachment();
134 mDirty = false;
135 }
136
137 glViewport(0, 0, mWidth, mHeight);
138 checkError(rsc);
139 } else {
140 glBindFramebuffer(GL_FRAMEBUFFER, 0);
141 glViewport(0, 0, rsc->getWidth(), rsc->getHeight());
142 }
143}