slang_rs_reflection.cpp revision bd49c8ff5a35befb413de3b6d7989d257b54f057
12dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "slang_rs_context.hpp"
22dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "slang_rs_export_var.hpp"
32dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "slang_rs_reflection.hpp"
42dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "slang_rs_export_func.hpp"
52dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
62dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <ctype.h>
72dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
82dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <utility>
92dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <cstdarg>
102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersusing std::make_pair;
122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersusing std::endl;
132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#define RS_SCRIPT_CLASS_NAME_PREFIX         "ScriptC_"
162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME    "ScriptC"
17ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier
18ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier#define RS_TYPE_CLASS_NAME_PREFIX           "ScriptField_"
192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#define RS_TYPE_CLASS_SUPER_CLASS_NAME      "android.renderscript.Script.FieldBase"
202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
21ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#define RS_TYPE_ITEM_CLASS_NAME             "Item"
22ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom
232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#define RS_TYPE_ITEM_BUFFER_NAME            "mItemArray"
242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#define RS_TYPE_ITEM_BUFFER_PACKER_NAME     "mIOBuffer"
252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2604d7aa92bc5548bc4d272b9480614f06248194ccIan Rogers#define RS_EXPORT_VAR_INDEX_PREFIX          "mExportVarIdx_"
271d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#define RS_EXPORT_VAR_PREFIX                "mExportVar_"
281d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2904d7aa92bc5548bc4d272b9480614f06248194ccIan Rogers#define RS_EXPORT_FUNC_INDEX_PREFIX         "mExportFuncIdx_"
302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#define RS_EXPORT_VAR_ALLOCATION_PREFIX     "mAlloction_"
3204d7aa92bc5548bc4d272b9480614f06248194ccIan Rogers#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX   "mData_"
332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace slang {
352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers/* Some utility function using internal in RSReflection */
372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic bool GetFileNameWithoutExtension(const std::string& FileName, std::string& OutFileName) {
382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    OutFileName.clear();
392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    if(FileName.empty() || (FileName == "-"))
412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        return true;
427971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi
437971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi    /* find last component in given path */
447971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi    size_t SlashPos = FileName.find_last_of("/\\");
457971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi
467971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi    if((SlashPos != std::string::npos) && ((SlashPos + 1) < FileName.length()))
477971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        OutFileName = FileName.substr(SlashPos + 1);
487971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi    else
497971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        OutFileName = FileName;
50b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
517971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi    size_t DotPos = OutFileName.find_first_of('.');
527971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi    if(DotPos != std::string::npos)
53b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers        OutFileName.erase(DotPos);
547971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi
557971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi    return true;
567971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi}
577971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi
587971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchistatic const char* GetPrimitiveTypeName(const RSExportPrimitiveType* EPT) {
597971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi    static const char* PrimitiveTypeJavaNameMap[] = {
607971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "",
617971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "",
627971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "float",    /* RSExportPrimitiveType::DataTypeFloat32 */
637971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "double",   /* RSExportPrimitiveType::DataTypeFloat64 */
647971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "byte",     /* RSExportPrimitiveType::DataTypeSigned8 */
657971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "short",    /* RSExportPrimitiveType::DataTypeSigned16 */
667971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "int",      /* RSExportPrimitiveType::DataTypeSigned32 */
677971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "long",     /* RSExportPrimitiveType::DataTypeSigned64 */
68590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        "short",    /* RSExportPrimitiveType::DataTypeUnsigned8 */
69590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        "int",      /* RSExportPrimitiveType::DataTypeUnsigned16 */
702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        "long",     /* RSExportPrimitiveType::DataTypeUnsigned32 */
712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        "long",     /* RSExportPrimitiveType::DataTypeUnsigned64 */
72590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
73590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        "int",      /* RSExportPrimitiveType::DataTypeUnsigned565 */
742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        "int",      /* RSExportPrimitiveType::DataTypeUnsigned5551 */
752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        "int",      /* RSExportPrimitiveType::DataTypeUnsigned4444 */
767971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi
777971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "Element",  /* RSExportPrimitiveType::DataTypeRSElement */
787971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "Type",     /* RSExportPrimitiveType::DataTypeRSType */
797971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "Allocation",   /* RSExportPrimitiveType::DataTypeRSAllocation */
807971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "Sampler",  /* RSExportPrimitiveType::DataTypeRSSampler */
817971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "Script",   /* RSExportPrimitiveType::DataTypeRSScript */
827971928828f6c429b5fb3a2fddfed05c3b20bdccHiroshi Yamauchi        "SimpleMesh",       /* RSExportPrimitiveType::DataTypeRSSimpleMesh */
83590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        "ProgramFragment",  /* RSExportPrimitiveType::DataTypeRSProgramFragment */
842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        "ProgramVertex",    /* RSExportPrimitiveType::DataTypeRSProgramVertex */
85590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        "ProgramRaster",    /* RSExportPrimitiveType::DataTypeRSProgramRaster */
862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        "ProgramStore",     /* RSExportPrimitiveType::DataTypeRSProgramStore */
872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    };
88ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
89590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    if((EPT->getType() >= 0) && (EPT->getType() < (sizeof(PrimitiveTypeJavaNameMap) / sizeof(const char*))))
902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        return PrimitiveTypeJavaNameMap[ EPT->getType() ];
912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
92590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    assert(false && "GetPrimitiveTypeName : Unknown primitive data type");
932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return NULL;
942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
95590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
96590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierstatic const char* GetVectorTypeName(const RSExportVectorType* EVT) {
97590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    static const char* VectorTypeJavaNameMap[][3] = {
98590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        /* 0 */ { "Byte2",  "Byte3",    "Byte4" },
99590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        /* 1 */ { "Short2", "Short3",   "Short4" },
100590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        /* 2 */ { "Int2",   "Int3",     "Int4" },
101590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        /* 3 */ { "Long2",  "Long3",    "Long4" },
1024cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi        /* 4 */ { "Float2", "Float3",   "Float4" },
1034cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi    };
1044cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi
1054cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi    const char** BaseElement;
1064cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi
1074cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi    switch(EVT->getType()) {
1084cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi        case RSExportPrimitiveType::DataTypeSigned8:
1094cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi            BaseElement = VectorTypeJavaNameMap[0];
1104cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi        break;
1114cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi
1124cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi        case RSExportPrimitiveType::DataTypeSigned16:
1134cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi        case RSExportPrimitiveType::DataTypeUnsigned8:
1144cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi            BaseElement = VectorTypeJavaNameMap[1];
1154cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi        break;
1164cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi
1174cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi        case RSExportPrimitiveType::DataTypeSigned32:
1184cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi        case RSExportPrimitiveType::DataTypeUnsigned16:
1194cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi            BaseElement = VectorTypeJavaNameMap[2];
1204cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi        break;
1214cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi
122590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        case RSExportPrimitiveType::DataTypeUnsigned32:
123590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            BaseElement = VectorTypeJavaNameMap[3];
124590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        break;
125590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
126590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        case RSExportPrimitiveType::DataTypeFloat32:
127590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            BaseElement = VectorTypeJavaNameMap[4];
128590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        break;
129590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
1304cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi        default:
131590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            assert(false && "RSReflection::genElementTypeName : Unsupported vector element data type");
1324cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi        break;
133590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    }
1344cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi
1352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    assert((EVT->getNumElement() > 1) && (EVT->getNumElement() <= 4) && "Number of element in vector type is invalid");
1360732d59d42523b8c2d807de3a380d2fbfa781364Mathieu Chartier
1372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return BaseElement[EVT->getNumElement() - 2];
1382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1394e6a31eb97f22f4480827474b30b9e64f396eaceMathieu Chartier
140ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartierstatic const char* GetPackerAPIName(const RSExportPrimitiveType* EPT) {
1414e6a31eb97f22f4480827474b30b9e64f396eaceMathieu Chartier    static const char* PrimitiveTypePackerAPINameMap[] = {
142ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "",
143b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers        "",
144ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addF32",   /* RSExportPrimitiveType::DataTypeFloat32 */
1454e6a31eb97f22f4480827474b30b9e64f396eaceMathieu Chartier        "addF64",   /* RSExportPrimitiveType::DataTypeFloat64 */
146b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers        "addI8",    /* RSExportPrimitiveType::DataTypeSigned8 */
147ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addI16",   /* RSExportPrimitiveType::DataTypeSigned16 */
148ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addI32",   /* RSExportPrimitiveType::DataTypeSigned32 */
149ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addI64",   /* RSExportPrimitiveType::DataTypeSigned64 */
150ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addU8",    /* RSExportPrimitiveType::DataTypeUnsigned8 */
151590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        "addU16",   /* RSExportPrimitiveType::DataTypeUnsigned16 */
152ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addU32",   /* RSExportPrimitiveType::DataTypeUnsigned32 */
1534d7f61d44a732cfbc8573e5d93364983fd746888Mathieu Chartier        "addU64",   /* RSExportPrimitiveType::DataTypeUnsigned64 */
154ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier
155ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addU16",   /* RSExportPrimitiveType::DataTypeUnsigned565 */
156ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addU16",   /* RSExportPrimitiveType::DataTypeUnsigned5551 */
157ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addU16",   /* RSExportPrimitiveType::DataTypeUnsigned4444 */
158ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier
159ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addObj",   /* RSExportPrimitiveType::DataTypeRSElement */
160ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addObj",   /* RSExportPrimitiveType::DataTypeRSType */
161ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addObj",   /* RSExportPrimitiveType::DataTypeRSAllocation */
162ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addObj",   /* RSExportPrimitiveType::DataTypeRSSampler */
163ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addObj",   /* RSExportPrimitiveType::DataTypeRSScript */
164ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addObj",   /* RSExportPrimitiveType::DataTypeRSSimpleMesh */
165ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addObj",   /* RSExportPrimitiveType::DataTypeRSProgramFragment */
166ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addObj",   /* RSExportPrimitiveType::DataTypeRSProgramVertex */
167ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        "addObj",   /* RSExportPrimitiveType::DataTypeRSProgramRaster */
168590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        "addObj",   /* RSExportPrimitiveType::DataTypeRSProgramStore */
169590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    };
170590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
171590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    if((EPT->getType() >= 0) && (EPT->getType() < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char*))))
172ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        return PrimitiveTypePackerAPINameMap[ EPT->getType() ];
173ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier
174ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier    assert(false && "GetPackerAPIName : Unknown primitive data type");
175ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier    return NULL;
176ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier}
177ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier
178ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartierstatic std::string GetTypeName(const RSExportType* ET) {
179ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier    switch(ET->getClass()) {
180ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        case RSExportType::ExportClassPrimitive:
181ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier            return GetPrimitiveTypeName(static_cast<const RSExportPrimitiveType*>(ET));
182ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        break;
183590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
184590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        case RSExportType::ExportClassPointer:
185590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        {
186590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            const RSExportType* PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType();
187ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier
188ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier            if(PointeeType->getClass() != RSExportType::ExportClassRecord)
189ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier                return "Allocation";
190ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier            else
191ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier                return RS_TYPE_CLASS_NAME_PREFIX + PointeeType->getName();
192ad2541a59c00c2c69e8973088891a2b5257c9780Mathieu Chartier        }
193ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers        break;
194ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
1954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier        case RSExportType::ExportClassVector:
1964e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier            return GetVectorTypeName(static_cast<const RSExportVectorType*>(ET));
1974e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier        break;
1982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        case RSExportType::ExportClassRecord:
200ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers            return RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + "."RS_TYPE_ITEM_CLASS_NAME;
201ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom        break;
2022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        default:
2042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers            assert(false && "Unknown class of type");
205ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom        break;
2062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    }
2072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return "";
2092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic const char* GetBuiltinElementConstruct(const RSExportType* ET) {
2122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    if(ET->getClass() == RSExportType::ExportClassPrimitive) {
2132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET);
2142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        if(EPT->getKind() == RSExportPrimitiveType::DataKindUser) {
2152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers            static const char* PrimitiveBuiltinElementConstructMap[] = {
2162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                NULL,
2172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                NULL,
2182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                "F32", /* RSExportPrimitiveType::DataTypeFloat32 */
219ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                NULL,       /* RSExportPrimitiveType::DataTypeFloat64 */
2202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                "I8",  /* RSExportPrimitiveType::DataTypeSigned8 */
2212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                NULL,       /* RSExportPrimitiveType::DataTypeSigned16 */
2222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                "I32", /* RSExportPrimitiveType::DataTypeSigned32 */
223ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                NULL,       /* RSExportPrimitiveType::DataTypeSigned64 */
2242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                "U8",  /* RSExportPrimitiveType::DataTypeUnsigned8 */
2252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                NULL,       /* RSExportPrimitiveType::DataTypeUnsigned16 */
2262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                "U32", /* RSExportPrimitiveType::DataTypeUnsigned32 */
2272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                NULL,       /* RSExportPrimitiveType::DataTypeUnsigned64 */
2282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                NULL,   /* RSExportPrimitiveType::DataTypeUnsigned565 */
2302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                NULL,   /* RSExportPrimitiveType::DataTypeUnsigned5551 */
2312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                NULL,   /* RSExportPrimitiveType::DataTypeUnsigned4444 */
2322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                "ELEMENT", /* RSExportPrimitiveType::DataTypeRSElement */
2342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                "TYPE",    /* RSExportPrimitiveType::DataTypeRSType */
2352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                "ALLOCATION",  /* RSExportPrimitiveType::DataTypeRSAllocation */
2362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                "SAMPLER",     /* RSExportPrimitiveType::DataTypeRSSampler */
2372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                "SCRIPT",      /* RSExportPrimitiveType::DataTypeRSScript */
238                "MESH",        /* RSExportPrimitiveType::DataTypeRSSimpleMesh */
239                "PROGRAM_FRAGMENT",    /* RSExportPrimitiveType::DataTypeRSProgramFragment */
240                "PROGRAM_VERTEX",      /* RSExportPrimitiveType::DataTypeRSProgramVertex */
241                "PROGRAM_RASTER",      /* RSExportPrimitiveType::DataTypeRSProgramRaster */
242                "PROGRAM_STORE",       /* RSExportPrimitiveType::DataTypeRSProgramStore */
243            };
244
245            if((EPT->getType() >= 0) && (EPT->getType() < (sizeof(PrimitiveBuiltinElementConstructMap) / sizeof(const char*))))
246                return PrimitiveBuiltinElementConstructMap[ EPT->getType() ];
247        } else if(EPT->getKind() == RSExportPrimitiveType::DataKindPixelA) {
248            if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
249                return "A_8";
250        } else if(EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGB) {
251            if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned565)
252                return "RGB_565";
253            else if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
254                return "RGB_888";
255        } else if(EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGBA) {
256            if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned5551)
257                return "RGB_5551";
258            else if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned4444)
259                return "RGB_4444";
260            else if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
261                return "RGB_8888";
262        } else if(EPT->getKind() == RSExportPrimitiveType::DataKindIndex) {
263            if(EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned16)
264                return "INDEX_16";
265        }
266    } else if(ET->getClass() == RSExportType::ExportClassVector) {
267        const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(ET);
268        if(EVT->getKind() == RSExportPrimitiveType::DataKindPosition) {
269            if(EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
270                if(EVT->getNumElement() == 2)
271                    return "ATTRIB_POSITION_2";
272                else if(EVT->getNumElement() == 3)
273                    return "ATTRIB_POSITION_3";
274            }
275        } else if(EVT->getKind() == RSExportPrimitiveType::DataKindTexture) {
276            if(EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
277                if(EVT->getNumElement() == 2)
278                    return "ATTRIB_TEXTURE_2";
279            }
280        } else if(EVT->getKind() == RSExportPrimitiveType::DataKindNormal) {
281            if(EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
282                if(EVT->getNumElement() == 3)
283                    return "ATTRIB_NORMAL_3";
284            }
285        } else if(EVT->getKind() == RSExportPrimitiveType::DataKindColor) {
286            if(EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
287                if(EVT->getNumElement() == 4)
288                    return "ATTRIB_COLOR_F32_4";
289            } else if(EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) {
290                if(EVT->getNumElement() == 4)
291                    return "ATTRIB_COLOR_U8_4";
292            }
293        }
294    } else if(ET->getClass() == RSExportType::ExportClassPointer) {
295        return "USER_I32";  /* tread pointer type variable as unsigned int (TODO: this is target dependent) */
296    }
297
298    return NULL;
299}
300
301static const char* GetElementDataKindName(RSExportPrimitiveType::DataKind DK) {
302    static const char* ElementDataKindNameMap[] = {
303        "Element.DataKind.USER",        /* RSExportPrimitiveType::DataKindUser */
304        "Element.DataKind.COLOR",       /* RSExportPrimitiveType::DataKindColor */
305        "Element.DataKind.POSITION",    /* RSExportPrimitiveType::DataKindPosition */
306        "Element.DataKind.TEXTURE",     /* RSExportPrimitiveType::DataKindTexture */
307        "Element.DataKind.NORMAL",      /* RSExportPrimitiveType::DataKindNormal */
308        "Element.DataKind.INDEX",       /* RSExportPrimitiveType::DataKindIndex */
309        "Element.DataKind.POINT_SIZE",  /* RSExportPrimitiveType::DataKindPointSize */
310        "Element.DataKind.PIXEL_L",     /* RSExportPrimitiveType::DataKindPixelL */
311        "Element.DataKind.PIXEL_A",     /* RSExportPrimitiveType::DataKindPixelA */
312        "Element.DataKind.PIXEL_LA",    /* RSExportPrimitiveType::DataKindPixelLA */
313        "Element.DataKind.PIXEL_RGB",   /* RSExportPrimitiveType::DataKindPixelRGB */
314        "Element.DataKind.PIXEL_RGBA",  /* RSExportPrimitiveType::DataKindPixelRGBA */
315    };
316
317    if((DK >= 0) && (DK < (sizeof(ElementDataKindNameMap) / sizeof(const char*))))
318        return ElementDataKindNameMap[ DK ];
319    else
320        return NULL;
321}
322
323static const char* GetElementDataTypeName(RSExportPrimitiveType::DataType DT) {
324    static const char* ElementDataTypeNameMap[] = {
325        NULL,
326        NULL,
327        "Element.DataType.FLOAT_32",    /* RSExportPrimitiveType::DataTypeFloat32 */
328        NULL,                           /* RSExportPrimitiveType::DataTypeFloat64 */
329        "Element.DataType.SIGNED_8",    /* RSExportPrimitiveType::DataTypeSigned8 */
330        "Element.DataType.SIGNED_16",   /* RSExportPrimitiveType::DataTypeSigned16 */
331        "Element.DataType.SIGNED_32",   /* RSExportPrimitiveType::DataTypeSigned32 */
332        NULL,                           /* RSExportPrimitiveType::DataTypeSigned64 */
333        "Element.DataType.UNSIGNED_8",  /* RSExportPrimitiveType::DataTypeUnsigned8 */
334        "Element.DataType.UNSIGNED_16", /* RSExportPrimitiveType::DataTypeUnsigned16 */
335        "Element.DataType.UNSIGNED_32", /* RSExportPrimitiveType::DataTypeUnsigned32 */
336        NULL,                           /* RSExportPrimitiveType::DataTypeUnsigned64 */
337
338        "Element.DataType.UNSIGNED_5_6_5",   /* RSExportPrimitiveType::DataTypeUnsigned565 */
339        "Element.DataType.UNSIGNED_5_5_5_1", /* RSExportPrimitiveType::DataTypeUnsigned5551 */
340        "Element.DataType.UNSIGNED_4_4_4_4", /* RSExportPrimitiveType::DataTypeUnsigned4444 */
341
342        "Element.DataType.RS_ELEMENT",  /* RSExportPrimitiveType::DataTypeRSElement */
343        "Element.DataType.RS_TYPE",     /* RSExportPrimitiveType::DataTypeRSType */
344        "Element.DataType.RS_ALLOCATION",   /* RSExportPrimitiveType::DataTypeRSAllocation */
345        "Element.DataType.RS_SAMPLER",      /* RSExportPrimitiveType::DataTypeRSSampler */
346        "Element.DataType.RS_SCRIPT",       /* RSExportPrimitiveType::DataTypeRSScript */
347        "Element.DataType.RS_MESH",         /* RSExportPrimitiveType::DataTypeRSSimpleMesh */
348        "Element.DataType.RS_PROGRAM_FRAGMENT", /* RSExportPrimitiveType::DataTypeRSProgramFragment */
349        "Element.DataType.RS_PROGRAM_VERTEX",   /* RSExportPrimitiveType::DataTypeRSProgramVertex */
350        "Element.DataType.RS_PROGRAM_RASTER",   /* RSExportPrimitiveType::DataTypeRSProgramRaster */
351        "Element.DataType.RS_PROGRAM_STORE",    /* RSExportPrimitiveType::DataTypeRSProgramStore */
352    };
353
354    if((DT >= 0) && (DT < (sizeof(ElementDataTypeNameMap) / sizeof(const char*))))
355        return ElementDataTypeNameMap[ DT ];
356    else
357        return NULL;
358}
359
360/****************************** Methods to generate script class ******************************/
361bool RSReflection::genScriptClass(Context& C, const std::string& ClassName, std::string& ErrorMsg) {
362    if(!C.startClass(Context::AM_Public, false, ClassName, RS_SCRIPT_CLASS_SUPER_CLASS_NAME, ErrorMsg))
363        return false;
364
365    genScriptClassConstructor(C);
366
367    /* Reflect export variable */
368    for(RSContext::const_export_var_iterator I = mRSContext->export_vars_begin();
369        I != mRSContext->export_vars_end();
370        I++)
371        genExportVariable(C, *I);
372
373    /* Reflect export function */
374    for(RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin();
375        I != mRSContext->export_funcs_end();
376        I++)
377        genExportFunction(C, *I);
378
379    C.endClass();
380
381    return true;
382}
383
384void RSReflection::genScriptClassConstructor(Context& C) {
385    C.indent() << "// Constructor" << endl;
386    C.startFunction(Context::AM_Public, false, NULL, C.getClassName(), 4, "RenderScript", "rs",
387                                                                          "Resources", "resources",
388                                                                          "int", "id",
389                                                                          "boolean", "isRoot");
390    /* Call constructor of super class */
391    C.indent() << "super(rs, resources, id, isRoot);" << endl;
392    C.endFunction();
393    return;
394}
395
396void RSReflection::genExportVariable(Context& C, const RSExportVar* EV) {
397    const RSExportType* ET = EV->getType();
398
399    C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << " = " << C.getNextExportVarSlot() << ";" << endl;
400
401    switch(ET->getClass()) {
402        case RSExportType::ExportClassPrimitive:
403            genPrimitiveTypeExportVariable(C, EV);
404        break;
405
406        case RSExportType::ExportClassPointer:
407            genPointerTypeExportVariable(C, EV);
408        break;
409
410        case RSExportType::ExportClassVector:
411            genVectorTypeExportVariable(C, EV);
412        break;
413
414        case RSExportType::ExportClassRecord:
415            genRecordTypeExportVariable(C, EV);
416        break;
417
418        default:
419            assert(false && "Unknown class of type");
420        break;
421    }
422
423    return;
424}
425
426void RSReflection::genExportFunction(Context& C, const RSExportFunc* EF) {
427    C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << " = " << C.getNextExportFuncSlot() << ";" << endl;
428
429    /* invoke_*() */
430    Context::ArgTy Args;
431
432    for(RSExportFunc::const_param_iterator I = EF->params_begin();
433        I != EF->params_end();
434        I++)
435    {
436        const RSExportFunc::Parameter* P = *I;
437        Args.push_back( make_pair(GetTypeName(P->getType()), P->getName()) );
438    }
439
440    C.startFunction(Context::AM_Public, false, "void", "invoke_" + EF->getName(), Args);
441
442    if(!EF->hasParam()) {
443        C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");" << endl;
444    } else {
445        const RSExportRecordType* ERT = EF->getParamPacketType();
446        std::string FieldPackerName = EF->getName() + "_fp";
447
448        if(genCreateFieldPacker(C, ERT, FieldPackerName.c_str()))
449            genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str());
450
451        C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", " << FieldPackerName << ");" << endl;
452    }
453
454    C.endFunction();
455    return;
456}
457
458void RSReflection::genPrimitiveTypeExportVariable(Context& C, const RSExportVar* EV) {
459    assert((EV->getType()->getClass() == RSExportType::ExportClassPrimitive) && "Variable should be type of primitive here");
460
461    const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(EV->getType());
462    const char* TypeName = GetPrimitiveTypeName(EPT);
463
464    C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl;
465
466    /* set_*() */
467    C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName, "v");
468    C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl;
469
470    if(EPT->isRSObjectType())
471        C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", (v == null) ? 0 : v.getID());" << endl;
472    else
473        C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", v);" << endl;
474
475    C.endFunction();
476
477    genGetExportVariable(C, TypeName, EV->getName());
478
479    return;
480}
481
482void RSReflection::genPointerTypeExportVariable(Context& C, const RSExportVar* EV) {
483    const RSExportType* ET = EV->getType();
484    const RSExportType* PointeeType;
485    std::string TypeName;
486
487    assert((ET->getClass() == RSExportType::ExportClassPointer) && "Variable should be type of pointer here");
488
489    PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType();
490    TypeName = GetTypeName(ET);
491
492    /* bind_*() */
493    C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl;
494
495    C.startFunction(Context::AM_Public, false, "void", "bind_" + EV->getName(), 1, TypeName.c_str(), "v");
496
497    C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl;
498    C.indent() << "if(v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl;
499
500    if(PointeeType->getClass() == RSExportType::ExportClassRecord)
501        C.indent() << "else bindAllocation(v.getAllocation(), "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl;
502    else
503        C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" << endl;
504
505    C.endFunction();
506
507    genGetExportVariable(C, TypeName, EV->getName());
508
509    return;
510}
511
512void RSReflection::genVectorTypeExportVariable(Context& C, const RSExportVar* EV) {
513    assert((EV->getType()->getClass() == RSExportType::ExportClassVector) && "Variable should be type of vector here");
514
515    const RSExportVectorType* EVT = static_cast<const RSExportVectorType*>(EV->getType());
516    const char* TypeName = GetVectorTypeName(EVT);
517    const char* FieldPackerName = "fp";
518
519    C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl;
520
521    /* set_*() */
522    C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName, "v");
523    C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl;
524
525    if(genCreateFieldPacker(C, EVT, FieldPackerName))
526        genPackVarOfType(C, EVT, "v", FieldPackerName);
527    C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " << FieldPackerName << ");" << endl;
528
529    C.endFunction();
530
531    genGetExportVariable(C, TypeName, EV->getName());
532    return;
533}
534
535void RSReflection::genRecordTypeExportVariable(Context& C, const RSExportVar* EV) {
536    assert((EV->getType()->getClass() == RSExportType::ExportClassRecord) && "Variable should be type of struct here");
537
538    const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(EV->getType());
539    std::string TypeName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName() + "."RS_TYPE_ITEM_CLASS_NAME;
540    const char* FieldPackerName = "fp";
541
542    C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX << EV->getName() << ";" << endl;
543
544    /* set_*() */
545    C.startFunction(Context::AM_Public, false, "void", "set_" + EV->getName(), 1, TypeName.c_str(), "v");
546    C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << endl;
547
548    if(genCreateFieldPacker(C, ERT, FieldPackerName))
549        genPackVarOfType(C, ERT, "v", FieldPackerName);
550    C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " << FieldPackerName << ");" << endl;
551
552    C.endFunction();
553
554    genGetExportVariable(C, TypeName.c_str(), EV->getName());
555    return;
556}
557
558void RSReflection::genGetExportVariable(Context& C, const std::string& TypeName, const std::string& VarName) {
559    C.startFunction(Context::AM_Public, false, TypeName.c_str(), "get_" + VarName, 0);
560
561    C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << endl;
562
563    C.endFunction();
564    return;
565}
566
567/****************************** Methods to generate script class /end ******************************/
568
569bool RSReflection::genCreateFieldPacker(Context& C, const RSExportType* ET, const char* FieldPackerName) {
570    size_t AllocSize = RSExportType::GetTypeAllocSize(ET);
571    if(AllocSize > 0)
572        C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker(" << AllocSize << ");" << endl;
573    else
574        return false;
575    return true;
576}
577
578void RSReflection::genPackVarOfType(Context& C, const RSExportType* ET, const char* VarName, const char* FieldPackerName) {
579    switch(ET->getClass()) {
580        case RSExportType::ExportClassPrimitive:
581        case RSExportType::ExportClassVector:
582            C.indent() << FieldPackerName << "." << GetPackerAPIName(static_cast<const RSExportPrimitiveType*>(ET)) << "(" << VarName << ");" << endl;
583        break;
584
585        case RSExportType::ExportClassPointer:
586        {
587            /* Must reflect as type Allocation in Java */
588            const RSExportType* PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType();
589
590            if(PointeeType->getClass() != RSExportType::ExportClassRecord)
591                C.indent() << FieldPackerName << ".addI32(" << VarName << ".getPtr());" << endl;
592            else
593                C.indent() << FieldPackerName << ".addI32(" << VarName << ".getAllocation().getPtr());" << endl;
594        }
595        break;
596
597        case RSExportType::ExportClassRecord:
598        {
599            const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET);
600            int Pos = 0;    /* relative pos from now on in field packer */
601
602            for(RSExportRecordType::const_field_iterator I = ERT->fields_begin();
603                I != ERT->fields_end();
604                I++)
605            {
606                const RSExportRecordType::Field* F = *I;
607                std::string FieldName;
608                size_t FieldOffset = F->getOffsetInParent();
609                size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
610                size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
611
612                if(VarName != NULL)
613                    FieldName = VarName + ("." + F->getName());
614                else
615                    FieldName = F->getName();
616
617                if(FieldOffset > Pos)
618                    C.indent() << FieldPackerName << ".skip(" << (FieldOffset - Pos) << ");" << endl;
619
620                genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName);
621
622                if(FieldAllocSize > FieldStoreSize)  /* there's padding in the field type */
623                    C.indent() << FieldPackerName << ".skip(" << (FieldAllocSize - FieldStoreSize) << ");" << endl;
624
625                Pos = FieldOffset + FieldAllocSize;
626            }
627
628            /* There maybe some padding after the struct */
629            size_t Padding = RSExportType::GetTypeAllocSize(ERT) - Pos;
630            if(Padding > 0)
631                C.indent() << FieldPackerName << ".skip(" << Padding << ");" << endl;
632        }
633        break;
634
635        default:
636            assert(false && "Unknown class of type");
637        break;
638    }
639
640    return;
641}
642
643/****************************** Methods to generate type class  ******************************/
644bool RSReflection::genTypeClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg) {
645    std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName();
646
647    if(!C.startClass(Context::AM_Public, false, ClassName, RS_TYPE_CLASS_SUPER_CLASS_NAME, ErrorMsg))
648        return false;
649
650    if(!genTypeItemClass(C, ERT, ErrorMsg))
651        return false;
652
653    /* Declare item buffer and item buffer packer */
654    C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[];" << endl;
655    C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";" << endl;
656
657    genTypeClassConstructor(C, ERT);
658    genTypeClassCopyToArray(C, ERT);
659    genTypeClasSet(C, ERT);
660    genTypeClasCopyAll(C, ERT);
661
662    C.endClass();
663
664    return true;
665}
666
667bool RSReflection::genTypeItemClass(Context& C, const RSExportRecordType* ERT, std::string& ErrorMsg) {
668    C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME;
669    C.startBlock();
670
671    C.indent() << "public static final int sizeof = " << RSExportType::GetTypeAllocSize(ERT) << ";" << endl;
672
673    /* Member elements */
674    C.out() << endl;
675    for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin();
676        FI != ERT->fields_end();
677        FI++)
678        C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName() << ";" << endl;
679
680    /* Constructor */
681    C.out() << endl;
682    C.indent() << RS_TYPE_ITEM_CLASS_NAME"()";
683    C.startBlock();
684
685    for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin();
686        FI != ERT->fields_end();
687        FI++)
688    {
689        const RSExportRecordType::Field* F = *FI;
690        if((F->getType()->getClass() == RSExportType::ExportClassVector) || (F->getType()->getClass() == RSExportType::ExportClassRecord))
691        C.indent() << F->getName() << " = new " << GetTypeName(F->getType()) << "();" << endl;
692    }
693
694    C.endBlock();   /* end Constructor */
695
696    C.endBlock();   /* end Item class */
697
698
699    return true;
700}
701
702void RSReflection::genTypeClassConstructor(Context& C, const RSExportRecordType* ERT) {
703    const char* RenderScriptVar = "rs";
704
705    C.startFunction(Context::AM_Public, false, NULL, C.getClassName(), 2, "RenderScript", RenderScriptVar,
706                                                                          "int", "count");
707
708    C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << endl;
709    C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << endl;
710
711    genBuildElement(C, ERT, "mElement", RenderScriptVar);
712    /* Call init() in super class */
713    C.indent() << "init(" << RenderScriptVar << ", count);" << endl;
714    C.endFunction();
715
716    return;
717}
718
719void RSReflection::genTypeClassCopyToArray(Context& C, const RSExportRecordType* ERT) {
720    C.startFunction(Context::AM_Private, false, "void", "copyToArray", 2, RS_TYPE_ITEM_CLASS_NAME, "i",
721                                                                          "int", "index");
722
723    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;
724    C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);" << endl;
725
726    genPackVarOfType(C, ERT, "i", RS_TYPE_ITEM_BUFFER_PACKER_NAME);
727
728    C.endFunction();
729    return;
730}
731
732void RSReflection::genTypeClasSet(Context& C, const RSExportRecordType* ERT) {
733    C.startFunction(Context::AM_Public, false, "void", "set", 3, RS_TYPE_ITEM_CLASS_NAME, "i",
734                                                                 "int", "index",
735                                                                 "boolean", "copyNow");
736    C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) "RS_TYPE_ITEM_BUFFER_NAME" = new "RS_TYPE_ITEM_CLASS_NAME"[mType.getX() /* count */];" << endl;
737    C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << endl;
738
739    C.indent() << "if (copyNow) ";
740    C.startBlock();
741
742    C.indent() << "copyToArray(i, index);" << endl;
743    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;
744
745    C.endBlock();   /* end if (copyNow) */
746
747    C.endFunction();
748    return;
749}
750
751void RSReflection::genTypeClasCopyAll(Context& C, const RSExportRecordType* ERT) {
752    C.startFunction(Context::AM_Public, false, "void", "copyAll", 0);
753
754    C.indent() << "for (int ct=0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++) copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);" << endl;
755    C.indent() << "mAllocation.data("RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << endl;
756
757    C.endFunction();
758    return;
759}
760
761/****************************** Methods to generate type class /end ******************************/
762
763/******************** Methods to create Element in Java of given record type ********************/
764void RSReflection::genBuildElement(Context& C, const RSExportRecordType* ERT, const char* ElementName, const char* RenderScriptVar) {
765    const char* ElementBuilderName = "eb";
766
767    /* Create element builder */
768    C.startBlock(true);
769
770    C.indent() << "Element.Builder " << ElementBuilderName << " = new Element.Builder(" << RenderScriptVar << ");" << endl;
771
772    /* eb.add(...) */
773    genAddElementToElementBuilder(C, ERT, "", ElementBuilderName, RenderScriptVar);
774
775    C.indent() << ElementName << " = " << ElementBuilderName << ".create();" << endl;
776
777    C.endBlock();
778    return;
779}
780
781#define EB_ADD(x, ...)  \
782    C.indent() << ElementBuilderName << ".add(Element." << x ##__VA_ARGS__ ", \"" << VarName << "\");" << endl
783
784void RSReflection::genAddElementToElementBuilder(Context& C, const RSExportType* ET, const std::string& VarName, const char* ElementBuilderName, const char* RenderScriptVar) {
785    const char* ElementConstruct = GetBuiltinElementConstruct(ET);
786
787    if(ElementConstruct != NULL) {
788      EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")");
789    } else {
790      if((ET->getClass() == RSExportType::ExportClassPrimitive) || (ET->getClass() == RSExportType::ExportClassVector)) {
791        const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(ET);
792        const char* DataKindName = GetElementDataKindName(EPT->getKind());
793        const char* DataTypeName = GetElementDataTypeName(EPT->getType());
794        int Size = (ET->getClass() == RSExportType::ExportClassVector) ? static_cast<const RSExportVectorType*>(ET)->getNumElement() : 1;
795
796        switch(EPT->getKind()) {
797          case RSExportPrimitiveType::DataKindColor:
798          case RSExportPrimitiveType::DataKindPosition:
799          case RSExportPrimitiveType::DataKindTexture:
800          case RSExportPrimitiveType::DataKindNormal:
801          case RSExportPrimitiveType::DataKindPointSize:
802            /* Element.createAttrib() */
803            EB_ADD("createAttrib(" << RenderScriptVar << ", " << DataTypeName << ", " << DataKindName << ", " << Size << ")");
804            break;
805
806          case RSExportPrimitiveType::DataKindIndex:
807            /* Element.createIndex() */
808            EB_ADD("createAttrib(" << RenderScriptVar << ")");
809            break;
810
811          case RSExportPrimitiveType::DataKindPixelL:
812          case RSExportPrimitiveType::DataKindPixelA:
813          case RSExportPrimitiveType::DataKindPixelLA:
814          case RSExportPrimitiveType::DataKindPixelRGB:
815          case RSExportPrimitiveType::DataKindPixelRGBA:
816            /* Element.createPixel() */
817            EB_ADD("createVector(" << RenderScriptVar << ", " << DataTypeName << ", " << DataKindName << ")");
818            break;
819
820          case RSExportPrimitiveType::DataKindUser:
821          default:
822            if(EPT->getClass() == RSExportType::ExportClassPrimitive)
823              /* Element.createUser() */
824              EB_ADD("createUser(" << RenderScriptVar << ", " << DataTypeName << ")");
825            else /* (ET->getClass() == RSExportType::ExportClassVector) must hold here */
826              /* Element.createVector() */
827              EB_ADD("createVector(" << RenderScriptVar << ", " << DataTypeName << ", " << Size << ")");
828            break;
829        }
830      } else if(ET->getClass() == RSExportType::ExportClassPointer) {
831        /* Pointer type variable should be resolved in GetBuiltinElementConstruct()  */
832        assert(false && "??");
833      } else if(ET->getClass() == RSExportType::ExportClassRecord) {
834        /*
835         * Simalar to genPackVarOfType.
836         *
837         * TODO: Generalize these two function such that there's no duplicated codes.
838         */
839        const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET);
840        int Pos = 0;    /* relative pos from now on */
841
842        for(RSExportRecordType::const_field_iterator I = ERT->fields_begin();
843            I != ERT->fields_end();
844            I++)
845        {
846          const RSExportRecordType::Field* F = *I;
847          std::string FieldName;
848          size_t FieldOffset = F->getOffsetInParent();
849          size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType());
850          size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType());
851
852          if(!VarName.empty())
853            FieldName = VarName + "." + F->getName();
854          else
855            FieldName = F->getName();
856
857          /* alignment */
858          genAddPaddingToElementBuiler(C, (FieldOffset - Pos), ElementBuilderName, RenderScriptVar);
859
860          /* eb.add(...) */
861          genAddElementToElementBuilder(C, (*I)->getType(), FieldName, ElementBuilderName, RenderScriptVar);
862
863          /* there's padding within the field type */
864          genAddPaddingToElementBuiler(C, (FieldAllocSize - FieldStoreSize), ElementBuilderName, RenderScriptVar);
865
866          Pos = FieldOffset + FieldAllocSize;
867        }
868
869        /* There maybe some padding after the struct */
870        genAddPaddingToElementBuiler(C, (RSExportType::GetTypeAllocSize(ERT) - Pos), ElementBuilderName, RenderScriptVar);
871      } else {
872        assert(false && "Unknown class of type");
873      }
874    }
875}
876
877void RSReflection::genAddPaddingToElementBuiler(Context& C, size_t PaddingSize, const char* ElementBuilderName, const char* RenderScriptVar) {
878    while(PaddingSize > 0) {
879        const std::string& VarName = C.createPaddingField();
880        if(PaddingSize >= 4) {
881          EB_ADD("U32(" << RenderScriptVar << ")");
882          PaddingSize -= 4;
883        } else if(PaddingSize >= 2) {
884            EB_ADD("U16(" << RenderScriptVar << ")");
885            PaddingSize -= 2;
886        } else if(PaddingSize >= 1) {
887            EB_ADD("U8(" << RenderScriptVar << ")");
888            PaddingSize -= 1;
889        }
890    }
891    return;
892}
893
894#undef EB_ADD
895/******************** Methods to create Element in Java of given record type /end ********************/
896
897bool RSReflection::reflect(const char* OutputPackageName, const std::string& InputFileName, const std::string& OutputBCFileName) {
898    Context *C = NULL;
899    std::string ResourceId = "";
900
901    if(!GetFileNameWithoutExtension(OutputBCFileName, ResourceId))
902        return false;
903
904    if(ResourceId.empty())
905        ResourceId = "<Resource ID>";
906
907    if((OutputPackageName == NULL) || (*OutputPackageName == '\0') || strcmp(OutputPackageName, "-") == 0)
908        C = new Context("<Package Name>", ResourceId, true);
909    else
910        C = new Context(OutputPackageName, ResourceId, false);
911
912    if(C != NULL) {
913        std::string ErrorMsg, ScriptClassName;
914        /* class ScriptC_<ScriptName> */
915        if(!GetFileNameWithoutExtension(InputFileName, ScriptClassName))
916            return false;
917
918        if(ScriptClassName.empty())
919            ScriptClassName = "<Input Script Name>";
920
921        ScriptClassName.at(0) = toupper(ScriptClassName.at(0));
922        ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX);
923
924        if(!genScriptClass(*C, ScriptClassName, ErrorMsg)) {
925            std::cerr << "Failed to generate class " << ScriptClassName << " (" << ErrorMsg << ")" << endl;
926            return false;
927        }
928
929        /* class ScriptField_<TypeName> */
930        for(RSContext::const_export_type_iterator TI = mRSContext->export_types_begin();
931            TI != mRSContext->export_types_end();
932            TI++)
933        {
934            const RSExportType* ET = TI->getValue();
935
936            if(ET->getClass() == RSExportType::ExportClassRecord) {
937                const RSExportRecordType* ERT = static_cast<const RSExportRecordType*>(ET);
938
939                if(!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) {
940                    std::cerr << "Failed to generate type class for struct '" << ERT->getName() << "' (" << ErrorMsg << ")" << endl;
941                    return false;
942                }
943            }
944        }
945    }
946
947    return true;
948}
949
950/****************************** RSReflection::Context ******************************/
951const char* const RSReflection::Context::LicenseNote =
952    "/*\n"
953	" * Copyright (C) 2010 The Android Open Source Project\n"
954	" *\n"
955	" * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
956	" * you may not use this file except in compliance with the License.\n"
957	" * You may obtain a copy of the License at\n"
958	" *\n"
959	" *      http://www.apache.org/licenses/LICENSE-2.0\n"
960	" *\n"
961	" * Unless required by applicable law or agreed to in writing, software\n"
962	" * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
963	" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
964	" * See the License for the specific language governing permissions and\n"
965	" * limitations under the License.\n"
966	" */\n";
967
968const char* const RSReflection::Context::Import[] = {
969    /* RenderScript java class */
970    "android.renderscript.*",
971    /* Import R */
972    "android.content.res.Resources",
973    /* Import for debugging */
974    "android.util.Log",
975};
976
977const char* RSReflection::Context::AccessModifierStr(AccessModifier AM) {
978    switch(AM) {
979        case AM_Public: return "public"; break;
980        case AM_Protected: return "protected"; break;
981        case AM_Private: return "private"; break;
982        default: return ""; break;
983    }
984}
985
986bool RSReflection::Context::startClass(AccessModifier AM, bool IsStatic, const std::string& ClassName, const char* SuperClassName, std::string& ErrorMsg) {
987    if(mVerbose)
988        std::cout << "Generating " << ClassName << ".java ..." << endl;
989
990    /* Open the file */
991    if(!mUseStdout) {
992        mOF.clear();
993        mOF.open((ClassName + ".java").c_str());
994        if(!mOF.good()) {
995            ErrorMsg = "failed to open file '" + ClassName + ".java' for write";
996            return false;
997        }
998    }
999
1000    /* License */
1001    out() << LicenseNote << endl;
1002
1003    /* Package */
1004    if(!mPackageName.empty())
1005        out() << "package " << mPackageName << ";" << endl;
1006    out() << endl;
1007
1008    /* Imports */
1009    for(int i=0;i<(sizeof(Import)/sizeof(const char*));i++)
1010        out() << "import " << Import[i] << ";" << endl;
1011    out() << endl;
1012
1013    out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class " << ClassName;
1014    if(SuperClassName != NULL)
1015        out() << " extends " << SuperClassName;
1016
1017    startBlock();
1018
1019    mClassName = ClassName;
1020
1021    return true;
1022}
1023
1024void RSReflection::Context::endClass() {
1025    endBlock();
1026    if(!mUseStdout)
1027        mOF.close();
1028    clear();
1029    return;
1030}
1031
1032void RSReflection::Context::startBlock(bool ShouldIndent) {
1033    if(ShouldIndent)
1034        indent() << "{" << endl;
1035    else
1036        out() << " {" << endl;
1037    incIndentLevel();
1038    return;
1039}
1040
1041void RSReflection::Context::endBlock() {
1042    decIndentLevel();
1043    indent() << "}" << endl << endl;
1044    return;
1045}
1046
1047void RSReflection::Context::startTypeClass(const std::string& ClassName) {
1048    indent() << "public static class " << ClassName;
1049    startBlock();
1050    return;
1051}
1052
1053void RSReflection::Context::endTypeClass() {
1054    endBlock();
1055    return;
1056}
1057
1058void RSReflection::Context::startFunction(AccessModifier AM, bool IsStatic, const char* ReturnType, const std::string& FunctionName, int Argc, ...) {
1059    ArgTy Args;
1060    va_list vl;
1061    va_start(vl, Argc);
1062
1063    for(int i=0;i<Argc;i++) {
1064        const char* ArgType = va_arg(vl, const char*);
1065        const char* ArgName = va_arg(vl, const char*);
1066
1067        Args.push_back( make_pair(ArgType, ArgName) );
1068    }
1069    va_end(vl);
1070
1071    startFunction(AM, IsStatic, ReturnType, FunctionName, Args);
1072
1073    return;
1074}
1075
1076void RSReflection::Context::startFunction(AccessModifier AM,
1077                                          bool IsStatic,
1078                                          const char* ReturnType,
1079                                          const std::string& FunctionName,
1080                                          const ArgTy& Args)
1081{
1082    indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ") << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "(";
1083
1084    bool FirstArg = true;
1085    for(ArgTy::const_iterator I = Args.begin();
1086        I != Args.end();
1087        I++)
1088    {
1089        if(!FirstArg)
1090            out() << ", ";
1091        else
1092            FirstArg = false;
1093
1094        out() << I->first << " " << I->second;
1095    }
1096
1097    out() << ")";
1098    startBlock();
1099
1100    return;
1101}
1102
1103void RSReflection::Context::endFunction() {
1104    endBlock();
1105    return;
1106}
1107
1108}   /* namespace slang */
1109