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