diff options
-rw-r--r-- | graphics/java/android/renderscript/Allocation.java | 95 | ||||
-rw-r--r-- | graphics/java/android/renderscript/RenderScript.java | 16 | ||||
-rw-r--r-- | graphics/jni/android_renderscript_RenderScript.cpp | 34 | ||||
-rw-r--r-- | libs/rs/driver/rsdAllocation.cpp | 97 | ||||
-rw-r--r-- | libs/rs/driver/rsdAllocation.h | 8 | ||||
-rw-r--r-- | libs/rs/driver/rsdCore.cpp | 3 | ||||
-rw-r--r-- | libs/rs/rs.spec | 15 | ||||
-rw-r--r-- | libs/rs/rsAllocation.cpp | 39 | ||||
-rw-r--r-- | libs/rs/rsAllocation.h | 6 | ||||
-rw-r--r-- | libs/rs/rs_hal.h | 6 |
10 files changed, 301 insertions, 18 deletions
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index 44401c83c1e8..37a270e9c10d 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -102,7 +102,7 @@ public class Allocation extends BaseObj { public static final int USAGE_SCRIPT = 0x0001; /** - * GRAPHICS_TEXTURE The allcation will be used as a texture + * GRAPHICS_TEXTURE The allocation will be used as a texture * source by one or more graphics programs. * */ @@ -124,34 +124,34 @@ public class Allocation extends BaseObj { public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008; /** - * USAGE_GRAPHICS_RENDER_TARGET The allcation will be used as a + * USAGE_GRAPHICS_RENDER_TARGET The allocation will be used as a * target for offscreen rendering * */ public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010; /** - * USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT The allocation will be - * used with a SurfaceTexture object. This usage will cause the - * allocation to be created read only. + * USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE The allocation + * will be used as a SurfaceTexture graphics consumer. This + * usage may only be used with USAGE_GRAPHICS_TEXTURE. * * @hide */ public static final int USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE = 0x0020; /** - * USAGE_IO_INPUT The allocation will be - * used with a SurfaceTexture object. This usage will cause the - * allocation to be created read only. + * USAGE_IO_INPUT The allocation will be used as SurfaceTexture + * consumer. This usage will cause the allocation to be created + * read only. * * @hide */ public static final int USAGE_IO_INPUT = 0x0040; /** - * USAGE_IO_OUTPUT The allocation will be - * used with a SurfaceTexture object. This usage will cause the - * allocation to be created write only. + * USAGE_IO_OUTPUT The allocation will be used as a + * SurfaceTexture producer. The dimensions and format of the + * SurfaceTexture will be forced to those of the allocation. * * @hide */ @@ -323,6 +323,37 @@ public class Allocation extends BaseObj { mRS.nAllocationSyncAll(getIDSafe(), srcLocation); } + /** + * Send a buffer to the output stream. The contents of the + * Allocation will be undefined after this operation. + * + * @hide + * + */ + public void ioSendOutput() { + if ((mUsage & USAGE_IO_OUTPUT) == 0) { + throw new RSIllegalArgumentException( + "Can only send buffer if IO_OUTPUT usage specified."); + } + mRS.validate(); + mRS.nAllocationIoSend(getID()); + } + + /** + * Receive the latest input into the Allocation. + * + * @hide + * + */ + public void ioGetInput() { + if ((mUsage & USAGE_IO_INPUT) == 0) { + throw new RSIllegalArgumentException( + "Can only send buffer if IO_OUTPUT usage specified."); + } + mRS.validate(); + mRS.nAllocationIoReceive(getID()); + } + public void copyFrom(BaseObj[] d) { mRS.validate(); validateIsObject(); @@ -887,17 +918,37 @@ public class Allocation extends BaseObj { updateCacheInfo(mType); } - /* + /** + * Resize a 2D allocation. The contents of the allocation are + * preserved. If new elements are allocated objects are created + * with null contents and the new region is otherwise undefined. + * + * If the new region is smaller the references of any objects + * outside the new region will be released. + * + * A new type will be created with the new dimension. + * + * @hide + * @param dimX The new size of the allocation. + * @param dimY The new size of the allocation. + */ public void resize(int dimX, int dimY) { - if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) { - throw new RSIllegalStateException("Resize only support for 2D allocations at this time."); + if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { + throw new RSInvalidStateException( + "Resize only support for 2D allocations at this time."); } if (mType.getY() == 0) { - throw new RSIllegalStateException("Resize only support for 2D allocations at this time."); + throw new RSInvalidStateException( + "Resize only support for 2D allocations at this time."); } mRS.nAllocationResize2D(getID(), dimX, dimY); + mRS.finish(); // Necessary because resize is fifoed and update is async. + + int typeID = mRS.nAllocationGetType(getID()); + mType = new Type(typeID, mRS); + mType.updateFromNative(); + updateCacheInfo(mType); } - */ @@ -1090,6 +1141,18 @@ public class Allocation extends BaseObj { } + /** + * @hide + */ + public void setSurfaceTexture(SurfaceTexture sur) { + if ((mUsage & USAGE_IO_OUTPUT) == 0) { + throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT."); + } + + mRS.validate(); + mRS.nAllocationSetSurfaceTexture(getID(), sur); + } + /** * Creates a non-mipmapped renderscript allocation to use as a diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java index d3c801f2f730..56303f712b67 100644 --- a/graphics/java/android/renderscript/RenderScript.java +++ b/graphics/java/android/renderscript/RenderScript.java @@ -274,6 +274,22 @@ public class RenderScript { validate(); return rsnAllocationGetSurfaceTextureID(mContext, alloc); } + native void rsnAllocationSetSurfaceTexture(int con, int alloc, SurfaceTexture sur); + synchronized void nAllocationSetSurfaceTexture(int alloc, SurfaceTexture sur) { + validate(); + rsnAllocationSetSurfaceTexture(mContext, alloc, sur); + } + native void rsnAllocationIoSend(int con, int alloc); + synchronized void nAllocationIoSend(int alloc) { + validate(); + rsnAllocationIoSend(mContext, alloc); + } + native void rsnAllocationIoReceive(int con, int alloc); + synchronized void nAllocationIoReceive(int alloc) { + validate(); + rsnAllocationIoReceive(mContext, alloc); + } + native void rsnAllocationGenerateMipmaps(int con, int alloc); synchronized void nAllocationGenerateMipmaps(int alloc) { diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp index 94f19b34661d..4d087b047bf3 100644 --- a/graphics/jni/android_renderscript_RenderScript.cpp +++ b/graphics/jni/android_renderscript_RenderScript.cpp @@ -451,6 +451,37 @@ nAllocationGetSurfaceTextureID(JNIEnv *_env, jobject _this, RsContext con, jint } static void +nAllocationSetSurfaceTexture(JNIEnv *_env, jobject _this, RsContext con, + RsAllocation alloc, jobject sur) +{ + LOG_API("nAllocationSetSurfaceTexture, con(%p), alloc(%p), surface(%p)", + con, alloc, (Surface *)sur); + + sp<ANativeWindow> window; + if (sur != 0) { + sp<SurfaceTexture> st = SurfaceTexture_getSurfaceTexture(_env, sur); + window = new SurfaceTextureClient(st); + } + + rsAllocationSetSurface(con, alloc, window.get()); +} + +static void +nAllocationIoSend(JNIEnv *_env, jobject _this, RsContext con, RsAllocation alloc) +{ + LOG_API("nAllocationIoSend, con(%p), alloc(%p)", con, alloc); + rsAllocationIoSend(con, alloc); +} + +static void +nAllocationIoReceive(JNIEnv *_env, jobject _this, RsContext con, RsAllocation alloc) +{ + LOG_API("nAllocationIoReceive, con(%p), alloc(%p)", con, alloc); + rsAllocationIoReceive(con, alloc); +} + + +static void nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, RsContext con, jint alloc) { LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", con, (RsAllocation)alloc); @@ -1277,6 +1308,9 @@ static JNINativeMethod methods[] = { {"rsnAllocationSyncAll", "(III)V", (void*)nAllocationSyncAll }, {"rsnAllocationGetSurfaceTextureID", "(II)I", (void*)nAllocationGetSurfaceTextureID }, +{"rsnAllocationSetSurfaceTexture", "(IILandroid/graphics/SurfaceTexture;)V", (void*)nAllocationSetSurfaceTexture }, +{"rsnAllocationIoSend", "(II)V", (void*)nAllocationIoSend }, +{"rsnAllocationIoReceive", "(II)V", (void*)nAllocationIoReceive }, {"rsnAllocationData1D", "(IIIII[II)V", (void*)nAllocationData1D_i }, {"rsnAllocationData1D", "(IIIII[SI)V", (void*)nAllocationData1D_s }, {"rsnAllocationData1D", "(IIIII[BI)V", (void*)nAllocationData1D_b }, diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp index ea921923e745..b673a0a6fbd1 100644 --- a/libs/rs/driver/rsdAllocation.cpp +++ b/libs/rs/driver/rsdAllocation.cpp @@ -23,6 +23,11 @@ #include "rsAllocation.h" +#include "system/window.h" +#include "hardware/gralloc.h" +#include "ui/Rect.h" +#include "ui/GraphicBufferMapper.h" + #include <GLES/gl.h> #include <GLES2/gl2.h> #include <GLES/glext.h> @@ -220,7 +225,8 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) { } void * ptr = alloc->mHal.state.usrPtr; - if (!ptr) { + if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) { + } else { ptr = malloc(alloc->mHal.state.type->getSizeBytes()); if (!ptr) { free(drv); @@ -248,7 +254,7 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) { alloc->mHal.drvState.mallocPtr = ptr; drv->mallocPtr = (uint8_t *)ptr; alloc->mHal.drv = drv; - if (forceZero) { + if (forceZero && ptr) { memset(ptr, 0, alloc->mHal.state.type->getSizeBytes()); } @@ -386,6 +392,93 @@ int32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *al return drv->textureID; } +static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + int32_t r = nw->dequeueBuffer(nw, &drv->wndBuffer); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer."); + return false; + } + + // This lock is implicitly released by the queue buffer in IoSend + r = nw->lockBuffer(nw, drv->wndBuffer); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error locking next IO output buffer."); + return false; + } + + // Must lock the whole surface + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height); + + void *dst = NULL; + mapper.lock(drv->wndBuffer->handle, + GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN, + bounds, &dst); + alloc->mHal.drvState.mallocPtr = dst; + return true; +} + +void rsdAllocationSetSurfaceTexture(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + //ALOGE("rsdAllocationSetSurfaceTexture %p %p", alloc, nw); + + // Cleanup old surface if there is one. + if (alloc->mHal.state.wndSurface) { + ANativeWindow *old = alloc->mHal.state.wndSurface; + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + mapper.unlock(drv->wndBuffer->handle); + old->queueBuffer(old, drv->wndBuffer); + } + + if (nw != NULL) { + int32_t r; + r = native_window_set_usage(nw, GRALLOC_USAGE_SW_READ_RARELY | + GRALLOC_USAGE_SW_WRITE_OFTEN); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage."); + return; + } + + r = native_window_set_buffers_dimensions(nw, alloc->mHal.state.dimensionX, + alloc->mHal.state.dimensionY); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions."); + return; + } + + r = native_window_set_buffer_count(nw, 3); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count."); + return; + } + + IoGetBuffer(rsc, alloc, nw); + } +} + +void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) { + 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."); + return; + } + + IoGetBuffer(rsc, alloc, nw); +} + +void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) { + ALOGE("not implemented"); +} + + void rsdAllocationData1D(const Context *rsc, const Allocation *alloc, uint32_t xoff, uint32_t lod, uint32_t count, const void *data, uint32_t sizeBytes) { diff --git a/libs/rs/driver/rsdAllocation.h b/libs/rs/driver/rsdAllocation.h index 230804b53ae8..e3a5126383d0 100644 --- a/libs/rs/driver/rsdAllocation.h +++ b/libs/rs/driver/rsdAllocation.h @@ -24,6 +24,7 @@ #include <GLES2/gl2.h> class RsdFrameBufferObj; +struct ANativeWindowBuffer; struct DrvAllocation { // Is this a legal structure to be used as a texture source. @@ -47,6 +48,7 @@ struct DrvAllocation { bool uploadDeferred; RsdFrameBufferObj * readBackFBO; + ANativeWindowBuffer *wndBuffer; }; GLenum rsdTypeToGLType(RsDataType t); @@ -69,6 +71,12 @@ void rsdAllocationMarkDirty(const android::renderscript::Context *rsc, const android::renderscript::Allocation *alloc); int32_t rsdAllocationInitSurfaceTexture(const android::renderscript::Context *rsc, const android::renderscript::Allocation *alloc); +void rsdAllocationSetSurfaceTexture(const android::renderscript::Context *rsc, + android::renderscript::Allocation *alloc, ANativeWindow *nw); +void rsdAllocationIoSend(const android::renderscript::Context *rsc, + android::renderscript::Allocation *alloc); +void rsdAllocationIoReceive(const android::renderscript::Context *rsc, + android::renderscript::Allocation *alloc); void rsdAllocationData1D(const android::renderscript::Context *rsc, const android::renderscript::Allocation *alloc, diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp index e01195509a87..bf2b62a69cdb 100644 --- a/libs/rs/driver/rsdCore.cpp +++ b/libs/rs/driver/rsdCore.cpp @@ -74,6 +74,9 @@ static RsdHalFunctions FunctionTable = { rsdAllocationSyncAll, rsdAllocationMarkDirty, rsdAllocationInitSurfaceTexture, + rsdAllocationSetSurfaceTexture, + rsdAllocationIoSend, + rsdAllocationIoReceive, rsdAllocationData1D, rsdAllocationData2D, rsdAllocationData3D, diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec index 6759bc7bb271..491474ec2cd0 100644 --- a/libs/rs/rs.spec +++ b/libs/rs/rs.spec @@ -69,6 +69,21 @@ AllocationGetSurfaceTextureID { ret int32_t } +AllocationSetSurface { + param RsAllocation alloc + param RsNativeWindow sur + sync + } + +AllocationIoSend { + param RsAllocation alloc + } + +AllocationIoReceive { + param RsAllocation alloc + } + + ContextFinish { sync } diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp index 02c680939de3..83c88fdffacf 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -17,6 +17,7 @@ #include "rsContext.h" #include "rs_hal.h" +#include "system/window.h" using namespace android; using namespace android::renderscript; @@ -44,6 +45,7 @@ Allocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32 delete a; return NULL; } + return a; } @@ -420,6 +422,28 @@ int32_t Allocation::getSurfaceTextureID(const Context *rsc) { return id; } +void Allocation::setSurface(const Context *rsc, RsNativeWindow sur) { + ANativeWindow *nw = (ANativeWindow *)sur; + ANativeWindow *old = mHal.state.wndSurface; + if (nw) { + nw->incStrong(NULL); + } + rsc->mHal.funcs.allocation.setSurfaceTexture(rsc, this, nw); + mHal.state.wndSurface = nw; + if (old) { + old->decStrong(NULL); + } +} + +void Allocation::ioSend(const Context *rsc) { + rsc->mHal.funcs.allocation.ioSend(rsc, this); +} + +void Allocation::ioReceive(const Context *rsc) { + rsc->mHal.funcs.allocation.ioReceive(rsc, this); +} + + ///////////////// // @@ -670,6 +694,21 @@ int32_t rsi_AllocationGetSurfaceTextureID(Context *rsc, RsAllocation valloc) { return alloc->getSurfaceTextureID(rsc); } +void rsi_AllocationSetSurface(Context *rsc, RsAllocation valloc, RsNativeWindow sur) { + Allocation *alloc = static_cast<Allocation *>(valloc); + alloc->setSurface(rsc, sur); +} + +void rsi_AllocationIoSend(Context *rsc, RsAllocation valloc) { + Allocation *alloc = static_cast<Allocation *>(valloc); + alloc->ioSend(rsc); +} + +void rsi_AllocationIoReceive(Context *rsc, RsAllocation valloc) { + Allocation *alloc = static_cast<Allocation *>(valloc); + alloc->ioReceive(rsc); +} + } } diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h index 58a582b75866..58a6fcacf6ac 100644 --- a/libs/rs/rsAllocation.h +++ b/libs/rs/rsAllocation.h @@ -19,6 +19,8 @@ #include "rsType.h" +struct ANativeWindow; + // --------------------------------------------------------------------------- namespace android { namespace renderscript { @@ -57,6 +59,7 @@ public: bool hasReferences; void * usrPtr; int32_t surfaceTextureID; + ANativeWindow *wndSurface; }; State state; @@ -127,6 +130,9 @@ public: } int32_t getSurfaceTextureID(const Context *rsc); + void setSurface(const Context *rsc, RsNativeWindow sur); + void ioSend(const Context *rsc); + void ioReceive(const Context *rsc); protected: Vector<const Program *> mToDirtyList; diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h index 1e222e1664cf..e48aa167583b 100644 --- a/libs/rs/rs_hal.h +++ b/libs/rs/rs_hal.h @@ -19,6 +19,8 @@ #include <RenderScriptDefines.h> +struct ANativeWindow; + namespace android { namespace renderscript { @@ -115,7 +117,11 @@ typedef struct { bool zeroNew); void (*syncAll)(const Context *rsc, const Allocation *alloc, RsAllocationUsageType src); void (*markDirty)(const Context *rsc, const Allocation *alloc); + int32_t (*initSurfaceTexture)(const Context *rsc, const Allocation *alloc); + void (*setSurfaceTexture)(const Context *rsc, Allocation *alloc, ANativeWindow *sur); + void (*ioSend)(const Context *rsc, Allocation *alloc); + void (*ioReceive)(const Context *rsc, Allocation *alloc); void (*data1D)(const Context *rsc, const Allocation *alloc, uint32_t xoff, uint32_t lod, uint32_t count, |