summaryrefslogtreecommitdiffstats
path: root/libs/rs/rsAllocation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/rs/rsAllocation.cpp')
-rw-r--r--libs/rs/rsAllocation.cpp811
1 files changed, 517 insertions, 294 deletions
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 4e8278d..41c9fe2 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -13,41 +13,45 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+#ifndef ANDROID_RS_BUILD_FOR_HOST
#include "rsContext.h"
#include <GLES/gl.h>
#include <GLES2/gl2.h>
#include <GLES/glext.h>
+#else
+#include "rsContextHostStub.h"
+
+#include <OpenGL/gl.h>
+#include <OpenGl/glext.h>
+#endif
+
+#include "utils/StopWatch.h"
+
+static void rsaAllocationGenerateScriptMips(RsContext con, RsAllocation va);
using namespace android;
using namespace android::renderscript;
-Allocation::Allocation(Context *rsc, const Type *type) : ObjectBase(rsc)
-{
+Allocation::Allocation(Context *rsc, const Type *type, uint32_t usages,
+ RsAllocationMipmapControl mc)
+ : ObjectBase(rsc) {
init(rsc, type);
- mPtr = malloc(mType->getSizeBytes());
+ mUsageFlags = usages;
+ mMipmapControl = mc;
+
+ allocScriptMemory();
+ if (mType->getElement()->getHasReferences()) {
+ memset(mPtr, 0, mType->getSizeBytes());
+ }
if (!mPtr) {
LOGE("Allocation::Allocation, alloc failure");
}
}
-Allocation::Allocation(Context *rsc, const Type *type, void *bmp,
- void *callbackData, RsBitmapCallback_t callback)
-: ObjectBase(rsc)
-{
- init(rsc, type);
- mPtr = bmp;
- mUserBitmapCallback = callback;
- mUserBitmapCallbackData = callbackData;
-}
-
-void Allocation::init(Context *rsc, const Type *type)
-{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
+void Allocation::init(Context *rsc, const Type *type) {
mPtr = NULL;
mCpuWrite = false;
@@ -57,10 +61,10 @@ void Allocation::init(Context *rsc, const Type *type)
mReadWriteRatio = 0;
mUpdateSize = 0;
+ mUsageFlags = 0;
+ mMipmapControl = RS_ALLOCATION_MIPMAP_NONE;
- mIsTexture = false;
mTextureID = 0;
- mIsVertexBuffer = false;
mBufferID = 0;
mUploadDefered = false;
@@ -73,14 +77,12 @@ void Allocation::init(Context *rsc, const Type *type)
mPtr = NULL;
}
-Allocation::~Allocation()
-{
+Allocation::~Allocation() {
if (mUserBitmapCallback != NULL) {
mUserBitmapCallback(mUserBitmapCallbackData);
- } else {
- free(mPtr);
+ mPtr = NULL;
}
- mPtr = NULL;
+ freeScriptMemory();
if (mBufferID) {
// Causes a SW crash....
@@ -94,46 +96,70 @@ Allocation::~Allocation()
}
}
-void Allocation::setCpuWritable(bool)
-{
+void Allocation::setCpuWritable(bool) {
}
-void Allocation::setGpuWritable(bool)
-{
+void Allocation::setGpuWritable(bool) {
}
-void Allocation::setCpuReadable(bool)
-{
+void Allocation::setCpuReadable(bool) {
}
-void Allocation::setGpuReadable(bool)
-{
+void Allocation::setGpuReadable(bool) {
}
-bool Allocation::fixAllocation()
-{
+bool Allocation::fixAllocation() {
return false;
}
-void Allocation::deferedUploadToTexture(const Context *rsc, bool genMipmap, uint32_t lodOffset)
-{
- rsAssert(lodOffset < mType->getLODCount());
- mIsTexture = true;
- mTextureLOD = lodOffset;
+void Allocation::deferedUploadToTexture(const Context *rsc) {
+ mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
mUploadDefered = true;
- mTextureGenMipmap = !mType->getDimLOD() && genMipmap;
}
-void Allocation::uploadToTexture(const Context *rsc)
-{
- //rsAssert(!mTextureId);
+uint32_t Allocation::getGLTarget() const {
+ if (getIsTexture()) {
+ if (mType->getDimFaces()) {
+ return GL_TEXTURE_CUBE_MAP;
+ } else {
+ return GL_TEXTURE_2D;
+ }
+ }
+ if (getIsBufferObject()) {
+ return GL_ARRAY_BUFFER;
+ }
+ return 0;
+}
+
+void Allocation::allocScriptMemory() {
+ rsAssert(!mPtr);
+ mPtr = malloc(mType->getSizeBytes());
+}
- mIsTexture = true;
- if (!rsc->checkDriver()) {
- mUploadDefered = true;
- return;
+void Allocation::freeScriptMemory() {
+ if (mPtr) {
+ free(mPtr);
+ mPtr = NULL;
+ }
+}
+
+
+void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
+ rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
+
+ if (getIsTexture()) {
+ uploadToTexture(rsc);
+ }
+ if (getIsBufferObject()) {
+ uploadToBufferObject(rsc);
}
+ mUploadDefered = false;
+}
+
+void Allocation::uploadToTexture(const Context *rsc) {
+
+ mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
GLenum type = mType->getElement()->getComponent().getGLType();
GLenum format = mType->getElement()->getComponent().getGLFormat();
@@ -141,6 +167,12 @@ void Allocation::uploadToTexture(const Context *rsc)
return;
}
+ if (!mPtr) {
+ return;
+ }
+
+ bool isFirstUpload = false;
+
if (!mTextureID) {
glGenTextures(1, &mTextureID);
@@ -153,41 +185,95 @@ void Allocation::uploadToTexture(const Context *rsc)
mUploadDefered = true;
return;
}
+ isFirstUpload = true;
}
- glBindTexture(GL_TEXTURE_2D, mTextureID);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- Adapter2D adapt(getContext(), this);
- for(uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) {
- adapt.setLOD(lod+mTextureLOD);
+ upload2DTexture(isFirstUpload);
- uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
- glTexImage2D(GL_TEXTURE_2D, lod, format,
- adapt.getDimX(), adapt.getDimY(),
- 0, format, type, ptr);
+ if (!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
+ freeScriptMemory();
}
- if (mTextureGenMipmap) {
- glGenerateMipmap(GL_TEXTURE_2D);
+
+ rsc->checkError("Allocation::uploadToTexture");
+}
+
+const static GLenum gFaceOrder[] = {
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
+};
+
+void Allocation::update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
+ uint32_t lod, RsAllocationCubemapFace face,
+ uint32_t w, uint32_t h) {
+ GLenum type = mType->getElement()->getComponent().getGLType();
+ GLenum format = mType->getElement()->getComponent().getGLFormat();
+ GLenum target = (GLenum)getGLTarget();
+ rsAssert(mTextureID);
+ glBindTexture(target, mTextureID);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ GLenum t = GL_TEXTURE_2D;
+ if (mType->getDimFaces()) {
+ t = gFaceOrder[face];
+ }
+ glTexSubImage2D(t, lod, xoff, yoff, w, h, format, type, ptr);
+}
+
+void Allocation::upload2DTexture(bool isFirstUpload) {
+ GLenum type = mType->getElement()->getComponent().getGLType();
+ GLenum format = mType->getElement()->getComponent().getGLFormat();
+
+ GLenum target = (GLenum)getGLTarget();
+ glBindTexture(target, mTextureID);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ uint32_t faceCount = 1;
+ if (mType->getDimFaces()) {
+ faceCount = 6;
+ }
+
+ for (uint32_t face = 0; face < faceCount; face ++) {
+ for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
+ const uint8_t *p = (const uint8_t *)mPtr;
+ p += mType->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);
+
+ GLenum t = GL_TEXTURE_2D;
+ if (mType->getDimFaces()) {
+ t = gFaceOrder[face];
+ }
+
+ if (isFirstUpload) {
+ glTexImage2D(t, lod, format,
+ mType->getLODDimX(lod), mType->getLODDimY(lod),
+ 0, format, type, p);
+ } else {
+ glTexSubImage2D(t, lod, 0, 0,
+ mType->getLODDimX(lod), mType->getLODDimY(lod),
+ format, type, p);
+ }
+ }
}
+ if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
+#ifndef ANDROID_RS_BUILD_FOR_HOST
+ glGenerateMipmap(target);
+#endif //ANDROID_RS_BUILD_FOR_HOST
+ }
}
-void Allocation::deferedUploadToBufferObject(const Context *rsc)
-{
- mIsVertexBuffer = true;
+void Allocation::deferedUploadToBufferObject(const Context *rsc) {
+ mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
mUploadDefered = true;
}
-void Allocation::uploadToBufferObject(const Context *rsc)
-{
+void Allocation::uploadToBufferObject(const Context *rsc) {
rsAssert(!mType->getDimY());
rsAssert(!mType->getDimZ());
- mIsVertexBuffer = true;
- if (!rsc->checkDriver()) {
- mUploadDefered = true;
- return;
- }
+ mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
if (!mBufferID) {
glGenBuffers(1, &mBufferID);
@@ -197,45 +283,25 @@ void Allocation::uploadToBufferObject(const Context *rsc)
mUploadDefered = true;
return;
}
-
- glBindBuffer(GL_ARRAY_BUFFER, mBufferID);
- glBufferData(GL_ARRAY_BUFFER, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ GLenum target = (GLenum)getGLTarget();
+ glBindBuffer(target, mBufferID);
+ glBufferData(target, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
+ glBindBuffer(target, 0);
+ rsc->checkError("Allocation::uploadToBufferObject");
}
-void Allocation::uploadCheck(const Context *rsc)
-{
+void Allocation::uploadCheck(Context *rsc) {
if (mUploadDefered) {
- mUploadDefered = false;
- if (mIsVertexBuffer) {
- uploadToBufferObject(rsc);
- }
- if (mIsTexture) {
- uploadToTexture(rsc);
- }
+ syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT);
}
}
-
-void Allocation::data(const void *data, uint32_t sizeBytes)
-{
- uint32_t size = mType->getSizeBytes();
- if (size != sizeBytes) {
- LOGE("Allocation::data called with mismatched size expected %i, got %i", size, sizeBytes);
- return;
- }
- memcpy(mPtr, data, size);
- sendDirty();
- mUploadDefered = true;
-}
-
-void Allocation::read(void *data)
-{
+void Allocation::read(void *data) {
memcpy(data, mPtr, mType->getSizeBytes());
}
-void Allocation::subData(uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes)
-{
+void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
+ uint32_t count, const void *data, uint32_t sizeBytes) {
uint32_t eSize = mType->getElementSizeBytes();
uint8_t * ptr = static_cast<uint8_t *>(mPtr);
ptr += eSize * xoff;
@@ -246,49 +312,143 @@ void Allocation::subData(uint32_t xoff, uint32_t count, const void *data, uint32
mType->dumpLOGV("type info");
return;
}
+
+ if (mType->getElement()->getHasReferences()) {
+ incRefs(data, count);
+ decRefs(ptr, count);
+ }
+
memcpy(ptr, data, size);
sendDirty();
mUploadDefered = true;
}
-void Allocation::subData(uint32_t xoff, uint32_t yoff,
- uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes)
-{
+void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
+ uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
uint32_t eSize = mType->getElementSizeBytes();
uint32_t lineSize = eSize * w;
uint32_t destW = mType->getDimX();
- const uint8_t *src = static_cast<const uint8_t *>(data);
- uint8_t *dst = static_cast<uint8_t *>(mPtr);
- dst += eSize * (xoff + yoff * destW);
+ //LOGE("data2d %p, %i %i %i %i %i %i %p %i", this, xoff, yoff, lod, face, w, h, data, sizeBytes);
- if ((lineSize * eSize * h) != sizeBytes) {
+ if ((lineSize * h) != sizeBytes) {
+ LOGE("Allocation size mismatch, expected %i, got %i", (lineSize * h), sizeBytes);
rsAssert(!"Allocation::subData called with mismatched size");
return;
}
- for (uint32_t line=yoff; line < (yoff+h); line++) {
- uint8_t * ptr = static_cast<uint8_t *>(mPtr);
- memcpy(dst, src, lineSize);
- src += lineSize;
- dst += destW * eSize;
+ if (mPtr) {
+ const uint8_t *src = static_cast<const uint8_t *>(data);
+ uint8_t *dst = static_cast<uint8_t *>(mPtr);
+ dst += mType->getLODFaceOffset(lod, face, xoff, yoff);
+
+ //LOGE(" %p %p %i ", dst, src, eSize);
+ for (uint32_t line=yoff; line < (yoff+h); line++) {
+ if (mType->getElement()->getHasReferences()) {
+ incRefs(src, w);
+ decRefs(dst, w);
+ }
+ memcpy(dst, src, lineSize);
+ src += lineSize;
+ dst += destW * eSize;
+ }
+ sendDirty();
+ mUploadDefered = true;
+ } else {
+ update2DTexture(data, xoff, yoff, lod, face, w, h);
+ }
+}
+
+void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
+ uint32_t lod, RsAllocationCubemapFace face,
+ uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
+}
+
+void Allocation::elementData(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::subData(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::elementData(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.add(p);
+void Allocation::addProgramToDirty(const Program *p) {
+ mToDirtyList.push(p);
}
-void Allocation::removeProgramToDirty(const Program *p)
-{
+void Allocation::removeProgramToDirty(const Program *p) {
for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
if (mToDirtyList[ct] == p) {
mToDirtyList.removeAt(ct);
@@ -298,8 +458,7 @@ void Allocation::removeProgramToDirty(const Program *p)
rsAssert(0);
}
-void Allocation::dumpLOGV(const char *prefix) const
-{
+void Allocation::dumpLOGV(const char *prefix) const {
ObjectBase::dumpLOGV(prefix);
String8 s(prefix);
@@ -311,57 +470,143 @@ void Allocation::dumpLOGV(const char *prefix) const
LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
- LOGV("%s allocation mIsTexture=%i mTextureID=%i, mIsVertexBuffer=%i, mBufferID=%i",
- prefix, mIsTexture, mTextureID, mIsVertexBuffer, mBufferID);
+ LOGV("%s allocation mUsageFlags=0x04%x, mMipmapControl=0x%04x, mTextureID=%i, mBufferID=%i",
+ prefix, mUsageFlags, mMipmapControl, mTextureID, mBufferID);
+}
+
+void Allocation::serialize(OStream *stream) const {
+ // Need to identify ourselves
+ stream->addU32((uint32_t)getClassId());
+ String8 name(getName());
+ stream->addString(&name);
+
+ // First thing we need to serialize is the type object since it will be needed
+ // to initialize the class
+ mType->serialize(stream);
+
+ uint32_t dataSize = mType->getSizeBytes();
+ // Write how much data we are storing
+ stream->addU32(dataSize);
+ // Now write the data
+ stream->addByteArray(mPtr, dataSize);
+}
+
+Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
+ // First make sure we are reading the correct object
+ RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
+ if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
+ LOGE("allocation loading skipped due to invalid class id\n");
+ return NULL;
+ }
+
+ String8 name;
+ stream->loadString(&name);
+
+ Type *type = Type::createFromStream(rsc, stream);
+ if (!type) {
+ return NULL;
+ }
+ type->compute();
+
+ // Number of bytes we wrote out for this allocation
+ uint32_t dataSize = stream->loadU32();
+ if (dataSize != type->getSizeBytes()) {
+ LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
+ ObjectBase::checkDelete(type);
+ return NULL;
+ }
+
+ Allocation *alloc = new Allocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
+ alloc->setName(name.string(), name.size());
+
+ uint32_t count = dataSize / type->getElementSizeBytes();
+
+ // Read in all of our allocation data
+ alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
+ stream->reset(stream->getPos() + dataSize);
+
+ return alloc;
}
-void Allocation::sendDirty() const
-{
+void Allocation::sendDirty() const {
for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
mToDirtyList[ct]->forceDirty();
}
}
-/////////////////
-//
+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 --;
+ p += stride;
+ }
+}
-namespace android {
-namespace renderscript {
+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();
-RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype)
-{
- const Type * type = static_cast<const Type *>(vtype);
+ p += stride * startOff;
+ while (ct > 0) {
+ e->decRefs(p);
+ ct --;
+ p += stride;
+ }
+}
- Allocation * alloc = new Allocation(rsc, type);
- alloc->incUserRef();
- return alloc;
+void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
}
-RsAllocation rsi_AllocationCreateSized(Context *rsc, RsElement e, size_t count)
-{
- Type * type = new Type(rsc);
- type->setDimX(count);
- type->setElement(static_cast<Element *>(e));
- type->compute();
- return rsi_AllocationCreateTyped(rsc, type);
+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 rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel)
-{
+void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
+ LOGE("not implemented");
+}
+
+/////////////////
+//
+
+
+namespace android {
+namespace renderscript {
+
+void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) {
Allocation *alloc = static_cast<Allocation *>(va);
- alloc->deferedUploadToTexture(rsc, genmip, baseMipLevel);
+ alloc->deferedUploadToTexture(rsc);
}
-void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va)
-{
+void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) {
Allocation *alloc = static_cast<Allocation *>(va);
alloc->deferedUploadToBufferObject(rsc);
}
-static void mip565(const Adapter2D &out, const Adapter2D &in)
-{
+static void mip565(const Adapter2D &out, const Adapter2D &in) {
uint32_t w = out.getDimX();
uint32_t h = out.getDimY();
@@ -379,8 +624,7 @@ static void mip565(const Adapter2D &out, const Adapter2D &in)
}
}
-static void mip8888(const Adapter2D &out, const Adapter2D &in)
-{
+static void mip8888(const Adapter2D &out, const Adapter2D &in) {
uint32_t w = out.getDimX();
uint32_t h = out.getDimY();
@@ -398,8 +642,7 @@ static void mip8888(const Adapter2D &out, const Adapter2D &in)
}
}
-static void mip8(const Adapter2D &out, const Adapter2D &in)
-{
+static void mip8(const Adapter2D &out, const Adapter2D &in) {
uint32_t w = out.getDimX();
uint32_t h = out.getDimY();
@@ -417,9 +660,8 @@ static void mip8(const Adapter2D &out, const Adapter2D &in)
}
}
-static void mip(const Adapter2D &out, const Adapter2D &in)
-{
- switch(out.getBaseType()->getElement()->getSizeBits()) {
+static void mip(const Adapter2D &out, const Adapter2D &in) {
+ switch (out.getBaseType()->getElement()->getSizeBits()) {
case 32:
mip8888(out, in);
break;
@@ -429,190 +671,171 @@ static void mip(const Adapter2D &out, const Adapter2D &in)
case 8:
mip8(out, in);
break;
-
}
-
}
-typedef void (*ElementConverter_t)(void *dst, const void *src, uint32_t count);
+#ifndef ANDROID_RS_BUILD_FOR_HOST
-static void elementConverter_cpy_16(void *dst, const void *src, uint32_t count)
-{
- memcpy(dst, src, count * 2);
-}
-static void elementConverter_cpy_8(void *dst, const void *src, uint32_t count)
-{
- memcpy(dst, src, count);
-}
-static void elementConverter_cpy_32(void *dst, const void *src, uint32_t count)
-{
- memcpy(dst, src, count * 4);
+void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
+ Allocation *a = static_cast<Allocation *>(va);
+ a->syncAll(rsc, src);
}
+void rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) {
+ Allocation *texAlloc = static_cast<Allocation *>(va);
+ rsaAllocationGenerateScriptMips(rsc, texAlloc);
+}
-static void elementConverter_888_to_565(void *dst, const void *src, uint32_t count)
-{
- uint16_t *d = static_cast<uint16_t *>(dst);
- const uint8_t *s = static_cast<const uint8_t *>(src);
+void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) {
+ Allocation *texAlloc = static_cast<Allocation *>(va);
+ const Type * t = texAlloc->getType();
- while(count--) {
- *d = rs888to565(s[0], s[1], s[2]);
- d++;
- s+= 3;
+ size_t s = t->getDimX() * t->getDimY() * t->getElementSizeBytes();
+ if (s != dataLen) {
+ rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
+ return;
}
+
+ memcpy(data, texAlloc->getPtr(), s);
}
-static void elementConverter_8888_to_565(void *dst, const void *src, uint32_t count)
-{
- uint16_t *d = static_cast<uint16_t *>(dst);
- const uint8_t *s = static_cast<const uint8_t *>(src);
+void rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
+ uint32_t count, const void *data, uint32_t sizeBytes) {
+ Allocation *a = static_cast<Allocation *>(va);
+ a->data(rsc, xoff, lod, count, data, sizeBytes);
+}
- while(count--) {
- *d = rs888to565(s[0], s[1], s[2]);
- d++;
- s+= 4;
- }
+void rsi_Allocation2DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t lod, RsAllocationCubemapFace face,
+ const void *data, uint32_t eoff, uint32_t sizeBytes) {
+ Allocation *a = static_cast<Allocation *>(va);
+ a->elementData(rsc, x, y, data, eoff, sizeBytes);
+}
+
+void rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t lod,
+ const void *data, uint32_t eoff, uint32_t sizeBytes) {
+ Allocation *a = static_cast<Allocation *>(va);
+ a->elementData(rsc, x, data, eoff, sizeBytes);
}
-static ElementConverter_t pickConverter(const Element *dst, const Element *src)
-{
- GLenum srcGLType = src->getComponent().getGLType();
- GLenum srcGLFmt = src->getComponent().getGLFormat();
- GLenum dstGLType = dst->getComponent().getGLType();
- GLenum dstGLFmt = dst->getComponent().getGLFormat();
+void rsi_Allocation2DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
+ uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
+ Allocation *a = static_cast<Allocation *>(va);
+ a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes);
+}
- if (srcGLFmt == dstGLFmt && srcGLType == dstGLType) {
- switch(dst->getSizeBytes()) {
- case 4:
- return elementConverter_cpy_32;
- case 2:
- return elementConverter_cpy_16;
- case 1:
- return elementConverter_cpy_8;
- }
- }
+void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data) {
+ Allocation *a = static_cast<Allocation *>(va);
+ a->read(data);
+}
- if (srcGLType == GL_UNSIGNED_BYTE &&
- srcGLFmt == GL_RGB &&
- dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
- dstGLType == GL_RGB) {
+void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
+ Allocation *a = static_cast<Allocation *>(va);
+ a->resize1D(rsc, dimX);
+}
- return elementConverter_888_to_565;
- }
+void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
+ Allocation *a = static_cast<Allocation *>(va);
+ a->resize2D(rsc, dimX, dimY);
+}
+
+#endif //ANDROID_RS_BUILD_FOR_HOST
- if (srcGLType == GL_UNSIGNED_BYTE &&
- srcGLFmt == GL_RGBA &&
- dstGLType == GL_UNSIGNED_SHORT_5_6_5 &&
- dstGLType == GL_RGB) {
+}
+}
- return elementConverter_8888_to_565;
+static void rsaAllocationGenerateScriptMips(RsContext con, RsAllocation va) {
+ Context *rsc = static_cast<Context *>(con);
+ Allocation *texAlloc = static_cast<Allocation *>(va);
+ uint32_t numFaces = texAlloc->getType()->getDimFaces() ? 6 : 1;
+ for (uint32_t face = 0; face < numFaces; face ++) {
+ Adapter2D adapt(rsc, texAlloc);
+ Adapter2D adapt2(rsc, texAlloc);
+ adapt.setFace(face);
+ adapt2.setFace(face);
+ for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
+ adapt.setLOD(lod);
+ adapt2.setLOD(lod + 1);
+ mip(adapt2, adapt);
+ }
}
+}
- LOGE("pickConverter, unsuported combo, src %p, dst %p", src, dst);
- return 0;
+const void * rsaAllocationGetType(RsContext con, RsAllocation va) {
+ Allocation *a = static_cast<Allocation *>(va);
+ a->getType()->incUserRef();
+
+ return a->getType();
}
-RsAllocation rsi_AllocationCreateBitmapRef(Context *rsc, RsType vtype,
- void *bmp, void *callbackData, RsBitmapCallback_t callback)
-{
- const Type * type = static_cast<const Type *>(vtype);
- Allocation * alloc = new Allocation(rsc, type, bmp, callbackData, callback);
+RsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype,
+ RsAllocationMipmapControl mips,
+ uint32_t usages) {
+ Context *rsc = static_cast<Context *>(con);
+ Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype), usages, mips);
alloc->incUserRef();
return alloc;
}
-RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data)
-{
- const Element *src = static_cast<const Element *>(_src);
- const Element *dst = static_cast<const Element *>(_dst);
- // Check for pow2 on pre es 2.0 versions.
- rsAssert(rsc->checkVersion2_0() || (!(w & (w-1)) && !(h & (h-1))));
+RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
+ RsAllocationMipmapControl mips,
+ const void *data, uint32_t usages) {
+ Context *rsc = static_cast<Context *>(con);
+ Type *t = static_cast<Type *>(vtype);
- //LOGE("rsi_AllocationCreateFromBitmap %i %i %i %i %i", w, h, dstFmt, srcFmt, genMips);
- rsi_TypeBegin(rsc, _dst);
- rsi_TypeAdd(rsc, RS_DIMENSION_X, w);
- rsi_TypeAdd(rsc, RS_DIMENSION_Y, h);
- if (genMips) {
- rsi_TypeAdd(rsc, RS_DIMENSION_LOD, 1);
- }
- RsType type = rsi_TypeCreate(rsc);
-
- RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, type);
+ RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, vtype, mips, usages);
Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
if (texAlloc == NULL) {
LOGE("Memory allocation failure");
return NULL;
}
- 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);
- }
+ memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
+ if (mips == RS_ALLOCATION_MIPMAP_FULL) {
+ rsaAllocationGenerateScriptMips(rsc, texAlloc);
}
+ texAlloc->deferedUploadToTexture(rsc);
return texAlloc;
}
-RsAllocation rsi_AllocationCreateFromBitmapBoxed(Context *rsc, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data)
-{
- const Element *srcE = static_cast<const Element *>(_src);
- const Element *dstE = static_cast<const Element *>(_dst);
- uint32_t w2 = rsHigherPow2(w);
- uint32_t h2 = rsHigherPow2(h);
+RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
+ RsAllocationMipmapControl mips,
+ const void *data, uint32_t usages) {
+ Context *rsc = static_cast<Context *>(con);
+ Type *t = static_cast<Type *>(vtype);
- if ((w2 == w) && (h2 == h)) {
- return rsi_AllocationCreateFromBitmap(rsc, w, h, _dst, _src, genMips, data);
+ // Cubemap allocation's faces should be Width by Width each.
+ // Source data should have 6 * Width by Width pixels
+ // Error checking is done in the java layer
+ RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, t, mips, usages);
+ Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
+ if (texAlloc == NULL) {
+ LOGE("Memory allocation failure");
+ return NULL;
}
- uint32_t bpp = srcE->getSizeBytes();
- size_t size = w2 * h2 * bpp;
- uint8_t *tmp = static_cast<uint8_t *>(malloc(size));
- memset(tmp, 0, size);
+ uint32_t faceSize = t->getDimX();
+ uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes();
+ uint32_t copySize = faceSize * t->getElementSizeBytes();
- const uint8_t * src = static_cast<const uint8_t *>(data);
- for (uint32_t y = 0; y < h; y++) {
- uint8_t * ydst = &tmp[(y + ((h2 - h) >> 1)) * w2 * bpp];
- memcpy(&ydst[((w2 - w) >> 1) * bpp], src, w * bpp);
- src += w * bpp;
- }
+ uint8_t *sourcePtr = (uint8_t*)data;
+ for (uint32_t face = 0; face < 6; face ++) {
+ Adapter2D faceAdapter(rsc, texAlloc);
+ faceAdapter.setFace(face);
- RsAllocation ret = rsi_AllocationCreateFromBitmap(rsc, w2, h2, _dst, _src, genMips, tmp);
- free(tmp);
- return ret;
-}
-
-void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes)
-{
- Allocation *a = static_cast<Allocation *>(va);
- a->data(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);
-}
-
-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);
-}
+ for (uint32_t dI = 0; dI < faceSize; dI ++) {
+ memcpy(faceAdapter.getElement(0, dI), sourcePtr + strideBytes * dI, copySize);
+ }
-void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data)
-{
- Allocation *a = static_cast<Allocation *>(va);
- a->read(data);
-}
+ // Move the data pointer to the next cube face
+ sourcePtr += copySize;
+ }
+ if (mips == RS_ALLOCATION_MIPMAP_FULL) {
+ rsaAllocationGenerateScriptMips(rsc, texAlloc);
+ }
-}
+ texAlloc->deferedUploadToTexture(rsc);
+ return texAlloc;
}