/* * 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; }