diff options
Diffstat (limited to 'libs/rs')
59 files changed, 3113 insertions, 421 deletions
diff --git a/libs/rs/Allocation.cpp b/libs/rs/Allocation.cpp new file mode 100644 index 0000000..d69c55f --- /dev/null +++ b/libs/rs/Allocation.cpp @@ -0,0 +1,471 @@ +/* + * 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. + */ + +#define LOG_TAG "libRS_cpp" + +#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..c9e00a4 --- /dev/null +++ b/libs/rs/Allocation.h @@ -0,0 +1,126 @@ +/* + * 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_ALLOCATION_H__ +#define __ANDROID_ALLOCATION_H__ + +#include <pthread.h> +#include <rs.h> + +#include "RenderScript.h" +#include "Type.h" +#include "Element.h" + +class Allocation : public 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); + +}; + +#endif diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk index 9c5d06b..45ed453 100644 --- a/libs/rs/Android.mk +++ b/libs/rs/Android.mk @@ -127,7 +127,14 @@ 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 \ + Script.cpp \ + ScriptC.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..82e51e7 --- /dev/null +++ b/libs/rs/BaseObj.cpp @@ -0,0 +1,67 @@ +/* + * 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. + */ + +#define LOG_TAG "libRS_cpp" + +#include <rs.h> + +#include "RenderScript.h" +#include "BaseObj.h" + +void * BaseObj::getID() const { + if (mID == NULL) { + ALOGE("Internal error: Object id 0."); + } + return mID; +} + +void * BaseObj::getObjID(const BaseObj *o) { + return o == NULL ? NULL : o->getID(); +} + + +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..79761b1 --- /dev/null +++ b/libs/rs/BaseObj.h @@ -0,0 +1,52 @@ +/* + * 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; + friend class Allocation; + friend class Script; + friend class ScriptC; + + void *mID; + RenderScript *mRS; + android::String8 mName; + + void * getID() const; + + BaseObj(void *id, RenderScript *rs); + void checkValid(); + + static void * getObjID(const BaseObj *o); + +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..f318d40 --- /dev/null +++ b/libs/rs/Element.cpp @@ -0,0 +1,428 @@ +/* + * 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. + */ + +#define LOG_TAG "libRS_cpp" + +#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()) { + mRS->throwError("Element contains no sub-elements"); + } + if (index >= mVisibleElementMap.size()) { + mRS->throwError("Illegal sub-element index"); + } + return mElements[mVisibleElementMap[index]]; +} + +const char * Element::getSubElementName(uint32_t index) { + if (!mVisibleElementMap.size()) { + mRS->throwError("Element contains no sub-elements"); + } + if (index >= mVisibleElementMap.size()) { + mRS->throwError("Illegal sub-element index"); + } + return mElementNames[mVisibleElementMap[index]]; +} + +size_t Element::getSubElementArraySize(uint32_t index) { + if (!mVisibleElementMap.size()) { + mRS->throwError("Element contains no sub-elements"); + } + if (index >= mVisibleElementMap.size()) { + mRS->throwError("Illegal sub-element index"); + } + return mArraySizes[mVisibleElementMap[index]]; +} + +uint32_t Element::getSubElementOffsetBytes(uint32_t index) { + if (mVisibleElementMap.size()) { + mRS->throwError("Element contains no sub-elements"); + } + if (index >= mVisibleElementMap.size()) { + mRS->throwError("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) { + 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) { + rs->throwError("Vector size out of range 2-4."); + } + 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) { + 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)) { + rs->throwError("Unsupported DataKind"); + } + 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)) { + rs->throwError("Unsupported DataType"); + } + if (dt == RS_TYPE_UNSIGNED_5_6_5 && dk != RS_KIND_PIXEL_RGB) { + rs->throwError("Bad kind and type combo"); + } + if (dt == RS_TYPE_UNSIGNED_5_5_5_1 && dk != RS_KIND_PIXEL_RGBA) { + rs->throwError("Bad kind and type combo"); + } + if (dt == RS_TYPE_UNSIGNED_4_4_4_4 && dk != RS_KIND_PIXEL_RGBA) { + rs->throwError("Bad kind and type combo"); + } + if (dt == RS_TYPE_UNSIGNED_16 && dk != RS_KIND_PIXEL_DEPTH) { + rs->throwError("Bad kind and type combo"); + } + + 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..0b42055 --- /dev/null +++ b/libs/rs/RenderScript.cpp @@ -0,0 +1,164 @@ +/* + * 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. + */ + +#define LOG_TAG "libRS_cpp" + +#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::throwError(const char *err) const { + ALOGE("RS CPP error: %s", err); + int * v = NULL; + v[0] = 0; +} + + +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 index 6d54268..0eb6a6d 100644 --- a/libs/rs/RenderScript.h +++ b/libs/rs/RenderScript.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * 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. @@ -14,58 +14,143 @@ * limitations under the License. */ -#ifndef RENDER_SCRIPT_H -#define RENDER_SCRIPT_H +#ifndef ANDROID_RENDERSCRIPT_H +#define ANDROID_RENDERSCRIPT_H -#include <stdint.h> -#include <sys/types.h> -#ifdef __cplusplus -extern "C" { -#endif +#include <pthread.h> +#include <utils/String8.h> +#include <utils/Vector.h> -#include "RenderScriptDefines.h" - -// -// A3D loading and object update code. -// Should only be called at object creation, not thread safe -RsObjectBase rsaFileA3DGetEntryByIndex(RsContext, uint32_t idx, RsFile); -RsFile rsaFileA3DCreateFromMemory(RsContext, const void *data, uint32_t len); -RsFile rsaFileA3DCreateFromAsset(RsContext, void *asset); -RsFile rsaFileA3DCreateFromFile(RsContext, const char *path); -void rsaFileA3DGetNumIndexEntries(RsContext, int32_t *numEntries, RsFile); -void rsaFileA3DGetIndexEntries(RsContext, RsFileIndexEntry *fileEntries, - uint32_t numEntries, RsFile); -void rsaGetName(RsContext, void * obj, const char **name); -// Mesh update functions -void rsaMeshGetVertexBufferCount(RsContext, RsMesh, int32_t *vtxCount); -void rsaMeshGetIndexCount(RsContext, RsMesh, int32_t *idxCount); -void rsaMeshGetVertices(RsContext, RsMesh, RsAllocation *vtxData, uint32_t vtxDataCount); -void rsaMeshGetIndices(RsContext, RsMesh, RsAllocation *va, - uint32_t *primType, uint32_t idxDataCount); -// Allocation update -const void* rsaAllocationGetType(RsContext con, RsAllocation va); -// Type update -void rsaTypeGetNativeData(RsContext, RsType, uint32_t *typeData, uint32_t typeDataSize); -// Element update -void rsaElementGetNativeData(RsContext, RsElement, uint32_t *elemData, uint32_t elemDataSize); -void rsaElementGetSubElements(RsContext, RsElement, uint32_t *ids, const char **names, - uint32_t *arraySizes, uint32_t dataSize); - -RsDevice rsDeviceCreate(); -void rsDeviceDestroy(RsDevice dev); -void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value); -RsContext rsContextCreate(RsDevice dev, uint32_t version, uint32_t sdkVersion); -RsContext rsContextCreateGL(RsDevice dev, uint32_t version, uint32_t sdkVersion, - RsSurfaceConfig sc, uint32_t dpi); - -#include "rsgApiFuncDecl.h" - -#ifdef __cplusplus -}; -#endif +#include "rs.h" + +class Element; +class Type; +class Allocation; + +class RenderScript { + friend class BaseObj; + friend class Allocation; + friend class Element; + friend class Type; + friend class Script; + friend class ScriptC; + +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; -#endif // RENDER_SCRIPT_H + 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; + + + + void throwError(const char *err) const; + + static void * threadProc(void *); + +}; + +#endif diff --git a/libs/rs/Script.cpp b/libs/rs/Script.cpp new file mode 100644 index 0000000..25fa673 --- /dev/null +++ b/libs/rs/Script.cpp @@ -0,0 +1,69 @@ +/* + * 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. + */ + +#define LOG_TAG "libRS_cpp" + +#include <utils/Log.h> +#include <malloc.h> + +#include "RenderScript.h" +#include "Element.h" +#include "Type.h" +#include "Allocation.h" +#include "Script.h" + +void Script::invoke(uint32_t slot, const void *v, size_t len) { + rsScriptInvokeV(mRS->mContext, getID(), slot, v, len); +} + +void Script::forEach(uint32_t slot, const Allocation *ain, const Allocation *aout, + const void *usr, size_t usrLen) { + if ((ain == NULL) && (aout == NULL)) { + mRS->throwError("At least one of ain or aout is required to be non-null."); + } + void *in_id = BaseObj::getObjID(ain); + void *out_id = BaseObj::getObjID(aout); + rsScriptForEach(mRS->mContext, getID(), slot, in_id, out_id, usr, usrLen); +} + + +Script::Script(void *id, RenderScript *rs) : BaseObj(id, rs) { +} + + +void Script::bindAllocation(const Allocation *va, uint32_t slot) { + rsScriptBindAllocation(mRS->mContext, getID(), BaseObj::getObjID(va), slot); +} + + +void Script::setVar(uint32_t index, const BaseObj *o) { + rsScriptSetVarObj(mRS->mContext, getID(), index, (o == NULL) ? 0 : o->getID()); +} + +void Script::setVar(uint32_t index, const void *v, size_t len) { + rsScriptSetVarV(mRS->mContext, getID(), index, v, len); +} + + + +void Script::FieldBase::init(RenderScript *rs, uint32_t dimx, uint32_t usages) { + mAllocation = Allocation::createSized(rs, mElement, dimx, RS_ALLOCATION_USAGE_SCRIPT | usages); +} + +//Script::FieldBase::FieldBase() { +//} + + diff --git a/libs/rs/Script.h b/libs/rs/Script.h new file mode 100644 index 0000000..54d1e40 --- /dev/null +++ b/libs/rs/Script.h @@ -0,0 +1,84 @@ +/* + * 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_SCRIPT_H__ +#define __ANDROID_SCRIPT_H__ + +#include <pthread.h> +#include <rs.h> + +#include "RenderScript.h" +#include "Allocation.h" + +class Type; +class Element; +class Allocation; + +class Script : public BaseObj { +protected: + Script(void *id, RenderScript *rs); + void forEach(uint32_t slot, const Allocation *in, const Allocation *out, const void *v, size_t); + void bindAllocation(const Allocation *va, uint32_t slot); + void setVar(uint32_t index, const void *, size_t len); + void setVar(uint32_t index, const BaseObj *o); + void invoke(uint32_t slot, const void *v, size_t len); + + + void invoke(uint32_t slot) { + invoke(slot, NULL, 0); + } + void setVar(uint32_t index, float v) { + setVar(index, &v, sizeof(v)); + } + void setVar(uint32_t index, double v) { + setVar(index, &v, sizeof(v)); + } + void setVar(uint32_t index, int32_t v) { + setVar(index, &v, sizeof(v)); + } + void setVar(uint32_t index, int64_t v) { + setVar(index, &v, sizeof(v)); + } + void setVar(uint32_t index, bool v) { + setVar(index, &v, sizeof(v)); + } + +public: + class FieldBase { + protected: + const Element *mElement; + Allocation *mAllocation; + + void init(RenderScript *rs, uint32_t dimx, uint32_t usages = 0); + + public: + const Element *getElement() { + return mElement; + } + + const Type *getType() { + return mAllocation->getType(); + } + + const Allocation *getAllocation() { + return mAllocation; + } + + //void updateAllocation(); + }; +}; + +#endif diff --git a/libs/rs/ScriptC.cpp b/libs/rs/ScriptC.cpp new file mode 100644 index 0000000..ad82ff4 --- /dev/null +++ b/libs/rs/ScriptC.cpp @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#define LOG_TAG "libRS_cpp" + +#include <utils/Log.h> +#include <malloc.h> + +#include "ScriptC.h" + +ScriptC::ScriptC(RenderScript *rs, + const char *codeTxt, size_t codeLength, + const char *cachedName, size_t cachedNameLength, + const char *cacheDir, size_t cacheDirLength) +: Script(NULL, rs) { + mID = rsScriptCCreate(rs->mContext, cachedName, cachedNameLength, + cacheDir, cacheDirLength, codeTxt, codeLength); +} + diff --git a/libs/rs/ScriptC.h b/libs/rs/ScriptC.h new file mode 100644 index 0000000..dcbbe10 --- /dev/null +++ b/libs/rs/ScriptC.h @@ -0,0 +1,34 @@ +/* + * 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_SCRIPTC_H__ +#define __ANDROID_SCRIPTC_H__ + +#include <pthread.h> +#include <rs.h> + +#include "Script.h" + +class ScriptC : public Script { +protected: + ScriptC(RenderScript *rs, + const char *codeTxt, size_t codeLength, + const char *cachedName, size_t cachedNameLength, + const char *cacheDir, size_t cacheDirLength); + +}; + +#endif diff --git a/libs/rs/Type.cpp b/libs/rs/Type.cpp new file mode 100644 index 0000000..1352bd7 --- /dev/null +++ b/libs/rs/Type.cpp @@ -0,0 +1,160 @@ +/* + * 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. + */ + +#define LOG_TAG "libRS_cpp" + +#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() { + 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..53481c3 --- /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 "Element.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/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp index ea92192..fb93d82 100644 --- a/libs/rs/driver/rsdAllocation.cpp +++ b/libs/rs/driver/rsdAllocation.cpp @@ -23,6 +23,11 @@ #include "rsAllocation.h" +#include "system/window.h" +#include "hardware/gralloc.h" +#include "ui/Rect.h" +#include "ui/GraphicBufferMapper.h" + #include <GLES/gl.h> #include <GLES2/gl2.h> #include <GLES/glext.h> @@ -220,7 +225,8 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) { } void * ptr = alloc->mHal.state.usrPtr; - if (!ptr) { + if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) { + } else { ptr = malloc(alloc->mHal.state.type->getSizeBytes()); if (!ptr) { free(drv); @@ -248,7 +254,7 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) { alloc->mHal.drvState.mallocPtr = ptr; drv->mallocPtr = (uint8_t *)ptr; alloc->mHal.drv = drv; - if (forceZero) { + if (forceZero && ptr) { memset(ptr, 0, alloc->mHal.state.type->getSizeBytes()); } @@ -386,9 +392,96 @@ int32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *al return drv->textureID; } +static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + int32_t r = nw->dequeueBuffer(nw, &drv->wndBuffer); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer."); + return false; + } + + // This lock is implicitly released by the queue buffer in IoSend + r = nw->lockBuffer(nw, drv->wndBuffer); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error locking next IO output buffer."); + return false; + } + + // Must lock the whole surface + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height); + + void *dst = NULL; + mapper.lock(drv->wndBuffer->handle, + GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN, + bounds, &dst); + alloc->mHal.drvState.mallocPtr = dst; + return true; +} + +void rsdAllocationSetSurfaceTexture(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + //ALOGE("rsdAllocationSetSurfaceTexture %p %p", alloc, nw); + + // Cleanup old surface if there is one. + if (alloc->mHal.state.wndSurface) { + ANativeWindow *old = alloc->mHal.state.wndSurface; + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + mapper.unlock(drv->wndBuffer->handle); + old->queueBuffer(old, drv->wndBuffer); + } + + if (nw != NULL) { + int32_t r; + r = native_window_set_usage(nw, GRALLOC_USAGE_SW_READ_RARELY | + GRALLOC_USAGE_SW_WRITE_OFTEN); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage."); + return; + } + + r = native_window_set_buffers_dimensions(nw, alloc->mHal.state.dimensionX, + alloc->mHal.state.dimensionY); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions."); + return; + } + + r = native_window_set_buffer_count(nw, 3); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count."); + return; + } + + IoGetBuffer(rsc, alloc, nw); + } +} + +void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + ANativeWindow *nw = alloc->mHal.state.wndSurface; + + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + mapper.unlock(drv->wndBuffer->handle); + int32_t r = nw->queueBuffer(nw, drv->wndBuffer); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer."); + return; + } + + IoGetBuffer(rsc, alloc, nw); +} + +void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) { + ALOGE("not implemented"); +} + + void rsdAllocationData1D(const Context *rsc, const Allocation *alloc, uint32_t xoff, uint32_t lod, uint32_t count, - const void *data, uint32_t sizeBytes) { + const void *data, size_t sizeBytes) { DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; const uint32_t eSize = alloc->mHal.state.type->getElementSizeBytes(); @@ -407,7 +500,7 @@ void rsdAllocationData1D(const Context *rsc, const Allocation *alloc, void rsdAllocationData2D(const Context *rsc, const Allocation *alloc, 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 w, uint32_t h, const void *data, size_t sizeBytes) { DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; uint32_t eSize = alloc->mHal.state.elementSizeBytes; diff --git a/libs/rs/driver/rsdAllocation.h b/libs/rs/driver/rsdAllocation.h index 230804b..e3a5126 100644 --- a/libs/rs/driver/rsdAllocation.h +++ b/libs/rs/driver/rsdAllocation.h @@ -24,6 +24,7 @@ #include <GLES2/gl2.h> class RsdFrameBufferObj; +struct ANativeWindowBuffer; struct DrvAllocation { // Is this a legal structure to be used as a texture source. @@ -47,6 +48,7 @@ struct DrvAllocation { bool uploadDeferred; RsdFrameBufferObj * readBackFBO; + ANativeWindowBuffer *wndBuffer; }; GLenum rsdTypeToGLType(RsDataType t); @@ -69,6 +71,12 @@ void rsdAllocationMarkDirty(const android::renderscript::Context *rsc, const android::renderscript::Allocation *alloc); int32_t rsdAllocationInitSurfaceTexture(const android::renderscript::Context *rsc, const android::renderscript::Allocation *alloc); +void rsdAllocationSetSurfaceTexture(const android::renderscript::Context *rsc, + android::renderscript::Allocation *alloc, ANativeWindow *nw); +void rsdAllocationIoSend(const android::renderscript::Context *rsc, + android::renderscript::Allocation *alloc); +void rsdAllocationIoReceive(const android::renderscript::Context *rsc, + android::renderscript::Allocation *alloc); void rsdAllocationData1D(const android::renderscript::Context *rsc, const android::renderscript::Allocation *alloc, diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp index bec6fff..dd78684 100644 --- a/libs/rs/driver/rsdBcc.cpp +++ b/libs/rs/driver/rsdBcc.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ - #include "rsdCore.h" #include "rsdBcc.h" #include "rsdRuntime.h" @@ -30,7 +29,6 @@ extern "C" { #include "libdex/ZipArchive.h" } - using namespace android; using namespace android::renderscript; @@ -45,6 +43,7 @@ struct DrvScript { bcinfo::MetadataExtractor *ME; InvokeFunc_t *mInvokeFunctions; + ForEachFunc_t *mForEachFunctions; void ** mFieldAddress; bool * mFieldIsObject; const uint32_t *mExportForEachSignatureList; @@ -162,8 +161,16 @@ bool rsdScriptInit(const Context *rsc, } exportForEachSignatureCount = drv->ME->getExportForEachSignatureCount(); - rsAssert(exportForEachSignatureCount <= 1); drv->mExportForEachSignatureList = drv->ME->getExportForEachSignatureList(); + if (exportForEachSignatureCount > 0) { + drv->mForEachFunctions = + (ForEachFunc_t*) calloc(exportForEachSignatureCount, + sizeof(ForEachFunc_t)); + bccGetExportForEachList(drv->mBccScript, exportForEachSignatureCount, + (void **) drv->mForEachFunctions); + } else { + drv->mForEachFunctions = NULL; + } // Copy info over to runtime script->mHal.info.exportedFunctionCount = drv->ME->getExportFuncCount(); @@ -196,6 +203,7 @@ error: typedef struct { Context *rsc; Script *script; + ForEachFunc_t kernel; uint32_t sig; const Allocation * ain; Allocation * aout; @@ -235,7 +243,7 @@ static void wc_xy(void *usr, uint32_t idx) { RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv; uint32_t sig = mtls->sig; - outer_foreach_t fn = (outer_foreach_t) mtls->script->mHal.info.root; + outer_foreach_t fn = (outer_foreach_t) mtls->kernel; while (1) { uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum); uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize; @@ -265,7 +273,7 @@ static void wc_x(void *usr, uint32_t idx) { RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv; uint32_t sig = mtls->sig; - outer_foreach_t fn = (outer_foreach_t) mtls->script->mHal.info.root; + outer_foreach_t fn = (outer_foreach_t) mtls->kernel; while (1) { uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum); uint32_t xStart = mtls->xStart + slice * mtls->mSliceSize; @@ -299,8 +307,8 @@ void rsdScriptInvokeForEach(const Context *rsc, memset(&mtls, 0, sizeof(mtls)); DrvScript *drv = (DrvScript *)s->mHal.drv; - // We only support slot 0 (root) at this point in time. - rsAssert(slot == 0); + mtls.kernel = drv->mForEachFunctions[slot]; + rsAssert(mtls.kernel != NULL); mtls.sig = 0x1f; // temp fix for old apps, full table in slang_rs_export_foreach.cpp if (drv->mExportForEachSignatureList) { mtls.sig = drv->mExportForEachSignatureList[slot]; @@ -391,7 +399,7 @@ void rsdScriptInvokeForEach(const Context *rsc, uint32_t sig = mtls.sig; //ALOGE("launch 3"); - outer_foreach_t fn = (outer_foreach_t) mtls.script->mHal.info.root; + outer_foreach_t fn = (outer_foreach_t) mtls.kernel; for (p.ar[0] = mtls.arrayStart; p.ar[0] < mtls.arrayEnd; p.ar[0]++) { for (p.z = mtls.zStart; p.z < mtls.zEnd; p.z++) { for (p.y = mtls.yStart; p.y < mtls.yEnd; p.y++) { @@ -517,6 +525,11 @@ void rsdScriptDestroy(const Context *dc, Script *script) { drv->mInvokeFunctions = NULL; } + if (drv->mForEachFunctions) { + free(drv->mForEachFunctions); + drv->mForEachFunctions = NULL; + } + delete drv->ME; drv->ME = NULL; diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp index e011955..bf2b62a 100644 --- a/libs/rs/driver/rsdCore.cpp +++ b/libs/rs/driver/rsdCore.cpp @@ -74,6 +74,9 @@ static RsdHalFunctions FunctionTable = { rsdAllocationSyncAll, rsdAllocationMarkDirty, rsdAllocationInitSurfaceTexture, + rsdAllocationSetSurfaceTexture, + rsdAllocationIoSend, + rsdAllocationIoReceive, rsdAllocationData1D, rsdAllocationData2D, rsdAllocationData3D, diff --git a/libs/rs/driver/rsdCore.h b/libs/rs/driver/rsdCore.h index 168bdf3..05ca13bb 100644 --- a/libs/rs/driver/rsdCore.h +++ b/libs/rs/driver/rsdCore.h @@ -25,6 +25,7 @@ #include "rsdGL.h" typedef void (* InvokeFunc_t)(void); +typedef void (* ForEachFunc_t)(void); typedef void (*WorkerCallback_t)(void *usr, uint32_t idx); typedef struct RsdSymbolTableRec { diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp index b136cc7..8033b08 100644 --- a/libs/rs/driver/rsdGL.cpp +++ b/libs/rs/driver/rsdGL.cpp @@ -16,8 +16,8 @@ #include <ui/FramebufferNativeWindow.h> #include <ui/PixelFormat.h> -#include <ui/EGLUtils.h> -#include <ui/egl/android_natives.h> + +#include <system/window.h> #include <sys/types.h> #include <sys/resource.h> @@ -47,6 +47,29 @@ using namespace android::renderscript; static int32_t gGLContextCount = 0; static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { + struct EGLUtils { + static const char *strerror(EGLint err) { + switch (err){ + case EGL_SUCCESS: return "EGL_SUCCESS"; + case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; + case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; + case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; + case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; + case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; + case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; + case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; + case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; + case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; + case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; + case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; + case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; + case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; + case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; + default: return "UNKNOWN"; + } + } + }; + if (returnVal != EGL_TRUE) { fprintf(stderr, "%s() returned %d\n", op, returnVal); } diff --git a/libs/rs/driver/rsdProgram.cpp b/libs/rs/driver/rsdProgram.cpp index 54484df..fa4cb0f 100644 --- a/libs/rs/driver/rsdProgram.cpp +++ b/libs/rs/driver/rsdProgram.cpp @@ -34,8 +34,11 @@ using namespace android; using namespace android::renderscript; bool rsdProgramVertexInit(const Context *rsc, const ProgramVertex *pv, - const char* shader, uint32_t shaderLen) { - RsdShader *drv = new RsdShader(pv, GL_VERTEX_SHADER, shader, shaderLen); + const char* shader, size_t shaderLen, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength) { + RsdShader *drv = new RsdShader(pv, GL_VERTEX_SHADER, shader, shaderLen, + textureNames, textureNamesCount, textureNamesLength); pv->mHal.drv = drv; return drv->createShader(); @@ -78,8 +81,11 @@ void rsdProgramVertexDestroy(const Context *rsc, const ProgramVertex *pv) { } bool rsdProgramFragmentInit(const Context *rsc, const ProgramFragment *pf, - const char* shader, uint32_t shaderLen) { - RsdShader *drv = new RsdShader(pf, GL_FRAGMENT_SHADER, shader, shaderLen); + const char* shader, size_t shaderLen, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength) { + RsdShader *drv = new RsdShader(pf, GL_FRAGMENT_SHADER, shader, shaderLen, + textureNames, textureNamesCount, textureNamesLength); pf->mHal.drv = drv; return drv->createShader(); diff --git a/libs/rs/driver/rsdProgramFragment.h b/libs/rs/driver/rsdProgramFragment.h index 366cb40..b03a9fe 100644 --- a/libs/rs/driver/rsdProgramFragment.h +++ b/libs/rs/driver/rsdProgramFragment.h @@ -22,7 +22,9 @@ bool rsdProgramFragmentInit(const android::renderscript::Context *rsc, const android::renderscript::ProgramFragment *, - const char* shader, uint32_t shaderLen); + const char* shader, size_t shaderLen, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); void rsdProgramFragmentSetActive(const android::renderscript::Context *rsc, const android::renderscript::ProgramFragment *); void rsdProgramFragmentDestroy(const android::renderscript::Context *rsc, diff --git a/libs/rs/driver/rsdProgramVertex.h b/libs/rs/driver/rsdProgramVertex.h index e998572..f917a41 100644 --- a/libs/rs/driver/rsdProgramVertex.h +++ b/libs/rs/driver/rsdProgramVertex.h @@ -21,7 +21,9 @@ bool rsdProgramVertexInit(const android::renderscript::Context *rsc, const android::renderscript::ProgramVertex *, - const char* shader, uint32_t shaderLen); + const char* shader, size_t shaderLen, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); void rsdProgramVertexSetActive(const android::renderscript::Context *rsc, const android::renderscript::ProgramVertex *); void rsdProgramVertexDestroy(const android::renderscript::Context *rsc, diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp index 3bca794..1e73b95 100644 --- a/libs/rs/driver/rsdShader.cpp +++ b/libs/rs/driver/rsdShader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2011-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. @@ -30,14 +30,16 @@ using namespace android; using namespace android::renderscript; RsdShader::RsdShader(const Program *p, uint32_t type, - const char * shaderText, uint32_t shaderLength) { - + const char * shaderText, size_t shaderLength, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength) { mUserShader.setTo(shaderText, shaderLength); mRSProgram = p; mType = type; initMemberVars(); initAttribAndUniformArray(); - init(); + init(textureNames, textureNamesCount, textureNamesLength); + createTexturesString(textureNames, textureNamesCount, textureNamesLength); } RsdShader::~RsdShader() { @@ -65,25 +67,26 @@ void RsdShader::initMemberVars() { mIsValid = false; } -void RsdShader::init() { +void RsdShader::init(const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength) { uint32_t attribCount = 0; uint32_t uniformCount = 0; for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) { - initAddUserElement(mRSProgram->mHal.state.inputElements[ct], mAttribNames, NULL, &attribCount, RS_SHADER_ATTR); + initAddUserElement(mRSProgram->mHal.state.inputElements[ct], mAttribNames, + NULL, &attribCount, RS_SHADER_ATTR); } for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) { - initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI); + initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(), + mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI); } mTextureUniformIndexStart = uniformCount; - char buf[256]; for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) { - snprintf(buf, sizeof(buf), "UNI_Tex%i", ct); - mUniformNames[uniformCount].setTo(buf); + mUniformNames[uniformCount].setTo("UNI_"); + mUniformNames[uniformCount].append(textureNames[ct], textureNamesLength[ct]); mUniformArraySizes[uniformCount] = 1; uniformCount++; } - } String8 RsdShader::getGLSLInputString() const { @@ -135,22 +138,25 @@ void RsdShader::appendAttributes() { } } -void RsdShader::appendTextures() { - char buf[256]; - for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) { +void RsdShader::createTexturesString(const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength) { + mShaderTextures.setTo(""); + for (uint32_t ct = 0; ct < mRSProgram->mHal.state.texturesCount; ct ++) { if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) { Allocation *a = mRSProgram->mHal.state.textures[ct]; if (a && a->mHal.state.surfaceTextureID) { - snprintf(buf, sizeof(buf), "uniform samplerExternalOES UNI_Tex%i;\n", ct); + mShaderTextures.append("uniform samplerExternalOES UNI_"); } else { - snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct); + mShaderTextures.append("uniform sampler2D UNI_"); } mTextureTargets[ct] = GL_TEXTURE_2D; } else { - snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct); + mShaderTextures.append("uniform samplerCube UNI_"); mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP; } - mShader.append(buf); + + mShaderTextures.append(textureNames[ct], textureNamesLength[ct]); + mShaderTextures.append(";\n"); } } @@ -161,7 +167,7 @@ bool RsdShader::createShader() { } appendUserConstants(); appendAttributes(); - appendTextures(); + mShader.append(mShaderTextures); mShader.append(mUserShader); @@ -418,7 +424,8 @@ void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) { DrvAllocation *drvTex = (DrvAllocation *)mRSProgram->mHal.state.textures[ct]->mHal.drv; if (drvTex->glTarget != GL_TEXTURE_2D && drvTex->glTarget != GL_TEXTURE_CUBE_MAP) { - ALOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", (uint)this, ct); + ALOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", + (uint)this, ct); rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader"); } RSD_CALL_GL(glBindTexture, drvTex->glTarget, drvTex->textureID); diff --git a/libs/rs/driver/rsdShader.h b/libs/rs/driver/rsdShader.h index 3f0d6ea..e32145f 100644 --- a/libs/rs/driver/rsdShader.h +++ b/libs/rs/driver/rsdShader.h @@ -39,7 +39,9 @@ class RsdShader { public: RsdShader(const android::renderscript::Program *p, uint32_t type, - const char * shaderText, uint32_t shaderLength); + const char * shaderText, uint32_t shaderLength, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); virtual ~RsdShader(); bool createShader(); @@ -67,19 +69,27 @@ protected: // Applies to vertex and fragment shaders only void appendUserConstants(); - void setupUserConstants(const android::renderscript::Context *rsc, RsdShaderCache *sc, bool isFragment); - void initAddUserElement(const android::renderscript::Element *e, android::String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix); + void setupUserConstants(const android::renderscript::Context *rsc, + RsdShaderCache *sc, bool isFragment); + void initAddUserElement(const android::renderscript::Element *e, + android::String8 *names, uint32_t *arrayLengths, + uint32_t *count, const char *prefix); void setupTextures(const android::renderscript::Context *rsc, RsdShaderCache *sc); - void setupSampler(const android::renderscript::Context *rsc, const android::renderscript::Sampler *s, const android::renderscript::Allocation *tex); + void setupSampler(const android::renderscript::Context *rsc, + const android::renderscript::Sampler *s, + const android::renderscript::Allocation *tex); void appendAttributes(); void appendTextures(); + void createTexturesString(const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); void initAttribAndUniformArray(); mutable bool mDirty; android::String8 mShader; android::String8 mUserShader; + android::String8 mShaderTextures; uint32_t mShaderID; uint32_t mType; @@ -93,10 +103,14 @@ protected: int32_t mTextureUniformIndexStart; - void logUniform(const android::renderscript::Element *field, const float *fd, uint32_t arraySize ); - void setUniform(const android::renderscript::Context *rsc, const android::renderscript::Element *field, const float *fd, int32_t slot, uint32_t arraySize ); + void logUniform(const android::renderscript::Element *field, + const float *fd, uint32_t arraySize); + void setUniform(const android::renderscript::Context *rsc, + const android::renderscript::Element *field, + const float *fd, int32_t slot, uint32_t arraySize ); void initMemberVars(); - void init(); + void init(const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); }; #endif //ANDROID_RSD_SHADER_H diff --git a/libs/rs/rs.h b/libs/rs/rs.h new file mode 100644 index 0000000..fbcaf4a --- /dev/null +++ b/libs/rs/rs.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2007 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 RENDER_SCRIPT_H +#define RENDER_SCRIPT_H + +#include <stdint.h> +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include "rsDefines.h" + +// +// A3D loading and object update code. +// Should only be called at object creation, not thread safe +RsObjectBase rsaFileA3DGetEntryByIndex(RsContext, uint32_t idx, RsFile); +RsFile rsaFileA3DCreateFromMemory(RsContext, const void *data, uint32_t len); +RsFile rsaFileA3DCreateFromAsset(RsContext, void *asset); +RsFile rsaFileA3DCreateFromFile(RsContext, const char *path); +void rsaFileA3DGetNumIndexEntries(RsContext, int32_t *numEntries, RsFile); +void rsaFileA3DGetIndexEntries(RsContext, RsFileIndexEntry *fileEntries, + uint32_t numEntries, RsFile); +void rsaGetName(RsContext, void * obj, const char **name); +// Mesh update functions +void rsaMeshGetVertexBufferCount(RsContext, RsMesh, int32_t *vtxCount); +void rsaMeshGetIndexCount(RsContext, RsMesh, int32_t *idxCount); +void rsaMeshGetVertices(RsContext, RsMesh, RsAllocation *vtxData, uint32_t vtxDataCount); +void rsaMeshGetIndices(RsContext, RsMesh, RsAllocation *va, + uint32_t *primType, uint32_t idxDataCount); +// Allocation update +const void* rsaAllocationGetType(RsContext con, RsAllocation va); +// Type update +void rsaTypeGetNativeData(RsContext, RsType, uint32_t *typeData, uint32_t typeDataSize); +// Element update +void rsaElementGetNativeData(RsContext, RsElement, uint32_t *elemData, uint32_t elemDataSize); +void rsaElementGetSubElements(RsContext, RsElement, uint32_t *ids, const char **names, + uint32_t *arraySizes, uint32_t dataSize); + +RsDevice rsDeviceCreate(); +void rsDeviceDestroy(RsDevice dev); +void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value); +RsContext rsContextCreate(RsDevice dev, uint32_t version, uint32_t sdkVersion); +RsContext rsContextCreateGL(RsDevice dev, uint32_t version, uint32_t sdkVersion, + RsSurfaceConfig sc, uint32_t dpi); + +#include "rsgApiFuncDecl.h" + +#ifdef __cplusplus +}; +#endif + +#endif // RENDER_SCRIPT_H + + + diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec index 6759bc7..cf4a391 100644 --- a/libs/rs/rs.spec +++ b/libs/rs/rs.spec @@ -69,168 +69,183 @@ AllocationGetSurfaceTextureID { ret int32_t } +AllocationSetSurface { + param RsAllocation alloc + param RsNativeWindow sur + sync + } + +AllocationIoSend { + param RsAllocation alloc + } + +AllocationIoReceive { + param RsAllocation alloc + } + + ContextFinish { - sync - } + sync + } ContextBindRootScript { - param RsScript sampler - } + param RsScript sampler + } ContextBindProgramStore { - param RsProgramStore pgm - } + param RsProgramStore pgm + } ContextBindProgramFragment { - param RsProgramFragment pgm - } + param RsProgramFragment pgm + } ContextBindProgramVertex { - param RsProgramVertex pgm - } + param RsProgramVertex pgm + } ContextBindProgramRaster { - param RsProgramRaster pgm - } + param RsProgramRaster pgm + } ContextBindFont { - param RsFont pgm - } + param RsFont pgm + } ContextPause { - } + } ContextResume { - } + } ContextSetSurface { - param uint32_t width - param uint32_t height - param RsNativeWindow sur + param uint32_t width + param uint32_t height + param RsNativeWindow sur sync - } + } ContextDump { - param int32_t bits + param int32_t bits } ContextSetPriority { - param int32_t priority - } + param int32_t priority + } ContextDestroyWorker { sync } AssignName { - param RsObjectBase obj - param const char *name - } + param RsObjectBase obj + param const char *name + } ObjDestroy { - param RsAsyncVoidPtr objPtr - } + param RsAsyncVoidPtr objPtr + } ElementCreate { direct - param RsDataType mType - param RsDataKind mKind - param bool mNormalized - param uint32_t mVectorSize - ret RsElement - } + param RsDataType mType + param RsDataKind mKind + param bool mNormalized + param uint32_t mVectorSize + ret RsElement + } ElementCreate2 { direct - param const RsElement * elements - param const char ** names - param const uint32_t * arraySize - ret RsElement - } + param const RsElement * elements + param const char ** names + param const uint32_t * arraySize + ret RsElement + } AllocationCopyToBitmap { - param RsAllocation alloc - param void * data - } + param RsAllocation alloc + param void * data + } Allocation1DData { - param RsAllocation va - param uint32_t xoff - param uint32_t lod - param uint32_t count - param const void *data - } + param RsAllocation va + param uint32_t xoff + param uint32_t lod + param uint32_t count + param const void *data + } Allocation1DElementData { - param RsAllocation va - param uint32_t x - param uint32_t lod - param const void *data - param size_t comp_offset - } + param RsAllocation va + param uint32_t x + param uint32_t lod + param const void *data + param size_t comp_offset + } Allocation2DData { - param RsAllocation va - param uint32_t xoff - param uint32_t yoff - param uint32_t lod - param RsAllocationCubemapFace face - param uint32_t w - param uint32_t h - param const void *data - } + param RsAllocation va + param uint32_t xoff + param uint32_t yoff + param uint32_t lod + param RsAllocationCubemapFace face + param uint32_t w + param uint32_t h + param const void *data + } Allocation2DElementData { - param RsAllocation va - param uint32_t x - param uint32_t y - param uint32_t lod - param RsAllocationCubemapFace face - param const void *data - param size_t element_offset - } + param RsAllocation va + param uint32_t x + param uint32_t y + param uint32_t lod + param RsAllocationCubemapFace face + param const void *data + param size_t element_offset + } AllocationGenerateMipmaps { - param RsAllocation va + param RsAllocation va } AllocationRead { - param RsAllocation va - param void * data - } + param RsAllocation va + param void * data + } AllocationSyncAll { - param RsAllocation va - param RsAllocationUsageType src + param RsAllocation va + param RsAllocationUsageType src } AllocationResize1D { - param RsAllocation va - param uint32_t dimX - } + param RsAllocation va + param uint32_t dimX + } AllocationResize2D { - param RsAllocation va - param uint32_t dimX - param uint32_t dimY - } + param RsAllocation va + param uint32_t dimX + param uint32_t dimY + } AllocationCopy2DRange { - param RsAllocation dest - param uint32_t destXoff - param uint32_t destYoff - param uint32_t destMip - param uint32_t destFace - param uint32_t width - param uint32_t height - param RsAllocation src - param uint32_t srcXoff - param uint32_t srcYoff - param uint32_t srcMip - param uint32_t srcFace - } + param RsAllocation dest + param uint32_t destXoff + param uint32_t destYoff + param uint32_t destMip + param uint32_t destFace + param uint32_t width + param uint32_t height + param RsAllocation src + param uint32_t srcXoff + param uint32_t srcYoff + param uint32_t srcMip + param uint32_t srcFace + } SamplerCreate { direct @@ -244,26 +259,26 @@ SamplerCreate { } ScriptBindAllocation { - param RsScript vtm - param RsAllocation va - param uint32_t slot - } + param RsScript vtm + param RsAllocation va + param uint32_t slot + } ScriptSetTimeZone { - param RsScript s - param const char * timeZone - } + param RsScript s + param const char * timeZone + } ScriptInvoke { - param RsScript s - param uint32_t slot - } + param RsScript s + param uint32_t slot + } ScriptInvokeV { - param RsScript s - param uint32_t slot - param const void * data - } + param RsScript s + param uint32_t slot + param const void * data + } ScriptForEach { param RsScript s @@ -274,125 +289,127 @@ ScriptForEach { } ScriptSetVarI { - param RsScript s - param uint32_t slot - param int value - } + param RsScript s + param uint32_t slot + param int value + } ScriptSetVarObj { - param RsScript s - param uint32_t slot - param RsObjectBase value - } + param RsScript s + param uint32_t slot + param RsObjectBase value + } ScriptSetVarJ { - param RsScript s - param uint32_t slot - param int64_t value - } + param RsScript s + param uint32_t slot + param int64_t value + } ScriptSetVarF { - param RsScript s - param uint32_t slot - param float value - } + param RsScript s + param uint32_t slot + param float value + } ScriptSetVarD { - param RsScript s - param uint32_t slot - param double value - } + param RsScript s + param uint32_t slot + param double value + } ScriptSetVarV { - param RsScript s - param uint32_t slot - param const void * data - } + param RsScript s + param uint32_t slot + param const void * data + } ScriptCCreate { param const char * resName param const char * cacheDir - param const char * text - ret RsScript - } + param const char * text + ret RsScript + } ProgramStoreCreate { - direct - param bool colorMaskR - param bool colorMaskG - param bool colorMaskB - param bool colorMaskA + direct + param bool colorMaskR + param bool colorMaskG + param bool colorMaskB + param bool colorMaskA param bool depthMask param bool ditherEnable - param RsBlendSrcFunc srcFunc - param RsBlendDstFunc destFunc + param RsBlendSrcFunc srcFunc + param RsBlendDstFunc destFunc param RsDepthFunc depthFunc - ret RsProgramStore - } + ret RsProgramStore + } ProgramRasterCreate { - direct - param bool pointSprite - param RsCullMode cull - ret RsProgramRaster + direct + param bool pointSprite + param RsCullMode cull + ret RsProgramRaster } ProgramBindConstants { - param RsProgram vp - param uint32_t slot - param RsAllocation constants - } + param RsProgram vp + param uint32_t slot + param RsAllocation constants + } ProgramBindTexture { - param RsProgramFragment pf - param uint32_t slot - param RsAllocation a - } + param RsProgramFragment pf + param uint32_t slot + param RsAllocation a + } ProgramBindSampler { - param RsProgramFragment pf - param uint32_t slot - param RsSampler s - } + param RsProgramFragment pf + param uint32_t slot + param RsSampler s + } ProgramFragmentCreate { - direct - param const char * shaderText - param const uint32_t * params - ret RsProgramFragment - } + direct + param const char * shaderText + param const char ** textureNames + param const uint32_t * params + ret RsProgramFragment + } ProgramVertexCreate { - direct - param const char * shaderText - param const uint32_t * params - ret RsProgramVertex - } + direct + param const char * shaderText + param const char ** textureNames + param const uint32_t * params + ret RsProgramVertex + } FontCreateFromFile { - param const char *name - param float fontSize - param uint32_t dpi - ret RsFont - } + param const char *name + param float fontSize + param uint32_t dpi + ret RsFont + } FontCreateFromMemory { - param const char *name - param float fontSize - param uint32_t dpi - param const void *data - ret RsFont - } + param const char *name + param float fontSize + param uint32_t dpi + param const void *data + ret RsFont + } MeshCreate { - param RsAllocation *vtx - param RsAllocation *idx - param uint32_t *primType - ret RsMesh - } + param RsAllocation *vtx + param RsAllocation *idx + param uint32_t *primType + ret RsMesh + } PathCreate { param RsPathPrimitive pp @@ -402,4 +419,3 @@ PathCreate { param float quality ret RsPath } - diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp index 02c6809..83c88fd 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -17,6 +17,7 @@ #include "rsContext.h" #include "rs_hal.h" +#include "system/window.h" using namespace android; using namespace android::renderscript; @@ -44,6 +45,7 @@ Allocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32 delete a; return NULL; } + return a; } @@ -420,6 +422,28 @@ int32_t Allocation::getSurfaceTextureID(const Context *rsc) { return id; } +void Allocation::setSurface(const Context *rsc, RsNativeWindow sur) { + ANativeWindow *nw = (ANativeWindow *)sur; + ANativeWindow *old = mHal.state.wndSurface; + if (nw) { + nw->incStrong(NULL); + } + rsc->mHal.funcs.allocation.setSurfaceTexture(rsc, this, nw); + mHal.state.wndSurface = nw; + if (old) { + old->decStrong(NULL); + } +} + +void Allocation::ioSend(const Context *rsc) { + rsc->mHal.funcs.allocation.ioSend(rsc, this); +} + +void Allocation::ioReceive(const Context *rsc) { + rsc->mHal.funcs.allocation.ioReceive(rsc, this); +} + + ///////////////// // @@ -670,6 +694,21 @@ int32_t rsi_AllocationGetSurfaceTextureID(Context *rsc, RsAllocation valloc) { return alloc->getSurfaceTextureID(rsc); } +void rsi_AllocationSetSurface(Context *rsc, RsAllocation valloc, RsNativeWindow sur) { + Allocation *alloc = static_cast<Allocation *>(valloc); + alloc->setSurface(rsc, sur); +} + +void rsi_AllocationIoSend(Context *rsc, RsAllocation valloc) { + Allocation *alloc = static_cast<Allocation *>(valloc); + alloc->ioSend(rsc); +} + +void rsi_AllocationIoReceive(Context *rsc, RsAllocation valloc) { + Allocation *alloc = static_cast<Allocation *>(valloc); + alloc->ioReceive(rsc); +} + } } diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h index 58a582b..58a6fca 100644 --- a/libs/rs/rsAllocation.h +++ b/libs/rs/rsAllocation.h @@ -19,6 +19,8 @@ #include "rsType.h" +struct ANativeWindow; + // --------------------------------------------------------------------------- namespace android { namespace renderscript { @@ -57,6 +59,7 @@ public: bool hasReferences; void * usrPtr; int32_t surfaceTextureID; + ANativeWindow *wndSurface; }; State state; @@ -127,6 +130,9 @@ public: } int32_t getSurfaceTextureID(const Context *rsc); + void setSurface(const Context *rsc, RsNativeWindow sur); + void ioSend(const Context *rsc); + void ioReceive(const Context *rsc); protected: Vector<const Program *> mToDirtyList; diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index adaefc6..95ac76e 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -263,6 +263,10 @@ void * Context::threadProc(void *vrsc) { rsc->timerSet(RS_TIMER_IDLE); #ifndef ANDROID_RS_SERIALIZE + if (!rsc->mRootScript.get() || !rsc->mHasSurface || rsc->mPaused) { + targetRate = 0; + } + if (vsyncRate != targetRate) { displayEvent.setVsyncRate(targetRate); vsyncRate = targetRate; diff --git a/libs/rs/RenderScriptDefines.h b/libs/rs/rsDefines.h index 990ef26..990ef26 100644 --- a/libs/rs/RenderScriptDefines.h +++ b/libs/rs/rsDefines.h diff --git a/libs/rs/RenderScriptEnv.h b/libs/rs/rsEnv.h index b82eaf1..b82eaf1 100644 --- a/libs/rs/RenderScriptEnv.h +++ b/libs/rs/rsEnv.h diff --git a/libs/rs/rsFileA3D.h b/libs/rs/rsFileA3D.h index 056b5af..baf81de 100644 --- a/libs/rs/rsFileA3D.h +++ b/libs/rs/rsFileA3D.h @@ -17,11 +17,11 @@ #ifndef ANDROID_RS_FILE_A3D_H #define ANDROID_RS_FILE_A3D_H -#include "RenderScript.h" +#include "rs.h" #include "rsMesh.h" +#include <androidfw/Asset.h> #include <utils/String8.h> -#include <utils/Asset.h> #include "rsStream.h" #include <stdio.h> diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp index 4f21b3b..c4276cf 100644 --- a/libs/rs/rsFont.cpp +++ b/libs/rs/rsFont.cpp @@ -490,8 +490,14 @@ void FontState::initRenderState() { shaderString.append(" gl_FragColor = col;\n"); shaderString.append("}\n"); - ObjectBaseRef<const Element> colorElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4); - ObjectBaseRef<const Element> gammaElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1); + const char *textureNames[] = { "Tex0" }; + const size_t textureNamesLengths[] = { 4 }; + size_t numTextures = sizeof(textureNamesLengths)/sizeof(*textureNamesLengths); + + ObjectBaseRef<const Element> colorElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, + RS_KIND_USER, false, 4); + ObjectBaseRef<const Element> gammaElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, + RS_KIND_USER, false, 1); Element::Builder builder; builder.add(colorElem.get(), "Color", 1); builder.add(gammaElem.get(), "Gamma", 1); @@ -506,14 +512,17 @@ void FontState::initRenderState() { tmp[3] = RS_TEXTURE_2D; mFontShaderFConstant.set(Allocation::createAllocation(mRSC, inputType.get(), - RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS)); - ProgramFragment *pf = new ProgramFragment(mRSC, shaderString.string(), - shaderString.length(), tmp, 4); + RS_ALLOCATION_USAGE_SCRIPT | + RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS)); + ProgramFragment *pf = new ProgramFragment(mRSC, shaderString.string(), shaderString.length(), + textureNames, numTextures, textureNamesLengths, + tmp, 4); mFontShaderF.set(pf); mFontShaderF->bindAllocation(mRSC, mFontShaderFConstant.get(), 0); mFontSampler.set(Sampler::getSampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST, - RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP).get()); + RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, + RS_SAMPLER_CLAMP).get()); mFontShaderF->bindSampler(mRSC, 0, mFontSampler.get()); mFontProgramStore.set(ProgramStore::getProgramStore(mRSC, true, true, true, true, @@ -525,10 +534,12 @@ void FontState::initRenderState() { } void FontState::initTextTexture() { - ObjectBaseRef<const Element> alphaElem = Element::createRef(mRSC, RS_TYPE_UNSIGNED_8, RS_KIND_PIXEL_A, true, 1); + ObjectBaseRef<const Element> alphaElem = Element::createRef(mRSC, RS_TYPE_UNSIGNED_8, + RS_KIND_PIXEL_A, true, 1); // We will allocate a texture to initially hold 32 character bitmaps - ObjectBaseRef<Type> texType = Type::getTypeRef(mRSC, alphaElem.get(), 1024, 256, 0, false, false); + ObjectBaseRef<Type> texType = Type::getTypeRef(mRSC, alphaElem.get(), + 1024, 256, 0, false, false); Allocation *cacheAlloc = Allocation::createAllocation(mRSC, texType.get(), RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE); diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h index 4ca794d..88c4795 100644 --- a/libs/rs/rsFont.h +++ b/libs/rs/rsFont.h @@ -17,7 +17,7 @@ #ifndef ANDROID_RS_FONT_H #define ANDROID_RS_FONT_H -#include "RenderScript.h" +#include "rs.h" #include "rsStream.h" #include <utils/String8.h> #include <utils/Vector.h> diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h index 166b5d3..8eea427 100644 --- a/libs/rs/rsMesh.h +++ b/libs/rs/rsMesh.h @@ -18,7 +18,7 @@ #define ANDROID_RS_MESH_H -#include "RenderScript.h" +#include "rs.h" // --------------------------------------------------------------------------- namespace android { diff --git a/libs/rs/rsPath.h b/libs/rs/rsPath.h index dac795e..7c05503 100644 --- a/libs/rs/rsPath.h +++ b/libs/rs/rsPath.h @@ -18,7 +18,7 @@ #define ANDROID_RS_PATH_H -#include "RenderScript.h" +#include "rs.h" // --------------------------------------------------------------------------- namespace android { diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp index 8061515..7114f29 100644 --- a/libs/rs/rsProgram.cpp +++ b/libs/rs/rsProgram.cpp @@ -20,8 +20,8 @@ using namespace android; using namespace android::renderscript; -Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, - const uint32_t * params, uint32_t paramLength) +Program::Program(Context *rsc, const char * shaderText, size_t shaderLength, + const uint32_t * params, size_t paramLength) : ProgramBase(rsc) { initMemberVars(); diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h index 06fc3ec..d032930 100644 --- a/libs/rs/rsProgram.h +++ b/libs/rs/rsProgram.h @@ -58,8 +58,8 @@ public: }; Hal mHal; - Program(Context *, const char * shaderText, uint32_t shaderLength, - const uint32_t * params, uint32_t paramLength); + Program(Context *, const char * shaderText, size_t shaderLength, + const uint32_t * params, size_t paramLength); virtual ~Program(); virtual bool freeChildren(); diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp index 4e73ca6..bebde1e 100644 --- a/libs/rs/rsProgramFragment.cpp +++ b/libs/rs/rsProgramFragment.cpp @@ -20,16 +20,18 @@ using namespace android; using namespace android::renderscript; -ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText, - uint32_t shaderLength, const uint32_t * params, - uint32_t paramLength) +ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText, size_t shaderLength, + const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength, + + const uint32_t * params, size_t paramLength) : Program(rsc, shaderText, shaderLength, params, paramLength) { mConstantColor[0] = 1.f; mConstantColor[1] = 1.f; mConstantColor[2] = 1.f; mConstantColor[3] = 1.f; - mRSC->mHal.funcs.fragment.init(mRSC, this, mUserShader.string(), mUserShader.length()); + mRSC->mHal.funcs.fragment.init(mRSC, this, mUserShader.string(), mUserShader.length(), + textureNames, textureNamesCount, textureNamesLength); } ProgramFragment::~ProgramFragment() { @@ -110,8 +112,8 @@ void ProgramFragmentState::init(Context *rsc) { Allocation *constAlloc = Allocation::createAllocation(rsc, inputType.get(), RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS); - ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(), - shaderString.length(), tmp, 2); + ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(), shaderString.length(), + NULL, 0, NULL, tmp, 2); pf->bindAllocation(rsc, constAlloc, 0); pf->setConstantColor(rsc, 1.0f, 1.0f, 1.0f, 1.0f); @@ -127,9 +129,14 @@ namespace android { namespace renderscript { RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc, const char * shaderText, - size_t shaderLength, const uint32_t * params, - size_t paramLength) { - ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength); + size_t shaderLength, + const char** textureNames, + size_t textureNamesCount, + const size_t *textureNamesLength, + const uint32_t * params, size_t paramLength) { + ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, + textureNames, textureNamesCount, textureNamesLength, + params, paramLength); pf->incUserRef(); //ALOGE("rsi_ProgramFragmentCreate %p", pf); return pf; diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h index d6e20cd..4eb28e7 100644 --- a/libs/rs/rsProgramFragment.h +++ b/libs/rs/rsProgramFragment.h @@ -27,9 +27,9 @@ class ProgramFragmentState; class ProgramFragment : public Program { public: - ProgramFragment(Context *rsc, const char * shaderText, - uint32_t shaderLength, const uint32_t * params, - uint32_t paramLength); + ProgramFragment(Context *rsc, const char * shaderText, size_t shaderLength, + const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength, + const uint32_t * params, size_t paramLength); virtual ~ProgramFragment(); virtual void setup(Context *, ProgramFragmentState *); diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp index 871caac..c8a53ea 100644 --- a/libs/rs/rsProgramVertex.cpp +++ b/libs/rs/rsProgramVertex.cpp @@ -21,11 +21,13 @@ using namespace android; using namespace android::renderscript; -ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText, - uint32_t shaderLength, const uint32_t * params, - uint32_t paramLength) +ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText, size_t shaderLength, + const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength, + + const uint32_t * params, size_t paramLength) : Program(rsc, shaderText, shaderLength, params, paramLength) { - mRSC->mHal.funcs.vertex.init(mRSC, this, mUserShader.string(), mUserShader.length()); + mRSC->mHal.funcs.vertex.init(mRSC, this, mUserShader.string(), mUserShader.length(), + textureNames, textureNamesCount, textureNamesLength); } ProgramVertex::~ProgramVertex() { @@ -191,8 +193,8 @@ void ProgramVertexState::init(Context *rsc) { tmp[2] = RS_PROGRAM_PARAM_INPUT; tmp[3] = (uint32_t)attrElem.get(); - ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(), - shaderString.length(), tmp, 4); + ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(), shaderString.length(), + NULL, 0, NULL, tmp, 4); Allocation *alloc = Allocation::createAllocation(rsc, inputType.get(), RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS); pv->bindAllocation(rsc, alloc, 0); @@ -229,10 +231,13 @@ void ProgramVertexState::deinit(Context *rsc) { namespace android { namespace renderscript { -RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, const char * shaderText, - size_t shaderLength, const uint32_t * params, - size_t paramLength) { - ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, params, paramLength); +RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, const char * shaderText, size_t shaderLength, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength, + const uint32_t * params, size_t paramLength) { + ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, + textureNames, textureNamesCount, textureNamesLength, + params, paramLength); pv->incUserRef(); return pv; } diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h index 5cfdd8b..67c2a88 100644 --- a/libs/rs/rsProgramVertex.h +++ b/libs/rs/rsProgramVertex.h @@ -27,8 +27,9 @@ class ProgramVertexState; class ProgramVertex : public Program { public: - ProgramVertex(Context *,const char * shaderText, uint32_t shaderLength, - const uint32_t * params, uint32_t paramLength); + ProgramVertex(Context *,const char * shaderText, size_t shaderLength, + const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength, + const uint32_t * params, size_t paramLength); virtual ~ProgramVertex(); virtual void setup(Context *rsc, ProgramVertexState *state); diff --git a/libs/rs/rsSampler.h b/libs/rs/rsSampler.h index 654cd9c..013e4ca 100644 --- a/libs/rs/rsSampler.h +++ b/libs/rs/rsSampler.h @@ -18,7 +18,7 @@ #define ANDROID_RS_SAMPLER_H #include "rsAllocation.h" -#include "RenderScript.h" +#include "rs.h" // --------------------------------------------------------------------------- namespace android { diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp index 357dbe3..6a3bd4b 100644 --- a/libs/rs/rsScript.cpp +++ b/libs/rs/rsScript.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2009-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. @@ -113,7 +113,7 @@ void rsi_ScriptForEach(Context *rsc, RsScript vs, uint32_t slot, RsAllocation vain, RsAllocation vaout, const void *params, size_t paramLen) { Script *s = static_cast<Script *>(vs); - s->runForEach(rsc, + s->runForEach(rsc, slot, static_cast<const Allocation *>(vain), static_cast<Allocation *>(vaout), params, paramLen); diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h index 99dceaf..7879ea6 100644 --- a/libs/rs/rsScript.h +++ b/libs/rs/rsScript.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2009-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. @@ -74,6 +74,7 @@ public: virtual bool freeChildren(); virtual void runForEach(Context *rsc, + uint32_t slot, const Allocation * ain, Allocation * aout, const void * usr, diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp index b4eb995..79725b9 100644 --- a/libs/rs/rsScriptC.cpp +++ b/libs/rs/rsScriptC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2009-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. @@ -128,6 +128,7 @@ uint32_t ScriptC::run(Context *rsc) { void ScriptC::runForEach(Context *rsc, + uint32_t slot, const Allocation * ain, Allocation * aout, const void * usr, @@ -138,7 +139,7 @@ void ScriptC::runForEach(Context *rsc, setupGLState(rsc); setupScript(rsc); - rsc->mHal.funcs.script.invokeForEach(rsc, this, 0, ain, aout, usr, usrBytes, sc); + rsc->mHal.funcs.script.invokeForEach(rsc, this, slot, ain, aout, usr, usrBytes, sc); } void ScriptC::Invoke(Context *rsc, uint32_t slot, const void *data, size_t len) { diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h index c65a5bf..92e1f4f 100644 --- a/libs/rs/rsScriptC.h +++ b/libs/rs/rsScriptC.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2009-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. @@ -19,7 +19,7 @@ #include "rsScript.h" -#include "RenderScriptEnv.h" +#include "rsEnv.h" #ifndef ANDROID_RS_SERIALIZE #include "bcinfo/BitcodeTranslator.h" @@ -47,6 +47,7 @@ public: virtual uint32_t run(Context *); virtual void runForEach(Context *rsc, + uint32_t slot, const Allocation * ain, Allocation * aout, const void * usr, diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp index 183e207..a5a0fae 100644 --- a/libs/rs/rsScriptC_Lib.cpp +++ b/libs/rs/rsScriptC_Lib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2009-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. @@ -157,7 +157,7 @@ void rsrForEach(Context *rsc, Script *sc, Allocation *in, Allocation *out, const void *usr, uint32_t usrBytes, const RsScriptCall *call) { - target->runForEach(rsc, in, out, usr, usrBytes, call); + target->runForEach(rsc, /* root slot */ 0, in, out, usr, usrBytes, call); } void rsrAllocationSyncAll(Context *rsc, Script *sc, Allocation *a, RsAllocationUsageType usage) { diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp index 4f30573..7182f53 100644 --- a/libs/rs/rsThreadIO.cpp +++ b/libs/rs/rsThreadIO.cpp @@ -31,6 +31,8 @@ using namespace android::renderscript; ThreadIO::ThreadIO() { mRunning = true; + mPureFifo = false; + mMaxInlineSize = 1024; } ThreadIO::~ThreadIO() { @@ -65,6 +67,16 @@ void ThreadIO::clientShutdown() { mToClient.shutdown(); } +void ThreadIO::coreWrite(const void *data, size_t len) { + //ALOGV("core write %p %i", data, (int)len); + mToCore.writeAsync(data, len, true); +} + +void ThreadIO::coreRead(void *data, size_t len) { + //ALOGV("core read %p %i", data, (int)len); + mToCore.read(data, len); +} + void ThreadIO::coreSetReturn(const void *data, size_t dataLen) { uint32_t buf; if (data == NULL) { @@ -91,6 +103,7 @@ void ThreadIO::setTimeoutCallback(void (*cb)(void *), void *dat, uint64_t timeou bool ThreadIO::playCoreCommands(Context *con, int waitFd) { bool ret = false; + const bool isLocal = !isPureFifo(); uint8_t buf[2 * 1024]; const CoreCmdHeader *cmd = (const CoreCmdHeader *)&buf[0]; @@ -120,14 +133,19 @@ bool ThreadIO::playCoreCommands(Context *con, int waitFd) { } if (p[0].revents) { - size_t r = mToCore.read(&buf[0], sizeof(CoreCmdHeader)); - mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes); - - if (r != sizeof(CoreCmdHeader)) { - // exception or timeout occurred. - break; + size_t r = 0; + if (isLocal) { + r = mToCore.read(&buf[0], sizeof(CoreCmdHeader)); + mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes); + if (r != sizeof(CoreCmdHeader)) { + // exception or timeout occurred. + break; + } + } else { + r = mToCore.read((void *)&cmd->cmdID, sizeof(cmd->cmdID)); } + ret = true; if (con->props.mLogTimes) { con->timerSet(Context::RS_TIMER_INTERNAL); @@ -138,7 +156,12 @@ bool ThreadIO::playCoreCommands(Context *con, int waitFd) { rsAssert(cmd->cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *))); ALOGE("playCoreCommands error con %p, cmd %i", con, cmd->cmdID); } - gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes); + + if (isLocal) { + gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes); + } else { + gPlaybackRemoteFuncs[cmd->cmdID](con, this); + } if (con->props.mLogTimes) { con->timerSet(Context::RS_TIMER_IDLE); diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h index 62e3e33..cb7d4ab 100644 --- a/libs/rs/rsThreadIO.h +++ b/libs/rs/rsThreadIO.h @@ -34,6 +34,13 @@ public: void init(); void shutdown(); + size_t getMaxInlineSize() { + return mMaxInlineSize; + } + bool isPureFifo() { + return mPureFifo; + } + // Plays back commands from the client. // Returns true if any commands were processed. bool playCoreCommands(Context *con, int waitFd); @@ -42,8 +49,16 @@ public: void * coreHeader(uint32_t, size_t dataLen); void coreCommit(); + void coreSetReturn(const void *data, size_t dataLen); void coreGetReturn(void *data, size_t dataLen); + void coreWrite(const void *data, size_t len); + void coreRead(void *data, size_t len); + + void asyncSetReturn(const void *data, size_t dataLen); + void asyncGetReturn(void *data, size_t dataLen); + void asyncWrite(const void *data, size_t len); + void asyncRead(void *data, size_t len); RsMessageToClientType getClientHeader(size_t *receiveLen, uint32_t *usrID); @@ -65,6 +80,8 @@ protected: ClientCmdHeader mLastClientHeader; bool mRunning; + bool mPureFifo; + size_t mMaxInlineSize; FifoSocket mToClient; FifoSocket mToCore; diff --git a/libs/rs/rsUtils.h b/libs/rs/rsUtils.h index db6f592..a9a992a 100644 --- a/libs/rs/rsUtils.h +++ b/libs/rs/rsUtils.h @@ -34,7 +34,7 @@ #include <math.h> -#include "RenderScript.h" +#include "rs.h" namespace android { namespace renderscript { diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h index 1e222e1..e4bf17f 100644 --- a/libs/rs/rs_hal.h +++ b/libs/rs/rs_hal.h @@ -17,7 +17,9 @@ #ifndef RS_HAL_H #define RS_HAL_H -#include <RenderScriptDefines.h> +#include <rsDefines.h> + +struct ANativeWindow; namespace android { namespace renderscript { @@ -115,19 +117,23 @@ typedef struct { bool zeroNew); void (*syncAll)(const Context *rsc, const Allocation *alloc, RsAllocationUsageType src); void (*markDirty)(const Context *rsc, const Allocation *alloc); + int32_t (*initSurfaceTexture)(const Context *rsc, const Allocation *alloc); + void (*setSurfaceTexture)(const Context *rsc, Allocation *alloc, ANativeWindow *sur); + void (*ioSend)(const Context *rsc, Allocation *alloc); + void (*ioReceive)(const Context *rsc, Allocation *alloc); void (*data1D)(const Context *rsc, const Allocation *alloc, uint32_t xoff, uint32_t lod, uint32_t count, - const void *data, uint32_t sizeBytes); + const void *data, size_t sizeBytes); void (*data2D)(const Context *rsc, const Allocation *alloc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, uint32_t w, uint32_t h, - const void *data, uint32_t sizeBytes); + const void *data, size_t sizeBytes); void (*data3D)(const Context *rsc, const Allocation *alloc, 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); + uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes); // Allocation to allocation copies void (*allocData1D)(const Context *rsc, @@ -151,9 +157,9 @@ typedef struct { uint32_t srcLod, RsAllocationCubemapFace srcFace); void (*elementData1D)(const Context *rsc, const Allocation *alloc, uint32_t x, - const void *data, uint32_t elementOff, uint32_t sizeBytes); + const void *data, uint32_t elementOff, size_t sizeBytes); void (*elementData2D)(const Context *rsc, const Allocation *alloc, uint32_t x, uint32_t y, - const void *data, uint32_t elementOff, uint32_t sizeBytes); + const void *data, uint32_t elementOff, size_t sizeBytes); } allocation; @@ -172,14 +178,18 @@ typedef struct { struct { bool (*init)(const Context *rsc, const ProgramVertex *pv, - const char* shader, uint32_t shaderLen); + const char* shader, size_t shaderLen, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); void (*setActive)(const Context *rsc, const ProgramVertex *pv); void (*destroy)(const Context *rsc, const ProgramVertex *pv); } vertex; struct { bool (*init)(const Context *rsc, const ProgramFragment *pf, - const char* shader, uint32_t shaderLen); + const char* shader, size_t shaderLen, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); void (*setActive)(const Context *rsc, const ProgramFragment *pf); void (*destroy)(const Context *rsc, const ProgramFragment *pf); } fragment; diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c index 385c8b5..99c305e 100644 --- a/libs/rs/rsg_generator.c +++ b/libs/rs/rsg_generator.c @@ -238,7 +238,7 @@ void printApiCpp(FILE *f) { //fprintf(f, " ALOGE(\"add command %s\\n\");\n", api->name); if (hasInlineDataPointers(api)) { fprintf(f, " RS_CMD_%s *cmd = NULL;\n", api->name); - fprintf(f, " if (dataSize < 1024) {;\n"); + fprintf(f, " if (dataSize < io->getMaxInlineSize()) {;\n"); fprintf(f, " cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, dataSize + size));\n", api->name, api->name); fprintf(f, " } else {\n"); fprintf(f, " cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, size));\n", api->name, api->name); @@ -252,7 +252,7 @@ void printApiCpp(FILE *f) { const VarType *vt = &api->params[ct2]; needFlush += vt->ptrLevel; if (vt->ptrLevel && hasInlineDataPointers(api)) { - fprintf(f, " if (dataSize < 1024) {\n"); + fprintf(f, " if (dataSize < io->getMaxInlineSize()) {\n"); fprintf(f, " memcpy(payload, %s, %s_length);\n", vt->name, vt->name); fprintf(f, " cmd->%s = (", vt->name); printVarType(f, vt); @@ -272,7 +272,7 @@ void printApiCpp(FILE *f) { fprintf(f, " io->coreCommit();\n"); if (hasInlineDataPointers(api)) { - fprintf(f, " if (dataSize >= 1024) {\n"); + fprintf(f, " if (dataSize >= io->getMaxInlineSize()) {\n"); fprintf(f, " io->coreGetReturn(NULL, 0);\n"); fprintf(f, " }\n"); } else if (api->ret.typeName[0]) { @@ -288,81 +288,71 @@ void printApiCpp(FILE *f) { fprintf(f, "};\n\n"); + // Generate a remote sender function + const char * str = "core"; + if (api->direct) { + str = "async"; + } + fprintf(f, "static "); printFuncDecl(f, api, "RF_", 0, 0); fprintf(f, "\n{\n"); - fprintf(f, " Fifo *f = NULL;\n"); - fprintf(f, " RS_CMD_%s cmd;\n", api->name); - fprintf(f, " const uint32_t cmdSize = sizeof(cmd);\n"); + fprintf(f, " ThreadIO *io = &((Context *)rsc)->mIO;\n"); fprintf(f, " const uint32_t cmdID = RS_CMD_ID_%s;\n", api->name); - fprintf(f, " f->writeAsync(&cmdID, sizeof(cmdID));\n"); - fprintf(f, " intptr_t offset = cmdSize;\n"); - fprintf(f, " uint32_t dataSize = 0;\n"); + fprintf(f, " io->%sWrite(&cmdID, sizeof(cmdID));\n\n", str); + for (ct2=0; ct2 < api->paramCount; ct2++) { const VarType *vt = &api->params[ct2]; - if (vt->isConst && vt->ptrLevel) { - switch(vt->ptrLevel) { - case 1: - fprintf(f, " dataSize += %s_length;\n", vt->name); - break; - case 2: - fprintf(f, " for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name); - fprintf(f, " dataSize += %s_length[ct];\n", vt->name); - fprintf(f, " }\n"); - break; - default: - printf("pointer level not handled!!"); - } + if (vt->ptrLevel == 0) { + fprintf(f, " io->%sWrite(& %s, sizeof(%s));\n", str, vt->name, vt->name); } } fprintf(f, "\n"); for (ct2=0; ct2 < api->paramCount; ct2++) { const VarType *vt = &api->params[ct2]; - switch(vt->ptrLevel) { - case 0: - fprintf(f, " cmd.%s = %s;\n", vt->name, vt->name); - break; - case 1: - fprintf(f, " cmd.%s = (", vt->name); - printVarType(f, vt); - fprintf(f, ")offset;\n"); - fprintf(f, " offset += %s_length;\n", vt->name); - break; - case 2: - fprintf(f, " cmd.%s = (", vt->name); - printVarType(f, vt); - fprintf(f, ")offset;\n"); + if ((vt->ptrLevel == 1) && (vt->isConst)) { + fprintf(f, " io->%sWrite(%s, %s_length);\n", str, vt->name, vt->name); + } + } + fprintf(f, "\n"); + + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + if ((vt->ptrLevel == 2) && (vt->isConst)) { fprintf(f, " for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name); - fprintf(f, " offset += %s_length[ct];\n", vt->name); + fprintf(f, " io->%sWrite(%s[ct], %s_length[ct]);\n", str, vt->name, vt->name); fprintf(f, " }\n"); - break; - default: - fprintf(stderr, "pointer level not handled!!"); } } fprintf(f, "\n"); - fprintf(f, " f->writeAsync(&cmd, cmdSize);\n"); for (ct2=0; ct2 < api->paramCount; ct2++) { const VarType *vt = &api->params[ct2]; - if (vt->ptrLevel == 1) { - fprintf(f, " f->writeAsync(%s, %s_length);\n", vt->name, vt->name); + if ((vt->ptrLevel == 1) && (!vt->isConst)) { + fprintf(f, " io->%sGetReturn(%s, %s_length);\n", str, vt->name, vt->name); } - if (vt->ptrLevel == 2) { + } + fprintf(f, "\n"); + + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + if ((vt->ptrLevel == 2) && (!vt->isConst)) { fprintf(f, " for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name); - fprintf(f, " f->writeAsync(%s, %s_length[ct]);\n", vt->name, vt->name); - fprintf(f, " offset += %s_length[ct];\n", vt->name); + fprintf(f, " io->%sGetReturn(%s[ct], %s_length[ct]);\n", str, vt->name, vt->name); fprintf(f, " }\n"); } } + fprintf(f, "\n"); if (api->ret.typeName[0]) { fprintf(f, " "); printVarType(f, &api->ret); fprintf(f, " retValue;\n"); - fprintf(f, " f->writeWaitReturn(&retValue, sizeof(retValue));\n"); + fprintf(f, " io->%sGetReturn(&retValue, sizeof(retValue));\n", str); fprintf(f, " return retValue;\n"); + } else /*if (api->sync)*/ { + fprintf(f, " io->%sGetReturn(NULL, 0);\n", str); } fprintf(f, "}\n\n"); } @@ -418,7 +408,6 @@ void printPlaybackCpp(FILE *f) { fprintf(f, "#include \"rsDevice.h\"\n"); fprintf(f, "#include \"rsContext.h\"\n"); fprintf(f, "#include \"rsThreadIO.h\"\n"); - //fprintf(f, "#include \"rsgApiStructs.h\"\n"); fprintf(f, "#include \"rsgApiFuncDecl.h\"\n"); fprintf(f, "\n"); fprintf(f, "namespace android {\n"); @@ -434,8 +423,6 @@ void printPlaybackCpp(FILE *f) { } fprintf(f, "void rsp_%s(Context *con, const void *vp, size_t cmdSizeBytes) {\n", api->name); - - //fprintf(f, " ALOGE(\"play command %s\\n\");\n", api->name); fprintf(f, " const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name); if (hasInlineDataPointers(api)) { @@ -488,30 +475,40 @@ void printPlaybackCpp(FILE *f) { const ApiEntry * api = &apis[ct]; int needFlush = 0; - fprintf(f, "void rspr_%s(Context *con, Fifo *f, uint8_t *scratch, size_t scratchSize) {\n", api->name); - - //fprintf(f, " ALOGE(\"play command %s\\n\");\n", api->name); + fprintf(f, "void rspr_%s(Context *con, ThreadIO *io) {\n", api->name); fprintf(f, " RS_CMD_%s cmd;\n", api->name); - fprintf(f, " f->read(&cmd, sizeof(cmd));\n"); for (ct2=0; ct2 < api->paramCount; ct2++) { const VarType *vt = &api->params[ct2]; - needFlush += vt->ptrLevel; + if (vt->ptrLevel == 0) { + fprintf(f, " io->coreRead(&cmd.%s, sizeof(cmd.%s));\n", vt->name, vt->name); + } + } + fprintf(f, "\n"); + + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; if (vt->ptrLevel == 1) { fprintf(f, " cmd.%s = (", vt->name); printVarType(f, vt); - fprintf(f, ")scratch;\n"); - fprintf(f, " f->read(scratch, cmd.%s_length);\n", vt->name); - fprintf(f, " scratch += cmd.%s_length;\n", vt->name); + fprintf(f, ")malloc(cmd.%s_length);\n", vt->name); + + if (vt->isConst) { + fprintf(f, " if (cmd.%s_length) io->coreRead((void *)cmd.%s, cmd.%s_length);\n", vt->name, vt->name, vt->name); + } } + } + fprintf(f, "\n"); + + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; if (vt->ptrLevel == 2) { - fprintf(f, " size_t sum_%s = 0;\n", vt->name); fprintf(f, " for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name); - fprintf(f, " ((size_t *)scratch)[ct] = cmd.%s_length[ct];\n", vt->name); - fprintf(f, " sum_%s += cmd.%s_length[ct];\n", vt->name, vt->name); + fprintf(f, " cmd.%s = (", vt->name); + printVarType(f, vt); + fprintf(f, ")malloc(cmd.%s_length[ct]);\n", vt->name); + fprintf(f, " io->coreRead(& cmd.%s, cmd.%s_length[ct]);\n", vt->name, vt->name); fprintf(f, " }\n"); - fprintf(f, " f->read(scratch, sum_%s);\n", vt->name); - fprintf(f, " scratch += sum_%s;\n", vt->name); } } fprintf(f, "\n"); @@ -535,10 +532,42 @@ void printPlaybackCpp(FILE *f) { } fprintf(f, ");\n"); + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + if ((vt->ptrLevel == 1) && (!vt->isConst)) { + fprintf(f, " io->coreSetReturn((void *)cmd.%s, cmd.%s_length);\n", vt->name, vt->name); + } + } + + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + if ((vt->ptrLevel == 2) && (!vt->isConst)) { + fprintf(f, " for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name); + fprintf(f, " io->coreSetReturn((void *)cmd.%s[ct], cmd.%s_length[ct]);\n", vt->name, vt->name); + fprintf(f, " }\n"); + } + } + fprintf(f, "\n"); + if (api->ret.typeName[0]) { - fprintf(f, " f->readReturn(&ret, sizeof(ret));\n"); - } else if (needFlush) { - fprintf(f, " f->readReturn(NULL, 0);\n"); + fprintf(f, " io->coreSetReturn(&ret, sizeof(ret));\n"); + } else /*if (needFlush)*/ { + fprintf(f, " io->coreSetReturn(NULL, 0);\n"); + } + + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + if (vt->ptrLevel == 1) { + fprintf(f, " free((void *)cmd.%s);\n", vt->name); + } + } + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + if (vt->ptrLevel == 2) { + fprintf(f, " for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name); + fprintf(f, " free((void *)cmd.%s);\n", vt->name); + fprintf(f, " }\n"); + } } fprintf(f, "};\n\n"); @@ -608,7 +637,7 @@ int main(int argc, char **argv) { fprintf(f, " uint32_t size;\n"); fprintf(f, "} RsPlaybackRemoteHeader;\n\n"); fprintf(f, "typedef void (*RsPlaybackLocalFunc)(Context *, const void *, size_t sizeBytes);\n"); - fprintf(f, "typedef void (*RsPlaybackRemoteFunc)(Context *, Fifo *, uint8_t *scratch, size_t scratchSize);\n"); + fprintf(f, "typedef void (*RsPlaybackRemoteFunc)(Context *, ThreadIO *);\n"); fprintf(f, "extern RsPlaybackLocalFunc gPlaybackFuncs[%i];\n", apiCount + 1); fprintf(f, "extern RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i];\n", apiCount + 1); diff --git a/libs/rs/tests/Android.mk b/libs/rs/tests/Android.mk new file mode 100644 index 0000000..197e862 --- /dev/null +++ b/libs/rs/tests/Android.mk @@ -0,0 +1,30 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + compute.cpp \ + ScriptC_mono.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/ScriptC_mono.cpp b/libs/rs/tests/ScriptC_mono.cpp new file mode 100644 index 0000000..7f83616 --- /dev/null +++ b/libs/rs/tests/ScriptC_mono.cpp @@ -0,0 +1,87 @@ +/* + * 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 "ScriptC_mono.h" + +static const char mono[] = \ + "\xDE\xC0\x17\x0B\x00\x00\x00\x00\x18\x00\x00\x00\xFC\x03\x00\x00\x00\x00\x00\x00" \ + "\x10\x00\x00\x00\x42\x43\xC0\xDE\x21\x0C\x00\x00\xFC\x00\x00\x00\x01\x10\x00\x00" \ + "\x12\x00\x00\x00\x07\x81\x23\x91\x41\xC8\x04\x49\x06\x10\x32\x39\x92\x01\x84\x0C" \ + "\x25\x05\x08\x19\x1E\x04\x8B\x62\x80\x14\x45\x02\x42\x92\x0B\x42\xA4\x10\x32\x14" \ + "\x38\x08\x18\x49\x0A\x32\x44\x24\x48\x0A\x90\x21\x23\xC4\x52\x80\x0C\x19\x21\x72" \ + "\x24\x07\xC8\x48\x11\x62\xA8\xA0\xA8\x40\xC6\xF0\x01\x00\x00\x00\x49\x18\x00\x00" \ + "\x08\x00\x00\x00\x0B\x8C\x00\x04\x41\x10\x04\x09\x01\x04\x41\x10\x04\x89\xFF\xFF" \ + "\xFF\xFF\x1F\xC0\x60\x81\xF0\xFF\xFF\xFF\xFF\x03\x18\x00\x00\x00\x89\x20\x00\x00" \ + "\x13\x00\x00\x00\x32\x22\x48\x09\x20\x64\x85\x04\x93\x22\xA4\x84\x04\x93\x22\xE3" \ + "\x84\xA1\x90\x14\x12\x4C\x8A\x8C\x0B\x84\xA4\x4C\x10\x48\x23\x00\x73\x04\xC8\x30" \ + "\x02\x11\x90\x28\x03\x18\x83\xC8\x0C\xC0\x30\x02\x61\x14\xE1\x08\x42\xC3\x08\x83" \ + "\x51\x06\xA3\x14\xAD\x22\x08\x45\x6D\x20\x60\x8E\x00\x0C\x86\x11\x06\x08\x00\x00" \ + "\x13\xB0\x70\x90\x87\x76\xB0\x87\x3B\x68\x03\x77\x78\x07\x77\x28\x87\x36\x60\x87" \ + "\x74\x70\x87\x7A\xC0\x87\x36\x38\x07\x77\xA8\x87\x72\x08\x07\x71\x48\x87\x0D\xF2" \ + "\x50\x0E\x6D\x00\x0F\x7A\x30\x07\x72\xA0\x07\x73\x20\x07\x7A\x30\x07\x72\xD0\x06" \ + "\xE9\x10\x07\x7A\x80\x07\x7A\x80\x07\x6D\x90\x0E\x78\xA0\x07\x78\xA0\x07\x78\xD0" \ + "\x06\xE9\x10\x07\x76\xA0\x07\x71\x60\x07\x7A\x10\x07\x76\xD0\x06\xE9\x30\x07\x72" \ + "\xA0\x07\x73\x20\x07\x7A\x30\x07\x72\xD0\x06\xE9\x60\x07\x74\xA0\x07\x76\x40\x07" \ + "\x7A\x60\x07\x74\xD0\x06\xE6\x30\x07\x72\xA0\x07\x73\x20\x07\x7A\x30\x07\x72\xD0" \ + "\x06\xE6\x60\x07\x74\xA0\x07\x76\x40\x07\x7A\x60\x07\x74\xD0\x06\xF6\x60\x07\x74" \ + "\xA0\x07\x76\x40\x07\x7A\x60\x07\x74\xD0\x06\xF6\x10\x07\x72\x80\x07\x7A\x60\x07" \ + "\x74\xA0\x07\x71\x20\x07\x78\xD0\x06\xE1\x00\x07\x7A\x00\x07\x7A\x60\x07\x74\xD0" \ + "\x06\xEE\x30\x07\x72\xD0\x06\xB3\x60\x07\x74\x30\x44\x29\x00\x00\x08\x00\x00\x00" \ + "\x80\x21\x4A\x02\x04\x00\x00\x00\x00\x00\x0C\x51\x18\x20\x00\x00\x00\x00\x00\x60" \ + "\x88\xE2\x00\x01\x00\x00\x00\x00\x00\x79\x18\x00\x45\x00\x00\x00\x43\x88\x27\x78" \ + "\x84\x05\x87\x3D\x94\x83\x3C\xCC\x43\x3A\xBC\x83\x3B\x2C\x08\xE2\x60\x08\xF1\x10" \ + "\x4F\xB1\x20\x52\x87\x70\xB0\x87\x70\xF8\x05\x78\x08\x87\x71\x58\x87\x70\x38\x87" \ + "\x72\xF8\x05\x77\x08\x87\x76\x28\x87\x05\x63\x30\x0E\xEF\xD0\x0E\x6E\x50\x0E\xF8" \ + "\x10\x0E\xED\x00\x0F\xEC\x50\x0E\x6E\x10\x0E\xEE\x40\x0E\xF2\xF0\x0E\xE9\x40\x0E" \ + "\x6E\x20\x0F\xF3\xE0\x06\xE8\x50\x0E\xEC\xC0\x0E\xEF\x30\x0E\xEF\xD0\x0E\xF0\x50" \ + "\x0F\xF4\x50\x0E\x43\x84\xE7\x58\x40\xC8\xC3\x3B\xBC\x03\x3D\x0C\x11\x9E\x64\x41" \ + "\x30\x07\x43\x88\x67\x79\x98\x05\xCF\x3B\xB4\x83\x3B\xA4\x03\x3C\xBC\x03\x3D\x94" \ + "\x83\x3B\xD0\x03\x18\x8C\x03\x3A\x84\x83\x3C\x0C\x21\x9E\x06\x00\x16\x44\xB3\x90" \ + "\x0E\xED\x00\x0F\xEC\x50\x0E\x60\x30\x0A\x6F\x30\x0A\x6B\xB0\x06\x60\x40\x0B\xA2" \ + "\x10\x0A\xA1\x30\xE2\x18\x03\x78\x90\x87\x70\x38\x87\x76\x08\x87\x29\x02\x30\x8C" \ + "\xB8\xC6\x40\x1E\xE6\xE1\x17\xCA\x01\x1F\xE0\xE1\x1D\xE4\x81\x1E\x7E\xC1\x1C\xDE" \ + "\x41\x1E\xCA\x21\x1C\xC6\x01\x1D\x7E\xC1\x1D\xC2\xA1\x1D\xCA\x61\x4A\x60\x8C\x90" \ + "\xC6\x40\x1E\xE6\xE1\x17\xCA\x01\x1F\xE0\xE1\x1D\xE4\x81\x1E\x7E\xC1\x1C\xDE\x41" \ + "\x1E\xCA\x21\x1C\xC6\x01\x1D\xA6\x04\x08\x00\x00\x61\x20\x00\x00\x24\x00\x00\x00" \ + "\x13\x04\x41\x2C\x10\x00\x00\x00\x0C\x00\x00\x00\x04\x8B\xA0\x04\x46\x00\xE8\xCC" \ + "\x00\x90\x9A\x01\x98\x63\x70\x1A\x86\xCC\x18\x41\x6D\xFA\xB2\xEF\x8D\x11\x88\x6D" \ + "\xCC\xC6\xDF\x18\xC1\x49\x97\x72\xFA\x51\x9C\x63\x40\x0E\x63\x04\x00\x00\x00\x00" \ + "\x44\x8C\x11\x03\x42\x08\x82\x68\x90\x41\x4A\x9E\x11\x83\x42\x08\x84\x69\x99\x63" \ + "\x50\x28\x64\x90\xA1\x52\xA0\x11\x03\x42\x08\x06\x6B\x30\xA2\xB8\x06\x00\xC3\x81" \ + "\x00\x00\x00\x00\x03\x00\x00\x00\x46\x40\x54\x3F\xD2\x58\x41\x51\xFD\x0E\x35\x01" \ + "\x01\x31\x00\x00\x03\x00\x00\x00\x5B\x06\x20\x50\xB6\x0C\x47\xA0\x00\x00\x00\x00" \ + "\x00\x00\x00\x00\x79\x18\x00\x00\x0B\x00\x00\x00\x33\x08\x80\x1C\xC4\xE1\x1C\x66" \ + "\x14\x01\x3D\x88\x43\x38\x84\xC3\x8C\x42\x80\x07\x79\x78\x07\x73\x98\xB1\x0C\xE6" \ + "\x00\x0F\xE1\x30\x0E\xE3\x50\x0F\xF2\x10\x0E\xE3\x90\x0F\x00\x00\x71\x20\x00\x00" \ + "\x0E\x00\x00\x00\x06\x40\x44\x8E\x33\x59\x40\x14\x49\x6E\xF3\x00\x82\xC2\x39\x8B" \ + "\x13\xF1\x3C\xCF\x9B\x40\xF3\xCF\xF7\xE0\x4C\x5D\x75\xFF\x05\xFB\xDB\x80\xF6\xCF" \ + "\xF5\x1E\x49\x29\x20\x28\x9C\xB3\x38\x51\xEB\xF0\x3C\xCF\x77\xD5\xFD\x17\x00\x00" \ + "\x00\x00\x00\x00"; + + +ScriptC_mono::ScriptC_mono(RenderScript *rs, const char *cacheDir, size_t cacheDirLength) : + ScriptC(rs, mono, sizeof(mono) - 1, "mono", 4, cacheDir, cacheDirLength) { + + printf("sizeof text %i", sizeof(mono)); + + + +} + +void ScriptC_mono::forEach_root(const Allocation *ain, const Allocation *aout) { + forEach(0, ain, aout, NULL, 0); +} + diff --git a/libs/rs/tests/ScriptC_mono.h b/libs/rs/tests/ScriptC_mono.h new file mode 100644 index 0000000..7e4f601 --- /dev/null +++ b/libs/rs/tests/ScriptC_mono.h @@ -0,0 +1,26 @@ +/* + * 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 "ScriptC.h" + +class ScriptC_mono : protected ScriptC { +public: + ScriptC_mono(RenderScript *rs, const char *cacheDir, size_t cacheDirLength); + + void forEach_root(const Allocation *ain, const Allocation *aout); + +}; + diff --git a/libs/rs/tests/compute.cpp b/libs/rs/tests/compute.cpp new file mode 100644 index 0000000..42eaa52 --- /dev/null +++ b/libs/rs/tests/compute.cpp @@ -0,0 +1,58 @@ + +#include "RenderScript.h" +#include "Element.h" +#include "Type.h" +#include "Allocation.h" + +#include "ScriptC_mono.h" + +int main(int argc, char** argv) +{ + + RenderScript *rs = new RenderScript(); + printf("New RS %p\n", rs); + + 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); + + + Allocation *a1 = Allocation::createSized(rs, e, 1000); + printf("Allocation %p\n", a1); + + Allocation *ain = Allocation::createTyped(rs, t); + Allocation *aout = Allocation::createTyped(rs, t); + printf("Allocation %p %p\n", ain, aout); + + ScriptC_mono * sc = new ScriptC_mono(rs, NULL, 0); + printf("new script\n"); + + uint32_t *buf = new uint32_t[t->getCount()]; + for (uint32_t ct=0; ct < t->getCount(); ct++) { + buf[ct] = ct | (ct << 16); + } + //ain->copy1DRangeFrom(0, 128*128, (int32_t *)buf, 128*128*4); + ain->copy1DRangeFromUnchecked(0, t->getCount(), buf, t->getCount()*4); + + + + sc->forEach_root(ain, aout); + printf("for each done\n"); + + + printf("Deleting stuff\n"); + delete sc; + delete t; + delete a1; + delete e; + delete rs; + printf("Delete OK\n"); +} |