Implement allocation resizing.
Change-Id: Ie38d42419d595cec730a8721cc1321c5edb6b4d6
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index a4752f4..0da637e 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -280,6 +280,17 @@
ret const void*
}
+AllocationResize1D {
+ param RsAllocation va
+ param uint32_t dimX
+ }
+
+AllocationResize2D {
+ param RsAllocation va
+ param uint32_t dimX
+ param uint32_t dimY
+ }
+
SamplerBegin {
}
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 0356e4d..2e9e0b3 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -488,12 +488,13 @@
}
}
-void Allocation::incRefs(const void *ptr, size_t ct) const
+void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const
{
const uint8_t *p = static_cast<const uint8_t *>(ptr);
const Element *e = mType->getElement();
uint32_t stride = e->getSizeBytes();
+ p += stride * startOff;
while (ct > 0) {
e->incRefs(p);
ct --;
@@ -501,12 +502,13 @@
}
}
-void Allocation::decRefs(const void *ptr, size_t ct) const
+void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const
{
const uint8_t *p = static_cast<const uint8_t *>(ptr);
const Element *e = mType->getElement();
uint32_t stride = e->getSizeBytes();
+ p += stride * startOff;
while (ct > 0) {
e->decRefs(p);
ct --;
@@ -514,6 +516,37 @@
}
}
+void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len)
+{
+}
+
+void Allocation::resize1D(Context *rsc, uint32_t dimX)
+{
+ Type *t = mType->cloneAndResize1D(rsc, dimX);
+
+ uint32_t oldDimX = mType->getDimX();
+ if (dimX == oldDimX) {
+ return;
+ }
+
+ if (dimX < oldDimX) {
+ decRefs(mPtr, oldDimX - dimX, dimX);
+ }
+ mPtr = realloc(mPtr, t->getSizeBytes());
+
+ if (dimX > oldDimX) {
+ const Element *e = mType->getElement();
+ uint32_t stride = e->getSizeBytes();
+ memset(((uint8_t *)mPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
+ }
+ mType.set(t);
+}
+
+void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY)
+{
+ LOGE("not implemented");
+}
+
/////////////////
//
@@ -822,6 +855,18 @@
a->read(data);
}
+void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX)
+{
+ Allocation *a = static_cast<Allocation *>(va);
+ a->resize1D(rsc, dimX);
+}
+
+void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY)
+{
+ Allocation *a = static_cast<Allocation *>(va);
+ a->resize2D(rsc, dimX, dimY);
+}
+
const void* rsi_AllocationGetType(Context *rsc, RsAllocation va)
{
Allocation *a = static_cast<Allocation *>(va);
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index ce5372f..24e245f 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -55,6 +55,10 @@
void uploadToBufferObject(const Context *rsc);
uint32_t getBufferObjectID() const {return mBufferID;}
+ void copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len);
+
+ void resize1D(Context *rsc, uint32_t dimX);
+ void resize2D(Context *rsc, uint32_t dimX, uint32_t dimY);
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);
@@ -86,8 +90,8 @@
bool getIsTexture() const {return mIsTexture;}
bool getIsBufferObject() const {return mIsVertexBuffer;}
- void incRefs(const void *ptr, size_t ct) const;
- void decRefs(const void *ptr, size_t ct) const;
+ void incRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
+ void decRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
void sendDirty() const;
bool getHasGraphicsMipmaps() const {return mTextureGenMipmap;}
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index fc037a3..8cdb48a 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -274,6 +274,59 @@
return false;
}
+Type * Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const
+{
+ TypeState * stc = &rsc->mStateType;
+ for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
+ Type *t = stc->mTypes[ct];
+ if (t->getElement() != mElement.get()) continue;
+ if (t->getDimX() != dimX) continue;
+ if (t->getDimY() != mDimY) continue;
+ if (t->getDimZ() != mDimZ) continue;
+ if (t->getDimLOD() != mDimLOD) continue;
+ if (t->getDimFaces() != mFaces) continue;
+ t->incUserRef();
+ return t;
+ }
+
+ Type *nt = new Type(rsc);
+ nt->mElement.set(mElement);
+ nt->mDimX = dimX;
+ nt->mDimY = mDimY;
+ nt->mDimZ = mDimZ;
+ nt->mDimLOD = mDimLOD;
+ nt->mFaces = mFaces;
+ nt->compute();
+ return nt;
+}
+
+Type * Type::cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const
+{
+ TypeState * stc = &rsc->mStateType;
+ for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
+ Type *t = stc->mTypes[ct];
+ if (t->getElement() != mElement.get()) continue;
+ if (t->getDimX() != dimX) continue;
+ if (t->getDimY() != dimY) continue;
+ if (t->getDimZ() != mDimZ) continue;
+ if (t->getDimLOD() != mDimLOD) continue;
+ if (t->getDimFaces() != mFaces) continue;
+ t->incUserRef();
+ return t;
+ }
+
+ Type *nt = new Type(rsc);
+ nt->mElement.set(mElement);
+ nt->mDimX = dimX;
+ nt->mDimY = dimY;
+ nt->mDimZ = mDimZ;
+ nt->mDimLOD = mDimLOD;
+ nt->mFaces = mFaces;
+ nt->compute();
+ return nt;
+}
+
+
//////////////////////////////////////////////////
//
namespace android {
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index 33faa87..b5548c0 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -79,6 +79,9 @@
bool isEqual(const Type *other) const;
+ Type * cloneAndResize1D(Context *rsc, uint32_t dimX) const;
+ Type * cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const;
+
protected:
struct LOD {
size_t mX;