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