Implement IO_OUTPUT + SurfaceTexture
Change-Id: Id96fecd6d768196523330c5eda77c4ee86b9bd3c
diff --git a/driver/rsdAllocation.cpp b/driver/rsdAllocation.cpp
index f358f93..324eaf6 100644
--- a/driver/rsdAllocation.cpp
+++ b/driver/rsdAllocation.cpp
@@ -263,6 +263,9 @@
drv->uploadDeferred = true;
}
+ drv->width = alloc->getType()->getDimX();
+ drv->height = alloc->getType()->getDimY();
+
drv->readBackFBO = NULL;
return true;
@@ -371,7 +374,8 @@
if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
UploadToTexture(rsc, alloc);
} else {
- if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
+ if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) &&
+ ~(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) {
AllocateRenderTarget(rsc, alloc);
}
}
@@ -418,6 +422,7 @@
GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN,
bounds, &dst);
alloc->mHal.drvState.mallocPtr = dst;
+
return true;
}
@@ -426,6 +431,13 @@
//ALOGE("rsdAllocationSetSurfaceTexture %p %p", alloc, nw);
+ if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
+ //TODO finish support for render target + script
+ drv->wnd = nw;
+ return;
+ }
+
+
// Cleanup old surface if there is one.
if (alloc->mHal.state.wndSurface) {
ANativeWindow *old = alloc->mHal.state.wndSurface;
@@ -436,8 +448,15 @@
if (nw != NULL) {
int32_t r;
- r = native_window_set_usage(nw, GRALLOC_USAGE_SW_READ_RARELY |
- GRALLOC_USAGE_SW_WRITE_OFTEN);
+ uint32_t flags = 0;
+ if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
+ flags |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN;
+ }
+ if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
+ flags |= GRALLOC_USAGE_HW_RENDER;
+ }
+
+ r = native_window_set_usage(nw, flags);
if (r) {
rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
return;
@@ -464,15 +483,23 @@
DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
ANativeWindow *nw = alloc->mHal.state.wndSurface;
- GraphicBufferMapper &mapper = GraphicBufferMapper::get();
- mapper.unlock(drv->wndBuffer->handle);
- int32_t r = nw->queueBuffer(nw, drv->wndBuffer);
- if (r) {
- rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
+ if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
+ RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+ RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
return;
}
- IoGetBuffer(rsc, alloc, nw);
+ if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
+ GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+ mapper.unlock(drv->wndBuffer->handle);
+ int32_t r = nw->queueBuffer(nw, drv->wndBuffer);
+ if (r) {
+ rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
+ return;
+ }
+
+ IoGetBuffer(rsc, alloc, nw);
+ }
}
void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) {
diff --git a/driver/rsdAllocation.h b/driver/rsdAllocation.h
index e3a5126..bd5151b 100644
--- a/driver/rsdAllocation.h
+++ b/driver/rsdAllocation.h
@@ -40,6 +40,8 @@
uint32_t renderTargetID;
uint8_t * mallocPtr;
+ uint32_t width;
+ uint32_t height;
GLenum glTarget;
GLenum glType;
@@ -48,6 +50,7 @@
bool uploadDeferred;
RsdFrameBufferObj * readBackFBO;
+ ANativeWindow *wnd;
ANativeWindowBuffer *wndBuffer;
};
diff --git a/driver/rsdFrameBufferObj.cpp b/driver/rsdFrameBufferObj.cpp
index 91452b0..afdf9b8 100644
--- a/driver/rsdFrameBufferObj.cpp
+++ b/driver/rsdFrameBufferObj.cpp
@@ -18,6 +18,7 @@
#include "rsdFrameBufferObj.h"
#include "rsdAllocation.h"
#include "rsdGL.h"
+#include "rsdCore.h"
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
@@ -122,23 +123,33 @@
}
void RsdFrameBufferObj::setActive(const Context *rsc) {
+ RsdHal *dc = (RsdHal *)rsc->mHal.drv;
bool framebuffer = renderToFramebuffer();
- if (!framebuffer) {
- if(mFBOId == 0) {
- RSD_CALL_GL(glGenFramebuffers, 1, &mFBOId);
- }
- RSD_CALL_GL(glBindFramebuffer, GL_FRAMEBUFFER, mFBOId);
- if (mDirty) {
- setDepthAttachment();
- setColorAttachment();
- mDirty = false;
- }
-
- RSD_CALL_GL(glViewport, 0, 0, mWidth, mHeight);
- checkError(rsc);
+ if(mColorTargets[0] && mColorTargets[0]->wnd) {
+ rsdGLSetInternalSurface(rsc, mColorTargets[0]->wnd);
} else {
- RSD_CALL_GL(glBindFramebuffer, GL_FRAMEBUFFER, 0);
- RSD_CALL_GL(glViewport, 0, 0, rsc->getWidth(), rsc->getHeight());
+ if (!framebuffer) {
+ if(mFBOId == 0) {
+ RSD_CALL_GL(glGenFramebuffers, 1, &mFBOId);
+ }
+ RSD_CALL_GL(glBindFramebuffer, GL_FRAMEBUFFER, mFBOId);
+
+ if (mDirty) {
+ setDepthAttachment();
+ setColorAttachment();
+ mDirty = false;
+ }
+
+ RSD_CALL_GL(glViewport, 0, 0, mWidth, mHeight);
+ checkError(rsc);
+ } else {
+ if(dc->gl.wndSurface != dc->gl.currentWndSurface) {
+ rsdGLSetInternalSurface(rsc, dc->gl.wndSurface);
+ } else {
+ RSD_CALL_GL(glBindFramebuffer, GL_FRAMEBUFFER, 0);
+ }
+ RSD_CALL_GL(glViewport, 0, 0, rsc->getWidth(), rsc->getHeight());
+ }
}
}
diff --git a/driver/rsdGL.cpp b/driver/rsdGL.cpp
index e308adb..a935e6f 100644
--- a/driver/rsdGL.cpp
+++ b/driver/rsdGL.cpp
@@ -424,13 +424,11 @@
}
-bool rsdGLSetSurface(const Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
+bool rsdGLSetInternalSurface(const Context *rsc, RsNativeWindow sur) {
RsdHal *dc = (RsdHal *)rsc->mHal.drv;
EGLBoolean ret;
- // WAR: Some drivers fail to handle 0 size surfaces correcntly.
- // Use the pbuffer to avoid this pitfall.
- if ((dc->gl.egl.surface != NULL) || (w == 0) || (h == 0)) {
+ if (dc->gl.egl.surface != NULL) {
rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
dc->gl.egl.surfaceDefault, dc->gl.egl.context);
@@ -441,23 +439,19 @@
checkEglError("eglDestroySurface", ret);
dc->gl.egl.surface = NULL;
- dc->gl.width = 1;
- dc->gl.height = 1;
}
- if (dc->gl.wndSurface != NULL) {
- dc->gl.wndSurface->decStrong(NULL);
+ if (dc->gl.currentWndSurface != NULL) {
+ dc->gl.currentWndSurface->decStrong(NULL);
}
- dc->gl.wndSurface = (ANativeWindow *)sur;
- if (dc->gl.wndSurface != NULL) {
- dc->gl.wndSurface->incStrong(NULL);
- dc->gl.width = w;
- dc->gl.height = h;
+ dc->gl.currentWndSurface = (ANativeWindow *)sur;
+ if (dc->gl.currentWndSurface != NULL) {
+ dc->gl.currentWndSurface->incStrong(NULL);
rsc->setWatchdogGL("eglCreateWindowSurface", __LINE__, __FILE__);
dc->gl.egl.surface = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
- dc->gl.wndSurface, NULL);
+ dc->gl.currentWndSurface, NULL);
checkEglError("eglCreateWindowSurface");
if (dc->gl.egl.surface == EGL_NO_SURFACE) {
ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
@@ -472,6 +466,25 @@
return true;
}
+bool rsdGLSetSurface(const Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
+ RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+
+ if (dc->gl.wndSurface != NULL) {
+ dc->gl.wndSurface->decStrong(NULL);
+ dc->gl.wndSurface = NULL;
+ }
+ if(w && h) {
+ // WAR: Some drivers fail to handle 0 size surfaces correctly. Use the
+ // pbuffer to avoid this pitfall.
+ dc->gl.wndSurface = (ANativeWindow *)sur;
+ if (dc->gl.wndSurface != NULL) {
+ dc->gl.wndSurface->incStrong(NULL);
+ }
+ }
+
+ return rsdGLSetInternalSurface(rsc, sur);
+}
+
void rsdGLSwap(const android::renderscript::Context *rsc) {
RsdHal *dc = (RsdHal *)rsc->mHal.drv;
RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
diff --git a/driver/rsdGL.h b/driver/rsdGL.h
index 1e5b40f..419c317 100644
--- a/driver/rsdGL.h
+++ b/driver/rsdGL.h
@@ -67,14 +67,15 @@
} gl;
ANativeWindow *wndSurface;
- uint32_t width;
- uint32_t height;
+ ANativeWindow *currentWndSurface;
+
RsdShaderCache *shaderCache;
RsdVertexArrayState *vertexArrayState;
RsdFrameBufferObj *currentFrameBuffer;
} RsdGL;
-
+bool rsdGLSetInternalSurface(const android::renderscript::Context *rsc,
+ RsNativeWindow sur);
bool rsdGLInit(const android::renderscript::Context *rsc);
void rsdGLShutdown(const android::renderscript::Context *rsc);
bool rsdGLSetSurface(const android::renderscript::Context *rsc,
diff --git a/driver/rsdRuntimeStubs.cpp b/driver/rsdRuntimeStubs.cpp
index aa9f159..779076d 100644
--- a/driver/rsdRuntimeStubs.cpp
+++ b/driver/rsdRuntimeStubs.cpp
@@ -26,6 +26,7 @@
#include "rsdRuntime.h"
#include "rsdPath.h"
+#include "rsdAllocation.h"
#include <time.h>
@@ -80,6 +81,18 @@
srcXoff, srcYoff, srcMip, srcFace);
}
+static void SC_AllocationIoSend(Allocation *alloc) {
+ GET_TLS();
+ rsdAllocationIoSend(rsc, alloc);
+}
+
+
+static void SC_AllocationIoReceive(Allocation *alloc) {
+ GET_TLS();
+ rsdAllocationIoReceive(rsc, alloc);
+}
+
+
//////////////////////////////////////////////////////////////////////////////
// Context
@@ -586,7 +599,8 @@
{ "_Z20rsgAllocationSyncAll13rs_allocationj", (void *)&SC_AllocationSyncAll2, false },
{ "_Z20rsgAllocationSyncAll13rs_allocation24rs_allocation_usage_type", (void *)&SC_AllocationSyncAll2, false },
{ "_Z15rsGetAllocationPKv", (void *)&SC_GetAllocation, true },
-
+ { "_Z18rsAllocationIoSend13rs_allocation", (void *)&SC_AllocationIoSend, false },
+ { "_Z21rsAllocationIoReceive13rs_allocation", (void *)&SC_AllocationIoReceive, false },
{ "_Z23rsAllocationCopy1DRange13rs_allocationjjjS_jj", (void *)&SC_AllocationCopy1DRange, false },
{ "_Z23rsAllocationCopy2DRange13rs_allocationjjj26rs_allocation_cubemap_facejjS_jjjS0_", (void *)&SC_AllocationCopy2DRange, false },
diff --git a/driver/rsdShader.cpp b/driver/rsdShader.cpp
index 6d9fa90..d39bdb8 100644
--- a/driver/rsdShader.cpp
+++ b/driver/rsdShader.cpp
@@ -480,23 +480,28 @@
}
DrvAllocation *drvTex = (DrvAllocation *)mRSProgram->mHal.state.textures[ct]->mHal.drv;
- if (drvTex->glTarget != GL_TEXTURE_2D &&
- drvTex->glTarget != GL_TEXTURE_CUBE_MAP &&
- drvTex->glTarget != GL_TEXTURE_EXTERNAL_OES) {
+
+ if (mCurrentState->mTextureTargets[ct] != GL_TEXTURE_2D &&
+ mCurrentState->mTextureTargets[ct] != GL_TEXTURE_CUBE_MAP &&
+ mCurrentState->mTextureTargets[ct] != GL_TEXTURE_EXTERNAL_OES) {
ALOGE("Attempting to bind unknown texture to shader id %u, texture unit %u",
(uint)this, ct);
rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
}
- RSD_CALL_GL(glBindTexture, drvTex->glTarget, drvTex->textureID);
+ RSD_CALL_GL(glBindTexture, mCurrentState->mTextureTargets[ct], drvTex->textureID);
rsdGLCheckError(rsc, "ProgramFragment::setup tex bind");
if (mRSProgram->mHal.state.samplers[ct]) {
setupSampler(rsc, mRSProgram->mHal.state.samplers[ct],
mRSProgram->mHal.state.textures[ct]);
} else {
- RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- RSD_CALL_GL(glTexParameteri, drvTex->glTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ RSD_CALL_GL(glTexParameteri, mCurrentState->mTextureTargets[ct],
+ GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ RSD_CALL_GL(glTexParameteri, mCurrentState->mTextureTargets[ct],
+ GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ RSD_CALL_GL(glTexParameteri, mCurrentState->mTextureTargets[ct],
+ GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ RSD_CALL_GL(glTexParameteri, mCurrentState->mTextureTargets[ct],
+ GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
rsdGLCheckError(rsc, "ProgramFragment::setup tex env");
}
rsdGLCheckError(rsc, "ProgramFragment::setup uniforms");