/* * Copyright (C) 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_RSCPPSTRUCTS_H #define ANDROID_RSCPPSTRUCTS_H #include "rsCppUtils.h" #ifndef RS_SERVER #include "utils/RefBase.h" #else #include "RefBase.h" #endif // Every row in an RS allocation is guaranteed to be aligned by this amount // Every row in a user-backed allocation must be aligned by this amount #define RS_CPU_ALLOCATION_ALIGNMENT 16 namespace android { namespace RSC { typedef void (*ErrorHandlerFunc_t)(uint32_t errorNum, const char *errorText); typedef void (*MessageHandlerFunc_t)(uint32_t msgNum, const void *msgData, size_t msgLen); class RS; class BaseObj; class Element; class Type; class Allocation; class Script; class ScriptC; class RS : public android::LightRefBase { public: RS(); virtual ~RS(); bool init(bool forceCpu = false, bool synchronous = false); void setErrorHandler(ErrorHandlerFunc_t func); ErrorHandlerFunc_t getErrorHandler() { return mErrorFunc; } void setMessageHandler(MessageHandlerFunc_t func); MessageHandlerFunc_t getMessageHandler() { return mMessageFunc; } void throwError(const char *err) const; RsContext getContext() { return mContext; } void finish(); private: bool init(int targetApi, bool forceCpu, bool synchronous); static void * threadProc(void *); static bool gInitialized; static pthread_mutex_t gInitMutex; pthread_t mMessageThreadId; pid_t mNativeMessageThreadId; bool mMessageRun; RsDevice mDev; RsContext mContext; ErrorHandlerFunc_t mErrorFunc; MessageHandlerFunc_t mMessageFunc; struct { Element *U8; Element *I8; Element *U16; Element *I16; Element *U32; Element *I32; Element *U64; Element *I64; Element *F32; Element *F64; Element *BOOLEAN; Element *ELEMENT; Element *TYPE; Element *ALLOCATION; Element *SAMPLER; Element *SCRIPT; Element *MESH; Element *PROGRAM_FRAGMENT; Element *PROGRAM_VERTEX; Element *PROGRAM_RASTER; Element *PROGRAM_STORE; Element *A_8; Element *RGB_565; Element *RGB_888; Element *RGBA_5551; Element *RGBA_4444; Element *RGBA_8888; Element *FLOAT_2; Element *FLOAT_3; Element *FLOAT_4; Element *DOUBLE_2; Element *DOUBLE_3; Element *DOUBLE_4; Element *UCHAR_2; Element *UCHAR_3; Element *UCHAR_4; Element *CHAR_2; Element *CHAR_3; Element *CHAR_4; Element *USHORT_2; Element *USHORT_3; Element *USHORT_4; Element *SHORT_2; Element *SHORT_3; Element *SHORT_4; Element *UINT_2; Element *UINT_3; Element *UINT_4; Element *INT_2; Element *INT_3; Element *INT_4; Element *ULONG_2; Element *ULONG_3; Element *ULONG_4; Element *LONG_2; Element *LONG_3; Element *LONG_4; Element *MATRIX_4X4; Element *MATRIX_3X3; Element *MATRIX_2X2; } mElements; }; class BaseObj : public android::LightRefBase { protected: void *mID; sp mRS; String8 mName; BaseObj(void *id, sp rs); void checkValid(); static void * getObjID(sp o); public: void * getID() const; virtual ~BaseObj(); virtual void updateFromNative(); virtual bool equals(const BaseObj *obj); }; class Allocation : public BaseObj { protected: android::sp mType; uint32_t mUsage; android::sp 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(sp t); Allocation(void *id, sp rs, sp 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: android::sp getType() { return mType; } void syncAll(RsAllocationUsageType srcLocation); void ioSendOutput(); void ioGetInput(); void generateMipmaps(); void copy1DRangeFrom(uint32_t off, size_t count, const void *data); void copy1DRangeFrom(uint32_t off, size_t count, sp data, uint32_t dataOff); void copy1DRangeTo(uint32_t off, size_t count, void *data); void copy1DFrom(const void* data); void copy1DTo(void* data); void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data); void copy2DRangeTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, void *data); void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, sp data, uint32_t dataXoff, uint32_t dataYoff); void copy2DStridedFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data, size_t stride); void copy2DStridedFrom(const void *data, size_t stride); void copy2DStridedTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, void *data, size_t stride); void copy2DStridedTo(void *data, size_t stride); void resize(int dimX); void resize(int dimX, int dimY); static sp createTyped(sp rs, sp type, RsAllocationMipmapControl mips, uint32_t usage); static sp createTyped(sp rs, sp type, RsAllocationMipmapControl mips, uint32_t usage, void * pointer); static sp createTyped(sp rs, sp type, uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT); static sp createSized(sp rs, sp e, size_t count, uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT); static sp createSized2D(sp rs, sp e, size_t x, size_t y, uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT); }; class Element : public BaseObj { public: bool isComplex(); size_t getSubElementCount() { return mVisibleElementMap.size(); } sp getSubElement(uint32_t index); const char * getSubElementName(uint32_t index); size_t getSubElementArraySize(uint32_t index); uint32_t getSubElementOffsetBytes(uint32_t index); RsDataType getDataType() const { return mType; } RsDataKind getDataKind() const { return mKind; } size_t getSizeBytes() const { return mSizeBytes; } static sp BOOLEAN(sp rs); static sp U8(sp rs); static sp I8(sp rs); static sp U16(sp rs); static sp I16(sp rs); static sp U32(sp rs); static sp I32(sp rs); static sp U64(sp rs); static sp I64(sp rs); static sp F32(sp rs); static sp F64(sp rs); static sp ELEMENT(sp rs); static sp TYPE(sp rs); static sp ALLOCATION(sp rs); static sp SAMPLER(sp rs); static sp SCRIPT(sp rs); static sp MESH(sp rs); static sp PROGRAM_FRAGMENT(sp rs); static sp PROGRAM_VERTEX(sp rs); static sp PROGRAM_RASTER(sp rs); static sp PROGRAM_STORE(sp rs); static sp A_8(sp rs); static sp RGB_565(sp rs); static sp RGB_888(sp rs); static sp RGBA_5551(sp rs); static sp RGBA_4444(sp rs); static sp RGBA_8888(sp rs); static sp F32_2(sp rs); static sp F32_3(sp rs); static sp F32_4(sp rs); static sp F64_2(sp rs); static sp F64_3(sp rs); static sp F64_4(sp rs); static sp U8_2(sp rs); static sp U8_3(sp rs); static sp U8_4(sp rs); static sp I8_2(sp rs); static sp I8_3(sp rs); static sp I8_4(sp rs); static sp U16_2(sp rs); static sp U16_3(sp rs); static sp U16_4(sp rs); static sp I16_2(sp rs); static sp I16_3(sp rs); static sp I16_4(sp rs); static sp U32_2(sp rs); static sp U32_3(sp rs); static sp U32_4(sp rs); static sp I32_2(sp rs); static sp I32_3(sp rs); static sp I32_4(sp rs); static sp U64_2(sp rs); static sp U64_3(sp rs); static sp U64_4(sp rs); static sp I64_2(sp rs); static sp I64_3(sp rs); static sp I64_4(sp rs); static sp MATRIX_4X4(sp rs); static sp MATRIX_3X3(sp rs); static sp MATRIX_2X2(sp rs); Element(void *id, sp rs, android::Vector > &elements, android::Vector &elementNames, android::Vector &arraySizes); Element(void *id, sp rs, RsDataType dt, RsDataKind dk, bool norm, uint32_t size); Element(sp rs); virtual ~Element(); void updateFromNative(); static sp createUser(sp rs, RsDataType dt); static sp createVector(sp rs, RsDataType dt, uint32_t size); static sp createPixel(sp rs, RsDataType dt, RsDataKind dk); bool isCompatible(spe); class Builder { private: sp mRS; android::Vector > mElements; android::Vector mElementNames; android::Vector mArraySizes; bool mSkipPadding; public: Builder(sp rs); ~Builder(); void add(sp, android::String8 &name, uint32_t arraySize = 1); sp create(); }; private: void updateVisibleSubElements(); android::Vector > mElements; android::Vector mElementNames; android::Vector mArraySizes; android::Vector mVisibleElementMap; android::Vector mOffsetInBytes; RsDataType mType; RsDataKind mKind; bool mNormalized; size_t mSizeBytes; size_t mVectorSize; }; class FieldPacker { protected: unsigned char* mData; size_t mPos; size_t mLen; public: FieldPacker(size_t len) : mPos(0), mLen(len) { mData = new unsigned char[len]; } virtual ~FieldPacker() { delete [] mData; } void align(size_t v) { if ((v & (v - 1)) != 0) { ALOGE("Non-power-of-two alignment: %zu", v); return; } while ((mPos & (v - 1)) != 0) { mData[mPos++] = 0; } } void reset() { mPos = 0; } void reset(size_t i) { if (i >= mLen) { ALOGE("Out of bounds: i (%zu) >= len (%zu)", i, mLen); return; } mPos = i; } void skip(size_t i) { size_t res = mPos + i; if (res > mLen) { ALOGE("Exceeded buffer length: i (%zu) > len (%zu)", i, mLen); return; } mPos = res; } void* getData() const { return mData; } size_t getLength() const { return mLen; } template void add(T t) { align(sizeof(t)); if (mPos + sizeof(t) <= mLen) { memcpy(&mData[mPos], &t, sizeof(t)); mPos += sizeof(t); } } /* void add(rs_matrix4x4 m) { for (size_t i = 0; i < 16; i++) { add(m.m[i]); } } void add(rs_matrix3x3 m) { for (size_t i = 0; i < 9; i++) { add(m.m[i]); } } void add(rs_matrix2x2 m) { for (size_t i = 0; i < 4; i++) { add(m.m[i]); } } */ void add(BaseObj* obj) { if (obj != NULL) { add((uint32_t) (uintptr_t) obj->getID()); } else { add((uint32_t) 0); } } }; class Type : public BaseObj { protected: friend class Allocation; uint32_t mDimX; uint32_t mDimY; uint32_t mDimZ; bool mDimMipmaps; bool mDimFaces; size_t mElementCount; sp mElement; void calcElementCount(); virtual void updateFromNative(); public: sp 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, sp rs); static sp create(sp rs, sp e, uint32_t dimX, uint32_t dimY, uint32_t dimZ); class Builder { protected: sp mRS; uint32_t mDimX; uint32_t mDimY; uint32_t mDimZ; bool mDimMipmaps; bool mDimFaces; sp mElement; public: Builder(sp rs, sp e); void setX(uint32_t value); void setY(int value); void setMipmaps(bool value); void setFaces(bool value); sp create(); }; }; class Script : public BaseObj { private: protected: Script(void *id, sp rs); void forEach(uint32_t slot, sp in, sp out, const void *v, size_t) const; void bindAllocation(sp va, uint32_t slot) const; void setVar(uint32_t index, const void *, size_t len) const; void setVar(uint32_t index, sp o) const; void invoke(uint32_t slot, const void *v, size_t len) const; void invoke(uint32_t slot) const { invoke(slot, NULL, 0); } void setVar(uint32_t index, float v) const { setVar(index, &v, sizeof(v)); } void setVar(uint32_t index, double v) const { setVar(index, &v, sizeof(v)); } void setVar(uint32_t index, int32_t v) const { setVar(index, &v, sizeof(v)); } void setVar(uint32_t index, int64_t v) const { setVar(index, &v, sizeof(v)); } void setVar(uint32_t index, bool v) const { setVar(index, &v, sizeof(v)); } public: class FieldBase { protected: sp mElement; sp mAllocation; void init(sp rs, uint32_t dimx, uint32_t usages = 0); public: sp getElement() { return mElement; } sp getType() { return mAllocation->getType(); } sp getAllocation() { return mAllocation; } //void updateAllocation(); }; }; class ScriptC : public Script { protected: ScriptC(sp rs, const void *codeTxt, size_t codeLength, const char *cachedName, size_t cachedNameLength, const char *cacheDir, size_t cacheDirLength); }; class ScriptIntrinsic : public Script { protected: ScriptIntrinsic(sp rs, int id, sp e); }; class ScriptIntrinsicBlend : public ScriptIntrinsic { public: ScriptIntrinsicBlend(sp rs, sp e); void blendClear(sp in, sp out); void blendSrc(sp in, sp out); void blendDst(sp in, sp out); void blendSrcOver(sp in, sp out); void blendDstOver(sp in, sp out); void blendSrcIn(sp in, sp out); void blendDstIn(sp in, sp out); void blendSrcOut(sp in, sp out); void blendDstOut(sp in, sp out); void blendSrcAtop(sp in, sp out); void blendDstAtop(sp in, sp out); void blendXor(sp in, sp out); void blendMultiply(sp in, sp out); void blendAdd(sp in, sp out); void blendSubtract(sp in, sp out); }; class ScriptIntrinsicBlur : public ScriptIntrinsic { public: ScriptIntrinsicBlur(sp rs, sp e); void blur(sp in, sp out); void setRadius(float radius); }; } } #endif