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