rsdFrameBuffer.cpp revision eb4fe18dd88634330f9566cbb9e785d8c7ec5813
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 18#include "rsdCore.h" 19#include "rsdFrameBuffer.h" 20#include "rsdAllocation.h" 21 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) { 63 DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv; 64 65 if (drv->textureID) { 66 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 67 GL_TEXTURE_2D, drv->textureID, 0); 68 } else { 69 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 70 GL_RENDERBUFFER, drv->renderTargetID); 71 } 72 } else { 73 // Reset last attachment 74 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); 75 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); 76 } 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) { 84 DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv; 85 86 if (drv->textureID) { 87 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, 88 GL_TEXTURE_2D, drv->textureID, 0); 89 } else { 90 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, 91 GL_RENDERBUFFER, drv->renderTargetID); 92 } 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 162