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