slang_rs_reflection.cpp revision 3f8b44dba57685b437cecc208f2a20a4ed93ed36
1e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include "slang_rs_context.hpp" 2e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include "slang_rs_export_var.hpp" 3e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include "slang_rs_reflection.hpp" 4e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include "slang_rs_export_func.hpp" 5e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include "slang_rs_reflect_utils.hpp" 6e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 7e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include <ctype.h> 8e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 9e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include <utility> 10e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include <cstdarg> 11e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 12e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include "llvm/ADT/APFloat.h" 13e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 14e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huberusing std::make_pair; 15e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huberusing std::endl; 16e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 17e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 18e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_" 19e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC" 20e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 216c6b4d0d2b98a7ceee8b697daaf611f8df3254fbJames Dong#define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_" 22e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#define RS_TYPE_CLASS_SUPER_CLASS_NAME "android.renderscript.Script.FieldBase" 23e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 24e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#define RS_TYPE_ITEM_CLASS_NAME "Item" 25e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 26e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#define RS_TYPE_ITEM_BUFFER_NAME "mItemArray" 27e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#define RS_TYPE_ITEM_BUFFER_PACKER_NAME "mIOBuffer" 28e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 29e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#define RS_EXPORT_VAR_INDEX_PREFIX "mExportVarIdx_" 30e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#define RS_EXPORT_VAR_PREFIX "mExportVar_" 31e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 32e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#define RS_EXPORT_FUNC_INDEX_PREFIX "mExportFuncIdx_" 33e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 34e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#define RS_EXPORT_VAR_ALLOCATION_PREFIX "mAlloction_" 35e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_" 36e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 37e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Hubernamespace slang { 38e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 39e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber/* Some utility function using internal in RSReflection */ 40f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huberstatic bool GetClassNameFromFileName(const std::string& FileName, std::string& ClassName) { 41f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber ClassName.clear(); 42f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber 43e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber if(FileName.empty() || (FileName == "-")) 44e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber return true; 45e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 46e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber ClassName = RSSlangReflectUtils::JavaClassNameFromRSFileName(FileName.c_str()); 47e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 488ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber return true; 498ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber} 508ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huber 518ae1d0bdcef22f2bdd8d283e0e615f3ba6c3f4cdAndreas Huberstatic const char* GetPrimitiveTypeName(const RSExportPrimitiveType* EPT) { 52e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber static const char* PrimitiveTypeJavaNameMap[] = { 531900e77bac4276f247f80fd06d19316cac598f57Marco Nelissen "", 54e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber "", 55e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber "float", /* RSExportPrimitiveType::DataTypeFloat32 */ 56e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber "double", /* RSExportPrimitiveType::DataTypeFloat64 */ 57f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber "byte", /* RSExportPrimitiveType::DataTypeSigned8 */ 58f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber "short", /* RSExportPrimitiveType::DataTypeSigned16 */ 59e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber "int", /* RSExportPrimitiveType::DataTypeSigned32 */ 60e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber "long", /* RSExportPrimitiveType::DataTypeSigned64 */ 61e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber "short", /* RSExportPrimitiveType::DataTypeUnsigned8 */ 62bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber "int", /* RSExportPrimitiveType::DataTypeUnsigned16 */ 63e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber "long", /* RSExportPrimitiveType::DataTypeUnsigned32 */ 64e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber "long", /* RSExportPrimitiveType::DataTypeUnsigned64 */ 65e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 66e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber "int", /* RSExportPrimitiveType::DataTypeUnsigned565 */ 67e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber "int", /* RSExportPrimitiveType::DataTypeUnsigned5551 */ 68e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber "int", /* RSExportPrimitiveType::DataTypeUnsigned4444 */ 69e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 70e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber "boolean", /* RSExportPrimitiveType::DataTypeBool */ 71e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber 72e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber "Element", /* RSExportPrimitiveType::DataTypeRSElement */ 73 "Type", /* RSExportPrimitiveType::DataTypeRSType */ 74 "Allocation", /* RSExportPrimitiveType::DataTypeRSAllocation */ 75 "Sampler", /* RSExportPrimitiveType::DataTypeRSSampler */ 76 "Script", /* RSExportPrimitiveType::DataTypeRSScript */ 77 "Mesh", /* RSExportPrimitiveType::DataTypeRSMesh */ 78 "ProgramFragment", /* RSExportPrimitiveType::DataTypeRSProgramFragment */ 79 "ProgramVertex", /* RSExportPrimitiveType::DataTypeRSProgramVertex */ 80 "ProgramRaster", /* RSExportPrimitiveType::DataTypeRSProgramRaster */ 81 "ProgramStore", /* RSExportPrimitiveType::DataTypeRSProgramStore */ 82 "Font", /* RSExportPrimitiveType::DataTypeRSFont */ 83 "Matrix2f", /* RSExportPrimitiveType::DataTypeRSMatrix2x2 */ 84 "Matrix3f", /* RSExportPrimitiveType::DataTypeRSMatrix3x3 */ 85 "Matrix4f", /* RSExportPrimitiveType::DataTypeRSMatrix4x4 */ 86 }; 87 88 if((EPT->getType() >= 0) && (EPT->getType() < (sizeof(PrimitiveTypeJavaNameMap) / sizeof(const char*)))) { 89 // printf("Type %d\n", EPT->getType()); 90 return PrimitiveTypeJavaNameMap[ EPT->getType() ]; 91 } 92 93 assert(false && "GetPrimitiveTypeName : Unknown primitive data type"); 94 return NULL; 95} 96 97static const char* GetVectorTypeName(const RSExportVectorType* EVT) { 98 static const char* VectorTypeJavaNameMap[][3] = { 99 /* 0 */ { "Byte2", "Byte3", "Byte4" }, 100 /* 1 */ { "Short2", "Short3", "Short4" }, 101 /* 2 */ { "Int2", "Int3", "Int4" }, 102 /* 3 */ { "Long2", "Long3", "Long4" }, 103 /* 4 */ { "Float2", "Float3", "Float4" }, 104 }; 105 106 const char** BaseElement; 107 108 switch(EVT->getType()) { 109 case RSExportPrimitiveType::DataTypeSigned8: 110 BaseElement = VectorTypeJavaNameMap[0]; 111 break; 112 113 case RSExportPrimitiveType::DataTypeSigned16: 114 case RSExportPrimitiveType::DataTypeUnsigned8: 115 BaseElement = VectorTypeJavaNameMap[1]; 116 break; 117 118 case RSExportPrimitiveType::DataTypeSigned32: 119 case RSExportPrimitiveType::DataTypeUnsigned16: 120 BaseElement = VectorTypeJavaNameMap[2]; 121 break; 122 123 case RSExportPrimitiveType::DataTypeUnsigned32: 124 BaseElement = VectorTypeJavaNameMap[3]; 125 break; 126 127 case RSExportPrimitiveType::DataTypeFloat32: 128 BaseElement = VectorTypeJavaNameMap[4]; 129 break; 130 131 case RSExportPrimitiveType::DataTypeBool: 132 BaseElement = VectorTypeJavaNameMap[0]; 133 break; 134 135 default: 136 assert(false && "RSReflection::genElementTypeName : Unsupported vector element data type"); 137 break; 138 } 139 140 assert((EVT->getNumElement() > 1) && (EVT->getNumElement() <= 4) && "Number of element in vector type is invalid"); 141 142 return BaseElement[EVT->getNumElement() - 2]; 143} 144 145static const char* GetVectorAccessor(int Index) { 146 static const char* VectorAccessorMap[] = { 147 /* 0 */ "x", 148 /* 1 */ "y", 149 /* 2 */ "z", 150 /* 3 */ "w", 151 }; 152 153 assert((Index >= 0) && (Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) && "Out-of-bound index to access vector member"); 154 155 return VectorAccessorMap[Index]; 156} 157 158static const char* GetPackerAPIName(const RSExportPrimitiveType* EPT) { 159 static const char* PrimitiveTypePackerAPINameMap[] = { 160 "", 161 "", 162 "addF32", /* RSExportPrimitiveType::DataTypeFloat32 */ 163 "addF64", /* RSExportPrimitiveType::DataTypeFloat64 */ 164 "addI8", /* RSExportPrimitiveType::DataTypeSigned8 */ 165 "addI16", /* RSExportPrimitiveType::DataTypeSigned16 */ 166 "addI32", /* RSExportPrimitiveType::DataTypeSigned32 */ 167 "addI64", /* RSExportPrimitiveType::DataTypeSigned64 */ 168 "addU8", /* RSExportPrimitiveType::DataTypeUnsigned8 */ 169 "addU16", /* RSExportPrimitiveType::DataTypeUnsigned16 */ 170 "addU32", /* RSExportPrimitiveType::DataTypeUnsigned32 */ 171 "addU64", /* RSExportPrimitiveType::DataTypeUnsigned64 */ 172 173 "addU16", /* RSExportPrimitiveType::DataTypeUnsigned565 */ 174 "addU16", /* RSExportPrimitiveType::DataTypeUnsigned5551 */ 175 "addU16", /* RSExportPrimitiveType::DataTypeUnsigned4444 */ 176 177 "addBoolean", /* RSExportPrimitiveType::DataTypeBool */ 178 179 "addObj", /* RSExportPrimitiveType::DataTypeRSElement */ 180 "addObj", /* RSExportPrimitiveType::DataTypeRSType */ 181 "addObj", /* RSExportPrimitiveType::DataTypeRSAllocation */ 182 "addObj", /* RSExportPrimitiveType::DataTypeRSSampler */ 183 "addObj", /* RSExportPrimitiveType::DataTypeRSScript */ 184 "addObj", /* RSExportPrimitiveType::DataTypeRSMesh */ 185 "addObj", /* RSExportPrimitiveType::DataTypeRSProgramFragment */ 186 "addObj", /* RSExportPrimitiveType::DataTypeRSProgramVertex */ 187 "addObj", /* RSExportPrimitiveType::DataTypeRSProgramRaster */ 188 "addObj", /* RSExportPrimitiveType::DataTypeRSProgramStore */ 189 "addObj", /* RSExportPrimitiveType::DataTypeRSFont */ 190 "addObj", /* RSExportPrimitiveType::DataTypeRSMatrix2x2 */ 191 "addObj", /* RSExportPrimitiveType::DataTypeRSMatrix3x3 */ 192 "addObj", /* RSExportPrimitiveType::DataTypeRSMatrix4x4 */ 193 }; 194 195 if((EPT->getType() >= 0) && (EPT->getType() < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char*)))) 196 return PrimitiveTypePackerAPINameMap[ EPT->getType() ]; 197 198 assert(false && "GetPackerAPIName : Unknown primitive data type"); 199 return NULL; 200} 201 202static std::string GetTypeName(const RSExportType* ET) { 203 switch(ET->getClass()) { 204 case RSExportType::ExportClassPrimitive: 205 case RSExportType::ExportClassConstantArray: 206 return GetPrimitiveTypeName(static_cast<const RSExportPrimitiveType*>(ET)); 207 break; 208 209 case RSExportType::ExportClassPointer: 210 { 211 const RSExportType* PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 212 213 if(PointeeType->getClass() != RSExportType::ExportClassRecord) 214 return "Allocation"; 215 else 216 return RS_TYPE_CLASS_NAME_PREFIX + PointeeType->getName(); 217 } 218 break; 219 220 case RSExportType::ExportClassVector: 221 return GetVectorTypeName(static_cast<const RSExportVectorType*>(ET)); 222 break; 223 224 case RSExportType::ExportClassRecord: 225 return RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + "."RS_TYPE_ITEM_CLASS_NAME; 226 break; 227 228 default: 229 assert(false && "Unknown class of type"); 230 break; 231 } 232 233 return ""; 234} 235 236static const char* GetBuiltinElementConstruct(const RSExportType* ET) { 237 if (ET->getClass() == RSExportType::ExportClassPrimitive || ET->getClass() == RSExportType::ExportClassConstantArray) { 238 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET); 239 if (EPT->getKind() == RSExportPrimitiveType::DataKindUser) { 240 static const char* PrimitiveBuiltinElementConstructMap[] = { 241 NULL, 242 NULL, 243 "F32", /* RSExportPrimitiveType::DataTypeFloat32 */ 244 NULL, /* RSExportPrimitiveType::DataTypeFloat64 */ 245 "I8", /* RSExportPrimitiveType::DataTypeSigned8 */ 246 NULL, /* RSExportPrimitiveType::DataTypeSigned16 */ 247 "I32", /* RSExportPrimitiveType::DataTypeSigned32 */ 248 NULL, /* RSExportPrimitiveType::DataTypeSigned64 */ 249 "U8", /* RSExportPrimitiveType::DataTypeUnsigned8 */ 250 NULL, /* RSExportPrimitiveType::DataTypeUnsigned16 */ 251 "U32", /* RSExportPrimitiveType::DataTypeUnsigned32 */ 252 NULL, /* RSExportPrimitiveType::DataTypeUnsigned64 */ 253 254 NULL, /* RSExportPrimitiveType::DataTypeUnsigned565 */ 255 NULL, /* RSExportPrimitiveType::DataTypeUnsigned5551 */ 256 NULL, /* RSExportPrimitiveType::DataTypeUnsigned4444 */ 257 258 "BOOLEAN", /* RSExportPrimitiveType::DataTypeBool */ 259 260 "ELEMENT", /* RSExportPrimitiveType::DataTypeRSElement */ 261 "TYPE", /* RSExportPrimitiveType::DataTypeRSType */ 262 "ALLOCATION", /* RSExportPrimitiveType::DataTypeRSAllocation */ 263 "SAMPLER", /* RSExportPrimitiveType::DataTypeRSSampler */ 264 "SCRIPT", /* RSExportPrimitiveType::DataTypeRSScript */ 265 "MESH", /* RSExportPrimitiveType::DataTypeRSMesh */ 266 "PROGRAM_FRAGMENT", /* RSExportPrimitiveType::DataTypeRSProgramFragment */ 267 "PROGRAM_VERTEX", /* RSExportPrimitiveType::DataTypeRSProgramVertex */ 268 "PROGRAM_RASTER", /* RSExportPrimitiveType::DataTypeRSProgramRaster */ 269 "PROGRAM_STORE", /* RSExportPrimitiveType::DataTypeRSProgramStore */ 270 "FONT", /* RSExportPrimitiveType::DataTypeRSFont */ 271 "MATRIX_2X2", /* RSExportPrimitiveType::DataTypeRSMatrix2x2 */ 272 "MATRIX_3X3", /* RSExportPrimitiveType::DataTypeRSMatrix3x3 */ 273 "MATRIX_4X4", /* RSExportPrimitiveType::DataTypeRSMatrix4x4 */ 274 }; 275 276 if ((EPT->getType() >= 0) && (EPT->getType() < (sizeof(PrimitiveBuiltinElementConstructMap) / sizeof(const char*)))) 277 return PrimitiveBuiltinElementConstructMap[ EPT->getType() ]; 278 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelA) { 279 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 280 return "A_8"; 281 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGB) { 282 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned565) 283 return "RGB_565"; 284 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 285 return "RGB_888"; 286 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGBA) { 287 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned5551) 288 return "RGB_5551"; 289 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned4444) 290 return "RGB_4444"; 291 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 292 return "RGB_8888"; 293 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindIndex) { 294 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned16) 295 return "INDEX_16"; 296 } 297 } else if (ET->getClass() == RSExportType::ExportClassVector) { 298 const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(ET); 299 if (EVT->getKind() == RSExportPrimitiveType::DataKindPosition) { 300 if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 301 if (EVT->getNumElement() == 2) 302 return "ATTRIB_POSITION_2"; 303 else if (EVT->getNumElement() == 3) 304 return "ATTRIB_POSITION_3"; 305 } 306 } else if (EVT->getKind() == RSExportPrimitiveType::DataKindTexture) { 307 if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 308 if (EVT->getNumElement() == 2) 309 return "ATTRIB_TEXTURE_2"; 310 } 311 } else if (EVT->getKind() == RSExportPrimitiveType::DataKindNormal) { 312 if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 313 if (EVT->getNumElement() == 3) 314 return "ATTRIB_NORMAL_3"; 315 } 316 } else if (EVT->getKind() == RSExportPrimitiveType::DataKindColor) { 317 if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 318 if (EVT->getNumElement() == 4) 319 return "ATTRIB_COLOR_F32_4"; 320 } else if (EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) { 321 if (EVT->getNumElement() == 4) 322 return "ATTRIB_COLOR_U8_4"; 323 } 324 } 325 } else if (ET->getClass() == RSExportType::ExportClassPointer) { 326 return "USER_I32"; /* tread pointer type variable as unsigned int (TODO: this is target dependent) */ 327 } 328 329 return NULL; 330} 331 332static const char* GetElementDataKindName(RSExportPrimitiveType::DataKind DK) { 333 static const char* ElementDataKindNameMap[] = { 334 "Element.DataKind.USER", /* RSExportPrimitiveType::DataKindUser */ 335 "Element.DataKind.COLOR", /* RSExportPrimitiveType::DataKindColor */ 336 "Element.DataKind.POSITION", /* RSExportPrimitiveType::DataKindPosition */ 337 "Element.DataKind.TEXTURE", /* RSExportPrimitiveType::DataKindTexture */ 338 "Element.DataKind.NORMAL", /* RSExportPrimitiveType::DataKindNormal */ 339 "Element.DataKind.INDEX", /* RSExportPrimitiveType::DataKindIndex */ 340 "Element.DataKind.POINT_SIZE", /* RSExportPrimitiveType::DataKindPointSize */ 341 "Element.DataKind.PIXEL_L", /* RSExportPrimitiveType::DataKindPixelL */ 342 "Element.DataKind.PIXEL_A", /* RSExportPrimitiveType::DataKindPixelA */ 343 "Element.DataKind.PIXEL_LA", /* RSExportPrimitiveType::DataKindPixelLA */ 344 "Element.DataKind.PIXEL_RGB", /* RSExportPrimitiveType::DataKindPixelRGB */ 345 "Element.DataKind.PIXEL_RGBA", /* RSExportPrimitiveType::DataKindPixelRGBA */ 346 }; 347 348 if((DK >= 0) && (DK < (sizeof(ElementDataKindNameMap) / sizeof(const char*)))) 349 return ElementDataKindNameMap[ DK ]; 350 else 351 return NULL; 352} 353 354static const char* GetElementDataTypeName(RSExportPrimitiveType::DataType DT) { 355 static const char* ElementDataTypeNameMap[] = { 356 NULL, 357 NULL, 358 "Element.DataType.FLOAT_32", /* RSExportPrimitiveType::DataTypeFloat32 */ 359 NULL, /* RSExportPrimitiveType::DataTypeFloat64 */ 360 "Element.DataType.SIGNED_8", /* RSExportPrimitiveType::DataTypeSigned8 */ 361 "Element.DataType.SIGNED_16", /* RSExportPrimitiveType::DataTypeSigned16 */ 362 "Element.DataType.SIGNED_32", /* RSExportPrimitiveType::DataTypeSigned32 */ 363 NULL, /* RSExportPrimitiveType::DataTypeSigned64 */ 364 "Element.DataType.UNSIGNED_8", /* RSExportPrimitiveType::DataTypeUnsigned8 */ 365 "Element.DataType.UNSIGNED_16", /* RSExportPrimitiveType::DataTypeUnsigned16 */ 366 "Element.DataType.UNSIGNED_32", /* RSExportPrimitiveType::DataTypeUnsigned32 */ 367 NULL, /* RSExportPrimitiveType::DataTypeUnsigned64 */ 368 369 "Element.DataType.UNSIGNED_5_6_5", /* RSExportPrimitiveType::DataTypeUnsigned565 */ 370 "Element.DataType.UNSIGNED_5_5_5_1", /* RSExportPrimitiveType::DataTypeUnsigned5551 */ 371 "Element.DataType.UNSIGNED_4_4_4_4", /* RSExportPrimitiveType::DataTypeUnsigned4444 */ 372 373 "Element.DataType.BOOLEAN", /* RSExportPrimitiveType::DataTypeBool */ 374 375 "Element.DataType.RS_ELEMENT", /* RSExportPrimitiveType::DataTypeRSElement */ 376 "Element.DataType.RS_TYPE", /* RSExportPrimitiveType::DataTypeRSType */ 377 "Element.DataType.RS_ALLOCATION", /* RSExportPrimitiveType::DataTypeRSAllocation */ 378 "Element.DataType.RS_SAMPLER", /* RSExportPrimitiveType::DataTypeRSSampler */ 379 "Element.DataType.RS_SCRIPT", /* RSExportPrimitiveType::DataTypeRSScript */ 380 "Element.DataType.RS_MESH", /* RSExportPrimitiveType::DataTypeRSMesh */ 381 "Element.DataType.RS_PROGRAM_FRAGMENT", /* RSExportPrimitiveType::DataTypeRSProgramFragment */ 382 "Element.DataType.RS_PROGRAM_VERTEX", /* RSExportPrimitiveType::DataTypeRSProgramVertex */ 383 "Element.DataType.RS_PROGRAM_RASTER", /* RSExportPrimitiveType::DataTypeRSProgramRaster */ 384 "Element.DataType.RS_PROGRAM_STORE", /* RSExportPrimitiveType::DataTypeRSProgramStore */ 385 "Element.DataType.RS_FONT", /* RSExportPrimitiveType::DataTypeRSFont */ 386 "Element.DataType.RS_MATRIX_2X2", /* RSExportPrimitiveType::DataTypeRSMatrix2x2 */ 387 "Element.DataType.RS_MATRIX_3X3", /* RSExportPrimitiveType::DataTypeRSMatrix3x3 */ 388 "Element.DataType.RS_MATRIX_4X4", /* RSExportPrimitiveType::DataTypeRSMatrix4x4 */ 389 }; 390 391 if((DT >= 0) && (DT < (sizeof(ElementDataTypeNameMap) / sizeof(const char*)))) 392 return ElementDataTypeNameMap[ DT ]; 393 else 394 return NULL; 395} 396 397bool RSReflection::openScriptFile(Context&C, const std::string& ClassName, std::string& ErrorMsg) { 398 if(!C.mUseStdout) { 399 C.mOF.clear(); 400 std::string _path = RSSlangReflectUtils::ComputePackagedPath( 401 mRSContext->getReflectJavaPathName(), C.getPackageName()); 402 403 RSSlangReflectUtils::mkdir_p(_path.c_str()); 404 C.mOF.open(( _path + "/" + ClassName + ".java" ).c_str()); 405 if(!C.mOF.good()) { 406 ErrorMsg = "failed to open file '" + _path + "/" + ClassName + ".java' for write"; 407 408 return false; 409 } 410 } 411 return true; 412} 413 414/****************************** Methods to generate script class ******************************/ 415bool RSReflection::genScriptClass(Context& C, const std::string& ClassName, std::string& ErrorMsg) { 416 /* Open the file */ 417 if (!openScriptFile(C, ClassName, ErrorMsg)) { 418 return false; 419 } 420 421 if(!C.startClass(Context::AM_Public, false, ClassName, RS_SCRIPT_CLASS_SUPER_CLASS_NAME, ErrorMsg)) 422 return false; 423 424 genScriptClassConstructor(C); 425 426 /* Reflect export variable */ 427 for(RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(); 428 I != mRSContext->export_vars_end(); 429 I++) 430 genExportVariable(C, *I); 431 432 /* Reflect export function */ 433 for(RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(); 434 I != mRSContext->export_funcs_end(); 435 I++) 436 genExportFunction(C, *I); 437 438 C.endClass(); 439 440 return true; 441} 442 443void RSReflection::genScriptClassConstructor(Context& C) { 444 C.indent() << "// Constructor" << endl; 445 C.startFunction(Context::AM_Public, false, NULL, C.getClassName(), 4, "RenderScript", "rs", 446 "Resources", "resources", 447 "int", "id", 448 "boolean", "isRoot"); 449 /* Call constructor of super class */ 450 C.indent() << "super(rs, resources, id, isRoot);" << endl; 451 452 /* If an exported variable has initial value, reflect it */ 453 454 for(RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(); 455 I != mRSContext->export_vars_end(); 456 I++) 457 { 458 const RSExportVar* EV = *I; 459 if(!EV->getInit().isUninit()) 460 genInitExportVariable(C, EV->getType(), EV->getName(), EV->getInit()); 461 } 462 463 C.endFunction(); 464 return; 465} 466 467void RSReflection::genInitBoolExportVariable(Context& C, const std::string& VarName, const APValue& Val) { 468 assert(!Val.isUninit() && "Not a valid initializer"); 469 470 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = "; 471 assert((Val.getKind() == APValue::Int) && "Bool type has wrong initial APValue"); 472 473 if (Val.getInt().getSExtValue() == 0) { 474 C.out() << "false"; 475 } else { 476 C.out() << "true"; 477 } 478 C.out() << ";" << endl; 479 480 return; 481} 482 483void RSReflection::genInitPrimitiveExportVariable(Context& C, const std::string& VarName, const APValue& Val) { 484 assert(!Val.isUninit() && "Not a valid initializer"); 485 486 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = "; 487 switch(Val.getKind()) { 488 case APValue::Int: C.out() << Val.getInt().getSExtValue(); break; 489 490 case APValue::Float: { 491 llvm::APFloat apf = Val.getFloat(); 492 if (apf.semanticsPrecision(apf.getSemantics()) == 24 /*llvm::APFloat::IEEEsingle*/) { 493 C.out() << apf.convertToFloat(); 494 } else { 495 C.out() << apf.convertToDouble(); 496 } 497 break; 498 } 499 500 case APValue::ComplexInt: 501 case APValue::ComplexFloat: 502 case APValue::LValue: 503 case APValue::Vector: 504 assert(false && "Primitive type cannot have such kind of initializer"); 505 break; 506 507 default: 508 assert(false && "Unknown kind of initializer"); 509 break; 510 } 511 C.out() << ";" << endl; 512 513 return; 514} 515 516void RSReflection::genInitExportVariable(Context& C, const RSExportType* ET, const std::string& VarName, const APValue& Val) { 517 assert(!Val.isUninit() && "Not a valid initializer"); 518 519 switch(ET->getClass()) { 520 case RSExportType::ExportClassPrimitive: 521 case RSExportType::ExportClassConstantArray: 522 { 523 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET); 524 if (EPT->getType() == RSExportPrimitiveType::DataTypeBool) { 525 genInitBoolExportVariable(C, VarName, Val); 526 } else { 527 genInitPrimitiveExportVariable(C, VarName, Val); 528 } 529 break; 530 } 531 532 case RSExportType::ExportClassPointer: 533 if(!Val.isInt() || Val.getInt().getSExtValue() != 0) 534 std::cout << "Initializer which is non-NULL to pointer type variable will be ignored" << endl; 535 break; 536 537 case RSExportType::ExportClassVector: 538 { 539 const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(ET); 540 switch(Val.getKind()) { 541 case APValue::Int: 542 case APValue::Float: 543 for(int i=0;i<EVT->getNumElement();i++) { 544 std::string Name = VarName + "." + GetVectorAccessor(i); 545 genInitPrimitiveExportVariable(C, Name, Val); 546 } 547 break; 548 549 case APValue::Vector: 550 { 551 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new " << GetVectorTypeName(EVT) << "();" << endl; 552 553 unsigned NumElements = std::min(static_cast<unsigned>(EVT->getNumElement()), Val.getVectorLength()); 554 for(unsigned i=0;i<NumElements;i++) { 555 const APValue& ElementVal = Val.getVectorElt(i); 556 std::string Name = VarName + "." + GetVectorAccessor(i); 557 genInitPrimitiveExportVariable(C, Name, ElementVal); 558 } 559 } 560 break; 561 } 562 } 563 break; 564 565 /* TODO: Resolving initializer of a record type variable is complex. It cannot obtain by just simply evaluating the initializer expression. */ 566 case RSExportType::ExportClassRecord: 567 { 568 /* 569 unsigned InitIndex = 0; 570 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 571 572 assert((Val.getKind() == APValue::Vector) && "Unexpected type of initializer for record type variable"); 573 574 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "RS_TYPE_CLASS_NAME_PREFIX << ERT->getName() << "."RS_TYPE_ITEM_CLASS_NAME"();" << endl; 575 576 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin(); 577 I != ERT->fields_end(); 578 I++) 579 { 580 const RSExportRecordType::Field* F = *I; 581 std::string FieldName = VarName + "." + F->getName(); 582 583 if(InitIndex > Val.getVectorLength()) 584 break; 585 586 genInitPrimitiveExportVariable(C, FieldName, Val.getVectorElt(InitIndex++)); 587 } 588 */ 589 assert(false && "Unsupported initializer for record type variable currently"); 590 } 591 break; 592 593 default: 594 assert(false && "Unknown class of type"); 595 break; 596 } 597 return; 598} 599 600void RSReflection::genExportVariable(Context& C, const RSExportVar* EV) { 601 const RSExportType* ET = EV->getType(); 602 603 C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << " = " << C.getNextExportVarSlot() << ";" << endl; 604 605 switch(ET->getClass()) { 606 case RSExportType::ExportClassPrimitive: 607 case RSExportType::ExportClassConstantArray: 608 genPrimitiveTypeExportVariable(C, EV); 609 break; 610 611 case RSExportType::ExportClassPointer: 612 genPointerTypeExportVariable(C, EV); 613 break; 614 615 case RSExportType::ExportClassVector: 616 genVectorTypeExportVariable(C, EV); 617 break; 618 619 case RSExportType::ExportClassRecord: 620 genRecordTypeExportVariable(C, EV); 621 break; 622 623 default: 624 assert(false && "Unknown class of type"); 625 break; 626 } 627 628 return; 629} 630 631void RSReflection::genExportFunction(Context& C, const RSExportFunc* EF) { 632 C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << " = " << C.getNextExportFuncSlot() << ";" << endl; 633 634 /* invoke_*() */ 635 Context::ArgTy Args; 636 637 for(RSExportFunc::const_param_iterator I = EF->params_begin(); 638 I != EF->params_end(); 639 I++) 640 { 641 const RSExportFunc::Parameter* P = *I; 642 Args.push_back( make_pair(GetTypeName(P->getType()), P->getName()) ); 643 } 644 645 C.startFunction(Context::AM_Public, false, "void", "invoke_" + EF->getName(), Args); 646 647 if(!EF->hasParam()) { 648 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");" << endl; 649 } else { 650 const RSExportRecordType* ERT = EF->getParamPacketType(); 651 std::string FieldPackerName = EF->getName() + "_fp"; 652 653 if(genCreateFieldPacker(C, ERT, FieldPackerName.c_str())) 654 genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str()); 655 656 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", " << FieldPackerName << ");" << endl; 657 } 658 659 C.endFunction(); 660 return; 661} 662 663void RSReflection::genPrimitiveTypeExportVariable(Context& C, const RSExportVar* EV) { 664 assert(( EV->getType()->getClass() == RSExportType::ExportClassPrimitive || 665 EV->getType()->getClass() == RSExportType::ExportClassConstantArray 666 ) && "Variable should be type of primitive here"); 667 668 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(EV->getType()); 669 const char* TypeName = GetPrimitiveTypeName(EPT); 670 671 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 672 673 /* set_*() */ 674 if(!EV->isConst()) { 675 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName, "v"); 676 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 677 678 if(EPT->isRSObjectType()) 679 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", (v == null) ? 0 : v.getID());" << endl; 680 else 681 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", v);" << endl; 682 683 C.endFunction(); 684 } 685 686 genGetExportVariable(C, TypeName, EV->getName()); 687 688 return; 689} 690 691void RSReflection::genPointerTypeExportVariable(Context& C, const RSExportVar* EV) { 692 const RSExportType* ET = EV->getType(); 693 const RSExportType* PointeeType; 694 std::string TypeName; 695 696 assert((ET->getClass() == RSExportType::ExportClassPointer) && "Variable should be type of pointer here"); 697 698 PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 699 TypeName = GetTypeName(ET); 700 701 /* bind_*() */ 702 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 703 704 C.startFunction(Context::AM_Public, false, "void", "bind_" + EV->getName(), 1, TypeName.c_str(), "v"); 705 706 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 707 C.indent() << "if(v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl; 708 709 if(PointeeType->getClass() == RSExportType::ExportClassRecord) 710 C.indent() << "else bindAllocation(v.getAllocation(), "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl; 711 else 712 C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl; 713 714 C.endFunction(); 715 716 genGetExportVariable(C, TypeName, EV->getName()); 717 718 return; 719} 720 721void RSReflection::genVectorTypeExportVariable(Context& C, const RSExportVar* EV) { 722 assert((EV->getType()->getClass() == RSExportType::ExportClassVector) && "Variable should be type of vector here"); 723 724 const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(EV->getType()); 725 const char* TypeName = GetVectorTypeName(EVT); 726 const char* FieldPackerName = "fp"; 727 728 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 729 730 /* set_*() */ 731 if(!EV->isConst()) { 732 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName, "v"); 733 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 734 735 if(genCreateFieldPacker(C, EVT, FieldPackerName)) 736 genPackVarOfType(C, EVT, "v", FieldPackerName); 737 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " << FieldPackerName << ");" << endl; 738 739 C.endFunction(); 740 } 741 742 genGetExportVariable(C, TypeName, EV->getName()); 743 return; 744} 745 746void RSReflection::genRecordTypeExportVariable(Context& C, const RSExportVar* EV) { 747 assert((EV->getType()->getClass() == RSExportType::ExportClassRecord) && "Variable should be type of struct here"); 748 749 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(EV->getType()); 750 std::string TypeName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName() + "."RS_TYPE_ITEM_CLASS_NAME; 751 const char* FieldPackerName = "fp"; 752 753 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl; 754 755 /* set_*() */ 756 if(!EV->isConst()) { 757 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName.c_str(), "v"); 758 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl; 759 760 if(genCreateFieldPacker(C, ERT, FieldPackerName)) 761 genPackVarOfType(C, ERT, "v", FieldPackerName); 762 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " << FieldPackerName << ");" << endl; 763 764 C.endFunction(); 765 } 766 767 genGetExportVariable(C, TypeName.c_str(), EV->getName()); 768 return; 769} 770 771void RSReflection::genGetExportVariable(Context& C, const std::string& TypeName, const std::string& VarName) { 772 C.startFunction(Context::AM_Public, false, TypeName.c_str(), "get_" + VarName, 0); 773 774 C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << endl; 775 776 C.endFunction(); 777 return; 778} 779 780/****************************** Methods to generate script class /end ******************************/ 781 782bool RSReflection::genCreateFieldPacker(Context& C, const RSExportType* ET, const char* FieldPackerName) { 783 size_t AllocSize = RSExportType::GetTypeAllocSize(ET); 784 if(AllocSize > 0) 785 C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker(" << AllocSize << ");" << endl; 786 else 787 return false; 788 return true; 789} 790 791void RSReflection::genPackVarOfType(Context& C, const RSExportType* ET, const char* VarName, const char* FieldPackerName) { 792 switch(ET->getClass()) { 793 case RSExportType::ExportClassPrimitive: 794 case RSExportType::ExportClassConstantArray: 795 case RSExportType::ExportClassVector: 796 C.indent() << FieldPackerName << "." << GetPackerAPIName(static_cast<const RSExportPrimitiveType*>(ET)) << "(" << VarName << ");" << endl; 797 break; 798 799 case RSExportType::ExportClassPointer: 800 { 801 /* Must reflect as type Allocation in Java */ 802 const RSExportType* PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 803 804 if(PointeeType->getClass() != RSExportType::ExportClassRecord) 805 C.indent() << FieldPackerName << ".addI32(" << VarName << ".getPtr());" << endl; 806 else 807 C.indent() << FieldPackerName << ".addI32(" << VarName << ".getAllocation().getPtr());" << endl; 808 } 809 break; 810 811 case RSExportType::ExportClassRecord: 812 { 813 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 814 int Pos = 0; /* relative pos from now on in field packer */ 815 816 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin(); 817 I != ERT->fields_end(); 818 I++) 819 { 820 const RSExportRecordType::Field* F = *I; 821 std::string FieldName; 822 size_t FieldOffset = F->getOffsetInParent(); 823 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 824 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 825 826 if(VarName != NULL) 827 FieldName = VarName + ("." + F->getName()); 828 else 829 FieldName = F->getName(); 830 831 if(FieldOffset > Pos) 832 C.indent() << FieldPackerName << ".skip(" << (FieldOffset - Pos) << ");" << endl; 833 834 genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName); 835 836 if(FieldAllocSize > FieldStoreSize) /* there's padding in the field type */ 837 C.indent() << FieldPackerName << ".skip(" << (FieldAllocSize - FieldStoreSize) << ");" << endl; 838 839 Pos = FieldOffset + FieldAllocSize; 840 } 841 842 /* There maybe some padding after the struct */ 843 size_t Padding = RSExportType::GetTypeAllocSize(ERT) - Pos; 844 if(Padding > 0) 845 C.indent() << FieldPackerName << ".skip(" << Padding << ");" << endl; 846 } 847 break; 848 849 default: 850 assert(false && "Unknown class of type"); 851 break; 852 } 853 854 return; 855} 856 857/****************************** Methods to generate type class ******************************/ 858bool RSReflection::genTypeClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg) { 859 std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName(); 860 861 /* Open the file */ 862 if (!openScriptFile(C, ClassName, ErrorMsg)) { 863 return false; 864 } 865 866 if(!C.startClass(Context::AM_Public, false, ClassName, RS_TYPE_CLASS_SUPER_CLASS_NAME, ErrorMsg)) 867 return false; 868 869 if(!genTypeItemClass(C, ERT, ErrorMsg)) 870 return false; 871 872 /* Declare item buffer and item buffer packer */ 873 C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[];" << endl; 874 C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";" << endl; 875 876 genTypeClassConstructor(C, ERT); 877 genTypeClassCopyToArray(C, ERT); 878 genTypeClasSet(C, ERT); 879 genTypeClasGet(C, ERT); 880 genTypeClasCopyAll(C, ERT); 881 882 C.endClass(); 883 884 return true; 885} 886 887bool RSReflection::genTypeItemClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg) { 888 C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME; 889 C.startBlock(); 890 891 C.indent() << "public static final int sizeof = " << RSExportType::GetTypeAllocSize(ERT) << ";" << endl; 892 893 /* Member elements */ 894 C.out() << endl; 895 for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin(); 896 FI != ERT->fields_end(); 897 FI++) { 898 C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName() << ";" << endl; 899 } 900 901 /* Constructor */ 902 C.out() << endl; 903 C.indent() << RS_TYPE_ITEM_CLASS_NAME"()"; 904 C.startBlock(); 905 906 for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin(); 907 FI != ERT->fields_end(); 908 FI++) 909 { 910 const RSExportRecordType::Field* F = *FI; 911 if( (F->getType()->getClass() == RSExportType::ExportClassVector) || 912 (F->getType()->getClass() == RSExportType::ExportClassRecord) || 913 (F->getType()->getClass() == RSExportType::ExportClassConstantArray) 914 ) { 915 C.indent() << F->getName() << " = new " << GetTypeName(F->getType()) << "();" << endl; 916 } 917 } 918 919 C.endBlock(); /* end Constructor */ 920 921 C.endBlock(); /* end Item class */ 922 923 924 return true; 925} 926 927void RSReflection::genTypeClassConstructor(Context& C, const RSExportRecordType* ERT) { 928 const char* RenderScriptVar = "rs"; 929 930 C.startFunction(Context::AM_Public, true, "Element", "createElement", 1, "RenderScript", RenderScriptVar); 931 genBuildElement(C, ERT, RenderScriptVar); 932 C.endFunction(); 933 934 C.startFunction(Context::AM_Public, false, NULL, C.getClassName(), 2, "RenderScript", RenderScriptVar, 935 "int", "count"); 936 937 C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << endl; 938 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << endl; 939 C.indent() << "mElement = createElement(" << RenderScriptVar << ");" << endl; 940 /* Call init() in super class */ 941 C.indent() << "init(" << RenderScriptVar << ", count);" << endl; 942 C.endFunction(); 943 944 return; 945} 946 947void RSReflection::genTypeClassCopyToArray(Context& C, const RSExportRecordType* ERT) { 948 C.startFunction(Context::AM_Private, false, "void", "copyToArray", 2, RS_TYPE_ITEM_CLASS_NAME, "i", 949 "int", "index"); 950 951 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_PACKER_NAME" == null) "RS_TYPE_ITEM_BUFFER_PACKER_NAME" = new FieldPacker("RS_TYPE_ITEM_CLASS_NAME".sizeof * mType.getX() /* count */);" << endl; 952 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);" << endl; 953 954 genPackVarOfType(C, ERT, "i", RS_TYPE_ITEM_BUFFER_PACKER_NAME); 955 956 C.endFunction(); 957 return; 958} 959 960void RSReflection::genTypeClasSet(Context& C, const RSExportRecordType* ERT) { 961 C.startFunction(Context::AM_Public, false, "void", "set", 3, RS_TYPE_ITEM_CLASS_NAME, "i", 962 "int", "index", 963 "boolean", "copyNow"); 964 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) "RS_TYPE_ITEM_BUFFER_NAME" = new "RS_TYPE_ITEM_CLASS_NAME"[mType.getX() /* count */];" << endl; 965 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << endl; 966 967 C.indent() << "if (copyNow) "; 968 C.startBlock(); 969 970 C.indent() << "copyToArray(i, index);" << endl; 971 //C.indent() << "mAllocation.subData1D(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof, "RS_TYPE_ITEM_CLASS_NAME".sizeof, "RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << endl; 972 C.indent() << "mAllocation.subData1D(index, 1, "RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << endl; 973 974 C.endBlock(); /* end if (copyNow) */ 975 976 C.endFunction(); 977 return; 978} 979 980void RSReflection::genTypeClasGet(Context& C, const RSExportRecordType* ERT) { 981 C.startFunction(Context::AM_Public, false, RS_TYPE_ITEM_CLASS_NAME, "get", 1, "int", "index"); 982 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return null;" << endl; 983 C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index];" << endl; 984 C.endFunction(); 985 return; 986} 987 988void RSReflection::genTypeClasCopyAll(Context& C, const RSExportRecordType* ERT) { 989 C.startFunction(Context::AM_Public, false, "void", "copyAll", 0); 990 991 C.indent() << "for (int ct=0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++) copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);" << endl; 992 C.indent() << "mAllocation.data("RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << endl; 993 994 C.endFunction(); 995 return; 996} 997 998/****************************** Methods to generate type class /end ******************************/ 999 1000/******************** Methods to create Element in Java of given record type ********************/ 1001void RSReflection::genBuildElement(Context& C, const RSExportRecordType* ERT, const char* RenderScriptVar) { 1002 const char* ElementBuilderName = "eb"; 1003 1004 /* Create element builder */ 1005 // C.startBlock(true); 1006 1007 C.indent() << "Element.Builder " << ElementBuilderName << " = new Element.Builder(" << RenderScriptVar << ");" << endl; 1008 1009 /* eb.add(...) */ 1010 genAddElementToElementBuilder(C, ERT, "", ElementBuilderName, RenderScriptVar); 1011 1012 C.indent() << "return " << ElementBuilderName << ".create();" << endl; 1013 1014 // C.endBlock(); 1015 return; 1016} 1017 1018#define EB_ADD(x, ...) \ 1019 C.indent() << ElementBuilderName << ".add(Element." << x ##__VA_ARGS__ ", \"" << VarName << "\");" << endl 1020 1021void RSReflection::genAddElementToElementBuilder(Context& C, const RSExportType* ET, const std::string& VarName, const char* ElementBuilderName, const char* RenderScriptVar) { 1022 const char* ElementConstruct = GetBuiltinElementConstruct(ET); 1023 1024 if(ElementConstruct != NULL) { 1025 EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")"); 1026 } else { 1027 if ((ET->getClass() == RSExportType::ExportClassPrimitive) || 1028 (ET->getClass() == RSExportType::ExportClassVector) || 1029 (ET->getClass() == RSExportType::ExportClassConstantArray) 1030 ) { 1031 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET); 1032 const char* DataKindName = GetElementDataKindName(EPT->getKind()); 1033 const char* DataTypeName = GetElementDataTypeName(EPT->getType()); 1034 int Size = (ET->getClass() == RSExportType::ExportClassVector) ? static_cast<const RSExportVectorType*>(ET)->getNumElement() : 1; 1035 1036 switch(EPT->getKind()) { 1037 case RSExportPrimitiveType::DataKindColor: 1038 case RSExportPrimitiveType::DataKindPosition: 1039 case RSExportPrimitiveType::DataKindTexture: 1040 case RSExportPrimitiveType::DataKindNormal: 1041 case RSExportPrimitiveType::DataKindPointSize: 1042 /* Element.createAttrib() */ 1043 EB_ADD("createAttrib(" << RenderScriptVar << ", " << DataTypeName << ", " << DataKindName << ", " << Size << ")"); 1044 break; 1045 1046 case RSExportPrimitiveType::DataKindIndex: 1047 /* Element.createIndex() */ 1048 EB_ADD("createAttrib(" << RenderScriptVar << ")"); 1049 break; 1050 1051 case RSExportPrimitiveType::DataKindPixelL: 1052 case RSExportPrimitiveType::DataKindPixelA: 1053 case RSExportPrimitiveType::DataKindPixelLA: 1054 case RSExportPrimitiveType::DataKindPixelRGB: 1055 case RSExportPrimitiveType::DataKindPixelRGBA: 1056 /* Element.createPixel() */ 1057 EB_ADD("createVector(" << RenderScriptVar << ", " << DataTypeName << ", " << DataKindName << ")"); 1058 break; 1059 1060 case RSExportPrimitiveType::DataKindUser: 1061 default: 1062 if (EPT->getClass() == RSExportType::ExportClassPrimitive || EPT->getClass() == RSExportType::ExportClassConstantArray) { 1063 /* Element.createUser() */ 1064 EB_ADD("createUser(" << RenderScriptVar << ", " << DataTypeName << ")"); 1065 } else { /* (ET->getClass() == RSExportType::ExportClassVector) must hold here */ 1066 /* Element.createVector() */ 1067 EB_ADD("createVector(" << RenderScriptVar << ", " << DataTypeName << ", " << Size << ")"); 1068 } 1069 break; 1070 } 1071 } else if(ET->getClass() == RSExportType::ExportClassPointer) { 1072 /* Pointer type variable should be resolved in GetBuiltinElementConstruct() */ 1073 assert(false && "??"); 1074 } else if(ET->getClass() == RSExportType::ExportClassRecord) { 1075 /* 1076 * Simalar to genPackVarOfType. 1077 * 1078 * TODO: Generalize these two function such that there's no duplicated codes. 1079 */ 1080 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 1081 int Pos = 0; /* relative pos from now on */ 1082 1083 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin(); 1084 I != ERT->fields_end(); 1085 I++) 1086 { 1087 const RSExportRecordType::Field* F = *I; 1088 std::string FieldName; 1089 size_t FieldOffset = F->getOffsetInParent(); 1090 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1091 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 1092 1093 if(!VarName.empty()) 1094 FieldName = VarName + "." + F->getName(); 1095 else 1096 FieldName = F->getName(); 1097 1098 /* alignment */ 1099 genAddPaddingToElementBuiler(C, (FieldOffset - Pos), ElementBuilderName, RenderScriptVar); 1100 1101 /* eb.add(...) */ 1102 genAddElementToElementBuilder(C, (*I)->getType(), FieldName, ElementBuilderName, RenderScriptVar); 1103 1104 /* There is padding within the field type */ 1105 genAddPaddingToElementBuiler(C, (FieldAllocSize - FieldStoreSize), ElementBuilderName, RenderScriptVar); 1106 1107 Pos = FieldOffset + FieldAllocSize; 1108 } 1109 1110 /* There maybe some padding after the struct */ 1111 //unsigned char align = RSExportType::GetTypeAlignment(ERT); 1112 //size_t siz = RSExportType::GetTypeAllocSize(ERT); 1113 size_t siz1 = RSExportType::GetTypeStoreSize(ERT); 1114 1115 genAddPaddingToElementBuiler(C, siz1 - Pos, ElementBuilderName, RenderScriptVar); 1116 } else { 1117 assert(false && "Unknown class of type"); 1118 } 1119 } 1120} 1121 1122void RSReflection::genAddPaddingToElementBuiler(Context& C, size_t PaddingSize, const char* ElementBuilderName, const char* RenderScriptVar) { 1123 while(PaddingSize > 0) { 1124 const std::string& VarName = C.createPaddingField(); 1125 if(PaddingSize >= 4) { 1126 EB_ADD("U32(" << RenderScriptVar << ")"); 1127 PaddingSize -= 4; 1128 } else if(PaddingSize >= 2) { 1129 EB_ADD("U16(" << RenderScriptVar << ")"); 1130 PaddingSize -= 2; 1131 } else if(PaddingSize >= 1) { 1132 EB_ADD("U8(" << RenderScriptVar << ")"); 1133 PaddingSize -= 1; 1134 } 1135 } 1136 return; 1137} 1138 1139#undef EB_ADD 1140/******************** Methods to create Element in Java of given record type /end ********************/ 1141 1142bool RSReflection::reflect(const char* OutputPackageName, const std::string& InputFileName, const std::string& OutputBCFileName) { 1143 Context *C = NULL; 1144 std::string ResourceId = ""; 1145 1146 if(!GetClassNameFromFileName(OutputBCFileName, ResourceId)) 1147 return false; 1148 1149 if(ResourceId.empty()) 1150 ResourceId = "<Resource ID>"; 1151 1152 if((OutputPackageName == NULL) || (*OutputPackageName == '\0') || strcmp(OutputPackageName, "-") == 0) 1153 C = new Context(InputFileName, "<Package Name>", ResourceId, true); 1154 else 1155 C = new Context(InputFileName, OutputPackageName, ResourceId, false); 1156 1157 if(C != NULL) { 1158 std::string ErrorMsg, ScriptClassName; 1159 /* class ScriptC_<ScriptName> */ 1160 if(!GetClassNameFromFileName(InputFileName, ScriptClassName)) 1161 return false; 1162 1163 if(ScriptClassName.empty()) 1164 ScriptClassName = "<Input Script Name>"; 1165 1166 ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX); 1167 1168 if (mRSContext->getLicenseNote() != NULL) { 1169 C->setLicenseNote(*(mRSContext->getLicenseNote())); 1170 } 1171 1172 if(!genScriptClass(*C, ScriptClassName, ErrorMsg)) { 1173 std::cerr << "Failed to generate class " << ScriptClassName << " (" << ErrorMsg << ")" << endl; 1174 return false; 1175 } 1176 1177 /* class ScriptField_<TypeName> */ 1178 for(RSContext::const_export_type_iterator TI = mRSContext->export_types_begin(); 1179 TI != mRSContext->export_types_end(); 1180 TI++) 1181 { 1182 const RSExportType* ET = TI->getValue(); 1183 1184 if(ET->getClass() == RSExportType::ExportClassRecord) { 1185 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET); 1186 1187 if(!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) { 1188 std::cerr << "Failed to generate type class for struct '" << ERT->getName() << "' (" << ErrorMsg << ")" << endl; 1189 return false; 1190 } 1191 } 1192 } 1193 } 1194 1195 return true; 1196} 1197 1198/****************************** RSReflection::Context ******************************/ 1199const char* const RSReflection::Context::ApacheLicenseNote = 1200 "/*\n" 1201 " * Copyright (C) 2010 The Android Open Source Project\n" 1202 " *\n" 1203 " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" 1204 " * you may not use this file except in compliance with the License.\n" 1205 " * You may obtain a copy of the License at\n" 1206 " *\n" 1207 " * http://www.apache.org/licenses/LICENSE-2.0\n" 1208 " *\n" 1209 " * Unless required by applicable law or agreed to in writing, software\n" 1210 " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" 1211 " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" 1212 " * See the License for the specific language governing permissions and\n" 1213 " * limitations under the License.\n" 1214 " */\n" 1215 "\n"; 1216 1217const char* const RSReflection::Context::Import[] = { 1218 /* RenderScript java class */ 1219 "android.renderscript.*", 1220 /* Import R */ 1221 "android.content.res.Resources", 1222 /* Import for debugging */ 1223 "android.util.Log", 1224}; 1225 1226const char* RSReflection::Context::AccessModifierStr(AccessModifier AM) { 1227 switch(AM) { 1228 case AM_Public: return "public"; break; 1229 case AM_Protected: return "protected"; break; 1230 case AM_Private: return "private"; break; 1231 default: return ""; break; 1232 } 1233} 1234 1235bool RSReflection::Context::startClass(AccessModifier AM, bool IsStatic, const std::string& ClassName, const char* SuperClassName, std::string& ErrorMsg) { 1236 if(mVerbose) 1237 std::cout << "Generating " << ClassName << ".java ..." << endl; 1238 1239 /* License */ 1240 out() << mLicenseNote; 1241 1242 /* Notice of generated file */ 1243 out() << "/*" << endl; 1244 out() << " * This file is auto-generated. DO NOT MODIFY!" << endl; 1245 out() << " * The source RenderScript file: " << mInputRSFile << endl; 1246 out() << " */" << endl; 1247 1248 /* Package */ 1249 if(!mPackageName.empty()) 1250 out() << "package " << mPackageName << ";" << endl; 1251 out() << endl; 1252 1253 /* Imports */ 1254 for(int i=0;i<(sizeof(Import)/sizeof(const char*));i++) 1255 out() << "import " << Import[i] << ";" << endl; 1256 out() << endl; 1257 1258 /* All reflected classes should be annotated as hidden, so that they won't be exposed in SDK. */ 1259 out() << "/**" << endl; 1260 out() << " * @hide" << endl; 1261 out() << " */" << endl; 1262 1263 out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class " << ClassName; 1264 if(SuperClassName != NULL) 1265 out() << " extends " << SuperClassName; 1266 1267 startBlock(); 1268 1269 mClassName = ClassName; 1270 1271 return true; 1272} 1273 1274void RSReflection::Context::endClass() { 1275 endBlock(); 1276 if(!mUseStdout) 1277 mOF.close(); 1278 clear(); 1279 return; 1280} 1281 1282void RSReflection::Context::startBlock(bool ShouldIndent) { 1283 if(ShouldIndent) 1284 indent() << "{" << endl; 1285 else 1286 out() << " {" << endl; 1287 incIndentLevel(); 1288 return; 1289} 1290 1291void RSReflection::Context::endBlock() { 1292 decIndentLevel(); 1293 indent() << "}" << endl << endl; 1294 return; 1295} 1296 1297void RSReflection::Context::startTypeClass(const std::string& ClassName) { 1298 indent() << "public static class " << ClassName; 1299 startBlock(); 1300 return; 1301} 1302 1303void RSReflection::Context::endTypeClass() { 1304 endBlock(); 1305 return; 1306} 1307 1308void RSReflection::Context::startFunction(AccessModifier AM, bool IsStatic, const char* ReturnType, const std::string& FunctionName, int Argc, ...) { 1309 ArgTy Args; 1310 va_list vl; 1311 va_start(vl, Argc); 1312 1313 for(int i=0;i<Argc;i++) { 1314 const char* ArgType = va_arg(vl, const char*); 1315 const char* ArgName = va_arg(vl, const char*); 1316 1317 Args.push_back( make_pair(ArgType, ArgName) ); 1318 } 1319 va_end(vl); 1320 1321 startFunction(AM, IsStatic, ReturnType, FunctionName, Args); 1322 1323 return; 1324} 1325 1326void RSReflection::Context::startFunction(AccessModifier AM, 1327 bool IsStatic, 1328 const char* ReturnType, 1329 const std::string& FunctionName, 1330 const ArgTy& Args) 1331{ 1332 indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ") << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "("; 1333 1334 bool FirstArg = true; 1335 for(ArgTy::const_iterator I = Args.begin(); 1336 I != Args.end(); 1337 I++) 1338 { 1339 if(!FirstArg) 1340 out() << ", "; 1341 else 1342 FirstArg = false; 1343 1344 out() << I->first << " " << I->second; 1345 } 1346 1347 out() << ")"; 1348 startBlock(); 1349 1350 return; 1351} 1352 1353void RSReflection::Context::endFunction() { 1354 endBlock(); 1355 return; 1356} 1357 1358} /* namespace slang */ 1359