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