b/3093447 Create element of constant array using Element.add(Element element,
String name, int arraySize) API.
diff --git a/slang_rs_reflection.cpp b/slang_rs_reflection.cpp
index befd712..a142a96 100644
--- a/slang_rs_reflection.cpp
+++ b/slang_rs_reflection.cpp
@@ -22,6 +22,7 @@
#include <sys/stat.h>
#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/StringExtras.h"
#include "slang_utils.h"
#include "slang_rs_context.h"
@@ -308,18 +309,18 @@
static_cast<const RSExportPrimitiveType*>(ET);
if (EPT->getKind() == RSExportPrimitiveType::DataKindUser) {
static const char *PrimitiveBuiltinElementConstructMap[] = {
- NULL, // RSExportPrimitiveType::DataTypeFloat16
- "F32", // RSExportPrimitiveType::DataTypeFloat32
- "F64", // RSExportPrimitiveType::DataTypeFloat64
- "I8", // RSExportPrimitiveType::DataTypeSigned8
- NULL, // RSExportPrimitiveType::DataTypeSigned16
- "I32", // RSExportPrimitiveType::DataTypeSigned32
- "I64", // RSExportPrimitiveType::DataTypeSigned64
- "U8", // RSExportPrimitiveType::DataTypeUnsigned8
- NULL, // RSExportPrimitiveType::DataTypeUnsigned16
- "U32", // RSExportPrimitiveType::DataTypeUnsigned32
- "U64", // RSExportPrimitiveType::DataTypeUnsigned64
- "BOOLEAN", // RSExportPrimitiveType::DataTypeBoolean
+ NULL, // RSExportPrimitiveType::DataTypeFloat16
+ "Element.F32", // RSExportPrimitiveType::DataTypeFloat32
+ "Element.F64", // RSExportPrimitiveType::DataTypeFloat64
+ "Element.I8", // RSExportPrimitiveType::DataTypeSigned8
+ NULL, // RSExportPrimitiveType::DataTypeSigned16
+ "Element.I32", // RSExportPrimitiveType::DataTypeSigned32
+ "Element.I64", // RSExportPrimitiveType::DataTypeSigned64
+ "Element.U8", // RSExportPrimitiveType::DataTypeUnsigned8
+ NULL, // RSExportPrimitiveType::DataTypeUnsigned16
+ "Element.U32", // RSExportPrimitiveType::DataTypeUnsigned32
+ "Element.U64", // RSExportPrimitiveType::DataTypeUnsigned64
+ "Element.BOOLEAN", // RSExportPrimitiveType::DataTypeBoolean
NULL, // RSExportPrimitiveType::DataTypeUnsigned565
NULL, // RSExportPrimitiveType::DataTypeUnsigned5551
@@ -329,17 +330,17 @@
NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3
NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4
- "ELEMENT", // RSExportPrimitiveType::DataTypeRSElement
- "TYPE", // RSExportPrimitiveType::DataTypeRSType
- "ALLOCATION", // RSExportPrimitiveType::DataTypeRSAllocation
- "SAMPLER", // RSExportPrimitiveType::DataTypeRSSampler
- "SCRIPT", // RSExportPrimitiveType::DataTypeRSScript
- "MESH", // RSExportPrimitiveType::DataTypeRSMesh
- "PROGRAM_FRAGMENT", // RSExportPrimitiveType::DataTypeRSProgramFragment
- "PROGRAM_VERTEX", // RSExportPrimitiveType::DataTypeRSProgramVertex
- "PROGRAM_RASTER", // RSExportPrimitiveType::DataTypeRSProgramRaster
- "PROGRAM_STORE", // RSExportPrimitiveType::DataTypeRSProgramStore
- "FONT", // RSExportPrimitiveType::DataTypeRSFont
+ "Element.ELEMENT", // RSExportPrimitiveType::DataTypeRSElement
+ "Element.TYPE", // RSExportPrimitiveType::DataTypeRSType
+ "Element.ALLOCATION", // RSExportPrimitiveType::DataTypeRSAllocation
+ "Element.SAMPLER", // RSExportPrimitiveType::DataTypeRSSampler
+ "Element.SCRIPT", // RSExportPrimitiveType::DataTypeRSScript
+ "Element.MESH", // RSExportPrimitiveType::DataTypeRSMesh
+ "Element.PROGRAM_FRAGMENT", // RSExportPrimitiveType::DataTypeRSProgramFragment
+ "Element.PROGRAM_VERTEX", // RSExportPrimitiveType::DataTypeRSProgramVertex
+ "Element.PROGRAM_RASTER", // RSExportPrimitiveType::DataTypeRSProgramRaster
+ "Element.PROGRAM_STORE", // RSExportPrimitiveType::DataTypeRSProgramStore
+ "Element.FONT", // RSExportPrimitiveType::DataTypeRSFont
};
unsigned TypeId = EPT->getType();
@@ -348,58 +349,47 @@
return PrimitiveBuiltinElementConstructMap[ EPT->getType() ];
} else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelA) {
if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
- return "A_8";
+ return "Element.A_8";
} else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGB) {
if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned565)
- return "RGB_565";
+ return "Element.RGB_565";
else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
- return "RGB_888";
+ return "Element.RGB_888";
} else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGBA) {
if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned5551)
- return "RGBA_5551";
+ return "Element.RGBA_5551";
else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned4444)
- return "RGBA_4444";
+ return "Element.RGBA_4444";
else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8)
- return "RGBA_8888";
+ return "Element.RGBA_8888";
}
} else if (ET->getClass() == RSExportType::ExportClassVector) {
const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(ET);
if (EVT->getKind() == RSExportPrimitiveType::DataKindUser) {
if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) {
if (EVT->getNumElement() == 2)
- return "F32_2";
+ return "Element.F32_2";
else if (EVT->getNumElement() == 3)
- return "F32_3";
+ return "Element.F32_3";
else if (EVT->getNumElement() == 4)
- return "F32_4";
+ return "Element.F32_4";
} else if (EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) {
if (EVT->getNumElement() == 4)
- return "U8_4";
+ return "Element.U8_4";
}
}
} else if (ET->getClass() == RSExportType::ExportClassMatrix) {
const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET);
switch (EMT->getDim()) {
- case 2: {
- return "MATRIX_2X2";
- break;
- }
- case 3: {
- return "MATRIX_3X3";
- break;
- }
- case 4: {
- return "MATRIX_4X4";
- break;
- }
- default: {
- assert(false && "Unsupported dimension of matrix");
- }
+ case 2: return "Element.MATRIX_2X2";
+ case 3: return "Element.MATRIX_3X3";
+ case 4: return "Element.MATRIX_4X4";
+ default: assert(false && "Unsupported dimension of matrix");
}
} else if (ET->getClass() == RSExportType::ExportClassPointer) {
// Treat pointer type variable as unsigned int
// TODO(zonr): this is target dependent
- return "USER_I32";
+ return "Element.USER_I32";
}
return NULL;
@@ -833,10 +823,10 @@
PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType();
TypeName = GetTypeName(ET);
- // bind_*()
C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX
<< EV->getName() << ";" << std::endl;
+ // bind_*()
C.startFunction(Context::AM_Public,
false,
"void",
@@ -1070,11 +1060,29 @@
case RSExportType::ExportClassConstantArray: {
const RSExportConstantArrayType *ECAT =
static_cast<const RSExportConstantArrayType *>(ET);
- C.indent() << "for (int ct = 0; ct < " << ECAT->getSize() << "; ct++)";
+
+ // TODO(zonr): more elegant way. Currently, we obtain the unique index
+ // variable (this method involves recursive call which means
+ // we may have more than one level loop, therefore we can't
+ // always use the same index variable name here) name given
+ // in the for-loop from counting the '.' in @VarName.
+ unsigned Level = 0;
+ size_t LastDotPos = 0;
+ std::string ElementVarName(VarName);
+
+ while (LastDotPos != std::string::npos) {
+ LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1);
+ Level++;
+ }
+ std::string IndexVarName("ct");
+ IndexVarName.append(llvm::utostr_32(Level));
+
+ C.indent() << "for (int " << IndexVarName << " = 0; " <<
+ IndexVarName << " < " << ECAT->getSize() << "; " <<
+ IndexVarName << "++)";
C.startBlock();
- std::string ElementVarName(VarName);
- ElementVarName.append("[ct]");
+ ElementVarName.append("[" + IndexVarName + "]");
genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(),
FieldPackerName);
@@ -1293,7 +1301,7 @@
1,
"RenderScript",
RenderScriptVar);
- genBuildElement(C, ERT, RenderScriptVar);
+ genBuildElement(C, "eb", ERT, RenderScriptVar, /* IsInline = */false);
C.endFunction();
C.startFunction(Context::AM_Public,
@@ -1479,13 +1487,11 @@
/******************** Methods to generate type class /end ********************/
/********** Methods to create Element in Java of given record type ***********/
-void RSReflection::genBuildElement(Context &C, const RSExportRecordType *ERT,
- const char *RenderScriptVar) {
- const char *ElementBuilderName = "eb";
-
- // Create element builder
- // C.startBlock(true);
-
+void RSReflection::genBuildElement(Context &C,
+ const char *ElementBuilderName,
+ const RSExportRecordType *ERT,
+ const char *RenderScriptVar,
+ bool IsInline) {
C.indent() << "Element.Builder " << ElementBuilderName << " = "
"new Element.Builder(" << RenderScriptVar << ");" << std::endl;
@@ -1494,25 +1500,29 @@
ERT,
"",
ElementBuilderName,
- RenderScriptVar);
+ RenderScriptVar,
+ /* ArraySize = */0);
- C.indent() << "return " << ElementBuilderName << ".create();" << std::endl;
-
- // C.endBlock();
+ if (!IsInline)
+ C.indent() << "return " << ElementBuilderName << ".create();" << std::endl;
return;
}
-#define EB_ADD(x) \
+#define EB_ADD(x) do { \
C.indent() << ElementBuilderName \
- << ".add(Element." << x << ", \"" << VarName << "\");" \
- << std::endl; \
- C.incFieldIndex()
+ << ".add(" << x << ", \"" << VarName << "\""; \
+ if (ArraySize > 0) \
+ C.out() << ", " << ArraySize; \
+ C.out() << ");" << std::endl; \
+ C.incFieldIndex(); \
+} while (false)
void RSReflection::genAddElementToElementBuilder(Context &C,
const RSExportType *ET,
const std::string &VarName,
const char *ElementBuilderName,
- const char *RenderScriptVar) {
+ const char *RenderScriptVar,
+ unsigned ArraySize) {
const char *ElementConstruct = GetBuiltinElementConstruct(ET);
if (ElementConstruct != NULL) {
@@ -1535,23 +1545,23 @@
case RSExportPrimitiveType::DataKindPixelRGB:
case RSExportPrimitiveType::DataKindPixelRGBA: {
// Element.createPixel()
- EB_ADD("createPixel(" << RenderScriptVar << ", "
- << DataTypeName << ", "
- << DataKindName << ")");
+ EB_ADD("Element.createPixel(" << RenderScriptVar << ", "
+ << DataTypeName << ", "
+ << DataKindName << ")");
break;
}
case RSExportPrimitiveType::DataKindUser:
default: {
if (EPT->getClass() == RSExportType::ExportClassPrimitive) {
// Element.createUser()
- EB_ADD("createUser(" << RenderScriptVar << ", "
- << DataTypeName << ")");
+ EB_ADD("Element.createUser(" << RenderScriptVar << ", "
+ << DataTypeName << ")");
} else {
assert((ET->getClass() == RSExportType::ExportClassVector) &&
"Unexpected type.");
- EB_ADD("createVector(" << RenderScriptVar << ", "
- << DataTypeName << ", "
- << Size << ")");
+ EB_ADD("Element.createVector(" << RenderScriptVar << ", "
+ << DataTypeName << ", "
+ << Size << ")");
}
break;
}
@@ -1569,18 +1579,27 @@
} else if (ET->getClass() == RSExportType::ExportClassConstantArray) {
const RSExportConstantArrayType *ECAT =
static_cast<const RSExportConstantArrayType *>(ET);
- C.indent() << "for (int ct = 0; ct < " << ECAT->getSize() << "; ct++)";
- C.startBlock();
- std::string ElementVarName(VarName);
- ElementVarName.append("[\" + ct + \"]");
- genAddElementToElementBuilder(C,
- ECAT->getElementType(),
- ElementVarName,
- ElementBuilderName,
- RenderScriptVar);
+ const RSExportType *ElementType = ECAT->getElementType();
+ if (ElementType->getClass() != RSExportType::ExportClassRecord) {
+ genAddElementToElementBuilder(C,
+ ECAT->getElementType(),
+ VarName,
+ ElementBuilderName,
+ RenderScriptVar,
+ ECAT->getSize());
+ } else {
+ std::string NewElementBuilderName(ElementBuilderName);
+ NewElementBuilderName.append(1, '_');
- C.endBlock();
+ genBuildElement(C,
+ NewElementBuilderName.c_str(),
+ static_cast<const RSExportRecordType*>(ElementType),
+ RenderScriptVar,
+ /* IsInline = */true);
+ ArraySize = ECAT->getSize();
+ EB_ADD(NewElementBuilderName << ".create()");
+ }
} else if (ET->getClass() == RSExportType::ExportClassRecord) {
// Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType.
//
@@ -1613,11 +1632,26 @@
// eb.add(...)
C.addFieldIndexMapping(F);
- genAddElementToElementBuilder(C,
- F->getType(),
- FieldName,
- ElementBuilderName,
- RenderScriptVar);
+ if (F->getType()->getClass() != RSExportType::ExportClassRecord) {
+ genAddElementToElementBuilder(C,
+ F->getType(),
+ FieldName,
+ ElementBuilderName,
+ RenderScriptVar,
+ 0);
+ } else {
+ std::string NewElementBuilderName(ElementBuilderName);
+ NewElementBuilderName.append(1, '_');
+
+ genBuildElement(C,
+ NewElementBuilderName.c_str(),
+ static_cast<const RSExportRecordType*>(F->getType()),
+ RenderScriptVar,
+ /* IsInline = */true);
+
+ const std::string &VarName = FieldName; // Hack for EB_ADD macro
+ EB_ADD(NewElementBuilderName << ".create()");
+ }
// There is padding within the field type
genAddPaddingToElementBuiler(C,
@@ -1629,12 +1663,10 @@
}
// There maybe some padding after the struct
- //unsigned char align = RSExportType::GetTypeAlignment(ERT);
- //size_t siz = RSExportType::GetTypeAllocSize(ERT);
- size_t siz1 = RSExportType::GetTypeStoreSize(ERT);
+ size_t RecordStoreSize = RSExportType::GetTypeStoreSize(ERT);
genAddPaddingToElementBuiler(C,
- siz1 - Pos,
+ RecordStoreSize - Pos,
ElementBuilderName,
RenderScriptVar);
} else {
@@ -1647,16 +1679,17 @@
int PaddingSize,
const char *ElementBuilderName,
const char *RenderScriptVar) {
+ unsigned ArraySize = 0; // Hack the EB_ADD macro
while (PaddingSize > 0) {
const std::string &VarName = C.createPaddingField();
if (PaddingSize >= 4) {
- EB_ADD("U32(" << RenderScriptVar << ")");
+ EB_ADD("Element.U32(" << RenderScriptVar << ")");
PaddingSize -= 4;
} else if (PaddingSize >= 2) {
- EB_ADD("U16(" << RenderScriptVar << ")");
+ EB_ADD("Element.U16(" << RenderScriptVar << ")");
PaddingSize -= 2;
} else if (PaddingSize >= 1) {
- EB_ADD("U8(" << RenderScriptVar << ")");
+ EB_ADD("Element.U8(" << RenderScriptVar << ")");
PaddingSize -= 1;
}
}
diff --git a/slang_rs_reflection.h b/slang_rs_reflection.h
index f382bbf..ff6099e 100644
--- a/slang_rs_reflection.h
+++ b/slang_rs_reflection.h
@@ -244,13 +244,16 @@
void genTypeClassCopyAll(Context &C, const RSExportRecordType *ERT);
void genBuildElement(Context &C,
+ const char *ElementBuilderName,
const RSExportRecordType *ERT,
- const char *RenderScriptVar);
+ const char *RenderScriptVar,
+ bool IsInline);
void genAddElementToElementBuilder(Context &C,
const RSExportType *ERT,
const std::string &VarName,
const char *ElementBuilderName,
- const char *RenderScriptVar);
+ const char *RenderScriptVar,
+ unsigned ArraySize);
void genAddPaddingToElementBuiler(Context &C,
int PaddingSize,
const char *ElementBuilderName,