--- a/dom/canvas/WebGLProgram.cpp
+++ b/dom/canvas/WebGLProgram.cpp
@@ -167,17 +167,17 @@ webgl::UniformInfo::UniformInfo(WebGLAct
{
if (mSamplerTexList) {
mSamplerValues.assign(mActiveInfo->mElemCount, 0);
}
}
//////////
-//#define DUMP_SHADERVAR_MAPPINGS
+#define DUMP_SHADERVAR_MAPPINGS
static already_AddRefed<const webgl::LinkedProgramInfo>
QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
{
WebGLContext* const webgl = prog->mContext;
RefPtr<webgl::LinkedProgramInfo> info(new webgl::LinkedProgramInfo(prog));
@@ -233,36 +233,38 @@ QueryProgramInfo(WebGLProgram* prog, gl:
&elemCount, &elemType, mappedName.BeginWriting());
GLenum error = gl->fGetError();
if (error != LOCAL_GL_NO_ERROR) {
gfxCriticalNote << "Failed to do glGetActiveAttrib: " << error;
}
mappedName.SetLength(lengthWithoutNull);
+ if (mappedName.Find("gl_") == 0) {
+#ifdef DUMP_SHADERVAR_MAPPINGS
+ printf_stderr("[attrib %u/%u] <skipping %s>\n", i, numActiveAttribs,
+ mappedName.BeginReading());
+#endif
+ continue;
+ }
+
// Attribs can't be arrays, so we can skip some of the mess we have in the Uniform
// path.
nsDependentCString userName;
if (!prog->FindAttribUserNameByMappedName(mappedName, &userName))
userName.Rebind(mappedName, 0);
///////
const GLint loc = gl->fGetAttribLocation(prog->mGLName,
mappedName.BeginReading());
- if (loc == -1) {
- MOZ_ASSERT(mappedName == "gl_InstanceID",
- "Active attrib should have a location.");
- continue;
- }
#ifdef DUMP_SHADERVAR_MAPPINGS
- printf_stderr("[attrib %i: %i] %s/%s\n", i, loc, mappedName.BeginReading(),
- userName.BeginReading());
- printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull);
+ printf_stderr("[attrib %u/%u] @%u %s->%s\n", i, numActiveAttribs, loc,
+ userName.BeginReading(), mappedName.BeginReading());
#endif
///////
const bool isArray = false;
const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(webgl, elemCount,
elemType, isArray,
userName,
@@ -286,16 +288,17 @@ QueryProgramInfo(WebGLProgram* prog, gl:
GLsizei lengthWithoutNull = 0;
GLint elemCount = 0; // `size`
GLenum elemType = 0; // `type`
gl->fGetActiveUniform(prog->mGLName, i, mappedName.Length()+1, &lengthWithoutNull,
&elemCount, &elemType, mappedName.BeginWriting());
mappedName.SetLength(lengthWithoutNull);
+ MOZ_ASSERT(mappedName.Find("gl_") != 0);
///////
nsAutoCString baseMappedName;
bool isArray;
size_t arrayIndex;
if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex))
MOZ_CRASH("GFX: Failed to parse `mappedName` received from driver.");
@@ -321,21 +324,18 @@ QueryProgramInfo(WebGLProgram* prog, gl:
if (loc != -1)
isArray = true;
}
}
///////
#ifdef DUMP_SHADERVAR_MAPPINGS
- printf_stderr("[uniform %i] %s/%i/%s/%s\n", i, mappedName.BeginReading(),
- (int)isArray, baseMappedName.BeginReading(),
- baseUserName.BeginReading());
- printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull);
- printf_stderr(" isArray: %d\n", (int)isArray);
+ printf_stderr("[uniform %u/%u] %s->%s\n", i, numActiveUniforms,
+ baseUserName.BeginReading(), mappedName.BeginReading());
#endif
///////
const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(webgl, elemCount,
elemType, isArray,
baseUserName,
baseMappedName);
@@ -360,55 +360,38 @@ QueryProgramInfo(WebGLProgram* prog, gl:
nsAutoCString mappedName;
mappedName.SetLength(maxUniformBlockLenWithNull - 1);
GLint lengthWithoutNull;
gl->fGetActiveUniformBlockiv(prog->mGLName, i, LOCAL_GL_UNIFORM_BLOCK_NAME_LENGTH, &lengthWithoutNull);
gl->fGetActiveUniformBlockName(prog->mGLName, i, maxUniformBlockLenWithNull, &lengthWithoutNull, mappedName.BeginWriting());
mappedName.SetLength(lengthWithoutNull);
- nsAutoCString baseMappedName;
- bool isArray;
- size_t arrayIndex;
- if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex))
- MOZ_CRASH("GFX: Failed to parse `mappedName` received from driver.");
+ MOZ_ASSERT(mappedName.Find("gl_") != 0);
+
+ ////
- nsAutoCString baseUserName;
- if (!prog->FindUniformBlockByMappedName(baseMappedName, &baseUserName,
- &isArray))
- {
- baseUserName = baseMappedName;
+ nsCString userName;
+ if (!prog->UnmapUniformBlockName(mappedName, &userName))
+ continue;
- if (needsCheckForArrays && !isArray) {
- std::string mappedNameStr = baseMappedName.BeginReading();
- mappedNameStr += "[0]";
-
- GLuint loc = gl->fGetUniformBlockIndex(prog->mGLName,
- mappedNameStr.c_str());
- if (loc != LOCAL_GL_INVALID_INDEX)
- isArray = true;
- }
- }
+#ifdef DUMP_SHADERVAR_MAPPINGS
+ printf_stderr("[uniform block %u/%u] %s->%s\n", i, numActiveUniformBlocks,
+ userName.BeginReading(), mappedName.BeginReading());
+#endif
////
GLuint dataSize = 0;
gl->fGetActiveUniformBlockiv(prog->mGLName, i,
LOCAL_GL_UNIFORM_BLOCK_DATA_SIZE,
(GLint*)&dataSize);
-#ifdef DUMP_SHADERVAR_MAPPINGS
- printf_stderr("[uniform block %i] %s/%i/%s/%s\n", i,
- mappedName.BeginReading(), (int)isArray,
- baseMappedName.BeginReading(), baseUserName.BeginReading());
- printf_stderr(" lengthWithoutNull: %d\n", lengthWithoutNull);
- printf_stderr(" isArray: %d\n", (int)isArray);
-#endif
- auto* block = new webgl::UniformBlockInfo(webgl, baseUserName, baseMappedName,
+ auto* block = new webgl::UniformBlockInfo(webgl, userName, mappedName,
dataSize);
info->uniformBlocks.push_back(block);
}
}
// Transform feedback varyings
if (gl->IsSupported(gl::GLFeature::transform_feedback2)) {
@@ -424,42 +407,39 @@ QueryProgramInfo(WebGLProgram* prog, gl:
GLsizei elemCount;
GLenum elemType;
gl->fGetTransformFeedbackVarying(prog->mGLName, i,
maxTransformFeedbackVaryingLenWithNull,
&lengthWithoutNull, &elemCount, &elemType,
mappedName.BeginWriting());
mappedName.SetLength(lengthWithoutNull);
+ // Allowed to start with "gl_".
+
////
nsAutoCString baseMappedName;
bool isArray;
size_t arrayIndex;
if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex))
MOZ_CRASH("GFX: Failed to parse `mappedName` received from driver.");
-
nsAutoCString baseUserName;
if (!prog->FindVaryingByMappedName(mappedName, &baseUserName, &isArray)) {
baseUserName = baseMappedName;
-
- if (needsCheckForArrays && !isArray) {
- std::string mappedNameStr = baseMappedName.BeginReading();
- mappedNameStr += "[0]";
-
- GLuint loc = gl->fGetUniformBlockIndex(prog->mGLName,
- mappedNameStr.c_str());
- if (loc != LOCAL_GL_INVALID_INDEX)
- isArray = true;
- }
}
////
+#ifdef DUMP_SHADERVAR_MAPPINGS
+ printf_stderr("[transform feedback varying %u/%u] %s->%s\n", i,
+ numTransformFeedbackVaryings, baseUserName.BeginReading(),
+ mappedName.BeginReading());
+#endif
+
const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(webgl,
elemCount,
elemType,
isArray,
baseUserName,
mappedName);
info->transformFeedbackVaryings.push_back(activeInfo);
}
@@ -783,23 +763,30 @@ WebGLProgram::GetUniformBlockIndex(const
if (!IsLinked()) {
mContext->ErrorInvalidOperation("getUniformBlockIndex: `program` must be linked.");
return LOCAL_GL_INVALID_INDEX;
}
const NS_LossyConvertUTF16toASCII userName(userName_wide);
- nsCString mappedName;
- if (!LinkInfo()->MapUniformBlockName(userName, &mappedName))
+ const webgl::UniformBlockInfo* info = nullptr;
+ for (const auto& cur : LinkInfo()->uniformBlocks) {
+ if (cur->mUserName == userName) {
+ info = cur;
+ break;
+ }
+ }
+ if (!info)
return LOCAL_GL_INVALID_INDEX;
+ const auto& mappedName = info->mMappedName;
+
gl::GLContext* gl = mContext->GL();
gl->MakeCurrent();
-
return gl->fGetUniformBlockIndex(mGLName, mappedName.BeginReading());
}
void
WebGLProgram::GetActiveUniformBlockName(GLuint uniformBlockIndex, nsAString& retval) const
{
if (!IsLinked()) {
mContext->ErrorInvalidOperation("getActiveUniformBlockName: `program` must be linked.");
@@ -808,19 +795,18 @@ WebGLProgram::GetActiveUniformBlockName(
const webgl::LinkedProgramInfo* linkInfo = LinkInfo();
GLuint uniformBlockCount = (GLuint) linkInfo->uniformBlocks.size();
if (uniformBlockIndex >= uniformBlockCount) {
mContext->ErrorInvalidValue("getActiveUniformBlockName: index %u invalid.", uniformBlockIndex);
return;
}
- const webgl::UniformBlockInfo* blockInfo = linkInfo->uniformBlocks[uniformBlockIndex];
-
- retval.Assign(NS_ConvertASCIItoUTF16(blockInfo->mBaseUserName));
+ const auto& blockInfo = linkInfo->uniformBlocks[uniformBlockIndex];
+ retval.Assign(NS_ConvertASCIItoUTF16(blockInfo->mUserName));
}
JS::Value
WebGLProgram::GetActiveUniformBlockParam(GLuint uniformBlockIndex, GLenum pname) const
{
if (!IsLinked()) {
mContext->ErrorInvalidOperation("getActiveUniformBlockParameter: `program` must be linked.");
return JS::NullValue();
@@ -1494,27 +1480,34 @@ WebGLProgram::GetTransformFeedbackVaryin
return nullptr;
}
RefPtr<WebGLActiveInfo> ret = LinkInfo()->transformFeedbackVaryings[index];
return ret.forget();
}
bool
-WebGLProgram::FindUniformBlockByMappedName(const nsACString& mappedName,
- nsCString* const out_userName,
- bool* const out_isArray) const
+WebGLProgram::UnmapUniformBlockName(const nsCString& mappedName,
+ nsCString* const out_userName) const
{
- if (mVertShader->FindUniformBlockByMappedName(mappedName, out_userName, out_isArray))
- return true;
+ nsCString baseMappedName;
+ bool isArray;
+ size_t arrayIndex;
+ if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex))
+ return false;
- if (mFragShader->FindUniformBlockByMappedName(mappedName, out_userName, out_isArray))
- return true;
+ nsCString baseUserName;
+ if (!mVertShader->UnmapUniformBlockName(baseMappedName, &baseUserName) &&
+ !mFragShader->UnmapUniformBlockName(baseMappedName, &baseUserName))
+ {
+ return false;
+ }
- return false;
+ AssembleName(baseUserName, isArray, arrayIndex, out_userName);
+ return true;
}
void
WebGLProgram::EnumerateFragOutputs(std::map<nsCString, const nsCString> &out_FragOutputs) const
{
MOZ_ASSERT(mFragShader);
mFragShader->EnumerateFragOutputs(out_FragOutputs);
@@ -1573,41 +1566,16 @@ webgl::LinkedProgramInfo::FindUniform(co
AssembleName(baseMappedName, isArray, arrayIndex, out_mappedName);
*out_arrayIndex = arrayIndex;
*out_info = info;
return true;
}
bool
-webgl::LinkedProgramInfo::MapUniformBlockName(const nsCString& userName,
- nsCString* const out_mappedName) const
-{
- nsCString baseUserName;
- bool isArray;
- size_t arrayIndex;
- if (!ParseName(userName, &baseUserName, &isArray, &arrayIndex))
- return false;
-
- const webgl::UniformBlockInfo* info = nullptr;
- for (const auto& block : uniformBlocks) {
- if (block->mBaseUserName == baseUserName) {
- info = block;
- break;
- }
- }
- if (!info)
- return false;
-
- const auto& baseMappedName = info->mBaseMappedName;
- AssembleName(baseMappedName, isArray, arrayIndex, out_mappedName);
- return true;
-}
-
-bool
webgl::LinkedProgramInfo::MapFragDataName(const nsCString& userName,
nsCString* const out_mappedName) const
{
// FS outputs can be arrays, but not structures.
if (!fragDataMap.size()) {
// No mappings map from validation, so just forward it.
*out_mappedName = userName;
--- a/dom/canvas/WebGLProgram.h
+++ b/dom/canvas/WebGLProgram.h
@@ -55,26 +55,26 @@ protected:
GetTexList(WebGLActiveInfo* activeInfo);
public:
explicit UniformInfo(WebGLActiveInfo* activeInfo);
};
struct UniformBlockInfo final
{
- const nsCString mBaseUserName;
- const nsCString mBaseMappedName;
+ const nsCString mUserName;
+ const nsCString mMappedName;
const uint32_t mDataSize;
const IndexedBufferBinding* mBinding;
- UniformBlockInfo(WebGLContext* webgl, const nsACString& baseUserName,
- const nsACString& baseMappedName, uint32_t dataSize)
- : mBaseUserName(baseUserName)
- , mBaseMappedName(baseMappedName)
+ UniformBlockInfo(WebGLContext* webgl, const nsACString& userName,
+ const nsACString& mappedName, uint32_t dataSize)
+ : mUserName(userName)
+ , mMappedName(mappedName)
, mDataSize(dataSize)
, mBinding(&webgl->mIndexedUniformBufferBindings[0])
{ }
};
struct LinkedProgramInfo final
: public RefCounted<LinkedProgramInfo>
, public SupportsWeakPtr<LinkedProgramInfo>
@@ -104,18 +104,16 @@ struct LinkedProgramInfo final
std::map<nsCString, const nsCString> fragDataMap;
explicit LinkedProgramInfo(WebGLProgram* prog);
~LinkedProgramInfo();
bool FindAttrib(const nsCString& userName, const AttribInfo** const out_info) const;
bool FindUniform(const nsCString& userName, nsCString* const out_mappedName,
size_t* const out_arrayIndex, UniformInfo** const out_info) const;
- bool MapUniformBlockName(const nsCString& userName,
- nsCString* const out_mappedName) const;
bool MapFragDataName(const nsCString& userName,
nsCString* const out_mappedName) const;
};
} // namespace webgl
class WebGLProgram final
: public nsWrapperCache
@@ -163,19 +161,18 @@ public:
bool FindAttribUserNameByMappedName(const nsACString& mappedName,
nsDependentCString* const out_userName) const;
bool FindVaryingByMappedName(const nsACString& mappedName,
nsCString* const out_userName,
bool* const out_isArray) const;
bool FindUniformByMappedName(const nsACString& mappedName,
nsCString* const out_userName,
bool* const out_isArray) const;
- bool FindUniformBlockByMappedName(const nsACString& mappedName,
- nsCString* const out_userName,
- bool* const out_isArray) const;
+ bool UnmapUniformBlockName(const nsCString& mappedName,
+ nsCString* const out_userName) const;
void TransformFeedbackVaryings(const dom::Sequence<nsString>& varyings,
GLenum bufferMode);
already_AddRefed<WebGLActiveInfo> GetTransformFeedbackVarying(GLuint index) const;
void EnumerateFragOutputs(std::map<nsCString, const nsCString> &out_FragOutputs) const;
bool IsLinked() const { return mMostRecentLinkInfo; }