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