slang_rs_reflection.cpp revision 68e8e9f98730b3672fb96d49e33b9db70a90ed3f
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 std::string prefix = mRSContext->getReflectJavaPathName(); 432 if (prefix.empty()) { 433 _path.insert(0, 1, '.'); 434 } else { 435 _path.insert(0, mRSContext->getReflectJavaPathName()); 436 } 437 438 _mkdir(_path); 439 C.mOF.open(( _path + "/" + ClassName + ".java" ).c_str()); 440 if(!C.mOF.good()) { 441 ErrorMsg = "failed to open file '" + _path + "/" + ClassName + ".java' for write"; 442 443 return false; 444 } 445 } 446 return true; 447} 448 449/****************************** Methods to generate script class ******************************/ 450bool RSReflection::genScriptClass(Context& C, const std::string& ClassName, std::string& ErrorMsg) { 451 /* Open the file */ 452 if (!openScriptFile(C, ClassName, ErrorMsg)) { 453 return false; 454 } 455 456 if(!C.startClass(Context::AM_Public, false, ClassName, RS_SCRIPT_CLASS_SUPER_CLASS_NAME, ErrorMsg)) 457 return false; 458 459 genScriptClassConstructor(C); 460 461 /* Reflect export variable */ 462 for(RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(); 463 I != mRSContext->export_vars_end(); 464 I++) 465 genExportVariable(C, *I); 466 467 /* Reflect export function */ 468 for(RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(); 469 I != mRSContext->export_funcs_end(); 470 I++) 471 genExportFunction(C, *I); 472 473 C.endClass(); 474 475 return true; 476} 477 478void RSReflection::genScriptClassConstructor(Context& C) { 479 C.indent() << "// Constructor" << endl; 480 C.startFunction(Context::AM_Public, false, NULL, C.getClassName(), 4, "RenderScript", "rs", 481 "Resources", "resources", 482 "int", "id", 483 "boolean", "isRoot"); 484 /* Call constructor of super class */ 485 C.indent() << "super(rs, resources, id, isRoot);" << endl; 486 487 /* If an exported variable has initial value, reflect it */ 488 489 for(RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(); 490 I != mRSContext->export_vars_end(); 491 I++) 492 { 493 const RSExportVar* EV = *I; 494 if(!EV->getInit().isUninit()) 495 genInitExportVariable(C, EV->getType(), EV->getName(), EV->getInit()); 496 } 497 498 C.endFunction(); 499 return; 500} 501 502void RSReflection::genInitBoolExportVariable(Context& C, const std::string& VarName, const APValue& Val) { 503 assert(!Val.isUninit() && "Not a valid initializer"); 504 505 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = "; 506 assert((Val.getKind() == APValue::Int) && "Bool type has wrong initial APValue"); 507 508 if (Val.getInt().getSExtValue() == 0) { 509 C.out() << "false"; 510 } else { 511 C.out() << "true"; 512 } 513 C.out() << ";" << endl; 514 515 return; 516} 517 518void RSReflection::genInitPrimitiveExportVariable(Context& C, const std::string& VarName, const APValue& Val) { 519 assert(!Val.isUninit() && "Not a valid initializer"); 520 521 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = "; 522 switch(Val.getKind()) { 523 case APValue::Int: C.out() << Val.getInt().getSExtValue(); break; 524 case APValue::Float: C.out() << Val.getFloat().convertToDouble(); break; 525 526 case APValue::ComplexInt: 527 case APValue::ComplexFloat: 528 case APValue::LValue: 529 case 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 break; 536 } 537 C.out() << ";" << endl; 538 539 return; 540} 541 542void RSReflection::genInitExportVariable(Context& C, const RSExportType* ET, const std::string& VarName, const APValue& Val) { 543 assert(!Val.isUninit() && "Not a valid initializer"); 544 545 switch(ET->getClass()) { 546 case RSExportType::ExportClassPrimitive: { 547 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET); 548 if (EPT->getType() == RSExportPrimitiveType::DataTypeBool) { 549 genInitBoolExportVariable(C, VarName, Val); 550 } else { 551 genInitPrimitiveExportVariable(C, VarName, Val); 552 } 553 break; 554 } 555 556 case RSExportType::ExportClassPointer: 557 if(!Val.isInt() || Val.getInt().getSExtValue() != 0) 558 std::cout << "Initializer which is non-NULL to pointer type variable will be ignored" << endl; 559 break; 560 561 case RSExportType::ExportClassVector: 562 { 563 const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(ET); 564 switch(Val.getKind()) { 565 case APValue::Int: 566 case APValue::Float: 567 for(int i=0;i<EVT->getNumElement();i++) { 568 std::string Name = VarName + "." + GetVectorAccessor(i); 569 genInitPrimitiveExportVariable(C, Name, Val); 570 } 571 break; 572 573 case APValue::Vector: 574 { 575 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new " << GetVectorTypeName(EVT) << "();" << endl; 576 577 unsigned NumElements = std::min(static_cast<unsigned>(EVT->getNumElement()), Val.getVectorLength()); 578 for(unsigned i=0;i<NumElements;i++) { 579 const APValue& ElementVal = Val.getVectorElt(i); 580 std::string Name = VarName + "." + GetVectorAccessor(i); 581 genInitPrimitiveExportVariable(C, Name, ElementVal); 582 } 583 } 584 break; 585 } 586 } 587 break; 588 589 /* TODO: Resolving initializer of a record type variable is complex. It cannot obtain by just simply evaluating the initializer expression. */ 590 case RSExportType::ExportClassRecord: 591 { 592 /* 593 unsigned InitIndex = 0; 594 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 595 596 assert((Val.getKind() == APValue::Vector) && "Unexpected type of initializer for record type variable"); 597 598 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "RS_TYPE_CLASS_NAME_PREFIX << ERT->getName() << "."RS_TYPE_ITEM_CLASS_NAME"();" << endl; 599 600 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin(); 601 I != ERT->fields_end(); 602 I++) 603 { 604 const RSExportRecordType::Field* F = *I; 605 std::string FieldName = VarName + "." + F->getName(); 606 607 if(InitIndex > Val.getVectorLength()) 608 break; 609 610 genInitPrimitiveExportVariable(C, FieldName, Val.getVectorElt(InitIndex++)); 611 } 612 */ 613 assert(false && "Unsupported initializer for record type variable currently"); 614 } 615 break; 616 617 default: 618 assert(false && "Unknown class of type"); 619 break; 620 } 621 return; 622} 623 624void RSReflection::genExportVariable(Context& C, const RSExportVar* EV) { 625 const RSExportType* ET = EV->getType(); 626 627 C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << " = " << C.getNextExportVarSlot() << ";" << endl; 628 629 switch(ET->getClass()) { 630 case RSExportType::ExportClassPrimitive: 631 genPrimitiveTypeExportVariable(C, EV); 632 break; 633 634 case RSExportType::ExportClassPointer: 635 genPointerTypeExportVariable(C, EV); 636 break; 637 638 case RSExportType::ExportClassVector: 639 genVectorTypeExportVariable(C, EV); 640 break; 641 642 case RSExportType::ExportClassRecord: 643 genRecordTypeExportVariable(C, EV); 644 break; 645 646 default: 647 assert(false && "Unknown class of type"); 648 break; 649 } 650 651 return; 652} 653 654void RSReflection::genExportFunction(Context& C, const RSExportFunc* EF) { 655 C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << " = " << C.getNextExportFuncSlot() << ";" << endl; 656 657 /* invoke_*() */ 658 Context::ArgTy Args; 659 660 for(RSExportFunc::const_param_iterator I = EF->params_begin(); 661 I != EF->params_end(); 662 I++) 663 { 664 const RSExportFunc::Parameter* P = *I; 665 Args.push_back( make_pair(GetTypeName(P->getType()), P->getName()) ); 666 } 667 668 C.startFunction(Context::AM_Public, false, "void", "invoke_" + EF->getName(), Args); 669 670 if(!EF->hasParam()) { 671 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");" << endl; 672 } else { 673 const RSExportRecordType* ERT = EF->getParamPacketType(); 674 std::string FieldPackerName = EF->getName() + "_fp"; 675 676 if(genCreateFieldPacker(C, ERT, FieldPackerName.c_str())) 677 genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str()); 678 679 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", " << FieldPackerName << ");" << endl; 680 } 681 682 C.endFunction(); 683 return; 684} 685 686void RSReflection::genPrimitiveTypeExportVariable(Context& C, const RSExportVar* EV) { 687 assert((EV->getType()->getClass() == RSExportType::ExportClassPrimitive) && "Variable should be type of primitive here"); 688 689 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(EV->getType()); 690 const char* TypeName = GetPrimitiveTypeName(EPT); 691 692 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 693 694 /* set_*() */ 695 if(!EV->isConst()) { 696 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName, "v"); 697 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 698 699 if(EPT->isRSObjectType()) 700 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", (v == null) ? 0 : v.getID());" << endl; 701 else 702 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", v);" << endl; 703 704 C.endFunction(); 705 } 706 707 genGetExportVariable(C, TypeName, EV->getName()); 708 709 return; 710} 711 712void RSReflection::genPointerTypeExportVariable(Context& C, const RSExportVar* EV) { 713 const RSExportType* ET = EV->getType(); 714 const RSExportType* PointeeType; 715 std::string TypeName; 716 717 assert((ET->getClass() == RSExportType::ExportClassPointer) && "Variable should be type of pointer here"); 718 719 PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 720 TypeName = GetTypeName(ET); 721 722 /* bind_*() */ 723 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 724 725 C.startFunction(Context::AM_Public, false, "void", "bind_" + EV->getName(), 1, TypeName.c_str(), "v"); 726 727 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 728 C.indent() << "if(v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl; 729 730 if(PointeeType->getClass() == RSExportType::ExportClassRecord) 731 C.indent() << "else bindAllocation(v.getAllocation(), "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl; 732 else 733 C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl; 734 735 C.endFunction(); 736 737 genGetExportVariable(C, TypeName, EV->getName()); 738 739 return; 740} 741 742void RSReflection::genVectorTypeExportVariable(Context& C, const RSExportVar* EV) { 743 assert((EV->getType()->getClass() == RSExportType::ExportClassVector) && "Variable should be type of vector here"); 744 745 const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(EV->getType()); 746 const char* TypeName = GetVectorTypeName(EVT); 747 const char* FieldPackerName = "fp"; 748 749 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 750 751 /* set_*() */ 752 if(!EV->isConst()) { 753 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName, "v"); 754 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 755 756 if(genCreateFieldPacker(C, EVT, FieldPackerName)) 757 genPackVarOfType(C, EVT, "v", FieldPackerName); 758 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " << FieldPackerName << ");" << endl; 759 760 C.endFunction(); 761 } 762 763 genGetExportVariable(C, TypeName, EV->getName()); 764 return; 765} 766 767void RSReflection::genRecordTypeExportVariable(Context& C, const RSExportVar* EV) { 768 assert((EV->getType()->getClass() == RSExportType::ExportClassRecord) && "Variable should be type of struct here"); 769 770 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(EV->getType()); 771 std::string TypeName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName() + "."RS_TYPE_ITEM_CLASS_NAME; 772 const char* FieldPackerName = "fp"; 773 774 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 775 776 /* set_*() */ 777 if(!EV->isConst()) { 778 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName.c_str(), "v"); 779 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 780 781 if(genCreateFieldPacker(C, ERT, FieldPackerName)) 782 genPackVarOfType(C, ERT, "v", FieldPackerName); 783 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " << FieldPackerName << ");" << endl; 784 785 C.endFunction(); 786 } 787 788 genGetExportVariable(C, TypeName.c_str(), EV->getName()); 789 return; 790} 791 792void RSReflection::genGetExportVariable(Context& C, const std::string& TypeName, const std::string& VarName) { 793 C.startFunction(Context::AM_Public, false, TypeName.c_str(), "get_" + VarName, 0); 794 795 C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << endl; 796 797 C.endFunction(); 798 return; 799} 800 801/****************************** Methods to generate script class /end ******************************/ 802 803bool RSReflection::genCreateFieldPacker(Context& C, const RSExportType* ET, const char* FieldPackerName) { 804 size_t AllocSize = RSExportType::GetTypeAllocSize(ET); 805 if(AllocSize > 0) 806 C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker(" << AllocSize << ");" << endl; 807 else 808 return false; 809 return true; 810} 811 812void RSReflection::genPackVarOfType(Context& C, const RSExportType* ET, const char* VarName, const char* FieldPackerName) { 813 switch(ET->getClass()) { 814 case RSExportType::ExportClassPrimitive: 815 case RSExportType::ExportClassVector: 816 C.indent() << FieldPackerName << "." << GetPackerAPIName(static_cast<const RSExportPrimitiveType*>(ET)) << "(" << VarName << ");" << endl; 817 break; 818 819 case RSExportType::ExportClassPointer: 820 { 821 /* Must reflect as type Allocation in Java */ 822 const RSExportType* PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 823 824 if(PointeeType->getClass() != RSExportType::ExportClassRecord) 825 C.indent() << FieldPackerName << ".addI32(" << VarName << ".getPtr());" << endl; 826 else 827 C.indent() << FieldPackerName << ".addI32(" << VarName << ".getAllocation().getPtr());" << endl; 828 } 829 break; 830 831 case RSExportType::ExportClassRecord: 832 { 833 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 834 int Pos = 0; /* relative pos from now on in field packer */ 835 836 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin(); 837 I != ERT->fields_end(); 838 I++) 839 { 840 const RSExportRecordType::Field* F = *I; 841 std::string FieldName; 842 size_t FieldOffset = F->getOffsetInParent(); 843 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 844 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 845 846 if(VarName != NULL) 847 FieldName = VarName + ("." + F->getName()); 848 else 849 FieldName = F->getName(); 850 851 if(FieldOffset > Pos) 852 C.indent() << FieldPackerName << ".skip(" << (FieldOffset - Pos) << ");" << endl; 853 854 genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName); 855 856 if(FieldAllocSize > FieldStoreSize) /* there's padding in the field type */ 857 C.indent() << FieldPackerName << ".skip(" << (FieldAllocSize - FieldStoreSize) << ");" << endl; 858 859 Pos = FieldOffset + FieldAllocSize; 860 } 861 862 /* There maybe some padding after the struct */ 863 size_t Padding = RSExportType::GetTypeAllocSize(ERT) - Pos; 864 if(Padding > 0) 865 C.indent() << FieldPackerName << ".skip(" << Padding << ");" << endl; 866 } 867 break; 868 869 default: 870 assert(false && "Unknown class of type"); 871 break; 872 } 873 874 return; 875} 876 877/****************************** Methods to generate type class ******************************/ 878bool RSReflection::genTypeClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg) { 879 std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName(); 880 881 /* Open the file */ 882 if (!openScriptFile(C, ClassName, ErrorMsg)) { 883 return false; 884 } 885 886 if(!C.startClass(Context::AM_Public, false, ClassName, RS_TYPE_CLASS_SUPER_CLASS_NAME, ErrorMsg)) 887 return false; 888 889 if(!genTypeItemClass(C, ERT, ErrorMsg)) 890 return false; 891 892 /* Declare item buffer and item buffer packer */ 893 C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[];" << endl; 894 C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";" << endl; 895 896 genTypeClassConstructor(C, ERT); 897 genTypeClassCopyToArray(C, ERT); 898 genTypeClasSet(C, ERT); 899 genTypeClasCopyAll(C, ERT); 900 901 C.endClass(); 902 903 return true; 904} 905 906bool RSReflection::genTypeItemClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg) { 907 C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME; 908 C.startBlock(); 909 910 C.indent() << "public static final int sizeof = " << RSExportType::GetTypeAllocSize(ERT) << ";" << endl; 911 912 /* Member elements */ 913 C.out() << endl; 914 for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin(); 915 FI != ERT->fields_end(); 916 FI++) 917 C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName() << ";" << endl; 918 919 /* Constructor */ 920 C.out() << endl; 921 C.indent() << RS_TYPE_ITEM_CLASS_NAME"()"; 922 C.startBlock(); 923 924 for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin(); 925 FI != ERT->fields_end(); 926 FI++) 927 { 928 const RSExportRecordType::Field* F = *FI; 929 if((F->getType()->getClass() == RSExportType::ExportClassVector) || (F->getType()->getClass() == RSExportType::ExportClassRecord)) 930 C.indent() << F->getName() << " = new " << GetTypeName(F->getType()) << "();" << endl; 931 } 932 933 C.endBlock(); /* end Constructor */ 934 935 C.endBlock(); /* end Item class */ 936 937 938 return true; 939} 940 941void RSReflection::genTypeClassConstructor(Context& C, const RSExportRecordType* ERT) { 942 const char* RenderScriptVar = "rs"; 943 944 C.startFunction(Context::AM_Public, true, "Element", "createElement", 1, "RenderScript", RenderScriptVar); 945 genBuildElement(C, ERT, RenderScriptVar); 946 C.endFunction(); 947 948 C.startFunction(Context::AM_Public, false, NULL, C.getClassName(), 2, "RenderScript", RenderScriptVar, 949 "int", "count"); 950 951 C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << endl; 952 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << endl; 953 C.indent() << "mElement = createElement(" << RenderScriptVar << ");" << endl; 954 /* Call init() in super class */ 955 C.indent() << "init(" << RenderScriptVar << ", count);" << endl; 956 C.endFunction(); 957 958 return; 959} 960 961void RSReflection::genTypeClassCopyToArray(Context& C, const RSExportRecordType* ERT) { 962 C.startFunction(Context::AM_Private, false, "void", "copyToArray", 2, RS_TYPE_ITEM_CLASS_NAME, "i", 963 "int", "index"); 964 965 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; 966 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);" << endl; 967 968 genPackVarOfType(C, ERT, "i", RS_TYPE_ITEM_BUFFER_PACKER_NAME); 969 970 C.endFunction(); 971 return; 972} 973 974void RSReflection::genTypeClasSet(Context& C, const RSExportRecordType* ERT) { 975 C.startFunction(Context::AM_Public, false, "void", "set", 3, RS_TYPE_ITEM_CLASS_NAME, "i", 976 "int", "index", 977 "boolean", "copyNow"); 978 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) "RS_TYPE_ITEM_BUFFER_NAME" = new "RS_TYPE_ITEM_CLASS_NAME"[mType.getX() /* count */];" << endl; 979 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << endl; 980 981 C.indent() << "if (copyNow) "; 982 C.startBlock(); 983 984 C.indent() << "copyToArray(i, index);" << endl; 985 //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; 986 C.indent() << "mAllocation.subData1D(index, 1, "RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << endl; 987 988 C.endBlock(); /* end if (copyNow) */ 989 990 C.endFunction(); 991 return; 992} 993 994void RSReflection::genTypeClasCopyAll(Context& C, const RSExportRecordType* ERT) { 995 C.startFunction(Context::AM_Public, false, "void", "copyAll", 0); 996 997 C.indent() << "for (int ct=0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++) copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);" << endl; 998 C.indent() << "mAllocation.data("RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << endl; 999 1000 C.endFunction(); 1001 return; 1002} 1003 1004/****************************** Methods to generate type class /end ******************************/ 1005 1006/******************** Methods to create Element in Java of given record type ********************/ 1007void RSReflection::genBuildElement(Context& C, const RSExportRecordType* ERT, const char* RenderScriptVar) { 1008 const char* ElementBuilderName = "eb"; 1009 1010 /* Create element builder */ 1011 // C.startBlock(true); 1012 1013 C.indent() << "Element.Builder " << ElementBuilderName << " = new Element.Builder(" << RenderScriptVar << ");" << endl; 1014 1015 /* eb.add(...) */ 1016 genAddElementToElementBuilder(C, ERT, "", ElementBuilderName, RenderScriptVar); 1017 1018 C.indent() << "return " << ElementBuilderName << ".create();" << endl; 1019 1020 // C.endBlock(); 1021 return; 1022} 1023 1024#define EB_ADD(x, ...) \ 1025 C.indent() << ElementBuilderName << ".add(Element." << x ##__VA_ARGS__ ", \"" << VarName << "\");" << endl 1026 1027void RSReflection::genAddElementToElementBuilder(Context& C, const RSExportType* ET, const std::string& VarName, const char* ElementBuilderName, const char* RenderScriptVar) { 1028 const char* ElementConstruct = GetBuiltinElementConstruct(ET); 1029 1030 if(ElementConstruct != NULL) { 1031 EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")"); 1032 } else { 1033 if((ET->getClass() == RSExportType::ExportClassPrimitive) || (ET->getClass() == RSExportType::ExportClassVector)) { 1034 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET); 1035 const char* DataKindName = GetElementDataKindName(EPT->getKind()); 1036 const char* DataTypeName = GetElementDataTypeName(EPT->getType()); 1037 int Size = (ET->getClass() == RSExportType::ExportClassVector) ? static_cast<const RSExportVectorType*>(ET)->getNumElement() : 1; 1038 1039 switch(EPT->getKind()) { 1040 case RSExportPrimitiveType::DataKindColor: 1041 case RSExportPrimitiveType::DataKindPosition: 1042 case RSExportPrimitiveType::DataKindTexture: 1043 case RSExportPrimitiveType::DataKindNormal: 1044 case RSExportPrimitiveType::DataKindPointSize: 1045 /* Element.createAttrib() */ 1046 EB_ADD("createAttrib(" << RenderScriptVar << ", " << DataTypeName << ", " << DataKindName << ", " << Size << ")"); 1047 break; 1048 1049 case RSExportPrimitiveType::DataKindIndex: 1050 /* Element.createIndex() */ 1051 EB_ADD("createAttrib(" << RenderScriptVar << ")"); 1052 break; 1053 1054 case RSExportPrimitiveType::DataKindPixelL: 1055 case RSExportPrimitiveType::DataKindPixelA: 1056 case RSExportPrimitiveType::DataKindPixelLA: 1057 case RSExportPrimitiveType::DataKindPixelRGB: 1058 case RSExportPrimitiveType::DataKindPixelRGBA: 1059 /* Element.createPixel() */ 1060 EB_ADD("createVector(" << RenderScriptVar << ", " << DataTypeName << ", " << DataKindName << ")"); 1061 break; 1062 1063 case RSExportPrimitiveType::DataKindUser: 1064 default: 1065 if(EPT->getClass() == RSExportType::ExportClassPrimitive) 1066 /* Element.createUser() */ 1067 EB_ADD("createUser(" << RenderScriptVar << ", " << DataTypeName << ")"); 1068 else /* (ET->getClass() == RSExportType::ExportClassVector) must hold here */ 1069 /* Element.createVector() */ 1070 EB_ADD("createVector(" << RenderScriptVar << ", " << DataTypeName << ", " << Size << ")"); 1071 break; 1072 } 1073 } else if(ET->getClass() == RSExportType::ExportClassPointer) { 1074 /* Pointer type variable should be resolved in GetBuiltinElementConstruct() */ 1075 assert(false && "??"); 1076 } else if(ET->getClass() == RSExportType::ExportClassRecord) { 1077 /* 1078 * Simalar to genPackVarOfType. 1079 * 1080 * TODO: Generalize these two function such that there's no duplicated codes. 1081 */ 1082 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 1083 int Pos = 0; /* relative pos from now on */ 1084 1085 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin(); 1086 I != ERT->fields_end(); 1087 I++) 1088 { 1089 const RSExportRecordType::Field* F = *I; 1090 std::string FieldName; 1091 size_t FieldOffset = F->getOffsetInParent(); 1092 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1093 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 1094 1095 if(!VarName.empty()) 1096 FieldName = VarName + "." + F->getName(); 1097 else 1098 FieldName = F->getName(); 1099 1100 /* alignment */ 1101 genAddPaddingToElementBuiler(C, (FieldOffset - Pos), ElementBuilderName, RenderScriptVar); 1102 1103 /* eb.add(...) */ 1104 genAddElementToElementBuilder(C, (*I)->getType(), FieldName, ElementBuilderName, RenderScriptVar); 1105 1106 /* there's padding within the field type */ 1107 genAddPaddingToElementBuiler(C, (FieldAllocSize - FieldStoreSize), ElementBuilderName, RenderScriptVar); 1108 1109 Pos = FieldOffset + FieldAllocSize; 1110 } 1111 1112 /* There maybe some padding after the struct */ 1113 genAddPaddingToElementBuiler(C, (RSExportType::GetTypeAllocSize(ERT) - Pos), ElementBuilderName, RenderScriptVar); 1114 } else { 1115 assert(false && "Unknown class of type"); 1116 } 1117 } 1118} 1119 1120void RSReflection::genAddPaddingToElementBuiler(Context& C, size_t PaddingSize, const char* ElementBuilderName, const char* RenderScriptVar) { 1121 while(PaddingSize > 0) { 1122 const std::string& VarName = C.createPaddingField(); 1123 if(PaddingSize >= 4) { 1124 EB_ADD("U32(" << RenderScriptVar << ")"); 1125 PaddingSize -= 4; 1126 } else if(PaddingSize >= 2) { 1127 EB_ADD("U16(" << RenderScriptVar << ")"); 1128 PaddingSize -= 2; 1129 } else if(PaddingSize >= 1) { 1130 EB_ADD("U8(" << RenderScriptVar << ")"); 1131 PaddingSize -= 1; 1132 } 1133 } 1134 return; 1135} 1136 1137#undef EB_ADD 1138/******************** Methods to create Element in Java of given record type /end ********************/ 1139 1140bool RSReflection::reflect(const char* OutputPackageName, const std::string& InputFileName, const std::string& OutputBCFileName) { 1141 Context *C = NULL; 1142 std::string ResourceId = ""; 1143 1144 if(!GetFileNameWithoutExtension(OutputBCFileName, ResourceId)) 1145 return false; 1146 1147 if(ResourceId.empty()) 1148 ResourceId = "<Resource ID>"; 1149 1150 if((OutputPackageName == NULL) || (*OutputPackageName == '\0') || strcmp(OutputPackageName, "-") == 0) 1151 C = new Context("<Package Name>", ResourceId, true); 1152 else 1153 C = new Context(OutputPackageName, ResourceId, false); 1154 1155 if(C != NULL) { 1156 std::string ErrorMsg, ScriptClassName; 1157 /* class ScriptC_<ScriptName> */ 1158 if(!GetFileNameWithoutExtension(InputFileName, ScriptClassName)) 1159 return false; 1160 1161 if(ScriptClassName.empty()) 1162 ScriptClassName = "<Input Script Name>"; 1163 1164 ScriptClassName.at(0) = toupper(ScriptClassName.at(0)); 1165 ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX); 1166 1167 if (mRSContext->getLicenseNote() != NULL) 1168 C->setLicenseNote(*mRSContext->getLicenseNote()); 1169 1170 if(!genScriptClass(*C, ScriptClassName, ErrorMsg)) { 1171 std::cerr << "Failed to generate class " << ScriptClassName << " (" << ErrorMsg << ")" << endl; 1172 return false; 1173 } 1174 1175 /* class ScriptField_<TypeName> */ 1176 for(RSContext::const_export_type_iterator TI = mRSContext->export_types_begin(); 1177 TI != mRSContext->export_types_end(); 1178 TI++) 1179 { 1180 const RSExportType* ET = TI->getValue(); 1181 1182 if(ET->getClass() == RSExportType::ExportClassRecord) { 1183 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 1184 1185 if(!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) { 1186 std::cerr << "Failed to generate type class for struct '" << ERT->getName() << "' (" << ErrorMsg << ")" << endl; 1187 return false; 1188 } 1189 } 1190 } 1191 } 1192 1193 return true; 1194} 1195 1196/****************************** RSReflection::Context ******************************/ 1197const char* const RSReflection::Context::ApacheLicenseNote = 1198 "/*\n" 1199 " * Copyright (C) 2010 The Android Open Source Project\n" 1200 " *\n" 1201 " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" 1202 " * you may not use this file except in compliance with the License.\n" 1203 " * You may obtain a copy of the License at\n" 1204 " *\n" 1205 " * http://www.apache.org/licenses/LICENSE-2.0\n" 1206 " *\n" 1207 " * Unless required by applicable law or agreed to in writing, software\n" 1208 " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" 1209 " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" 1210 " * See the License for the specific language governing permissions and\n" 1211 " * limitations under the License.\n" 1212 " */\n" 1213 "\n"; 1214 1215const char* const RSReflection::Context::Import[] = { 1216 /* RenderScript java class */ 1217 "android.renderscript.*", 1218 /* Import R */ 1219 "android.content.res.Resources", 1220 /* Import for debugging */ 1221 "android.util.Log", 1222}; 1223 1224const char* RSReflection::Context::AccessModifierStr(AccessModifier AM) { 1225 switch(AM) { 1226 case AM_Public: return "public"; break; 1227 case AM_Protected: return "protected"; break; 1228 case AM_Private: return "private"; break; 1229 default: return ""; break; 1230 } 1231} 1232 1233bool RSReflection::Context::startClass(AccessModifier AM, bool IsStatic, const std::string& ClassName, const char* SuperClassName, std::string& ErrorMsg) { 1234 if(mVerbose) 1235 std::cout << "Generating " << ClassName << ".java ..." << endl; 1236 1237 /* License */ 1238 out() << mLicenseNote; 1239 1240 /* Package */ 1241 if(!mPackageName.empty()) 1242 out() << "package " << mPackageName << ";" << endl; 1243 out() << endl; 1244 1245 /* Imports */ 1246 for(int i=0;i<(sizeof(Import)/sizeof(const char*));i++) 1247 out() << "import " << Import[i] << ";" << endl; 1248 out() << endl; 1249 1250 out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class " << ClassName; 1251 if(SuperClassName != NULL) 1252 out() << " extends " << SuperClassName; 1253 1254 startBlock(); 1255 1256 mClassName = ClassName; 1257 1258 return true; 1259} 1260 1261void RSReflection::Context::endClass() { 1262 endBlock(); 1263 if(!mUseStdout) 1264 mOF.close(); 1265 clear(); 1266 return; 1267} 1268 1269void RSReflection::Context::startBlock(bool ShouldIndent) { 1270 if(ShouldIndent) 1271 indent() << "{" << endl; 1272 else 1273 out() << " {" << endl; 1274 incIndentLevel(); 1275 return; 1276} 1277 1278void RSReflection::Context::endBlock() { 1279 decIndentLevel(); 1280 indent() << "}" << endl << endl; 1281 return; 1282} 1283 1284void RSReflection::Context::startTypeClass(const std::string& ClassName) { 1285 indent() << "public static class " << ClassName; 1286 startBlock(); 1287 return; 1288} 1289 1290void RSReflection::Context::endTypeClass() { 1291 endBlock(); 1292 return; 1293} 1294 1295void RSReflection::Context::startFunction(AccessModifier AM, bool IsStatic, const char* ReturnType, const std::string& FunctionName, int Argc, ...) { 1296 ArgTy Args; 1297 va_list vl; 1298 va_start(vl, Argc); 1299 1300 for(int i=0;i<Argc;i++) { 1301 const char* ArgType = va_arg(vl, const char*); 1302 const char* ArgName = va_arg(vl, const char*); 1303 1304 Args.push_back( make_pair(ArgType, ArgName) ); 1305 } 1306 va_end(vl); 1307 1308 startFunction(AM, IsStatic, ReturnType, FunctionName, Args); 1309 1310 return; 1311} 1312 1313void RSReflection::Context::startFunction(AccessModifier AM, 1314 bool IsStatic, 1315 const char* ReturnType, 1316 const std::string& FunctionName, 1317 const ArgTy& Args) 1318{ 1319 indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ") << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "("; 1320 1321 bool FirstArg = true; 1322 for(ArgTy::const_iterator I = Args.begin(); 1323 I != Args.end(); 1324 I++) 1325 { 1326 if(!FirstArg) 1327 out() << ", "; 1328 else 1329 FirstArg = false; 1330 1331 out() << I->first << " " << I->second; 1332 } 1333 1334 out() << ")"; 1335 startBlock(); 1336 1337 return; 1338} 1339 1340void RSReflection::Context::endFunction() { 1341 endBlock(); 1342 return; 1343} 1344 1345} /* namespace slang */ 1346