summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Sakhartchouk <alexst@google.com>2011-06-16 11:05:13 -0700
committerAlex Sakhartchouk <alexst@google.com>2011-06-16 11:05:13 -0700
commita94952436aeb251f587c1bccdf94c7f75285dfe2 (patch)
tree7441b7c5b98f8a12c612e1e748cfcce875f10249
parent74a827988567a9d65954bb0d825a3ba4a97e2947 (diff)
downloadrs-a94952436aeb251f587c1bccdf94c7f75285dfe2.tar.gz
Adding ability to read back fbo data to renderscript
Change-Id: Ie684c26cbcde22f2483b43415dfc39a3de22c5a1
-rw-r--r--Android.mk1
-rw-r--r--driver/rsdAllocation.cpp92
-rw-r--r--driver/rsdAllocation.h5
-rw-r--r--driver/rsdFrameBuffer.cpp138
-rw-r--r--driver/rsdFrameBufferObj.cpp143
-rw-r--r--driver/rsdFrameBufferObj.h59
-rw-r--r--driver/rsdGL.cpp2
-rw-r--r--driver/rsdGL.h2
-rw-r--r--driver/rsdMeshObj.cpp9
-rw-r--r--driver/rsdRuntimeStubs.cpp7
-rw-r--r--rsFBOCache.cpp10
11 files changed, 353 insertions, 115 deletions
diff --git a/Android.mk b/Android.mk
index 9fabf8d1..d9cc6b66 100644
--- a/Android.mk
+++ b/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/driver/rsdAllocation.cpp b/driver/rsdAllocation.cpp
index 8bfc1857..01a0cf69 100644
--- a/driver/rsdAllocation.cpp
+++ b/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/driver/rsdAllocation.h b/driver/rsdAllocation.h
index 7555c4ab..4fc4419f 100644
--- a/driver/rsdAllocation.h
+++ b/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/driver/rsdFrameBuffer.cpp b/driver/rsdFrameBuffer.cpp
index ce72b5d7..8c1b12d7 100644
--- a/driver/rsdFrameBuffer.cpp
+++ b/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/driver/rsdFrameBufferObj.cpp b/driver/rsdFrameBufferObj.cpp
new file mode 100644
index 00000000..145bf34e
--- /dev/null
+++ b/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/driver/rsdFrameBufferObj.h b/driver/rsdFrameBufferObj.h
new file mode 100644
index 00000000..c6e7deb5
--- /dev/null
+++ b/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/driver/rsdGL.cpp b/driver/rsdGL.cpp
index a70589b5..3ff03b4d 100644
--- a/driver/rsdGL.cpp
+++ b/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/driver/rsdGL.h b/driver/rsdGL.h
index 01c84384..0d5b7e7b 100644
--- a/driver/rsdGL.h
+++ b/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/driver/rsdMeshObj.cpp b/driver/rsdMeshObj.cpp
index c220ac14..4315c0da 100644
--- a/driver/rsdMeshObj.cpp
+++ b/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/driver/rsdRuntimeStubs.cpp b/driver/rsdRuntimeStubs.cpp
index bd8b3c32..25302aa5 100644
--- a/driver/rsdRuntimeStubs.cpp
+++ b/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/rsFBOCache.cpp b/rsFBOCache.cpp
index 6960ef23..c5c64c27 100644
--- a/rsFBOCache.cpp
+++ b/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;