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