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