diff --git a/dom/canvas/WebGLShaderValidator.cpp b/dom/canvas/WebGLShaderValidator.cpp index d7786a9493ee..989c150cac28 100644 --- a/dom/canvas/WebGLShaderValidator.cpp +++ b/dom/canvas/WebGLShaderValidator.cpp @@ -474,14 +474,44 @@ ShaderValidator::FindUniformByMappedName(const std::string& mappedName, return true; } + const size_t dotPos = mappedName.find("."); + const std::vector& interfaces = *ShGetInterfaceBlocks(mHandle); for (const auto& interface : interfaces) { + + std::string mappedFieldName; + const bool hasInstanceName = !interface.instanceName.empty(); + + // If the InterfaceBlock has an instanceName, all variables defined + // within the block are qualified with the block name, as opposed + // to being placed in the global scope. + if (hasInstanceName) { + + // If mappedName has no block name prefix, skip + if (std::string::npos == dotPos) + continue; + + // If mappedName has a block name prefix that doesn't match, skip + const std::string mappedInterfaceBlockName = mappedName.substr(0, dotPos); + if (interface.mappedName != mappedInterfaceBlockName) + continue; + + mappedFieldName = mappedName.substr(dotPos + 1); + } else { + mappedFieldName = mappedName; + } + for (const auto& field : interface.fields) { const sh::ShaderVariable* found; - if (!field.findInfoByMappedName(mappedName, &found, out_userName)) + if (!field.findInfoByMappedName(mappedFieldName, &found, out_userName)) continue; + if (hasInstanceName) { + // Prepend the user name of the interface that matched + *out_userName = interface.name + "." + *out_userName; + } + *out_isArray = found->isArray(); return true; }