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