Bug 1319426 - Don't keep ANGLE shader compilers around. r=lsalzman

This will also make it easier if we want to reuse compilers/validators.

Differential Revision: https://phabricator.services.mozilla.com/D35398

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jeff Gilbert 2019-06-21 16:52:50 +00:00
Родитель ccda45f8e3
Коммит 07c032ccbd
7 изменённых файлов: 208 добавлений и 225 удалений

Просмотреть файл

@ -6,6 +6,7 @@
#ifndef WEBGLCONTEXT_H_
#define WEBGLCONTEXT_H_
#include <memory>
#include <stdarg.h>
#include "GLContextTypes.h"
@ -1507,7 +1508,8 @@ class WebGLContext : public nsICanvasRenderingContextInternal,
mutable GLenum mWebGLError;
webgl::ShaderValidator* CreateShaderValidator(GLenum shaderType) const;
std::unique_ptr<webgl::ShaderValidator> CreateShaderValidator(
GLenum shaderType) const;
// some GL constants
uint32_t mGLMaxTextureUnits = 0;

Просмотреть файл

@ -474,51 +474,46 @@ static RefPtr<const webgl::LinkedProgramInfo> QueryProgramInfo(
{
const auto& fragShader = prog->FragShader();
MOZ_RELEASE_ASSERT(fragShader);
MOZ_RELEASE_ASSERT(fragShader->Validator());
const auto& handle = fragShader->Validator()->mHandle;
const auto version = sh::GetShaderVersion(handle);
const auto& compileResults = fragShader->CompileResults();
const auto version = compileResults->mShaderVersion;
const auto fnAddInfo = [&](const webgl::FragOutputInfo& x) {
info->fragOutputs.insert({x.loc, x});
};
if (version == 300) {
const auto& fragOutputs = sh::GetOutputVariables(handle);
if (fragOutputs) {
for (const auto& cur : *fragOutputs) {
auto loc = cur.location;
if (loc == -1) loc = 0;
for (const auto& cur : compileResults->mOutputVariables) {
auto loc = cur.location;
if (loc == -1) loc = 0;
const auto info = webgl::FragOutputInfo{
uint8_t(loc), nsCString(cur.name.c_str()),
nsCString(cur.mappedName.c_str()), FragOutputBaseType(cur.type)};
if (!cur.isArray()) {
fnAddInfo(info);
continue;
}
MOZ_ASSERT(cur.arraySizes.size() == 1);
for (uint32_t i = 0; i < cur.arraySizes[0]; ++i) {
const auto indexStr = nsPrintfCString("[%u]", i);
const auto info = webgl::FragOutputInfo{
uint8_t(loc), nsCString(cur.name.c_str()),
nsCString(cur.mappedName.c_str()), FragOutputBaseType(cur.type)};
if (!cur.isArray()) {
fnAddInfo(info);
continue;
}
MOZ_ASSERT(cur.arraySizes.size() == 1);
for (uint32_t i = 0; i < cur.arraySizes[0]; ++i) {
const auto indexStr = nsPrintfCString("[%u]", i);
auto userName = info.userName;
userName.Append(indexStr);
auto mappedName = info.mappedName;
mappedName.Append(indexStr);
auto userName = info.userName;
userName.Append(indexStr);
auto mappedName = info.mappedName;
mappedName.Append(indexStr);
const auto indexedInfo = webgl::FragOutputInfo{
uint8_t(info.loc + i), userName, mappedName, info.baseType};
fnAddInfo(indexedInfo);
}
const auto indexedInfo = webgl::FragOutputInfo{
uint8_t(info.loc + i), userName, mappedName, info.baseType};
fnAddInfo(indexedInfo);
}
}
} else {
// ANGLE's translator doesn't tell us about non-user frag outputs. :(
const auto& translatedSource = fragShader->TranslatedSource();
const auto& translatedSource = compileResults->mObjectCode;
uint32_t drawBuffers = 1;
if (translatedSource.Find("(gl_FragData[1]") != -1 ||
translatedSource.Find("(webgl_FragData[1]") != -1) {
if (translatedSource.find("(gl_FragData[1]") != std::string::npos ||
translatedSource.find("(webgl_FragData[1]") != std::string::npos) {
// The matching with the leading '(' prevents cleverly-named user vars
// breaking this. Since ANGLE initializes all outputs, if this is an MRT
// shader, FragData[1] will be present. FragData[0] is valid for non-MRT
@ -536,10 +531,8 @@ static RefPtr<const webgl::LinkedProgramInfo> QueryProgramInfo(
}
const auto& vertShader = prog->VertShader();
MOZ_RELEASE_ASSERT(vertShader);
MOZ_RELEASE_ASSERT(vertShader->Validator());
const auto& handle = vertShader->Validator()->mHandle;
const auto numViews = sh::GetVertexShaderNumViews(handle);
const auto& vertCompileResults = vertShader->CompileResults();
const auto numViews = vertCompileResults->mVertexShaderNumViews;
if (numViews != -1) {
info->zLayerCount = AssertedCast<uint8_t>(numViews);
}
@ -1153,13 +1146,15 @@ bool WebGLProgram::ValidateForLink() {
mLinkLog.AssignLiteral("Must have a compiled vertex shader attached.");
return false;
}
const auto& vertInfo = *mVertShader->CompileResults();
if (!mFragShader || !mFragShader->IsCompiled()) {
mLinkLog.AssignLiteral("Must have an compiled fragment shader attached.");
return false;
}
const auto& fragInfo = *mFragShader->CompileResults();
if (!mFragShader->CanLinkTo(mVertShader, &mLinkLog)) return false;
if (!fragInfo.CanLinkTo(vertInfo, &mLinkLog)) return false;
const auto& gl = mContext->gl;

Просмотреть файл

@ -38,25 +38,6 @@ static void PrintLongString(const char* const begin, const size_t len) {
printf_stderr("%s", chunkBegin);
}
// On success, writes to out_validator and out_translatedSource.
// On failure, writes to out_translationLog.
static bool Translate(const nsACString& source,
webgl::ShaderValidator* validator,
nsACString* const out_translationLog,
nsACString* const out_translatedSource) {
if (!validator->ValidateAndTranslate(source.BeginReading())) {
const std::string& log = sh::GetInfoLog(validator->mHandle);
out_translationLog->Assign(log.data(), log.length());
return false;
}
// Success
const std::string& output = sh::GetObjectCode(validator->mHandle);
out_translatedSource->Assign(output.data(), output.length());
return true;
}
template <size_t N>
static bool SubstringStartsWith(const std::string& testStr, size_t offset,
const char (&refStr)[N]) {
@ -93,9 +74,8 @@ static void GetCompilationStatusAndLog(gl::GLContext* gl, GLuint shader,
WebGLShader::WebGLShader(WebGLContext* webgl, GLenum type)
: WebGLRefCountedObject(webgl),
mGLName(webgl->gl->fCreateShader(type)),
mType(type),
mTranslationSuccessful(false),
mCompilationSuccessful(false) {
mType(type) {
mCompileResults = std::make_unique<webgl::ShaderValidatorResults>();
mContext->mShaders.insertBack(this);
}
@ -119,41 +99,44 @@ void WebGLShader::ShaderSource(const nsAString& source) {
}
void WebGLShader::CompileShader() {
mValidator = nullptr;
mTranslationSuccessful = false;
mCompilationSuccessful = false;
gl::GLContext* gl = mContext->gl;
mValidator.reset(mContext->CreateShaderValidator(mType));
MOZ_ASSERT(mValidator);
static const bool kDumpShaders = PR_GetEnv("MOZ_WEBGL_DUMP_SHADERS");
if (MOZ_UNLIKELY(kDumpShaders)) {
printf_stderr("==== begin MOZ_WEBGL_DUMP_SHADERS ====\n");
PrintLongString(mCleanSource.BeginReading(), mCleanSource.Length());
}
const bool success = Translate(mCleanSource, mValidator.get(),
&mValidationLog, &mTranslatedSource);
{
const auto validator = mContext->CreateShaderValidator(mType);
MOZ_ASSERT(validator);
mCompileResults =
validator->ValidateAndTranslate(mCleanSource.BeginReading());
}
mCompilationLog = mCompileResults->mInfoLog.c_str();
const auto& success = mCompileResults->mValid;
if (MOZ_UNLIKELY(kDumpShaders)) {
printf_stderr("\n==== \\/ \\/ \\/ ====\n");
if (success) {
PrintLongString(mTranslatedSource.BeginReading(),
mTranslatedSource.Length());
const auto& translated = mCompileResults->mObjectCode;
PrintLongString(translated.data(), translated.length());
} else {
printf_stderr("Validation failed:\n%s", mValidationLog.BeginReading());
printf_stderr("Validation failed:\n%s",
mCompileResults->mInfoLog.c_str());
}
printf_stderr("\n==== end ====\n");
}
if (!success) return;
mTranslationSuccessful = true;
const char* const parts[] = {mTranslatedSource.BeginReading()};
gl->fShaderSource(mGLName, ArrayLength(parts), parts, nullptr);
const std::array<const char*, 1> parts = {
mCompileResults->mObjectCode.c_str()};
gl->fShaderSource(mGLName, parts.size(), parts.data(), nullptr);
gl->fCompileShader(mGLName);
@ -161,10 +144,8 @@ void WebGLShader::CompileShader() {
&mCompilationLog);
}
void WebGLShader::GetShaderInfoLog(nsAString* out) const {
const nsCString& log =
!mTranslationSuccessful ? mValidationLog : mCompilationLog;
CopyASCIItoUTF16(log, *out);
void WebGLShader::GetShaderInfoLog(nsAString* const out) const {
CopyASCIItoUTF16(mCompilationLog, *out);
}
JS::Value WebGLShader::GetShaderParameter(GLenum pname) const {
@ -191,20 +172,16 @@ void WebGLShader::GetShaderSource(nsAString* out) const {
void WebGLShader::GetShaderTranslatedSource(nsAString* out) const {
out->SetIsVoid(false);
CopyASCIItoUTF16(mTranslatedSource, *out);
const auto& wrapper =
nsDependentCString(mCompileResults->mObjectCode.c_str());
CopyASCIItoUTF16(wrapper, *out);
}
////////////////////////////////////////////////////////////////////////////////
bool WebGLShader::CanLinkTo(const WebGLShader* prev,
nsCString* const out_log) const {
return mValidator->CanLinkTo(prev->mValidator.get(), out_log);
}
size_t WebGLShader::CalcNumSamplerUniforms() const {
const auto& uniforms = *sh::GetUniforms(mValidator->mHandle);
size_t accum = 0;
for (const auto& cur : uniforms) {
for (const auto& cur : mCompileResults->mUniforms) {
const auto& type = cur.type;
if (type == LOCAL_GL_SAMPLER_2D || type == LOCAL_GL_SAMPLER_CUBE) {
accum += cur.getArraySizeProduct();
@ -214,13 +191,12 @@ size_t WebGLShader::CalcNumSamplerUniforms() const {
}
size_t WebGLShader::NumAttributes() const {
return sh::GetAttributes(mValidator->mHandle)->size();
return mCompileResults->mAttributes.size();
}
void WebGLShader::BindAttribLocation(GLuint prog, const std::string& userName,
GLuint index) const {
const auto& attribs = *sh::GetAttributes(mValidator->mHandle);
for (const auto& attrib : attribs) {
for (const auto& attrib : mCompileResults->mAttributes) {
if (attrib.name == userName) {
mContext->gl->fBindAttribLocation(prog, index, attrib.mappedName.c_str());
return;
@ -232,8 +208,7 @@ bool WebGLShader::FindAttribUserNameByMappedName(
const nsACString& mappedName, nsCString* const out_userName) const {
const std::string mappedNameStr(mappedName.BeginReading());
const auto& attribs = *sh::GetAttributes(mValidator->mHandle);
for (const auto& cur : attribs) {
for (const auto& cur : mCompileResults->mAttributes) {
if (cur.mappedName == mappedNameStr) {
*out_userName = cur.name.c_str();
return true;
@ -247,8 +222,7 @@ bool WebGLShader::FindVaryingByMappedName(const nsACString& mappedName,
bool* const out_isArray) const {
const std::string mappedNameStr(mappedName.BeginReading());
const auto& varyings = *sh::GetVaryings(mValidator->mHandle);
for (const auto& cur : varyings) {
for (const auto& cur : mCompileResults->mVaryings) {
const sh::ShaderVariable* found;
std::string userName;
if (!cur.findInfoByMappedName(mappedNameStr, &found, &userName)) continue;
@ -267,8 +241,8 @@ bool WebGLShader::FindUniformByMappedName(const nsACString& mappedName,
const std::string mappedNameStr(mappedName.BeginReading(),
mappedName.Length());
std::string userNameStr;
if (!mValidator->FindUniformByMappedName(mappedNameStr, &userNameStr,
out_isArray))
if (!mCompileResults->FindUniformByMappedName(mappedNameStr, &userNameStr,
out_isArray))
return false;
*out_userName = userNameStr.c_str();
@ -277,8 +251,7 @@ bool WebGLShader::FindUniformByMappedName(const nsACString& mappedName,
bool WebGLShader::UnmapUniformBlockName(
const nsACString& baseMappedName, nsCString* const out_baseUserName) const {
const auto& interfaces = *sh::GetInterfaceBlocks(mValidator->mHandle);
for (const auto& interface : interfaces) {
for (const auto& interface : mCompileResults->mInterfaceBlocks) {
const nsDependentCString interfaceMappedName(interface.mappedName.data(),
interface.mappedName.size());
if (baseMappedName == interfaceMappedName) {
@ -299,7 +272,7 @@ void WebGLShader::MapTransformFeedbackVaryings(
out_mappedVaryings->clear();
out_mappedVaryings->reserve(varyings.size());
const auto& shaderVaryings = *sh::GetVaryings(mValidator->mHandle);
const auto& shaderVaryings = mCompileResults->mVaryings;
for (const auto& wideUserName : varyings) {
const NS_LossyConvertUTF16toASCII mozUserName(
@ -326,13 +299,10 @@ JSObject* WebGLShader::WrapObject(JSContext* js,
}
size_t WebGLShader::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const {
size_t validatorSize = mValidator ? mallocSizeOf(mValidator.get()) : 0;
return mallocSizeOf(this) +
mSource.SizeOfExcludingThisIfUnshared(mallocSizeOf) +
mCleanSource.SizeOfExcludingThisIfUnshared(mallocSizeOf) +
validatorSize +
mValidationLog.SizeOfExcludingThisIfUnshared(mallocSizeOf) +
mTranslatedSource.SizeOfExcludingThisIfUnshared(mallocSizeOf) +
mCompileResults->SizeOfIncludingThis(mallocSizeOf) +
mCompilationLog.SizeOfExcludingThisIfUnshared(mallocSizeOf);
}

Просмотреть файл

@ -7,6 +7,7 @@
#define WEBGL_SHADER_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
@ -21,7 +22,7 @@
namespace mozilla {
namespace webgl {
class ShaderValidator;
class ShaderValidatorResults;
} // namespace webgl
class WebGLShader final : public nsWrapperCache,
@ -46,7 +47,6 @@ class WebGLShader final : public nsWrapperCache,
void ShaderSource(const nsAString& source);
// Util funcs
bool CanLinkTo(const WebGLShader* prev, nsCString* const out_log) const;
size_t CalcNumSamplerUniforms() const;
size_t NumAttributes() const;
bool FindAttribUserNameByMappedName(const nsACString& mappedName,
@ -60,11 +60,8 @@ class WebGLShader final : public nsWrapperCache,
bool UnmapUniformBlockName(const nsACString& baseMappedName,
nsCString* const out_baseUserName) const;
bool IsCompiled() const {
return mTranslationSuccessful && mCompilationSuccessful;
}
const auto* Validator() const { return mValidator.get(); }
const auto& TranslatedSource() const { return mTranslatedSource; }
bool IsCompiled() const { return mCompilationSuccessful; }
const auto& CompileResults() const { return mCompileResults; }
private:
void BindAttribLocation(GLuint prog, const std::string& userName,
@ -94,12 +91,9 @@ class WebGLShader final : public nsWrapperCache,
nsString mSource;
nsCString mCleanSource;
UniquePtr<webgl::ShaderValidator> mValidator;
nsCString mValidationLog;
bool mTranslationSuccessful;
nsCString mTranslatedSource;
bool mCompilationSuccessful;
std::unique_ptr<const webgl::ShaderValidatorResults>
mCompileResults; // Never null.
bool mCompilationSuccessful = false;
nsCString mCompilationLog;
};

Просмотреть файл

@ -139,7 +139,7 @@ static ShShaderOutput ShaderOutput(gl::GLContext* gl) {
return SH_GLSL_COMPATIBILITY_OUTPUT;
}
webgl::ShaderValidator* WebGLContext::CreateShaderValidator(
std::unique_ptr<webgl::ShaderValidator> WebGLContext::CreateShaderValidator(
GLenum shaderType) const {
const auto spec = (IsWebGL2() ? SH_WEBGL2_SPEC : SH_WEBGL_SPEC);
const auto outputLanguage = ShaderOutput(gl);
@ -212,27 +212,46 @@ webgl::ShaderValidator* WebGLContext::CreateShaderValidator(
namespace webgl {
/*static*/
ShaderValidator* ShaderValidator::Create(GLenum shaderType, ShShaderSpec spec,
ShShaderOutput outputLanguage,
const ShBuiltInResources& resources,
ShCompileOptions compileOptions) {
std::unique_ptr<ShaderValidator> ShaderValidator::Create(
GLenum shaderType, ShShaderSpec spec, ShShaderOutput outputLanguage,
const ShBuiltInResources& resources, ShCompileOptions compileOptions) {
ShHandle handle =
sh::ConstructCompiler(shaderType, spec, outputLanguage, &resources);
MOZ_RELEASE_ASSERT(handle);
if (!handle) return nullptr;
return new ShaderValidator(handle, compileOptions,
resources.MaxVaryingVectors);
return std::unique_ptr<ShaderValidator>(
new ShaderValidator(handle, compileOptions, resources.MaxVaryingVectors));
}
ShaderValidator::~ShaderValidator() { sh::Destruct(mHandle); }
bool ShaderValidator::ValidateAndTranslate(const char* source) {
MOZ_ASSERT(!mHasRun);
mHasRun = true;
std::unique_ptr<const ShaderValidatorResults>
ShaderValidator::ValidateAndTranslate(const char* const source) const {
auto ret = std::make_unique<ShaderValidatorResults>();
const char* const parts[] = {source};
return sh::Compile(mHandle, parts, ArrayLength(parts), mCompileOptions);
const std::array<const char*, 1> parts = {source};
ret->mValid =
sh::Compile(mHandle, parts.data(), parts.size(), mCompileOptions);
ret->mInfoLog = sh::GetInfoLog(mHandle);
if (ret->mValid) {
ret->mObjectCode = sh::GetObjectCode(mHandle);
ret->mShaderVersion = sh::GetShaderVersion(mHandle);
ret->mVertexShaderNumViews = sh::GetVertexShaderNumViews(mHandle);
ret->mAttributes = *sh::GetAttributes(mHandle);
ret->mInterfaceBlocks = *sh::GetInterfaceBlocks(mHandle);
ret->mOutputVariables = *sh::GetOutputVariables(mHandle);
ret->mUniforms = *sh::GetUniforms(mHandle);
ret->mVaryings = *sh::GetVaryings(mHandle);
ret->mMaxVaryingVectors = mMaxVaryingVectors;
}
sh::ClearResults(mHandle);
return ret;
}
template <size_t N>
@ -240,91 +259,58 @@ static bool StartsWith(const std::string& haystack, const char (&needle)[N]) {
return haystack.compare(0, N - 1, needle) == 0;
}
bool ShaderValidator::CanLinkTo(const ShaderValidator* prev,
nsCString* const out_log) const {
if (!prev) {
nsPrintfCString error("Passed in NULL prev ShaderValidator.");
*out_log = error;
return false;
}
bool ShaderValidatorResults::CanLinkTo(const ShaderValidatorResults& vert,
nsCString* const out_log) const {
MOZ_ASSERT(mValid);
MOZ_ASSERT(vert.mValid);
const auto shaderVersion = sh::GetShaderVersion(mHandle);
if (sh::GetShaderVersion(prev->mHandle) != shaderVersion) {
if (vert.mShaderVersion != mShaderVersion) {
nsPrintfCString error(
"Vertex shader version %d does not match"
" fragment shader version %d.",
sh::GetShaderVersion(prev->mHandle), sh::GetShaderVersion(mHandle));
vert.mShaderVersion, mShaderVersion);
*out_log = error;
return false;
}
{
const std::vector<sh::Uniform>* vertPtr = sh::GetUniforms(prev->mHandle);
const std::vector<sh::Uniform>* fragPtr = sh::GetUniforms(mHandle);
if (!vertPtr || !fragPtr) {
nsPrintfCString error("Could not create uniform list.");
*out_log = error;
return false;
}
for (const auto& itrFrag : mUniforms) {
for (const auto& itrVert : vert.mUniforms) {
if (itrVert.name != itrFrag.name) continue;
for (auto itrFrag = fragPtr->begin(); itrFrag != fragPtr->end();
++itrFrag) {
for (auto itrVert = vertPtr->begin(); itrVert != vertPtr->end();
++itrVert) {
if (itrVert->name != itrFrag->name) continue;
if (!itrVert->isSameUniformAtLinkTime(*itrFrag)) {
nsPrintfCString error(
"Uniform `%s` is not linkable between"
" attached shaders.",
itrFrag->name.c_str());
*out_log = error;
return false;
}
break;
if (!itrVert.isSameUniformAtLinkTime(itrFrag)) {
nsPrintfCString error(
"Uniform `%s` is not linkable between"
" attached shaders.",
itrFrag.name.c_str());
*out_log = error;
return false;
}
}
}
{
const auto vertVars = sh::GetInterfaceBlocks(prev->mHandle);
const auto fragVars = sh::GetInterfaceBlocks(mHandle);
if (!vertVars || !fragVars) {
nsPrintfCString error("Could not create uniform block list.");
*out_log = error;
return false;
}
for (const auto& fragVar : *fragVars) {
for (const auto& vertVar : *vertVars) {
if (vertVar.name != fragVar.name) continue;
if (!vertVar.isSameInterfaceBlockAtLinkTime(fragVar)) {
nsPrintfCString error(
"Interface block `%s` is not linkable between"
" attached shaders.",
fragVar.name.c_str());
*out_log = error;
return false;
}
break;
}
break;
}
}
const auto& vertVaryings = sh::GetVaryings(prev->mHandle);
const auto& fragVaryings = sh::GetVaryings(mHandle);
if (!vertVaryings || !fragVaryings) {
nsPrintfCString error("Could not create varying list.");
*out_log = error;
return false;
for (const auto& fragVar : mInterfaceBlocks) {
for (const auto& vertVar : vert.mInterfaceBlocks) {
if (vertVar.name != fragVar.name) continue;
if (!vertVar.isSameInterfaceBlockAtLinkTime(fragVar)) {
nsPrintfCString error(
"Interface block `%s` is not linkable between"
" attached shaders.",
fragVar.name.c_str());
*out_log = error;
return false;
}
break;
}
}
{
std::vector<sh::ShaderVariable> staticUseVaryingList;
for (const auto& fragVarying : *fragVaryings) {
for (const auto& fragVarying : mVaryings) {
static const char prefix[] = "gl_";
if (StartsWith(fragVarying.name, prefix)) {
if (fragVarying.staticUse) {
@ -336,10 +322,10 @@ bool ShaderValidator::CanLinkTo(const ShaderValidator* prev,
bool definedInVertShader = false;
bool staticVertUse = false;
for (const auto& vertVarying : *vertVaryings) {
for (const auto& vertVarying : vert.mVaryings) {
if (vertVarying.name != fragVarying.name) continue;
if (!vertVarying.isSameVaryingAtLinkTime(fragVarying, shaderVersion)) {
if (!vertVarying.isSameVaryingAtLinkTime(fragVarying, mShaderVersion)) {
nsPrintfCString error(
"Varying `%s`is not linkable between"
" attached shaders.",
@ -377,14 +363,14 @@ bool ShaderValidator::CanLinkTo(const ShaderValidator* prev,
}
}
if (shaderVersion == 100) {
if (mShaderVersion == 100) {
// Enforce ESSL1 invariant linking rules.
bool isInvariant_Position = false;
bool isInvariant_PointSize = false;
bool isInvariant_FragCoord = false;
bool isInvariant_PointCoord = false;
for (const auto& varying : *vertVaryings) {
for (const auto& varying : vert.mVaryings) {
if (varying.name == "gl_Position") {
isInvariant_Position = varying.isInvariant;
} else if (varying.name == "gl_PointSize") {
@ -392,7 +378,7 @@ bool ShaderValidator::CanLinkTo(const ShaderValidator* prev,
}
}
for (const auto& varying : *fragVaryings) {
for (const auto& varying : mVaryings) {
if (varying.name == "gl_FragCoord") {
isInvariant_FragCoord = varying.isInvariant;
} else if (varying.name == "gl_PointCoord") {
@ -428,13 +414,12 @@ bool ShaderValidator::CanLinkTo(const ShaderValidator* prev,
}
// This must handle names like "foo.bar[0]".
bool ShaderValidator::FindUniformByMappedName(const std::string& mappedName,
std::string* const out_userName,
bool* const out_isArray) const {
const std::vector<sh::Uniform>& uniforms = *sh::GetUniforms(mHandle);
for (auto itr = uniforms.begin(); itr != uniforms.end(); ++itr) {
bool ShaderValidatorResults::FindUniformByMappedName(
const std::string& mappedName, std::string* const out_userName,
bool* const out_isArray) const {
for (const auto& cur : mUniforms) {
const sh::ShaderVariable* found;
if (!itr->findInfoByMappedName(mappedName, &found, out_userName)) continue;
if (!cur.findInfoByMappedName(mappedName, &found, out_userName)) continue;
*out_isArray = found->isArray();
return true;
@ -442,9 +427,7 @@ bool ShaderValidator::FindUniformByMappedName(const std::string& mappedName,
const size_t dotPos = mappedName.find(".");
const std::vector<sh::InterfaceBlock>& interfaces =
*sh::GetInterfaceBlocks(mHandle);
for (const auto& interface : interfaces) {
for (const auto& interface : mInterfaceBlocks) {
std::string mappedFieldName;
const bool hasInstanceName = !interface.instanceName.empty();
@ -483,5 +466,30 @@ bool ShaderValidator::FindUniformByMappedName(const std::string& mappedName,
return false;
}
size_t ShaderValidatorResults::SizeOfIncludingThis(
const MallocSizeOf fnSizeOf) const {
auto ret = fnSizeOf(this);
ret += mInfoLog.size();
ret += mObjectCode.size();
for (const auto& cur : mAttributes) {
ret += fnSizeOf(&cur);
}
for (const auto& cur : mInterfaceBlocks) {
ret += fnSizeOf(&cur);
}
for (const auto& cur : mOutputVariables) {
ret += fnSizeOf(&cur);
}
for (const auto& cur : mUniforms) {
ret += fnSizeOf(&cur);
}
for (const auto& cur : mVaryings) {
ret += fnSizeOf(&cur);
}
return ret;
}
} // namespace webgl
} // namespace mozilla

Просмотреть файл

@ -15,6 +15,31 @@
namespace mozilla {
namespace webgl {
class ShaderValidatorResults final {
public:
std::string mInfoLog;
bool mValid = false;
std::string mObjectCode;
int mShaderVersion = 0;
int mVertexShaderNumViews = 0;
std::vector<sh::Attribute> mAttributes;
std::vector<sh::InterfaceBlock> mInterfaceBlocks;
std::vector<sh::OutputVariable> mOutputVariables;
std::vector<sh::Uniform> mUniforms;
std::vector<sh::Varying> mVaryings;
int mMaxVaryingVectors = 0;
bool CanLinkTo(const ShaderValidatorResults& vert,
nsCString* const out_log) const;
bool FindUniformByMappedName(const std::string& mappedName,
std::string* const out_userName,
bool* const out_isArray) const;
size_t SizeOfIncludingThis(MallocSizeOf) const;
};
class ShaderValidator final {
public:
const ShHandle mHandle;
@ -22,36 +47,24 @@ class ShaderValidator final {
private:
const ShCompileOptions mCompileOptions;
const int mMaxVaryingVectors;
bool mHasRun;
public:
static ShaderValidator* Create(GLenum shaderType, ShShaderSpec spec,
ShShaderOutput outputLanguage,
const ShBuiltInResources& resources,
ShCompileOptions compileOptions);
static std::unique_ptr<ShaderValidator> Create(
GLenum shaderType, ShShaderSpec spec, ShShaderOutput outputLanguage,
const ShBuiltInResources& resources, ShCompileOptions compileOptions);
private:
ShaderValidator(ShHandle handle, ShCompileOptions compileOptions,
int maxVaryingVectors)
: mHandle(handle),
mCompileOptions(compileOptions),
mMaxVaryingVectors(maxVaryingVectors),
mHasRun(false) {}
mMaxVaryingVectors(maxVaryingVectors) {}
public:
~ShaderValidator();
bool ValidateAndTranslate(const char* source);
bool CanLinkTo(const ShaderValidator* prev, nsCString* const out_log) const;
bool FindUniformByMappedName(const std::string& mappedName,
std::string* const out_userName,
bool* const out_isArray) const;
bool ValidateTransformFeedback(
const std::vector<nsString>& userNames, uint32_t maxComponents,
nsCString* const out_errorText,
std::vector<std::string>* const out_mappedNames);
std::unique_ptr<const ShaderValidatorResults> ValidateAndTranslate(
const char*) const;
};
} // namespace webgl

Просмотреть файл

@ -1921,8 +1921,9 @@ static bool ValidateCopyTexImageForFeedback(const WebGLContext& webgl,
}
static bool DoCopyTexOrSubImage(WebGLContext* webgl, bool isSubImage,
WebGLTexture* const tex, const TexImageTarget target,
GLint level, GLint xWithinSrc, GLint yWithinSrc,
WebGLTexture* const tex,
const TexImageTarget target, GLint level,
GLint xWithinSrc, GLint yWithinSrc,
uint32_t srcTotalWidth, uint32_t srcTotalHeight,
const webgl::FormatUsageInfo* srcUsage,
GLint xOffset, GLint yOffset, GLint zOffset,