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