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