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