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