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