diff options
author | Jason Sams <rjsams@android.com> | 2012-02-23 14:19:43 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-02-23 14:19:43 -0800 |
commit | a23c4ebe04e97a4f5c4e25fa6c9f37c6244ebfe4 (patch) | |
tree | 52b22dd201ecaa06d1d92a2db093ce572b3cabf1 | |
parent | b8c247bde943e500651403b1967369c8e10b0184 (diff) | |
parent | f70b0fc880edb7c47d5bcc97edbc125b575bc90d (diff) | |
download | frameworks_base-a23c4ebe04e97a4f5c4e25fa6c9f37c6244ebfe4.zip frameworks_base-a23c4ebe04e97a4f5c4e25fa6c9f37c6244ebfe4.tar.gz frameworks_base-a23c4ebe04e97a4f5c4e25fa6c9f37c6244ebfe4.tar.bz2 |
Merge "start new headers"
-rw-r--r-- | graphics/java/android/renderscript/Allocation.java | 2 | ||||
-rw-r--r-- | libs/rs/Allocation.cpp | 469 | ||||
-rw-r--r-- | libs/rs/Allocation.h | 124 | ||||
-rw-r--r-- | libs/rs/Android.mk | 7 | ||||
-rw-r--r-- | libs/rs/BaseObj.cpp | 61 | ||||
-rw-r--r-- | libs/rs/BaseObj.h | 47 | ||||
-rw-r--r-- | libs/rs/Element.cpp | 436 | ||||
-rw-r--r-- | libs/rs/Element.h | 199 | ||||
-rw-r--r-- | libs/rs/RenderScript.cpp | 155 | ||||
-rw-r--r-- | libs/rs/RenderScript.h | 153 | ||||
-rw-r--r-- | libs/rs/Type.cpp | 159 | ||||
-rw-r--r-- | libs/rs/Type.h | 99 | ||||
-rw-r--r-- | libs/rs/tests/Android.mk | 29 | ||||
-rw-r--r-- | libs/rs/tests/compute.cpp | 41 |
14 files changed, 1980 insertions, 1 deletions
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index 37a270e..6539ff3 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -534,6 +534,7 @@ public class Allocation extends BaseObj { * @param fp */ public void setFromFieldPacker(int xoff, FieldPacker fp) { + mRS.validate(); int eSize = mType.mElement.getSizeBytes(); final byte[] data = fp.getData(); @@ -554,6 +555,7 @@ public class Allocation extends BaseObj { * @param fp */ public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) { + mRS.validate(); if (component_number >= mType.mElement.mElements.length) { throw new RSIllegalArgumentException("Component_number " + component_number + " out of range."); } diff --git a/libs/rs/Allocation.cpp b/libs/rs/Allocation.cpp new file mode 100644 index 0000000..46df171 --- /dev/null +++ b/libs/rs/Allocation.cpp @@ -0,0 +1,469 @@ +/* + * Copyright (C) 2008-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <utils/Log.h> +#include <malloc.h> + +#include "RenderScript.h" +#include "Element.h" +#include "Type.h" +#include "Allocation.h" + + +void * Allocation::getIDSafe() const { + //if (mAdaptedAllocation != NULL) { + //return mAdaptedAllocation.getID(); + //} + return getID(); +} + +void Allocation::updateCacheInfo(const Type *t) { + mCurrentDimX = t->getX(); + mCurrentDimY = t->getY(); + mCurrentDimZ = t->getZ(); + mCurrentCount = mCurrentDimX; + if (mCurrentDimY > 1) { + mCurrentCount *= mCurrentDimY; + } + if (mCurrentDimZ > 1) { + mCurrentCount *= mCurrentDimZ; + } +} + +Allocation::Allocation(void *id, RenderScript *rs, const Type *t, uint32_t usage) : BaseObj(id, rs) { + if ((usage & ~(RS_ALLOCATION_USAGE_SCRIPT | + RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE | + RS_ALLOCATION_USAGE_GRAPHICS_VERTEX | + RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS | + RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET | + RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE | + RS_ALLOCATION_USAGE_IO_INPUT | + RS_ALLOCATION_USAGE_IO_OUTPUT)) != 0) { + ALOGE("Unknown usage specified."); + } + + if ((usage & (RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE | + RS_ALLOCATION_USAGE_IO_INPUT)) != 0) { + mWriteAllowed = false; + if ((usage & ~(RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE | + RS_ALLOCATION_USAGE_IO_INPUT | + RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE | + RS_ALLOCATION_USAGE_SCRIPT)) != 0) { + ALOGE("Invalid usage combination."); + } + } + + mType = t; + mUsage = usage; + + if (t != NULL) { + updateCacheInfo(t); + } +} + +void Allocation::validateIsInt32() { + RsDataType dt = mType->getElement()->getDataType(); + if ((dt == RS_TYPE_SIGNED_32) || (dt == RS_TYPE_UNSIGNED_32)) { + return; + } + ALOGE("32 bit integer source does not match allocation type %i", dt); +} + +void Allocation::validateIsInt16() { + RsDataType dt = mType->getElement()->getDataType(); + if ((dt == RS_TYPE_SIGNED_16) || (dt == RS_TYPE_UNSIGNED_16)) { + return; + } + ALOGE("16 bit integer source does not match allocation type %i", dt); +} + +void Allocation::validateIsInt8() { + RsDataType dt = mType->getElement()->getDataType(); + if ((dt == RS_TYPE_SIGNED_8) || (dt == RS_TYPE_UNSIGNED_8)) { + return; + } + ALOGE("8 bit integer source does not match allocation type %i", dt); +} + +void Allocation::validateIsFloat32() { + RsDataType dt = mType->getElement()->getDataType(); + if (dt == RS_TYPE_FLOAT_32) { + return; + } + ALOGE("32 bit float source does not match allocation type %i", dt); +} + +void Allocation::validateIsObject() { + RsDataType dt = mType->getElement()->getDataType(); + if ((dt == RS_TYPE_ELEMENT) || + (dt == RS_TYPE_TYPE) || + (dt == RS_TYPE_ALLOCATION) || + (dt == RS_TYPE_SAMPLER) || + (dt == RS_TYPE_SCRIPT) || + (dt == RS_TYPE_MESH) || + (dt == RS_TYPE_PROGRAM_FRAGMENT) || + (dt == RS_TYPE_PROGRAM_VERTEX) || + (dt == RS_TYPE_PROGRAM_RASTER) || + (dt == RS_TYPE_PROGRAM_STORE)) { + return; + } + ALOGE("Object source does not match allocation type %i", dt); +} + +void Allocation::updateFromNative() { + BaseObj::updateFromNative(); + + const void *typeID = rsaAllocationGetType(mRS->mContext, getID()); + if(typeID != NULL) { + const Type *old = mType; + Type *t = new Type((void *)typeID, mRS); + t->updateFromNative(); + updateCacheInfo(t); + mType = t; + delete old; + } +} + +void Allocation::syncAll(RsAllocationUsageType srcLocation) { + switch (srcLocation) { + case RS_ALLOCATION_USAGE_SCRIPT: + case RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS: + case RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE: + case RS_ALLOCATION_USAGE_GRAPHICS_VERTEX: + break; + default: + ALOGE("Source must be exactly one usage type."); + } + rsAllocationSyncAll(mRS->mContext, getIDSafe(), srcLocation); +} + +void Allocation::ioSendOutput() { + if ((mUsage & RS_ALLOCATION_USAGE_IO_OUTPUT) == 0) { + ALOGE("Can only send buffer if IO_OUTPUT usage specified."); + } + rsAllocationIoSend(mRS->mContext, getID()); +} + +void Allocation::ioGetInput() { + if ((mUsage & RS_ALLOCATION_USAGE_IO_INPUT) == 0) { + ALOGE("Can only send buffer if IO_OUTPUT usage specified."); + } + rsAllocationIoReceive(mRS->mContext, getID()); +} + +/* +void copyFrom(BaseObj[] d) { + mRS.validate(); + validateIsObject(); + if (d.length != mCurrentCount) { + ALOGE("Array size mismatch, allocation sizeX = " + + mCurrentCount + ", array length = " + d.length); + } + int i[] = new int[d.length]; + for (int ct=0; ct < d.length; ct++) { + i[ct] = d[ct].getID(); + } + copy1DRangeFromUnchecked(0, mCurrentCount, i); +} +*/ + + +/* +void Allocation::setFromFieldPacker(int xoff, FieldPacker fp) { + mRS.validate(); + int eSize = mType.mElement.getSizeBytes(); + final byte[] data = fp.getData(); + + int count = data.length / eSize; + if ((eSize * count) != data.length) { + ALOGE("Field packer length " + data.length + + " not divisible by element size " + eSize + "."); + } + copy1DRangeFromUnchecked(xoff, count, data); +} + +void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) { + mRS.validate(); + if (component_number >= mType.mElement.mElements.length) { + ALOGE("Component_number " + component_number + " out of range."); + } + if(xoff < 0) { + ALOGE("Offset must be >= 0."); + } + + final byte[] data = fp.getData(); + int eSize = mType.mElement.mElements[component_number].getSizeBytes(); + eSize *= mType.mElement.mArraySizes[component_number]; + + if (data.length != eSize) { + ALOGE("Field packer sizelength " + data.length + + " does not match component size " + eSize + "."); + } + + mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD, + component_number, data, data.length); +} +*/ + +void Allocation::generateMipmaps() { + rsAllocationGenerateMipmaps(mRS->mContext, getID()); +} + +void Allocation::copy1DRangeFromUnchecked(uint32_t off, size_t count, const void *data, size_t dataLen) { + if(count < 1) { + ALOGE("Count must be >= 1."); + return; + } + if((off + count) > mCurrentCount) { + ALOGE("Overflow, Available count %zu, got %zu at offset %zu.", mCurrentCount, count, off); + return; + } + if((count * mType->getElement()->getSizeBytes()) > dataLen) { + ALOGE("Array too small for allocation type."); + return; + } + + rsAllocation1DData(mRS->mContext, getIDSafe(), off, mSelectedLOD, count, data, dataLen); +} + +void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int32_t *d, size_t dataLen) { + validateIsInt32(); + copy1DRangeFromUnchecked(off, count, d, dataLen); +} + +void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int16_t *d, size_t dataLen) { + validateIsInt16(); + copy1DRangeFromUnchecked(off, count, d, dataLen); +} + +void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int8_t *d, size_t dataLen) { + validateIsInt8(); + copy1DRangeFromUnchecked(off, count, d, dataLen); +} + +void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const float *d, size_t dataLen) { + validateIsFloat32(); + copy1DRangeFromUnchecked(off, count, d, dataLen); +} + +void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const Allocation *data, uint32_t dataOff) { + rsAllocationCopy2DRange(mRS->mContext, getIDSafe(), off, 0, + mSelectedLOD, mSelectedFace, + count, 1, data->getIDSafe(), dataOff, 0, + data->mSelectedLOD, data->mSelectedFace); +} + +void Allocation::validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h) { + if (mAdaptedAllocation != NULL) { + + } else { + if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) { + ALOGE("Updated region larger than allocation."); + } + } +} + +void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const int8_t *data, size_t dataLen) { + validate2DRange(xoff, yoff, w, h); + rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, + w, h, data, dataLen); +} + +void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const int16_t *data, size_t dataLen) { + validate2DRange(xoff, yoff, w, h); + rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, + w, h, data, dataLen); +} + +void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const int32_t *data, size_t dataLen) { + validate2DRange(xoff, yoff, w, h); + rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, + w, h, data, dataLen); +} + +void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const float *data, size_t dataLen) { + validate2DRange(xoff, yoff, w, h); + rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, + w, h, data, dataLen); +} + +void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const Allocation *data, size_t dataLen, + uint32_t dataXoff, uint32_t dataYoff) { + validate2DRange(xoff, yoff, w, h); + rsAllocationCopy2DRange(mRS->mContext, getIDSafe(), xoff, yoff, + mSelectedLOD, mSelectedFace, + w, h, data->getIDSafe(), dataXoff, dataYoff, + data->mSelectedLOD, data->mSelectedFace); +} + +/* +void copyTo(byte[] d) { + validateIsInt8(); + mRS.validate(); + mRS.nAllocationRead(getID(), d); +} + +void copyTo(short[] d) { + validateIsInt16(); + mRS.validate(); + mRS.nAllocationRead(getID(), d); +} + +void copyTo(int[] d) { + validateIsInt32(); + mRS.validate(); + mRS.nAllocationRead(getID(), d); +} + +void copyTo(float[] d) { + validateIsFloat32(); + mRS.validate(); + mRS.nAllocationRead(getID(), d); +} + +void resize(int dimX) { + if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { + throw new RSInvalidStateException("Resize only support for 1D allocations at this time."); + } + mRS.nAllocationResize1D(getID(), dimX); + 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); +} + +void resize(int dimX, int dimY) { + 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 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); +} +*/ + + +Allocation *Allocation::createTyped(RenderScript *rs, const Type *type, + RsAllocationMipmapControl mips, uint32_t usage) { + void *id = rsAllocationCreateTyped(rs->mContext, type->getID(), mips, usage, 0); + if (id == 0) { + ALOGE("Allocation creation failed."); + return NULL; + } + return new Allocation(id, rs, type, usage); +} + +Allocation *Allocation::createTyped(RenderScript *rs, const Type *type, + RsAllocationMipmapControl mips, uint32_t usage, void *pointer) { + void *id = rsAllocationCreateTyped(rs->mContext, type->getID(), mips, usage, (uint32_t)pointer); + if (id == 0) { + ALOGE("Allocation creation failed."); + } + return new Allocation(id, rs, type, usage); +} + +Allocation *Allocation::createTyped(RenderScript *rs, const Type *type, uint32_t usage) { + return createTyped(rs, type, RS_ALLOCATION_MIPMAP_NONE, usage); +} + +Allocation *Allocation::createSized(RenderScript *rs, const Element *e, size_t count, uint32_t usage) { + Type::Builder b(rs, e); + b.setX(count); + const Type *t = b.create(); + + void *id = rsAllocationCreateTyped(rs->mContext, t->getID(), RS_ALLOCATION_MIPMAP_NONE, usage, 0); + if (id == 0) { + ALOGE("Allocation creation failed."); + } + return new Allocation(id, rs, t, usage); +} + + +/* +SurfaceTexture getSurfaceTexture() { + if ((mUsage & USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) == 0) { + throw new RSInvalidStateException("Allocation is not a surface texture."); + } + + int id = mRS.nAllocationGetSurfaceTextureID(getID()); + return new SurfaceTexture(id); + +} + +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); +} + + +static Allocation createFromBitmapResource(RenderScript rs, + Resources res, + int id, + MipmapControl mips, + int usage) { + + rs.validate(); + Bitmap b = BitmapFactory.decodeResource(res, id); + Allocation alloc = createFromBitmap(rs, b, mips, usage); + b.recycle(); + return alloc; +} + +static Allocation createFromBitmapResource(RenderScript rs, + Resources res, + int id) { + return createFromBitmapResource(rs, res, id, + MipmapControl.MIPMAP_NONE, + USAGE_GRAPHICS_TEXTURE); +} + +static Allocation createFromString(RenderScript rs, + String str, + int usage) { + rs.validate(); + byte[] allocArray = NULL; + try { + allocArray = str.getBytes("UTF-8"); + Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage); + alloc.copyFrom(allocArray); + return alloc; + } + catch (Exception e) { + throw new RSRuntimeException("Could not convert string to utf-8."); + } +} +*/ + diff --git a/libs/rs/Allocation.h b/libs/rs/Allocation.h new file mode 100644 index 0000000..059e61d --- /dev/null +++ b/libs/rs/Allocation.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2008-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include <pthread.h> +#include <rs.h> + +#include "RenderScript.h" +#include "Type.h" +#include "Element.h" + +class Allocation : BaseObj { +protected: + const Type *mType; + uint32_t mUsage; + Allocation *mAdaptedAllocation; + + bool mConstrainedLOD; + bool mConstrainedFace; + bool mConstrainedY; + bool mConstrainedZ; + bool mReadAllowed; + bool mWriteAllowed; + uint32_t mSelectedY; + uint32_t mSelectedZ; + uint32_t mSelectedLOD; + RsAllocationCubemapFace mSelectedFace; + + uint32_t mCurrentDimX; + uint32_t mCurrentDimY; + uint32_t mCurrentDimZ; + uint32_t mCurrentCount; + + + void * getIDSafe() const; + void updateCacheInfo(const Type *t); + + Allocation(void *id, RenderScript *rs, const Type *t, uint32_t usage); + + void validateIsInt32(); + void validateIsInt16(); + void validateIsInt8(); + void validateIsFloat32(); + void validateIsObject(); + + virtual void updateFromNative(); + + void validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h); + +public: + const Type * getType() { + return mType; + } + + void syncAll(RsAllocationUsageType srcLocation); + void ioSendOutput(); + void ioGetInput(); + + //void copyFrom(BaseObj[] d); + //void copyFromUnchecked(int[] d); + //void copyFromUnchecked(short[] d); + //void copyFromUnchecked(byte[] d); + //void copyFromUnchecked(float[] d); + //void copyFrom(int[] d); + //void copyFrom(short[] d); + //void copyFrom(byte[] d); + //void copyFrom(float[] d); + //void setFromFieldPacker(int xoff, FieldPacker fp); + //void setFromFieldPacker(int xoff, int component_number, FieldPacker fp); + void generateMipmaps(); + void copy1DRangeFromUnchecked(uint32_t off, size_t count, const void *data, size_t dataLen); + void copy1DRangeFrom(uint32_t off, size_t count, const int32_t* d, size_t dataLen); + void copy1DRangeFrom(uint32_t off, size_t count, const int16_t* d, size_t dataLen); + void copy1DRangeFrom(uint32_t off, size_t count, const int8_t* d, size_t dataLen); + void copy1DRangeFrom(uint32_t off, size_t count, const float* d, size_t dataLen); + void copy1DRangeFrom(uint32_t off, size_t count, const Allocation *data, uint32_t dataOff); + + void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const int32_t *data, size_t dataLen); + void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const int16_t *data, size_t dataLen); + void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const int8_t *data, size_t dataLen); + void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const float *data, size_t dataLen); + void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const Allocation *data, size_t dataLen, + uint32_t dataXoff, uint32_t dataYoff); + + //void copyTo(byte[] d); + //void copyTo(short[] d); + //void copyTo(int[] d); + //void copyTo(float[] d); + void resize(int dimX); + void resize(int dimX, int dimY); + + static Allocation *createTyped(RenderScript *rs, const Type *type, + RsAllocationMipmapControl mips, uint32_t usage); + static Allocation *createTyped(RenderScript *rs, const Type *type, + RsAllocationMipmapControl mips, uint32_t usage, void * pointer); + + static Allocation *createTyped(RenderScript *rs, const Type *type, + uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT); + static Allocation *createSized(RenderScript *rs, const Element *e, size_t count, + uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT); + //SurfaceTexture *getSurfaceTexture(); + //void setSurfaceTexture(SurfaceTexture *sur); + +}; + + diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk index 9c5d06b..b7cc177 100644 --- a/libs/rs/Android.mk +++ b/libs/rs/Android.mk @@ -127,7 +127,12 @@ LOCAL_SRC_FILES:= \ driver/rsdSampler.cpp \ driver/rsdShader.cpp \ driver/rsdShaderCache.cpp \ - driver/rsdVertexArray.cpp + driver/rsdVertexArray.cpp \ + RenderScript.cpp \ + BaseObj.cpp \ + Element.cpp \ + Type.cpp \ + Allocation.cpp LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libbcc libbcinfo libgui diff --git a/libs/rs/BaseObj.cpp b/libs/rs/BaseObj.cpp new file mode 100644 index 0000000..b2f5450 --- /dev/null +++ b/libs/rs/BaseObj.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include <rs.h> + +#include "RenderScript.h" +#include "BaseObj.h" + +void * BaseObj::getID() const { + if (mID == NULL) { + ALOGE("Internal error: Object id 0."); + } + return mID; +} + +BaseObj::BaseObj(void *id, RenderScript *rs) { + mRS = rs; + mID = id; +} + +void BaseObj::checkValid() { + if (mID == 0) { + ALOGE("Invalid object."); + } +} + +BaseObj::~BaseObj() { + rsObjDestroy(mRS->mContext, mID); + mRS = NULL; + mID = NULL; +} + +void BaseObj::updateFromNative() { + const char *name = NULL; + rsaGetName(mRS, mID, &name); + mName = name; +} + +bool BaseObj::equals(const BaseObj *obj) { + // Early-out check to see if both BaseObjs are actually the same + if (this == obj) + return true; + return mID == obj->mID; +} + + + diff --git a/libs/rs/BaseObj.h b/libs/rs/BaseObj.h new file mode 100644 index 0000000..91f3714 --- /dev/null +++ b/libs/rs/BaseObj.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ANDROID_BASE_OBJ_H__ +#define __ANDROID_BASE_OBJ_H__ + + +#include <pthread.h> +#include <rs.h> + +#include "RenderScript.h" + +class BaseObj { +protected: + friend class Element; + friend class Type; + + void *mID; + RenderScript *mRS; + android::String8 mName; + + void * getID() const; + + BaseObj(void *id, RenderScript *rs); + void checkValid(); + +public: + + virtual ~BaseObj(); + virtual void updateFromNative(); + virtual bool equals(const BaseObj *obj); +}; + +#endif diff --git a/libs/rs/Element.cpp b/libs/rs/Element.cpp new file mode 100644 index 0000000..c621c82 --- /dev/null +++ b/libs/rs/Element.cpp @@ -0,0 +1,436 @@ +/* + * Copyright (C) 2008-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <utils/Log.h> +#include <malloc.h> +#include <string.h> + +#include "RenderScript.h" +#include "Element.h" + + +const Element * Element::getSubElement(uint32_t index) { + if (!mVisibleElementMap.size()) { + ALOGE("Element contains no sub-elements"); + return NULL; + } + if (index >= mVisibleElementMap.size()) { + ALOGE("Illegal sub-element index"); + } + return mElements[mVisibleElementMap[index]]; +} + +const char * Element::getSubElementName(uint32_t index) { + if (!mVisibleElementMap.size()) { + ALOGE("Element contains no sub-elements"); + } + if (index >= mVisibleElementMap.size()) { + ALOGE("Illegal sub-element index"); + } + return mElementNames[mVisibleElementMap[index]]; +} + +size_t Element::getSubElementArraySize(uint32_t index) { + if (!mVisibleElementMap.size()) { + ALOGE("Element contains no sub-elements"); + } + if (index >= mVisibleElementMap.size()) { + ALOGE("Illegal sub-element index"); + } + return mArraySizes[mVisibleElementMap[index]]; +} + +uint32_t Element::getSubElementOffsetBytes(uint32_t index) { + if (mVisibleElementMap.size()) { + ALOGE("Element contains no sub-elements"); + } + if (index >= mVisibleElementMap.size()) { + ALOGE("Illegal sub-element index"); + } + return mOffsetInBytes[mVisibleElementMap[index]]; +} + + +#define CREATE_USER(N, T) const Element * Element::N(RenderScript *rs) { \ + return createUser(rs, RS_TYPE_##T); \ +} +CREATE_USER(BOOLEAN, BOOLEAN); +CREATE_USER(U8, UNSIGNED_8); +CREATE_USER(I8, SIGNED_8); +CREATE_USER(U16, UNSIGNED_16); +CREATE_USER(I16, SIGNED_16); +CREATE_USER(U32, UNSIGNED_32); +CREATE_USER(I32, SIGNED_32); +CREATE_USER(U64, UNSIGNED_64); +CREATE_USER(I64, SIGNED_64); +CREATE_USER(F32, FLOAT_32); +CREATE_USER(F64, FLOAT_64); +CREATE_USER(ELEMENT, ELEMENT); +CREATE_USER(TYPE, TYPE); +CREATE_USER(ALLOCATION, ALLOCATION); +CREATE_USER(SAMPLER, SAMPLER); +CREATE_USER(SCRIPT, SCRIPT); +CREATE_USER(MESH, MESH); +CREATE_USER(PROGRAM_FRAGMENT, PROGRAM_FRAGMENT); +CREATE_USER(PROGRAM_VERTEX, PROGRAM_VERTEX); +CREATE_USER(PROGRAM_RASTER, PROGRAM_RASTER); +CREATE_USER(PROGRAM_STORE, PROGRAM_STORE); +CREATE_USER(MATRIX_4X4, MATRIX_4X4); +CREATE_USER(MATRIX_3X3, MATRIX_3X3); +CREATE_USER(MATRIX_2X2, MATRIX_2X2); + +#define CREATE_PIXEL(N, T, K) const Element * Element::N(RenderScript *rs) { \ + return createPixel(rs, RS_TYPE_##T, RS_KIND_##K); \ +} +CREATE_PIXEL(A_8, UNSIGNED_8, PIXEL_A); +CREATE_PIXEL(RGB_565, UNSIGNED_5_6_5, PIXEL_RGB); +CREATE_PIXEL(RGB_888, UNSIGNED_8, PIXEL_RGB); +CREATE_PIXEL(RGBA_4444, UNSIGNED_4_4_4_4, PIXEL_RGBA); +CREATE_PIXEL(RGBA_8888, UNSIGNED_8, PIXEL_RGBA); + +#define CREATE_VECTOR(N, T) const Element * Element::N##_2(RenderScript *rs) { \ + return createVector(rs, RS_TYPE_##T, 2); \ +} \ +const Element * Element::N##_3(RenderScript *rs) { \ + return createVector(rs, RS_TYPE_##T, 3); \ +} \ +const Element * Element::N##_4(RenderScript *rs) { \ + return createVector(rs, RS_TYPE_##T, 4); \ +} +CREATE_VECTOR(U8, UNSIGNED_8); +CREATE_VECTOR(I8, SIGNED_8); +CREATE_VECTOR(U16, UNSIGNED_16); +CREATE_VECTOR(I16, SIGNED_16); +CREATE_VECTOR(U32, UNSIGNED_32); +CREATE_VECTOR(I32, SIGNED_32); +CREATE_VECTOR(U64, UNSIGNED_64); +CREATE_VECTOR(I64, SIGNED_64); +CREATE_VECTOR(F32, FLOAT_32); +CREATE_VECTOR(F64, FLOAT_64); + + +void Element::updateVisibleSubElements() { + if (!mElements.size()) { + return; + } + mVisibleElementMap.clear(); + + int noPaddingFieldCount = 0; + size_t fieldCount = mElementNames.size(); + // Find out how many elements are not padding + for (size_t ct = 0; ct < fieldCount; ct ++) { + if (mElementNames[ct].string()[0] != '#') { + noPaddingFieldCount ++; + } + } + + // Make a map that points us at non-padding elements + for (size_t ct = 0; ct < fieldCount; ct ++) { + if (mElementNames[ct].string()[0] != '#') { + mVisibleElementMap.push((uint32_t)ct); + } + } +} + +Element::Element(void *id, RenderScript *rs, + android::Vector<const Element *> &elements, + android::Vector<android::String8> &elementNames, + android::Vector<uint32_t> &arraySizes) : BaseObj(id, rs) { + mSizeBytes = 0; + mVectorSize = 1; + mElements = elements; + mArraySizes = arraySizes; + mElementNames = elementNames; + + mType = RS_TYPE_NONE; + mKind = RS_KIND_USER; + + for (size_t ct = 0; ct < mElements.size(); ct++ ) { + mOffsetInBytes.push(mSizeBytes); + mSizeBytes += mElements[ct]->mSizeBytes * mArraySizes[ct]; + } + updateVisibleSubElements(); +} + + +static uint32_t GetSizeInBytesForType(RsDataType dt) { + switch(dt) { + case RS_TYPE_NONE: + return 0; + case RS_TYPE_SIGNED_8: + case RS_TYPE_UNSIGNED_8: + case RS_TYPE_BOOLEAN: + return 1; + + case RS_TYPE_FLOAT_16: + case RS_TYPE_SIGNED_16: + case RS_TYPE_UNSIGNED_16: + case RS_TYPE_UNSIGNED_5_6_5: + case RS_TYPE_UNSIGNED_5_5_5_1: + case RS_TYPE_UNSIGNED_4_4_4_4: + return 2; + + case RS_TYPE_FLOAT_32: + case RS_TYPE_SIGNED_32: + case RS_TYPE_UNSIGNED_32: + return 4; + + case RS_TYPE_FLOAT_64: + case RS_TYPE_SIGNED_64: + case RS_TYPE_UNSIGNED_64: + return 8; + + case RS_TYPE_MATRIX_4X4: + return 16 * 4; + case RS_TYPE_MATRIX_3X3: + return 9 * 4; + case RS_TYPE_MATRIX_2X2: + return 4 * 4; + + case RS_TYPE_TYPE: + case RS_TYPE_ALLOCATION: + case RS_TYPE_SAMPLER: + case RS_TYPE_SCRIPT: + case RS_TYPE_MESH: + case RS_TYPE_PROGRAM_FRAGMENT: + case RS_TYPE_PROGRAM_VERTEX: + case RS_TYPE_PROGRAM_RASTER: + case RS_TYPE_PROGRAM_STORE: + return 4; + + default: + break; + } + + ALOGE("Missing type %i", dt); + return 0; +} + +Element::Element(void *id, RenderScript *rs, + RsDataType dt, RsDataKind dk, bool norm, uint32_t size) : + BaseObj(id, rs) +{ + uint32_t tsize = GetSizeInBytesForType(dt); + if ((dt != RS_TYPE_UNSIGNED_5_6_5) && + (dt != RS_TYPE_UNSIGNED_4_4_4_4) && + (dt != RS_TYPE_UNSIGNED_5_5_5_1)) { + if (size == 3) { + mSizeBytes = tsize * 4; + } else { + mSizeBytes = tsize * size; + } + } else { + mSizeBytes = tsize; + } + mType = dt; + mKind = dk; + mNormalized = norm; + mVectorSize = size; +} + +Element::~Element() { +} + + /* + Element(int id, RenderScript rs) { + super(id, rs); + } + */ + +void Element::updateFromNative() { + BaseObj::updateFromNative(); +/* + // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements + int[] dataBuffer = new int[5]; + mRS.nElementGetNativeData(getID(), dataBuffer); + + mNormalized = dataBuffer[2] == 1 ? true : false; + mVectorSize = dataBuffer[3]; + mSize = 0; + for (DataType dt: DataType.values()) { + if(dt.mID == dataBuffer[0]){ + mType = dt; + mSize = mType.mSize * mVectorSize; + } + } + for (DataKind dk: DataKind.values()) { + if(dk.mID == dataBuffer[1]){ + mKind = dk; + } + } + + int numSubElements = dataBuffer[4]; + if(numSubElements > 0) { + mElements = new Element[numSubElements]; + mElementNames = new String[numSubElements]; + mArraySizes = new int[numSubElements]; + mOffsetInBytes = new int[numSubElements]; + + int[] subElementIds = new int[numSubElements]; + mRS.nElementGetSubElements(getID(), subElementIds, mElementNames, mArraySizes); + for(int i = 0; i < numSubElements; i ++) { + mElements[i] = new Element(subElementIds[i], mRS); + mElements[i].updateFromNative(); + mOffsetInBytes[i] = mSize; + mSize += mElements[i].mSize * mArraySizes[i]; + } + } + */ + updateVisibleSubElements(); +} + +const Element * Element::createUser(RenderScript *rs, RsDataType dt) { + ALOGE("createUser %p %i", rs, dt); + void * id = rsElementCreate(rs->mContext, dt, RS_KIND_USER, false, 1); + return new Element(id, rs, dt, RS_KIND_USER, false, 1); +} + +const Element * Element::createVector(RenderScript *rs, RsDataType dt, uint32_t size) { + if (size < 2 || size > 4) { + ALOGE("Vector size out of range 2-4."); + return NULL; + } + void *id = rsElementCreate(rs->mContext, dt, RS_KIND_USER, false, size); + return new Element(id, rs, dt, RS_KIND_USER, false, size); +} + +const Element * Element::createPixel(RenderScript *rs, RsDataType dt, RsDataKind dk) { + ALOGE("createPixel %p %i %i", rs, dt, dk); + if (!(dk == RS_KIND_PIXEL_L || + dk == RS_KIND_PIXEL_A || + dk == RS_KIND_PIXEL_LA || + dk == RS_KIND_PIXEL_RGB || + dk == RS_KIND_PIXEL_RGBA || + dk == RS_KIND_PIXEL_DEPTH)) { + ALOGE("Unsupported DataKind"); + return NULL; + } + if (!(dt == RS_TYPE_UNSIGNED_8 || + dt == RS_TYPE_UNSIGNED_16 || + dt == RS_TYPE_UNSIGNED_5_6_5 || + dt == RS_TYPE_UNSIGNED_4_4_4_4 || + dt == RS_TYPE_UNSIGNED_5_5_5_1)) { + ALOGE("Unsupported DataType"); + return NULL; + } + if (dt == RS_TYPE_UNSIGNED_5_6_5 && dk != RS_KIND_PIXEL_RGB) { + ALOGE("Bad kind and type combo"); + return NULL; + } + if (dt == RS_TYPE_UNSIGNED_5_5_5_1 && dk != RS_KIND_PIXEL_RGBA) { + ALOGE("Bad kind and type combo"); + return NULL; + } + if (dt == RS_TYPE_UNSIGNED_4_4_4_4 && dk != RS_KIND_PIXEL_RGBA) { + ALOGE("Bad kind and type combo"); + return NULL; + } + if (dt == RS_TYPE_UNSIGNED_16 && dk != RS_KIND_PIXEL_DEPTH) { + ALOGE("Bad kind and type combo"); + return NULL; + } + + int size = 1; + switch (dk) { + case RS_KIND_PIXEL_LA: + size = 2; + break; + case RS_KIND_PIXEL_RGB: + size = 3; + break; + case RS_KIND_PIXEL_RGBA: + size = 4; + break; + case RS_KIND_PIXEL_DEPTH: + size = 2; + break; + default: + break; + } + + void * id = rsElementCreate(rs->mContext, dt, dk, true, size); + return new Element(id, rs, dt, dk, true, size); +} + +bool Element::isCompatible(const Element *e) { + // Try strict BaseObj equality to start with. + if (this == e) { + return true; + } + + // Ignore mKind because it is allowed to be different (user vs. pixel). + // We also ignore mNormalized because it can be different. The mType + // field must be non-null since we require name equivalence for + // user-created Elements. + return ((mSizeBytes == e->mSizeBytes) && + (mType != NULL) && + (mType == e->mType) && + (mVectorSize == e->mVectorSize)); +} + +Element::Builder::Builder(RenderScript *rs) { + mRS = rs; + mSkipPadding = false; +} + +void Element::Builder::add(const Element *e, android::String8 &name, uint32_t arraySize) { + // Skip padding fields after a vector 3 type. + if (mSkipPadding) { + const char *s1 = "#padding_"; + const char *s2 = name; + size_t len = strlen(s1); + if (strlen(s2) >= len) { + if (!memcmp(s1, s2, len)) { + mSkipPadding = false; + return; + } + } + } + + if (e->mVectorSize == 3) { + mSkipPadding = true; + } else { + mSkipPadding = false; + } + + mElements.add(e); + mElementNames.add(name); + mArraySizes.add(arraySize); +} + +const Element * Element::Builder::create() { + size_t fieldCount = mElements.size(); + const char ** nameArray = (const char **)calloc(fieldCount, sizeof(char *)); + size_t* sizeArray = (size_t*)calloc(fieldCount, sizeof(size_t)); + + for (size_t ct = 0; ct < fieldCount; ct++) { + nameArray[ct] = mElementNames[ct].string(); + sizeArray[ct] = mElementNames[ct].length(); + } + + void *id = rsElementCreate2(mRS->mContext, + (RsElement *)mElements.array(), fieldCount, + nameArray, fieldCount * sizeof(size_t), sizeArray, + (const uint32_t *)mArraySizes.array(), fieldCount); + + + free(nameArray); + free(sizeArray); + + Element *e = new Element(id, mRS, mElements, mElementNames, mArraySizes); + return e; +} + diff --git a/libs/rs/Element.h b/libs/rs/Element.h new file mode 100644 index 0000000..a579dc3 --- /dev/null +++ b/libs/rs/Element.h @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2008-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ANDROID_ELEMENT_H__ +#define __ANDROID_ELEMENT_H__ + +#include <rs.h> +#include "RenderScript.h" +#include "BaseObj.h" + +class Element : public BaseObj { +public: + /** + * Return if a element is too complex for use as a data source for a Mesh or + * a Program. + * + * @return boolean + */ + bool isComplex(); + + /** + * @hide + * @return number of sub-elements in this element + */ + size_t getSubElementCount() { + return mVisibleElementMap.size(); + } + + /** + * @hide + * @param index index of the sub-element to return + * @return sub-element in this element at given index + */ + const Element * getSubElement(uint32_t index); + + /** + * @hide + * @param index index of the sub-element + * @return sub-element in this element at given index + */ + const char * getSubElementName(uint32_t index); + + /** + * @hide + * @param index index of the sub-element + * @return array size of sub-element in this element at given index + */ + size_t getSubElementArraySize(uint32_t index); + + /** + * @hide + * @param index index of the sub-element + * @return offset in bytes of sub-element in this element at given index + */ + uint32_t getSubElementOffsetBytes(uint32_t index); + + /** + * @hide + * @return element data type + */ + RsDataType getDataType() const { + return mType; + } + + /** + * @hide + * @return element data kind + */ + RsDataKind getDataKind() const { + return mKind; + } + + size_t getSizeBytes() const { + return mSizeBytes; + } + + + static const Element * BOOLEAN(RenderScript *rs); + static const Element * U8(RenderScript *rs); + static const Element * I8(RenderScript *rs); + static const Element * U16(RenderScript *rs); + static const Element * I16(RenderScript *rs); + static const Element * U32(RenderScript *rs); + static const Element * I32(RenderScript *rs); + static const Element * U64(RenderScript *rs); + static const Element * I64(RenderScript *rs); + static const Element * F32(RenderScript *rs); + static const Element * F64(RenderScript *rs); + static const Element * ELEMENT(RenderScript *rs); + static const Element * TYPE(RenderScript *rs); + static const Element * ALLOCATION(RenderScript *rs); + static const Element * SAMPLER(RenderScript *rs); + static const Element * SCRIPT(RenderScript *rs); + static const Element * MESH(RenderScript *rs); + static const Element * PROGRAM_FRAGMENT(RenderScript *rs); + static const Element * PROGRAM_VERTEX(RenderScript *rs); + static const Element * PROGRAM_RASTER(RenderScript *rs); + static const Element * PROGRAM_STORE(RenderScript *rs); + + static const Element * A_8(RenderScript *rs); + static const Element * RGB_565(RenderScript *rs); + static const Element * RGB_888(RenderScript *rs); + static const Element * RGBA_5551(RenderScript *rs); + static const Element * RGBA_4444(RenderScript *rs); + static const Element * RGBA_8888(RenderScript *rs); + + static const Element * F32_2(RenderScript *rs); + static const Element * F32_3(RenderScript *rs); + static const Element * F32_4(RenderScript *rs); + static const Element * F64_2(RenderScript *rs); + static const Element * F64_3(RenderScript *rs); + static const Element * F64_4(RenderScript *rs); + static const Element * U8_2(RenderScript *rs); + static const Element * U8_3(RenderScript *rs); + static const Element * U8_4(RenderScript *rs); + static const Element * I8_2(RenderScript *rs); + static const Element * I8_3(RenderScript *rs); + static const Element * I8_4(RenderScript *rs); + static const Element * U16_2(RenderScript *rs); + static const Element * U16_3(RenderScript *rs); + static const Element * U16_4(RenderScript *rs); + static const Element * I16_2(RenderScript *rs); + static const Element * I16_3(RenderScript *rs); + static const Element * I16_4(RenderScript *rs); + static const Element * U32_2(RenderScript *rs); + static const Element * U32_3(RenderScript *rs); + static const Element * U32_4(RenderScript *rs); + static const Element * I32_2(RenderScript *rs); + static const Element * I32_3(RenderScript *rs); + static const Element * I32_4(RenderScript *rs); + static const Element * U64_2(RenderScript *rs); + static const Element * U64_3(RenderScript *rs); + static const Element * U64_4(RenderScript *rs); + static const Element * I64_2(RenderScript *rs); + static const Element * I64_3(RenderScript *rs); + static const Element * I64_4(RenderScript *rs); + static const Element * MATRIX_4X4(RenderScript *rs); + static const Element * MATRIX_3X3(RenderScript *rs); + static const Element * MATRIX_2X2(RenderScript *rs); + + Element(void *id, RenderScript *rs, + android::Vector<const Element *> &elements, + android::Vector<android::String8> &elementNames, + android::Vector<uint32_t> &arraySizes); + Element(void *id, RenderScript *rs, RsDataType dt, RsDataKind dk, bool norm, uint32_t size); + Element(RenderScript *rs); + virtual ~Element(); + + void updateFromNative(); + static const Element * createUser(RenderScript *rs, RsDataType dt); + static const Element * createVector(RenderScript *rs, RsDataType dt, uint32_t size); + static const Element * createPixel(RenderScript *rs, RsDataType dt, RsDataKind dk); + bool isCompatible(const Element *e); + + class Builder { + private: + RenderScript *mRS; + android::Vector<const Element *> mElements; + android::Vector<android::String8> mElementNames; + android::Vector<uint32_t> mArraySizes; + bool mSkipPadding; + + public: + Builder(RenderScript *rs); + ~Builder(); + void add(const Element *, android::String8 &name, uint32_t arraySize = 1); + const Element * create(); + }; + +private: + void updateVisibleSubElements(); + + android::Vector<const Element *> mElements; + android::Vector<android::String8> mElementNames; + android::Vector<uint32_t> mArraySizes; + android::Vector<uint32_t> mVisibleElementMap; + android::Vector<uint32_t> mOffsetInBytes; + + RsDataType mType; + RsDataKind mKind; + bool mNormalized; + size_t mSizeBytes; + size_t mVectorSize; +}; + +#endif diff --git a/libs/rs/RenderScript.cpp b/libs/rs/RenderScript.cpp new file mode 100644 index 0000000..58d1ce1 --- /dev/null +++ b/libs/rs/RenderScript.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2008-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <utils/Log.h> +#include <malloc.h> +#include <string.h> + +#include "RenderScript.h" + +bool RenderScript::gInitialized = false; +pthread_mutex_t RenderScript::gInitMutex = PTHREAD_MUTEX_INITIALIZER; + +RenderScript::RenderScript() { + mDev = NULL; + mContext = NULL; + mErrorFunc = NULL; + mMessageFunc = NULL; + mMessageRun = false; + + memset(&mElements, 0, sizeof(mElements)); +} + +RenderScript::~RenderScript() { + mMessageRun = false; + + rsContextDeinitToClient(mContext); + + void *res = NULL; + int status = pthread_join(mMessageThreadId, &res); + + rsContextDestroy(mContext); + mContext = NULL; + rsDeviceDestroy(mDev); + mDev = NULL; +} + +bool RenderScript::init(int targetApi) { + mDev = rsDeviceCreate(); + if (mDev == 0) { + ALOGE("Device creation failed"); + return false; + } + + mContext = rsContextCreate(mDev, 0, targetApi); + if (mContext == 0) { + ALOGE("Context creation failed"); + return false; + } + + + pid_t mNativeMessageThreadId; + + int status = pthread_create(&mMessageThreadId, NULL, threadProc, this); + if (status) { + ALOGE("Failed to start RenderScript message thread."); + return false; + } + // Wait for the message thread to be active. + while (!mMessageRun) { + usleep(1000); + } + + return true; +} + +void * RenderScript::threadProc(void *vrsc) { + RenderScript *rs = static_cast<RenderScript *>(vrsc); + size_t rbuf_size = 256; + void * rbuf = malloc(rbuf_size); + + rsContextInitToClient(rs->mContext); + rs->mMessageRun = true; + + while (rs->mMessageRun) { + size_t receiveLen = 0; + uint32_t usrID = 0; + uint32_t subID = 0; + RsMessageToClientType r = rsContextPeekMessage(rs->mContext, + &receiveLen, sizeof(receiveLen), + &usrID, sizeof(usrID)); + + if (receiveLen >= rbuf_size) { + rbuf_size = receiveLen + 32; + rbuf = realloc(rbuf, rbuf_size); + } + if (!rbuf) { + ALOGE("RenderScript::message handler realloc error %zu", rbuf_size); + // No clean way to recover now? + } + rsContextGetMessage(rs->mContext, rbuf, rbuf_size, &receiveLen, sizeof(receiveLen), + &subID, sizeof(subID)); + + switch(r) { + case RS_MESSAGE_TO_CLIENT_ERROR: + ALOGE("RS Error %s", (const char *)rbuf); + + if(rs->mMessageFunc != NULL) { + rs->mErrorFunc(usrID, (const char *)rbuf); + } + break; + case RS_MESSAGE_TO_CLIENT_EXCEPTION: + // teardown. But we want to avoid starving other threads during + // teardown by yielding until the next line in the destructor can + // execute to set mRun = false + usleep(1000); + break; + case RS_MESSAGE_TO_CLIENT_USER: + if(rs->mMessageFunc != NULL) { + rs->mMessageFunc(usrID, rbuf, receiveLen); + } else { + ALOGE("Received a message from the script with no message handler installed."); + } + break; + + default: + ALOGE("RenderScript unknown message type %i", r); + } + } + + if (rbuf) { + free(rbuf); + } + ALOGE("RenderScript Message thread exiting."); + return NULL; +} + +void RenderScript::setErrorHandler(ErrorHandlerFunc_t func) { + mErrorFunc = func; +} + +void RenderScript::setMessageHandler(MessageHandlerFunc_t func) { + mMessageFunc = func; +} + +void RenderScript::contextDump() { +} + +void RenderScript::finish() { + +} + + diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h new file mode 100644 index 0000000..2d352be --- /dev/null +++ b/libs/rs/RenderScript.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2008-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_RENDERSCRIPT_H +#define ANDROID_RENDERSCRIPT_H + + +#include <pthread.h> +#include <utils/String8.h> +#include <utils/Vector.h> + +#include "rs.h" + +class Element; +class Type; +class Allocation; + +class RenderScript { + friend class BaseObj; + friend class Allocation; + friend class Element; + friend class Type; + +public: + RenderScript(); + virtual ~RenderScript(); + + typedef void (*ErrorHandlerFunc_t)(uint32_t errorNum, const char *errorText); + typedef void (*MessageHandlerFunc_t)(uint32_t msgNum, const void *msgData, size_t msgLen); + + + void setErrorHandler(ErrorHandlerFunc_t func); + ErrorHandlerFunc_t getErrorHandler() {return mErrorFunc;} + + void setMessageHandler(MessageHandlerFunc_t func); + MessageHandlerFunc_t getMessageHandler() {return mMessageFunc;} + + bool init(int targetApi); + void contextDump(); + void finish(); + +private: + static bool gInitialized; + static pthread_mutex_t gInitMutex; + + pthread_t mMessageThreadId; + pid_t mNativeMessageThreadId; + bool mMessageRun; + + RsDevice mDev; + RsContext mContext; + + ErrorHandlerFunc_t mErrorFunc; + MessageHandlerFunc_t mMessageFunc; + + struct { + Element *U8; + Element *I8; + Element *U16; + Element *I16; + Element *U32; + Element *I32; + Element *U64; + Element *I64; + Element *F32; + Element *F64; + Element *BOOLEAN; + + Element *ELEMENT; + Element *TYPE; + Element *ALLOCATION; + Element *SAMPLER; + Element *SCRIPT; + Element *MESH; + Element *PROGRAM_FRAGMENT; + Element *PROGRAM_VERTEX; + Element *PROGRAM_RASTER; + Element *PROGRAM_STORE; + + Element *A_8; + Element *RGB_565; + Element *RGB_888; + Element *RGBA_5551; + Element *RGBA_4444; + Element *RGBA_8888; + + Element *FLOAT_2; + Element *FLOAT_3; + Element *FLOAT_4; + + Element *DOUBLE_2; + Element *DOUBLE_3; + Element *DOUBLE_4; + + Element *UCHAR_2; + Element *UCHAR_3; + Element *UCHAR_4; + + Element *CHAR_2; + Element *CHAR_3; + Element *CHAR_4; + + Element *USHORT_2; + Element *USHORT_3; + Element *USHORT_4; + + Element *SHORT_2; + Element *SHORT_3; + Element *SHORT_4; + + Element *UINT_2; + Element *UINT_3; + Element *UINT_4; + + Element *INT_2; + Element *INT_3; + Element *INT_4; + + Element *ULONG_2; + Element *ULONG_3; + Element *ULONG_4; + + Element *LONG_2; + Element *LONG_3; + Element *LONG_4; + + Element *MATRIX_4X4; + Element *MATRIX_3X3; + Element *MATRIX_2X2; + } mElements; + + + + + static void * threadProc(void *); + +}; + +#endif + diff --git a/libs/rs/Type.cpp b/libs/rs/Type.cpp new file mode 100644 index 0000000..3249f97 --- /dev/null +++ b/libs/rs/Type.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <utils/Log.h> +#include <malloc.h> +#include <string.h> + +#include "RenderScript.h" +#include "Element.h" +#include "Type.h" + +void Type::calcElementCount() { + bool hasLod = hasMipmaps(); + uint32_t x = getX(); + uint32_t y = getY(); + uint32_t z = getZ(); + uint32_t faces = 1; + if (hasFaces()) { + faces = 6; + } + if (x == 0) { + x = 1; + } + if (y == 0) { + y = 1; + } + if (z == 0) { + z = 1; + } + + uint32_t count = x * y * z * faces; + while (hasLod && ((x > 1) || (y > 1) || (z > 1))) { + if(x > 1) { + x >>= 1; + } + if(y > 1) { + y >>= 1; + } + if(z > 1) { + z >>= 1; + } + + count += x * y * z * faces; + } + mElementCount = count; +} + + +Type::Type(void *id, RenderScript *rs) : BaseObj(id, rs) { + mDimX = 0; + mDimY = 0; + mDimZ = 0; + mDimMipmaps = false; + mDimFaces = false; + mElement = NULL; +} + +void Type::updateFromNative() { + // We have 6 integer to obtain mDimX; mDimY; mDimZ; + // mDimLOD; mDimFaces; mElement; + + /* + int[] dataBuffer = new int[6]; + mRS.nTypeGetNativeData(getID(), dataBuffer); + + mDimX = dataBuffer[0]; + mDimY = dataBuffer[1]; + mDimZ = dataBuffer[2]; + mDimMipmaps = dataBuffer[3] == 1 ? true : false; + mDimFaces = dataBuffer[4] == 1 ? true : false; + + int elementID = dataBuffer[5]; + if(elementID != 0) { + mElement = new Element(elementID, mRS); + mElement.updateFromNative(); + } + calcElementCount(); + */ +} + +Type::Builder::Builder(RenderScript *rs, const Element *e) { + mRS = rs; + mElement = e; + mDimX = 0; + mDimY = 0; + mDimZ = 0; + mDimMipmaps = false; + mDimFaces = false; +} + +void Type::Builder::setX(uint32_t value) { + if(value < 1) { + ALOGE("Values of less than 1 for Dimension X are not valid."); + } + mDimX = value; +} + +void Type::Builder::setY(int value) { + if(value < 1) { + ALOGE("Values of less than 1 for Dimension Y are not valid."); + } + mDimY = value; +} + +void Type::Builder::setMipmaps(bool value) { + mDimMipmaps = value; +} + +void Type::Builder::setFaces(bool value) { + mDimFaces = value; +} + +const Type * Type::Builder::create() { + ALOGE(" %i %i %i %i %i", mDimX, mDimY, mDimZ, mDimFaces, mDimMipmaps); + if (mDimZ > 0) { + if ((mDimX < 1) || (mDimY < 1)) { + ALOGE("Both X and Y dimension required when Z is present."); + } + if (mDimFaces) { + ALOGE("Cube maps not supported with 3D types."); + } + } + if (mDimY > 0) { + if (mDimX < 1) { + ALOGE("X dimension required when Y is present."); + } + } + if (mDimFaces) { + if (mDimY < 1) { + ALOGE("Cube maps require 2D Types."); + } + } + + void * id = rsTypeCreate(mRS->mContext, mElement->getID(), mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces); + Type *t = new Type(id, mRS); + t->mElement = mElement; + t->mDimX = mDimX; + t->mDimY = mDimY; + t->mDimZ = mDimZ; + t->mDimMipmaps = mDimMipmaps; + t->mDimFaces = mDimFaces; + + t->calcElementCount(); + return t; +} + diff --git a/libs/rs/Type.h b/libs/rs/Type.h new file mode 100644 index 0000000..fb4e8b1 --- /dev/null +++ b/libs/rs/Type.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ANDROID_TYPE_H__ +#define __ANDROID_TYPE_H__ + +#include <rs.h> +#include "RenderScript.h" +#include "BaseObj.h" + +class Type : public BaseObj { +protected: + friend class Allocation; + + uint32_t mDimX; + uint32_t mDimY; + uint32_t mDimZ; + bool mDimMipmaps; + bool mDimFaces; + size_t mElementCount; + const Element *mElement; + + void calcElementCount(); + virtual void updateFromNative(); + +public: + + const Element* getElement() const { + return mElement; + } + + uint32_t getX() const { + return mDimX; + } + + uint32_t getY() const { + return mDimY; + } + + uint32_t getZ() const { + return mDimZ; + } + + bool hasMipmaps() const { + return mDimMipmaps; + } + + bool hasFaces() const { + return mDimFaces; + } + + size_t getCount() const { + return mElementCount; + } + + size_t getSizeBytes() const { + return mElementCount * mElement->getSizeBytes(); + } + + + Type(void *id, RenderScript *rs); + + + class Builder { + protected: + RenderScript *mRS; + uint32_t mDimX; + uint32_t mDimY; + uint32_t mDimZ; + bool mDimMipmaps; + bool mDimFaces; + const Element *mElement; + + public: + Builder(RenderScript *rs, const Element *e); + + void setX(uint32_t value); + void setY(int value); + void setMipmaps(bool value); + void setFaces(bool value); + const Type * create(); + }; + +}; + +#endif diff --git a/libs/rs/tests/Android.mk b/libs/rs/tests/Android.mk new file mode 100644 index 0000000..a773e84 --- /dev/null +++ b/libs/rs/tests/Android.mk @@ -0,0 +1,29 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + compute.cpp + +LOCAL_SHARED_LIBRARIES := \ + libRS \ + libz \ + libcutils \ + libutils \ + libEGL \ + libGLESv1_CM \ + libGLESv2 \ + libui \ + libbcc \ + libbcinfo \ + libgui + +LOCAL_MODULE:= rstest-compute + +LOCAL_MODULE_TAGS := tests + +LOCAL_C_INCLUDES += .. \ + frameworks/base/libs/rs \ + out/target/product/stingray/obj/SHARED_LIBRARIES/libRS_intermediates + +include $(BUILD_EXECUTABLE) + diff --git a/libs/rs/tests/compute.cpp b/libs/rs/tests/compute.cpp new file mode 100644 index 0000000..702b974 --- /dev/null +++ b/libs/rs/tests/compute.cpp @@ -0,0 +1,41 @@ + +#include "RenderScript.h" +#include "Element.h" +#include "Type.h" +#include "Allocation.h" + +int main(int argc, char** argv) +{ + + RenderScript *rs = new RenderScript(); + printf("New RS %p\n", rs); + + //usleep(100000); + + bool r = rs->init(16); + printf("Init returned %i\n", r); + + const Element *e = Element::RGBA_8888(rs); + printf("Element %p\n", e); + + Type::Builder tb(rs, e); + tb.setX(128); + tb.setY(128); + const Type *t = tb.create(); + printf("Type %p\n", t); + + + const Allocation *a1 = Allocation::createSized(rs, e, 1000); + printf("Allocation %p\n", a1); + + + //usleep(1000000); + + + printf("Deleting stuff\n"); + delete t; + delete a1; + delete e; + delete rs; + printf("Delete OK\n"); +} |