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