Commit 0982a2bf by Olli Etuaho Committed by Commit Bot

Prefix internal names in GLSL output

Prefixing internal names will avoid clashes with user-defined names. We use prefix webgl_angle_ so that the internal names are both reserved in WebGL on one hand and clearly separated from hashed names starting with just webgl_ on the other hand. BUG=angleproject:1597 TEST=WebGL conformance tests Change-Id: I7deef9c1a38105c8b57eda13c84eec13e515a91a Reviewed-on: https://chromium-review.googlesource.com/406247Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 21b786b1
...@@ -237,9 +237,8 @@ void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence &args) ...@@ -237,9 +237,8 @@ void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence &args)
const TType &type = arg->getType(); const TType &type = arg->getType();
writeVariableType(type); writeVariableType(type);
const TString &name = arg->getSymbol(); if (!arg->getName().getString().empty())
if (!name.empty()) out << " " << hashName(arg->getName());
out << " " << hashName(name);
if (type.isArray()) if (type.isArray())
out << arrayBrackets(type); out << arrayBrackets(type);
...@@ -257,7 +256,7 @@ const TConstantUnion *TOutputGLSLBase::writeConstantUnion( ...@@ -257,7 +256,7 @@ const TConstantUnion *TOutputGLSLBase::writeConstantUnion(
if (type.getBasicType() == EbtStruct) if (type.getBasicType() == EbtStruct)
{ {
const TStructure *structure = type.getStruct(); const TStructure *structure = type.getStruct();
out << hashName(structure->name()) << "("; out << hashName(TName(structure->name())) << "(";
const TFieldList &fields = structure->fields(); const TFieldList &fields = structure->fields();
for (size_t i = 0; i < fields.size(); ++i) for (size_t i = 0; i < fields.size(); ++i)
...@@ -331,7 +330,7 @@ void TOutputGLSLBase::visitSymbol(TIntermSymbol *node) ...@@ -331,7 +330,7 @@ void TOutputGLSLBase::visitSymbol(TIntermSymbol *node)
if (mLoopUnrollStack.needsToReplaceSymbolWithValue(node)) if (mLoopUnrollStack.needsToReplaceSymbolWithValue(node))
out << mLoopUnrollStack.getLoopIndexValue(node); out << mLoopUnrollStack.getLoopIndexValue(node);
else else
out << hashVariableName(node->getSymbol()); out << hashVariableName(node->getName());
if (mDeclaringVariables && node->getType().isArray()) if (mDeclaringVariables && node->getType().isArray())
out << arrayBrackets(node->getType()); out << arrayBrackets(node->getType());
...@@ -464,7 +463,7 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node) ...@@ -464,7 +463,7 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
TString fieldName = field->name(); TString fieldName = field->name();
if (!mSymbolTable.findBuiltIn(structure->name(), mShaderVersion)) if (!mSymbolTable.findBuiltIn(structure->name(), mShaderVersion))
fieldName = hashName(fieldName); fieldName = hashName(TName(fieldName));
out << fieldName; out << fieldName;
visitChildren = false; visitChildren = false;
...@@ -481,7 +480,7 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node) ...@@ -481,7 +480,7 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
TString fieldName = field->name(); TString fieldName = field->name();
ASSERT(!mSymbolTable.findBuiltIn(interfaceBlock->name(), mShaderVersion)); ASSERT(!mSymbolTable.findBuiltIn(interfaceBlock->name(), mShaderVersion));
fieldName = hashName(fieldName); fieldName = hashName(TName(fieldName));
out << fieldName; out << fieldName;
visitChildren = false; visitChildren = false;
...@@ -928,7 +927,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -928,7 +927,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
ASSERT(sequence && sequence->size() == 1); ASSERT(sequence && sequence->size() == 1);
const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode(); const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode();
ASSERT(symbol); ASSERT(symbol);
out << "invariant " << hashVariableName(symbol->getSymbol()); out << "invariant " << hashVariableName(symbol->getName());
} }
visitChildren = false; visitChildren = false;
break; break;
...@@ -1104,7 +1103,7 @@ bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node) ...@@ -1104,7 +1103,7 @@ bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node)
TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence(); TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence();
TIntermSymbol *indexSymbol = TIntermSymbol *indexSymbol =
(*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode(); (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
TString name = hashVariableName(indexSymbol->getSymbol()); TString name = hashVariableName(indexSymbol->getName());
out << "for (int " << name << " = 0; " out << "for (int " << name << " = 0; "
<< name << " < 1; " << name << " < 1; "
<< "++" << name << ")\n"; << "++" << name << ")\n";
...@@ -1192,27 +1191,43 @@ void TOutputGLSLBase::visitCodeBlock(TIntermBlock *node) ...@@ -1192,27 +1191,43 @@ void TOutputGLSLBase::visitCodeBlock(TIntermBlock *node)
TString TOutputGLSLBase::getTypeName(const TType &type) TString TOutputGLSLBase::getTypeName(const TType &type)
{ {
if (type.getBasicType() == EbtStruct) if (type.getBasicType() == EbtStruct)
return hashName(type.getStruct()->name()); return hashName(TName(type.getStruct()->name()));
else else
return type.getBuiltInTypeNameString(); return type.getBuiltInTypeNameString();
} }
TString TOutputGLSLBase::hashName(const TString &name) TString TOutputGLSLBase::hashName(const TName &name)
{ {
if (mHashFunction == NULL || name.empty()) if (name.getString().empty())
return name; {
NameMap::const_iterator it = mNameMap.find(name.c_str()); ASSERT(!name.isInternal());
return name.getString();
}
if (name.isInternal())
{
// TODO(oetuaho): Would be nicer to prefix non-internal names with "_" instead, like is
// done in the HLSL output, but that requires fairly complex changes elsewhere in the code
// as well.
// We need to use a prefix that is reserved in WebGL in order to guarantee that the internal
// names don't conflict with user-defined names from WebGL.
return "webgl_angle_" + name.getString();
}
if (mHashFunction == nullptr)
{
return name.getString();
}
NameMap::const_iterator it = mNameMap.find(name.getString().c_str());
if (it != mNameMap.end()) if (it != mNameMap.end())
return it->second.c_str(); return it->second.c_str();
TString hashedName = TIntermTraverser::hash(name, mHashFunction); TString hashedName = TIntermTraverser::hash(name.getString(), mHashFunction);
mNameMap[name.c_str()] = hashedName.c_str(); mNameMap[name.getString().c_str()] = hashedName.c_str();
return hashedName; return hashedName;
} }
TString TOutputGLSLBase::hashVariableName(const TString &name) TString TOutputGLSLBase::hashVariableName(const TName &name)
{ {
if (mSymbolTable.findBuiltIn(name, mShaderVersion) != NULL) if (mSymbolTable.findBuiltIn(name.getString(), mShaderVersion) != NULL)
return name; return name.getString();
return hashName(name); return hashName(name);
} }
...@@ -1223,9 +1238,16 @@ TString TOutputGLSLBase::hashFunctionNameIfNeeded(const TName &mangledName) ...@@ -1223,9 +1238,16 @@ TString TOutputGLSLBase::hashFunctionNameIfNeeded(const TName &mangledName)
if (mSymbolTable.findBuiltIn(mangledStr, mShaderVersion) != nullptr || name == "main") if (mSymbolTable.findBuiltIn(mangledStr, mShaderVersion) != nullptr || name == "main")
return translateTextureFunction(name); return translateTextureFunction(name);
if (mangledName.isInternal()) if (mangledName.isInternal())
{
// Internal function names are outputted as-is - they may refer to functions manually added
// to the output shader source that are not included in the AST at all.
return name; return name;
}
else else
return hashName(name); {
TName nameObj(name);
return hashName(nameObj);
}
} }
bool TOutputGLSLBase::structDeclared(const TStructure *structure) const bool TOutputGLSLBase::structDeclared(const TStructure *structure) const
...@@ -1243,14 +1265,14 @@ void TOutputGLSLBase::declareStruct(const TStructure *structure) ...@@ -1243,14 +1265,14 @@ void TOutputGLSLBase::declareStruct(const TStructure *structure)
{ {
TInfoSinkBase &out = objSink(); TInfoSinkBase &out = objSink();
out << "struct " << hashName(structure->name()) << "{\n"; out << "struct " << hashName(TName(structure->name())) << "{\n";
const TFieldList &fields = structure->fields(); const TFieldList &fields = structure->fields();
for (size_t i = 0; i < fields.size(); ++i) for (size_t i = 0; i < fields.size(); ++i)
{ {
const TField *field = fields[i]; const TField *field = fields[i];
if (writeVariablePrecision(field->type()->getPrecision())) if (writeVariablePrecision(field->type()->getPrecision()))
out << " "; out << " ";
out << getTypeName(*field->type()) << " " << hashName(field->name()); out << getTypeName(*field->type()) << " " << hashName(TName(field->name()));
if (field->type()->isArray()) if (field->type()->isArray())
out << arrayBrackets(*field->type()); out << arrayBrackets(*field->type());
out << ";\n"; out << ";\n";
...@@ -1311,14 +1333,14 @@ void TOutputGLSLBase::declareInterfaceBlock(const TInterfaceBlock *interfaceBloc ...@@ -1311,14 +1333,14 @@ void TOutputGLSLBase::declareInterfaceBlock(const TInterfaceBlock *interfaceBloc
{ {
TInfoSinkBase &out = objSink(); TInfoSinkBase &out = objSink();
out << hashName(interfaceBlock->name()) << "{\n"; out << hashName(TName(interfaceBlock->name())) << "{\n";
const TFieldList &fields = interfaceBlock->fields(); const TFieldList &fields = interfaceBlock->fields();
for (size_t i = 0; i < fields.size(); ++i) for (size_t i = 0; i < fields.size(); ++i)
{ {
const TField *field = fields[i]; const TField *field = fields[i];
if (writeVariablePrecision(field->type()->getPrecision())) if (writeVariablePrecision(field->type()->getPrecision()))
out << " "; out << " ";
out << getTypeName(*field->type()) << " " << hashName(field->name()); out << getTypeName(*field->type()) << " " << hashName(TName(field->name()));
if (field->type()->isArray()) if (field->type()->isArray())
out << arrayBrackets(*field->type()); out << arrayBrackets(*field->type());
out << ";\n"; out << ";\n";
......
...@@ -61,9 +61,9 @@ class TOutputGLSLBase : public TIntermTraverser ...@@ -61,9 +61,9 @@ class TOutputGLSLBase : public TIntermTraverser
// Return the original name if hash function pointer is NULL; // Return the original name if hash function pointer is NULL;
// otherwise return the hashed name. // otherwise return the hashed name.
TString hashName(const TString &name); TString hashName(const TName &name);
// Same as hashName(), but without hashing built-in variables. // Same as hashName(), but without hashing built-in variables.
TString hashVariableName(const TString &name); TString hashVariableName(const TName &name);
// Same as hashName(), but without hashing built-in functions and with unmangling. // Same as hashName(), but without hashing built-in functions and with unmangling.
TString hashFunctionNameIfNeeded(const TName &mangledName); TString hashFunctionNameIfNeeded(const TName &mangledName);
// Used to translate function names for differences between ESSL and GLSL // Used to translate function names for differences between ESSL and GLSL
......
...@@ -31,7 +31,7 @@ TEST_F(RecordConstantPrecisionTest, HigherPrecisionConstantAsParameter) ...@@ -31,7 +31,7 @@ TEST_F(RecordConstantPrecisionTest, HigherPrecisionConstantAsParameter)
" gl_FragColor = vec4(b);\n" " gl_FragColor = vec4(b);\n"
"}\n"; "}\n";
compile(shaderString); compile(shaderString);
ASSERT_TRUE(foundInCode("const highp float s")); ASSERT_TRUE(foundInCode("const highp float webgl_angle_s"));
ASSERT_FALSE(foundInCode("fract(4096.5")); ASSERT_FALSE(foundInCode("fract(4096.5"));
ASSERT_FALSE(foundInCode("fract((4096.5")); ASSERT_FALSE(foundInCode("fract((4096.5"));
} }
...@@ -49,7 +49,7 @@ TEST_F(RecordConstantPrecisionTest, EqualPrecisionConstantAsParameter) ...@@ -49,7 +49,7 @@ TEST_F(RecordConstantPrecisionTest, EqualPrecisionConstantAsParameter)
" gl_FragColor = vec4(b);\n" " gl_FragColor = vec4(b);\n"
"}\n"; "}\n";
compile(shaderString); compile(shaderString);
ASSERT_FALSE(foundInCode("const mediump float s")); ASSERT_FALSE(foundInCode("const mediump float webgl_angle_s"));
ASSERT_TRUE(foundInCode("fract((4096.5")); ASSERT_TRUE(foundInCode("fract((4096.5"));
} }
...@@ -67,7 +67,7 @@ TEST_F(RecordConstantPrecisionTest, FoldedBinaryConstantPrecisionIsHigher) ...@@ -67,7 +67,7 @@ TEST_F(RecordConstantPrecisionTest, FoldedBinaryConstantPrecisionIsHigher)
" gl_FragColor = vec4(b);\n" " gl_FragColor = vec4(b);\n"
"}\n"; "}\n";
compile(shaderString); compile(shaderString);
ASSERT_TRUE(foundInCode("const highp float s")); ASSERT_TRUE(foundInCode("const highp float webgl_angle_s"));
ASSERT_FALSE(foundInCode("fract(4096.5")); ASSERT_FALSE(foundInCode("fract(4096.5"));
ASSERT_FALSE(foundInCode("fract((4096.5")); ASSERT_FALSE(foundInCode("fract((4096.5"));
} }
...@@ -87,7 +87,7 @@ TEST_F(RecordConstantPrecisionTest, FoldedUnaryConstantPrecisionIsHigher) ...@@ -87,7 +87,7 @@ TEST_F(RecordConstantPrecisionTest, FoldedUnaryConstantPrecisionIsHigher)
" gl_FragColor = vec4(b);\n" " gl_FragColor = vec4(b);\n"
"}\n"; "}\n";
compile(shaderString); compile(shaderString);
ASSERT_TRUE(foundInCode("const highp float s")); ASSERT_TRUE(foundInCode("const highp float webgl_angle_s"));
ASSERT_FALSE(foundInCode("sin(0.5")); ASSERT_FALSE(foundInCode("sin(0.5"));
ASSERT_FALSE(foundInCode("sin((0.5")); ASSERT_FALSE(foundInCode("sin((0.5"));
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment