slang_rs_reflection.cpp revision b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5d
1/* 2 * Copyright 2010, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "slang_rs_reflection.h" 18 19#include <sys/stat.h> 20 21#include <cstdarg> 22#include <cctype> 23 24#include <algorithm> 25#include <string> 26#include <utility> 27 28#include "llvm/ADT/APFloat.h" 29#include "llvm/ADT/StringExtras.h" 30 31#include "os_sep.h" 32#include "slang_rs_context.h" 33#include "slang_rs_export_var.h" 34#include "slang_rs_export_foreach.h" 35#include "slang_rs_export_func.h" 36#include "slang_rs_reflect_utils.h" 37#include "slang_utils.h" 38 39#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_" 40#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC" 41 42#define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_" 43#define RS_TYPE_CLASS_SUPER_CLASS_NAME "android.renderscript.Script.FieldBase" 44 45#define RS_TYPE_ITEM_CLASS_NAME "Item" 46 47#define RS_TYPE_ITEM_BUFFER_NAME "mItemArray" 48#define RS_TYPE_ITEM_BUFFER_PACKER_NAME "mIOBuffer" 49 50#define RS_EXPORT_VAR_INDEX_PREFIX "mExportVarIdx_" 51#define RS_EXPORT_VAR_PREFIX "mExportVar_" 52 53#define RS_EXPORT_FUNC_INDEX_PREFIX "mExportFuncIdx_" 54#define RS_EXPORT_FOREACH_INDEX_PREFIX "mExportForEachIdx_" 55 56#define RS_EXPORT_VAR_ALLOCATION_PREFIX "mAlloction_" 57#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_" 58 59namespace slang { 60 61// Some utility function using internal in RSReflection 62static bool GetClassNameFromFileName(const std::string &FileName, 63 std::string &ClassName) { 64 ClassName.clear(); 65 66 if (FileName.empty() || (FileName == "-")) 67 return true; 68 69 ClassName = 70 RSSlangReflectUtils::JavaClassNameFromRSFileName(FileName.c_str()); 71 72 return true; 73} 74 75static const char *GetPrimitiveTypeName(const RSExportPrimitiveType *EPT) { 76 static const char *PrimitiveTypeJavaNameMap[] = { 77 "", // RSExportPrimitiveType::DataTypeFloat16 78 "float", // RSExportPrimitiveType::DataTypeFloat32 79 "double", // RSExportPrimitiveType::DataTypeFloat64 80 "byte", // RSExportPrimitiveType::DataTypeSigned8 81 "short", // RSExportPrimitiveType::DataTypeSigned16 82 "int", // RSExportPrimitiveType::DataTypeSigned32 83 "long", // RSExportPrimitiveType::DataTypeSigned64 84 "short", // RSExportPrimitiveType::DataTypeUnsigned8 85 "int", // RSExportPrimitiveType::DataTypeUnsigned16 86 "long", // RSExportPrimitiveType::DataTypeUnsigned32 87 "long", // RSExportPrimitiveType::DataTypeUnsigned64 88 "boolean", // RSExportPrimitiveType::DataTypeBoolean 89 90 "int", // RSExportPrimitiveType::DataTypeUnsigned565 91 "int", // RSExportPrimitiveType::DataTypeUnsigned5551 92 "int", // RSExportPrimitiveType::DataTypeUnsigned4444 93 94 "", // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2 95 "", // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3 96 "", // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4 97 98 "Element", // RSExportPrimitiveType::DataTypeRSElement 99 "Type", // RSExportPrimitiveType::DataTypeRSType 100 "Allocation", // RSExportPrimitiveType::DataTypeRSAllocation 101 "Sampler", // RSExportPrimitiveType::DataTypeRSSampler 102 "Script", // RSExportPrimitiveType::DataTypeRSScript 103 "Mesh", // RSExportPrimitiveType::DataTypeRSMesh 104 "ProgramFragment", // RSExportPrimitiveType::DataTypeRSProgramFragment 105 "ProgramVertex", // RSExportPrimitiveType::DataTypeRSProgramVertex 106 "ProgramRaster", // RSExportPrimitiveType::DataTypeRSProgramRaster 107 "ProgramStore", // RSExportPrimitiveType::DataTypeRSProgramStore 108 "Font", // RSExportPrimitiveType::DataTypeRSFont 109 }; 110 unsigned TypeId = EPT->getType(); 111 112 if (TypeId < (sizeof(PrimitiveTypeJavaNameMap) / sizeof(const char*))) { 113 return PrimitiveTypeJavaNameMap[ EPT->getType() ]; 114 } 115 116 slangAssert(false && "GetPrimitiveTypeName : Unknown primitive data type"); 117 return NULL; 118} 119 120static const char *GetVectorTypeName(const RSExportVectorType *EVT) { 121 static const char *VectorTypeJavaNameMap[][3] = { 122 /* 0 */ { "Byte2", "Byte3", "Byte4" }, 123 /* 1 */ { "Short2", "Short3", "Short4" }, 124 /* 2 */ { "Int2", "Int3", "Int4" }, 125 /* 3 */ { "Long2", "Long3", "Long4" }, 126 /* 4 */ { "Float2", "Float3", "Float4" }, 127 }; 128 129 const char **BaseElement = NULL; 130 131 switch (EVT->getType()) { 132 case RSExportPrimitiveType::DataTypeSigned8: 133 case RSExportPrimitiveType::DataTypeBoolean: { 134 BaseElement = VectorTypeJavaNameMap[0]; 135 break; 136 } 137 case RSExportPrimitiveType::DataTypeSigned16: 138 case RSExportPrimitiveType::DataTypeUnsigned8: { 139 BaseElement = VectorTypeJavaNameMap[1]; 140 break; 141 } 142 case RSExportPrimitiveType::DataTypeSigned32: 143 case RSExportPrimitiveType::DataTypeUnsigned16: { 144 BaseElement = VectorTypeJavaNameMap[2]; 145 break; 146 } 147 case RSExportPrimitiveType::DataTypeSigned64: 148 case RSExportPrimitiveType::DataTypeUnsigned64: 149 case RSExportPrimitiveType::DataTypeUnsigned32: { 150 BaseElement = VectorTypeJavaNameMap[3]; 151 break; 152 } 153 case RSExportPrimitiveType::DataTypeFloat32: { 154 BaseElement = VectorTypeJavaNameMap[4]; 155 break; 156 } 157 default: { 158 slangAssert(false && "RSReflection::genElementTypeName : Unsupported " 159 "vector element data type"); 160 break; 161 } 162 } 163 164 slangAssert((EVT->getNumElement() > 1) && 165 (EVT->getNumElement() <= 4) && 166 "Number of element in vector type is invalid"); 167 168 return BaseElement[EVT->getNumElement() - 2]; 169} 170 171static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) { 172 static const char *MatrixTypeJavaNameMap[] = { 173 /* 2x2 */ "Matrix2f", 174 /* 3x3 */ "Matrix3f", 175 /* 4x4 */ "Matrix4f", 176 }; 177 unsigned Dim = EMT->getDim(); 178 179 if ((Dim - 2) < (sizeof(MatrixTypeJavaNameMap) / sizeof(const char*))) 180 return MatrixTypeJavaNameMap[ EMT->getDim() - 2 ]; 181 182 slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension"); 183 return NULL; 184} 185 186static const char *GetVectorAccessor(unsigned Index) { 187 static const char *VectorAccessorMap[] = { 188 /* 0 */ "x", 189 /* 1 */ "y", 190 /* 2 */ "z", 191 /* 3 */ "w", 192 }; 193 194 slangAssert((Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) && 195 "Out-of-bound index to access vector member"); 196 197 return VectorAccessorMap[Index]; 198} 199 200static const char *GetPackerAPIName(const RSExportPrimitiveType *EPT) { 201 static const char *PrimitiveTypePackerAPINameMap[] = { 202 "", // RSExportPrimitiveType::DataTypeFloat16 203 "addF32", // RSExportPrimitiveType::DataTypeFloat32 204 "addF64", // RSExportPrimitiveType::DataTypeFloat64 205 "addI8", // RSExportPrimitiveType::DataTypeSigned8 206 "addI16", // RSExportPrimitiveType::DataTypeSigned16 207 "addI32", // RSExportPrimitiveType::DataTypeSigned32 208 "addI64", // RSExportPrimitiveType::DataTypeSigned64 209 "addU8", // RSExportPrimitiveType::DataTypeUnsigned8 210 "addU16", // RSExportPrimitiveType::DataTypeUnsigned16 211 "addU32", // RSExportPrimitiveType::DataTypeUnsigned32 212 "addU64", // RSExportPrimitiveType::DataTypeUnsigned64 213 "addBoolean", // RSExportPrimitiveType::DataTypeBoolean 214 215 "addU16", // RSExportPrimitiveType::DataTypeUnsigned565 216 "addU16", // RSExportPrimitiveType::DataTypeUnsigned5551 217 "addU16", // RSExportPrimitiveType::DataTypeUnsigned4444 218 219 "addMatrix", // RSExportPrimitiveType::DataTypeRSMatrix2x2 220 "addMatrix", // RSExportPrimitiveType::DataTypeRSMatrix3x3 221 "addMatrix", // RSExportPrimitiveType::DataTypeRSMatrix4x4 222 223 "addObj", // RSExportPrimitiveType::DataTypeRSElement 224 "addObj", // RSExportPrimitiveType::DataTypeRSType 225 "addObj", // RSExportPrimitiveType::DataTypeRSAllocation 226 "addObj", // RSExportPrimitiveType::DataTypeRSSampler 227 "addObj", // RSExportPrimitiveType::DataTypeRSScript 228 "addObj", // RSExportPrimitiveType::DataTypeRSMesh 229 "addObj", // RSExportPrimitiveType::DataTypeRSProgramFragment 230 "addObj", // RSExportPrimitiveType::DataTypeRSProgramVertex 231 "addObj", // RSExportPrimitiveType::DataTypeRSProgramRaster 232 "addObj", // RSExportPrimitiveType::DataTypeRSProgramStore 233 "addObj", // RSExportPrimitiveType::DataTypeRSFont 234 }; 235 unsigned TypeId = EPT->getType(); 236 237 if (TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char*))) 238 return PrimitiveTypePackerAPINameMap[ EPT->getType() ]; 239 240 slangAssert(false && "GetPackerAPIName : Unknown primitive data type"); 241 return NULL; 242} 243 244static std::string GetTypeName(const RSExportType *ET) { 245 switch (ET->getClass()) { 246 case RSExportType::ExportClassPrimitive: { 247 return GetPrimitiveTypeName( 248 static_cast<const RSExportPrimitiveType*>(ET)); 249 } 250 case RSExportType::ExportClassPointer: { 251 const RSExportType *PointeeType = 252 static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 253 254 if (PointeeType->getClass() != RSExportType::ExportClassRecord) 255 return "Allocation"; 256 else 257 return RS_TYPE_CLASS_NAME_PREFIX + PointeeType->getName(); 258 } 259 case RSExportType::ExportClassVector: { 260 return GetVectorTypeName(static_cast<const RSExportVectorType*>(ET)); 261 } 262 case RSExportType::ExportClassMatrix: { 263 return GetMatrixTypeName(static_cast<const RSExportMatrixType*>(ET)); 264 } 265 case RSExportType::ExportClassConstantArray: { 266 const RSExportConstantArrayType* CAT = 267 static_cast<const RSExportConstantArrayType*>(ET); 268 std::string ElementTypeName = GetTypeName(CAT->getElementType()); 269 ElementTypeName.append("[]"); 270 return ElementTypeName; 271 } 272 case RSExportType::ExportClassRecord: { 273 return RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + 274 "."RS_TYPE_ITEM_CLASS_NAME; 275 } 276 default: { 277 slangAssert(false && "Unknown class of type"); 278 } 279 } 280 281 return ""; 282} 283 284static const char *GetTypeNullValue(const RSExportType *ET) { 285 switch (ET->getClass()) { 286 case RSExportType::ExportClassPrimitive: { 287 const RSExportPrimitiveType *EPT = 288 static_cast<const RSExportPrimitiveType*>(ET); 289 if (EPT->isRSObjectType()) 290 return "null"; 291 else if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean) 292 return "false"; 293 else 294 return "0"; 295 break; 296 } 297 case RSExportType::ExportClassPointer: 298 case RSExportType::ExportClassVector: 299 case RSExportType::ExportClassMatrix: 300 case RSExportType::ExportClassConstantArray: 301 case RSExportType::ExportClassRecord: { 302 return "null"; 303 break; 304 } 305 default: { 306 slangAssert(false && "Unknown class of type"); 307 } 308 } 309 return ""; 310} 311 312static const char *GetBuiltinElementConstruct(const RSExportType *ET) { 313 if (ET->getClass() == RSExportType::ExportClassPrimitive) { 314 const RSExportPrimitiveType *EPT = 315 static_cast<const RSExportPrimitiveType*>(ET); 316 if (EPT->getKind() == RSExportPrimitiveType::DataKindUser) { 317 static const char *PrimitiveBuiltinElementConstructMap[] = { 318 NULL, // RSExportPrimitiveType::DataTypeFloat16 319 "Element.F32", // RSExportPrimitiveType::DataTypeFloat32 320 "Element.F64", // RSExportPrimitiveType::DataTypeFloat64 321 "Element.I8", // RSExportPrimitiveType::DataTypeSigned8 322 NULL, // RSExportPrimitiveType::DataTypeSigned16 323 "Element.I32", // RSExportPrimitiveType::DataTypeSigned32 324 "Element.I64", // RSExportPrimitiveType::DataTypeSigned64 325 "Element.U8", // RSExportPrimitiveType::DataTypeUnsigned8 326 NULL, // RSExportPrimitiveType::DataTypeUnsigned16 327 "Element.U32", // RSExportPrimitiveType::DataTypeUnsigned32 328 "Element.U64", // RSExportPrimitiveType::DataTypeUnsigned64 329 "Element.BOOLEAN", // RSExportPrimitiveType::DataTypeBoolean 330 331 NULL, // RSExportPrimitiveType::DataTypeUnsigned565 332 NULL, // RSExportPrimitiveType::DataTypeUnsigned5551 333 NULL, // RSExportPrimitiveType::DataTypeUnsigned4444 334 335 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2 336 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3 337 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4 338 339 "Element.ELEMENT", // RSExportPrimitiveType::DataTypeRSElement 340 "Element.TYPE", // RSExportPrimitiveType::DataTypeRSType 341 "Element.ALLOCATION", // RSExportPrimitiveType::DataTypeRSAllocation 342 "Element.SAMPLER", // RSExportPrimitiveType::DataTypeRSSampler 343 "Element.SCRIPT", // RSExportPrimitiveType::DataTypeRSScript 344 "Element.MESH", // RSExportPrimitiveType::DataTypeRSMesh 345 "Element.PROGRAM_FRAGMENT", 346 // RSExportPrimitiveType::DataTypeRSProgramFragment 347 "Element.PROGRAM_VERTEX", 348 // RSExportPrimitiveType::DataTypeRSProgramVertex 349 "Element.PROGRAM_RASTER", 350 // RSExportPrimitiveType::DataTypeRSProgramRaster 351 "Element.PROGRAM_STORE", 352 // RSExportPrimitiveType::DataTypeRSProgramStore 353 "Element.FONT", 354 // RSExportPrimitiveType::DataTypeRSFont 355 }; 356 unsigned TypeId = EPT->getType(); 357 358 if (TypeId < 359 (sizeof(PrimitiveBuiltinElementConstructMap) / sizeof(const char*))) 360 return PrimitiveBuiltinElementConstructMap[ EPT->getType() ]; 361 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelA) { 362 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 363 return "Element.A_8"; 364 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGB) { 365 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned565) 366 return "Element.RGB_565"; 367 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 368 return "Element.RGB_888"; 369 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGBA) { 370 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned5551) 371 return "Element.RGBA_5551"; 372 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned4444) 373 return "Element.RGBA_4444"; 374 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 375 return "Element.RGBA_8888"; 376 } 377 } else if (ET->getClass() == RSExportType::ExportClassVector) { 378 const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(ET); 379 if (EVT->getKind() == RSExportPrimitiveType::DataKindUser) { 380 if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 381 if (EVT->getNumElement() == 2) 382 return "Element.F32_2"; 383 else if (EVT->getNumElement() == 3) 384 return "Element.F32_3"; 385 else if (EVT->getNumElement() == 4) 386 return "Element.F32_4"; 387 } else if (EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) { 388 if (EVT->getNumElement() == 4) 389 return "Element.U8_4"; 390 } 391 } 392 } else if (ET->getClass() == RSExportType::ExportClassMatrix) { 393 const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET); 394 switch (EMT->getDim()) { 395 case 2: return "Element.MATRIX_2X2"; 396 case 3: return "Element.MATRIX_3X3"; 397 case 4: return "Element.MATRIX_4X4"; 398 default: slangAssert(false && "Unsupported dimension of matrix"); 399 } 400 } else if (ET->getClass() == RSExportType::ExportClassPointer) { 401 // Treat pointer type variable as unsigned int 402 // TODO(zonr): this is target dependent 403 return "Element.USER_I32"; 404 } 405 406 return NULL; 407} 408 409static const char *GetElementDataKindName(RSExportPrimitiveType::DataKind DK) { 410 static const char *ElementDataKindNameMap[] = { 411 "Element.DataKind.USER", // RSExportPrimitiveType::DataKindUser 412 "Element.DataKind.PIXEL_L", // RSExportPrimitiveType::DataKindPixelL 413 "Element.DataKind.PIXEL_A", // RSExportPrimitiveType::DataKindPixelA 414 "Element.DataKind.PIXEL_LA", // RSExportPrimitiveType::DataKindPixelLA 415 "Element.DataKind.PIXEL_RGB", // RSExportPrimitiveType::DataKindPixelRGB 416 "Element.DataKind.PIXEL_RGBA", // RSExportPrimitiveType::DataKindPixelRGBA 417 }; 418 419 if (static_cast<unsigned>(DK) < 420 (sizeof(ElementDataKindNameMap) / sizeof(const char*))) 421 return ElementDataKindNameMap[ DK ]; 422 else 423 return NULL; 424} 425 426static const char *GetElementDataTypeName(RSExportPrimitiveType::DataType DT) { 427 static const char *ElementDataTypeNameMap[] = { 428 NULL, // RSExportPrimitiveType::DataTypeFloat16 429 "Element.DataType.FLOAT_32", // RSExportPrimitiveType::DataTypeFloat32 430 "Element.DataType.FLOAT_64", // RSExportPrimitiveType::DataTypeFloat64 431 "Element.DataType.SIGNED_8", // RSExportPrimitiveType::DataTypeSigned8 432 "Element.DataType.SIGNED_16", // RSExportPrimitiveType::DataTypeSigned16 433 "Element.DataType.SIGNED_32", // RSExportPrimitiveType::DataTypeSigned32 434 "Element.DataType.SIGNED_64", // RSExportPrimitiveType::DataTypeSigned64 435 "Element.DataType.UNSIGNED_8", // RSExportPrimitiveType::DataTypeUnsigned8 436 "Element.DataType.UNSIGNED_16", 437 // RSExportPrimitiveType::DataTypeUnsigned16 438 "Element.DataType.UNSIGNED_32", 439 // RSExportPrimitiveType::DataTypeUnsigned32 440 "Element.DataType.UNSIGNED_64", 441 // RSExportPrimitiveType::DataTypeUnsigned64 442 "Element.DataType.BOOLEAN", 443 // RSExportPrimitiveType::DataTypeBoolean 444 445 // RSExportPrimitiveType::DataTypeUnsigned565 446 "Element.DataType.UNSIGNED_5_6_5", 447 // RSExportPrimitiveType::DataTypeUnsigned5551 448 "Element.DataType.UNSIGNED_5_5_5_1", 449 // RSExportPrimitiveType::DataTypeUnsigned4444 450 "Element.DataType.UNSIGNED_4_4_4_4", 451 452 // DataTypeRSMatrix* must have been resolved in GetBuiltinElementConstruct() 453 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2 454 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3 455 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4 456 457 "Element.DataType.RS_ELEMENT", // RSExportPrimitiveType::DataTypeRSElement 458 "Element.DataType.RS_TYPE", // RSExportPrimitiveType::DataTypeRSType 459 // RSExportPrimitiveType::DataTypeRSAllocation 460 "Element.DataType.RS_ALLOCATION", 461 // RSExportPrimitiveType::DataTypeRSSampler 462 "Element.DataType.RS_SAMPLER", 463 // RSExportPrimitiveType::DataTypeRSScript 464 "Element.DataType.RS_SCRIPT", 465 // RSExportPrimitiveType::DataTypeRSMesh 466 "Element.DataType.RS_MESH", 467 // RSExportPrimitiveType::DataTypeRSProgramFragment 468 "Element.DataType.RS_PROGRAM_FRAGMENT", 469 // RSExportPrimitiveType::DataTypeRSProgramVertex 470 "Element.DataType.RS_PROGRAM_VERTEX", 471 // RSExportPrimitiveType::DataTypeRSProgramRaster 472 "Element.DataType.RS_PROGRAM_RASTER", 473 // RSExportPrimitiveType::DataTypeRSProgramStore 474 "Element.DataType.RS_PROGRAM_STORE", 475 // RSExportPrimitiveType::DataTypeRSFont 476 "Element.DataType.RS_FONT", 477 }; 478 479 if (static_cast<unsigned>(DT) < 480 (sizeof(ElementDataTypeNameMap) / sizeof(const char*))) 481 return ElementDataTypeNameMap[ DT ]; 482 else 483 return NULL; 484} 485 486/********************** Methods to generate script class **********************/ 487bool RSReflection::genScriptClass(Context &C, 488 const std::string &ClassName, 489 std::string &ErrorMsg) { 490 if (!C.startClass(Context::AM_Public, 491 false, 492 ClassName, 493 RS_SCRIPT_CLASS_SUPER_CLASS_NAME, 494 ErrorMsg)) 495 return false; 496 497 genScriptClassConstructor(C); 498 499 // Reflect export variable 500 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(), 501 E = mRSContext->export_vars_end(); 502 I != E; 503 I++) 504 genExportVariable(C, *I); 505 506 // Reflect export for each functions 507 for (RSContext::const_export_foreach_iterator 508 I = mRSContext->export_foreach_begin(), 509 E = mRSContext->export_foreach_end(); 510 I != E; I++) 511 genExportForEach(C, *I); 512 513 // Reflect export function 514 for (RSContext::const_export_func_iterator 515 I = mRSContext->export_funcs_begin(), 516 E = mRSContext->export_funcs_end(); 517 I != E; I++) 518 genExportFunction(C, *I); 519 520 C.endClass(); 521 522 return true; 523} 524 525void RSReflection::genScriptClassConstructor(Context &C) { 526 C.indent() << "// Constructor" << std::endl; 527 C.startFunction(Context::AM_Public, 528 false, 529 NULL, 530 C.getClassName(), 531 3, 532 "RenderScript", "rs", 533 "Resources", "resources", 534 "int", "id"); 535 // Call constructor of super class 536 C.indent() << "super(rs, resources, id);" << std::endl; 537 538 // If an exported variable has initial value, reflect it 539 540 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(), 541 E = mRSContext->export_vars_end(); 542 I != E; 543 I++) { 544 const RSExportVar *EV = *I; 545 if (!EV->getInit().isUninit()) 546 genInitExportVariable(C, EV->getType(), EV->getName(), EV->getInit()); 547 } 548 549 C.endFunction(); 550 551 return; 552} 553 554void RSReflection::genInitBoolExportVariable(Context &C, 555 const std::string &VarName, 556 const clang::APValue &Val) { 557 slangAssert(!Val.isUninit() && "Not a valid initializer"); 558 559 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = "; 560 slangAssert((Val.getKind() == clang::APValue::Int) && 561 "Bool type has wrong initial APValue"); 562 563 C.out() << ((Val.getInt().getSExtValue() == 0) ? "false" : "true") 564 << ";" << std::endl; 565 566 return; 567} 568 569void RSReflection::genInitPrimitiveExportVariable( 570 Context &C, 571 const std::string &VarName, 572 const clang::APValue &Val) { 573 slangAssert(!Val.isUninit() && "Not a valid initializer"); 574 575 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = "; 576 switch (Val.getKind()) { 577 case clang::APValue::Int: { 578 llvm::APInt api = Val.getInt(); 579 C.out() << api.getSExtValue(); 580 if (api.getBitWidth() > 32) { 581 C.out() << "L"; 582 } 583 break; 584 } 585 case clang::APValue::Float: { 586 llvm::APFloat apf = Val.getFloat(); 587 if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) { 588 C.out() << apf.convertToFloat() << "f"; 589 } else { 590 C.out() << apf.convertToDouble(); 591 } 592 break; 593 } 594 595 case clang::APValue::ComplexInt: 596 case clang::APValue::ComplexFloat: 597 case clang::APValue::LValue: 598 case clang::APValue::Vector: { 599 slangAssert(false && 600 "Primitive type cannot have such kind of initializer"); 601 break; 602 } 603 default: { 604 slangAssert(false && "Unknown kind of initializer"); 605 } 606 } 607 C.out() << ";" << std::endl; 608 609 return; 610} 611 612void RSReflection::genInitExportVariable(Context &C, 613 const RSExportType *ET, 614 const std::string &VarName, 615 const clang::APValue &Val) { 616 slangAssert(!Val.isUninit() && "Not a valid initializer"); 617 618 switch (ET->getClass()) { 619 case RSExportType::ExportClassPrimitive: { 620 const RSExportPrimitiveType *EPT = 621 static_cast<const RSExportPrimitiveType*>(ET); 622 if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean) { 623 genInitBoolExportVariable(C, VarName, Val); 624 } else { 625 genInitPrimitiveExportVariable(C, VarName, Val); 626 } 627 break; 628 } 629 case RSExportType::ExportClassPointer: { 630 if (!Val.isInt() || Val.getInt().getSExtValue() != 0) 631 std::cout << "Initializer which is non-NULL to pointer type variable " 632 "will be ignored" << std::endl; 633 break; 634 } 635 case RSExportType::ExportClassVector: { 636 const RSExportVectorType *EVT = 637 static_cast<const RSExportVectorType*>(ET); 638 switch (Val.getKind()) { 639 case clang::APValue::Int: 640 case clang::APValue::Float: { 641 for (unsigned i = 0; i < EVT->getNumElement(); i++) { 642 std::string Name = VarName + "." + GetVectorAccessor(i); 643 genInitPrimitiveExportVariable(C, Name, Val); 644 } 645 break; 646 } 647 case clang::APValue::Vector: { 648 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new " 649 << GetVectorTypeName(EVT) << "();" << std::endl; 650 651 unsigned NumElements = 652 std::min(static_cast<unsigned>(EVT->getNumElement()), 653 Val.getVectorLength()); 654 for (unsigned i = 0; i < NumElements; i++) { 655 const clang::APValue &ElementVal = Val.getVectorElt(i); 656 std::string Name = VarName + "." + GetVectorAccessor(i); 657 genInitPrimitiveExportVariable(C, Name, ElementVal); 658 } 659 break; 660 } 661 case clang::APValue::Uninitialized: 662 case clang::APValue::ComplexInt: 663 case clang::APValue::ComplexFloat: 664 case clang::APValue::LValue: { 665 slangAssert(false && "Unexpected type of value of initializer."); 666 } 667 } 668 break; 669 } 670 // TODO(zonr): Resolving initializer of a record (and matrix) type variable 671 // is complex. It cannot obtain by just simply evaluating the initializer 672 // expression. 673 case RSExportType::ExportClassMatrix: 674 case RSExportType::ExportClassConstantArray: 675 case RSExportType::ExportClassRecord: { 676#if 0 677 unsigned InitIndex = 0; 678 const RSExportRecordType *ERT = 679 static_cast<const RSExportRecordType*>(ET); 680 681 slangAssert((Val.getKind() == clang::APValue::Vector) && 682 "Unexpected type of initializer for record type variable"); 683 684 C.indent() << RS_EXPORT_VAR_PREFIX << VarName 685 << " = new "RS_TYPE_CLASS_NAME_PREFIX << ERT->getName() 686 << "."RS_TYPE_ITEM_CLASS_NAME"();" << std::endl; 687 688 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(), 689 E = ERT->fields_end(); 690 I != E; 691 I++) { 692 const RSExportRecordType::Field *F = *I; 693 std::string FieldName = VarName + "." + F->getName(); 694 695 if (InitIndex > Val.getVectorLength()) 696 break; 697 698 genInitPrimitiveExportVariable(C, 699 FieldName, 700 Val.getVectorElt(InitIndex++)); 701 } 702#endif 703 slangAssert(false && "Unsupported initializer for record/matrix/constant " 704 "array type variable currently"); 705 break; 706 } 707 default: { 708 slangAssert(false && "Unknown class of type"); 709 } 710 } 711 return; 712} 713 714void RSReflection::genExportVariable(Context &C, const RSExportVar *EV) { 715 const RSExportType *ET = EV->getType(); 716 717 C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX 718 << EV->getName() << " = " << C.getNextExportVarSlot() << ";" 719 << std::endl; 720 721 switch (ET->getClass()) { 722 case RSExportType::ExportClassPrimitive: { 723 genPrimitiveTypeExportVariable(C, EV); 724 break; 725 } 726 case RSExportType::ExportClassPointer: { 727 genPointerTypeExportVariable(C, EV); 728 break; 729 } 730 case RSExportType::ExportClassVector: { 731 genVectorTypeExportVariable(C, EV); 732 break; 733 } 734 case RSExportType::ExportClassMatrix: { 735 genMatrixTypeExportVariable(C, EV); 736 break; 737 } 738 case RSExportType::ExportClassConstantArray: { 739 genConstantArrayTypeExportVariable(C, EV); 740 break; 741 } 742 case RSExportType::ExportClassRecord: { 743 genRecordTypeExportVariable(C, EV); 744 break; 745 } 746 default: { 747 slangAssert(false && "Unknown class of type"); 748 } 749 } 750 751 return; 752} 753 754void RSReflection::genExportFunction(Context &C, const RSExportFunc *EF) { 755 C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX 756 << EF->getName() << " = " << C.getNextExportFuncSlot() << ";" 757 << std::endl; 758 759 // invoke_*() 760 Context::ArgTy Args; 761 762 if (EF->hasParam()) { 763 for (RSExportFunc::const_param_iterator I = EF->params_begin(), 764 E = EF->params_end(); 765 I != E; 766 I++) { 767 Args.push_back(std::make_pair(GetTypeName((*I)->getType()), 768 (*I)->getName())); 769 } 770 } 771 772 C.startFunction(Context::AM_Public, 773 false, 774 "void", 775 "invoke_" + EF->getName(/*Mangle=*/ false), 776 // We are using un-mangled name since Java 777 // supports method overloading. 778 Args); 779 780 if (!EF->hasParam()) { 781 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");" 782 << std::endl; 783 } else { 784 const RSExportRecordType *ERT = EF->getParamPacketType(); 785 std::string FieldPackerName = EF->getName() + "_fp"; 786 787 if (genCreateFieldPacker(C, ERT, FieldPackerName.c_str())) 788 genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str()); 789 790 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", " 791 << FieldPackerName << ");" << std::endl; 792 } 793 794 C.endFunction(); 795 return; 796} 797 798void RSReflection::genExportForEach(Context &C, const RSExportForEach *EF) { 799 C.indent() << "private final static int "RS_EXPORT_FOREACH_INDEX_PREFIX 800 << EF->getName() << " = " << C.getNextExportForEachSlot() << ";" 801 << std::endl; 802 803 // forEach_*() 804 Context::ArgTy Args; 805 806 slangAssert(EF->getNumParameters() > 0); 807 808 if (EF->hasIn()) 809 Args.push_back(std::make_pair("Allocation", "ain")); 810 //Args.push_back(std::make_pair(GetTypeName(EF->getInType()), "ain")); 811 if (EF->hasOut()) 812 Args.push_back(std::make_pair("Allocation", "aout")); 813 //Args.push_back(std::make_pair(GetTypeName(EF->getOutType()), "aout")); 814 815 const RSExportRecordType *ERT = EF->getParamPacketType(); 816 if (ERT) { 817 for (RSExportForEach::const_param_iterator I = EF->params_begin(), 818 E = EF->params_end(); 819 I != E; 820 I++) { 821 Args.push_back(std::make_pair(GetTypeName((*I)->getType()), 822 (*I)->getName())); 823 } 824 } 825 826 C.startFunction(Context::AM_Public, 827 false, 828 "void", 829 "forEach_" + EF->getName(), 830 Args); 831 832 const RSExportType *IET = EF->getInType(); 833 if (IET) { 834 genTypeCheck(C, IET, "ain"); 835 } 836 837 const RSExportType *OET = EF->getOutType(); 838 if (OET) { 839 genTypeCheck(C, OET, "aout"); 840 } 841 842 if (EF->hasIn() && EF->hasOut()) { 843 C.indent() << "// Verify dimensions" << std::endl; 844 C.indent() << "Type tIn = ain.getType();" << std::endl; 845 C.indent() << "Type tOut = aout.getType();" << std::endl; 846 C.indent() << "if ((tIn.getCount() != tOut.getCount()) ||" << std::endl; 847 C.indent() << " (tIn.getX() != tOut.getX()) ||" << std::endl; 848 C.indent() << " (tIn.getY() != tOut.getY()) ||" << std::endl; 849 C.indent() << " (tIn.getZ() != tOut.getZ()) ||" << std::endl; 850 C.indent() << " (tIn.hasFaces() != tOut.hasFaces()) ||" << std::endl; 851 C.indent() << " (tIn.hasMipmaps() != tOut.hasMipmaps())) {" << std::endl; 852 C.indent() << " throw new RSRuntimeException(\"Dimension mismatch\");"; 853 C.out() << std::endl; 854 C.indent() << "}" << std::endl; 855 } 856 857 std::string FieldPackerName = EF->getName() + "_fp"; 858 if (ERT) { 859 if (genCreateFieldPacker(C, ERT, FieldPackerName.c_str())) { 860 genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str()); 861 } 862 } 863 C.indent() << "forEach("RS_EXPORT_FOREACH_INDEX_PREFIX << EF->getName(); 864 865 if (EF->hasIn()) 866 C.out() << ", ain"; 867 else 868 C.out() << ", null"; 869 870 if (EF->hasOut()) 871 C.out() << ", aout"; 872 else 873 C.out() << ", null"; 874 875 if (EF->hasUsrData()) 876 C.out() << ", " << FieldPackerName; 877 else 878 C.out() << ", null"; 879 880 C.out() << ");" << std::endl; 881 882 C.endFunction(); 883 return; 884} 885 886void RSReflection::genTypeCheck(Context &C, 887 const RSExportType *ET, 888 const char *VarName) { 889 C.indent() << "// check " << VarName << std::endl; 890 return; 891} 892 893 894void RSReflection::genPrimitiveTypeExportVariable( 895 Context &C, 896 const RSExportVar *EV) { 897 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassPrimitive) 898 && "Variable should be type of primitive here"); 899 900 const RSExportPrimitiveType *EPT = 901 static_cast<const RSExportPrimitiveType*>(EV->getType()); 902 const char *TypeName = GetPrimitiveTypeName(EPT); 903 904 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 905 << EV->getName() << ";" << std::endl; 906 907 // set_*() 908 if (!EV->isConst()) { 909 C.startFunction(Context::AM_Public, 910 false, 911 "void", 912 "set_" + EV->getName(), 913 1, 914 TypeName, "v"); 915 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 916 917 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() 918 << ", v);" << std::endl; 919 920 C.endFunction(); 921 } 922 923 genGetExportVariable(C, TypeName, EV->getName()); 924 925 return; 926} 927 928void RSReflection::genPointerTypeExportVariable(Context &C, 929 const RSExportVar *EV) { 930 const RSExportType *ET = EV->getType(); 931 const RSExportType *PointeeType; 932 std::string TypeName; 933 934 slangAssert((ET->getClass() == RSExportType::ExportClassPointer) && 935 "Variable should be type of pointer here"); 936 937 PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 938 TypeName = GetTypeName(ET); 939 940 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 941 << EV->getName() << ";" << std::endl; 942 943 // bind_*() 944 C.startFunction(Context::AM_Public, 945 false, 946 "void", 947 "bind_" + EV->getName(), 948 1, 949 TypeName.c_str(), "v"); 950 951 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 952 C.indent() << "if (v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX 953 << EV->getName() << ");" << std::endl; 954 955 if (PointeeType->getClass() == RSExportType::ExportClassRecord) 956 C.indent() << "else bindAllocation(v.getAllocation(), " 957 RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" 958 << std::endl; 959 else 960 C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX 961 << EV->getName() << ");" << std::endl; 962 963 C.endFunction(); 964 965 genGetExportVariable(C, TypeName, EV->getName()); 966 967 return; 968} 969 970void RSReflection::genVectorTypeExportVariable(Context &C, 971 const RSExportVar *EV) { 972 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassVector) && 973 "Variable should be type of vector here"); 974 975 const RSExportVectorType *EVT = 976 static_cast<const RSExportVectorType*>(EV->getType()); 977 const char *TypeName = GetVectorTypeName(EVT); 978 const char *FieldPackerName = "fp"; 979 980 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 981 << EV->getName() << ";" << std::endl; 982 983 // set_*() 984 if (!EV->isConst()) { 985 C.startFunction(Context::AM_Public, 986 false, 987 "void", 988 "set_" + EV->getName(), 989 1, 990 TypeName, "v"); 991 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 992 993 if (genCreateFieldPacker(C, EVT, FieldPackerName)) 994 genPackVarOfType(C, EVT, "v", FieldPackerName); 995 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " 996 << FieldPackerName << ");" << std::endl; 997 998 C.endFunction(); 999 } 1000 1001 genGetExportVariable(C, TypeName, EV->getName()); 1002 return; 1003} 1004 1005void RSReflection::genMatrixTypeExportVariable(Context &C, 1006 const RSExportVar *EV) { 1007 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassMatrix) && 1008 "Variable should be type of matrix here"); 1009 1010 const RSExportMatrixType *EMT = 1011 static_cast<const RSExportMatrixType*>(EV->getType()); 1012 const char *TypeName = GetMatrixTypeName(EMT); 1013 const char *FieldPackerName = "fp"; 1014 1015 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 1016 << EV->getName() << ";" << std::endl; 1017 1018 // set_*() 1019 if (!EV->isConst()) { 1020 C.startFunction(Context::AM_Public, 1021 false, 1022 "void", 1023 "set_" + EV->getName(), 1024 1, 1025 TypeName, "v"); 1026 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 1027 1028 if (genCreateFieldPacker(C, EMT, FieldPackerName)) 1029 genPackVarOfType(C, EMT, "v", FieldPackerName); 1030 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " 1031 << FieldPackerName << ");" << std::endl; 1032 1033 C.endFunction(); 1034 } 1035 1036 genGetExportVariable(C, TypeName, EV->getName()); 1037 return; 1038} 1039 1040void RSReflection::genConstantArrayTypeExportVariable( 1041 Context &C, 1042 const RSExportVar *EV) { 1043 slangAssert((EV->getType()->getClass() == 1044 RSExportType::ExportClassConstantArray) && 1045 "Variable should be type of constant array here"); 1046 1047 const RSExportConstantArrayType *ECAT = 1048 static_cast<const RSExportConstantArrayType*>(EV->getType()); 1049 std::string TypeName = GetTypeName(ECAT); 1050 const char *FieldPackerName = "fp"; 1051 1052 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 1053 << EV->getName() << ";" << std::endl; 1054 1055 // set_*() 1056 if (!EV->isConst()) { 1057 C.startFunction(Context::AM_Public, 1058 false, 1059 "void", 1060 "set_" + EV->getName(), 1061 1, 1062 TypeName.c_str(), "v"); 1063 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 1064 1065 if (genCreateFieldPacker(C, ECAT, FieldPackerName)) 1066 genPackVarOfType(C, ECAT, "v", FieldPackerName); 1067 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " 1068 << FieldPackerName << ");" << std::endl; 1069 1070 C.endFunction(); 1071 } 1072 1073 genGetExportVariable(C, TypeName, EV->getName()); 1074 return; 1075} 1076 1077void RSReflection::genRecordTypeExportVariable(Context &C, 1078 const RSExportVar *EV) { 1079 slangAssert((EV->getType()->getClass() == RSExportType::ExportClassRecord) && 1080 "Variable should be type of struct here"); 1081 1082 const RSExportRecordType *ERT = 1083 static_cast<const RSExportRecordType*>(EV->getType()); 1084 std::string TypeName = 1085 RS_TYPE_CLASS_NAME_PREFIX + ERT->getName() + "."RS_TYPE_ITEM_CLASS_NAME; 1086 const char *FieldPackerName = "fp"; 1087 1088 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 1089 << EV->getName() << ";" << std::endl; 1090 1091 // set_*() 1092 if (!EV->isConst()) { 1093 C.startFunction(Context::AM_Public, 1094 false, 1095 "void", 1096 "set_" + EV->getName(), 1097 1, 1098 TypeName.c_str(), "v"); 1099 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 1100 1101 if (genCreateFieldPacker(C, ERT, FieldPackerName)) 1102 genPackVarOfType(C, ERT, "v", FieldPackerName); 1103 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() 1104 << ", " << FieldPackerName << ");" << std::endl; 1105 1106 C.endFunction(); 1107 } 1108 1109 genGetExportVariable(C, TypeName.c_str(), EV->getName()); 1110 return; 1111} 1112 1113void RSReflection::genGetExportVariable(Context &C, 1114 const std::string &TypeName, 1115 const std::string &VarName) { 1116 C.startFunction(Context::AM_Public, 1117 false, 1118 TypeName.c_str(), 1119 "get_" + VarName, 1120 0); 1121 1122 C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << std::endl; 1123 1124 C.endFunction(); 1125 return; 1126} 1127 1128/******************* Methods to generate script class /end *******************/ 1129 1130bool RSReflection::genCreateFieldPacker(Context &C, 1131 const RSExportType *ET, 1132 const char *FieldPackerName) { 1133 size_t AllocSize = RSExportType::GetTypeAllocSize(ET); 1134 if (AllocSize > 0) 1135 C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker(" 1136 << AllocSize << ");" << std::endl; 1137 else 1138 return false; 1139 return true; 1140} 1141 1142void RSReflection::genPackVarOfType(Context &C, 1143 const RSExportType *ET, 1144 const char *VarName, 1145 const char *FieldPackerName) { 1146 switch (ET->getClass()) { 1147 case RSExportType::ExportClassPrimitive: 1148 case RSExportType::ExportClassVector: { 1149 C.indent() << FieldPackerName << "." 1150 << GetPackerAPIName( 1151 static_cast<const RSExportPrimitiveType*>(ET)) 1152 << "(" << VarName << ");" << std::endl; 1153 break; 1154 } 1155 case RSExportType::ExportClassPointer: { 1156 // Must reflect as type Allocation in Java 1157 const RSExportType *PointeeType = 1158 static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 1159 1160 if (PointeeType->getClass() != RSExportType::ExportClassRecord) 1161 C.indent() << FieldPackerName << ".addI32(" << VarName 1162 << ".getPtr());" << std::endl; 1163 else 1164 C.indent() << FieldPackerName << ".addI32(" << VarName 1165 << ".getAllocation().getPtr());" << std::endl; 1166 break; 1167 } 1168 case RSExportType::ExportClassMatrix: { 1169 C.indent() << FieldPackerName << ".addMatrix(" << VarName << ");" 1170 << std::endl; 1171 break; 1172 } 1173 case RSExportType::ExportClassConstantArray: { 1174 const RSExportConstantArrayType *ECAT = 1175 static_cast<const RSExportConstantArrayType *>(ET); 1176 1177 // TODO(zonr): more elegant way. Currently, we obtain the unique index 1178 // variable (this method involves recursive call which means 1179 // we may have more than one level loop, therefore we can't 1180 // always use the same index variable name here) name given 1181 // in the for-loop from counting the '.' in @VarName. 1182 unsigned Level = 0; 1183 size_t LastDotPos = 0; 1184 std::string ElementVarName(VarName); 1185 1186 while (LastDotPos != std::string::npos) { 1187 LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1); 1188 Level++; 1189 } 1190 std::string IndexVarName("ct"); 1191 IndexVarName.append(llvm::utostr_32(Level)); 1192 1193 C.indent() << "for (int " << IndexVarName << " = 0; " << 1194 IndexVarName << " < " << ECAT->getSize() << "; " << 1195 IndexVarName << "++)"; 1196 C.startBlock(); 1197 1198 ElementVarName.append("[" + IndexVarName + "]"); 1199 genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(), 1200 FieldPackerName); 1201 1202 C.endBlock(); 1203 break; 1204 } 1205 case RSExportType::ExportClassRecord: { 1206 const RSExportRecordType *ERT = 1207 static_cast<const RSExportRecordType*>(ET); 1208 // Relative pos from now on in field packer 1209 unsigned Pos = 0; 1210 1211 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(), 1212 E = ERT->fields_end(); 1213 I != E; 1214 I++) { 1215 const RSExportRecordType::Field *F = *I; 1216 std::string FieldName; 1217 size_t FieldOffset = F->getOffsetInParent(); 1218 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1219 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 1220 1221 if (VarName != NULL) 1222 FieldName = VarName + ("." + F->getName()); 1223 else 1224 FieldName = F->getName(); 1225 1226 if (FieldOffset > Pos) 1227 C.indent() << FieldPackerName << ".skip(" 1228 << (FieldOffset - Pos) << ");" << std::endl; 1229 1230 genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName); 1231 1232 // There is padding in the field type 1233 if (FieldAllocSize > FieldStoreSize) 1234 C.indent() << FieldPackerName << ".skip(" 1235 << (FieldAllocSize - FieldStoreSize) 1236 << ");" << std::endl; 1237 1238 Pos = FieldOffset + FieldAllocSize; 1239 } 1240 1241 // There maybe some padding after the struct 1242 size_t Padding = RSExportType::GetTypeAllocSize(ERT) - Pos; 1243 if (Padding > 0) 1244 C.indent() << FieldPackerName << ".skip(" << Padding << ");" 1245 << std::endl; 1246 break; 1247 } 1248 default: { 1249 slangAssert(false && "Unknown class of type"); 1250 } 1251 } 1252 1253 return; 1254} 1255 1256void RSReflection::genAllocateVarOfType(Context &C, 1257 const RSExportType *T, 1258 const std::string &VarName) { 1259 switch (T->getClass()) { 1260 case RSExportType::ExportClassPrimitive: { 1261 // Primitive type like int in Java has its own storage once it's declared. 1262 // 1263 // FIXME: Should we allocate storage for RS object? 1264 // if (static_cast<const RSExportPrimitiveType *>(T)->isRSObjectType()) 1265 // C.indent() << VarName << " = new " << GetTypeName(T) << "();" 1266 // << std::endl; 1267 break; 1268 } 1269 case RSExportType::ExportClassPointer: { 1270 // Pointer type is an instance of Allocation or a TypeClass whose value is 1271 // expected to be assigned by programmer later in Java program. Therefore 1272 // we don't reflect things like [VarName] = new Allocation(); 1273 C.indent() << VarName << " = null;" << std::endl; 1274 break; 1275 } 1276 case RSExportType::ExportClassConstantArray: { 1277 const RSExportConstantArrayType *ECAT = 1278 static_cast<const RSExportConstantArrayType *>(T); 1279 const RSExportType *ElementType = ECAT->getElementType(); 1280 1281 C.indent() << VarName << " = new " << GetTypeName(ElementType) 1282 << "[" << ECAT->getSize() << "];" << std::endl; 1283 1284 // Primitive type element doesn't need allocation code. 1285 if (ElementType->getClass() != RSExportType::ExportClassPrimitive) { 1286 C.indent() << "for (int $ct = 0; $ct < " << ECAT->getSize() << "; " 1287 "$ct++)"; 1288 C.startBlock(); 1289 1290 std::string ElementVarName(VarName); 1291 ElementVarName.append("[$ct]"); 1292 genAllocateVarOfType(C, ElementType, ElementVarName); 1293 1294 C.endBlock(); 1295 } 1296 break; 1297 } 1298 case RSExportType::ExportClassVector: 1299 case RSExportType::ExportClassMatrix: 1300 case RSExportType::ExportClassRecord: { 1301 C.indent() << VarName << " = new " << GetTypeName(T) << "();" 1302 << std::endl; 1303 break; 1304 } 1305 } 1306 return; 1307} 1308 1309void RSReflection::genNewItemBufferIfNull(Context &C, 1310 const char *Index) { 1311 C.indent() << "if (" RS_TYPE_ITEM_BUFFER_NAME " == null) " 1312 RS_TYPE_ITEM_BUFFER_NAME " = " 1313 "new " RS_TYPE_ITEM_CLASS_NAME 1314 "[getType().getX() /* count */];" 1315 << std::endl; 1316 if (Index != NULL) 1317 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] == null) " 1318 RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] = " 1319 "new "RS_TYPE_ITEM_CLASS_NAME"();" << std::endl; 1320 return; 1321} 1322 1323void RSReflection::genNewItemBufferPackerIfNull(Context &C) { 1324 C.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME " == null) " 1325 RS_TYPE_ITEM_BUFFER_PACKER_NAME " = " 1326 "new FieldPacker(" RS_TYPE_ITEM_CLASS_NAME 1327 ".sizeof * getType().getX()/* count */" 1328 ");" << std::endl; 1329 return; 1330} 1331 1332/********************** Methods to generate type class **********************/ 1333bool RSReflection::genTypeClass(Context &C, 1334 const RSExportRecordType *ERT, 1335 std::string &ErrorMsg) { 1336 std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName(); 1337 1338 if (!C.startClass(Context::AM_Public, 1339 false, 1340 ClassName, 1341 RS_TYPE_CLASS_SUPER_CLASS_NAME, 1342 ErrorMsg)) 1343 return false; 1344 1345 mGeneratedFileNames->push_back(ClassName); 1346 1347 genTypeItemClass(C, ERT); 1348 1349 // Declare item buffer and item buffer packer 1350 C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[]" 1351 ";" << std::endl; 1352 C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";" 1353 << std::endl; 1354 1355 genTypeClassConstructor(C, ERT); 1356 genTypeClassCopyToArray(C, ERT); 1357 genTypeClassItemSetter(C, ERT); 1358 genTypeClassItemGetter(C, ERT); 1359 genTypeClassComponentSetter(C, ERT); 1360 genTypeClassComponentGetter(C, ERT); 1361 genTypeClassCopyAll(C, ERT); 1362 genTypeClassResize(C); 1363 1364 C.endClass(); 1365 1366 C.resetFieldIndex(); 1367 C.clearFieldIndexMap(); 1368 1369 return true; 1370} 1371 1372void RSReflection::genTypeItemClass(Context &C, 1373 const RSExportRecordType *ERT) { 1374 C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME; 1375 C.startBlock(); 1376 1377 C.indent() << "public static final int sizeof = " 1378 << RSExportType::GetTypeAllocSize(ERT) << ";" << std::endl; 1379 1380 // Member elements 1381 C.out() << std::endl; 1382 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 1383 FE = ERT->fields_end(); 1384 FI != FE; 1385 FI++) { 1386 C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName() 1387 << ";" << std::endl; 1388 } 1389 1390 // Constructor 1391 C.out() << std::endl; 1392 C.indent() << RS_TYPE_ITEM_CLASS_NAME"()"; 1393 C.startBlock(); 1394 1395 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 1396 FE = ERT->fields_end(); 1397 FI != FE; 1398 FI++) { 1399 const RSExportRecordType::Field *F = *FI; 1400 genAllocateVarOfType(C, F->getType(), F->getName()); 1401 } 1402 1403 // end Constructor 1404 C.endBlock(); 1405 1406 // end Item class 1407 C.endBlock(); 1408 1409 return; 1410} 1411 1412void RSReflection::genTypeClassConstructor(Context &C, 1413 const RSExportRecordType *ERT) { 1414 const char *RenderScriptVar = "rs"; 1415 1416 C.startFunction(Context::AM_Public, 1417 true, 1418 "Element", 1419 "createElement", 1420 1, 1421 "RenderScript", RenderScriptVar); 1422 genBuildElement(C, "eb", ERT, RenderScriptVar, /* IsInline = */false); 1423 C.endFunction(); 1424 1425 C.startFunction(Context::AM_Public, 1426 false, 1427 NULL, 1428 C.getClassName(), 1429 2, 1430 "RenderScript", RenderScriptVar, 1431 "int", "count"); 1432 1433 C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << std::endl; 1434 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << std::endl; 1435 C.indent() << "mElement = createElement(" << RenderScriptVar << ");" 1436 << std::endl; 1437 // Call init() in super class 1438 C.indent() << "init(" << RenderScriptVar << ", count);" << std::endl; 1439 C.endFunction(); 1440 1441 C.startFunction(Context::AM_Public, 1442 false, 1443 NULL, 1444 C.getClassName(), 1445 3, 1446 "RenderScript", RenderScriptVar, 1447 "int", "count", 1448 "int", "usages"); 1449 1450 C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << std::endl; 1451 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << std::endl; 1452 C.indent() << "mElement = createElement(" << RenderScriptVar << ");" 1453 << std::endl; 1454 // Call init() in super class 1455 C.indent() << "init(" << RenderScriptVar << ", count, usages);" << std::endl; 1456 C.endFunction(); 1457 1458 return; 1459} 1460 1461void RSReflection::genTypeClassCopyToArray(Context &C, 1462 const RSExportRecordType *ERT) { 1463 C.startFunction(Context::AM_Private, 1464 false, 1465 "void", 1466 "copyToArray", 1467 2, 1468 RS_TYPE_ITEM_CLASS_NAME, "i", 1469 "int", "index"); 1470 1471 genNewItemBufferPackerIfNull(C); 1472 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME 1473 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);" 1474 << std::endl; 1475 1476 genPackVarOfType(C, ERT, "i", RS_TYPE_ITEM_BUFFER_PACKER_NAME); 1477 1478 C.endFunction(); 1479 return; 1480} 1481 1482void RSReflection::genTypeClassItemSetter(Context &C, 1483 const RSExportRecordType *ERT) { 1484 C.startFunction(Context::AM_Public, 1485 false, 1486 "void", 1487 "set", 1488 3, 1489 RS_TYPE_ITEM_CLASS_NAME, "i", 1490 "int", "index", 1491 "boolean", "copyNow"); 1492 genNewItemBufferIfNull(C, NULL); 1493 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << std::endl; 1494 1495 C.indent() << "if (copyNow) "; 1496 C.startBlock(); 1497 1498 C.indent() << "copyToArray(i, index);" << std::endl; 1499 C.indent() << "mAllocation.setFromFieldPacker(index, " 1500 RS_TYPE_ITEM_BUFFER_PACKER_NAME");" << std::endl; 1501 1502 // End of if (copyNow) 1503 C.endBlock(); 1504 1505 C.endFunction(); 1506 return; 1507} 1508 1509void RSReflection::genTypeClassItemGetter(Context &C, 1510 const RSExportRecordType *ERT) { 1511 C.startFunction(Context::AM_Public, 1512 false, 1513 RS_TYPE_ITEM_CLASS_NAME, 1514 "get", 1515 1, 1516 "int", "index"); 1517 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return null;" 1518 << std::endl; 1519 C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index];" << std::endl; 1520 C.endFunction(); 1521 return; 1522} 1523 1524void RSReflection::genTypeClassComponentSetter(Context &C, 1525 const RSExportRecordType *ERT) { 1526 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 1527 FE = ERT->fields_end(); 1528 FI != FE; 1529 FI++) { 1530 const RSExportRecordType::Field *F = *FI; 1531 size_t FieldOffset = F->getOffsetInParent(); 1532 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1533 unsigned FieldIndex = C.getFieldIndex(F); 1534 1535 C.startFunction(Context::AM_Public, 1536 false, 1537 "void", 1538 "set_" + F->getName(), 3, 1539 "int", "index", 1540 GetTypeName(F->getType()).c_str(), "v", 1541 "boolean", "copyNow"); 1542 genNewItemBufferPackerIfNull(C); 1543 genNewItemBufferIfNull(C, "index"); 1544 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName() 1545 << " = v;" << std::endl; 1546 1547 C.indent() << "if (copyNow) "; 1548 C.startBlock(); 1549 1550 if (FieldOffset > 0) 1551 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME 1552 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof + " 1553 << FieldOffset << ");" << std::endl; 1554 else 1555 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME 1556 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);" 1557 << std::endl; 1558 genPackVarOfType(C, F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME); 1559 1560 C.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize << ");" 1561 << std::endl; 1562 genPackVarOfType(C, F->getType(), "v", "fp"); 1563 C.indent() << "mAllocation.setFromFieldPacker(index, " << FieldIndex 1564 << ", fp);" 1565 << std::endl; 1566 1567 // End of if (copyNow) 1568 C.endBlock(); 1569 1570 C.endFunction(); 1571 } 1572 return; 1573} 1574 1575void RSReflection::genTypeClassComponentGetter(Context &C, 1576 const RSExportRecordType *ERT) { 1577 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 1578 FE = ERT->fields_end(); 1579 FI != FE; 1580 FI++) { 1581 const RSExportRecordType::Field *F = *FI; 1582 C.startFunction(Context::AM_Public, 1583 false, 1584 GetTypeName(F->getType()).c_str(), 1585 "get_" + F->getName(), 1586 1, 1587 "int", "index"); 1588 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return " 1589 << GetTypeNullValue(F->getType()) << ";" << std::endl; 1590 C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName() 1591 << ";" << std::endl; 1592 C.endFunction(); 1593 } 1594 return; 1595} 1596 1597void RSReflection::genTypeClassCopyAll(Context &C, 1598 const RSExportRecordType *ERT) { 1599 C.startFunction(Context::AM_Public, false, "void", "copyAll", 0); 1600 1601 C.indent() << "for (int ct = 0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++)" 1602 " copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);" 1603 << std::endl; 1604 C.indent() << "mAllocation.setFromFieldPacker(0, " 1605 RS_TYPE_ITEM_BUFFER_PACKER_NAME");" 1606 << std::endl; 1607 1608 C.endFunction(); 1609 return; 1610} 1611 1612void RSReflection::genTypeClassResize(Context &C) { 1613 C.startFunction(Context::AM_Public, 1614 false, 1615 "void", 1616 "resize", 1617 1, 1618 "int", "newSize"); 1619 1620 C.indent() << "if (mItemArray != null) "; 1621 C.startBlock(); 1622 C.indent() << "int oldSize = mItemArray.length;" << std::endl; 1623 C.indent() << "int copySize = Math.min(oldSize, newSize);" << std::endl; 1624 C.indent() << "if (newSize == oldSize) return;" << std::endl; 1625 C.indent() << "Item ni[] = new Item[newSize];" << std::endl; 1626 C.indent() << "System.arraycopy(mItemArray, 0, ni, 0, copySize);" 1627 << std::endl; 1628 C.indent() << "mItemArray = ni;" << std::endl; 1629 C.endBlock(); 1630 C.indent() << "mAllocation.resize(newSize);" << std::endl; 1631 1632 C.indent() << "if (" RS_TYPE_ITEM_BUFFER_PACKER_NAME " != null) " 1633 RS_TYPE_ITEM_BUFFER_PACKER_NAME " = " 1634 "new FieldPacker(" RS_TYPE_ITEM_CLASS_NAME 1635 ".sizeof * getType().getX()/* count */" 1636 ");" << std::endl; 1637 1638 C.endFunction(); 1639 return; 1640} 1641 1642/******************** Methods to generate type class /end ********************/ 1643 1644/********** Methods to create Element in Java of given record type ***********/ 1645void RSReflection::genBuildElement(Context &C, 1646 const char *ElementBuilderName, 1647 const RSExportRecordType *ERT, 1648 const char *RenderScriptVar, 1649 bool IsInline) { 1650 C.indent() << "Element.Builder " << ElementBuilderName << " = " 1651 "new Element.Builder(" << RenderScriptVar << ");" << std::endl; 1652 1653 // eb.add(...) 1654 genAddElementToElementBuilder(C, 1655 ERT, 1656 "", 1657 ElementBuilderName, 1658 RenderScriptVar, 1659 /* ArraySize = */0); 1660 1661 if (!IsInline) 1662 C.indent() << "return " << ElementBuilderName << ".create();" << std::endl; 1663 return; 1664} 1665 1666#define EB_ADD(x) do { \ 1667 C.indent() << ElementBuilderName \ 1668 << ".add(" << x << ", \"" << VarName << "\""; \ 1669 if (ArraySize > 0) \ 1670 C.out() << ", " << ArraySize; \ 1671 C.out() << ");" << std::endl; \ 1672 C.incFieldIndex(); \ 1673} while (false) 1674 1675void RSReflection::genAddElementToElementBuilder(Context &C, 1676 const RSExportType *ET, 1677 const std::string &VarName, 1678 const char *ElementBuilderName, 1679 const char *RenderScriptVar, 1680 unsigned ArraySize) { 1681 const char *ElementConstruct = GetBuiltinElementConstruct(ET); 1682 1683 if (ElementConstruct != NULL) { 1684 EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")"); 1685 } else { 1686 if ((ET->getClass() == RSExportType::ExportClassPrimitive) || 1687 (ET->getClass() == RSExportType::ExportClassVector)) { 1688 const RSExportPrimitiveType *EPT = 1689 static_cast<const RSExportPrimitiveType*>(ET); 1690 const char *DataKindName = GetElementDataKindName(EPT->getKind()); 1691 const char *DataTypeName = GetElementDataTypeName(EPT->getType()); 1692 int Size = (ET->getClass() == RSExportType::ExportClassVector) ? 1693 static_cast<const RSExportVectorType*>(ET)->getNumElement() : 1694 1; 1695 1696 switch (EPT->getKind()) { 1697 case RSExportPrimitiveType::DataKindPixelL: 1698 case RSExportPrimitiveType::DataKindPixelA: 1699 case RSExportPrimitiveType::DataKindPixelLA: 1700 case RSExportPrimitiveType::DataKindPixelRGB: 1701 case RSExportPrimitiveType::DataKindPixelRGBA: { 1702 // Element.createPixel() 1703 EB_ADD("Element.createPixel(" << RenderScriptVar << ", " 1704 << DataTypeName << ", " 1705 << DataKindName << ")"); 1706 break; 1707 } 1708 case RSExportPrimitiveType::DataKindUser: 1709 default: { 1710 if (EPT->getClass() == RSExportType::ExportClassPrimitive) { 1711 // Element.createUser() 1712 EB_ADD("Element.createUser(" << RenderScriptVar << ", " 1713 << DataTypeName << ")"); 1714 } else { 1715 slangAssert((ET->getClass() == RSExportType::ExportClassVector) && 1716 "Unexpected type."); 1717 EB_ADD("Element.createVector(" << RenderScriptVar << ", " 1718 << DataTypeName << ", " 1719 << Size << ")"); 1720 } 1721 break; 1722 } 1723 } 1724#ifndef NDEBUG 1725 } else if (ET->getClass() == RSExportType::ExportClassPointer) { 1726 // Pointer type variable should be resolved in 1727 // GetBuiltinElementConstruct() 1728 slangAssert(false && "??"); 1729 } else if (ET->getClass() == RSExportType::ExportClassMatrix) { 1730 // Matrix type variable should be resolved 1731 // in GetBuiltinElementConstruct() 1732 slangAssert(false && "??"); 1733#endif 1734 } else if (ET->getClass() == RSExportType::ExportClassConstantArray) { 1735 const RSExportConstantArrayType *ECAT = 1736 static_cast<const RSExportConstantArrayType *>(ET); 1737 1738 const RSExportType *ElementType = ECAT->getElementType(); 1739 if (ElementType->getClass() != RSExportType::ExportClassRecord) { 1740 genAddElementToElementBuilder(C, 1741 ECAT->getElementType(), 1742 VarName, 1743 ElementBuilderName, 1744 RenderScriptVar, 1745 ECAT->getSize()); 1746 } else { 1747 std::string NewElementBuilderName(ElementBuilderName); 1748 NewElementBuilderName.append(1, '_'); 1749 1750 genBuildElement(C, 1751 NewElementBuilderName.c_str(), 1752 static_cast<const RSExportRecordType*>(ElementType), 1753 RenderScriptVar, 1754 /* IsInline = */true); 1755 ArraySize = ECAT->getSize(); 1756 EB_ADD(NewElementBuilderName << ".create()"); 1757 } 1758 } else if (ET->getClass() == RSExportType::ExportClassRecord) { 1759 // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType. 1760 // 1761 // TODO(zonr): Generalize these two function such that there's no 1762 // duplicated codes. 1763 const RSExportRecordType *ERT = 1764 static_cast<const RSExportRecordType*>(ET); 1765 int Pos = 0; // relative pos from now on 1766 1767 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(), 1768 E = ERT->fields_end(); 1769 I != E; 1770 I++) { 1771 const RSExportRecordType::Field *F = *I; 1772 std::string FieldName; 1773 int FieldOffset = F->getOffsetInParent(); 1774 int FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1775 int FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 1776 1777 if (!VarName.empty()) 1778 FieldName = VarName + "." + F->getName(); 1779 else 1780 FieldName = F->getName(); 1781 1782 // Alignment 1783 genAddPaddingToElementBuiler(C, 1784 (FieldOffset - Pos), 1785 ElementBuilderName, 1786 RenderScriptVar); 1787 1788 // eb.add(...) 1789 C.addFieldIndexMapping(F); 1790 if (F->getType()->getClass() != RSExportType::ExportClassRecord) { 1791 genAddElementToElementBuilder(C, 1792 F->getType(), 1793 FieldName, 1794 ElementBuilderName, 1795 RenderScriptVar, 1796 0); 1797 } else { 1798 std::string NewElementBuilderName(ElementBuilderName); 1799 NewElementBuilderName.append(1, '_'); 1800 1801 genBuildElement(C, 1802 NewElementBuilderName.c_str(), 1803 static_cast<const RSExportRecordType*>(F->getType()), 1804 RenderScriptVar, 1805 /* IsInline = */true); 1806 1807 const std::string &VarName = FieldName; // Hack for EB_ADD macro 1808 EB_ADD(NewElementBuilderName << ".create()"); 1809 } 1810 1811 // There is padding within the field type 1812 genAddPaddingToElementBuiler(C, 1813 (FieldAllocSize - FieldStoreSize), 1814 ElementBuilderName, 1815 RenderScriptVar); 1816 1817 Pos = FieldOffset + FieldAllocSize; 1818 } 1819 1820 // There maybe some padding after the struct 1821 size_t RecordStoreSize = RSExportType::GetTypeStoreSize(ERT); 1822 1823 genAddPaddingToElementBuiler(C, 1824 RecordStoreSize - Pos, 1825 ElementBuilderName, 1826 RenderScriptVar); 1827 } else { 1828 slangAssert(false && "Unknown class of type"); 1829 } 1830 } 1831} 1832 1833void RSReflection::genAddPaddingToElementBuiler(Context &C, 1834 int PaddingSize, 1835 const char *ElementBuilderName, 1836 const char *RenderScriptVar) { 1837 unsigned ArraySize = 0; // Hack the EB_ADD macro 1838 while (PaddingSize > 0) { 1839 const std::string &VarName = C.createPaddingField(); 1840 if (PaddingSize >= 4) { 1841 EB_ADD("Element.U32(" << RenderScriptVar << ")"); 1842 PaddingSize -= 4; 1843 } else if (PaddingSize >= 2) { 1844 EB_ADD("Element.U16(" << RenderScriptVar << ")"); 1845 PaddingSize -= 2; 1846 } else if (PaddingSize >= 1) { 1847 EB_ADD("Element.U8(" << RenderScriptVar << ")"); 1848 PaddingSize -= 1; 1849 } 1850 } 1851 return; 1852} 1853 1854#undef EB_ADD 1855/******** Methods to create Element in Java of given record type /end ********/ 1856 1857bool RSReflection::reflect(const std::string &OutputPathBase, 1858 const std::string &OutputPackageName, 1859 const std::string &InputFileName, 1860 const std::string &OutputBCFileName) { 1861 Context *C = NULL; 1862 std::string ResourceId = ""; 1863 1864 if (!GetClassNameFromFileName(OutputBCFileName, ResourceId)) 1865 return false; 1866 1867 if (ResourceId.empty()) 1868 ResourceId = "<Resource ID>"; 1869 1870 if (OutputPackageName.empty() || OutputPackageName == "-") 1871 C = new Context(OutputPathBase, InputFileName, "<Package Name>", 1872 ResourceId, true); 1873 else 1874 C = new Context(OutputPathBase, InputFileName, OutputPackageName, 1875 ResourceId, false); 1876 1877 if (C != NULL) { 1878 std::string ErrorMsg, ScriptClassName; 1879 // class ScriptC_<ScriptName> 1880 if (!GetClassNameFromFileName(InputFileName, ScriptClassName)) 1881 return false; 1882 1883 if (ScriptClassName.empty()) 1884 ScriptClassName = "<Input Script Name>"; 1885 1886 ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX); 1887 1888 if (mRSContext->getLicenseNote() != NULL) { 1889 C->setLicenseNote(*(mRSContext->getLicenseNote())); 1890 } 1891 1892 if (!genScriptClass(*C, ScriptClassName, ErrorMsg)) { 1893 std::cerr << "Failed to generate class " << ScriptClassName << " (" 1894 << ErrorMsg << ")" << std::endl; 1895 return false; 1896 } 1897 1898 mGeneratedFileNames->push_back(ScriptClassName); 1899 1900 // class ScriptField_<TypeName> 1901 for (RSContext::const_export_type_iterator TI = 1902 mRSContext->export_types_begin(), 1903 TE = mRSContext->export_types_end(); 1904 TI != TE; 1905 TI++) { 1906 const RSExportType *ET = TI->getValue(); 1907 1908 if (ET->getClass() == RSExportType::ExportClassRecord) { 1909 const RSExportRecordType *ERT = 1910 static_cast<const RSExportRecordType*>(ET); 1911 1912 if (!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) { 1913 std::cerr << "Failed to generate type class for struct '" 1914 << ERT->getName() << "' (" << ErrorMsg << ")" << std::endl; 1915 return false; 1916 } 1917 } 1918 } 1919 } 1920 1921 return true; 1922} 1923 1924/************************** RSReflection::Context **************************/ 1925const char *const RSReflection::Context::ApacheLicenseNote = 1926 "/*\n" 1927 " * Copyright (C) 2011 The Android Open Source Project\n" 1928 " *\n" 1929 " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" 1930 " * you may not use this file except in compliance with the License.\n" 1931 " * You may obtain a copy of the License at\n" 1932 " *\n" 1933 " * http://www.apache.org/licenses/LICENSE-2.0\n" 1934 " *\n" 1935 " * Unless required by applicable law or agreed to in writing, software\n" 1936 " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" 1937 " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or " 1938 "implied.\n" 1939 " * See the License for the specific language governing permissions and\n" 1940 " * limitations under the License.\n" 1941 " */\n" 1942 "\n"; 1943 1944const char *const RSReflection::Context::Import[] = { 1945 // RenderScript java class 1946 "android.renderscript.*", 1947 // Import R 1948 "android.content.res.Resources", 1949 // Import for debugging 1950 // "android.util.Log", 1951}; 1952 1953bool RSReflection::Context::openClassFile(const std::string &ClassName, 1954 std::string &ErrorMsg) { 1955 if (!mUseStdout) { 1956 mOF.clear(); 1957 std::string Path = 1958 RSSlangReflectUtils::ComputePackagedPath(mOutputPathBase.c_str(), 1959 mPackageName.c_str()); 1960 1961 if (!SlangUtils::CreateDirectoryWithParents(Path, &ErrorMsg)) 1962 return false; 1963 1964 std::string ClassFile = Path + OS_PATH_SEPARATOR_STR + ClassName + ".java"; 1965 1966 mOF.open(ClassFile.c_str()); 1967 if (!mOF.good()) { 1968 ErrorMsg = "failed to open file '" + ClassFile + "' for write"; 1969 return false; 1970 } 1971 } 1972 return true; 1973} 1974 1975const char *RSReflection::Context::AccessModifierStr(AccessModifier AM) { 1976 switch (AM) { 1977 case AM_Public: return "public"; break; 1978 case AM_Protected: return "protected"; break; 1979 case AM_Private: return "private"; break; 1980 default: return ""; break; 1981 } 1982} 1983 1984bool RSReflection::Context::startClass(AccessModifier AM, 1985 bool IsStatic, 1986 const std::string &ClassName, 1987 const char *SuperClassName, 1988 std::string &ErrorMsg) { 1989 if (mVerbose) 1990 std::cout << "Generating " << ClassName << ".java ..." << std::endl; 1991 1992 // Open file for class 1993 if (!openClassFile(ClassName, ErrorMsg)) 1994 return false; 1995 1996 // License 1997 out() << mLicenseNote; 1998 1999 // Notice of generated file 2000 out() << "/*" << std::endl; 2001 out() << " * This file is auto-generated. DO NOT MODIFY!" << std::endl; 2002 out() << " * The source RenderScript file: " << mInputRSFile << std::endl; 2003 out() << " */" << std::endl; 2004 2005 // Package 2006 if (!mPackageName.empty()) 2007 out() << "package " << mPackageName << ";" << std::endl; 2008 out() << std::endl; 2009 2010 // Imports 2011 for (unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++) 2012 out() << "import " << Import[i] << ";" << std::endl; 2013 out() << std::endl; 2014 2015 // All reflected classes should be annotated as hidden, so that they won't 2016 // be exposed in SDK. 2017 out() << "/**" << std::endl; 2018 out() << " * @hide" << std::endl; 2019 out() << " */" << std::endl; 2020 2021 out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class " 2022 << ClassName; 2023 if (SuperClassName != NULL) 2024 out() << " extends " << SuperClassName; 2025 2026 startBlock(); 2027 2028 mClassName = ClassName; 2029 2030 return true; 2031} 2032 2033void RSReflection::Context::endClass() { 2034 endBlock(); 2035 if (!mUseStdout) 2036 mOF.close(); 2037 clear(); 2038 return; 2039} 2040 2041void RSReflection::Context::startBlock(bool ShouldIndent) { 2042 if (ShouldIndent) 2043 indent() << "{" << std::endl; 2044 else 2045 out() << " {" << std::endl; 2046 incIndentLevel(); 2047 return; 2048} 2049 2050void RSReflection::Context::endBlock() { 2051 decIndentLevel(); 2052 indent() << "}" << std::endl << std::endl; 2053 return; 2054} 2055 2056void RSReflection::Context::startTypeClass(const std::string &ClassName) { 2057 indent() << "public static class " << ClassName; 2058 startBlock(); 2059 return; 2060} 2061 2062void RSReflection::Context::endTypeClass() { 2063 endBlock(); 2064 return; 2065} 2066 2067void RSReflection::Context::startFunction(AccessModifier AM, 2068 bool IsStatic, 2069 const char *ReturnType, 2070 const std::string &FunctionName, 2071 int Argc, ...) { 2072 ArgTy Args; 2073 va_list vl; 2074 va_start(vl, Argc); 2075 2076 for (int i = 0; i < Argc; i++) { 2077 const char *ArgType = va_arg(vl, const char*); 2078 const char *ArgName = va_arg(vl, const char*); 2079 2080 Args.push_back(std::make_pair(ArgType, ArgName)); 2081 } 2082 va_end(vl); 2083 2084 startFunction(AM, IsStatic, ReturnType, FunctionName, Args); 2085 2086 return; 2087} 2088 2089void RSReflection::Context::startFunction(AccessModifier AM, 2090 bool IsStatic, 2091 const char *ReturnType, 2092 const std::string &FunctionName, 2093 const ArgTy &Args) { 2094 indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ") 2095 << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "("; 2096 2097 bool FirstArg = true; 2098 for (ArgTy::const_iterator I = Args.begin(), E = Args.end(); 2099 I != E; 2100 I++) { 2101 if (!FirstArg) 2102 out() << ", "; 2103 else 2104 FirstArg = false; 2105 2106 out() << I->first << " " << I->second; 2107 } 2108 2109 out() << ")"; 2110 startBlock(); 2111 2112 return; 2113} 2114 2115void RSReflection::Context::endFunction() { 2116 endBlock(); 2117 return; 2118} 2119 2120} // namespace slang 2121