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");
diff --git a/rsFBOCache.cpp b/rsFBOCache.cpp index d50f3e0..1da327f 100644 --- a/rsFBOCache.cpp +++ b/rsFBOCache.cpp
@@ -50,7 +50,7 @@ return; } if (a != NULL) { - if (!a->getIsTexture()) { + if (!(a->getIsTexture() || (a->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT))) { ALOGE("Invalid Color Target"); return; }
diff --git a/scriptc/rs_allocation.rsh b/scriptc/rs_allocation.rsh index b0840a0..c6a0d6e 100644 --- a/scriptc/rs_allocation.rsh +++ b/scriptc/rs_allocation.rsh
@@ -146,6 +146,19 @@ #if (defined(RS_VERSION) && (RS_VERSION >= 16)) /** + * Send the contents of the Allocation to the queue. + */ +extern const void __attribute__((overloadable)) + rsAllocationIoSend(rs_allocation); + +/** + * Receive a new set of contents from the queue. + */ +extern const void __attribute__((overloadable)) + rsAllocationIoReceive(rs_allocation); + + +/** * @param a allocation to get data from * @return element describing allocation layout */