* Handle static code analysis automatically * Fix matc test cases * Only call InitializeProcess once per process
252 lines
7.7 KiB
C++
252 lines
7.7 KiB
C++
/*
|
|
* Copyright (C) 2018 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 <gtest/gtest.h>
|
|
|
|
#include "MockConfig.h"
|
|
|
|
#include <matc/MaterialCompiler.h>
|
|
#include <matc/MaterialLexer.h>
|
|
#include <matc/JsonishLexer.h>
|
|
#include <matc/JsonishParser.h>
|
|
|
|
class MaterialLexer: public ::testing::Test {
|
|
protected:
|
|
MaterialLexer() = default;
|
|
~MaterialLexer() = default;
|
|
};
|
|
|
|
class TestMaterialCompiler {
|
|
public:
|
|
explicit TestMaterialCompiler(const matc::MaterialCompiler& materialCompiler) :
|
|
mMaterialCompiler(materialCompiler) {}
|
|
|
|
bool parseMaterial(const char* buffer, size_t size, filamat::MaterialBuilder& builder)
|
|
const noexcept{
|
|
return mMaterialCompiler.parseMaterial(buffer, size, builder);
|
|
}
|
|
|
|
bool parseMaterialAsJSON(const char* buffer, size_t size, filamat::MaterialBuilder& builder)
|
|
const noexcept{
|
|
return mMaterialCompiler.parseMaterialAsJSON(buffer, size, builder);
|
|
}
|
|
|
|
private:
|
|
const matc::MaterialCompiler& mMaterialCompiler;
|
|
};
|
|
|
|
static std::string materialSource(R"(
|
|
material {
|
|
name : "Filament Default Material",
|
|
shadingModel : unlit
|
|
}
|
|
|
|
fragment {
|
|
void material(inout MaterialInputs material) {
|
|
prepareMaterial(material);
|
|
material.baseColor.rgb = vec3(0.8);
|
|
}
|
|
}
|
|
)");
|
|
|
|
static std::string materialSourceWithTool(R"(
|
|
material {
|
|
name : "Filament Default Material",
|
|
shadingModel : unlit
|
|
}
|
|
|
|
fragment {
|
|
void material(inout MaterialInputs material) {
|
|
prepareMaterial(material);
|
|
material.baseColor.rgb = vec3(0.8);
|
|
}
|
|
}
|
|
|
|
tool {
|
|
all of this should be ignored
|
|
matching braces are fine
|
|
{ } { { } } { }
|
|
}
|
|
)");
|
|
|
|
static std::string materialSourceWithCommentedBraces(R"(
|
|
material {
|
|
name : "Filament Default Material",
|
|
shadingModel : unlit
|
|
}
|
|
|
|
fragment {
|
|
void material(inout MaterialInputs material) {
|
|
prepareMaterial(material);
|
|
// if (test) {
|
|
material.baseColor.rgb = vec3(0.8); // if (test) {
|
|
}
|
|
}
|
|
)");
|
|
|
|
TEST_F(MaterialLexer, NormalMaterialLexing) {
|
|
matc::MaterialLexer materialLexer;
|
|
materialLexer.lex(materialSource.c_str(), materialSource.size(), 1);
|
|
auto lexemes = materialLexer.getLexemes();
|
|
// A material grammar is made of identifiers and blocks. The source provided has one identifier,
|
|
// followed by block,identifier, and block. Total expected is four.
|
|
EXPECT_EQ(lexemes.size(), 4);
|
|
}
|
|
|
|
TEST_F(MaterialLexer, MaterialCompiler) {
|
|
matc::MaterialCompiler rawCompiler;
|
|
TestMaterialCompiler compiler(rawCompiler);
|
|
filamat::MaterialBuilder unused;
|
|
bool result = compiler.parseMaterial(materialSource.c_str(), materialSource.size(), unused);
|
|
EXPECT_EQ(result, true);
|
|
}
|
|
|
|
TEST_F(MaterialLexer, MaterialCompilerWithToolSection) {
|
|
matc::MaterialCompiler rawCompiler;
|
|
TestMaterialCompiler compiler(rawCompiler);
|
|
filamat::MaterialBuilder unused;
|
|
bool result = compiler.parseMaterial(materialSourceWithTool.c_str(), materialSourceWithTool.size(), unused);
|
|
EXPECT_EQ(result, true);
|
|
}
|
|
|
|
TEST_F(MaterialLexer, MaterialCompilerWithCommentedBraces) {
|
|
matc::MaterialCompiler rawCompiler;
|
|
TestMaterialCompiler compiler(rawCompiler);
|
|
filamat::MaterialBuilder unused;
|
|
bool result = compiler.parseMaterial(materialSourceWithCommentedBraces.c_str(), materialSourceWithCommentedBraces.size(), unused);
|
|
EXPECT_EQ(result, true);
|
|
}
|
|
|
|
TEST_F(MaterialLexer, MaterialParserErrorOnlyIdentifier) {
|
|
std::string sourceMissingIdentifier(R"(
|
|
singleIdentifier
|
|
)");
|
|
matc::MaterialCompiler rawCompiler;
|
|
TestMaterialCompiler compiler(rawCompiler);
|
|
filamat::MaterialBuilder unused;
|
|
bool result = compiler.parseMaterial(
|
|
sourceMissingIdentifier.c_str(), sourceMissingIdentifier.size(), unused);
|
|
EXPECT_EQ(result, false);
|
|
}
|
|
|
|
TEST_F(MaterialLexer, MaterialParserErrorMissingBlock) {
|
|
std::string sourceMissingBlock(R"(
|
|
identifier1 {}
|
|
identifier1
|
|
)");
|
|
matc::MaterialCompiler rawCompiler;
|
|
TestMaterialCompiler compiler(rawCompiler);
|
|
filamat::MaterialBuilder unused;
|
|
bool result = compiler.parseMaterial(
|
|
sourceMissingBlock.c_str(), sourceMissingBlock.size(), unused);
|
|
EXPECT_EQ(result, false);
|
|
}
|
|
|
|
TEST_F(MaterialLexer, MaterialParserErrorTwoBlock) {
|
|
std::string sourceTwoBlock(R"(
|
|
identifier1 {} {}
|
|
)");
|
|
matc::MaterialCompiler rawCompiler;
|
|
TestMaterialCompiler compiler(rawCompiler);
|
|
filamat::MaterialBuilder unused;
|
|
bool result = compiler.parseMaterial(sourceTwoBlock.c_str(), sourceTwoBlock.size(), unused);
|
|
EXPECT_EQ(result, false);
|
|
}
|
|
|
|
TEST_F(MaterialLexer, MaterialParserSyntaxError) {
|
|
std::string sourceSyntaxError(R"(
|
|
identifier1 {} # identified2 {}
|
|
)");
|
|
matc::MaterialCompiler rawCompiler;
|
|
TestMaterialCompiler compiler(rawCompiler);
|
|
filamat::MaterialBuilder unused;
|
|
bool result = compiler.parseMaterial(sourceSyntaxError.c_str(), sourceSyntaxError.size(), unused);
|
|
EXPECT_EQ(result, false);
|
|
}
|
|
|
|
static std::string jsonMaterialSource(R"(
|
|
{
|
|
"fragment": "void material(inout MaterialInputs material) {
|
|
vec3 normal = vec3(0.0, 0.0, 1.0);
|
|
material.normal = normal;
|
|
prepareMaterial(material);
|
|
material.baseColor = vec4(1.0, 1.0, 1.0, 1.0) * materialParams.baseColorFactor;
|
|
material.metallic = materialParams.metallicFactor;
|
|
material.roughness = materialParams.roughnessFactor;
|
|
material.ambientOcclusion = 1.0;
|
|
material.emissive = vec4(0.0);
|
|
material.reflectance = 0.5;
|
|
// material.baseColor.xyz = normal;\n}",
|
|
"material": {
|
|
"blending": "opaque",
|
|
"name": "Gltf 2 Metallic-Roughness Material",
|
|
"parameters": [
|
|
{
|
|
"name": "baseColorFactor",
|
|
"type": "float4"
|
|
},
|
|
{
|
|
"name": "metallicFactor",
|
|
"type": "float"
|
|
},
|
|
{
|
|
"name": "roughnessFactor",
|
|
"type": "float"
|
|
},
|
|
{
|
|
"name": "emissiveFactor",
|
|
"type": "float4"
|
|
}
|
|
],
|
|
"requires": [
|
|
"position",
|
|
"tangents",
|
|
"uv0"
|
|
],
|
|
"shadingModel": "lit"
|
|
}
|
|
}
|
|
)");
|
|
|
|
TEST_F(MaterialLexer, JsonMaterialLexingAndParsing) {
|
|
matc::JsonishLexer jsonishLexer;
|
|
jsonishLexer.lex(jsonMaterialSource.c_str(), jsonMaterialSource.size(), 1);
|
|
auto lexemes = jsonishLexer.getLexemes();
|
|
|
|
EXPECT_TRUE(!lexemes.empty());
|
|
|
|
matc::JsonishParser jsonishParser(lexemes);
|
|
std::unique_ptr<matc::JsonishObject> root = jsonishParser.parse();
|
|
|
|
auto entries = root->getEntries();
|
|
EXPECT_TRUE(entries.size() == 2);
|
|
EXPECT_TRUE(entries.find("fragment") != entries.end());
|
|
EXPECT_TRUE(entries.find("material") != entries.end());
|
|
}
|
|
|
|
TEST_F(MaterialLexer, JsonMaterialCompiler) {
|
|
matc::MaterialCompiler rawCompiler;
|
|
TestMaterialCompiler compiler(rawCompiler);
|
|
filamat::MaterialBuilder unused;
|
|
bool result = compiler.parseMaterialAsJSON(jsonMaterialSource.c_str(), jsonMaterialSource.size(), unused);
|
|
EXPECT_EQ(result, true);
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|