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