blob: 7e9c59fb4605973683a551a31dce575ae73fc0b7 [file] [log] [blame]
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001#include "slang_rs_context.hpp"
2#include "slang_rs_export_var.hpp"
3#include "slang_rs_reflection.hpp"
4#include "slang_rs_export_func.hpp"
5
6#include <ctype.h>
7
8#include <utility>
9#include <cstdarg>
10
11using std::make_pair;
12using std::endl;
13
14
15#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_"
16#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC"
17
18#define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_"
19#define RS_TYPE_CLASS_SUPER_CLASS_NAME "android.renderscript.Script.FieldBase"
20
21#define RS_TYPE_ITEM_CLASS_NAME "Item"
22
23#define RS_TYPE_ITEM_BUFFER_NAME "mItemArray"
24#define RS_TYPE_ITEM_BUFFER_PACKER_NAME "mIOBuffer"
25
26#define RS_EXPORT_VAR_INDEX_PREFIX "mExportVarIdx_"
27#define RS_EXPORT_VAR_PREFIX "mExportVar_"
28
29#define RS_EXPORT_FUNC_INDEX_PREFIX "mExportFuncIdx_"
30
31#define RS_EXPORT_VAR_ALLOCATION_PREFIX "mAlloction_"
32#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_"
33
34namespace slang {
35
36/* Some utility function using internal in RSReflection */
37static bool GetFileNameWithoutExtension(const std::string& FileName, std::string& OutFileName) {
38 OutFileName.clear();
39
40 if(FileName.empty() || (FileName == "-"))
41 return true;
42
43 /* find last component in given path */
44 size_t SlashPos = FileName.find_last_of("/\\");
45
46 if((SlashPos != std::string::npos) && ((SlashPos + 1) < FileName.length()))
47 OutFileName = FileName.substr(SlashPos + 1);
48 else
49 OutFileName = FileName;
50
51 size_t DotPos = OutFileName.find_first_of('.');
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -070052 if(DotPos != std::string::npos)
53 OutFileName.erase(DotPos);
Shih-wei Liao462aefd2010-06-04 15:32:04 -070054
55 return true;
56}
57
58static const char* GetPrimitiveTypeName(const RSExportPrimitiveType* EPT) {
59 static const char* PrimitiveTypeJavaNameMap[] = {
60 "",
61 "",
62 "float", /* RSExportPrimitiveType::DataTypeFloat32 */
63 "double", /* RSExportPrimitiveType::DataTypeFloat64 */
64 "byte", /* RSExportPrimitiveType::DataTypeSigned8 */
65 "short", /* RSExportPrimitiveType::DataTypeSigned16 */
66 "int", /* RSExportPrimitiveType::DataTypeSigned32 */
67 "long", /* RSExportPrimitiveType::DataTypeSigned64 */
Shih-wei Liaoc20992e2010-06-09 18:30:18 -070068 "short", /* RSExportPrimitiveType::DataTypeUnsigned8 */
69 "int", /* RSExportPrimitiveType::DataTypeUnsigned16 */
70 "long", /* RSExportPrimitiveType::DataTypeUnsigned32 */
Shih-wei Liao462aefd2010-06-04 15:32:04 -070071 "long", /* RSExportPrimitiveType::DataTypeUnsigned64 */
72
Shih-wei Liaoc20992e2010-06-09 18:30:18 -070073 "int", /* RSExportPrimitiveType::DataTypeUnsigned565 */
74 "int", /* RSExportPrimitiveType::DataTypeUnsigned5551 */
75 "int", /* RSExportPrimitiveType::DataTypeUnsigned4444 */
Shih-wei Liao462aefd2010-06-04 15:32:04 -070076
Shih-wei Liao1f0d88f2010-06-25 00:15:24 -070077 "boolean", /* RSExportPrimitiveType::DataTypeBool */
Shih-wei Liaodd35e492010-06-21 14:42:40 -070078
Shih-wei Liao462aefd2010-06-04 15:32:04 -070079 "Element", /* RSExportPrimitiveType::DataTypeRSElement */
80 "Type", /* RSExportPrimitiveType::DataTypeRSType */
81 "Allocation", /* RSExportPrimitiveType::DataTypeRSAllocation */
82 "Sampler", /* RSExportPrimitiveType::DataTypeRSSampler */
83 "Script", /* RSExportPrimitiveType::DataTypeRSScript */
Shih-wei Liaof1bd5102010-07-09 14:44:22 -070084 "Mesh", /* RSExportPrimitiveType::DataTypeRSMesh */
Shih-wei Liao462aefd2010-06-04 15:32:04 -070085 "ProgramFragment", /* RSExportPrimitiveType::DataTypeRSProgramFragment */
86 "ProgramVertex", /* RSExportPrimitiveType::DataTypeRSProgramVertex */
87 "ProgramRaster", /* RSExportPrimitiveType::DataTypeRSProgramRaster */
88 "ProgramStore", /* RSExportPrimitiveType::DataTypeRSProgramStore */
Shih-wei Liaobb1f9f02010-06-24 12:35:17 -070089 "Font", /* RSExportPrimitiveType::DataTypeRSFont */
Shih-wei Liao462aefd2010-06-04 15:32:04 -070090 };
91
Shih-wei Liao1f0d88f2010-06-25 00:15:24 -070092 if((EPT->getType() >= 0) && (EPT->getType() < (sizeof(PrimitiveTypeJavaNameMap) / sizeof(const char*)))) {
93 // printf("Type %d\n", EPT->getType());
Shih-wei Liao462aefd2010-06-04 15:32:04 -070094 return PrimitiveTypeJavaNameMap[ EPT->getType() ];
Shih-wei Liao1f0d88f2010-06-25 00:15:24 -070095 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070096
97 assert(false && "GetPrimitiveTypeName : Unknown primitive data type");
98 return NULL;
99}
100
101static const char* GetVectorTypeName(const RSExportVectorType* EVT) {
102 static const char* VectorTypeJavaNameMap[][3] = {
103 /* 0 */ { "Byte2", "Byte3", "Byte4" },
104 /* 1 */ { "Short2", "Short3", "Short4" },
105 /* 2 */ { "Int2", "Int3", "Int4" },
Shih-wei Liaoc20992e2010-06-09 18:30:18 -0700106 /* 3 */ { "Long2", "Long3", "Long4" },
107 /* 4 */ { "Float2", "Float3", "Float4" },
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700108 };
109
110 const char** BaseElement;
111
112 switch(EVT->getType()) {
113 case RSExportPrimitiveType::DataTypeSigned8:
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700114 BaseElement = VectorTypeJavaNameMap[0];
115 break;
116
117 case RSExportPrimitiveType::DataTypeSigned16:
Shih-wei Liaoc20992e2010-06-09 18:30:18 -0700118 case RSExportPrimitiveType::DataTypeUnsigned8:
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700119 BaseElement = VectorTypeJavaNameMap[1];
120 break;
121
122 case RSExportPrimitiveType::DataTypeSigned32:
Shih-wei Liaoc20992e2010-06-09 18:30:18 -0700123 case RSExportPrimitiveType::DataTypeUnsigned16:
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700124 BaseElement = VectorTypeJavaNameMap[2];
125 break;
126
Shih-wei Liaoc20992e2010-06-09 18:30:18 -0700127 case RSExportPrimitiveType::DataTypeUnsigned32:
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700128 BaseElement = VectorTypeJavaNameMap[3];
129 break;
130
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -0700131 case RSExportPrimitiveType::DataTypeFloat32:
Shih-wei Liaoc20992e2010-06-09 18:30:18 -0700132 BaseElement = VectorTypeJavaNameMap[4];
133 break;
134
Shih-wei Liao1f0d88f2010-06-25 00:15:24 -0700135 case RSExportPrimitiveType::DataTypeBool:
136 BaseElement = VectorTypeJavaNameMap[0];
137 break;
138
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700139 default:
140 assert(false && "RSReflection::genElementTypeName : Unsupported vector element data type");
141 break;
142 }
143
144 assert((EVT->getNumElement() > 1) && (EVT->getNumElement() <= 4) && "Number of element in vector type is invalid");
145
146 return BaseElement[EVT->getNumElement() - 2];
147}
148
Shih-wei Liao324c0472010-06-21 13:15:11 -0700149static const char* GetVectorAccessor(int Index) {
150 static const char* VectorAccessorMap[] = {
151 /* 0 */ "x",
152 /* 1 */ "y",
153 /* 2 */ "z",
154 /* 3 */ "w",
155 };
156
157 assert((Index >= 0) && (Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) && "Out-of-bound index to access vector member");
158
159 return VectorAccessorMap[Index];
160}
161
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700162static const char* GetPackerAPIName(const RSExportPrimitiveType* EPT) {
163 static const char* PrimitiveTypePackerAPINameMap[] = {
164 "",
165 "",
166 "addF32", /* RSExportPrimitiveType::DataTypeFloat32 */
167 "addF64", /* RSExportPrimitiveType::DataTypeFloat64 */
168 "addI8", /* RSExportPrimitiveType::DataTypeSigned8 */
169 "addI16", /* RSExportPrimitiveType::DataTypeSigned16 */
170 "addI32", /* RSExportPrimitiveType::DataTypeSigned32 */
171 "addI64", /* RSExportPrimitiveType::DataTypeSigned64 */
172 "addU8", /* RSExportPrimitiveType::DataTypeUnsigned8 */
173 "addU16", /* RSExportPrimitiveType::DataTypeUnsigned16 */
174 "addU32", /* RSExportPrimitiveType::DataTypeUnsigned32 */
175 "addU64", /* RSExportPrimitiveType::DataTypeUnsigned64 */
176
177 "addU16", /* RSExportPrimitiveType::DataTypeUnsigned565 */
178 "addU16", /* RSExportPrimitiveType::DataTypeUnsigned5551 */
179 "addU16", /* RSExportPrimitiveType::DataTypeUnsigned4444 */
180
Shih-wei Liaodd35e492010-06-21 14:42:40 -0700181 "addBoolean", /* RSExportPrimitiveType::DataTypeBool */
182
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700183 "addObj", /* RSExportPrimitiveType::DataTypeRSElement */
184 "addObj", /* RSExportPrimitiveType::DataTypeRSType */
185 "addObj", /* RSExportPrimitiveType::DataTypeRSAllocation */
186 "addObj", /* RSExportPrimitiveType::DataTypeRSSampler */
187 "addObj", /* RSExportPrimitiveType::DataTypeRSScript */
Shih-wei Liaof1bd5102010-07-09 14:44:22 -0700188 "addObj", /* RSExportPrimitiveType::DataTypeRSMesh */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700189 "addObj", /* RSExportPrimitiveType::DataTypeRSProgramFragment */
190 "addObj", /* RSExportPrimitiveType::DataTypeRSProgramVertex */
191 "addObj", /* RSExportPrimitiveType::DataTypeRSProgramRaster */
192 "addObj", /* RSExportPrimitiveType::DataTypeRSProgramStore */
Shih-wei Liaobb1f9f02010-06-24 12:35:17 -0700193 "addObj", /* RSExportPrimitiveType::DataTypeRSFont */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700194 };
195
196 if((EPT->getType() >= 0) && (EPT->getType() < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char*))))
197 return PrimitiveTypePackerAPINameMap[ EPT->getType() ];
198
199 assert(false && "GetPackerAPIName : Unknown primitive data type");
200 return NULL;
201}
202
203static std::string GetTypeName(const RSExportType* ET) {
204 switch(ET->getClass()) {
205 case RSExportType::ExportClassPrimitive:
206 return GetPrimitiveTypeName(static_cast<const RSExportPrimitiveType*>(ET));
207 break;
208
209 case RSExportType::ExportClassPointer:
210 {
211 const RSExportType* PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType();
212
213 if(PointeeType->getClass() != RSExportType::ExportClassRecord)
214 return "Allocation";
215 else
216 return RS_TYPE_CLASS_NAME_PREFIX + PointeeType->getName();
217 }
218 break;
219
220 case RSExportType::ExportClassVector:
221 return GetVectorTypeName(static_cast<const RSExportVectorType*>(ET));
222 break;
223
224 case RSExportType::ExportClassRecord:
225 return RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + "."RS_TYPE_ITEM_CLASS_NAME;
226 break;
227
228 default:
229 assert(false && "Unknown class of type");
230 break;
231 }
232
233 return "";
234}
235
236static const char* GetBuiltinElementConstruct(const RSExportType* ET) {
237 if(ET->getClass() == RSExportType::ExportClassPrimitive) {
238 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET);
239 if(EPT->getKind() == RSExportPrimitiveType::DataKindUser) {
240 static const char* PrimitiveBuiltinElementConstructMap[] = {
241 NULL,
242 NULL,
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -0700243 "F32", /* RSExportPrimitiveType::DataTypeFloat32 */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700244 NULL, /* RSExportPrimitiveType::DataTypeFloat64 */
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -0700245 "I8", /* RSExportPrimitiveType::DataTypeSigned8 */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700246 NULL, /* RSExportPrimitiveType::DataTypeSigned16 */
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -0700247 "I32", /* RSExportPrimitiveType::DataTypeSigned32 */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700248 NULL, /* RSExportPrimitiveType::DataTypeSigned64 */
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -0700249 "U8", /* RSExportPrimitiveType::DataTypeUnsigned8 */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700250 NULL, /* RSExportPrimitiveType::DataTypeUnsigned16 */
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -0700251 "U32", /* RSExportPrimitiveType::DataTypeUnsigned32 */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700252 NULL, /* RSExportPrimitiveType::DataTypeUnsigned64 */
253
254 NULL, /* RSExportPrimitiveType::DataTypeUnsigned565 */
255 NULL, /* RSExportPrimitiveType::DataTypeUnsigned5551 */
256 NULL, /* RSExportPrimitiveType::DataTypeUnsigned4444 */
257
Shih-wei Liaodd35e492010-06-21 14:42:40 -0700258 "BOOLEAN", /* RSExportPrimitiveType::DataTypeBool */
259
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -0700260 "ELEMENT", /* RSExportPrimitiveType::DataTypeRSElement */
261 "TYPE", /* RSExportPrimitiveType::DataTypeRSType */
262 "ALLOCATION", /* RSExportPrimitiveType::DataTypeRSAllocation */
263 "SAMPLER", /* RSExportPrimitiveType::DataTypeRSSampler */
264 "SCRIPT", /* RSExportPrimitiveType::DataTypeRSScript */
Shih-wei Liaof1bd5102010-07-09 14:44:22 -0700265 "MESH", /* RSExportPrimitiveType::DataTypeRSMesh */
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -0700266 "PROGRAM_FRAGMENT", /* RSExportPrimitiveType::DataTypeRSProgramFragment */
267 "PROGRAM_VERTEX", /* RSExportPrimitiveType::DataTypeRSProgramVertex */
268 "PROGRAM_RASTER", /* RSExportPrimitiveType::DataTypeRSProgramRaster */
269 "PROGRAM_STORE", /* RSExportPrimitiveType::DataTypeRSProgramStore */
Shih-wei Liaobb1f9f02010-06-24 12:35:17 -0700270 "FONT", /* RSExportPrimitiveType::DataTypeRSFont */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700271 };
272
273 if((EPT->getType() >= 0) && (EPT->getType() < (sizeof(PrimitiveBuiltinElementConstructMap) / sizeof(const char*))))
274 return PrimitiveBuiltinElementConstructMap[ EPT->getType() ];
275 } else if(EPT->getKind() == RSExportPrimitiveType::DataKindPixelA) {
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -0700276 if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700277 return "A_8";
278 } else if(EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGB) {
279 if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned565)
280 return "RGB_565";
281 else if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
282 return "RGB_888";
283 } else if(EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGBA) {
284 if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned5551)
285 return "RGB_5551";
286 else if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned4444)
287 return "RGB_4444";
288 else if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
289 return "RGB_8888";
290 } else if(EPT->getKind() == RSExportPrimitiveType::DataKindIndex) {
291 if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned16)
292 return "INDEX_16";
293 }
294 } else if(ET->getClass() == RSExportType::ExportClassVector) {
295 const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(ET);
296 if(EVT->getKind() == RSExportPrimitiveType::DataKindPosition) {
297 if(EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
298 if(EVT->getNumElement() == 2)
299 return "ATTRIB_POSITION_2";
300 else if(EVT->getNumElement() == 3)
301 return "ATTRIB_POSITION_3";
302 }
303 } else if(EVT->getKind() == RSExportPrimitiveType::DataKindTexture) {
304 if(EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
305 if(EVT->getNumElement() == 2)
306 return "ATTRIB_TEXTURE_2";
307 }
308 } else if(EVT->getKind() == RSExportPrimitiveType::DataKindNormal) {
309 if(EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
310 if(EVT->getNumElement() == 3)
311 return "ATTRIB_NORMAL_3";
312 }
313 } else if(EVT->getKind() == RSExportPrimitiveType::DataKindColor) {
314 if(EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
315 if(EVT->getNumElement() == 4)
316 return "ATTRIB_COLOR_F32_4";
317 } else if(EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) {
318 if(EVT->getNumElement() == 4)
319 return "ATTRIB_COLOR_U8_4";
320 }
321 }
322 } else if(ET->getClass() == RSExportType::ExportClassPointer) {
Shih-wei Liaoc20992e2010-06-09 18:30:18 -0700323 return "USER_I32"; /* tread pointer type variable as unsigned int (TODO: this is target dependent) */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700324 }
325
326 return NULL;
327}
328
329static const char* GetElementDataKindName(RSExportPrimitiveType::DataKind DK) {
330 static const char* ElementDataKindNameMap[] = {
331 "Element.DataKind.USER", /* RSExportPrimitiveType::DataKindUser */
332 "Element.DataKind.COLOR", /* RSExportPrimitiveType::DataKindColor */
333 "Element.DataKind.POSITION", /* RSExportPrimitiveType::DataKindPosition */
334 "Element.DataKind.TEXTURE", /* RSExportPrimitiveType::DataKindTexture */
335 "Element.DataKind.NORMAL", /* RSExportPrimitiveType::DataKindNormal */
336 "Element.DataKind.INDEX", /* RSExportPrimitiveType::DataKindIndex */
337 "Element.DataKind.POINT_SIZE", /* RSExportPrimitiveType::DataKindPointSize */
338 "Element.DataKind.PIXEL_L", /* RSExportPrimitiveType::DataKindPixelL */
339 "Element.DataKind.PIXEL_A", /* RSExportPrimitiveType::DataKindPixelA */
340 "Element.DataKind.PIXEL_LA", /* RSExportPrimitiveType::DataKindPixelLA */
341 "Element.DataKind.PIXEL_RGB", /* RSExportPrimitiveType::DataKindPixelRGB */
342 "Element.DataKind.PIXEL_RGBA", /* RSExportPrimitiveType::DataKindPixelRGBA */
343 };
344
345 if((DK >= 0) && (DK < (sizeof(ElementDataKindNameMap) / sizeof(const char*))))
346 return ElementDataKindNameMap[ DK ];
347 else
348 return NULL;
349}
350
351static const char* GetElementDataTypeName(RSExportPrimitiveType::DataType DT) {
352 static const char* ElementDataTypeNameMap[] = {
353 NULL,
354 NULL,
355 "Element.DataType.FLOAT_32", /* RSExportPrimitiveType::DataTypeFloat32 */
356 NULL, /* RSExportPrimitiveType::DataTypeFloat64 */
357 "Element.DataType.SIGNED_8", /* RSExportPrimitiveType::DataTypeSigned8 */
358 "Element.DataType.SIGNED_16", /* RSExportPrimitiveType::DataTypeSigned16 */
359 "Element.DataType.SIGNED_32", /* RSExportPrimitiveType::DataTypeSigned32 */
360 NULL, /* RSExportPrimitiveType::DataTypeSigned64 */
361 "Element.DataType.UNSIGNED_8", /* RSExportPrimitiveType::DataTypeUnsigned8 */
362 "Element.DataType.UNSIGNED_16", /* RSExportPrimitiveType::DataTypeUnsigned16 */
363 "Element.DataType.UNSIGNED_32", /* RSExportPrimitiveType::DataTypeUnsigned32 */
364 NULL, /* RSExportPrimitiveType::DataTypeUnsigned64 */
365
366 "Element.DataType.UNSIGNED_5_6_5", /* RSExportPrimitiveType::DataTypeUnsigned565 */
367 "Element.DataType.UNSIGNED_5_5_5_1", /* RSExportPrimitiveType::DataTypeUnsigned5551 */
368 "Element.DataType.UNSIGNED_4_4_4_4", /* RSExportPrimitiveType::DataTypeUnsigned4444 */
369
Shih-wei Liaodd35e492010-06-21 14:42:40 -0700370 "Element.DataType.BOOLEAN", /* RSExportPrimitiveType::DataTypeBool */
371
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700372 "Element.DataType.RS_ELEMENT", /* RSExportPrimitiveType::DataTypeRSElement */
373 "Element.DataType.RS_TYPE", /* RSExportPrimitiveType::DataTypeRSType */
374 "Element.DataType.RS_ALLOCATION", /* RSExportPrimitiveType::DataTypeRSAllocation */
375 "Element.DataType.RS_SAMPLER", /* RSExportPrimitiveType::DataTypeRSSampler */
376 "Element.DataType.RS_SCRIPT", /* RSExportPrimitiveType::DataTypeRSScript */
Shih-wei Liaof1bd5102010-07-09 14:44:22 -0700377 "Element.DataType.RS_MESH", /* RSExportPrimitiveType::DataTypeRSMesh */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700378 "Element.DataType.RS_PROGRAM_FRAGMENT", /* RSExportPrimitiveType::DataTypeRSProgramFragment */
379 "Element.DataType.RS_PROGRAM_VERTEX", /* RSExportPrimitiveType::DataTypeRSProgramVertex */
380 "Element.DataType.RS_PROGRAM_RASTER", /* RSExportPrimitiveType::DataTypeRSProgramRaster */
381 "Element.DataType.RS_PROGRAM_STORE", /* RSExportPrimitiveType::DataTypeRSProgramStore */
Shih-wei Liaobb1f9f02010-06-24 12:35:17 -0700382 "Element.DataType.RS_FONT", /* RSExportPrimitiveType::DataTypeRSFont */
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700383 };
384
385 if((DT >= 0) && (DT < (sizeof(ElementDataTypeNameMap) / sizeof(const char*))))
386 return ElementDataTypeNameMap[ DT ];
387 else
388 return NULL;
389}
390
391/****************************** Methods to generate script class ******************************/
392bool RSReflection::genScriptClass(Context& C, const std::string& ClassName, std::string& ErrorMsg) {
Shih-wei Liao6de89272010-07-15 15:26:20 -0700393 /* Open the file */
394 if(!C.mUseStdout) {
395 C.mOF.clear();
396 C.mOF.open(( mRSContext->getReflectJavaPathName() + "/" + ClassName + ".java" ).c_str());
397 if(!C.mOF.good()) {
398 ErrorMsg = "failed to open file '" + ClassName + ".java' for write";
399 return false;
400 }
401 }
402
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -0700403 if(!C.startClass(Context::AM_Public, false, ClassName, RS_SCRIPT_CLASS_SUPER_CLASS_NAME, ErrorMsg))
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700404 return false;
405
406 genScriptClassConstructor(C);
407
408 /* Reflect export variable */
409 for(RSContext::const_export_var_iterator I = mRSContext->export_vars_begin();
410 I != mRSContext->export_vars_end();
411 I++)
412 genExportVariable(C, *I);
413
414 /* Reflect export function */
415 for(RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin();
416 I != mRSContext->export_funcs_end();
417 I++)
418 genExportFunction(C, *I);
419
420 C.endClass();
421
422 return true;
423}
424
425void RSReflection::genScriptClassConstructor(Context& C) {
426 C.indent() << "// Constructor" << endl;
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -0700427 C.startFunction(Context::AM_Public, false, NULL, C.getClassName(), 4, "RenderScript", "rs",
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700428 "Resources", "resources",
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -0700429 "int", "id",
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700430 "boolean", "isRoot");
431 /* Call constructor of super class */
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -0700432 C.indent() << "super(rs, resources, id, isRoot);" << endl;
Shih-wei Liao324c0472010-06-21 13:15:11 -0700433
434 /* If an exported variable has initial value, reflect it */
435
436 for(RSContext::const_export_var_iterator I = mRSContext->export_vars_begin();
437 I != mRSContext->export_vars_end();
438 I++)
439 {
440 const RSExportVar* EV = *I;
441 if(!EV->getInit().isUninit())
442 genInitExportVariable(C, EV->getType(), EV->getName(), EV->getInit());
443 }
444
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700445 C.endFunction();
446 return;
447}
448
Shih-wei Liao48bac232010-07-03 22:29:41 -0700449void RSReflection::genInitBoolExportVariable(Context& C, const std::string& VarName, const APValue& Val) {
450 assert(!Val.isUninit() && "Not a valid initializer");
451
452 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
453 assert((Val.getKind() == APValue::Int) && "Bool type has wrong initial APValue");
454
455 if (Val.getInt().getSExtValue() == 0) {
456 C.out() << "false";
457 } else {
458 C.out() << "true";
459 }
460 C.out() << ";" << endl;
461
462 return;
463}
464
Shih-wei Liao324c0472010-06-21 13:15:11 -0700465void RSReflection::genInitPrimitiveExportVariable(Context& C, const std::string& VarName, const APValue& Val) {
466 assert(!Val.isUninit() && "Not a valid initializer");
467
468 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = ";
469 switch(Val.getKind()) {
470 case APValue::Int: C.out() << Val.getInt().getSExtValue(); break;
471 case APValue::Float: C.out() << Val.getFloat().convertToDouble(); break;
472
473 case APValue::ComplexInt:
474 case APValue::ComplexFloat:
475 case APValue::LValue:
476 case APValue::Vector:
477 assert(false && "Primitive type cannot have such kind of initializer");
478 break;
479
480 default:
481 assert(false && "Unknown kind of initializer");
482 break;
483 }
484 C.out() << ";" << endl;
485
486 return;
487}
488
489void RSReflection::genInitExportVariable(Context& C, const RSExportType* ET, const std::string& VarName, const APValue& Val) {
490 assert(!Val.isUninit() && "Not a valid initializer");
491
492 switch(ET->getClass()) {
Shih-wei Liao48bac232010-07-03 22:29:41 -0700493 case RSExportType::ExportClassPrimitive: {
494 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET);
495 if (EPT->getType() == RSExportPrimitiveType::DataTypeBool) {
496 genInitBoolExportVariable(C, VarName, Val);
497 } else {
498 genInitPrimitiveExportVariable(C, VarName, Val);
499 }
500 break;
501 }
Shih-wei Liao324c0472010-06-21 13:15:11 -0700502
503 case RSExportType::ExportClassPointer:
504 if(!Val.isInt() || Val.getInt().getSExtValue() != 0)
505 std::cout << "Initializer which is non-NULL to pointer type variable will be ignored" << endl;
506 break;
507
508 case RSExportType::ExportClassVector:
509 {
510 const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(ET);
511 switch(Val.getKind()) {
512 case APValue::Int:
513 case APValue::Float:
514 for(int i=0;i<EVT->getNumElement();i++) {
515 std::string Name = VarName + "." + GetVectorAccessor(i);
516 genInitPrimitiveExportVariable(C, Name, Val);
517 }
518 break;
519
520 case APValue::Vector:
521 {
522 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new " << GetVectorTypeName(EVT) << "();" << endl;
523
524 unsigned NumElements = std::min(static_cast<unsigned>(EVT->getNumElement()), Val.getVectorLength());
525 for(unsigned i=0;i<NumElements;i++) {
526 const APValue& ElementVal = Val.getVectorElt(i);
527 std::string Name = VarName + "." + GetVectorAccessor(i);
528 genInitPrimitiveExportVariable(C, Name, ElementVal);
529 }
530 }
531 break;
532 }
533 }
534 break;
535
536 /* TODO: Resolving initializer of a record type variable is complex. It cannot obtain by just simply evaluating the initializer expression. */
537 case RSExportType::ExportClassRecord:
538 {
539 /*
540 unsigned InitIndex = 0;
541 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET);
542
543 assert((Val.getKind() == APValue::Vector) && "Unexpected type of initializer for record type variable");
544
545 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new "RS_TYPE_CLASS_NAME_PREFIX << ERT->getName() << "."RS_TYPE_ITEM_CLASS_NAME"();" << endl;
546
547 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin();
548 I != ERT->fields_end();
549 I++)
550 {
551 const RSExportRecordType::Field* F = *I;
552 std::string FieldName = VarName + "." + F->getName();
553
554 if(InitIndex > Val.getVectorLength())
555 break;
556
557 genInitPrimitiveExportVariable(C, FieldName, Val.getVectorElt(InitIndex++));
558 }
559 */
560 assert(false && "Unsupported initializer for record type variable currently");
561 }
562 break;
563
564 default:
565 assert(false && "Unknown class of type");
566 break;
567 }
568 return;
569}
570
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700571void RSReflection::genExportVariable(Context& C, const RSExportVar* EV) {
572 const RSExportType* ET = EV->getType();
573
574 C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << " = " << C.getNextExportVarSlot() << ";" << endl;
575
576 switch(ET->getClass()) {
577 case RSExportType::ExportClassPrimitive:
578 genPrimitiveTypeExportVariable(C, EV);
579 break;
580
581 case RSExportType::ExportClassPointer:
582 genPointerTypeExportVariable(C, EV);
583 break;
584
585 case RSExportType::ExportClassVector:
586 genVectorTypeExportVariable(C, EV);
587 break;
588
589 case RSExportType::ExportClassRecord:
590 genRecordTypeExportVariable(C, EV);
591 break;
592
593 default:
594 assert(false && "Unknown class of type");
595 break;
596 }
597
598 return;
599}
600
601void RSReflection::genExportFunction(Context& C, const RSExportFunc* EF) {
602 C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << " = " << C.getNextExportFuncSlot() << ";" << endl;
603
604 /* invoke_*() */
605 Context::ArgTy Args;
606
607 for(RSExportFunc::const_param_iterator I = EF->params_begin();
608 I != EF->params_end();
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -0700609 I++)
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700610 {
611 const RSExportFunc::Parameter* P = *I;
612 Args.push_back( make_pair(GetTypeName(P->getType()), P->getName()) );
613 }
614
615 C.startFunction(Context::AM_Public, false, "void", "invoke_" + EF->getName(), Args);
616
617 if(!EF->hasParam()) {
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -0700618 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");" << endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700619 } else {
620 const RSExportRecordType* ERT = EF->getParamPacketType();
621 std::string FieldPackerName = EF->getName() + "_fp";
622
623 if(genCreateFieldPacker(C, ERT, FieldPackerName.c_str()))
624 genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str());
625
Shih-wei Liaobdd78882010-06-06 05:55:36 -0700626 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", " << FieldPackerName << ");" << endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700627 }
628
629 C.endFunction();
630 return;
631}
632
633void RSReflection::genPrimitiveTypeExportVariable(Context& C, const RSExportVar* EV) {
634 assert((EV->getType()->getClass() == RSExportType::ExportClassPrimitive) && "Variable should be type of primitive here");
635
636 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(EV->getType());
637 const char* TypeName = GetPrimitiveTypeName(EPT);
638
639 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl;
640
641 /* set_*() */
Shih-wei Liaoc382c602010-06-21 15:04:48 -0700642 if(!EV->isConst()) {
643 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName, "v");
644 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700645
Shih-wei Liaoc382c602010-06-21 15:04:48 -0700646 if(EPT->isRSObjectType())
647 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", (v == null) ? 0 : v.getID());" << endl;
648 else
649 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", v);" << endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700650
Shih-wei Liaoc382c602010-06-21 15:04:48 -0700651 C.endFunction();
652 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700653
654 genGetExportVariable(C, TypeName, EV->getName());
655
656 return;
657}
658
659void RSReflection::genPointerTypeExportVariable(Context& C, const RSExportVar* EV) {
660 const RSExportType* ET = EV->getType();
661 const RSExportType* PointeeType;
662 std::string TypeName;
663
664 assert((ET->getClass() == RSExportType::ExportClassPointer) && "Variable should be type of pointer here");
665
666 PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType();
667 TypeName = GetTypeName(ET);
668
669 /* bind_*() */
670 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl;
671
672 C.startFunction(Context::AM_Public, false, "void", "bind_" + EV->getName(), 1, TypeName.c_str(), "v");
673
674 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl;
675 C.indent() << "if(v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl;
676
677 if(PointeeType->getClass() == RSExportType::ExportClassRecord)
678 C.indent() << "else bindAllocation(v.getAllocation(), "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl;
679 else
680 C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl;
681
682 C.endFunction();
683
684 genGetExportVariable(C, TypeName, EV->getName());
685
686 return;
687}
688
689void RSReflection::genVectorTypeExportVariable(Context& C, const RSExportVar* EV) {
690 assert((EV->getType()->getClass() == RSExportType::ExportClassVector) && "Variable should be type of vector here");
691
692 const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(EV->getType());
693 const char* TypeName = GetVectorTypeName(EVT);
694 const char* FieldPackerName = "fp";
695
696 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl;
697
698 /* set_*() */
Shih-wei Liaoc382c602010-06-21 15:04:48 -0700699 if(!EV->isConst()) {
700 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName, "v");
701 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700702
Shih-wei Liaoc382c602010-06-21 15:04:48 -0700703 if(genCreateFieldPacker(C, EVT, FieldPackerName))
704 genPackVarOfType(C, EVT, "v", FieldPackerName);
705 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " << FieldPackerName << ");" << endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700706
Shih-wei Liaoc382c602010-06-21 15:04:48 -0700707 C.endFunction();
708 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700709
710 genGetExportVariable(C, TypeName, EV->getName());
711 return;
712}
713
714void RSReflection::genRecordTypeExportVariable(Context& C, const RSExportVar* EV) {
715 assert((EV->getType()->getClass() == RSExportType::ExportClassRecord) && "Variable should be type of struct here");
716
717 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(EV->getType());
718 std::string TypeName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName() + "."RS_TYPE_ITEM_CLASS_NAME;
719 const char* FieldPackerName = "fp";
720
721 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl;
722
723 /* set_*() */
Shih-wei Liaoc382c602010-06-21 15:04:48 -0700724 if(!EV->isConst()) {
725 C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName.c_str(), "v");
726 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700727
Shih-wei Liaoc382c602010-06-21 15:04:48 -0700728 if(genCreateFieldPacker(C, ERT, FieldPackerName))
729 genPackVarOfType(C, ERT, "v", FieldPackerName);
730 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " << FieldPackerName << ");" << endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700731
Shih-wei Liaoc382c602010-06-21 15:04:48 -0700732 C.endFunction();
733 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700734
735 genGetExportVariable(C, TypeName.c_str(), EV->getName());
736 return;
737}
738
739void RSReflection::genGetExportVariable(Context& C, const std::string& TypeName, const std::string& VarName) {
740 C.startFunction(Context::AM_Public, false, TypeName.c_str(), "get_" + VarName, 0);
741
742 C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << endl;
743
744 C.endFunction();
745 return;
746}
747
748/****************************** Methods to generate script class /end ******************************/
749
750bool RSReflection::genCreateFieldPacker(Context& C, const RSExportType* ET, const char* FieldPackerName) {
751 size_t AllocSize = RSExportType::GetTypeAllocSize(ET);
752 if(AllocSize > 0)
753 C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker(" << AllocSize << ");" << endl;
754 else
755 return false;
756 return true;
757}
758
759void RSReflection::genPackVarOfType(Context& C, const RSExportType* ET, const char* VarName, const char* FieldPackerName) {
760 switch(ET->getClass()) {
761 case RSExportType::ExportClassPrimitive:
762 case RSExportType::ExportClassVector:
763 C.indent() << FieldPackerName << "." << GetPackerAPIName(static_cast<const RSExportPrimitiveType*>(ET)) << "(" << VarName << ");" << endl;
764 break;
765
766 case RSExportType::ExportClassPointer:
767 {
768 /* Must reflect as type Allocation in Java */
769 const RSExportType* PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType();
770
771 if(PointeeType->getClass() != RSExportType::ExportClassRecord)
Shih-wei Liaoc20992e2010-06-09 18:30:18 -0700772 C.indent() << FieldPackerName << ".addI32(" << VarName << ".getPtr());" << endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700773 else
Shih-wei Liaoc20992e2010-06-09 18:30:18 -0700774 C.indent() << FieldPackerName << ".addI32(" << VarName << ".getAllocation().getPtr());" << endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700775 }
776 break;
777
778 case RSExportType::ExportClassRecord:
779 {
780 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET);
781 int Pos = 0; /* relative pos from now on in field packer */
782
783 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin();
784 I != ERT->fields_end();
785 I++)
786 {
787 const RSExportRecordType::Field* F = *I;
788 std::string FieldName;
789 size_t FieldOffset = F->getOffsetInParent();
790 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
791 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
792
793 if(VarName != NULL)
794 FieldName = VarName + ("." + F->getName());
795 else
796 FieldName = F->getName();
797
798 if(FieldOffset > Pos)
799 C.indent() << FieldPackerName << ".skip(" << (FieldOffset - Pos) << ");" << endl;
800
801 genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName);
802
803 if(FieldAllocSize > FieldStoreSize) /* there's padding in the field type */
804 C.indent() << FieldPackerName << ".skip(" << (FieldAllocSize - FieldStoreSize) << ");" << endl;
805
806 Pos = FieldOffset + FieldAllocSize;
807 }
808
809 /* There maybe some padding after the struct */
810 size_t Padding = RSExportType::GetTypeAllocSize(ERT) - Pos;
811 if(Padding > 0)
812 C.indent() << FieldPackerName << ".skip(" << Padding << ");" << endl;
813 }
814 break;
815
816 default:
817 assert(false && "Unknown class of type");
818 break;
819 }
820
821 return;
822}
823
824/****************************** Methods to generate type class ******************************/
825bool RSReflection::genTypeClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg) {
826 std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName();
827
Shih-wei Liao6de89272010-07-15 15:26:20 -0700828 /* Open the file */
829 if(!C.mUseStdout) {
830 C.mOF.clear();
831 C.mOF.open(( mRSContext->getReflectJavaPathName() + "/" + ClassName + ".java" ).c_str());
832 if(!C.mOF.good()) {
833 ErrorMsg = "failed to open file '" + mRSContext->getReflectJavaPathName() + "/" + ClassName + ".java' for write";
834 return false;
835 }
836 }
837
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -0700838 if(!C.startClass(Context::AM_Public, false, ClassName, RS_TYPE_CLASS_SUPER_CLASS_NAME, ErrorMsg))
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700839 return false;
840
841 if(!genTypeItemClass(C, ERT, ErrorMsg))
842 return false;
843
844 /* Declare item buffer and item buffer packer */
845 C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[];" << endl;
846 C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";" << endl;
847
848 genTypeClassConstructor(C, ERT);
849 genTypeClassCopyToArray(C, ERT);
850 genTypeClasSet(C, ERT);
851 genTypeClasCopyAll(C, ERT);
852
853 C.endClass();
854
855 return true;
856}
857
858bool RSReflection::genTypeItemClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg) {
859 C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME;
860 C.startBlock();
861
862 C.indent() << "public static final int sizeof = " << RSExportType::GetTypeAllocSize(ERT) << ";" << endl;
863
864 /* Member elements */
865 C.out() << endl;
866 for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin();
867 FI != ERT->fields_end();
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -0700868 FI++)
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700869 C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName() << ";" << endl;
870
871 /* Constructor */
872 C.out() << endl;
873 C.indent() << RS_TYPE_ITEM_CLASS_NAME"()";
874 C.startBlock();
875
876 for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin();
877 FI != ERT->fields_end();
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -0700878 FI++)
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700879 {
880 const RSExportRecordType::Field* F = *FI;
881 if((F->getType()->getClass() == RSExportType::ExportClassVector) || (F->getType()->getClass() == RSExportType::ExportClassRecord))
882 C.indent() << F->getName() << " = new " << GetTypeName(F->getType()) << "();" << endl;
883 }
884
885 C.endBlock(); /* end Constructor */
886
887 C.endBlock(); /* end Item class */
888
889
890 return true;
891}
892
893void RSReflection::genTypeClassConstructor(Context& C, const RSExportRecordType* ERT) {
894 const char* RenderScriptVar = "rs";
895
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700896 C.startFunction(Context::AM_Public, true, "Element", "createElement", 1, "RenderScript", RenderScriptVar);
897 genBuildElement(C, ERT, RenderScriptVar);
898 C.endFunction();
899
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700900 C.startFunction(Context::AM_Public, false, NULL, C.getClassName(), 2, "RenderScript", RenderScriptVar,
901 "int", "count");
902
903 C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << endl;
904 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << endl;
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700905 C.indent() << "mElement = createElement(" << RenderScriptVar << ");" << endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700906 /* Call init() in super class */
907 C.indent() << "init(" << RenderScriptVar << ", count);" << endl;
908 C.endFunction();
909
910 return;
911}
912
913void RSReflection::genTypeClassCopyToArray(Context& C, const RSExportRecordType* ERT) {
914 C.startFunction(Context::AM_Private, false, "void", "copyToArray", 2, RS_TYPE_ITEM_CLASS_NAME, "i",
915 "int", "index");
916
917 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_PACKER_NAME" == null) "RS_TYPE_ITEM_BUFFER_PACKER_NAME" = new FieldPacker("RS_TYPE_ITEM_CLASS_NAME".sizeof * mType.getX() /* count */);" << endl;
918 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);" << endl;
919
920 genPackVarOfType(C, ERT, "i", RS_TYPE_ITEM_BUFFER_PACKER_NAME);
921
922 C.endFunction();
923 return;
924}
925
926void RSReflection::genTypeClasSet(Context& C, const RSExportRecordType* ERT) {
927 C.startFunction(Context::AM_Public, false, "void", "set", 3, RS_TYPE_ITEM_CLASS_NAME, "i",
928 "int", "index",
929 "boolean", "copyNow");
930 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) "RS_TYPE_ITEM_BUFFER_NAME" = new "RS_TYPE_ITEM_CLASS_NAME"[mType.getX() /* count */];" << endl;
931 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << endl;
932
933 C.indent() << "if (copyNow) ";
934 C.startBlock();
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -0700935
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700936 C.indent() << "copyToArray(i, index);" << endl;
Shih-wei Liao9e98e002010-06-18 15:14:58 -0700937 //C.indent() << "mAllocation.subData1D(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof, "RS_TYPE_ITEM_CLASS_NAME".sizeof, "RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << endl;
938 C.indent() << "mAllocation.subData1D(index, 1, "RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700939
940 C.endBlock(); /* end if (copyNow) */
941
942 C.endFunction();
943 return;
944}
945
946void RSReflection::genTypeClasCopyAll(Context& C, const RSExportRecordType* ERT) {
947 C.startFunction(Context::AM_Public, false, "void", "copyAll", 0);
948
949 C.indent() << "for (int ct=0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++) copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);" << endl;
950 C.indent() << "mAllocation.data("RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << endl;
951
952 C.endFunction();
953 return;
954}
955
956/****************************** Methods to generate type class /end ******************************/
957
958/******************** Methods to create Element in Java of given record type ********************/
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700959void RSReflection::genBuildElement(Context& C, const RSExportRecordType* ERT, const char* RenderScriptVar) {
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700960 const char* ElementBuilderName = "eb";
961
962 /* Create element builder */
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700963 // C.startBlock(true);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700964
965 C.indent() << "Element.Builder " << ElementBuilderName << " = new Element.Builder(" << RenderScriptVar << ");" << endl;
966
967 /* eb.add(...) */
968 genAddElementToElementBuilder(C, ERT, "", ElementBuilderName, RenderScriptVar);
969
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700970 C.indent() << "return " << ElementBuilderName << ".create();" << endl;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700971
Shih-wei Liao9e86e192010-06-18 20:42:28 -0700972 // C.endBlock();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700973 return;
974}
975
976#define EB_ADD(x, ...) \
Shih-wei Liaob1a28e72010-06-16 16:31:32 -0700977 C.indent() << ElementBuilderName << ".add(Element." << x ##__VA_ARGS__ ", \"" << VarName << "\");" << endl
978
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700979void RSReflection::genAddElementToElementBuilder(Context& C, const RSExportType* ET, const std::string& VarName, const char* ElementBuilderName, const char* RenderScriptVar) {
Shih-wei Liaob1a28e72010-06-16 16:31:32 -0700980 const char* ElementConstruct = GetBuiltinElementConstruct(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700981
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -0700982 if(ElementConstruct != NULL) {
983 EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")");
Shih-wei Liaob1a28e72010-06-16 16:31:32 -0700984 } else {
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -0700985 if((ET->getClass() == RSExportType::ExportClassPrimitive) || (ET->getClass() == RSExportType::ExportClassVector)) {
986 const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET);
987 const char* DataKindName = GetElementDataKindName(EPT->getKind());
988 const char* DataTypeName = GetElementDataTypeName(EPT->getType());
989 int Size = (ET->getClass() == RSExportType::ExportClassVector) ? static_cast<const RSExportVectorType*>(ET)->getNumElement() : 1;
990
991 switch(EPT->getKind()) {
992 case RSExportPrimitiveType::DataKindColor:
993 case RSExportPrimitiveType::DataKindPosition:
994 case RSExportPrimitiveType::DataKindTexture:
995 case RSExportPrimitiveType::DataKindNormal:
996 case RSExportPrimitiveType::DataKindPointSize:
997 /* Element.createAttrib() */
998 EB_ADD("createAttrib(" << RenderScriptVar << ", " << DataTypeName << ", " << DataKindName << ", " << Size << ")");
999 break;
1000
1001 case RSExportPrimitiveType::DataKindIndex:
1002 /* Element.createIndex() */
1003 EB_ADD("createAttrib(" << RenderScriptVar << ")");
1004 break;
1005
1006 case RSExportPrimitiveType::DataKindPixelL:
1007 case RSExportPrimitiveType::DataKindPixelA:
1008 case RSExportPrimitiveType::DataKindPixelLA:
1009 case RSExportPrimitiveType::DataKindPixelRGB:
1010 case RSExportPrimitiveType::DataKindPixelRGBA:
1011 /* Element.createPixel() */
1012 EB_ADD("createVector(" << RenderScriptVar << ", " << DataTypeName << ", " << DataKindName << ")");
1013 break;
1014
1015 case RSExportPrimitiveType::DataKindUser:
1016 default:
1017 if(EPT->getClass() == RSExportType::ExportClassPrimitive)
1018 /* Element.createUser() */
1019 EB_ADD("createUser(" << RenderScriptVar << ", " << DataTypeName << ")");
1020 else /* (ET->getClass() == RSExportType::ExportClassVector) must hold here */
1021 /* Element.createVector() */
1022 EB_ADD("createVector(" << RenderScriptVar << ", " << DataTypeName << ", " << Size << ")");
1023 break;
1024 }
1025 } else if(ET->getClass() == RSExportType::ExportClassPointer) {
1026 /* Pointer type variable should be resolved in GetBuiltinElementConstruct() */
1027 assert(false && "??");
1028 } else if(ET->getClass() == RSExportType::ExportClassRecord) {
1029 /*
1030 * Simalar to genPackVarOfType.
1031 *
1032 * TODO: Generalize these two function such that there's no duplicated codes.
1033 */
1034 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET);
1035 int Pos = 0; /* relative pos from now on */
1036
1037 for(RSExportRecordType::const_field_iterator I = ERT->fields_begin();
1038 I != ERT->fields_end();
1039 I++)
1040 {
1041 const RSExportRecordType::Field* F = *I;
1042 std::string FieldName;
1043 size_t FieldOffset = F->getOffsetInParent();
1044 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
1045 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
1046
1047 if(!VarName.empty())
1048 FieldName = VarName + "." + F->getName();
1049 else
1050 FieldName = F->getName();
1051
1052 /* alignment */
1053 genAddPaddingToElementBuiler(C, (FieldOffset - Pos), ElementBuilderName, RenderScriptVar);
1054
1055 /* eb.add(...) */
1056 genAddElementToElementBuilder(C, (*I)->getType(), FieldName, ElementBuilderName, RenderScriptVar);
1057
1058 /* there's padding within the field type */
1059 genAddPaddingToElementBuiler(C, (FieldAllocSize - FieldStoreSize), ElementBuilderName, RenderScriptVar);
1060
1061 Pos = FieldOffset + FieldAllocSize;
1062 }
1063
1064 /* There maybe some padding after the struct */
1065 genAddPaddingToElementBuiler(C, (RSExportType::GetTypeAllocSize(ERT) - Pos), ElementBuilderName, RenderScriptVar);
1066 } else {
1067 assert(false && "Unknown class of type");
1068 }
Shih-wei Liaob1a28e72010-06-16 16:31:32 -07001069 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001070}
1071
1072void RSReflection::genAddPaddingToElementBuiler(Context& C, size_t PaddingSize, const char* ElementBuilderName, const char* RenderScriptVar) {
1073 while(PaddingSize > 0) {
1074 const std::string& VarName = C.createPaddingField();
1075 if(PaddingSize >= 4) {
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -07001076 EB_ADD("U32(" << RenderScriptVar << ")");
1077 PaddingSize -= 4;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001078 } else if(PaddingSize >= 2) {
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -07001079 EB_ADD("U16(" << RenderScriptVar << ")");
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001080 PaddingSize -= 2;
1081 } else if(PaddingSize >= 1) {
Shih-wei Liaobd49c8f2010-06-17 09:51:36 -07001082 EB_ADD("U8(" << RenderScriptVar << ")");
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001083 PaddingSize -= 1;
1084 }
1085 }
1086 return;
1087}
1088
1089#undef EB_ADD
1090/******************** Methods to create Element in Java of given record type /end ********************/
1091
1092bool RSReflection::reflect(const char* OutputPackageName, const std::string& InputFileName, const std::string& OutputBCFileName) {
1093 Context *C = NULL;
1094 std::string ResourceId = "";
1095
1096 if(!GetFileNameWithoutExtension(OutputBCFileName, ResourceId))
1097 return false;
1098
1099 if(ResourceId.empty())
1100 ResourceId = "<Resource ID>";
1101
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -07001102 if((OutputPackageName == NULL) || (*OutputPackageName == '\0') || strcmp(OutputPackageName, "-") == 0)
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001103 C = new Context("<Package Name>", ResourceId, true);
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -07001104 else
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001105 C = new Context(OutputPackageName, ResourceId, false);
1106
1107 if(C != NULL) {
1108 std::string ErrorMsg, ScriptClassName;
1109 /* class ScriptC_<ScriptName> */
1110 if(!GetFileNameWithoutExtension(InputFileName, ScriptClassName))
1111 return false;
1112
1113 if(ScriptClassName.empty())
1114 ScriptClassName = "<Input Script Name>";
1115
1116 ScriptClassName.at(0) = toupper(ScriptClassName.at(0));
1117 ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX);
1118
Victor Hsiehd8a0d182010-07-07 19:22:33 +08001119 if (mRSContext->getLicenseNote() != NULL)
1120 C->setLicenseNote(*mRSContext->getLicenseNote());
1121
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001122 if(!genScriptClass(*C, ScriptClassName, ErrorMsg)) {
1123 std::cerr << "Failed to generate class " << ScriptClassName << " (" << ErrorMsg << ")" << endl;
1124 return false;
1125 }
1126
1127 /* class ScriptField_<TypeName> */
1128 for(RSContext::const_export_type_iterator TI = mRSContext->export_types_begin();
1129 TI != mRSContext->export_types_end();
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -07001130 TI++)
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001131 {
1132 const RSExportType* ET = TI->getValue();
1133
1134 if(ET->getClass() == RSExportType::ExportClassRecord) {
1135 const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET);
1136
1137 if(!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) {
1138 std::cerr << "Failed to generate type class for struct '" << ERT->getName() << "' (" << ErrorMsg << ")" << endl;
1139 return false;
1140 }
1141 }
1142 }
1143 }
1144
1145 return true;
1146}
1147
1148/****************************** RSReflection::Context ******************************/
Victor Hsiehd8a0d182010-07-07 19:22:33 +08001149const char* const RSReflection::Context::ApacheLicenseNote =
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001150 "/*\n"
1151 " * Copyright (C) 2010 The Android Open Source Project\n"
1152 " *\n"
1153 " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
1154 " * you may not use this file except in compliance with the License.\n"
1155 " * You may obtain a copy of the License at\n"
1156 " *\n"
1157 " * http://www.apache.org/licenses/LICENSE-2.0\n"
1158 " *\n"
1159 " * Unless required by applicable law or agreed to in writing, software\n"
1160 " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
1161 " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
1162 " * See the License for the specific language governing permissions and\n"
1163 " * limitations under the License.\n"
Victor Hsiehd8a0d182010-07-07 19:22:33 +08001164 " */\n"
1165 "\n";
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001166
1167const char* const RSReflection::Context::Import[] = {
1168 /* RenderScript java class */
1169 "android.renderscript.*",
1170 /* Import R */
1171 "android.content.res.Resources",
1172 /* Import for debugging */
1173 "android.util.Log",
1174};
1175
1176const char* RSReflection::Context::AccessModifierStr(AccessModifier AM) {
1177 switch(AM) {
1178 case AM_Public: return "public"; break;
1179 case AM_Protected: return "protected"; break;
1180 case AM_Private: return "private"; break;
1181 default: return ""; break;
1182 }
1183}
1184
1185bool RSReflection::Context::startClass(AccessModifier AM, bool IsStatic, const std::string& ClassName, const char* SuperClassName, std::string& ErrorMsg) {
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -07001186 if(mVerbose)
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001187 std::cout << "Generating " << ClassName << ".java ..." << endl;
1188
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001189 /* License */
Victor Hsiehd8a0d182010-07-07 19:22:33 +08001190 out() << mLicenseNote;
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001191
1192 /* Package */
1193 if(!mPackageName.empty())
1194 out() << "package " << mPackageName << ";" << endl;
1195 out() << endl;
1196
1197 /* Imports */
1198 for(int i=0;i<(sizeof(Import)/sizeof(const char*));i++)
1199 out() << "import " << Import[i] << ";" << endl;
1200 out() << endl;
1201
1202 out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class " << ClassName;
1203 if(SuperClassName != NULL)
1204 out() << " extends " << SuperClassName;
1205
1206 startBlock();
1207
1208 mClassName = ClassName;
1209
1210 return true;
1211}
1212
1213void RSReflection::Context::endClass() {
1214 endBlock();
1215 if(!mUseStdout)
1216 mOF.close();
1217 clear();
1218 return;
1219}
1220
1221void RSReflection::Context::startBlock(bool ShouldIndent) {
1222 if(ShouldIndent)
1223 indent() << "{" << endl;
1224 else
1225 out() << " {" << endl;
1226 incIndentLevel();
1227 return;
1228}
1229
1230void RSReflection::Context::endBlock() {
1231 decIndentLevel();
1232 indent() << "}" << endl << endl;
1233 return;
1234}
1235
1236void RSReflection::Context::startTypeClass(const std::string& ClassName) {
1237 indent() << "public static class " << ClassName;
1238 startBlock();
1239 return;
1240}
1241
1242void RSReflection::Context::endTypeClass() {
1243 endBlock();
1244 return;
1245}
1246
1247void RSReflection::Context::startFunction(AccessModifier AM, bool IsStatic, const char* ReturnType, const std::string& FunctionName, int Argc, ...) {
1248 ArgTy Args;
1249 va_list vl;
1250 va_start(vl, Argc);
1251
1252 for(int i=0;i<Argc;i++) {
1253 const char* ArgType = va_arg(vl, const char*);
1254 const char* ArgName = va_arg(vl, const char*);
1255
1256 Args.push_back( make_pair(ArgType, ArgName) );
1257 }
1258 va_end(vl);
1259
1260 startFunction(AM, IsStatic, ReturnType, FunctionName, Args);
1261
1262 return;
1263}
1264
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -07001265void RSReflection::Context::startFunction(AccessModifier AM,
1266 bool IsStatic,
1267 const char* ReturnType,
1268 const std::string& FunctionName,
1269 const ArgTy& Args)
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001270{
1271 indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ") << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "(";
1272
1273 bool FirstArg = true;
1274 for(ArgTy::const_iterator I = Args.begin();
1275 I != Args.end();
1276 I++)
1277 {
Shih-wei Liao2dd42ff2010-06-15 00:34:38 -07001278 if(!FirstArg)
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001279 out() << ", ";
1280 else
1281 FirstArg = false;
1282
1283 out() << I->first << " " << I->second;
1284 }
1285
1286 out() << ")";
1287 startBlock();
1288
1289 return;
1290}
1291
1292void RSReflection::Context::endFunction() {
1293 endBlock();
1294 return;
1295}
1296
1297} /* namespace slang */