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