slang_rs_reflection.cpp revision 8d75dc46a30e8617bd29dfe00492c5aab02dacf5
1b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include "slang_rs_context.hpp" 2b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include "slang_rs_export_var.hpp" 3b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include "slang_rs_reflection.hpp" 4b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include "slang_rs_export_func.hpp" 5b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include "slang_rs_reflect_utils.hpp" 6b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 7b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <ctype.h> 8b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 9b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <utility> 10b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include <cstdarg> 11b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 12b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#include "llvm/ADT/APFloat.h" 13b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 14b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenusing std::make_pair; 15b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenusing std::endl; 16b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 17b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 18b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_" 19b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC" 20b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 21b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen#define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_" 22b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define RS_TYPE_CLASS_SUPER_CLASS_NAME "android.renderscript.Script.FieldBase" 23b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 24b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define RS_TYPE_ITEM_CLASS_NAME "Item" 25b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 26b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define RS_TYPE_ITEM_BUFFER_NAME "mItemArray" 27b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define RS_TYPE_ITEM_BUFFER_PACKER_NAME "mIOBuffer" 28e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia 29b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define RS_EXPORT_VAR_INDEX_PREFIX "mExportVarIdx_" 30b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define RS_EXPORT_VAR_PREFIX "mExportVar_" 31b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 32b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define RS_EXPORT_FUNC_INDEX_PREFIX "mExportFuncIdx_" 33b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 34b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define RS_EXPORT_VAR_ALLOCATION_PREFIX "mAlloction_" 35b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_" 36b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 37b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissennamespace slang { 38b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 39b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen/* Some utility function using internal in RSReflection */ 40b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissenstatic bool GetClassNameFromFileName(const std::string& FileName, std::string& ClassName) { 41b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen ClassName.clear(); 42b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 43b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen if(FileName.empty() || (FileName == "-")) 44b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen return true; 45b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 46b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen ClassName = RSSlangReflectUtils::JavaClassNameFromRSFileName(FileName.c_str()); 47b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 48b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen return true; 49b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen} 50b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 51e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jiastatic const char* GetPrimitiveTypeName(const RSExportPrimitiveType* EPT) { 52b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen static const char* PrimitiveTypeJavaNameMap[] = { 53e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia "", 54b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "", 55b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "float", /* RSExportPrimitiveType::DataTypeFloat32 */ 56b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "double", /* RSExportPrimitiveType::DataTypeFloat64 */ 57b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "byte", /* RSExportPrimitiveType::DataTypeSigned8 */ 58b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "short", /* RSExportPrimitiveType::DataTypeSigned16 */ 59b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "int", /* RSExportPrimitiveType::DataTypeSigned32 */ 60b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "long", /* RSExportPrimitiveType::DataTypeSigned64 */ 61b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "short", /* RSExportPrimitiveType::DataTypeUnsigned8 */ 62b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "int", /* RSExportPrimitiveType::DataTypeUnsigned16 */ 63b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "long", /* RSExportPrimitiveType::DataTypeUnsigned32 */ 64b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "long", /* RSExportPrimitiveType::DataTypeUnsigned64 */ 65b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 66b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "int", /* RSExportPrimitiveType::DataTypeUnsigned565 */ 67b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "int", /* RSExportPrimitiveType::DataTypeUnsigned5551 */ 68b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "int", /* RSExportPrimitiveType::DataTypeUnsigned4444 */ 69b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 70b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "boolean", /* RSExportPrimitiveType::DataTypeBool */ 71b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 72b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "Element", /* RSExportPrimitiveType::DataTypeRSElement */ 73b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "Type", /* RSExportPrimitiveType::DataTypeRSType */ 74b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "Allocation", /* RSExportPrimitiveType::DataTypeRSAllocation */ 75e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia "Sampler", /* RSExportPrimitiveType::DataTypeRSSampler */ 76e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia "Script", /* RSExportPrimitiveType::DataTypeRSScript */ 77e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia "Mesh", /* RSExportPrimitiveType::DataTypeRSMesh */ 78e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia "ProgramFragment", /* RSExportPrimitiveType::DataTypeRSProgramFragment */ 79b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "ProgramVertex", /* RSExportPrimitiveType::DataTypeRSProgramVertex */ 80b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "ProgramRaster", /* RSExportPrimitiveType::DataTypeRSProgramRaster */ 81b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "ProgramStore", /* RSExportPrimitiveType::DataTypeRSProgramStore */ 82b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "Font", /* RSExportPrimitiveType::DataTypeRSFont */ 83b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "Matrix2f", /* RSExportPrimitiveType::DataTypeRSMatrix2x2 */ 84b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "Matrix3f", /* RSExportPrimitiveType::DataTypeRSMatrix3x3 */ 85b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "Matrix4f", /* RSExportPrimitiveType::DataTypeRSMatrix4x4 */ 86b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen }; 87b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen unsigned TypeId = EPT->getType(); 88b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 89b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen if(TypeId < (sizeof(PrimitiveTypeJavaNameMap) / sizeof(const char*))) { 90b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen // printf("Type %d\n", EPT->getType()); 91b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen return PrimitiveTypeJavaNameMap[ EPT->getType() ]; 92b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen } 93b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 94b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen assert(false && "GetPrimitiveTypeName : Unknown primitive data type"); 95b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen return NULL; 96b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen} 97b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 98b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissenstatic const char* GetVectorTypeName(const RSExportVectorType* EVT) { 99b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen static const char* VectorTypeJavaNameMap[][3] = { 100b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen /* 0 */ { "Byte2", "Byte3", "Byte4" }, 101b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen /* 1 */ { "Short2", "Short3", "Short4" }, 102b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen /* 2 */ { "Int2", "Int3", "Int4" }, 103b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen /* 3 */ { "Long2", "Long3", "Long4" }, 104b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen /* 4 */ { "Float2", "Float3", "Float4" }, 105b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen }; 106b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 107b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen const char** BaseElement = NULL; 108b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 109b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen switch(EVT->getType()) { 110b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen case RSExportPrimitiveType::DataTypeSigned8: 111b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen BaseElement = VectorTypeJavaNameMap[0]; 112b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen break; 113b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 114b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen case RSExportPrimitiveType::DataTypeSigned16: 115b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen case RSExportPrimitiveType::DataTypeUnsigned8: 116b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen BaseElement = VectorTypeJavaNameMap[1]; 117b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen break; 118b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 119b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen case RSExportPrimitiveType::DataTypeSigned32: 120b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen case RSExportPrimitiveType::DataTypeUnsigned16: 121b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen BaseElement = VectorTypeJavaNameMap[2]; 122b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen break; 123b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 124b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen case RSExportPrimitiveType::DataTypeSigned64: 125b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen case RSExportPrimitiveType::DataTypeUnsigned32: 126b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen BaseElement = VectorTypeJavaNameMap[3]; 127b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen break; 128b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 129b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen case RSExportPrimitiveType::DataTypeFloat32: 130b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen BaseElement = VectorTypeJavaNameMap[4]; 131b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen break; 132b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 133b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen case RSExportPrimitiveType::DataTypeBool: 134b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen BaseElement = VectorTypeJavaNameMap[0]; 135b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen break; 136b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 137b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen default: 138b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen assert(false && "RSReflection::genElementTypeName : Unsupported vector element data type"); 139b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen break; 140b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen } 141b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 142b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen assert((EVT->getNumElement() > 1) && (EVT->getNumElement() <= 4) && "Number of element in vector type is invalid"); 143b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 144b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen return BaseElement[EVT->getNumElement() - 2]; 145b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen} 146b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 147b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenstatic const char* GetVectorAccessor(int Index) { 148b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen static const char* VectorAccessorMap[] = { 149b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen /* 0 */ "x", 150b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen /* 1 */ "y", 151b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen /* 2 */ "z", 152b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen /* 3 */ "w", 153b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen }; 154b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 155b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen assert((Index >= 0) && (Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) && "Out-of-bound index to access vector member"); 156b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 157b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen return VectorAccessorMap[Index]; 158b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen} 159b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 160b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenstatic const char* GetPackerAPIName(const RSExportPrimitiveType* EPT) { 161b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen static const char* PrimitiveTypePackerAPINameMap[] = { 162b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "", 163b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "", 164b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addF32", /* RSExportPrimitiveType::DataTypeFloat32 */ 165b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addF64", /* RSExportPrimitiveType::DataTypeFloat64 */ 166b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addI8", /* RSExportPrimitiveType::DataTypeSigned8 */ 167b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addI16", /* RSExportPrimitiveType::DataTypeSigned16 */ 168b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addI32", /* RSExportPrimitiveType::DataTypeSigned32 */ 169b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addI64", /* RSExportPrimitiveType::DataTypeSigned64 */ 170b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addU8", /* RSExportPrimitiveType::DataTypeUnsigned8 */ 171b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addU16", /* RSExportPrimitiveType::DataTypeUnsigned16 */ 172b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addU32", /* RSExportPrimitiveType::DataTypeUnsigned32 */ 173b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addU64", /* RSExportPrimitiveType::DataTypeUnsigned64 */ 174b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 175b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addU16", /* RSExportPrimitiveType::DataTypeUnsigned565 */ 176b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addU16", /* RSExportPrimitiveType::DataTypeUnsigned5551 */ 177b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addU16", /* RSExportPrimitiveType::DataTypeUnsigned4444 */ 178b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 179b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addBoolean", /* RSExportPrimitiveType::DataTypeBool */ 180b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 181b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSElement */ 182b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSType */ 183b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSAllocation */ 184b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSSampler */ 185b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSScript */ 186b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSMesh */ 187b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSProgramFragment */ 188b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSProgramVertex */ 189b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSProgramRaster */ 190b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSProgramStore */ 191b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSFont */ 192b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSMatrix2x2 */ 193b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSMatrix3x3 */ 194b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "addObj", /* RSExportPrimitiveType::DataTypeRSMatrix4x4 */ 195b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen }; 196b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen unsigned TypeId = EPT->getType(); 197b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 198b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen if(TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char*))) 199b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen return PrimitiveTypePackerAPINameMap[ EPT->getType() ]; 200b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 201b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen assert(false && "GetPackerAPIName : Unknown primitive data type"); 202b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen return NULL; 203b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen} 204b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 205b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenstatic std::string GetTypeName(const RSExportType* ET) { 206b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen switch(ET->getClass()) { 207b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen case RSExportType::ExportClassPrimitive: 208b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen case RSExportType::ExportClassConstantArray: 209b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen return GetPrimitiveTypeName(static_cast<const RSExportPrimitiveType*>(ET)); 210b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen break; 211b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 212b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen case RSExportType::ExportClassPointer: 213b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen { 214b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen const RSExportType* PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 215b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 216e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia if(PointeeType->getClass() != RSExportType::ExportClassRecord) 217e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia return "Allocation"; 218e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia else 219e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia return RS_TYPE_CLASS_NAME_PREFIX + PointeeType->getName(); 220e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia } 221e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia break; 222e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia 223e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia case RSExportType::ExportClassVector: 224e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia return GetVectorTypeName(static_cast<const RSExportVectorType*>(ET)); 225b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen break; 226b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 227b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen case RSExportType::ExportClassRecord: 228b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen return RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + "."RS_TYPE_ITEM_CLASS_NAME; 229b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen break; 230b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 231b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen default: 232b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen assert(false && "Unknown class of type"); 233b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen break; 234b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen } 235b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 236b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen return ""; 237b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen} 238b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 239b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenstatic const char* GetBuiltinElementConstruct(const RSExportType* ET) { 240b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen if (ET->getClass() == RSExportType::ExportClassPrimitive || ET->getClass() == RSExportType::ExportClassConstantArray) { 241b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET); 242b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen if (EPT->getKind() == RSExportPrimitiveType::DataKindUser) { 243b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen static const char* PrimitiveBuiltinElementConstructMap[] = { 244b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen NULL, 245b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen NULL, 246b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "F32", /* RSExportPrimitiveType::DataTypeFloat32 */ 247b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "F64", /* RSExportPrimitiveType::DataTypeFloat64 */ 248b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "I8", /* RSExportPrimitiveType::DataTypeSigned8 */ 249b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen NULL, /* RSExportPrimitiveType::DataTypeSigned16 */ 250b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "I32", /* RSExportPrimitiveType::DataTypeSigned32 */ 251b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "I64", /* RSExportPrimitiveType::DataTypeSigned64 */ 252b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "U8", /* RSExportPrimitiveType::DataTypeUnsigned8 */ 253b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen NULL, /* RSExportPrimitiveType::DataTypeUnsigned16 */ 254b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "U32", /* RSExportPrimitiveType::DataTypeUnsigned32 */ 255b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen NULL, /* RSExportPrimitiveType::DataTypeUnsigned64 */ 256b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 257b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen NULL, /* RSExportPrimitiveType::DataTypeUnsigned565 */ 258b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen NULL, /* RSExportPrimitiveType::DataTypeUnsigned5551 */ 259b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen NULL, /* RSExportPrimitiveType::DataTypeUnsigned4444 */ 260b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 261b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "BOOLEAN", /* RSExportPrimitiveType::DataTypeBool */ 262b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 263b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "ELEMENT", /* RSExportPrimitiveType::DataTypeRSElement */ 264b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "TYPE", /* RSExportPrimitiveType::DataTypeRSType */ 265b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "ALLOCATION", /* RSExportPrimitiveType::DataTypeRSAllocation */ 266b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "SAMPLER", /* RSExportPrimitiveType::DataTypeRSSampler */ 267b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "SCRIPT", /* RSExportPrimitiveType::DataTypeRSScript */ 268b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "MESH", /* RSExportPrimitiveType::DataTypeRSMesh */ 269b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "PROGRAM_FRAGMENT", /* RSExportPrimitiveType::DataTypeRSProgramFragment */ 270b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "PROGRAM_VERTEX", /* RSExportPrimitiveType::DataTypeRSProgramVertex */ 271b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "PROGRAM_RASTER", /* RSExportPrimitiveType::DataTypeRSProgramRaster */ 272b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "PROGRAM_STORE", /* RSExportPrimitiveType::DataTypeRSProgramStore */ 273b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "FONT", /* RSExportPrimitiveType::DataTypeRSFont */ 274b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "MATRIX_2X2", /* RSExportPrimitiveType::DataTypeRSMatrix2x2 */ 275b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen "MATRIX_3X3", /* RSExportPrimitiveType::DataTypeRSMatrix3x3 */ 276b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "MATRIX_4X4", /* RSExportPrimitiveType::DataTypeRSMatrix4x4 */ 277b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen }; 278b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen unsigned TypeId = EPT->getType(); 279b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen 280b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen if (TypeId < (sizeof(PrimitiveBuiltinElementConstructMap) / sizeof(const char*))) 281e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia return PrimitiveBuiltinElementConstructMap[ EPT->getType() ]; 282e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelA) { 283e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 284e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia return "A_8"; 285e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGB) { 286e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned565) 287e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia return "RGB_565"; 288e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 289e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia return "RGB_888"; 290e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGBA) { 291e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned5551) 292e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia return "RGB_5551"; 293e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned4444) 294e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia return "RGB_4444"; 295e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 296e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia return "RGB_8888"; 297e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia } else if (EPT->getKind() == RSExportPrimitiveType::DataKindIndex) { 298e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned16) 299e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia return "INDEX_16"; 300e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia } 301e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia } else if (ET->getClass() == RSExportType::ExportClassVector) { 302e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(ET); 303e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia if (EVT->getKind() == RSExportPrimitiveType::DataKindPosition) { 304e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 305e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia if (EVT->getNumElement() == 2) 306e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia return "ATTRIB_POSITION_2"; 307e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia else if (EVT->getNumElement() == 3) 308e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia return "ATTRIB_POSITION_3"; 309e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia } 310b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen } else if (EVT->getKind() == RSExportPrimitiveType::DataKindTexture) { 311e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 312e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia if (EVT->getNumElement() == 2) 313b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen return "ATTRIB_TEXTURE_2"; 314e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia } 315e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia } else if (EVT->getKind() == RSExportPrimitiveType::DataKindNormal) { 316b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 317b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen if (EVT->getNumElement() == 3) 3181d5a306c0b1322168e8f9fcf81876118a355a400Wei Jia return "ATTRIB_NORMAL_3"; 3191d5a306c0b1322168e8f9fcf81876118a355a400Wei Jia } 3201d5a306c0b1322168e8f9fcf81876118a355a400Wei Jia } else if (EVT->getKind() == RSExportPrimitiveType::DataKindColor) { 321b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 322e9a5b96e7927fd4e38623e17ac73e8e4e25877eeWei Jia if (EVT->getNumElement() == 4) 323b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen return "ATTRIB_COLOR_F32_4"; 324b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen } else if (EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) { 325b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen if (EVT->getNumElement() == 4) 326b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen return "ATTRIB_COLOR_U8_4"; 327b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen } 328b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen } 329b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen } else if (ET->getClass() == RSExportType::ExportClassPointer) { 330b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen return "USER_I32"; /* tread pointer type variable as unsigned int (TODO: this is target dependent) */ 331b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen } 332b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 333b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen return NULL; 334b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen} 335b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 336b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenstatic const char* GetElementDataKindName(RSExportPrimitiveType::DataKind DK) { 337b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen static const char* ElementDataKindNameMap[] = { 338b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataKind.USER", /* RSExportPrimitiveType::DataKindUser */ 339b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataKind.COLOR", /* RSExportPrimitiveType::DataKindColor */ 340b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataKind.POSITION", /* RSExportPrimitiveType::DataKindPosition */ 341b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataKind.TEXTURE", /* RSExportPrimitiveType::DataKindTexture */ 342b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataKind.NORMAL", /* RSExportPrimitiveType::DataKindNormal */ 343b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataKind.INDEX", /* RSExportPrimitiveType::DataKindIndex */ 344b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataKind.POINT_SIZE", /* RSExportPrimitiveType::DataKindPointSize */ 345b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataKind.PIXEL_L", /* RSExportPrimitiveType::DataKindPixelL */ 346b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataKind.PIXEL_A", /* RSExportPrimitiveType::DataKindPixelA */ 347b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataKind.PIXEL_LA", /* RSExportPrimitiveType::DataKindPixelLA */ 348b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataKind.PIXEL_RGB", /* RSExportPrimitiveType::DataKindPixelRGB */ 349b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataKind.PIXEL_RGBA", /* RSExportPrimitiveType::DataKindPixelRGBA */ 350b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen }; 351b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 352b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen if(static_cast<unsigned>(DK) < (sizeof(ElementDataKindNameMap) / sizeof(const char*))) 353b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen return ElementDataKindNameMap[ DK ]; 354b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen else 355b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen return NULL; 356b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen} 357b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 358b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenstatic const char* GetElementDataTypeName(RSExportPrimitiveType::DataType DT) { 359b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen static const char* ElementDataTypeNameMap[] = { 360b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen NULL, 361b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen NULL, 362b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.FLOAT_32", /* RSExportPrimitiveType::DataTypeFloat32 */ 363b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.FLOAT_64", /* RSExportPrimitiveType::DataTypeFloat64 */ 364b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.SIGNED_8", /* RSExportPrimitiveType::DataTypeSigned8 */ 365b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.SIGNED_16", /* RSExportPrimitiveType::DataTypeSigned16 */ 366b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.SIGNED_32", /* RSExportPrimitiveType::DataTypeSigned32 */ 367b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.SIGNED_64", /* RSExportPrimitiveType::DataTypeSigned64 */ 368b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.UNSIGNED_8", /* RSExportPrimitiveType::DataTypeUnsigned8 */ 369b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.UNSIGNED_16", /* RSExportPrimitiveType::DataTypeUnsigned16 */ 370b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.UNSIGNED_32", /* RSExportPrimitiveType::DataTypeUnsigned32 */ 371b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen NULL, /* RSExportPrimitiveType::DataTypeUnsigned64 */ 372b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 373b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.UNSIGNED_5_6_5", /* RSExportPrimitiveType::DataTypeUnsigned565 */ 374b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.UNSIGNED_5_5_5_1", /* RSExportPrimitiveType::DataTypeUnsigned5551 */ 375b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.UNSIGNED_4_4_4_4", /* RSExportPrimitiveType::DataTypeUnsigned4444 */ 376b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 377b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.BOOLEAN", /* RSExportPrimitiveType::DataTypeBool */ 378b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 379b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_ELEMENT", /* RSExportPrimitiveType::DataTypeRSElement */ 380b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_TYPE", /* RSExportPrimitiveType::DataTypeRSType */ 381b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_ALLOCATION", /* RSExportPrimitiveType::DataTypeRSAllocation */ 382b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_SAMPLER", /* RSExportPrimitiveType::DataTypeRSSampler */ 383b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_SCRIPT", /* RSExportPrimitiveType::DataTypeRSScript */ 384b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_MESH", /* RSExportPrimitiveType::DataTypeRSMesh */ 385b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_PROGRAM_FRAGMENT", /* RSExportPrimitiveType::DataTypeRSProgramFragment */ 386b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_PROGRAM_VERTEX", /* RSExportPrimitiveType::DataTypeRSProgramVertex */ 387b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_PROGRAM_RASTER", /* RSExportPrimitiveType::DataTypeRSProgramRaster */ 388b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_PROGRAM_STORE", /* RSExportPrimitiveType::DataTypeRSProgramStore */ 389b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_FONT", /* RSExportPrimitiveType::DataTypeRSFont */ 390b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_MATRIX_2X2", /* RSExportPrimitiveType::DataTypeRSMatrix2x2 */ 391b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_MATRIX_3X3", /* RSExportPrimitiveType::DataTypeRSMatrix3x3 */ 392b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen "Element.DataType.RS_MATRIX_4X4", /* RSExportPrimitiveType::DataTypeRSMatrix4x4 */ 393b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen }; 394b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen 395b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen if(static_cast<unsigned>(DT) < (sizeof(ElementDataTypeNameMap) / sizeof(const char*))) 396b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen return ElementDataTypeNameMap[ DT ]; 397 else 398 return NULL; 399} 400 401bool RSReflection::openScriptFile(Context&C, const std::string& ClassName, std::string& ErrorMsg) { 402 if(!C.mUseStdout) { 403 C.mOF.clear(); 404 std::string _path = RSSlangReflectUtils::ComputePackagedPath( 405 mRSContext->getReflectJavaPathName().c_str(), C.getPackageName().c_str()); 406 407 RSSlangReflectUtils::mkdir_p(_path.c_str()); 408 C.mOF.open(( _path + "/" + ClassName + ".java" ).c_str()); 409 if(!C.mOF.good()) { 410 ErrorMsg = "failed to open file '" + _path + "/" + ClassName + ".java' for write"; 411 412 return false; 413 } 414 } 415 return true; 416} 417 418/****************************** Methods to generate script class ******************************/ 419bool RSReflection::genScriptClass(Context& C, const std::string& ClassName, std::string& ErrorMsg) { 420 /* Open the file */ 421 if (!openScriptFile(C, ClassName, ErrorMsg)) { 422 return false; 423 } 424 425 if(!C.startClass(Context::AM_Public, false, ClassName, RS_SCRIPT_CLASS_SUPER_CLASS_NAME, ErrorMsg)) 426 return false; 427 428 genScriptClassConstructor(C); 429 430 /* Reflect export variable */ 431 for(RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(); 432 I != mRSContext->export_vars_end(); 433 I++) 434 genExportVariable(C, *I); 435 436 /* Reflect export function */ 437 for(RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(); 438 I != mRSContext->export_funcs_end(); 439 I++) 440 genExportFunction(C, *I); 441 442 C.endClass(); 443 444 return true; 445} 446 447void RSReflection::genScriptClassConstructor(Context& C) { 448 C.indent() << "// Constructor" << endl; 449 C.startFunction(Context::AM_Public, false, NULL, C.getClassName(), 4, "RenderScript", "rs", 450 "Resources", "resources", 451 "int", "id", 452 "boolean", "isRoot"); 453 /* Call constructor of super class */ 454 C.indent() << "super(rs, resources, id, isRoot);" << endl; 455 456 /* If an exported variable has initial value, reflect it */ 457 458 for(RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(); 459 I != mRSContext->export_vars_end(); 460 I++) 461 { 462 const RSExportVar* EV = *I; 463 if(!EV->getInit().isUninit()) 464 genInitExportVariable(C, EV->getType(), EV->getName(), EV->getInit()); 465 } 466 467 C.endFunction(); 468 return; 469} 470 471void RSReflection::genInitBoolExportVariable(Context& C, const std::string& VarName, const APValue& Val) { 472 assert(!Val.isUninit() && "Not a valid initializer"); 473 474 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = "; 475 assert((Val.getKind() == APValue::Int) && "Bool type has wrong initial APValue"); 476 477 if (Val.getInt().getSExtValue() == 0) { 478 C.out() << "false"; 479 } else { 480 C.out() << "true"; 481 } 482 C.out() << ";" << endl; 483 484 return; 485} 486 487void RSReflection::genInitPrimitiveExportVariable(Context& C, const std::string& VarName, const APValue& Val) { 488 assert(!Val.isUninit() && "Not a valid initializer"); 489 490 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = "; 491 switch(Val.getKind()) { 492 case APValue::Int: C.out() << Val.getInt().getSExtValue(); break; 493 494 case APValue::Float: { 495 llvm::APFloat apf = Val.getFloat(); 496 if (apf.semanticsPrecision(apf.getSemantics()) == 24 /*llvm::APFloat::IEEEsingle*/) { 497 C.out() << apf.convertToFloat() << "f"; 498 } else { 499 C.out() << apf.convertToDouble(); 500 } 501 break; 502 } 503 504 case APValue::ComplexInt: 505 case APValue::ComplexFloat: 506 case APValue::LValue: 507 case APValue::Vector: 508 assert(false && "Primitive type cannot have such kind of initializer"); 509 break; 510 511 default: 512 assert(false && "Unknown kind of initializer"); 513 break; 514 } 515 C.out() << ";" << endl; 516 517 return; 518} 519 520void RSReflection::genInitExportVariable(Context& C, const RSExportType* ET, const std::string& VarName, const APValue& Val) { 521 assert(!Val.isUninit() && "Not a valid initializer"); 522 523 switch(ET->getClass()) { 524 case RSExportType::ExportClassPrimitive: 525 case RSExportType::ExportClassConstantArray: 526 { 527 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET); 528 if (EPT->getType() == RSExportPrimitiveType::DataTypeBool) { 529 genInitBoolExportVariable(C, VarName, Val); 530 } else { 531 genInitPrimitiveExportVariable(C, VarName, Val); 532 } 533 break; 534 } 535 536 case RSExportType::ExportClassPointer: 537 if(!Val.isInt() || Val.getInt().getSExtValue() != 0) 538 std::cout << "Initializer which is non-NULL to pointer type variable will be ignored" << endl; 539 break; 540 541 case RSExportType::ExportClassVector: 542 { 543 const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(ET); 544 switch(Val.getKind()) { 545 case APValue::Int: 546 case APValue::Float: 547 for(int i=0;i<EVT->getNumElement();i++) { 548 std::string Name = VarName + "." + GetVectorAccessor(i); 549 genInitPrimitiveExportVariable(C, Name, Val); 550 } 551 break; 552 553 case APValue::Vector: 554 { 555 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new " << GetVectorTypeName(EVT) << "();" << endl; 556 557 unsigned NumElements = std::min(static_cast<unsigned>(EVT->getNumElement()), Val.getVectorLength()); 558 for(unsigned i=0;i<NumElements;i++) { 559 const APValue& ElementVal = Val.getVectorElt(i); 560 std::string Name = VarName + "." + GetVectorAccessor(i); 561 genInitPrimitiveExportVariable(C, Name, ElementVal); 562 } 563 } 564 break; 565 566 case APValue::Uninitialized: 567 case APValue::ComplexInt: 568 case APValue::ComplexFloat: 569 case APValue::LValue: 570 assert(false && "Unexpected type of value of initializer."); 571 break; 572 } 573 } 574 break; 575 576 /* TODO: Resolving initializer of a record type variable is complex. It cannot obtain by just simply evaluating the initializer expression. */ 577 case RSExportType::ExportClassRecord: 578 { 579 /* 580 unsigned InitIndex = 0; 581 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 582 583 assert((Val.getKind() == APValue::Vector) && "Unexpected type of initializer for record type variable"); 584 585 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "RS_TYPE_CLASS_NAME_PREFIX << ERT->getName() << "."RS_TYPE_ITEM_CLASS_NAME"();" << endl; 586 587 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin(); 588 I != ERT->fields_end(); 589 I++) 590 { 591 const RSExportRecordType::Field* F = *I; 592 std::string FieldName = VarName + "." + F->getName(); 593 594 if(InitIndex > Val.getVectorLength()) 595 break; 596 597 genInitPrimitiveExportVariable(C, FieldName, Val.getVectorElt(InitIndex++)); 598 } 599 */ 600 assert(false && "Unsupported initializer for record type variable currently"); 601 } 602 break; 603 604 default: 605 assert(false && "Unknown class of type"); 606 break; 607 } 608 return; 609} 610 611void RSReflection::genExportVariable(Context& C, const RSExportVar* EV) { 612 const RSExportType* ET = EV->getType(); 613 614 C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << " = " << C.getNextExportVarSlot() << ";" << endl; 615 616 switch(ET->getClass()) { 617 case RSExportType::ExportClassPrimitive: 618 case RSExportType::ExportClassConstantArray: 619 genPrimitiveTypeExportVariable(C, EV); 620 break; 621 622 case RSExportType::ExportClassPointer: 623 genPointerTypeExportVariable(C, EV); 624 break; 625 626 case RSExportType::ExportClassVector: 627 genVectorTypeExportVariable(C, EV); 628 break; 629 630 case RSExportType::ExportClassRecord: 631 genRecordTypeExportVariable(C, EV); 632 break; 633 634 default: 635 assert(false && "Unknown class of type"); 636 break; 637 } 638 639 return; 640} 641 642void RSReflection::genExportFunction(Context& C, const RSExportFunc* EF) { 643 C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << " = " << C.getNextExportFuncSlot() << ";" << endl; 644 645 /* invoke_*() */ 646 Context::ArgTy Args; 647 648 for(RSExportFunc::const_param_iterator I = EF->params_begin(); 649 I != EF->params_end(); 650 I++) 651 { 652 const RSExportFunc::Parameter* P = *I; 653 Args.push_back( make_pair(GetTypeName(P->getType()), P->getName()) ); 654 } 655 656 C.startFunction(Context::AM_Public, false, "void", "invoke_" + EF->getName(), Args); 657 658 if(!EF->hasParam()) { 659 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");" << endl; 660 } else { 661 const RSExportRecordType* ERT = EF->getParamPacketType(); 662 std::string FieldPackerName = EF->getName() + "_fp"; 663 664 if(genCreateFieldPacker(C, ERT, FieldPackerName.c_str())) 665 genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str()); 666 667 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", " << FieldPackerName << ");" << endl; 668 } 669 670 C.endFunction(); 671 return; 672} 673 674void RSReflection::genPrimitiveTypeExportVariable(Context& C, const RSExportVar* EV) { 675 assert(( EV->getType()->getClass() == RSExportType::ExportClassPrimitive || 676 EV->getType()->getClass() == RSExportType::ExportClassConstantArray 677 ) && "Variable should be type of primitive here"); 678 679 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(EV->getType()); 680 const char* TypeName = GetPrimitiveTypeName(EPT); 681 682 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 683 684 /* set_*() */ 685 if(!EV->isConst()) { 686 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName, "v"); 687 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 688 689 if(EPT->isRSObjectType()) 690 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", (v == null) ? 0 : v.getID());" << endl; 691 else 692 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", v);" << endl; 693 694 C.endFunction(); 695 } 696 697 genGetExportVariable(C, TypeName, EV->getName()); 698 699 return; 700} 701 702void RSReflection::genPointerTypeExportVariable(Context& C, const RSExportVar* EV) { 703 const RSExportType* ET = EV->getType(); 704 const RSExportType* PointeeType; 705 std::string TypeName; 706 707 assert((ET->getClass() == RSExportType::ExportClassPointer) && "Variable should be type of pointer here"); 708 709 PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 710 TypeName = GetTypeName(ET); 711 712 /* bind_*() */ 713 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 714 715 C.startFunction(Context::AM_Public, false, "void", "bind_" + EV->getName(), 1, TypeName.c_str(), "v"); 716 717 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 718 C.indent() << "if(v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl; 719 720 if(PointeeType->getClass() == RSExportType::ExportClassRecord) 721 C.indent() << "else bindAllocation(v.getAllocation(), "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl; 722 else 723 C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl; 724 725 C.endFunction(); 726 727 genGetExportVariable(C, TypeName, EV->getName()); 728 729 return; 730} 731 732void RSReflection::genVectorTypeExportVariable(Context& C, const RSExportVar* EV) { 733 assert((EV->getType()->getClass() == RSExportType::ExportClassVector) && "Variable should be type of vector here"); 734 735 const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(EV->getType()); 736 const char* TypeName = GetVectorTypeName(EVT); 737 const char* FieldPackerName = "fp"; 738 739 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 740 741 /* set_*() */ 742 if(!EV->isConst()) { 743 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName, "v"); 744 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 745 746 if(genCreateFieldPacker(C, EVT, FieldPackerName)) 747 genPackVarOfType(C, EVT, "v", FieldPackerName); 748 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " << FieldPackerName << ");" << endl; 749 750 C.endFunction(); 751 } 752 753 genGetExportVariable(C, TypeName, EV->getName()); 754 return; 755} 756 757void RSReflection::genRecordTypeExportVariable(Context& C, const RSExportVar* EV) { 758 assert((EV->getType()->getClass() == RSExportType::ExportClassRecord) && "Variable should be type of struct here"); 759 760 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(EV->getType()); 761 std::string TypeName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName() + "."RS_TYPE_ITEM_CLASS_NAME; 762 const char* FieldPackerName = "fp"; 763 764 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 765 766 /* set_*() */ 767 if(!EV->isConst()) { 768 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName.c_str(), "v"); 769 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 770 771 if(genCreateFieldPacker(C, ERT, FieldPackerName)) 772 genPackVarOfType(C, ERT, "v", FieldPackerName); 773 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " << FieldPackerName << ");" << endl; 774 775 C.endFunction(); 776 } 777 778 genGetExportVariable(C, TypeName.c_str(), EV->getName()); 779 return; 780} 781 782void RSReflection::genGetExportVariable(Context& C, const std::string& TypeName, const std::string& VarName) { 783 C.startFunction(Context::AM_Public, false, TypeName.c_str(), "get_" + VarName, 0); 784 785 C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << endl; 786 787 C.endFunction(); 788 return; 789} 790 791/****************************** Methods to generate script class /end ******************************/ 792 793bool RSReflection::genCreateFieldPacker(Context& C, const RSExportType* ET, const char* FieldPackerName) { 794 size_t AllocSize = RSExportType::GetTypeAllocSize(ET); 795 if(AllocSize > 0) 796 C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker(" << AllocSize << ");" << endl; 797 else 798 return false; 799 return true; 800} 801 802void RSReflection::genPackVarOfType(Context& C, const RSExportType* ET, const char* VarName, const char* FieldPackerName) { 803 switch(ET->getClass()) { 804 case RSExportType::ExportClassPrimitive: 805 case RSExportType::ExportClassVector: 806 C.indent() << FieldPackerName << "." << GetPackerAPIName(static_cast<const RSExportPrimitiveType*>(ET)) << "(" << VarName << ");" << endl; 807 break; 808 809 case RSExportType::ExportClassConstantArray: { 810 if (ET->getName().compare("addObj") == 0) { 811 C.indent() << FieldPackerName << "." << "addObj" << "(" << VarName << ");" << endl; 812 } else { 813 C.indent() << FieldPackerName << "." << GetPackerAPIName(static_cast<const RSExportPrimitiveType*>(ET)) << "(" << VarName << ");" << endl; 814 } 815 break; 816 } 817 818 case RSExportType::ExportClassPointer: 819 { 820 /* Must reflect as type Allocation in Java */ 821 const RSExportType* PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 822 823 if(PointeeType->getClass() != RSExportType::ExportClassRecord) 824 C.indent() << FieldPackerName << ".addI32(" << VarName << ".getPtr());" << endl; 825 else 826 C.indent() << FieldPackerName << ".addI32(" << VarName << ".getAllocation().getPtr());" << endl; 827 } 828 break; 829 830 case RSExportType::ExportClassRecord: 831 { 832 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 833 unsigned Pos = 0; /* relative pos from now on in field packer */ 834 835 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin(); 836 I != ERT->fields_end(); 837 I++) 838 { 839 const RSExportRecordType::Field* F = *I; 840 std::string FieldName; 841 size_t FieldOffset = F->getOffsetInParent(); 842 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 843 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 844 845 if(VarName != NULL) 846 FieldName = VarName + ("." + F->getName()); 847 else 848 FieldName = F->getName(); 849 850 if(FieldOffset > Pos) 851 C.indent() << FieldPackerName << ".skip(" << (FieldOffset - Pos) << ");" << endl; 852 853 genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName); 854 855 if(FieldAllocSize > FieldStoreSize) /* there's padding in the field type */ 856 C.indent() << FieldPackerName << ".skip(" << (FieldAllocSize - FieldStoreSize) << ");" << endl; 857 858 Pos = FieldOffset + FieldAllocSize; 859 } 860 861 /* There maybe some padding after the struct */ 862 size_t Padding = RSExportType::GetTypeAllocSize(ERT) - Pos; 863 if(Padding > 0) 864 C.indent() << FieldPackerName << ".skip(" << Padding << ");" << endl; 865 } 866 break; 867 868 default: 869 assert(false && "Unknown class of type"); 870 break; 871 } 872 873 return; 874} 875 876void RSReflection::genNewItemBufferIfNull(Context& C, const char* Index) { 877 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) " 878 RS_TYPE_ITEM_BUFFER_NAME" = new "RS_TYPE_ITEM_CLASS_NAME"[mType.getX() /* count */];" << endl; 879 if (Index != NULL) 880 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] == null) " 881 RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] = new "RS_TYPE_ITEM_CLASS_NAME"();" << endl; 882 return; 883} 884 885void RSReflection::genNewItemBufferPackerIfNull(Context& C) { 886 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_PACKER_NAME" == null) " 887 RS_TYPE_ITEM_BUFFER_PACKER_NAME" = new FieldPacker("RS_TYPE_ITEM_CLASS_NAME".sizeof * mType.getX() /* count */);" << endl; 888 return; 889} 890 891/****************************** Methods to generate type class ******************************/ 892bool RSReflection::genTypeClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg) { 893 std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName(); 894 895 /* Open the file */ 896 if (!openScriptFile(C, ClassName, ErrorMsg)) { 897 return false; 898 } 899 900 if(!C.startClass(Context::AM_Public, false, ClassName, RS_TYPE_CLASS_SUPER_CLASS_NAME, ErrorMsg)) 901 return false; 902 903 if(!genTypeItemClass(C, ERT, ErrorMsg)) 904 return false; 905 906 /* Declare item buffer and item buffer packer */ 907 C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[];" << endl; 908 C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";" << endl; 909 910 genTypeClassConstructor(C, ERT); 911 genTypeClassCopyToArray(C, ERT); 912 genTypeClassItemSetter(C, ERT); 913 genTypeClassItemGetter(C, ERT); 914 genTypeClassComponentSetter(C, ERT); 915 genTypeClassComponentGetter(C, ERT); 916 genTypeClassCopyAll(C, ERT); 917 918 C.endClass(); 919 920 return true; 921} 922 923bool RSReflection::genTypeItemClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg) { 924 C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME; 925 C.startBlock(); 926 927 C.indent() << "public static final int sizeof = " << RSExportType::GetTypeAllocSize(ERT) << ";" << endl; 928 929 /* Member elements */ 930 C.out() << endl; 931 for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin(); 932 FI != ERT->fields_end(); 933 FI++) { 934 C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName() << ";" << endl; 935 } 936 937 /* Constructor */ 938 C.out() << endl; 939 C.indent() << RS_TYPE_ITEM_CLASS_NAME"()"; 940 C.startBlock(); 941 942 for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin(); 943 FI != ERT->fields_end(); 944 FI++) 945 { 946 const RSExportRecordType::Field* F = *FI; 947 if( (F->getType()->getClass() == RSExportType::ExportClassVector) || 948 (F->getType()->getClass() == RSExportType::ExportClassRecord) || 949 (F->getType()->getClass() == RSExportType::ExportClassConstantArray) 950 ) { 951 C.indent() << F->getName() << " = new " << GetTypeName(F->getType()) << "();" << endl; 952 } 953 } 954 955 C.endBlock(); /* end Constructor */ 956 957 C.endBlock(); /* end Item class */ 958 959 960 return true; 961} 962 963void RSReflection::genTypeClassConstructor(Context& C, const RSExportRecordType* ERT) { 964 const char* RenderScriptVar = "rs"; 965 966 C.startFunction(Context::AM_Public, true, "Element", "createElement", 1, "RenderScript", RenderScriptVar); 967 genBuildElement(C, ERT, RenderScriptVar); 968 C.endFunction(); 969 970 C.startFunction(Context::AM_Public, false, NULL, C.getClassName(), 2, "RenderScript", RenderScriptVar, 971 "int", "count"); 972 973 C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << endl; 974 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << endl; 975 C.indent() << "mElement = createElement(" << RenderScriptVar << ");" << endl; 976 /* Call init() in super class */ 977 C.indent() << "init(" << RenderScriptVar << ", count);" << endl; 978 C.endFunction(); 979 980 return; 981} 982 983void RSReflection::genTypeClassCopyToArray(Context& C, const RSExportRecordType* ERT) { 984 C.startFunction(Context::AM_Private, false, "void", "copyToArray", 2, RS_TYPE_ITEM_CLASS_NAME, "i", 985 "int", "index"); 986 987 genNewItemBufferPackerIfNull(C); 988 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);" << endl; 989 990 genPackVarOfType(C, ERT, "i", RS_TYPE_ITEM_BUFFER_PACKER_NAME); 991 992 C.endFunction(); 993 return; 994} 995 996void RSReflection::genTypeClassItemSetter(Context& C, const RSExportRecordType* ERT) { 997 C.startFunction(Context::AM_Public, false, "void", "set", 3, RS_TYPE_ITEM_CLASS_NAME, "i", 998 "int", "index", 999 "boolean", "copyNow"); 1000 genNewItemBufferIfNull(C, NULL); 1001 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << endl; 1002 1003 C.indent() << "if (copyNow) "; 1004 C.startBlock(); 1005 1006 C.indent() << "copyToArray(i, index);" << endl; 1007 C.indent() << "mAllocation.subData1D(index, 1, "RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << endl; 1008 1009 C.endBlock(); /* end if (copyNow) */ 1010 1011 C.endFunction(); 1012 return; 1013} 1014 1015void RSReflection::genTypeClassItemGetter(Context& C, const RSExportRecordType* ERT) { 1016 C.startFunction(Context::AM_Public, false, RS_TYPE_ITEM_CLASS_NAME, "get", 1, "int", "index"); 1017 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return null;" << endl; 1018 C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index];" << endl; 1019 C.endFunction(); 1020 return; 1021} 1022void RSReflection::genTypeClassComponentSetter(Context& C, const RSExportRecordType* ERT) { 1023 for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin(); 1024 FI != ERT->fields_end(); 1025 FI++) 1026 { 1027 const RSExportRecordType::Field* F = *FI; 1028 size_t FieldOffset = F->getOffsetInParent(); 1029 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1030 unsigned FieldIndex = C.getFieldIndex(F); 1031 1032 C.startFunction(Context::AM_Public, false, "void", "set_" + F->getName(), 3, "int", "index", 1033 GetTypeName(F->getType()).c_str(), "v", 1034 "boolean", "copyNow"); 1035 genNewItemBufferPackerIfNull(C); 1036 genNewItemBufferIfNull(C, "index"); 1037 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName() << " = v;" << endl; 1038 1039 C.indent() << "if (copyNow) "; 1040 C.startBlock(); 1041 1042 if(FieldOffset > 0) 1043 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof + " << FieldOffset << ");" << endl; 1044 else 1045 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);" << endl; 1046 genPackVarOfType(C, F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME); 1047 1048 C.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize << ");" << endl; 1049 genPackVarOfType(C, F->getType(), "v", "fp"); 1050 C.indent() << "mAllocation.subElementData(index, " << 0/*FieldIndex*/ << ", fp);" << endl; 1051 1052 C.endBlock(); /* end if (copyNow) */ 1053 1054 C.endFunction(); 1055 } 1056 return; 1057} 1058 1059void RSReflection::genTypeClassComponentGetter(Context& C, const RSExportRecordType* ERT) { 1060 for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin(); 1061 FI != ERT->fields_end(); 1062 FI++) 1063 { 1064 const RSExportRecordType::Field* F = *FI; 1065 C.startFunction(Context::AM_Public, false, GetTypeName(F->getType()).c_str(), "get_" + F->getName(), 1, "int", "index"); 1066 //C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return null;" << endl; 1067 C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName() << ";" << endl; 1068 C.endFunction(); 1069 } 1070 return; 1071} 1072 1073void RSReflection::genTypeClassCopyAll(Context& C, const RSExportRecordType* ERT) { 1074 C.startFunction(Context::AM_Public, false, "void", "copyAll", 0); 1075 1076 C.indent() << "for (int ct=0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++) copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);" << endl; 1077 C.indent() << "mAllocation.data("RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << endl; 1078 1079 C.endFunction(); 1080 return; 1081} 1082 1083/****************************** Methods to generate type class /end ******************************/ 1084 1085/******************** Methods to create Element in Java of given record type ********************/ 1086void RSReflection::genBuildElement(Context& C, const RSExportRecordType* ERT, const char* RenderScriptVar) { 1087 const char* ElementBuilderName = "eb"; 1088 1089 /* Create element builder */ 1090 // C.startBlock(true); 1091 1092 C.indent() << "Element.Builder " << ElementBuilderName << " = new Element.Builder(" << RenderScriptVar << ");" << endl; 1093 1094 /* eb.add(...) */ 1095 genAddElementToElementBuilder(C, ERT, "", ElementBuilderName, RenderScriptVar); 1096 1097 C.indent() << "return " << ElementBuilderName << ".create();" << endl; 1098 1099 // C.endBlock(); 1100 return; 1101} 1102 1103#define EB_ADD(x) \ 1104 C.indent() << ElementBuilderName << ".add(Element." << x << ", \"" << VarName << "\");" << endl; \ 1105 C.incFieldIndex() 1106 1107void RSReflection::genAddElementToElementBuilder(Context& C, const RSExportType* ET, const std::string& VarName, const char* ElementBuilderName, const char* RenderScriptVar) { 1108 const char* ElementConstruct = GetBuiltinElementConstruct(ET); 1109 1110 if(ElementConstruct != NULL) { 1111 EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")"); 1112 } else { 1113 if ((ET->getClass() == RSExportType::ExportClassPrimitive) || 1114 (ET->getClass() == RSExportType::ExportClassVector) || 1115 (ET->getClass() == RSExportType::ExportClassConstantArray) 1116 ) { 1117 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET); 1118 const char* DataKindName = GetElementDataKindName(EPT->getKind()); 1119 const char* DataTypeName = GetElementDataTypeName(EPT->getType()); 1120 int Size = (ET->getClass() == RSExportType::ExportClassVector) ? static_cast<const RSExportVectorType*>(ET)->getNumElement() : 1; 1121 1122 switch(EPT->getKind()) { 1123 case RSExportPrimitiveType::DataKindColor: 1124 case RSExportPrimitiveType::DataKindPosition: 1125 case RSExportPrimitiveType::DataKindTexture: 1126 case RSExportPrimitiveType::DataKindNormal: 1127 case RSExportPrimitiveType::DataKindPointSize: 1128 /* Element.createAttrib() */ 1129 EB_ADD("createAttrib(" << RenderScriptVar << ", " << DataTypeName << ", " << DataKindName << ", " << Size << ")"); 1130 break; 1131 1132 case RSExportPrimitiveType::DataKindIndex: 1133 /* Element.createIndex() */ 1134 EB_ADD("createAttrib(" << RenderScriptVar << ")"); 1135 break; 1136 1137 case RSExportPrimitiveType::DataKindPixelL: 1138 case RSExportPrimitiveType::DataKindPixelA: 1139 case RSExportPrimitiveType::DataKindPixelLA: 1140 case RSExportPrimitiveType::DataKindPixelRGB: 1141 case RSExportPrimitiveType::DataKindPixelRGBA: 1142 /* Element.createPixel() */ 1143 EB_ADD("createVector(" << RenderScriptVar << ", " << DataTypeName << ", " << DataKindName << ")"); 1144 break; 1145 1146 case RSExportPrimitiveType::DataKindUser: 1147 default: 1148 if (EPT->getClass() == RSExportType::ExportClassPrimitive || EPT->getClass() == RSExportType::ExportClassConstantArray) { 1149 /* Element.createUser() */ 1150 EB_ADD("createUser(" << RenderScriptVar << ", " << DataTypeName << ")"); 1151 } else { /* (ET->getClass() == RSExportType::ExportClassVector) must hold here */ 1152 /* Element.createVector() */ 1153 EB_ADD("createVector(" << RenderScriptVar << ", " << DataTypeName << ", " << Size << ")"); 1154 } 1155 break; 1156 } 1157 } else if(ET->getClass() == RSExportType::ExportClassPointer) { 1158 /* Pointer type variable should be resolved in GetBuiltinElementConstruct() */ 1159 assert(false && "??"); 1160 } else if(ET->getClass() == RSExportType::ExportClassRecord) { 1161 /* 1162 * Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType. 1163 * TODO: Generalize these two function such that there's no duplicated codes. 1164 */ 1165 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 1166 int Pos = 0; /* relative pos from now on */ 1167 1168 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin(); 1169 I != ERT->fields_end(); 1170 I++) 1171 { 1172 const RSExportRecordType::Field* F = *I; 1173 std::string FieldName; 1174 size_t FieldOffset = F->getOffsetInParent(); 1175 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1176 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 1177 1178 if(!VarName.empty()) 1179 FieldName = VarName + "." + F->getName(); 1180 else 1181 FieldName = F->getName(); 1182 1183 /* alignment */ 1184 genAddPaddingToElementBuiler(C, (FieldOffset - Pos), ElementBuilderName, RenderScriptVar); 1185 1186 /* eb.add(...) */ 1187 C.addFieldIndexMapping(F); 1188 genAddElementToElementBuilder(C, F->getType(), FieldName, ElementBuilderName, RenderScriptVar); 1189 1190 /* There is padding within the field type */ 1191 genAddPaddingToElementBuiler(C, (FieldAllocSize - FieldStoreSize), ElementBuilderName, RenderScriptVar); 1192 1193 Pos = FieldOffset + FieldAllocSize; 1194 } 1195 1196 /* There maybe some padding after the struct */ 1197 //unsigned char align = RSExportType::GetTypeAlignment(ERT); 1198 //size_t siz = RSExportType::GetTypeAllocSize(ERT); 1199 size_t siz1 = RSExportType::GetTypeStoreSize(ERT); 1200 1201 genAddPaddingToElementBuiler(C, siz1 - Pos, ElementBuilderName, RenderScriptVar); 1202 } else { 1203 assert(false && "Unknown class of type"); 1204 } 1205 } 1206} 1207 1208void RSReflection::genAddPaddingToElementBuiler(Context& C, size_t PaddingSize, const char* ElementBuilderName, const char* RenderScriptVar) { 1209 while(PaddingSize > 0) { 1210 const std::string& VarName = C.createPaddingField(); 1211 if(PaddingSize >= 4) { 1212 EB_ADD("U32(" << RenderScriptVar << ")"); 1213 PaddingSize -= 4; 1214 } else if(PaddingSize >= 2) { 1215 EB_ADD("U16(" << RenderScriptVar << ")"); 1216 PaddingSize -= 2; 1217 } else if(PaddingSize >= 1) { 1218 EB_ADD("U8(" << RenderScriptVar << ")"); 1219 PaddingSize -= 1; 1220 } 1221 } 1222 return; 1223} 1224 1225#undef EB_ADD 1226/******************** Methods to create Element in Java of given record type /end ********************/ 1227 1228bool RSReflection::reflect(const char* OutputPackageName, const std::string& InputFileName, const std::string& OutputBCFileName) { 1229 Context *C = NULL; 1230 std::string ResourceId = ""; 1231 1232 if(!GetClassNameFromFileName(OutputBCFileName, ResourceId)) 1233 return false; 1234 1235 if(ResourceId.empty()) 1236 ResourceId = "<Resource ID>"; 1237 1238 if((OutputPackageName == NULL) || (*OutputPackageName == '\0') || strcmp(OutputPackageName, "-") == 0) 1239 C = new Context(InputFileName, "<Package Name>", ResourceId, true); 1240 else 1241 C = new Context(InputFileName, OutputPackageName, ResourceId, false); 1242 1243 if(C != NULL) { 1244 std::string ErrorMsg, ScriptClassName; 1245 /* class ScriptC_<ScriptName> */ 1246 if(!GetClassNameFromFileName(InputFileName, ScriptClassName)) 1247 return false; 1248 1249 if(ScriptClassName.empty()) 1250 ScriptClassName = "<Input Script Name>"; 1251 1252 ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX); 1253 1254 if (mRSContext->getLicenseNote() != NULL) { 1255 C->setLicenseNote(*(mRSContext->getLicenseNote())); 1256 } 1257 1258 if(!genScriptClass(*C, ScriptClassName, ErrorMsg)) { 1259 std::cerr << "Failed to generate class " << ScriptClassName << " (" << ErrorMsg << ")" << endl; 1260 return false; 1261 } 1262 1263 /* class ScriptField_<TypeName> */ 1264 for(RSContext::const_export_type_iterator TI = mRSContext->export_types_begin(); 1265 TI != mRSContext->export_types_end(); 1266 TI++) 1267 { 1268 const RSExportType* ET = TI->getValue(); 1269 1270 if(ET->getClass() == RSExportType::ExportClassRecord) { 1271 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 1272 1273 if(!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) { 1274 std::cerr << "Failed to generate type class for struct '" << ERT->getName() << "' (" << ErrorMsg << ")" << endl; 1275 return false; 1276 } 1277 } 1278 } 1279 } 1280 1281 return true; 1282} 1283 1284/****************************** RSReflection::Context ******************************/ 1285const char* const RSReflection::Context::ApacheLicenseNote = 1286 "/*\n" 1287 " * Copyright (C) 2010 The Android Open Source Project\n" 1288 " *\n" 1289 " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" 1290 " * you may not use this file except in compliance with the License.\n" 1291 " * You may obtain a copy of the License at\n" 1292 " *\n" 1293 " * http://www.apache.org/licenses/LICENSE-2.0\n" 1294 " *\n" 1295 " * Unless required by applicable law or agreed to in writing, software\n" 1296 " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" 1297 " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" 1298 " * See the License for the specific language governing permissions and\n" 1299 " * limitations under the License.\n" 1300 " */\n" 1301 "\n"; 1302 1303const char* const RSReflection::Context::Import[] = { 1304 /* RenderScript java class */ 1305 "android.renderscript.*", 1306 /* Import R */ 1307 "android.content.res.Resources", 1308 /* Import for debugging */ 1309 "android.util.Log", 1310}; 1311 1312const char* RSReflection::Context::AccessModifierStr(AccessModifier AM) { 1313 switch(AM) { 1314 case AM_Public: return "public"; break; 1315 case AM_Protected: return "protected"; break; 1316 case AM_Private: return "private"; break; 1317 default: return ""; break; 1318 } 1319} 1320 1321bool RSReflection::Context::startClass(AccessModifier AM, bool IsStatic, const std::string& ClassName, const char* SuperClassName, std::string& ErrorMsg) { 1322 if(mVerbose) 1323 std::cout << "Generating " << ClassName << ".java ..." << endl; 1324 1325 /* License */ 1326 out() << mLicenseNote; 1327 1328 /* Notice of generated file */ 1329 out() << "/*" << endl; 1330 out() << " * This file is auto-generated. DO NOT MODIFY!" << endl; 1331 out() << " * The source RenderScript file: " << mInputRSFile << endl; 1332 out() << " */" << endl; 1333 1334 /* Package */ 1335 if(!mPackageName.empty()) 1336 out() << "package " << mPackageName << ";" << endl; 1337 out() << endl; 1338 1339 /* Imports */ 1340 for(unsigned i=0;i<(sizeof(Import)/sizeof(const char*));i++) 1341 out() << "import " << Import[i] << ";" << endl; 1342 out() << endl; 1343 1344 /* All reflected classes should be annotated as hidden, so that they won't be exposed in SDK. */ 1345 out() << "/**" << endl; 1346 out() << " * @hide" << endl; 1347 out() << " */" << endl; 1348 1349 out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class " << ClassName; 1350 if(SuperClassName != NULL) 1351 out() << " extends " << SuperClassName; 1352 1353 startBlock(); 1354 1355 mClassName = ClassName; 1356 1357 return true; 1358} 1359 1360void RSReflection::Context::endClass() { 1361 endBlock(); 1362 if(!mUseStdout) 1363 mOF.close(); 1364 clear(); 1365 return; 1366} 1367 1368void RSReflection::Context::startBlock(bool ShouldIndent) { 1369 if(ShouldIndent) 1370 indent() << "{" << endl; 1371 else 1372 out() << " {" << endl; 1373 incIndentLevel(); 1374 return; 1375} 1376 1377void RSReflection::Context::endBlock() { 1378 decIndentLevel(); 1379 indent() << "}" << endl << endl; 1380 return; 1381} 1382 1383void RSReflection::Context::startTypeClass(const std::string& ClassName) { 1384 indent() << "public static class " << ClassName; 1385 startBlock(); 1386 return; 1387} 1388 1389void RSReflection::Context::endTypeClass() { 1390 endBlock(); 1391 return; 1392} 1393 1394void RSReflection::Context::startFunction(AccessModifier AM, bool IsStatic, const char* ReturnType, const std::string& FunctionName, int Argc, ...) { 1395 ArgTy Args; 1396 va_list vl; 1397 va_start(vl, Argc); 1398 1399 for(int i=0;i<Argc;i++) { 1400 const char* ArgType = va_arg(vl, const char*); 1401 const char* ArgName = va_arg(vl, const char*); 1402 1403 Args.push_back( make_pair(ArgType, ArgName) ); 1404 } 1405 va_end(vl); 1406 1407 startFunction(AM, IsStatic, ReturnType, FunctionName, Args); 1408 1409 return; 1410} 1411 1412void RSReflection::Context::startFunction(AccessModifier AM, 1413 bool IsStatic, 1414 const char* ReturnType, 1415 const std::string& FunctionName, 1416 const ArgTy& Args) 1417{ 1418 indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ") << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "("; 1419 1420 bool FirstArg = true; 1421 for(ArgTy::const_iterator I = Args.begin(); 1422 I != Args.end(); 1423 I++) 1424 { 1425 if(!FirstArg) 1426 out() << ", "; 1427 else 1428 FirstArg = false; 1429 1430 out() << I->first << " " << I->second; 1431 } 1432 1433 out() << ")"; 1434 startBlock(); 1435 1436 return; 1437} 1438 1439void RSReflection::Context::endFunction() { 1440 endBlock(); 1441 return; 1442} 1443 1444} /* namespace slang */ 1445