diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/gui/tests/SurfaceTextureClient_test.cpp | 2 | ||||
-rw-r--r-- | libs/gui/tests/SurfaceTexture_test.cpp | 24 | ||||
-rw-r--r-- | libs/rs/Android.mk | 1 | ||||
-rw-r--r-- | libs/rs/driver/rsdAllocation.cpp | 92 | ||||
-rw-r--r-- | libs/rs/driver/rsdAllocation.h | 5 | ||||
-rw-r--r-- | libs/rs/driver/rsdFrameBuffer.cpp | 138 | ||||
-rw-r--r-- | libs/rs/driver/rsdFrameBufferObj.cpp | 143 | ||||
-rw-r--r-- | libs/rs/driver/rsdFrameBufferObj.h | 59 | ||||
-rw-r--r-- | libs/rs/driver/rsdGL.cpp | 2 | ||||
-rw-r--r-- | libs/rs/driver/rsdGL.h | 2 | ||||
-rw-r--r-- | libs/rs/driver/rsdMeshObj.cpp | 9 | ||||
-rw-r--r-- | libs/rs/driver/rsdRuntimeStubs.cpp | 7 | ||||
-rw-r--r-- | libs/rs/rsFBOCache.cpp | 10 |
13 files changed, 364 insertions, 130 deletions
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp index a4c5b36..519b40e 100644 --- a/libs/gui/tests/SurfaceTextureClient_test.cpp +++ b/libs/gui/tests/SurfaceTextureClient_test.cpp @@ -590,7 +590,7 @@ TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffersWi // This test verifies that the buffer format can be queried immediately after // it is set. -TEST_F(SurfaceTextureClientTest, DISABLED_QueryFormatAfterSettingWorks) { +TEST_F(SurfaceTextureClientTest, QueryFormatAfterSettingWorks) { sp<ANativeWindow> anw(mSTC); int fmts[] = { // RGBA_8888 should not come first, as it's the default diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp index 50af3bb..f6cefa6 100644 --- a/libs/gui/tests/SurfaceTexture_test.cpp +++ b/libs/gui/tests/SurfaceTexture_test.cpp @@ -542,11 +542,7 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) { EXPECT_TRUE(checkPixel(36, 22, 155, 29, 0, 255)); } -// XXX: This test is disabled because it it currently broken on all devices to -// which I have access. Some of the checkPixel calls are not correct because -// I just copied them from the npot test above and haven't bothered to figure -// out the correct values. -TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledYV12BufferPow2) { +TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) { const int texWidth = 64; const int texHeight = 64; @@ -576,18 +572,18 @@ TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledYV12BufferPow2) { drawTexture(); - EXPECT_TRUE(checkPixel( 0, 0, 255, 127, 255, 255)); - EXPECT_TRUE(checkPixel(63, 0, 0, 133, 0, 255)); + EXPECT_TRUE(checkPixel( 0, 0, 0, 133, 0, 255)); + EXPECT_TRUE(checkPixel(63, 0, 255, 127, 255, 255)); EXPECT_TRUE(checkPixel(63, 63, 0, 133, 0, 255)); EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255)); - EXPECT_TRUE(checkPixel(22, 19, 247, 70, 255, 255)); - EXPECT_TRUE(checkPixel(45, 11, 209, 32, 235, 255)); - EXPECT_TRUE(checkPixel(52, 12, 100, 255, 73, 255)); - EXPECT_TRUE(checkPixel( 7, 32, 155, 0, 118, 255)); - EXPECT_TRUE(checkPixel(31, 54, 148, 71, 110, 255)); - EXPECT_TRUE(checkPixel(29, 28, 255, 127, 255, 255)); - EXPECT_TRUE(checkPixel(36, 41, 155, 29, 0, 255)); + EXPECT_TRUE(checkPixel(22, 19, 100, 255, 74, 255)); + EXPECT_TRUE(checkPixel(45, 11, 100, 255, 74, 255)); + EXPECT_TRUE(checkPixel(52, 12, 155, 0, 181, 255)); + EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255)); + EXPECT_TRUE(checkPixel(31, 54, 0, 71, 117, 255)); + EXPECT_TRUE(checkPixel(29, 28, 0, 133, 0, 255)); + EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255)); } TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) { diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk index 9fabf8d..d9cc6b6 100644 --- a/libs/rs/Android.mk +++ b/libs/rs/Android.mk @@ -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 \ diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp index 8bfc185..01a0cf6 100644 --- a/libs/rs/driver/rsdAllocation.cpp +++ b/libs/rs/driver/rsdAllocation.cpp @@ -19,6 +19,7 @@ #include "rsdBcc.h" #include "rsdRuntime.h" #include "rsdAllocation.h" +#include "rsdFrameBufferObj.h" #include "rsAllocation.h" @@ -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; } @@ -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; } @@ -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; } @@ -382,7 +429,40 @@ void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc, const android::renderscript::Allocation *dstAlloc, uint32_t dstXoff, uint32_t dstLod, uint32_t count, const android::renderscript::Allocation *srcAlloc, - uint32_t srcXoff, uint32_t srcLod){ + 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, @@ -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, diff --git a/libs/rs/driver/rsdAllocation.h b/libs/rs/driver/rsdAllocation.h index 7555c4a..4fc4419 100644 --- a/libs/rs/driver/rsdAllocation.h +++ b/libs/rs/driver/rsdAllocation.h @@ -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 @@ -42,8 +44,9 @@ struct DrvAllocation { GLenum glType; GLenum glFormat; - bool uploadDeferred; + + RsdFrameBufferObj * readBackFBO; }; GLenum rsdTypeToGLType(RsDataType t); diff --git a/libs/rs/driver/rsdFrameBuffer.cpp b/libs/rs/driver/rsdFrameBuffer.cpp index ce72b5d..8c1b12d 100644 --- a/libs/rs/driver/rsdFrameBuffer.cpp +++ b/libs/rs/driver/rsdFrameBuffer.cpp @@ -17,6 +17,7 @@ #include "rsdCore.h" #include "rsdFrameBuffer.h" +#include "rsdFrameBufferObj.h" #include "rsdAllocation.h" #include "rsContext.h" @@ -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); - } - } -} - -bool renderToFramebuffer(const FBOCache *fb) { - if (fb->mHal.state.depthTarget.get() != NULL) { - return false; - } + color = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv; - for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) { - if (fb->mHal.state.colorTargets[i].get() != NULL) { - return false; + if (color->uploadDeferred) { + rsdAllocationSyncAll(rsc, fb->mHal.state.colorTargets[i].get(), + RS_ALLOCATION_USAGE_SCRIPT); + } } + 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(), - fb->mHal.state.colorTargets[0]->getType()->getDimY()); - - checkError(rsc); - } else { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, rsc->getWidth(), rsc->getHeight()); + setDepthAttachment(rsc, fb); + setColorAttachment(rsc, fb); + + 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()); + } else if (fb->mHal.state.depthTarget.get()) { + fbo->setDimensions(fb->mHal.state.depthTarget->getType()->getDimX(), + fb->mHal.state.depthTarget->getType()->getDimY()); } + + fbo->setActive(rsc); } void rsdFrameBufferDestroy(const Context *rsc, const FBOCache *fb) { - DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv; - if(drv->mFBOId != 0) { - glDeleteFramebuffers(1, &drv->mFBOId); - } - - free(fb->mHal.drv); + RsdFrameBufferObj *fbo = (RsdFrameBufferObj *)fb->mHal.drv; + delete fbo; fb->mHal.drv = NULL; } diff --git a/libs/rs/driver/rsdFrameBufferObj.cpp b/libs/rs/driver/rsdFrameBufferObj.cpp new file mode 100644 index 0000000..145bf34 --- /dev/null +++ b/libs/rs/driver/rsdFrameBufferObj.cpp @@ -0,0 +1,143 @@ +/* + * 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()); + } +} diff --git a/libs/rs/driver/rsdFrameBufferObj.h b/libs/rs/driver/rsdFrameBufferObj.h new file mode 100644 index 0000000..c6e7deb --- /dev/null +++ b/libs/rs/driver/rsdFrameBufferObj.h @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#ifndef _RSD_FRAMEBUFFER_OBJ_H_ +#define _RSD_FRAMEBUFFER_OBJ_H_ + +#include <rsContext.h> + +class DrvAllocation; + +class RsdFrameBufferObj { +public: + RsdFrameBufferObj(); + ~RsdFrameBufferObj(); + + void setActive(const android::renderscript::Context *rsc); + void setColorTarget(DrvAllocation *color, uint32_t index) { + mColorTargets[index] = color; + mDirty = true; + } + void setDepthTarget(DrvAllocation *depth) { + mDepthTarget = depth; + mDirty = true; + } + void setDimensions(uint32_t width, uint32_t height) { + mWidth = width; + mHeight = height; + } +protected: + uint32_t mFBOId; + DrvAllocation **mColorTargets; + uint32_t mColorTargetsCount; + DrvAllocation *mDepthTarget; + + uint32_t mWidth; + uint32_t mHeight; + + bool mDirty; + + bool renderToFramebuffer(); + void checkError(const android::renderscript::Context *rsc); + void setColorAttachment(); + void setDepthAttachment(); +}; + +#endif //_RSD_FRAMEBUFFER_STATE_H_ diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp index a70589b..3ff03b4 100644 --- a/libs/rs/driver/rsdGL.cpp +++ b/libs/rs/driver/rsdGL.cpp @@ -39,6 +39,7 @@ #include "rsContext.h" #include "rsdShaderCache.h" #include "rsdVertexArray.h" +#include "rsdFrameBufferObj.h" using namespace android; using namespace android::renderscript; @@ -294,6 +295,7 @@ bool rsdGLInit(const Context *rsc) { dc->gl.shaderCache = new RsdShaderCache(); dc->gl.vertexArrayState = new RsdVertexArrayState(); dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs); + dc->gl.currentFrameBuffer = NULL; LOGV("initGLThread end %p", rsc); return true; diff --git a/libs/rs/driver/rsdGL.h b/libs/rs/driver/rsdGL.h index 01c8438..0d5b7e7 100644 --- a/libs/rs/driver/rsdGL.h +++ b/libs/rs/driver/rsdGL.h @@ -22,6 +22,7 @@ class RsdShaderCache; class RsdVertexArrayState; +class RsdFrameBufferObj; typedef void (* InvokeFunc_t)(void); typedef void (*WorkerCallback_t)(void *usr, uint32_t idx); @@ -68,6 +69,7 @@ typedef struct RsdGLRec { uint32_t height; RsdShaderCache *shaderCache; RsdVertexArrayState *vertexArrayState; + RsdFrameBufferObj *currentFrameBuffer; } RsdGL; diff --git a/libs/rs/driver/rsdMeshObj.cpp b/libs/rs/driver/rsdMeshObj.cpp index c220ac1..4315c0d 100644 --- a/libs/rs/driver/rsdMeshObj.cpp +++ b/libs/rs/driver/rsdMeshObj.cpp @@ -138,7 +138,10 @@ void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, ui for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) { const Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[ct].get(); - rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT); + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + if (drv->uploadDeferred) { + rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT); + } } // update attributes with either buffer information or data ptr based on their current state @@ -163,7 +166,9 @@ void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, ui const Allocation *idxAlloc = prim->mIndexBuffer.get(); if (idxAlloc) { DrvAllocation *drvAlloc = (DrvAllocation *)idxAlloc->mHal.drv; - rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT); + if (drvAlloc->uploadDeferred) { + rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT); + } if (drvAlloc->bufferID) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drvAlloc->bufferID); diff --git a/libs/rs/driver/rsdRuntimeStubs.cpp b/libs/rs/driver/rsdRuntimeStubs.cpp index bd8b3c3..25302aa 100644 --- a/libs/rs/driver/rsdRuntimeStubs.cpp +++ b/libs/rs/driver/rsdRuntimeStubs.cpp @@ -95,6 +95,8 @@ static void SC_AllocationCopy1DRange(Allocation *dstAlloc, Allocation *srcAlloc, uint32_t srcOff, uint32_t srcMip) { GET_TLS(); + rsrAllocationCopy1DRange(rsc, dstAlloc, dstOff, dstMip, count, + srcAlloc, srcOff, srcMip); } static void SC_AllocationCopy2DRange(Allocation *dstAlloc, @@ -105,6 +107,11 @@ static void SC_AllocationCopy2DRange(Allocation *dstAlloc, uint32_t srcXoff, uint32_t srcYoff, uint32_t srcMip, uint32_t srcFace) { GET_TLS(); + rsrAllocationCopy2DRange(rsc, dstAlloc, + dstXoff, dstYoff, dstMip, dstFace, + width, height, + srcAlloc, + srcXoff, srcYoff, srcMip, srcFace); } diff --git a/libs/rs/rsFBOCache.cpp b/libs/rs/rsFBOCache.cpp index 6960ef2..c5c64c2 100644 --- a/libs/rs/rsFBOCache.cpp +++ b/libs/rs/rsFBOCache.cpp @@ -80,16 +80,6 @@ void FBOCache::setup(Context *rsc) { return; } - if (mHal.state.depthTarget.get() != NULL) { - mHal.state.depthTarget->syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT); - } - - for (uint32_t i = 0; i < mHal.state.colorTargetsCount; i ++) { - if (mHal.state.colorTargets[i].get() != NULL) { - mHal.state.colorTargets[i]->syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT); - } - } - rsc->mHal.funcs.framebuffer.setActive(rsc, this); mDirty = false; |