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