SubElementData data upload functions.
Change-Id: I5f8c738b5457ae7f6085fc4cd331cf3d13ad75cf
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 6775c08..ee5dbc1 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -90,7 +90,7 @@
subData1D(0, mType.getElementCount(), d);
}
- public void subData(int off, FieldPacker fp) {
+ public void subData(int xoff, FieldPacker fp) {
int eSize = mType.mElement.getSizeBytes();
final byte[] data = fp.getData();
@@ -99,8 +99,28 @@
throw new IllegalArgumentException("Field packer length " + data.length +
" not divisible by element size " + eSize + ".");
}
- data1DChecks(off, count, data.length, data.length);
- mRS.nAllocationSubData1D(mID, off, count, data, data.length);
+ data1DChecks(xoff, count, data.length, data.length);
+ mRS.nAllocationSubData1D(mID, xoff, count, data, data.length);
+ }
+
+
+ public void subElementData(int xoff, int component_number, FieldPacker fp) {
+ if (component_number >= mType.mElement.mElements.length) {
+ throw new IllegalArgumentException("Component_number " + component_number + " out of range.");
+ }
+ if(xoff < 0) {
+ throw new IllegalArgumentException("Offset must be >= 0.");
+ }
+
+ final byte[] data = fp.getData();
+ int eSize = mType.mElement.mElements[component_number].getSizeBytes();
+
+ if (data.length != eSize) {
+ throw new IllegalArgumentException("Field packer sizelength " + data.length +
+ " does not match component size " + eSize + ".");
+ }
+
+ mRS.nAllocationSubElementData1D(mID, xoff, component_number, data, data.length);
}
private void data1DChecks(int off, int count, int len, int dataSize) {
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 08ba7e2..d51257b 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -232,6 +232,10 @@
synchronized void nAllocationSubData1D(int id, int off, int count, byte[] d, int sizeBytes) {
rsnAllocationSubData1D(mContext, id, off, count, d, sizeBytes);
}
+ native void rsnAllocationSubElementData1D(int con, int id, int xoff, int compIdx, byte[] d, int sizeBytes);
+ synchronized void nAllocationSubElementData1D(int id, int xoff, int compIdx, byte[] d, int sizeBytes) {
+ rsnAllocationSubElementData1D(mContext, id, xoff, compIdx, d, sizeBytes);
+ }
native void rsnAllocationSubData1D(int con, int id, int off, int count, float[] d, int sizeBytes);
synchronized void nAllocationSubData1D(int id, int off, int count, float[] d, int sizeBytes) {
rsnAllocationSubData1D(mContext, id, off, count, d, sizeBytes);
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 81f08e9..23b71b0 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -649,6 +649,17 @@
}
static void
+// native void rsnAllocationSubElementData1D(int con, int id, int xoff, int compIdx, byte[] d, int sizeBytes);
+nAllocationSubElementData1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint compIdx, jbyteArray data, int sizeBytes)
+{
+ jint len = _env->GetArrayLength(data);
+ LOG_API("nAllocationSubElementData1D, con(%p), alloc(%p), offset(%i), comp(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, compIdx, len, sizeBytes);
+ jbyte *ptr = _env->GetByteArrayElements(data, NULL);
+ rsAllocation1DSubElementData(con, (RsAllocation)alloc, offset, ptr, compIdx, sizeBytes);
+ _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
nAllocationSubData2D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint w, jint h, jintArray data, int sizeBytes)
{
jint len = _env->GetArrayLength(data);
@@ -1401,6 +1412,7 @@
{"rsnAllocationSubData1D", "(IIII[SI)V", (void*)nAllocationSubData1D_s },
{"rsnAllocationSubData1D", "(IIII[BI)V", (void*)nAllocationSubData1D_b },
{"rsnAllocationSubData1D", "(IIII[FI)V", (void*)nAllocationSubData1D_f },
+{"rsnAllocationSubElementData1D", "(IIII[BI)V", (void*)nAllocationSubElementData1D },
{"rsnAllocationSubData2D", "(IIIIII[II)V", (void*)nAllocationSubData2D_i },
{"rsnAllocationSubData2D", "(IIIIII[FI)V", (void*)nAllocationSubData2D_f },
{"rsnAllocationRead", "(II[I)V", (void*)nAllocationRead_i },
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 781dbea..ad162bb 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -184,6 +184,16 @@
togglePlay
}
+Allocation1DSubElementData {
+ param RsAllocation va
+ param uint32_t x
+ param const void *data
+ param uint32_t comp_offset
+ param uint32_t bytes
+ handcodeApi
+ togglePlay
+ }
+
Allocation2DSubData {
param RsAllocation va
param uint32_t xoff
@@ -194,6 +204,15 @@
param uint32_t bytes
}
+Allocation2DSubElementData {
+ param RsAllocation va
+ param uint32_t x
+ param uint32_t y
+ param const void *data
+ param uint32_t element_offset
+ param uint32_t bytes
+ }
+
AllocationRead {
param RsAllocation va
param void * data
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 7e44fea..60998c31 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -230,7 +230,7 @@
}
-void Allocation::data(const void *data, uint32_t sizeBytes)
+void Allocation::data(Context *rsc, const void *data, uint32_t sizeBytes)
{
uint32_t size = mType->getSizeBytes();
if (size != sizeBytes) {
@@ -253,7 +253,7 @@
memcpy(data, mPtr, mType->getSizeBytes());
}
-void Allocation::subData(uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes)
+void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes)
{
uint32_t eSize = mType->getElementSizeBytes();
uint8_t * ptr = static_cast<uint8_t *>(mPtr);
@@ -276,7 +276,7 @@
mUploadDefered = true;
}
-void Allocation::subData(uint32_t xoff, uint32_t yoff,
+void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff,
uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes)
{
uint32_t eSize = mType->getElementSizeBytes();
@@ -306,11 +306,93 @@
mUploadDefered = true;
}
-void Allocation::subData(uint32_t xoff, uint32_t yoff, uint32_t zoff,
+void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes)
{
}
+void Allocation::subElementData(Context *rsc, uint32_t x, const void *data,
+ uint32_t cIdx, uint32_t sizeBytes)
+{
+ uint32_t eSize = mType->getElementSizeBytes();
+ uint8_t * ptr = static_cast<uint8_t *>(mPtr);
+ ptr += eSize * x;
+
+ if (cIdx >= mType->getElement()->getFieldCount()) {
+ LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
+ rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
+ return;
+ }
+
+ if (x >= mType->getDimX()) {
+ LOGE("Error Allocation::subElementData X offset %i out of range.", x);
+ rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
+ return;
+ }
+
+ const Element * e = mType->getElement()->getField(cIdx);
+ ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
+
+ if (sizeBytes != e->getSizeBytes()) {
+ LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
+ rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
+ return;
+ }
+
+ if (e->getHasReferences()) {
+ e->incRefs(data);
+ e->decRefs(ptr);
+ }
+
+ memcpy(ptr, data, sizeBytes);
+ sendDirty();
+ mUploadDefered = true;
+}
+
+void Allocation::subElementData(Context *rsc, uint32_t x, uint32_t y,
+ const void *data, uint32_t cIdx, uint32_t sizeBytes)
+{
+ uint32_t eSize = mType->getElementSizeBytes();
+ uint8_t * ptr = static_cast<uint8_t *>(mPtr);
+ ptr += eSize * (x + y * mType->getDimX());
+
+ if (x >= mType->getDimX()) {
+ LOGE("Error Allocation::subElementData X offset %i out of range.", x);
+ rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
+ return;
+ }
+
+ if (y >= mType->getDimY()) {
+ LOGE("Error Allocation::subElementData X offset %i out of range.", x);
+ rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
+ return;
+ }
+
+ if (cIdx >= mType->getElement()->getFieldCount()) {
+ LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
+ rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
+ return;
+ }
+
+ const Element * e = mType->getElement()->getField(cIdx);
+ ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
+
+ if (sizeBytes != e->getSizeBytes()) {
+ LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
+ rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
+ return;
+ }
+
+ if (e->getHasReferences()) {
+ e->incRefs(data);
+ e->decRefs(ptr);
+ }
+
+ memcpy(ptr, data, sizeBytes);
+ sendDirty();
+ mUploadDefered = true;
+}
+
void Allocation::addProgramToDirty(const Program *p)
{
mToDirtyList.push(p);
@@ -394,7 +476,7 @@
alloc->setName(name.string(), name.size());
// Read in all of our allocation data
- alloc->data(stream->getPtr() + stream->getPos(), dataSize);
+ alloc->data(rsc, stream->getPtr() + stream->getPos(), dataSize);
stream->reset(stream->getPos() + dataSize);
return alloc;
@@ -662,16 +744,19 @@
}
ElementConverter_t cvt = pickConverter(dst, src);
- cvt(texAlloc->getPtr(), data, w * h);
-
- if (genMips) {
- Adapter2D adapt(rsc, texAlloc);
- Adapter2D adapt2(rsc, texAlloc);
- for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
- adapt.setLOD(lod);
- adapt2.setLOD(lod + 1);
- mip(adapt2, adapt);
+ if (cvt) {
+ cvt(texAlloc->getPtr(), data, w * h);
+ if (genMips) {
+ Adapter2D adapt(rsc, texAlloc);
+ Adapter2D adapt2(rsc, texAlloc);
+ for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
+ adapt.setLOD(lod);
+ adapt2.setLOD(lod + 1);
+ mip(adapt2, adapt);
+ }
}
+ } else {
+ rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format");
}
return texAlloc;
@@ -708,19 +793,31 @@
void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes)
{
Allocation *a = static_cast<Allocation *>(va);
- a->data(data, sizeBytes);
+ a->data(rsc, data, sizeBytes);
}
void rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes)
{
Allocation *a = static_cast<Allocation *>(va);
- a->subData(xoff, count, data, sizeBytes);
+ a->subData(rsc, xoff, count, data, sizeBytes);
+}
+
+void rsi_Allocation2DSubElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, const void *data, uint32_t eoff, uint32_t sizeBytes)
+{
+ Allocation *a = static_cast<Allocation *>(va);
+ a->subElementData(rsc, x, y, data, eoff, sizeBytes);
+}
+
+void rsi_Allocation1DSubElementData(Context *rsc, RsAllocation va, uint32_t x, const void *data, uint32_t eoff, uint32_t sizeBytes)
+{
+ Allocation *a = static_cast<Allocation *>(va);
+ a->subElementData(rsc, x, data, eoff, sizeBytes);
}
void rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes)
{
Allocation *a = static_cast<Allocation *>(va);
- a->subData(xoff, yoff, w, h, data, sizeBytes);
+ a->subData(rsc, xoff, yoff, w, h, data, sizeBytes);
}
void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data)
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index 177d5a4..967f220 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -56,13 +56,18 @@
uint32_t getBufferObjectID() const {return mBufferID;}
- void data(const void *data, uint32_t sizeBytes);
- void subData(uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes);
- void subData(uint32_t xoff, uint32_t yoff,
+ void data(Context *rsc, const void *data, uint32_t sizeBytes);
+ void subData(Context *rsc, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes);
+ void subData(Context *rsc, uint32_t xoff, uint32_t yoff,
uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes);
- void subData(uint32_t xoff, uint32_t yoff, uint32_t zoff,
+ void subData(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes);
+ void subElementData(Context *rsc, uint32_t x,
+ const void *data, uint32_t elementOff, uint32_t sizeBytes);
+ void subElementData(Context *rsc, uint32_t x, uint32_t y,
+ const void *data, uint32_t elementOff, uint32_t sizeBytes);
+
void read(void *data);
void enableGLVertexBuffers() const;
diff --git a/libs/rs/rsHandcode.h b/libs/rs/rsHandcode.h
index 353b73a..c02fd42 100644
--- a/libs/rs/rsHandcode.h
+++ b/libs/rs/rsHandcode.h
@@ -96,3 +96,26 @@
}
+static inline void rsHCAPI_Allocation1DSubElementData (RsContext rsc, RsAllocation va, uint32_t x, const void * data, uint32_t comp_offset, uint32_t sizeBytes)
+{
+ ThreadIO *io = &((Context *)rsc)->mIO;
+ uint32_t size = sizeof(RS_CMD_Allocation1DSubElementData);
+ if (sizeBytes < DATA_SYNC_SIZE) {
+ size += (sizeBytes + 3) & ~3;
+ }
+ RS_CMD_Allocation1DSubElementData *cmd = static_cast<RS_CMD_Allocation1DSubElementData *>(io->mToCore.reserve(size));
+ cmd->va = va;
+ cmd->x = x;
+ cmd->data = data;
+ cmd->comp_offset = comp_offset;
+ cmd->bytes = sizeBytes;
+ if (sizeBytes < DATA_SYNC_SIZE) {
+ cmd->data = (void *)(cmd+1);
+ memcpy(cmd+1, data, sizeBytes);
+ io->mToCore.commit(RS_CMD_ID_Allocation1DSubElementData, size);
+ } else {
+ io->mToCore.commitSync(RS_CMD_ID_Allocation1DSubElementData, size);
+ }
+
+}
+
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 41d8247..e1628f4 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -331,10 +331,10 @@
{
Matrix m;
m.loadOrtho(0,rsc->getWidth(), rsc->getHeight(),0, -1,1);
- mDefaultAlloc->subData(RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0], 16*4);
+ mDefaultAlloc->subData(rsc, RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0], 16*4);
m.loadIdentity();
- mDefaultAlloc->subData(RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0], 16*4);
+ mDefaultAlloc->subData(rsc, RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0], 16*4);
}
void ProgramVertexState::deinit(Context *rsc)