blob: ce72b5d7231dbb5d905d692d3a1af18dbef2baa8 [file] [log] [blame]
Alex Sakhartchouk2f6964f2011-05-13 14:53:34 -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 "rsdCore.h"
19#include "rsdFrameBuffer.h"
Jason Sams7e8aae72011-05-26 16:33:01 -070020#include "rsdAllocation.h"
Alex Sakhartchouk2f6964f2011-05-13 14:53:34 -070021
22#include "rsContext.h"
23#include "rsFBOCache.h"
24
25#include <GLES2/gl2.h>
26#include <GLES2/gl2ext.h>
27
28using namespace android;
29using namespace android::renderscript;
30
31struct DrvFrameBuffer {
32 GLuint mFBOId;
33};
34
35void checkError(const Context *rsc) {
36 GLenum status;
37 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
38 switch (status) {
39 case GL_FRAMEBUFFER_COMPLETE:
40 break;
41 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
42 rsc->setError(RS_ERROR_BAD_VALUE,
43 "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT");
44 break;
45 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
46 rsc->setError(RS_ERROR_BAD_VALUE,
47 "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
48 break;
49 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
50 rsc->setError(RS_ERROR_BAD_VALUE,
51 "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
52 break;
53 case GL_FRAMEBUFFER_UNSUPPORTED:
54 rsc->setError(RS_ERROR_BAD_VALUE,
55 "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED");
56 break;
57 }
58}
59
60
61void setDepthAttachment(const Context *rsc, const FBOCache *fb) {
62 if (fb->mHal.state.depthTarget.get() != NULL) {
Jason Sams7e8aae72011-05-26 16:33:01 -070063 DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv;
64
65 if (drv->textureID) {
Alex Sakhartchouk2f6964f2011-05-13 14:53:34 -070066 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
Jason Sams7e8aae72011-05-26 16:33:01 -070067 GL_TEXTURE_2D, drv->textureID, 0);
Alex Sakhartchouk2f6964f2011-05-13 14:53:34 -070068 } else {
Alex Sakhartchouk2f6964f2011-05-13 14:53:34 -070069 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
Jason Sams7e8aae72011-05-26 16:33:01 -070070 GL_RENDERBUFFER, drv->renderTargetID);
Alex Sakhartchouk2f6964f2011-05-13 14:53:34 -070071 }
72 } else {
73 // Reset last attachment
Jason Sams7e8aae72011-05-26 16:33:01 -070074 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
75 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
Alex Sakhartchouk2f6964f2011-05-13 14:53:34 -070076 }
77}
78
79void setColorAttachment(const Context *rsc, const FBOCache *fb) {
80 // Now attach color targets
81 for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) {
82 uint32_t texID = 0;
83 if (fb->mHal.state.colorTargets[i].get() != NULL) {
Jason Sams7e8aae72011-05-26 16:33:01 -070084 DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv;
85
86 if (drv->textureID) {
Alex Sakhartchouk2f6964f2011-05-13 14:53:34 -070087 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
Jason Sams7e8aae72011-05-26 16:33:01 -070088 GL_TEXTURE_2D, drv->textureID, 0);
Alex Sakhartchouk2f6964f2011-05-13 14:53:34 -070089 } else {
Alex Sakhartchouk2f6964f2011-05-13 14:53:34 -070090 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
Jason Sams7e8aae72011-05-26 16:33:01 -070091 GL_RENDERBUFFER, drv->renderTargetID);
Alex Sakhartchouk2f6964f2011-05-13 14:53:34 -070092 }
93 } else {
94 // Reset last attachment
95 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
96 GL_RENDERBUFFER, 0);
97 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
98 GL_TEXTURE_2D, 0, 0);
99 }
100 }
101}
102
103bool renderToFramebuffer(const FBOCache *fb) {
104 if (fb->mHal.state.depthTarget.get() != NULL) {
105 return false;
106 }
107
108 for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) {
109 if (fb->mHal.state.colorTargets[i].get() != NULL) {
110 return false;
111 }
112 }
113 return true;
114}
115
116
117bool rsdFrameBufferInit(const Context *rsc, const FBOCache *fb) {
118 DrvFrameBuffer *drv = (DrvFrameBuffer *)calloc(1, sizeof(DrvFrameBuffer));
119 if (drv == NULL) {
120 return false;
121 }
122 fb->mHal.drv = drv;
123 drv->mFBOId = 0;
124
125 return true;
126}
127
128void rsdFrameBufferSetActive(const Context *rsc, const FBOCache *fb) {
129 DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv;
130
131 bool framebuffer = renderToFramebuffer(fb);
132 if (!framebuffer) {
133 if(drv->mFBOId == 0) {
134 glGenFramebuffers(1, &drv->mFBOId);
135 }
136 glBindFramebuffer(GL_FRAMEBUFFER, drv->mFBOId);
137
138 setDepthAttachment(rsc, fb);
139 setColorAttachment(rsc, fb);
140
141 glViewport(0, 0, fb->mHal.state.colorTargets[0]->getType()->getDimX(),
142 fb->mHal.state.colorTargets[0]->getType()->getDimY());
143
144 checkError(rsc);
145 } else {
146 glBindFramebuffer(GL_FRAMEBUFFER, 0);
147 glViewport(0, 0, rsc->getWidth(), rsc->getHeight());
148 }
149}
150
151void rsdFrameBufferDestroy(const Context *rsc, const FBOCache *fb) {
152 DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv;
153 if(drv->mFBOId != 0) {
154 glDeleteFramebuffers(1, &drv->mFBOId);
155 }
156
157 free(fb->mHal.drv);
158 fb->mHal.drv = NULL;
159}
160
161