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