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