blob: 07708b575f96d653d96a1b4ba583f289cdda2f0d [file] [log] [blame]
zonr6315f762010-10-05 15:35:14 +08001#include "slang_rs_reflection.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002
3#include <utility>
4#include <cstdarg>
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07005#include <cctype>
6#include <sys/stat.h>
Shih-wei Liao462aefd2010-06-04 15:32:04 -07007
zonr6315f762010-10-05 15:35:14 +08008#include "llvm/ADT/APFloat.h"
9
Zonr Chang8c6d9b22010-10-07 18:01:19 +080010#include "slang_utils.h"
zonr6315f762010-10-05 15:35:14 +080011#include "slang_rs_context.h"
12#include "slang_rs_export_var.h"
13#include "slang_rs_export_func.h"
14#include "slang_rs_reflect_utils.h"
15
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070016#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_"
17#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC"
Shih-wei Liao8b1d0dd2010-07-15 18:56:55 -070018
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070019#define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_"
20#define RS_TYPE_CLASS_SUPER_CLASS_NAME "android.renderscript.Script.FieldBase"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070021
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070022#define RS_TYPE_ITEM_CLASS_NAME "Item"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070023
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070024#define RS_TYPE_ITEM_BUFFER_NAME "mItemArray"
25#define RS_TYPE_ITEM_BUFFER_PACKER_NAME "mIOBuffer"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070026
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070027#define RS_EXPORT_VAR_INDEX_PREFIX "mExportVarIdx_"
28#define RS_EXPORT_VAR_PREFIX "mExportVar_"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070029
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070030#define RS_EXPORT_FUNC_INDEX_PREFIX "mExportFuncIdx_"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070031
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070032#define RS_EXPORT_VAR_ALLOCATION_PREFIX "mAlloction_"
33#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070034
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070035using namespace slang;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070036
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070037// Some utility function using internal in RSReflection
38static bool GetClassNameFromFileName(const std::string &FileName,
39 std::string &ClassName) {
40 ClassName.clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -070041
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070042 if (FileName.empty() || (FileName == "-"))
Shih-wei Liao462aefd2010-06-04 15:32:04 -070043 return true;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070044
45 ClassName =
46 RSSlangReflectUtils::JavaClassNameFromRSFileName(FileName.c_str());
47
48 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070049}
50
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070051static const char *GetPrimitiveTypeName(const RSExportPrimitiveType *EPT) {
52 static const char *PrimitiveTypeJavaNameMap[] = {
Shih-wei Liao91a37832010-10-03 19:11:51 -070053 "", // RSExportPrimitiveType::DataTypeFloat16
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070054 "float", // RSExportPrimitiveType::DataTypeFloat32
55 "double", // RSExportPrimitiveType::DataTypeFloat64
56 "byte", // RSExportPrimitiveType::DataTypeSigned8
57 "short", // RSExportPrimitiveType::DataTypeSigned16
58 "int", // RSExportPrimitiveType::DataTypeSigned32
59 "long", // RSExportPrimitiveType::DataTypeSigned64
60 "short", // RSExportPrimitiveType::DataTypeUnsigned8
61 "int", // RSExportPrimitiveType::DataTypeUnsigned16
62 "long", // RSExportPrimitiveType::DataTypeUnsigned32
63 "long", // RSExportPrimitiveType::DataTypeUnsigned64
Shih-wei Liao91a37832010-10-03 19:11:51 -070064 "boolean", // RSExportPrimitiveType::DataTypeBoolean
Shih-wei Liao462aefd2010-06-04 15:32:04 -070065
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070066 "int", // RSExportPrimitiveType::DataTypeUnsigned565
67 "int", // RSExportPrimitiveType::DataTypeUnsigned5551
68 "int", // RSExportPrimitiveType::DataTypeUnsigned4444
Shih-wei Liao462aefd2010-06-04 15:32:04 -070069
Zonr Chang92b344a2010-10-05 20:39:03 +080070 "", // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
71 "", // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
72 "", // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
Shih-wei Liaodd35e492010-06-21 14:42:40 -070073
Zonr Chang92b344a2010-10-05 20:39:03 +080074 "Element", // RSExportPrimitiveType::DataTypeRSElement
75 "Type", // RSExportPrimitiveType::DataTypeRSType
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070076 "Allocation", // RSExportPrimitiveType::DataTypeRSAllocation
Zonr Chang92b344a2010-10-05 20:39:03 +080077 "Sampler", // RSExportPrimitiveType::DataTypeRSSampler
78 "Script", // RSExportPrimitiveType::DataTypeRSScript
79 "Mesh", // RSExportPrimitiveType::DataTypeRSMesh
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070080 "ProgramFragment", // RSExportPrimitiveType::DataTypeRSProgramFragment
81 "ProgramVertex", // RSExportPrimitiveType::DataTypeRSProgramVertex
82 "ProgramRaster", // RSExportPrimitiveType::DataTypeRSProgramRaster
83 "ProgramStore", // RSExportPrimitiveType::DataTypeRSProgramStore
84 "Font", // RSExportPrimitiveType::DataTypeRSFont
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070085 };
86 unsigned TypeId = EPT->getType();
Shih-wei Liao462aefd2010-06-04 15:32:04 -070087
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070088 if (TypeId < (sizeof(PrimitiveTypeJavaNameMap) / sizeof(const char*))) {
89 return PrimitiveTypeJavaNameMap[ EPT->getType() ];
90 }
91
92 assert(false && "GetPrimitiveTypeName : Unknown primitive data type");
93 return NULL;
94}
95
96static const char *GetVectorTypeName(const RSExportVectorType *EVT) {
97 static const char *VectorTypeJavaNameMap[][3] = {
98 /* 0 */ { "Byte2", "Byte3", "Byte4" },
99 /* 1 */ { "Short2", "Short3", "Short4" },
100 /* 2 */ { "Int2", "Int3", "Int4" },
101 /* 3 */ { "Long2", "Long3", "Long4" },
102 /* 4 */ { "Float2", "Float3", "Float4" },
103 };
104
105 const char **BaseElement = NULL;
106
107 switch (EVT->getType()) {
Shih-wei Liao91a37832010-10-03 19:11:51 -0700108 case RSExportPrimitiveType::DataTypeSigned8:
109 case RSExportPrimitiveType::DataTypeBoolean: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700110 BaseElement = VectorTypeJavaNameMap[0];
111 break;
Shih-wei Liao1f0d88f2010-06-25 00:15:24 -0700112 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700113 case RSExportPrimitiveType::DataTypeSigned16:
114 case RSExportPrimitiveType::DataTypeUnsigned8: {
115 BaseElement = VectorTypeJavaNameMap[1];
116 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700117 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700118 case RSExportPrimitiveType::DataTypeSigned32:
119 case RSExportPrimitiveType::DataTypeUnsigned16: {
120 BaseElement = VectorTypeJavaNameMap[2];
121 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700122 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700123 case RSExportPrimitiveType::DataTypeSigned64:
124 case RSExportPrimitiveType::DataTypeUnsigned32: {
125 BaseElement = VectorTypeJavaNameMap[3];
126 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700127 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700128 case RSExportPrimitiveType::DataTypeFloat32: {
129 BaseElement = VectorTypeJavaNameMap[4];
130 break;
131 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700132 default: {
133 assert(false && "RSReflection::genElementTypeName : Unsupported vector "
134 "element data type");
135 break;
136 }
137 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700138
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700139 assert((EVT->getNumElement() > 1) &&
140 (EVT->getNumElement() <= 4) &&
141 "Number of element in vector type is invalid");
142
143 return BaseElement[EVT->getNumElement() - 2];
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700144}
145
Zonr Chang92b344a2010-10-05 20:39:03 +0800146static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) {
147 static const char *MatrixTypeJavaNameMap[] = {
148 /* 2x2 */ "Matrix2f",
149 /* 3x3 */ "Matrix3f",
150 /* 4x4 */ "Matrix4f",
151 };
152 unsigned Dim = EMT->getDim();
153
154 if ((Dim - 2) < (sizeof(MatrixTypeJavaNameMap) / sizeof(const char*)))
155 return MatrixTypeJavaNameMap[ EMT->getDim() - 2 ];
156
157 assert(false && "GetMatrixTypeName : Unsupported matrix dimension");
158 return NULL;
159}
160
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700161static const char *GetVectorAccessor(int Index) {
162 static const char *VectorAccessorMap[] = {
163 /* 0 */ "x",
164 /* 1 */ "y",
165 /* 2 */ "z",
166 /* 3 */ "w",
167 };
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700168
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700169 assert((Index >= 0) &&
170 (Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) &&
171 "Out-of-bound index to access vector member");
172
173 return VectorAccessorMap[Index];
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700174}
175
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700176static const char *GetPackerAPIName(const RSExportPrimitiveType *EPT) {
zonr6315f762010-10-05 15:35:14 +0800177 static const char *PrimitiveTypePackerAPINameMap[] = {
Shih-wei Liao91a37832010-10-03 19:11:51 -0700178 "", // RSExportPrimitiveType::DataTypeFloat16
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700179 "addF32", // RSExportPrimitiveType::DataTypeFloat32
180 "addF64", // RSExportPrimitiveType::DataTypeFloat64
181 "addI8", // RSExportPrimitiveType::DataTypeSigned8
182 "addI16", // RSExportPrimitiveType::DataTypeSigned16
183 "addI32", // RSExportPrimitiveType::DataTypeSigned32
184 "addI64", // RSExportPrimitiveType::DataTypeSigned64
185 "addU8", // RSExportPrimitiveType::DataTypeUnsigned8
186 "addU16", // RSExportPrimitiveType::DataTypeUnsigned16
187 "addU32", // RSExportPrimitiveType::DataTypeUnsigned32
188 "addU64", // RSExportPrimitiveType::DataTypeUnsigned64
Shih-wei Liao91a37832010-10-03 19:11:51 -0700189 "addBoolean", // RSExportPrimitiveType::DataTypeBoolean
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700190
191 "addU16", // RSExportPrimitiveType::DataTypeUnsigned565
192 "addU16", // RSExportPrimitiveType::DataTypeUnsigned5551
193 "addU16", // RSExportPrimitiveType::DataTypeUnsigned4444
194
Shih-wei Liao91a37832010-10-03 19:11:51 -0700195 "addObj", // RSExportPrimitiveType::DataTypeRSMatrix2x2
196 "addObj", // RSExportPrimitiveType::DataTypeRSMatrix3x3
197 "addObj", // RSExportPrimitiveType::DataTypeRSMatrix4x4
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700198
199 "addObj", // RSExportPrimitiveType::DataTypeRSElement
200 "addObj", // RSExportPrimitiveType::DataTypeRSType
201 "addObj", // RSExportPrimitiveType::DataTypeRSAllocation
202 "addObj", // RSExportPrimitiveType::DataTypeRSSampler
203 "addObj", // RSExportPrimitiveType::DataTypeRSScript
204 "addObj", // RSExportPrimitiveType::DataTypeRSMesh
205 "addObj", // RSExportPrimitiveType::DataTypeRSProgramFragment
206 "addObj", // RSExportPrimitiveType::DataTypeRSProgramVertex
207 "addObj", // RSExportPrimitiveType::DataTypeRSProgramRaster
208 "addObj", // RSExportPrimitiveType::DataTypeRSProgramStore
209 "addObj", // RSExportPrimitiveType::DataTypeRSFont
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700210 };
211 unsigned TypeId = EPT->getType();
212
213 if (TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char*)))
214 return PrimitiveTypePackerAPINameMap[ EPT->getType() ];
215
216 assert(false && "GetPackerAPIName : Unknown primitive data type");
217 return NULL;
218}
219
220static std::string GetTypeName(const RSExportType *ET) {
221 switch (ET->getClass()) {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800222 case RSExportType::ExportClassPrimitive: {
zonr6315f762010-10-05 15:35:14 +0800223 return GetPrimitiveTypeName(
224 static_cast<const RSExportPrimitiveType*>(ET));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700225 }
226 case RSExportType::ExportClassPointer: {
227 const RSExportType *PointeeType =
228 static_cast<const RSExportPointerType*>(ET)->getPointeeType();
229
230 if (PointeeType->getClass() != RSExportType::ExportClassRecord)
231 return "Allocation";
232 else
233 return RS_TYPE_CLASS_NAME_PREFIX + PointeeType->getName();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700234 }
235 case RSExportType::ExportClassVector: {
236 return GetVectorTypeName(static_cast<const RSExportVectorType*>(ET));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700237 }
Zonr Chang92b344a2010-10-05 20:39:03 +0800238 case RSExportType::ExportClassMatrix: {
239 return GetMatrixTypeName(static_cast<const RSExportMatrixType*>(ET));
Zonr Chang2e1dba62010-10-05 22:20:11 +0800240 }
241 case RSExportType::ExportClassConstantArray: {
242 const RSExportConstantArrayType* CAT =
243 static_cast<const RSExportConstantArrayType*>(ET);
244 std::string ElementTypeName = GetTypeName(CAT->getElementType());
245 ElementTypeName.append("[]");
246 return ElementTypeName;
Zonr Chang92b344a2010-10-05 20:39:03 +0800247 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700248 case RSExportType::ExportClassRecord: {
zonr6315f762010-10-05 15:35:14 +0800249 return RS_TYPE_CLASS_NAME_PREFIX + ET->getName() +
250 "."RS_TYPE_ITEM_CLASS_NAME;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700251 }
252 default: {
253 assert(false && "Unknown class of type");
254 }
255 }
256
257 return "";
258}
259
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700260static const char *GetTypeNullValue(const RSExportType *ET) {
261 switch (ET->getClass()) {
262 case RSExportType::ExportClassPrimitive: {
Zonr Chang1ab1a452010-10-06 18:28:30 +0800263 const RSExportPrimitiveType *EPT =
264 static_cast<const RSExportPrimitiveType*>(ET);
265 if (EPT->isRSObjectType())
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700266 return "null";
Zonr Chang1ab1a452010-10-06 18:28:30 +0800267 else if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean)
268 return "false";
Shih-wei Liaocf950c42010-10-06 03:44:40 -0700269 else
270 return "0";
271 break;
272 }
273 case RSExportType::ExportClassPointer:
274 case RSExportType::ExportClassVector:
275 case RSExportType::ExportClassMatrix:
276 case RSExportType::ExportClassConstantArray:
277 case RSExportType::ExportClassRecord: {
278 return "null";
279 break;
280 }
281 default: {
282 assert(false && "Unknown class of type");
283 }
284 }
285 return "";
286}
287
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700288static const char *GetBuiltinElementConstruct(const RSExportType *ET) {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800289 if (ET->getClass() == RSExportType::ExportClassPrimitive) {
zonr6315f762010-10-05 15:35:14 +0800290 const RSExportPrimitiveType *EPT =
291 static_cast<const RSExportPrimitiveType*>(ET);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700292 if (EPT->getKind() == RSExportPrimitiveType::DataKindUser) {
293 static const char *PrimitiveBuiltinElementConstructMap[] = {
Shih-wei Liao91a37832010-10-03 19:11:51 -0700294 NULL, // RSExportPrimitiveType::DataTypeFloat16
295 "F32", // RSExportPrimitiveType::DataTypeFloat32
296 "F64", // RSExportPrimitiveType::DataTypeFloat64
297 "I8", // RSExportPrimitiveType::DataTypeSigned8
298 NULL, // RSExportPrimitiveType::DataTypeSigned16
299 "I32", // RSExportPrimitiveType::DataTypeSigned32
300 "I64", // RSExportPrimitiveType::DataTypeSigned64
301 "U8", // RSExportPrimitiveType::DataTypeUnsigned8
302 NULL, // RSExportPrimitiveType::DataTypeUnsigned16
303 "U32", // RSExportPrimitiveType::DataTypeUnsigned32
304 NULL, // RSExportPrimitiveType::DataTypeUnsigned64
305 "BOOLEAN", // RSExportPrimitiveType::DataTypeBoolean
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700306
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700307 NULL, // RSExportPrimitiveType::DataTypeUnsigned565
308 NULL, // RSExportPrimitiveType::DataTypeUnsigned5551
309 NULL, // RSExportPrimitiveType::DataTypeUnsigned4444
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700310
Zonr Chang92b344a2010-10-05 20:39:03 +0800311 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
312 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
313 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
Shih-wei Liaodd35e492010-06-21 14:42:40 -0700314
zonr6315f762010-10-05 15:35:14 +0800315 "ELEMENT", // RSExportPrimitiveType::DataTypeRSElement
316 "TYPE", // RSExportPrimitiveType::DataTypeRSType
317 "ALLOCATION", // RSExportPrimitiveType::DataTypeRSAllocation
318 "SAMPLER", // RSExportPrimitiveType::DataTypeRSSampler
319 "SCRIPT", // RSExportPrimitiveType::DataTypeRSScript
320 "MESH", // RSExportPrimitiveType::DataTypeRSMesh
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700321 "PROGRAM_FRAGMENT", // RSExportPrimitiveType::DataTypeRSProgramFragment
322 "PROGRAM_VERTEX", // RSExportPrimitiveType::DataTypeRSProgramVertex
323 "PROGRAM_RASTER", // RSExportPrimitiveType::DataTypeRSProgramRaster
324 "PROGRAM_STORE", // RSExportPrimitiveType::DataTypeRSProgramStore
325 "FONT", // RSExportPrimitiveType::DataTypeRSFont
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700326 };
327 unsigned TypeId = EPT->getType();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700328
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700329 if (TypeId <
330 (sizeof(PrimitiveBuiltinElementConstructMap) / sizeof(const char*)))
331 return PrimitiveBuiltinElementConstructMap[ EPT->getType() ];
332 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelA) {
333 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
334 return "A_8";
335 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGB) {
336 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned565)
337 return "RGB_565";
338 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
339 return "RGB_888";
340 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGBA) {
341 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned5551)
Shih-wei Liao91a37832010-10-03 19:11:51 -0700342 return "RGBA_5551";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700343 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned4444)
Shih-wei Liao91a37832010-10-03 19:11:51 -0700344 return "RGBA_4444";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700345 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
Shih-wei Liao91a37832010-10-03 19:11:51 -0700346 return "RGBA_8888";
Shih-wei Liao8b1d0dd2010-07-15 18:56:55 -0700347 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700348 } else if (ET->getClass() == RSExportType::ExportClassVector) {
349 const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(ET);
Shih-wei Liao91a37832010-10-03 19:11:51 -0700350 if (EVT->getKind() == RSExportPrimitiveType::DataKindUser) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700351 if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
352 if (EVT->getNumElement() == 2)
Shih-wei Liao91a37832010-10-03 19:11:51 -0700353 return "F32_2";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700354 else if (EVT->getNumElement() == 3)
Shih-wei Liao91a37832010-10-03 19:11:51 -0700355 return "F32_3";
356 else if (EVT->getNumElement() == 4)
357 return "F32_4";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700358 } else if (EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) {
359 if (EVT->getNumElement() == 4)
Shih-wei Liao91a37832010-10-03 19:11:51 -0700360 return "U8_4";
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700361 }
Shih-wei Liao324c0472010-06-21 13:15:11 -0700362 }
Zonr Chang92b344a2010-10-05 20:39:03 +0800363 } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
364 const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET);
365 switch (EMT->getDim()) {
366 case 2: {
367 return "MATRIX_2X2";
368 break;
369 }
370 case 3: {
371 return "MATRIX_3X3";
372 break;
373 }
374 case 4: {
375 return "MATRIX_4X4";
376 break;
377 }
378 default: {
379 assert(false && "Unsupported dimension of matrix");
380 }
381 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700382 } else if (ET->getClass() == RSExportType::ExportClassPointer) {
383 // Treat pointer type variable as unsigned int
zonr6315f762010-10-05 15:35:14 +0800384 // TODO(zonr): this is target dependent
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700385 return "USER_I32";
386 }
Shih-wei Liao324c0472010-06-21 13:15:11 -0700387
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700388 return NULL;
Shih-wei Liao324c0472010-06-21 13:15:11 -0700389}
390
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700391static const char *GetElementDataKindName(RSExportPrimitiveType::DataKind DK) {
392 static const char *ElementDataKindNameMap[] = {
393 "Element.DataKind.USER", // RSExportPrimitiveType::DataKindUser
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700394 "Element.DataKind.PIXEL_L", // RSExportPrimitiveType::DataKindPixelL
395 "Element.DataKind.PIXEL_A", // RSExportPrimitiveType::DataKindPixelA
396 "Element.DataKind.PIXEL_LA", // RSExportPrimitiveType::DataKindPixelLA
397 "Element.DataKind.PIXEL_RGB", // RSExportPrimitiveType::DataKindPixelRGB
398 "Element.DataKind.PIXEL_RGBA", // RSExportPrimitiveType::DataKindPixelRGBA
399 };
Shih-wei Liao324c0472010-06-21 13:15:11 -0700400
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700401 if (static_cast<unsigned>(DK) <
402 (sizeof(ElementDataKindNameMap) / sizeof(const char*)))
403 return ElementDataKindNameMap[ DK ];
404 else
405 return NULL;
Shih-wei Liao324c0472010-06-21 13:15:11 -0700406}
407
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700408static const char *GetElementDataTypeName(RSExportPrimitiveType::DataType DT) {
409 static const char *ElementDataTypeNameMap[] = {
Shih-wei Liao91a37832010-10-03 19:11:51 -0700410 NULL, // RSExportPrimitiveType::DataTypeFloat16
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700411 "Element.DataType.FLOAT_32", // RSExportPrimitiveType::DataTypeFloat32
412 "Element.DataType.FLOAT_64", // RSExportPrimitiveType::DataTypeFloat64
413 "Element.DataType.SIGNED_8", // RSExportPrimitiveType::DataTypeSigned8
414 "Element.DataType.SIGNED_16", // RSExportPrimitiveType::DataTypeSigned16
415 "Element.DataType.SIGNED_32", // RSExportPrimitiveType::DataTypeSigned32
416 "Element.DataType.SIGNED_64", // RSExportPrimitiveType::DataTypeSigned64
417 "Element.DataType.UNSIGNED_8", // RSExportPrimitiveType::DataTypeUnsigned8
418 "Element.DataType.UNSIGNED_16", // RSExportPrimitiveType::DataTypeUnsigned16
419 "Element.DataType.UNSIGNED_32", // RSExportPrimitiveType::DataTypeUnsigned32
420 NULL, // RSExportPrimitiveType::DataTypeUnsigned64
Shih-wei Liao91a37832010-10-03 19:11:51 -0700421 "Element.DataType.BOOLEAN", // RSExportPrimitiveType::DataTypeBoolean
422
423 // RSExportPrimitiveType::DataTypeUnsigned565
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700424 "Element.DataType.UNSIGNED_5_6_5",
Shih-wei Liao91a37832010-10-03 19:11:51 -0700425 // RSExportPrimitiveType::DataTypeUnsigned5551
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700426 "Element.DataType.UNSIGNED_5_5_5_1",
Shih-wei Liao91a37832010-10-03 19:11:51 -0700427 // RSExportPrimitiveType::DataTypeUnsigned4444
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700428 "Element.DataType.UNSIGNED_4_4_4_4",
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700429
Zonr Chang92b344a2010-10-05 20:39:03 +0800430 // DataTypeRSMatrix* must have been resolved in GetBuiltinElementConstruct()
431 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2
432 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
433 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700434
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700435 "Element.DataType.RS_ELEMENT", // RSExportPrimitiveType::DataTypeRSElement
436 "Element.DataType.RS_TYPE", // RSExportPrimitiveType::DataTypeRSType
437 // RSExportPrimitiveType::DataTypeRSAllocation
438 "Element.DataType.RS_ALLOCATION",
439 // RSExportPrimitiveType::DataTypeRSSampler
440 "Element.DataType.RS_SAMPLER",
441 // RSExportPrimitiveType::DataTypeRSScript
442 "Element.DataType.RS_SCRIPT",
443 // RSExportPrimitiveType::DataTypeRSMesh
444 "Element.DataType.RS_MESH",
445 // RSExportPrimitiveType::DataTypeRSProgramFragment
446 "Element.DataType.RS_PROGRAM_FRAGMENT",
447 // RSExportPrimitiveType::DataTypeRSProgramVertex
448 "Element.DataType.RS_PROGRAM_VERTEX",
449 // RSExportPrimitiveType::DataTypeRSProgramRaster
450 "Element.DataType.RS_PROGRAM_RASTER",
451 // RSExportPrimitiveType::DataTypeRSProgramStore
452 "Element.DataType.RS_PROGRAM_STORE",
453 // RSExportPrimitiveType::DataTypeRSFont
454 "Element.DataType.RS_FONT",
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700455 };
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700456
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700457 if (static_cast<unsigned>(DT) <
458 (sizeof(ElementDataTypeNameMap) / sizeof(const char*)))
459 return ElementDataTypeNameMap[ DT ];
460 else
461 return NULL;
462}
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700463
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700464/********************** Methods to generate script class **********************/
465bool RSReflection::genScriptClass(Context &C,
466 const std::string &ClassName,
467 std::string &ErrorMsg) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700468 if (!C.startClass(Context::AM_Public,
469 false,
470 ClassName,
471 RS_SCRIPT_CLASS_SUPER_CLASS_NAME,
472 ErrorMsg))
473 return false;
474
475 genScriptClassConstructor(C);
476
477 // Reflect export variable
478 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
479 E = mRSContext->export_vars_end();
480 I != E;
481 I++)
482 genExportVariable(C, *I);
483
484 // Reflect export function
485 for (RSContext::const_export_func_iterator
486 I = mRSContext->export_funcs_begin(),
487 E = mRSContext->export_funcs_end();
488 I != E; I++)
489 genExportFunction(C, *I);
490
491 C.endClass();
492
493 return true;
494}
495
496void RSReflection::genScriptClassConstructor(Context &C) {
497 C.indent() << "// Constructor" << std::endl;
498 C.startFunction(Context::AM_Public,
499 false,
500 NULL,
501 C.getClassName(),
502 4,
503 "RenderScript",
504 "rs",
505 "Resources",
506 "resources",
507 "int",
508 "id",
509 "boolean",
510 "isRoot");
511 // Call constructor of super class
512 C.indent() << "super(rs, resources, id, isRoot);" << std::endl;
513
514 // If an exported variable has initial value, reflect it
515
516 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
517 E = mRSContext->export_vars_end();
518 I != E;
519 I++) {
520 const RSExportVar *EV = *I;
521 if (!EV->getInit().isUninit())
522 genInitExportVariable(C, EV->getType(), EV->getName(), EV->getInit());
523 }
524
525 C.endFunction();
526 return;
527}
528
529void RSReflection::genInitBoolExportVariable(Context &C,
530 const std::string &VarName,
531 const clang::APValue &Val) {
532 assert(!Val.isUninit() && "Not a valid initializer");
533
534 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
535 assert((Val.getKind() == clang::APValue::Int) &&
536 "Bool type has wrong initial APValue");
537
Zonr Chang92b344a2010-10-05 20:39:03 +0800538 C.out() << ((Val.getInt().getSExtValue() == 0) ? "false" : "true")
539 << ";" << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700540
541 return;
542}
543
544void RSReflection::genInitPrimitiveExportVariable(Context &C,
545 const std::string &VarName,
546 const clang::APValue &Val) {
547 assert(!Val.isUninit() && "Not a valid initializer");
548
549 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
550 switch (Val.getKind()) {
551 case clang::APValue::Int: {
Stephen Hines050eb852010-10-07 11:38:29 -0700552 llvm::APInt api = Val.getInt();
553 C.out() << api.getSExtValue();
554 if (api.getBitWidth() > 32) {
555 C.out() << "L";
556 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700557 break;
558 }
559 case clang::APValue::Float: {
560 llvm::APFloat apf = Val.getFloat();
561 if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
562 C.out() << apf.convertToFloat() << "f";
563 } else {
564 C.out() << apf.convertToDouble();
565 }
566 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700567 }
568
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700569 case clang::APValue::ComplexInt:
570 case clang::APValue::ComplexFloat:
571 case clang::APValue::LValue:
572 case clang::APValue::Vector: {
573 assert(false && "Primitive type cannot have such kind of initializer");
574 break;
575 }
576 default: {
577 assert(false && "Unknown kind of initializer");
578 }
579 }
580 C.out() << ";" << std::endl;
581
582 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700583}
584
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700585void RSReflection::genInitExportVariable(Context &C,
586 const RSExportType *ET,
587 const std::string &VarName,
588 const clang::APValue &Val) {
589 assert(!Val.isUninit() && "Not a valid initializer");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700590
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700591 switch (ET->getClass()) {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800592 case RSExportType::ExportClassPrimitive: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700593 const RSExportPrimitiveType *EPT =
594 static_cast<const RSExportPrimitiveType*>(ET);
Shih-wei Liao91a37832010-10-03 19:11:51 -0700595 if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700596 genInitBoolExportVariable(C, VarName, Val);
597 } else {
598 genInitPrimitiveExportVariable(C, VarName, Val);
599 }
600 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700601 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700602 case RSExportType::ExportClassPointer: {
603 if (!Val.isInt() || Val.getInt().getSExtValue() != 0)
604 std::cout << "Initializer which is non-NULL to pointer type variable "
605 "will be ignored" << std::endl;
606 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700607 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700608 case RSExportType::ExportClassVector: {
609 const RSExportVectorType *EVT =
610 static_cast<const RSExportVectorType*>(ET);
611 switch (Val.getKind()) {
612 case clang::APValue::Int:
613 case clang::APValue::Float: {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800614 for (unsigned i = 0; i < EVT->getNumElement(); i++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700615 std::string Name = VarName + "." + GetVectorAccessor(i);
616 genInitPrimitiveExportVariable(C, Name, Val);
Shih-wei Liao1ebc0ca2010-09-14 10:57:21 -0700617 }
618 break;
619 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700620 case clang::APValue::Vector: {
621 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "
622 << GetVectorTypeName(EVT) << "();" << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700623
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700624 unsigned NumElements =
625 std::min(static_cast<unsigned>(EVT->getNumElement()),
626 Val.getVectorLength());
627 for (unsigned i = 0; i < NumElements; i++) {
628 const clang::APValue &ElementVal = Val.getVectorElt(i);
629 std::string Name = VarName + "." + GetVectorAccessor(i);
630 genInitPrimitiveExportVariable(C, Name, ElementVal);
631 }
632 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700633 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700634 case clang::APValue::Uninitialized:
635 case clang::APValue::ComplexInt:
636 case clang::APValue::ComplexFloat:
637 case clang::APValue::LValue: {
638 assert(false && "Unexpected type of value of initializer.");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700639 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700640 }
641 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700642 }
Zonr Chang92b344a2010-10-05 20:39:03 +0800643 // TODO(zonr): Resolving initializer of a record (and matrix) type variable
644 // is complex. It cannot obtain by just simply evaluating the initializer
645 // expression.
646 case RSExportType::ExportClassMatrix:
Zonr Chang2e1dba62010-10-05 22:20:11 +0800647 case RSExportType::ExportClassConstantArray:
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700648 case RSExportType::ExportClassRecord: {
649#if 0
650 unsigned InitIndex = 0;
zonr6315f762010-10-05 15:35:14 +0800651 const RSExportRecordType *ERT =
652 static_cast<const RSExportRecordType*>(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700653
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700654 assert((Val.getKind() == clang::APValue::Vector) && "Unexpected type of "
655 "initializer for record type variable");
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700656
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700657 C.indent() << RS_EXPORT_VAR_PREFIX << VarName
658 << " = new "RS_TYPE_CLASS_NAME_PREFIX << ERT->getName()
659 << "."RS_TYPE_ITEM_CLASS_NAME"();" << std::endl;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -0700660
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700661 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
662 E = ERT->fields_end();
663 I != E;
664 I++) {
665 const RSExportRecordType::Field *F = *I;
666 std::string FieldName = VarName + "." + F->getName();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700667
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700668 if (InitIndex > Val.getVectorLength())
669 break;
670
671 genInitPrimitiveExportVariable(C,
672 FieldName,
673 Val.getVectorElt(InitIndex++));
674 }
675#endif
Zonr Chang2e1dba62010-10-05 22:20:11 +0800676 assert(false && "Unsupported initializer for record/matrix/constant "
677 "array type variable currently");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700678 break;
Shih-wei Liao6de89272010-07-15 15:26:20 -0700679 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700680 default: {
681 assert(false && "Unknown class of type");
682 }
683 }
684 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700685}
686
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700687void RSReflection::genExportVariable(Context &C, const RSExportVar *EV) {
688 const RSExportType *ET = EV->getType();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700689
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700690 C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX
691 << EV->getName() << " = " << C.getNextExportVarSlot() << ";"
692 << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700693
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700694 switch (ET->getClass()) {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800695 case RSExportType::ExportClassPrimitive: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700696 genPrimitiveTypeExportVariable(C, EV);
697 break;
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700698 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700699 case RSExportType::ExportClassPointer: {
700 genPointerTypeExportVariable(C, EV);
701 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700702 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700703 case RSExportType::ExportClassVector: {
704 genVectorTypeExportVariable(C, EV);
705 break;
706 }
Zonr Chang92b344a2010-10-05 20:39:03 +0800707 case RSExportType::ExportClassMatrix: {
708 genMatrixTypeExportVariable(C, EV);
709 break;
710 }
Zonr Chang2e1dba62010-10-05 22:20:11 +0800711 case RSExportType::ExportClassConstantArray: {
712 genConstantArrayTypeExportVariable(C, EV);
713 break;
714 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700715 case RSExportType::ExportClassRecord: {
716 genRecordTypeExportVariable(C, EV);
717 break;
718 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700719 default: {
720 assert(false && "Unknown class of type");
721 }
722 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700723
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700724 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700725}
726
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700727void RSReflection::genExportFunction(Context &C, const RSExportFunc *EF) {
728 C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX
729 << EF->getName() << " = " << C.getNextExportFuncSlot() << ";"
730 << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700731
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700732 // invoke_*()
733 Context::ArgTy Args;
734
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800735 if (EF->hasParam()) {
736 for (RSExportFunc::const_param_iterator I = EF->params_begin(),
737 E = EF->params_end();
738 I != E;
739 I++) {
740 Args.push_back(std::make_pair(GetTypeName((*I)->getType()),
741 (*I)->getName()));
742 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700743 }
744
745 C.startFunction(Context::AM_Public,
746 false,
747 "void",
748 "invoke_" + EF->getName(),
749 Args);
750
751 if (!EF->hasParam()) {
752 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");"
753 << std::endl;
754 } else {
755 const RSExportRecordType *ERT = EF->getParamPacketType();
756 std::string FieldPackerName = EF->getName() + "_fp";
757
758 if (genCreateFieldPacker(C, ERT, FieldPackerName.c_str()))
759 genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str());
760
761 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", "
762 << FieldPackerName << ");" << std::endl;
763 }
764
765 C.endFunction();
766 return;
767}
768
769void RSReflection::genPrimitiveTypeExportVariable(Context &C,
770 const RSExportVar *EV) {
Zonr Chang2e1dba62010-10-05 22:20:11 +0800771 assert((EV->getType()->getClass() == RSExportType::ExportClassPrimitive) &&
772 "Variable should be type of primitive here");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700773
774 const RSExportPrimitiveType *EPT =
775 static_cast<const RSExportPrimitiveType*>(EV->getType());
776 const char *TypeName = GetPrimitiveTypeName(EPT);
777
778 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
779 << EV->getName() << ";" << std::endl;
780
781 // set_*()
782 if (!EV->isConst()) {
783 C.startFunction(Context::AM_Public,
784 false,
785 "void",
786 "set_" + EV->getName(),
787 1,
788 TypeName,
789 "v");
790 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
791
792 if (EPT->isRSObjectType())
793 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName()
794 << ", (v == null) ? 0 : v.getID());" << std::endl;
795 else
796 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName()
797 << ", v);" << std::endl;
798
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700799 C.endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700800 }
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700801
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700802 genGetExportVariable(C, TypeName, EV->getName());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700803
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700804 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700805}
806
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700807void RSReflection::genPointerTypeExportVariable(Context &C,
808 const RSExportVar *EV) {
809 const RSExportType *ET = EV->getType();
810 const RSExportType *PointeeType;
811 std::string TypeName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700812
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700813 assert((ET->getClass() == RSExportType::ExportClassPointer) &&
814 "Variable should be type of pointer here");
815
816 PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType();
817 TypeName = GetTypeName(ET);
818
819 // bind_*()
820 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
821 << EV->getName() << ";" << std::endl;
822
823 C.startFunction(Context::AM_Public,
824 false,
825 "void",
826 "bind_" + EV->getName(),
827 1,
828 TypeName.c_str(),
829 "v");
830
831 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
832 C.indent() << "if (v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX
833 << EV->getName() << ");" << std::endl;
834
835 if (PointeeType->getClass() == RSExportType::ExportClassRecord)
836 C.indent() << "else bindAllocation(v.getAllocation(), "
837 RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");"
838 << std::endl;
839 else
840 C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX
841 << EV->getName() << ");" << std::endl;
842
843 C.endFunction();
844
845 genGetExportVariable(C, TypeName, EV->getName());
846
847 return;
848}
849
850void RSReflection::genVectorTypeExportVariable(Context &C,
851 const RSExportVar *EV) {
852 assert((EV->getType()->getClass() == RSExportType::ExportClassVector) &&
853 "Variable should be type of vector here");
854
855 const RSExportVectorType *EVT =
856 static_cast<const RSExportVectorType*>(EV->getType());
857 const char *TypeName = GetVectorTypeName(EVT);
858 const char *FieldPackerName = "fp";
859
860 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
861 << EV->getName() << ";" << std::endl;
862
863 // set_*()
864 if (!EV->isConst()) {
865 C.startFunction(Context::AM_Public,
866 false,
867 "void",
868 "set_" + EV->getName(),
869 1,
870 TypeName,
871 "v");
872 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
873
874 if (genCreateFieldPacker(C, EVT, FieldPackerName))
875 genPackVarOfType(C, EVT, "v", FieldPackerName);
876 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", "
877 << FieldPackerName << ");" << std::endl;
878
879 C.endFunction();
880 }
881
882 genGetExportVariable(C, TypeName, EV->getName());
883 return;
884}
885
Zonr Chang92b344a2010-10-05 20:39:03 +0800886void RSReflection::genMatrixTypeExportVariable(Context &C,
887 const RSExportVar *EV) {
888 assert((EV->getType()->getClass() == RSExportType::ExportClassMatrix) &&
889 "Variable should be type of matrix here");
890
891 const RSExportMatrixType *EMT =
892 static_cast<const RSExportMatrixType*>(EV->getType());
893 const char *TypeName = GetMatrixTypeName(EMT);
894 const char *FieldPackerName = "fp";
895
896 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
897 << EV->getName() << ";" << std::endl;
898
899 // set_*()
900 if (!EV->isConst()) {
901 C.startFunction(Context::AM_Public,
902 false,
903 "void",
904 "set_" + EV->getName(),
905 1,
906 TypeName, "v");
907 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
908
909 if (genCreateFieldPacker(C, EMT, FieldPackerName))
910 genPackVarOfType(C, EMT, "v", FieldPackerName);
911 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", "
912 << FieldPackerName << ");" << std::endl;
913
914 C.endFunction();
915 }
916
917 genGetExportVariable(C, TypeName, EV->getName());
918 return;
919}
920
Zonr Chang2e1dba62010-10-05 22:20:11 +0800921void RSReflection::genConstantArrayTypeExportVariable(Context &C,
922 const RSExportVar *EV) {
923 assert((EV->getType()->getClass() == RSExportType::ExportClassConstantArray)&&
924 "Variable should be type of constant array here");
925
926 const RSExportConstantArrayType *ECAT =
927 static_cast<const RSExportConstantArrayType*>(EV->getType());
928 std::string TypeName = GetTypeName(ECAT);
929 const char *FieldPackerName = "fp";
930
931 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
932 << EV->getName() << ";" << std::endl;
933
934 // set_*()
935 if (!EV->isConst()) {
936 C.startFunction(Context::AM_Public,
937 false,
938 "void",
939 "set_" + EV->getName(),
940 1,
941 TypeName.c_str(), "v");
942 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
943
944 if (genCreateFieldPacker(C, ECAT, FieldPackerName))
945 genPackVarOfType(C, ECAT, "v", FieldPackerName);
946 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", "
947 << FieldPackerName << ");" << std::endl;
948
949 C.endFunction();
950 }
951
952 genGetExportVariable(C, TypeName, EV->getName());
953 return;
954}
955
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700956void RSReflection::genRecordTypeExportVariable(Context &C,
957 const RSExportVar *EV) {
958 assert((EV->getType()->getClass() == RSExportType::ExportClassRecord) &&
959 "Variable should be type of struct here");
960
961 const RSExportRecordType *ERT =
962 static_cast<const RSExportRecordType*>(EV->getType());
963 std::string TypeName =
964 RS_TYPE_CLASS_NAME_PREFIX + ERT->getName() + "."RS_TYPE_ITEM_CLASS_NAME;
965 const char *FieldPackerName = "fp";
966
967 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
968 << EV->getName() << ";" << std::endl;
969
970 // set_*()
971 if (!EV->isConst()) {
972 C.startFunction(Context::AM_Public,
973 false,
974 "void",
975 "set_" + EV->getName(),
976 1,
977 TypeName.c_str(),
978 "v");
979 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl;
980
981 if (genCreateFieldPacker(C, ERT, FieldPackerName))
982 genPackVarOfType(C, ERT, "v", FieldPackerName);
983 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName()
984 << ", " << FieldPackerName << ");" << std::endl;
985
986 C.endFunction();
987 }
988
989 genGetExportVariable(C, TypeName.c_str(), EV->getName());
990 return;
991}
992
993void RSReflection::genGetExportVariable(Context &C,
994 const std::string &TypeName,
995 const std::string &VarName) {
996 C.startFunction(Context::AM_Public,
997 false,
998 TypeName.c_str(),
999 "get_" + VarName,
1000 0);
1001
1002 C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << std::endl;
1003
1004 C.endFunction();
1005 return;
1006}
1007
1008/******************* Methods to generate script class /end *******************/
1009
1010bool RSReflection::genCreateFieldPacker(Context &C,
1011 const RSExportType *ET,
1012 const char *FieldPackerName) {
1013 size_t AllocSize = RSExportType::GetTypeAllocSize(ET);
1014 if (AllocSize > 0)
1015 C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker("
1016 << AllocSize << ");" << std::endl;
1017 else
1018 return false;
1019 return true;
1020}
1021
1022void RSReflection::genPackVarOfType(Context &C,
1023 const RSExportType *ET,
1024 const char *VarName,
1025 const char *FieldPackerName) {
1026 switch (ET->getClass()) {
1027 case RSExportType::ExportClassPrimitive:
1028 case RSExportType::ExportClassVector: {
1029 C.indent() << FieldPackerName << "."
1030 << GetPackerAPIName(
1031 static_cast<const RSExportPrimitiveType*>(ET))
1032 << "(" << VarName << ");" << std::endl;
1033 break;
1034 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001035 case RSExportType::ExportClassPointer: {
1036 // Must reflect as type Allocation in Java
1037 const RSExportType *PointeeType =
1038 static_cast<const RSExportPointerType*>(ET)->getPointeeType();
1039
1040 if (PointeeType->getClass() != RSExportType::ExportClassRecord)
1041 C.indent() << FieldPackerName << ".addI32(" << VarName
1042 << ".getPtr());" << std::endl;
1043 else
1044 C.indent() << FieldPackerName << ".addI32(" << VarName
1045 << ".getAllocation().getPtr());" << std::endl;
1046 break;
1047 }
Zonr Chang92b344a2010-10-05 20:39:03 +08001048 case RSExportType::ExportClassMatrix: {
1049 C.indent() << FieldPackerName << ".addObj(" << VarName << ");"
1050 << std::endl;
1051 break;
1052 }
Zonr Chang2e1dba62010-10-05 22:20:11 +08001053 case RSExportType::ExportClassConstantArray: {
1054 const RSExportConstantArrayType *ECAT =
1055 static_cast<const RSExportConstantArrayType *>(ET);
1056 C.indent() << "for (int ct = 0; ct < " << ECAT->getSize() << "; ct++)";
1057 C.startBlock();
1058
1059 std::string ElementVarName(VarName);
1060 ElementVarName.append("[ct]");
1061 genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(),
1062 FieldPackerName);
1063
1064 C.endBlock();
1065 break;
1066 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001067 case RSExportType::ExportClassRecord: {
zonr6315f762010-10-05 15:35:14 +08001068 const RSExportRecordType *ERT =
1069 static_cast<const RSExportRecordType*>(ET);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001070 // Relative pos from now on in field packer
1071 unsigned Pos = 0;
1072
1073 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
1074 E = ERT->fields_end();
1075 I != E;
1076 I++) {
1077 const RSExportRecordType::Field *F = *I;
1078 std::string FieldName;
1079 size_t FieldOffset = F->getOffsetInParent();
1080 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
1081 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
1082
1083 if (VarName != NULL)
1084 FieldName = VarName + ("." + F->getName());
1085 else
1086 FieldName = F->getName();
1087
1088 if (FieldOffset > Pos)
1089 C.indent() << FieldPackerName << ".skip("
1090 << (FieldOffset - Pos) << ");" << std::endl;
1091
1092 genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName);
1093
1094 // There is padding in the field type
1095 if (FieldAllocSize > FieldStoreSize)
1096 C.indent() << FieldPackerName << ".skip("
1097 << (FieldAllocSize - FieldStoreSize)
1098 << ");" << std::endl;
1099
1100 Pos = FieldOffset + FieldAllocSize;
1101 }
1102
1103 // There maybe some padding after the struct
1104 size_t Padding = RSExportType::GetTypeAllocSize(ERT) - Pos;
1105 if (Padding > 0)
1106 C.indent() << FieldPackerName << ".skip(" << Padding << ");"
1107 << std::endl;
1108 break;
1109 }
1110 default: {
1111 assert(false && "Unknown class of type");
1112 }
1113 }
1114
1115 return;
1116}
1117
Zonr Chang2e1dba62010-10-05 22:20:11 +08001118void RSReflection::genAllocateVarOfType(Context &C,
1119 const RSExportType *T,
1120 const std::string &VarName) {
1121 switch (T->getClass()) {
1122 case RSExportType::ExportClassPrimitive: {
1123 // Primitive type like int in Java has its own storage once it's declared.
1124 //
1125 // FIXME: Should we allocate storage for RS object?
1126 // if (static_cast<const RSExportPrimitiveType *>(T)->isRSObjectType())
1127 // C.indent() << VarName << " = new " << GetTypeName(T) << "();"
1128 // << std::endl;
1129 break;
1130 }
1131 case RSExportType::ExportClassPointer: {
1132 // Pointer type is an instance of Allocation or a TypeClass whose value is
1133 // expected to be assigned by programmer later in Java program. Therefore
1134 // we don't reflect things like [VarName] = new Allocation();
1135 C.indent() << VarName << " = null;" << std::endl;
1136 break;
1137 }
1138 case RSExportType::ExportClassConstantArray: {
1139 const RSExportConstantArrayType *ECAT =
1140 static_cast<const RSExportConstantArrayType *>(T);
1141 const RSExportType *ElementType = ECAT->getElementType();
1142
1143 // Primitive type element doesn't need allocation code.
1144 if (ElementType->getClass() != RSExportType::ExportClassPrimitive) {
1145 C.indent() << VarName << " = new " << GetTypeName(ElementType)
1146 << "[" << ECAT->getSize() << "];" << std::endl;
1147
1148 C.indent() << "for (int $ct = 0; $ct < " << ECAT->getSize() << "; "
1149 "$ct++)";
1150 C.startBlock();
1151
1152 std::string ElementVarName(VarName);
1153 ElementVarName.append("[$ct]");
1154 genAllocateVarOfType(C, ElementType, ElementVarName);
1155
1156 C.endBlock();
1157 }
1158 break;
1159 }
1160 case RSExportType::ExportClassVector:
1161 case RSExportType::ExportClassMatrix:
1162 case RSExportType::ExportClassRecord: {
1163 C.indent() << VarName << " = new " << GetTypeName(T) << "();"
1164 << std::endl;
1165 break;
1166 }
1167 }
1168 return;
1169}
1170
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001171void RSReflection::genNewItemBufferIfNull(Context &C, const char *Index) {
1172 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) "
Zonr Chang92b344a2010-10-05 20:39:03 +08001173 RS_TYPE_ITEM_BUFFER_NAME" = "
1174 "new "RS_TYPE_ITEM_CLASS_NAME"[mType.getX() /* count */];"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001175 << std::endl;
1176 if (Index != NULL)
1177 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] == null) "
Zonr Chang92b344a2010-10-05 20:39:03 +08001178 RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] = "
1179 "new "RS_TYPE_ITEM_CLASS_NAME"();" << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001180 return;
1181}
1182
1183void RSReflection::genNewItemBufferPackerIfNull(Context &C) {
1184 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_PACKER_NAME" == null) "
Zonr Chang92b344a2010-10-05 20:39:03 +08001185 RS_TYPE_ITEM_BUFFER_PACKER_NAME" = "
1186 "new FieldPacker("
1187 RS_TYPE_ITEM_CLASS_NAME".sizeof * mType.getX()/* count */"
1188 ");" << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001189 return;
1190}
1191
1192/********************** Methods to generate type class **********************/
1193bool RSReflection::genTypeClass(Context &C,
1194 const RSExportRecordType *ERT,
1195 std::string &ErrorMsg) {
1196 std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName();
1197
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001198 if (!C.startClass(Context::AM_Public,
1199 false,
1200 ClassName,
1201 RS_TYPE_CLASS_SUPER_CLASS_NAME,
1202 ErrorMsg))
1203 return false;
1204
Zonr Chang2e1dba62010-10-05 22:20:11 +08001205 genTypeItemClass(C, ERT);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001206
1207 // Declare item buffer and item buffer packer
1208 C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[]"
1209 ";" << std::endl;
1210 C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";"
1211 << std::endl;
1212
1213 genTypeClassConstructor(C, ERT);
1214 genTypeClassCopyToArray(C, ERT);
1215 genTypeClassItemSetter(C, ERT);
1216 genTypeClassItemGetter(C, ERT);
1217 genTypeClassComponentSetter(C, ERT);
1218 genTypeClassComponentGetter(C, ERT);
1219 genTypeClassCopyAll(C, ERT);
1220
1221 C.endClass();
1222
Zonr Chang66aa2992010-10-05 15:56:31 +08001223 C.resetFieldIndex();
1224 C.clearFieldIndexMap();
1225
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001226 return true;
1227}
1228
Zonr Chang2e1dba62010-10-05 22:20:11 +08001229void RSReflection::genTypeItemClass(Context &C, const RSExportRecordType *ERT) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001230 C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME;
1231 C.startBlock();
1232
1233 C.indent() << "public static final int sizeof = "
1234 << RSExportType::GetTypeAllocSize(ERT) << ";" << std::endl;
1235
1236 // Member elements
1237 C.out() << std::endl;
1238 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
1239 FE = ERT->fields_end();
1240 FI != FE;
1241 FI++) {
1242 C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName()
1243 << ";" << std::endl;
1244 }
1245
1246 // Constructor
1247 C.out() << std::endl;
1248 C.indent() << RS_TYPE_ITEM_CLASS_NAME"()";
1249 C.startBlock();
1250
1251 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
1252 FE = ERT->fields_end();
1253 FI != FE;
1254 FI++) {
1255 const RSExportRecordType::Field *F = *FI;
Zonr Chang2e1dba62010-10-05 22:20:11 +08001256 genAllocateVarOfType(C, F->getType(), F->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001257 }
1258
1259 // end Constructor
1260 C.endBlock();
1261
1262 // end Item class
1263 C.endBlock();
1264
Zonr Chang2e1dba62010-10-05 22:20:11 +08001265 return;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001266}
1267
1268void RSReflection::genTypeClassConstructor(Context &C,
1269 const RSExportRecordType *ERT) {
1270 const char *RenderScriptVar = "rs";
1271
1272 C.startFunction(Context::AM_Public,
1273 true,
1274 "Element",
1275 "createElement",
1276 1,
1277 "RenderScript",
1278 RenderScriptVar);
1279 genBuildElement(C, ERT, RenderScriptVar);
1280 C.endFunction();
1281
1282 C.startFunction(Context::AM_Public,
1283 false,
1284 NULL,
1285 C.getClassName(),
1286 2,
1287 "RenderScript",
1288 RenderScriptVar,
1289 "int",
1290 "count");
1291
1292 C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << std::endl;
1293 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << std::endl;
1294 C.indent() << "mElement = createElement(" << RenderScriptVar << ");"
1295 << std::endl;
1296 // Call init() in super class
1297 C.indent() << "init(" << RenderScriptVar << ", count);" << std::endl;
1298 C.endFunction();
1299
1300 return;
1301}
1302
1303void RSReflection::genTypeClassCopyToArray(Context &C,
1304 const RSExportRecordType *ERT) {
1305 C.startFunction(Context::AM_Private,
1306 false,
1307 "void",
1308 "copyToArray",
1309 2,
1310 RS_TYPE_ITEM_CLASS_NAME,
1311 "i",
1312 "int",
1313 "index");
1314
1315 genNewItemBufferPackerIfNull(C);
1316 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
Zonr Chang92b344a2010-10-05 20:39:03 +08001317 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);"
1318 << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001319
1320 genPackVarOfType(C, ERT, "i", RS_TYPE_ITEM_BUFFER_PACKER_NAME);
1321
1322 C.endFunction();
1323 return;
1324}
1325
1326void RSReflection::genTypeClassItemSetter(Context &C,
zonr6315f762010-10-05 15:35:14 +08001327 const RSExportRecordType *ERT) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001328 C.startFunction(Context::AM_Public,
1329 false,
1330 "void",
1331 "set",
1332 3,
1333 RS_TYPE_ITEM_CLASS_NAME,
1334 "i",
1335 "int",
1336 "index",
1337 "boolean",
1338 "copyNow");
1339 genNewItemBufferIfNull(C, NULL);
1340 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << std::endl;
1341
1342 C.indent() << "if (copyNow) ";
1343 C.startBlock();
1344
1345 C.indent() << "copyToArray(i, index);" << std::endl;
1346 C.indent() << "mAllocation.subData1D(index, 1, "
Zonr Chang92b344a2010-10-05 20:39:03 +08001347 RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001348
1349 // End of if (copyNow)
1350 C.endBlock();
1351
1352 C.endFunction();
1353 return;
1354}
1355
1356void RSReflection::genTypeClassItemGetter(Context &C,
1357 const RSExportRecordType *ERT) {
1358 C.startFunction(Context::AM_Public,
1359 false,
1360 RS_TYPE_ITEM_CLASS_NAME,
1361 "get",
1362 1,
1363 "int",
1364 "index");
1365 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return null;"
1366 << std::endl;
1367 C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index];" << std::endl;
1368 C.endFunction();
1369 return;
1370}
1371
1372void RSReflection::genTypeClassComponentSetter(Context &C,
1373 const RSExportRecordType *ERT) {
1374 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
1375 FE = ERT->fields_end();
1376 FI != FE;
1377 FI++) {
1378 const RSExportRecordType::Field *F = *FI;
1379 size_t FieldOffset = F->getOffsetInParent();
1380 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
1381 unsigned FieldIndex = C.getFieldIndex(F);
1382
1383 C.startFunction(Context::AM_Public,
1384 false,
1385 "void",
1386 "set_" + F->getName(), 3,
1387 "int",
1388 "index",
1389 GetTypeName(F->getType()).c_str(),
1390 "v",
1391 "boolean",
1392 "copyNow");
Shih-wei Liao9c631ff2010-09-17 11:57:29 -07001393 genNewItemBufferPackerIfNull(C);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001394 genNewItemBufferIfNull(C, "index");
1395 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName()
1396 << " = v;" << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001397
1398 C.indent() << "if (copyNow) ";
1399 C.startBlock();
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -07001400
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001401 if (FieldOffset > 0)
Zonr Chang92b344a2010-10-05 20:39:03 +08001402 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
1403 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof + "
1404 << FieldOffset << ");" << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001405 else
Zonr Chang92b344a2010-10-05 20:39:03 +08001406 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME
1407 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);"
1408 << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001409 genPackVarOfType(C, F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME);
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001410
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001411 C.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize << ");"
1412 << std::endl;
1413 genPackVarOfType(C, F->getType(), "v", "fp");
Zonr Chang66aa2992010-10-05 15:56:31 +08001414 C.indent() << "mAllocation.subElementData(index, " << FieldIndex << ", fp);"
1415 << std::endl;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001416
1417 // End of if (copyNow)
1418 C.endBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001419
1420 C.endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001421 }
1422 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001423}
1424
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001425void RSReflection::genTypeClassComponentGetter(Context &C,
1426 const RSExportRecordType *ERT) {
1427 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
1428 FE = ERT->fields_end();
1429 FI != FE;
1430 FI++) {
1431 const RSExportRecordType::Field *F = *FI;
1432 C.startFunction(Context::AM_Public,
1433 false,
1434 GetTypeName(F->getType()).c_str(),
1435 "get_" + F->getName(),
1436 1,
1437 "int",
1438 "index");
Shih-wei Liaocf950c42010-10-06 03:44:40 -07001439 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return "
1440 << GetTypeNullValue(F->getType()) << ";" << std::endl;
zonr6315f762010-10-05 15:35:14 +08001441 C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName()
1442 << ";" << std::endl;
Shih-wei Liao9b1f50b2010-08-05 12:40:41 -07001443 C.endFunction();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001444 }
1445 return;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -07001446}
1447
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001448void RSReflection::genTypeClassCopyAll(Context &C,
1449 const RSExportRecordType *ERT) {
1450 C.startFunction(Context::AM_Public, false, "void", "copyAll", 0);
1451
Zonr Chang2e1dba62010-10-05 22:20:11 +08001452 C.indent() << "for (int ct = 0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++)"
1453 " copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001454 << std::endl;
1455 C.indent() << "mAllocation.data("RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());"
1456 << std::endl;
1457
1458 C.endFunction();
1459 return;
Shih-wei Liao9c631ff2010-09-17 11:57:29 -07001460}
1461
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001462/******************** Methods to generate type class /end ********************/
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001463
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001464/********** Methods to create Element in Java of given record type ***********/
zonr6315f762010-10-05 15:35:14 +08001465void RSReflection::genBuildElement(Context &C, const RSExportRecordType *ERT,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001466 const char *RenderScriptVar) {
1467 const char *ElementBuilderName = "eb";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001468
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001469 // Create element builder
1470 // C.startBlock(true);
1471
1472 C.indent() << "Element.Builder " << ElementBuilderName << " = "
1473 "new Element.Builder(" << RenderScriptVar << ");" << std::endl;
1474
1475 // eb.add(...)
1476 genAddElementToElementBuilder(C,
1477 ERT,
1478 "",
1479 ElementBuilderName,
1480 RenderScriptVar);
1481
1482 C.indent() << "return " << ElementBuilderName << ".create();" << std::endl;
1483
1484 // C.endBlock();
1485 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001486}
1487
Zonr Chang92b344a2010-10-05 20:39:03 +08001488#define EB_ADD(x) \
1489 C.indent() << ElementBuilderName \
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001490 << ".add(Element." << x << ", \"" << VarName << "\");" \
Zonr Chang92b344a2010-10-05 20:39:03 +08001491 << std::endl; \
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001492 C.incFieldIndex()
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001493
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001494void RSReflection::genAddElementToElementBuilder(Context &C,
1495 const RSExportType *ET,
1496 const std::string &VarName,
1497 const char *ElementBuilderName,
1498 const char *RenderScriptVar) {
1499 const char *ElementConstruct = GetBuiltinElementConstruct(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001500
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001501 if (ElementConstruct != NULL) {
1502 EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")");
1503 } else {
1504 if ((ET->getClass() == RSExportType::ExportClassPrimitive) ||
Zonr Chang2e1dba62010-10-05 22:20:11 +08001505 (ET->getClass() == RSExportType::ExportClassVector)) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001506 const RSExportPrimitiveType *EPT =
1507 static_cast<const RSExportPrimitiveType*>(ET);
1508 const char *DataKindName = GetElementDataKindName(EPT->getKind());
1509 const char *DataTypeName = GetElementDataTypeName(EPT->getType());
1510 int Size = (ET->getClass() == RSExportType::ExportClassVector) ?
1511 static_cast<const RSExportVectorType*>(ET)->getNumElement() :
1512 1;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001513
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001514 switch (EPT->getKind()) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001515 case RSExportPrimitiveType::DataKindPixelL:
1516 case RSExportPrimitiveType::DataKindPixelA:
1517 case RSExportPrimitiveType::DataKindPixelLA:
1518 case RSExportPrimitiveType::DataKindPixelRGB:
1519 case RSExportPrimitiveType::DataKindPixelRGBA: {
1520 // Element.createPixel()
Shih-wei Liao91a37832010-10-03 19:11:51 -07001521 EB_ADD("createPixel(" << RenderScriptVar << ", "
1522 << DataTypeName << ", "
1523 << DataKindName << ")");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001524 break;
1525 }
1526 case RSExportPrimitiveType::DataKindUser:
1527 default: {
Zonr Chang2e1dba62010-10-05 22:20:11 +08001528 if (EPT->getClass() == RSExportType::ExportClassPrimitive) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001529 // Element.createUser()
1530 EB_ADD("createUser(" << RenderScriptVar << ", "
1531 << DataTypeName << ")");
1532 } else {
Zonr Chang92b344a2010-10-05 20:39:03 +08001533 assert((ET->getClass() == RSExportType::ExportClassVector) &&
1534 "Unexpected type.");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001535 EB_ADD("createVector(" << RenderScriptVar << ", "
1536 << DataTypeName << ", "
1537 << Size << ")");
1538 }
1539 break;
1540 }
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -07001541 }
Zonr Chang92b344a2010-10-05 20:39:03 +08001542#ifndef NDEBUG
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001543 } else if (ET->getClass() == RSExportType::ExportClassPointer) {
1544 // Pointer type variable should be resolved in
1545 // GetBuiltinElementConstruct()
1546 assert(false && "??");
Zonr Chang92b344a2010-10-05 20:39:03 +08001547 } else if (ET->getClass() == RSExportType::ExportClassMatrix) {
1548 // Matrix type variable should be resolved
1549 // in GetBuiltinElementConstruct()
1550 assert(false && "??");
1551#endif
Zonr Chang2e1dba62010-10-05 22:20:11 +08001552 } else if (ET->getClass() == RSExportType::ExportClassConstantArray) {
1553 const RSExportConstantArrayType *ECAT =
1554 static_cast<const RSExportConstantArrayType *>(ET);
1555 C.indent() << "for (int ct = 0; ct < " << ECAT->getSize() << "; ct++)";
1556 C.startBlock();
1557
1558 std::string ElementVarName(VarName);
1559 ElementVarName.append("[\" + ct + \"]");
1560 genAddElementToElementBuilder(C,
1561 ECAT->getElementType(),
1562 ElementVarName,
1563 ElementBuilderName,
1564 RenderScriptVar);
1565
1566 C.endBlock();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001567 } else if (ET->getClass() == RSExportType::ExportClassRecord) {
1568 // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType.
1569 //
zonr6315f762010-10-05 15:35:14 +08001570 // TODO(zonr): Generalize these two function such that there's no
1571 // duplicated codes.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001572 const RSExportRecordType *ERT =
1573 static_cast<const RSExportRecordType*>(ET);
1574 int Pos = 0; // relative pos from now on
1575
1576 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(),
1577 E = ERT->fields_end();
1578 I != E;
1579 I++) {
1580 const RSExportRecordType::Field *F = *I;
1581 std::string FieldName;
1582 int FieldOffset = F->getOffsetInParent();
1583 int FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
1584 int FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
1585
1586 if (!VarName.empty())
1587 FieldName = VarName + "." + F->getName();
1588 else
1589 FieldName = F->getName();
1590
1591 // Alignment
1592 genAddPaddingToElementBuiler(C,
1593 (FieldOffset - Pos),
1594 ElementBuilderName,
1595 RenderScriptVar);
1596
1597 // eb.add(...)
1598 C.addFieldIndexMapping(F);
1599 genAddElementToElementBuilder(C,
1600 F->getType(),
1601 FieldName,
1602 ElementBuilderName,
1603 RenderScriptVar);
1604
1605 // There is padding within the field type
1606 genAddPaddingToElementBuiler(C,
1607 (FieldAllocSize - FieldStoreSize),
1608 ElementBuilderName,
1609 RenderScriptVar);
1610
1611 Pos = FieldOffset + FieldAllocSize;
1612 }
1613
1614 // There maybe some padding after the struct
1615 //unsigned char align = RSExportType::GetTypeAlignment(ERT);
1616 //size_t siz = RSExportType::GetTypeAllocSize(ERT);
1617 size_t siz1 = RSExportType::GetTypeStoreSize(ERT);
1618
1619 genAddPaddingToElementBuiler(C,
1620 siz1 - Pos,
1621 ElementBuilderName,
1622 RenderScriptVar);
1623 } else {
1624 assert(false && "Unknown class of type");
Shih-wei Liaob1a28e72010-06-16 16:31:32 -07001625 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001626 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001627}
1628
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001629void RSReflection::genAddPaddingToElementBuiler(Context &C,
1630 int PaddingSize,
1631 const char *ElementBuilderName,
zonr6315f762010-10-05 15:35:14 +08001632 const char *RenderScriptVar) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001633 while (PaddingSize > 0) {
1634 const std::string &VarName = C.createPaddingField();
1635 if (PaddingSize >= 4) {
1636 EB_ADD("U32(" << RenderScriptVar << ")");
1637 PaddingSize -= 4;
1638 } else if (PaddingSize >= 2) {
1639 EB_ADD("U16(" << RenderScriptVar << ")");
1640 PaddingSize -= 2;
1641 } else if (PaddingSize >= 1) {
1642 EB_ADD("U8(" << RenderScriptVar << ")");
1643 PaddingSize -= 1;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001644 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001645 }
1646 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001647}
1648
1649#undef EB_ADD
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001650/******** Methods to create Element in Java of given record type /end ********/
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001651
Shih-wei Liaob81c6a42010-10-10 14:15:00 -07001652bool RSReflection::reflect(const std::string &OutputPathBase,
1653 const std::string &OutputPackageName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001654 const std::string &InputFileName,
1655 const std::string &OutputBCFileName) {
1656 Context *C = NULL;
1657 std::string ResourceId = "";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001658
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001659 if (!GetClassNameFromFileName(OutputBCFileName, ResourceId))
1660 return false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001661
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001662 if (ResourceId.empty())
1663 ResourceId = "<Resource ID>";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001664
Shih-wei Liaob81c6a42010-10-10 14:15:00 -07001665 if (OutputPackageName.empty() || OutputPackageName == "-")
1666 C = new Context(OutputPathBase, InputFileName, "<Package Name>",
1667 ResourceId, true);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001668 else
Shih-wei Liaob81c6a42010-10-10 14:15:00 -07001669 C = new Context(OutputPathBase, InputFileName, OutputPackageName,
1670 ResourceId, false);
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001671
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001672 if (C != NULL) {
1673 std::string ErrorMsg, ScriptClassName;
1674 // class ScriptC_<ScriptName>
1675 if (!GetClassNameFromFileName(InputFileName, ScriptClassName))
1676 return false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001677
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001678 if (ScriptClassName.empty())
1679 ScriptClassName = "<Input Script Name>";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001680
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001681 ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX);
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001682
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001683 if (mRSContext->getLicenseNote() != NULL) {
1684 C->setLicenseNote(*(mRSContext->getLicenseNote()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001685 }
1686
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001687 if (!genScriptClass(*C, ScriptClassName, ErrorMsg)) {
1688 std::cerr << "Failed to generate class " << ScriptClassName << " ("
1689 << ErrorMsg << ")" << std::endl;
1690 return false;
1691 }
1692
1693 // class ScriptField_<TypeName>
1694 for (RSContext::const_export_type_iterator TI =
1695 mRSContext->export_types_begin(),
1696 TE = mRSContext->export_types_end();
1697 TI != TE;
1698 TI++) {
1699 const RSExportType *ET = TI->getValue();
1700
1701 if (ET->getClass() == RSExportType::ExportClassRecord) {
1702 const RSExportRecordType *ERT =
1703 static_cast<const RSExportRecordType*>(ET);
1704
1705 if (!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) {
1706 std::cerr << "Failed to generate type class for struct '"
1707 << ERT->getName() << "' (" << ErrorMsg << ")" << std::endl;
1708 return false;
1709 }
1710 }
1711 }
1712 }
1713
1714 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001715}
1716
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001717/************************** RSReflection::Context **************************/
zonr6315f762010-10-05 15:35:14 +08001718const char *const RSReflection::Context::ApacheLicenseNote =
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001719 "/*\n"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001720 " * Copyright (C) 2010 The Android Open Source Project\n"
1721 " *\n"
1722 " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
1723 " * you may not use this file except in compliance with the License.\n"
1724 " * You may obtain a copy of the License at\n"
1725 " *\n"
1726 " * http://www.apache.org/licenses/LICENSE-2.0\n"
1727 " *\n"
1728 " * Unless required by applicable law or agreed to in writing, software\n"
1729 " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
1730 " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
1731 "implied.\n"
1732 " * See the License for the specific language governing permissions and\n"
1733 " * limitations under the License.\n"
1734 " */\n"
1735 "\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001736
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001737const char *const RSReflection::Context::Import[] = {
1738 // RenderScript java class
1739 "android.renderscript.*",
1740 // Import R
1741 "android.content.res.Resources",
1742 // Import for debugging
1743 "android.util.Log",
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001744};
1745
Zonr Chang8c6d9b22010-10-07 18:01:19 +08001746bool RSReflection::Context::openClassFile(const std::string &ClassName,
1747 std::string &ErrorMsg) {
1748 if (!mUseStdout) {
1749 mOF.clear();
1750 std::string Path =
Shih-wei Liaob81c6a42010-10-10 14:15:00 -07001751 RSSlangReflectUtils::ComputePackagedPath(mOutputPathBase.c_str(),
Zonr Chang8c6d9b22010-10-07 18:01:19 +08001752 mPackageName.c_str());
1753
1754 if (!SlangUtils::CreateDirectoryWithParents(Path, &ErrorMsg))
1755 return false;
1756
1757 std::string ClassFile = Path + "/" + ClassName + ".java";
1758
1759 mOF.open(ClassFile.c_str());
1760 if (!mOF.good()) {
1761 ErrorMsg = "failed to open file '" + ClassFile + "' for write";
1762 return false;
1763 }
1764 }
1765 return true;
1766}
1767
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001768const char *RSReflection::Context::AccessModifierStr(AccessModifier AM) {
1769 switch (AM) {
1770 case AM_Public: return "public"; break;
1771 case AM_Protected: return "protected"; break;
1772 case AM_Private: return "private"; break;
1773 default: return ""; break;
1774 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001775}
1776
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001777bool RSReflection::Context::startClass(AccessModifier AM,
1778 bool IsStatic,
1779 const std::string &ClassName,
1780 const char *SuperClassName,
1781 std::string &ErrorMsg) {
1782 if (mVerbose)
1783 std::cout << "Generating " << ClassName << ".java ..." << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001784
Zonr Chang8c6d9b22010-10-07 18:01:19 +08001785 // Open file for class
1786 if (!openClassFile(ClassName, ErrorMsg))
1787 return false;
1788
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001789 // License
1790 out() << mLicenseNote;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001791
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001792 // Notice of generated file
1793 out() << "/*" << std::endl;
1794 out() << " * This file is auto-generated. DO NOT MODIFY!" << std::endl;
1795 out() << " * The source RenderScript file: " << mInputRSFile << std::endl;
1796 out() << " */" << std::endl;
Ying Wang4e348442010-08-18 10:29:12 -07001797
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001798 // Package
1799 if (!mPackageName.empty())
1800 out() << "package " << mPackageName << ";" << std::endl;
1801 out() << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001802
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001803 // Imports
1804 for (unsigned i = 0;i < (sizeof(Import) / sizeof(const char*)); i++)
1805 out() << "import " << Import[i] << ";" << std::endl;
1806 out() << std::endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001807
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001808 // All reflected classes should be annotated as hidden, so that they won't
1809 // be exposed in SDK.
1810 out() << "/**" << std::endl;
1811 out() << " * @hide" << std::endl;
1812 out() << " */" << std::endl;
Ying Wang4e348442010-08-18 10:29:12 -07001813
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001814 out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class "
1815 << ClassName;
1816 if (SuperClassName != NULL)
1817 out() << " extends " << SuperClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001818
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001819 startBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001820
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001821 mClassName = ClassName;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001822
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001823 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001824}
1825
1826void RSReflection::Context::endClass() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001827 endBlock();
1828 if (!mUseStdout)
1829 mOF.close();
1830 clear();
1831 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001832}
1833
1834void RSReflection::Context::startBlock(bool ShouldIndent) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001835 if (ShouldIndent)
1836 indent() << "{" << std::endl;
1837 else
1838 out() << " {" << std::endl;
1839 incIndentLevel();
1840 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001841}
1842
1843void RSReflection::Context::endBlock() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001844 decIndentLevel();
1845 indent() << "}" << std::endl << std::endl;
1846 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001847}
1848
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001849void RSReflection::Context::startTypeClass(const std::string &ClassName) {
1850 indent() << "public static class " << ClassName;
1851 startBlock();
1852 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001853}
1854
1855void RSReflection::Context::endTypeClass() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001856 endBlock();
1857 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001858}
1859
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -07001860void RSReflection::Context::startFunction(AccessModifier AM,
1861 bool IsStatic,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001862 const char *ReturnType,
1863 const std::string &FunctionName,
1864 int Argc, ...) {
1865 ArgTy Args;
1866 va_list vl;
1867 va_start(vl, Argc);
1868
zonr6315f762010-10-05 15:35:14 +08001869 for (int i = 0; i < Argc; i++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001870 const char *ArgType = va_arg(vl, const char*);
1871 const char *ArgName = va_arg(vl, const char*);
1872
zonr6315f762010-10-05 15:35:14 +08001873 Args.push_back(std::make_pair(ArgType, ArgName));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001874 }
1875 va_end(vl);
1876
1877 startFunction(AM, IsStatic, ReturnType, FunctionName, Args);
1878
1879 return;
1880}
1881
1882void RSReflection::Context::startFunction(AccessModifier AM,
1883 bool IsStatic,
1884 const char *ReturnType,
1885 const std::string &FunctionName,
zonr6315f762010-10-05 15:35:14 +08001886 const ArgTy &Args) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001887 indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ")
1888 << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "(";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001889
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001890 bool FirstArg = true;
1891 for (ArgTy::const_iterator I = Args.begin(), E = Args.end();
1892 I != E;
1893 I++) {
1894 if (!FirstArg)
1895 out() << ", ";
1896 else
1897 FirstArg = false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001898
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001899 out() << I->first << " " << I->second;
1900 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001901
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001902 out() << ")";
1903 startBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001904
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001905 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001906}
1907
1908void RSReflection::Context::endFunction() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07001909 endBlock();
1910 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001911}