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