Loading libs/rs/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ LOCAL_SRC_FILES:= \ driver/rsdBcc.cpp \ driver/rsdCore.cpp \ driver/rsdFrameBuffer.cpp \ driver/rsdFrameBufferObj.cpp \ driver/rsdGL.cpp \ driver/rsdMesh.cpp \ driver/rsdMeshObj.cpp \ Loading libs/rs/driver/rsdAllocation.cpp +90 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include "rsdBcc.h" #include "rsdRuntime.h" #include "rsdAllocation.h" #include "rsdFrameBufferObj.h" #include "rsAllocation.h" Loading Loading @@ -244,6 +245,9 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) { if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) { drv->uploadDeferred = true; } drv->readBackFBO = NULL; return true; } Loading @@ -269,6 +273,10 @@ void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) { free(drv->mallocPtr); drv->mallocPtr = NULL; } if (drv->readBackFBO != NULL) { delete drv->readBackFBO; drv->readBackFBO = NULL; } free(drv); alloc->mHal.drv = NULL; } Loading @@ -292,13 +300,52 @@ void rsdAllocationResize(const Context *rsc, const Allocation *alloc, } } static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) { if (!alloc->getIsScript()) { return; // nothing to sync } RsdHal *dc = (RsdHal *)rsc->mHal.drv; RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer; DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; if (!drv->textureID && !drv->renderTargetID) { return; // nothing was rendered here yet, so nothing to sync } if (drv->readBackFBO == NULL) { drv->readBackFBO = new RsdFrameBufferObj(); drv->readBackFBO->setColorTarget(drv, 0); drv->readBackFBO->setDimensions(alloc->getType()->getDimX(), alloc->getType()->getDimY()); } // Bind the framebuffer object so we can read back from it drv->readBackFBO->setActive(rsc); // Do the readback glReadPixels(0, 0, alloc->getType()->getDimX(), alloc->getType()->getDimY(), drv->glFormat, drv->glType, alloc->getPtr()); // Revert framebuffer to its original lastFbo->setActive(rsc); } void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc, RsAllocationUsageType src) { DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; if (!drv->uploadDeferred) { if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { if(!alloc->getIsRenderTarget()) { rsc->setError(RS_ERROR_FATAL_DRIVER, "Attempting to sync allocation from render target, " "for non-render target allocation"); } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) { rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA" "render target"); } else { rsdAllocationSyncFromFBO(rsc, alloc); } return; } Loading Loading @@ -385,6 +432,39 @@ void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc, uint32_t srcXoff, uint32_t srcLod) { } uint8_t *getOffsetPtr(const android::renderscript::Allocation *alloc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face) { uint8_t *ptr = static_cast<uint8_t *>(alloc->getPtr()); ptr += alloc->getType()->getLODOffset(lod, xoff, yoff); if (face != 0) { uint32_t totalSizeBytes = alloc->getType()->getSizeBytes(); uint32_t faceOffset = totalSizeBytes / 6; ptr += faceOffset * (uint32_t)face; } return ptr; } void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc, const android::renderscript::Allocation *dstAlloc, uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod, RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h, const android::renderscript::Allocation *srcAlloc, uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, RsAllocationCubemapFace srcFace) { uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes(); for (uint32_t i = 0; i < h; i ++) { uint8_t *dstPtr = getOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstLod, dstFace); uint8_t *srcPtr = getOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcLod, srcFace); memcpy(dstPtr, srcPtr, w * elementSize); LOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)", dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace); } } void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc, const android::renderscript::Allocation *dstAlloc, uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod, Loading @@ -392,6 +472,14 @@ void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc, const android::renderscript::Allocation *srcAlloc, uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, RsAllocationCubemapFace srcFace) { if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) { rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not " "yet implemented."); return; } rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, dstLod, dstFace, w, h, srcAlloc, srcXoff, srcYoff, srcLod, srcFace); } void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc, Loading libs/rs/driver/rsdAllocation.h +4 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ #include <GLES/gl.h> #include <GLES2/gl2.h> class RsdFrameBufferObj; struct DrvAllocation { // Is this a legal structure to be used as a texture source. // Initially this will require 1D or 2D and color data Loading @@ -42,8 +44,9 @@ struct DrvAllocation { GLenum glType; GLenum glFormat; bool uploadDeferred; RsdFrameBufferObj * readBackFBO; }; GLenum rsdTypeToGLType(RsDataType t); Loading libs/rs/driver/rsdFrameBuffer.cpp +38 −100 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "rsdCore.h" #include "rsdFrameBuffer.h" #include "rsdFrameBufferObj.h" #include "rsdAllocation.h" #include "rsContext.h" Loading @@ -28,133 +29,70 @@ using namespace android; using namespace android::renderscript; struct DrvFrameBuffer { GLuint mFBOId; }; void checkError(const Context *rsc) { GLenum status; status = glCheckFramebufferStatus(GL_FRAMEBUFFER); switch (status) { case GL_FRAMEBUFFER_COMPLETE: break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT"); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); break; case GL_FRAMEBUFFER_UNSUPPORTED: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED"); break; } } void setDepthAttachment(const Context *rsc, const FBOCache *fb) { RsdFrameBufferObj *fbo = (RsdFrameBufferObj*)fb->mHal.drv; DrvAllocation *depth = NULL; if (fb->mHal.state.depthTarget.get() != NULL) { DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv; if (drv->textureID) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, drv->textureID, 0); } else { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, drv->renderTargetID); depth = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv; if (depth->uploadDeferred) { rsdAllocationSyncAll(rsc, fb->mHal.state.depthTarget.get(), RS_ALLOCATION_USAGE_SCRIPT); } } else { // Reset last attachment glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); } fbo->setDepthTarget(depth); } void setColorAttachment(const Context *rsc, const FBOCache *fb) { RsdFrameBufferObj *fbo = (RsdFrameBufferObj*)fb->mHal.drv; // Now attach color targets for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) { uint32_t texID = 0; DrvAllocation *color = NULL; if (fb->mHal.state.colorTargets[i].get() != NULL) { DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv; if (drv->textureID) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, drv->textureID, 0); } else { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, drv->renderTargetID); } } else { // Reset last attachment glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0); } } } color = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv; bool renderToFramebuffer(const FBOCache *fb) { if (fb->mHal.state.depthTarget.get() != NULL) { return false; if (color->uploadDeferred) { rsdAllocationSyncAll(rsc, fb->mHal.state.colorTargets[i].get(), RS_ALLOCATION_USAGE_SCRIPT); } for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) { if (fb->mHal.state.colorTargets[i].get() != NULL) { return false; } fbo->setColorTarget(color, i); } return true; } bool rsdFrameBufferInit(const Context *rsc, const FBOCache *fb) { DrvFrameBuffer *drv = (DrvFrameBuffer *)calloc(1, sizeof(DrvFrameBuffer)); if (drv == NULL) { RsdFrameBufferObj *fbo = new RsdFrameBufferObj(); if (fbo == NULL) { return false; } fb->mHal.drv = drv; drv->mFBOId = 0; fb->mHal.drv = fbo; RsdHal *dc = (RsdHal *)rsc->mHal.drv; dc->gl.currentFrameBuffer = fbo; return true; } void rsdFrameBufferSetActive(const Context *rsc, const FBOCache *fb) { DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv; bool framebuffer = renderToFramebuffer(fb); if (!framebuffer) { if(drv->mFBOId == 0) { glGenFramebuffers(1, &drv->mFBOId); } glBindFramebuffer(GL_FRAMEBUFFER, drv->mFBOId); setDepthAttachment(rsc, fb); setColorAttachment(rsc, fb); glViewport(0, 0, fb->mHal.state.colorTargets[0]->getType()->getDimX(), RsdFrameBufferObj *fbo = (RsdFrameBufferObj *)fb->mHal.drv; if (fb->mHal.state.colorTargets[0].get()) { fbo->setDimensions(fb->mHal.state.colorTargets[0]->getType()->getDimX(), fb->mHal.state.colorTargets[0]->getType()->getDimY()); checkError(rsc); } else { glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, rsc->getWidth(), rsc->getHeight()); } } else if (fb->mHal.state.depthTarget.get()) { fbo->setDimensions(fb->mHal.state.depthTarget->getType()->getDimX(), fb->mHal.state.depthTarget->getType()->getDimY()); } void rsdFrameBufferDestroy(const Context *rsc, const FBOCache *fb) { DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv; if(drv->mFBOId != 0) { glDeleteFramebuffers(1, &drv->mFBOId); fbo->setActive(rsc); } free(fb->mHal.drv); void rsdFrameBufferDestroy(const Context *rsc, const FBOCache *fb) { RsdFrameBufferObj *fbo = (RsdFrameBufferObj *)fb->mHal.drv; delete fbo; fb->mHal.drv = NULL; } Loading libs/rs/driver/rsdFrameBufferObj.cpp 0 → 100644 +143 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "rsdFrameBufferObj.h" #include "rsdAllocation.h" #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> using namespace android; using namespace android::renderscript; RsdFrameBufferObj::RsdFrameBufferObj() { mFBOId = 0; mWidth = 0; mHeight = 0; mColorTargetsCount = 1; mColorTargets = new DrvAllocation*[mColorTargetsCount]; for (uint32_t i = 0; i < mColorTargetsCount; i ++) { mColorTargets[i] = 0; } mDepthTarget = NULL; mDirty = true; } RsdFrameBufferObj::~RsdFrameBufferObj() { if(mFBOId != 0) { glDeleteFramebuffers(1, &mFBOId); } delete [] mColorTargets; } void RsdFrameBufferObj::checkError(const Context *rsc) { GLenum status; status = glCheckFramebufferStatus(GL_FRAMEBUFFER); switch (status) { case GL_FRAMEBUFFER_COMPLETE: break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT"); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); break; case GL_FRAMEBUFFER_UNSUPPORTED: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED"); break; } } void RsdFrameBufferObj::setDepthAttachment() { if (mDepthTarget != NULL) { if (mDepthTarget->textureID) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, mDepthTarget->textureID, 0); } else { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthTarget->renderTargetID); } } else { // Reset last attachment glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); } } void RsdFrameBufferObj::setColorAttachment() { // Now attach color targets for (uint32_t i = 0; i < mColorTargetsCount; i ++) { if (mColorTargets[i] != NULL) { if (mColorTargets[i]->textureID) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, mColorTargets[i]->textureID, 0); } else { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, mColorTargets[i]->renderTargetID); } } else { // Reset last attachment glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0); } } } bool RsdFrameBufferObj::renderToFramebuffer() { if (mDepthTarget != NULL) { return false; } for (uint32_t i = 0; i < mColorTargetsCount; i ++) { if (mColorTargets[i] != NULL) { return false; } } return true; } void RsdFrameBufferObj::setActive(const Context *rsc) { bool framebuffer = renderToFramebuffer(); if (!framebuffer) { if(mFBOId == 0) { glGenFramebuffers(1, &mFBOId); } glBindFramebuffer(GL_FRAMEBUFFER, mFBOId); if (mDirty) { setDepthAttachment(); setColorAttachment(); mDirty = false; } glViewport(0, 0, mWidth, mHeight); checkError(rsc); } else { glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, rsc->getWidth(), rsc->getHeight()); } } Loading
libs/rs/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ LOCAL_SRC_FILES:= \ driver/rsdBcc.cpp \ driver/rsdCore.cpp \ driver/rsdFrameBuffer.cpp \ driver/rsdFrameBufferObj.cpp \ driver/rsdGL.cpp \ driver/rsdMesh.cpp \ driver/rsdMeshObj.cpp \ Loading
libs/rs/driver/rsdAllocation.cpp +90 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include "rsdBcc.h" #include "rsdRuntime.h" #include "rsdAllocation.h" #include "rsdFrameBufferObj.h" #include "rsAllocation.h" Loading Loading @@ -244,6 +245,9 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) { if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) { drv->uploadDeferred = true; } drv->readBackFBO = NULL; return true; } Loading @@ -269,6 +273,10 @@ void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) { free(drv->mallocPtr); drv->mallocPtr = NULL; } if (drv->readBackFBO != NULL) { delete drv->readBackFBO; drv->readBackFBO = NULL; } free(drv); alloc->mHal.drv = NULL; } Loading @@ -292,13 +300,52 @@ void rsdAllocationResize(const Context *rsc, const Allocation *alloc, } } static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) { if (!alloc->getIsScript()) { return; // nothing to sync } RsdHal *dc = (RsdHal *)rsc->mHal.drv; RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer; DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; if (!drv->textureID && !drv->renderTargetID) { return; // nothing was rendered here yet, so nothing to sync } if (drv->readBackFBO == NULL) { drv->readBackFBO = new RsdFrameBufferObj(); drv->readBackFBO->setColorTarget(drv, 0); drv->readBackFBO->setDimensions(alloc->getType()->getDimX(), alloc->getType()->getDimY()); } // Bind the framebuffer object so we can read back from it drv->readBackFBO->setActive(rsc); // Do the readback glReadPixels(0, 0, alloc->getType()->getDimX(), alloc->getType()->getDimY(), drv->glFormat, drv->glType, alloc->getPtr()); // Revert framebuffer to its original lastFbo->setActive(rsc); } void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc, RsAllocationUsageType src) { DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; if (!drv->uploadDeferred) { if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) { if(!alloc->getIsRenderTarget()) { rsc->setError(RS_ERROR_FATAL_DRIVER, "Attempting to sync allocation from render target, " "for non-render target allocation"); } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) { rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA" "render target"); } else { rsdAllocationSyncFromFBO(rsc, alloc); } return; } Loading Loading @@ -385,6 +432,39 @@ void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc, uint32_t srcXoff, uint32_t srcLod) { } uint8_t *getOffsetPtr(const android::renderscript::Allocation *alloc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face) { uint8_t *ptr = static_cast<uint8_t *>(alloc->getPtr()); ptr += alloc->getType()->getLODOffset(lod, xoff, yoff); if (face != 0) { uint32_t totalSizeBytes = alloc->getType()->getSizeBytes(); uint32_t faceOffset = totalSizeBytes / 6; ptr += faceOffset * (uint32_t)face; } return ptr; } void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc, const android::renderscript::Allocation *dstAlloc, uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod, RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h, const android::renderscript::Allocation *srcAlloc, uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, RsAllocationCubemapFace srcFace) { uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes(); for (uint32_t i = 0; i < h; i ++) { uint8_t *dstPtr = getOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstLod, dstFace); uint8_t *srcPtr = getOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcLod, srcFace); memcpy(dstPtr, srcPtr, w * elementSize); LOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)", dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace); } } void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc, const android::renderscript::Allocation *dstAlloc, uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod, Loading @@ -392,6 +472,14 @@ void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc, const android::renderscript::Allocation *srcAlloc, uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod, RsAllocationCubemapFace srcFace) { if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) { rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not " "yet implemented."); return; } rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, dstLod, dstFace, w, h, srcAlloc, srcXoff, srcYoff, srcLod, srcFace); } void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc, Loading
libs/rs/driver/rsdAllocation.h +4 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ #include <GLES/gl.h> #include <GLES2/gl2.h> class RsdFrameBufferObj; struct DrvAllocation { // Is this a legal structure to be used as a texture source. // Initially this will require 1D or 2D and color data Loading @@ -42,8 +44,9 @@ struct DrvAllocation { GLenum glType; GLenum glFormat; bool uploadDeferred; RsdFrameBufferObj * readBackFBO; }; GLenum rsdTypeToGLType(RsDataType t); Loading
libs/rs/driver/rsdFrameBuffer.cpp +38 −100 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "rsdCore.h" #include "rsdFrameBuffer.h" #include "rsdFrameBufferObj.h" #include "rsdAllocation.h" #include "rsContext.h" Loading @@ -28,133 +29,70 @@ using namespace android; using namespace android::renderscript; struct DrvFrameBuffer { GLuint mFBOId; }; void checkError(const Context *rsc) { GLenum status; status = glCheckFramebufferStatus(GL_FRAMEBUFFER); switch (status) { case GL_FRAMEBUFFER_COMPLETE: break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT"); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); break; case GL_FRAMEBUFFER_UNSUPPORTED: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED"); break; } } void setDepthAttachment(const Context *rsc, const FBOCache *fb) { RsdFrameBufferObj *fbo = (RsdFrameBufferObj*)fb->mHal.drv; DrvAllocation *depth = NULL; if (fb->mHal.state.depthTarget.get() != NULL) { DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv; if (drv->textureID) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, drv->textureID, 0); } else { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, drv->renderTargetID); depth = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv; if (depth->uploadDeferred) { rsdAllocationSyncAll(rsc, fb->mHal.state.depthTarget.get(), RS_ALLOCATION_USAGE_SCRIPT); } } else { // Reset last attachment glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); } fbo->setDepthTarget(depth); } void setColorAttachment(const Context *rsc, const FBOCache *fb) { RsdFrameBufferObj *fbo = (RsdFrameBufferObj*)fb->mHal.drv; // Now attach color targets for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) { uint32_t texID = 0; DrvAllocation *color = NULL; if (fb->mHal.state.colorTargets[i].get() != NULL) { DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv; if (drv->textureID) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, drv->textureID, 0); } else { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, drv->renderTargetID); } } else { // Reset last attachment glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0); } } } color = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv; bool renderToFramebuffer(const FBOCache *fb) { if (fb->mHal.state.depthTarget.get() != NULL) { return false; if (color->uploadDeferred) { rsdAllocationSyncAll(rsc, fb->mHal.state.colorTargets[i].get(), RS_ALLOCATION_USAGE_SCRIPT); } for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) { if (fb->mHal.state.colorTargets[i].get() != NULL) { return false; } fbo->setColorTarget(color, i); } return true; } bool rsdFrameBufferInit(const Context *rsc, const FBOCache *fb) { DrvFrameBuffer *drv = (DrvFrameBuffer *)calloc(1, sizeof(DrvFrameBuffer)); if (drv == NULL) { RsdFrameBufferObj *fbo = new RsdFrameBufferObj(); if (fbo == NULL) { return false; } fb->mHal.drv = drv; drv->mFBOId = 0; fb->mHal.drv = fbo; RsdHal *dc = (RsdHal *)rsc->mHal.drv; dc->gl.currentFrameBuffer = fbo; return true; } void rsdFrameBufferSetActive(const Context *rsc, const FBOCache *fb) { DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv; bool framebuffer = renderToFramebuffer(fb); if (!framebuffer) { if(drv->mFBOId == 0) { glGenFramebuffers(1, &drv->mFBOId); } glBindFramebuffer(GL_FRAMEBUFFER, drv->mFBOId); setDepthAttachment(rsc, fb); setColorAttachment(rsc, fb); glViewport(0, 0, fb->mHal.state.colorTargets[0]->getType()->getDimX(), RsdFrameBufferObj *fbo = (RsdFrameBufferObj *)fb->mHal.drv; if (fb->mHal.state.colorTargets[0].get()) { fbo->setDimensions(fb->mHal.state.colorTargets[0]->getType()->getDimX(), fb->mHal.state.colorTargets[0]->getType()->getDimY()); checkError(rsc); } else { glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, rsc->getWidth(), rsc->getHeight()); } } else if (fb->mHal.state.depthTarget.get()) { fbo->setDimensions(fb->mHal.state.depthTarget->getType()->getDimX(), fb->mHal.state.depthTarget->getType()->getDimY()); } void rsdFrameBufferDestroy(const Context *rsc, const FBOCache *fb) { DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv; if(drv->mFBOId != 0) { glDeleteFramebuffers(1, &drv->mFBOId); fbo->setActive(rsc); } free(fb->mHal.drv); void rsdFrameBufferDestroy(const Context *rsc, const FBOCache *fb) { RsdFrameBufferObj *fbo = (RsdFrameBufferObj *)fb->mHal.drv; delete fbo; fb->mHal.drv = NULL; } Loading
libs/rs/driver/rsdFrameBufferObj.cpp 0 → 100644 +143 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "rsdFrameBufferObj.h" #include "rsdAllocation.h" #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> using namespace android; using namespace android::renderscript; RsdFrameBufferObj::RsdFrameBufferObj() { mFBOId = 0; mWidth = 0; mHeight = 0; mColorTargetsCount = 1; mColorTargets = new DrvAllocation*[mColorTargetsCount]; for (uint32_t i = 0; i < mColorTargetsCount; i ++) { mColorTargets[i] = 0; } mDepthTarget = NULL; mDirty = true; } RsdFrameBufferObj::~RsdFrameBufferObj() { if(mFBOId != 0) { glDeleteFramebuffers(1, &mFBOId); } delete [] mColorTargets; } void RsdFrameBufferObj::checkError(const Context *rsc) { GLenum status; status = glCheckFramebufferStatus(GL_FRAMEBUFFER); switch (status) { case GL_FRAMEBUFFER_COMPLETE: break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT"); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); break; case GL_FRAMEBUFFER_UNSUPPORTED: rsc->setError(RS_ERROR_BAD_VALUE, "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED"); break; } } void RsdFrameBufferObj::setDepthAttachment() { if (mDepthTarget != NULL) { if (mDepthTarget->textureID) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, mDepthTarget->textureID, 0); } else { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthTarget->renderTargetID); } } else { // Reset last attachment glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); } } void RsdFrameBufferObj::setColorAttachment() { // Now attach color targets for (uint32_t i = 0; i < mColorTargetsCount; i ++) { if (mColorTargets[i] != NULL) { if (mColorTargets[i]->textureID) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, mColorTargets[i]->textureID, 0); } else { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, mColorTargets[i]->renderTargetID); } } else { // Reset last attachment glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0); } } } bool RsdFrameBufferObj::renderToFramebuffer() { if (mDepthTarget != NULL) { return false; } for (uint32_t i = 0; i < mColorTargetsCount; i ++) { if (mColorTargets[i] != NULL) { return false; } } return true; } void RsdFrameBufferObj::setActive(const Context *rsc) { bool framebuffer = renderToFramebuffer(); if (!framebuffer) { if(mFBOId == 0) { glGenFramebuffers(1, &mFBOId); } glBindFramebuffer(GL_FRAMEBUFFER, mFBOId); if (mDirty) { setDepthAttachment(); setColorAttachment(); mDirty = false; } glViewport(0, 0, mWidth, mHeight); checkError(rsc); } else { glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, rsc->getWidth(), rsc->getHeight()); } }