/*
* Copyright 2010, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdio>
#include <cstring>
#include <string>
#include "slang_rs_type_spec.h"
enum {
#define ENUM_PRIMITIVE_DATA_TYPE(x, name, bits) x,
#define PRIMITIVE_DATA_TYPE_RANGE(x, y) \
FirstPrimitiveType = x, \
LastPrimitiveType = y,
PRIMITIVE_DATA_TYPE_ENUMS
#undef ENUM_PRIMITIVE_DATA_TYPE
#undef PRIMITIVE_DATA_TYPE_RANGE
#define ENUM_RS_MATRIX_DATA_TYPE(x, name, dim) x,
#define RS_MATRIX_DATA_TYPE_RANGE(x, y) \
FirstRSMatrixType = x, \
LastRSMatrixType = y,
RS_MATRIX_DATA_TYPE_ENUMS
#undef ENUM_RS_MATRIX_DATA_TYPE
#undef RS_MATRIX_DATA_TYPE_RANGE
#define ENUM_RS_OBJECT_DATA_TYPE(x, name) x,
#define RS_OBJECT_DATA_TYPE_RANGE(x, y) \
FirstRSObjectType = x, \
LastRSObjectType = y,
RS_OBJECT_DATA_TYPE_ENUMS
#undef ENUM_RS_OBJECT_DATA_TYPE
#undef RS_OBJECT_DATA_TYPE_RANGE
};
class RSDataTypeSpec {
private:
const char *mTypeName; // e.g. Float32
// FIXME: better name
const char *mTypePragmaName; // e.g. float
size_t mBits;
protected:
enum {
DT_PrimitiveClass,
DT_RSMatrixClass,
DT_RSObjectClass
} mClass;
public:
RSDataTypeSpec(const char *TypeName,
const char *TypePragmaName,
size_t Bits)
: mTypeName(TypeName),
mTypePragmaName(TypePragmaName),
mBits(Bits),
mClass(DT_PrimitiveClass) {
return;
}
inline const char *getTypeName() const { return mTypeName; }
inline const char *getTypePragmaName() const { return mTypePragmaName; }
inline size_t getSizeInBit() const { return mBits; }
inline bool isRSMatrix() const { return (mClass == DT_RSMatrixClass); }
inline bool isRSObject() const { return (mClass == DT_RSObjectClass); }
};
class RSMatrixDataTypeSpec : public RSDataTypeSpec {
private:
unsigned mDim;
static float ignore;
public:
RSMatrixDataTypeSpec(const char *TypeName,
const char *TypePragmaName,
unsigned Dim)
: RSDataTypeSpec(TypeName, TypePragmaName, Dim * Dim * sizeof(ignore)),
mDim(Dim) {
mClass = DT_RSMatrixClass;
return;
}
inline unsigned getDim() const { return mDim; }
};
class RSObjectDataTypeSpec : public RSDataTypeSpec {
public:
RSObjectDataTypeSpec(const char *TypeName,
const char *TypePragmaName)
: RSDataTypeSpec(TypeName, TypePragmaName, 32 /* opaque pointer */) {
mClass = DT_RSObjectClass;
return;
}
};
/////////////////////////////////////////////////////////////////////////////
// clang::BuiltinType::Kind -> RSDataTypeSpec
class ClangBuiltinTypeMap {
const char *mBuiltinTypeKind;
const RSDataTypeSpec *mDataType;
public:
ClangBuiltinTypeMap(const char *BuiltinTypeKind,
const RSDataTypeSpec *DataType)
: mBuiltinTypeKind(BuiltinTypeKind),
mDataType(DataType) {
return;
}
inline const char *getBuiltinTypeKind() const { return mBuiltinTypeKind; }
inline const RSDataTypeSpec *getDataType() const { return mDataType; }
};
/////////////////////////////////////////////////////////////////////////////
class RSDataElementSpec {
private:
const char *mElementName;
const RSDataTypeSpec *mDataType;
bool mIsNormal;
unsigned mVectorSize;
public:
RSDataElementSpec(const char *ElementName,
const RSDataTypeSpec *DataType,
bool IsNormal,
unsigned VectorSize)
: mElementName(ElementName),
mDataType(DataType),
mIsNormal(IsNormal),
mVectorSize(VectorSize) {
return;
}
inline const char *getElementName() const { return mElementName; }
inline const RSDataTypeSpec *getDataType() const { return mDataType; }
inline bool isNormal() const { return mIsNormal; }
inline unsigned getVectorSize() const { return mVectorSize; }
};
/////////////////////////////////////////////////////////////////////////////
// -gen-rs-data-type-enums
//
// ENUM_PRIMITIVE_DATA_TYPE(type, cname, bits)
// ENUM_PRIMITIVE_DATA_TYPE_RANGE(begin_type, end_type)
// ENUM_RS_MATRIX_DATA_TYPE(type, cname, bits)
// ENUM_RS_MATRIX_DATA_TYPE_RANGE(begin_type, end_type)
// ENUM_RS_OBJECT_DATA_TYPE(type, cname, bits)
// ENUM_RS_OBJECT_DATA_TYPE_RANGE(begin_type, end_type)
//
// ENUM_RS_DATA_TYPE(type, cname, bits)
// e.g., ENUM_RS_DATA_TYPE(Float32, "float", 256)
static int GenRSDataTypeEnums(const RSDataTypeSpec *const DataTypes[],
unsigned NumDataTypes) {
// Alias missing #define
#define ALIAS_DEF(x, y) \
printf("#ifndef " #x "\n"); \
printf("#define " #x "(type, cname, bits) " #y "(type, cname, bits)\n"); \
printf("#endif\n\n")
ALIAS_DEF(ENUM_PRIMITIVE_DATA_TYPE, ENUM_RS_DATA_TYPE);
ALIAS_DEF(ENUM_RS_MATRIX_DATA_TYPE, ENUM_RS_DATA_TYPE);
ALIAS_DEF(ENUM_RS_OBJECT_DATA_TYPE, ENUM_RS_DATA_TYPE);
#undef ALIAS_DEF
#define ALIAS_DEF(x) \
printf("#ifndef " #x "\n"); \
printf("#define " #x "(begin_type, end_type)\n"); \
printf("#endif\n\n")
ALIAS_DEF(ENUM_PRIMITIVE_DATA_TYPE_RANGE);
ALIAS_DEF(ENUM_RS_MATRIX_DATA_TYPE_RANGE);
ALIAS_DEF(ENUM_RS_OBJECT_DATA_TYPE_RANGE);
#undef ALIAS_DEF
#define DEF(x) \
printf(#x "(%s, \"%s\", %lu)\n", \
DataTypes[i]->getTypeName(), \
DataTypes[i]->getTypePragmaName(), \
(unsigned long) DataTypes[i]->getSizeInBit()); // NOLINT(runtime/int)
#define DEF_RANGE(x, begin, end) \
printf(#x "(%s, %s)\n\n", \
DataTypes[begin]->getTypeName(), \
DataTypes[end]->getTypeName())
for (unsigned i = FirstPrimitiveType; i <= LastPrimitiveType; i++)
DEF(ENUM_PRIMITIVE_DATA_TYPE);
DEF_RANGE(ENUM_PRIMITIVE_DATA_TYPE_RANGE,
FirstPrimitiveType, LastPrimitiveType);
for (unsigned i = FirstRSMatrixType; i <= LastRSMatrixType; i++)
DEF(ENUM_RS_MATRIX_DATA_TYPE)
DEF_RANGE(ENUM_RS_MATRIX_DATA_TYPE_RANGE,
FirstRSMatrixType, LastRSMatrixType);
for (unsigned i = FirstRSObjectType; i <= LastRSObjectType; i++)
DEF(ENUM_RS_OBJECT_DATA_TYPE)
DEF_RANGE(ENUM_RS_OBJECT_DATA_TYPE_RANGE,
FirstRSObjectType, LastRSObjectType);
#undef DEF
#undef DEF_RANGE
#define UNDEF(x) \
printf("#undef " #x "\n")
UNDEF(ENUM_PRIMITIVE_DATA_TYPE);
UNDEF(ENUM_RS_MATRIX_DATA_TYPE);
UNDEF(ENUM_RS_OBJECT_DATA_TYPE);
UNDEF(ENUM_PRIMITIVE_DATA_TYPE_RANGE);
UNDEF(ENUM_RS_MATRIX_DATA_TYPE_RANGE);
UNDEF(ENUM_RS_OBJECT_DATA_TYPE_RANGE);
UNDEF(ENUM_RS_DATA_TYPE);
return 0;
}
// -gen-clang-builtin-cnames
//
// ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname)
// e.g., ENUM_SUPPORT_BUILTIN_TYPE(clang::BuiltinType::Float, Float32, "float")
static int GenClangBuiltinEnum(
const ClangBuiltinTypeMap *const ClangBuilitinsMap[],
unsigned NumClangBuilitins) {
for (unsigned i = 0; i < NumClangBuilitins; i++)
printf("ENUM_SUPPORT_BUILTIN_TYPE(%s, %s, \"%s\")\n",
ClangBuilitinsMap[i]->getBuiltinTypeKind(),
ClangBuilitinsMap[i]->getDataType()->getTypeName(),
ClangBuilitinsMap[i]->getDataType()->getTypePragmaName());
printf("#undef ENUM_SUPPORT_BUILTIN_TYPE\n");
return 0;
}
// -gen-rs-matrix-type-enums
//
// ENUM_RS_MATRIX_TYPE(type, cname, dim)
// e.g., ENUM_RS_MATRIX_TYPE(RSMatrix2x2, "rs_matrix2x2", 2)
static int GenRSMatrixTypeEnums(const RSDataTypeSpec *const DataTypes[],
unsigned NumDataTypes) {
for (unsigned i = 0; i < NumDataTypes; i++)
if (DataTypes[i]->isRSMatrix()) {
const RSMatrixDataTypeSpec *const MatrixDataType =
static_cast<const RSMatrixDataTypeSpec *const>(DataTypes[i]);
printf("ENUM_RS_MATRIX_TYPE(%s, \"%s\", %u)\n",
MatrixDataType->getTypeName(),
MatrixDataType->getTypePragmaName(),
MatrixDataType->getDim());
}
printf("#undef ENUM_RS_MATRIX_TYPE\n");
return 0;
}
// -gen-rs-object-type-enums
//
// ENUM_RS_OBJECT_TYPE(type, cname)
// e.g., ENUM_RS_OBJECT_TYPE(RSElement, "rs_element")
static int GenRSObjectTypeEnums(const RSDataTypeSpec *const DataTypes[],
unsigned NumDataTypes) {
for (unsigned i = 0; i < NumDataTypes; i++)
if (DataTypes[i]->isRSObject())
printf("ENUM_RS_OBJECT_TYPE(%s, \"%s\")\n",
DataTypes[i]->getTypeName(),
DataTypes[i]->getTypePragmaName());
printf("#undef ENUM_RS_OBJECT_TYPE\n");
return 0;
}
// -gen-rs-data-element-enums
//
// ENUM_RS_DATA_ELEMENT(name, dt, dk, normailized, vsize)
// e.g., ENUM_RS_DATA_ELEMENT("rs_pixel_rgba", PixelRGB, Unsigned8, true, 4)
int GenRSDataElementEnums(const RSDataElementSpec *const DataElements[],
unsigned NumDataElements) {
for (unsigned i = 0; i < NumDataElements; i++)
printf("ENUM_RS_DATA_ELEMENT(\"%s\", %s, %s, %d)\n",
DataElements[i]->getElementName(),
DataElements[i]->getDataType()->getTypeName(),
((DataElements[i]->isNormal()) ? "true" : "false"),
DataElements[i]->getVectorSize());
printf("#undef ENUM_RS_DATA_ELEMENT\n");
return 0;
}
int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "usage: %s [gen type]\n", argv[0]);
return 1;
}
RSDataTypeSpec *DataTypes[] = {
#define ENUM_PRIMITIVE_DATA_TYPE(x, name, bits) \
new RSDataTypeSpec(#x , name, bits),
#define PRIMITIVE_DATA_TYPE_RANGE(x, y)
PRIMITIVE_DATA_TYPE_ENUMS
#undef ENUM_PRIMITIVE_DATA_TYPE
#undef PRIMITIVE_DATA_TYPE_RANGE
#define ENUM_RS_MATRIX_DATA_TYPE(x, name, dim) \
new RSMatrixDataTypeSpec(#x , name, dim),
#define RS_MATRIX_DATA_TYPE_RANGE(x, y)
RS_MATRIX_DATA_TYPE_ENUMS
#undef ENUM_RS_MATRIX_DATA_TYPE
#undef RS_MATRIX_DATA_TYPE_RANGE
#define ENUM_RS_OBJECT_DATA_TYPE(x, name) \
new RSObjectDataTypeSpec(#x, name),
#define RS_OBJECT_DATA_TYPE_RANGE(x, y)
RS_OBJECT_DATA_TYPE_ENUMS
#undef ENUM_RS_OBJECT_DATA_TYPE
#undef RS_OBJECT_DATA_TYPE_RANGE
};
unsigned NumDataTypes = sizeof(DataTypes) / sizeof(DataTypes[0]);
/////////////////////////////////////////////////////////////////////////////
ClangBuiltinTypeMap *ClangBuilitinsMap[] = {
new ClangBuiltinTypeMap("clang::BuiltinType::Bool", DataTypes[Boolean]),
new ClangBuiltinTypeMap("clang::BuiltinType::Char_U", DataTypes[Unsigned8]),
new ClangBuiltinTypeMap("clang::BuiltinType::UChar", DataTypes[Unsigned8]),
new ClangBuiltinTypeMap("clang::BuiltinType::Char16", DataTypes[Signed16]),
new ClangBuiltinTypeMap("clang::BuiltinType::Char32", DataTypes[Signed32]),
new ClangBuiltinTypeMap(
"clang::BuiltinType::UShort", DataTypes[Unsigned16]),
new ClangBuiltinTypeMap(
"clang::BuiltinType::UInt", DataTypes[Unsigned32]),
new ClangBuiltinTypeMap(
"clang::BuiltinType::ULong", DataTypes[Unsigned32]),
new ClangBuiltinTypeMap(
"clang::BuiltinType::ULongLong", DataTypes[Unsigned64]),
new ClangBuiltinTypeMap("clang::BuiltinType::Char_S", DataTypes[Signed8]),
new ClangBuiltinTypeMap("clang::BuiltinType::SChar", DataTypes[Signed8]),
new ClangBuiltinTypeMap("clang::BuiltinType::Short", DataTypes[Signed16]),
new ClangBuiltinTypeMap("clang::BuiltinType::Int", DataTypes[Signed32]),
new ClangBuiltinTypeMap("clang::BuiltinType::Long", DataTypes[Signed64]),
new ClangBuiltinTypeMap(
"clang::BuiltinType::LongLong", DataTypes[Signed64]),
new ClangBuiltinTypeMap("clang::BuiltinType::Float", DataTypes[Float32]),
new ClangBuiltinTypeMap("clang::BuiltinType::Double", DataTypes[Float64])
};
unsigned NumClangBuilitins =
sizeof(ClangBuilitinsMap) / sizeof(ClangBuilitinsMap[0]);
/////////////////////////////////////////////////////////////////////////////
RSDataElementSpec *DataElements[] = {
new RSDataElementSpec("rs_pixel_l",
DataTypes[Unsigned8],
/* IsNormal = */true, /* VectorSize = */1),
new RSDataElementSpec("rs_pixel_a",
DataTypes[Unsigned8],
true, 1),
new RSDataElementSpec("rs_pixel_la",
DataTypes[Unsigned8],
true, 2),
new RSDataElementSpec("rs_pixel_rgb",
DataTypes[Unsigned8],
true, 3),
new RSDataElementSpec("rs_pixel_rgba",
DataTypes[Unsigned8],
true, 4),
new RSDataElementSpec("rs_pixel_rgb565",
DataTypes[Unsigned8],
true, 3),
new RSDataElementSpec("rs_pixel_rgb5551",
DataTypes[Unsigned8],
true, 4),
new RSDataElementSpec("rs_pixel_rgb4444",
DataTypes[Unsigned8],
true, 4),
};
unsigned NumDataElements = sizeof(DataElements) / sizeof(DataElements[0]);
/////////////////////////////////////////////////////////////////////////////
int Result = 1;
if (::strcmp(argv[1], "-gen-rs-data-type-enums") == 0)
Result = GenRSDataTypeEnums(DataTypes, NumDataTypes);
else if (::strcmp(argv[1], "-gen-clang-builtin-enums") == 0)
Result = GenClangBuiltinEnum(ClangBuilitinsMap, NumClangBuilitins);
else if (::strcmp(argv[1], "-gen-rs-matrix-type-enums") == 0)
Result = GenRSMatrixTypeEnums(DataTypes, NumDataTypes);
else if (::strcmp(argv[1], "-gen-rs-object-type-enums") == 0)
Result = GenRSObjectTypeEnums(DataTypes, NumDataTypes);
else if (::strcmp(argv[1], "-gen-rs-data-element-enums") == 0)
Result = GenRSDataElementEnums(DataElements, NumDataElements);
else
fprintf(stderr, "%s: Unknown table generation type '%s'\n",
argv[0], argv[1]);
/////////////////////////////////////////////////////////////////////////////
for (unsigned i = 0; i < NumDataTypes; i++)
delete DataTypes[i];
for (unsigned i = 0; i < NumClangBuilitins; i++)
delete ClangBuilitinsMap[i];
for (unsigned i = 0; i < NumDataElements; i++)
delete DataElements[i];
return Result;
}