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