Bug 1038899 - WebGL fix attribute and uniform name lookup in WebGLProgram. r=jgilbert, r=vlad
authorWalter Litwinczyk <wlitwinczyk@mozilla.com>
Mon, 11 Aug 2014 14:36:30 -0700
changeset 199127 1a5c05669cdabba6ebfa37f5f926646774af66c5
parent 199126 c5f3e46fae05aea149404709ffddd296d2dc6408
child 199128 d541d505f3031fded5fa47b5b3b842b6138fb9e8
push id27298
push userryanvm@gmail.com
push dateTue, 12 Aug 2014 20:25:16 +0000
treeherdermozilla-central@7fc96293ada8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert, vlad
bugs1038899
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1038899 - WebGL fix attribute and uniform name lookup in WebGLProgram. r=jgilbert, r=vlad
dom/canvas/WebGLContextValidate.cpp
dom/canvas/WebGLProgram.cpp
--- a/dom/canvas/WebGLContextValidate.cpp
+++ b/dom/canvas/WebGLContextValidate.cpp
@@ -155,22 +155,17 @@ IsTexImageCubemapTarget(GLenum target)
 }
 
 /*
  * Pull data out of the program, post-linking
  */
 bool
 WebGLProgram::UpdateInfo()
 {
-    mIdentifierMap = nullptr;
-    mIdentifierReverseMap = nullptr;
-    mUniformInfoMap = nullptr;
-
     mAttribMaxNameLength = 0;
-
     for (size_t i = 0; i < mAttachedShaders.Length(); i++)
         mAttribMaxNameLength = std::max(mAttribMaxNameLength, mAttachedShaders[i]->mAttribMaxNameLength);
 
     GLint attribCount;
     mContext->gl->fGetProgramiv(mGLName, LOCAL_GL_ACTIVE_ATTRIBUTES, &attribCount);
 
     if (!mAttribsInUse.SetLength(mContext->mGLMaxVertexAttribs)) {
         mContext->ErrorOutOfMemory("updateInfo: out of memory to allocate %d attribs", mContext->mGLMaxVertexAttribs);
@@ -194,24 +189,38 @@ WebGLProgram::UpdateInfo()
                 mAttribsInUse[loc] = true;
             } else {
                 mContext->GenerateWarning("program exceeds MAX_VERTEX_ATTRIBS");
                 return false;
             }
         }
     }
 
-    if (!mUniformInfoMap) {
-        mUniformInfoMap = new CStringToUniformInfoMap;
-        for (size_t i = 0; i < mAttachedShaders.Length(); i++) {
-            for (size_t j = 0; j < mAttachedShaders[i]->mUniforms.Length(); j++) {
-                const WebGLMappedIdentifier& uniform = mAttachedShaders[i]->mUniforms[j];
-                const WebGLUniformInfo& info = mAttachedShaders[i]->mUniformInfos[j];
-                mUniformInfoMap->Put(uniform.mapped, info);
-            }
+    // nsAutoPtr will delete old version first
+    mIdentifierMap = new CStringMap;
+    mIdentifierReverseMap = new CStringMap;
+    mUniformInfoMap = new CStringToUniformInfoMap;
+    for (size_t i = 0; i < mAttachedShaders.Length(); i++) {
+        // Loop through ATTRIBUTES
+        for (size_t j = 0; j < mAttachedShaders[i]->mAttributes.Length(); j++) {
+            const WebGLMappedIdentifier& attrib = mAttachedShaders[i]->mAttributes[j];
+            mIdentifierMap->Put(attrib.original, attrib.mapped); // FORWARD MAPPING
+            mIdentifierReverseMap->Put(attrib.mapped, attrib.original); // REVERSE MAPPING
+        }
+
+        // Loop through UNIFORMS
+        for (size_t j = 0; j < mAttachedShaders[i]->mUniforms.Length(); j++) {
+            // Add the uniforms name mapping to mIdentifier[Reverse]Map
+            const WebGLMappedIdentifier& uniform = mAttachedShaders[i]->mUniforms[j];
+            mIdentifierMap->Put(uniform.original, uniform.mapped); // FOWARD MAPPING
+            mIdentifierReverseMap->Put(uniform.mapped, uniform.original); // REVERSE MAPPING
+
+            // Add uniform info to mUniformInfoMap
+            const WebGLUniformInfo& info = mAttachedShaders[i]->mUniformInfos[j];
+            mUniformInfoMap->Put(uniform.mapped, info);
         }
     }
 
     mActiveAttribMap.clear();
 
     GLint numActiveAttrs = 0;
     mContext->gl->fGetProgramiv(mGLName, LOCAL_GL_ACTIVE_ATTRIBUTES, &numActiveAttrs);
 
--- a/dom/canvas/WebGLProgram.cpp
+++ b/dom/canvas/WebGLProgram.cpp
@@ -50,16 +50,19 @@ JSObject*
 WebGLProgram::WrapObject(JSContext *cx) {
     return dom::WebGLProgramBinding::Wrap(cx, this);
 }
 
 WebGLProgram::WebGLProgram(WebGLContext *context)
     : WebGLContextBoundObject(context)
     , mLinkStatus(false)
     , mGeneration(0)
+    , mIdentifierMap(new CStringMap)
+    , mIdentifierReverseMap(new CStringMap)
+    , mUniformInfoMap(new CStringToUniformInfoMap)
     , mAttribMaxNameLength(0)
 {
     SetIsDOMBinding();
     mContext->MakeContextCurrent();
     mGLName = mContext->gl->fCreateProgram();
     mContext->mPrograms.insertBack(this);
 }
 
@@ -130,30 +133,17 @@ WebGLProgram::UpperBoundNumSamplerUnifor
             }
         }
     }
     return numSamplerUniforms;
 }
 
 void
 WebGLProgram::MapIdentifier(const nsACString& name, nsCString *mappedName) {
-    if (!mIdentifierMap) {
-        // if the identifier map doesn't exist yet, build it now
-        mIdentifierMap = new CStringMap;
-        for (size_t i = 0; i < mAttachedShaders.Length(); i++) {
-            for (size_t j = 0; j < mAttachedShaders[i]->mAttributes.Length(); j++) {
-                const WebGLMappedIdentifier& attrib = mAttachedShaders[i]->mAttributes[j];
-                mIdentifierMap->Put(attrib.original, attrib.mapped);
-            }
-            for (size_t j = 0; j < mAttachedShaders[i]->mUniforms.Length(); j++) {
-                const WebGLMappedIdentifier& uniform = mAttachedShaders[i]->mUniforms[j];
-                mIdentifierMap->Put(uniform.original, uniform.mapped);
-            }
-        }
-    }
+    MOZ_ASSERT(mIdentifierMap);
 
     nsCString mutableName(name);
     nsCString bracketPart;
     bool hadBracketPart = SplitLastSquareBracket(mutableName, bracketPart);
     if (hadBracketPart)
         mutableName.AppendLiteral("[0]");
 
     if (mIdentifierMap->Get(mutableName, mappedName)) {
@@ -175,30 +165,17 @@ WebGLProgram::MapIdentifier(const nsACSt
     // not found? return name unchanged. This case happens e.g. on bad user input, or when
     // we're not using identifier mapping, or if we didn't store an identifier in the map because
     // e.g. its mapping is trivial (as happens for short identifiers)
     mappedName->Assign(name);
 }
 
 void
 WebGLProgram::ReverseMapIdentifier(const nsACString& name, nsCString *reverseMappedName) {
-    if (!mIdentifierReverseMap) {
-        // if the identifier reverse map doesn't exist yet, build it now
-        mIdentifierReverseMap = new CStringMap;
-        for (size_t i = 0; i < mAttachedShaders.Length(); i++) {
-            for (size_t j = 0; j < mAttachedShaders[i]->mAttributes.Length(); j++) {
-                const WebGLMappedIdentifier& attrib = mAttachedShaders[i]->mAttributes[j];
-                mIdentifierReverseMap->Put(attrib.mapped, attrib.original);
-            }
-            for (size_t j = 0; j < mAttachedShaders[i]->mUniforms.Length(); j++) {
-                const WebGLMappedIdentifier& uniform = mAttachedShaders[i]->mUniforms[j];
-                mIdentifierReverseMap->Put(uniform.mapped, uniform.original);
-            }
-        }
-    }
+    MOZ_ASSERT(mIdentifierReverseMap);
 
     nsCString mutableName(name);
     nsCString bracketPart;
     bool hadBracketPart = SplitLastSquareBracket(mutableName, bracketPart);
     if (hadBracketPart)
         mutableName.AppendLiteral("[0]");
 
     if (mIdentifierReverseMap->Get(mutableName, reverseMappedName)) {
@@ -220,16 +197,18 @@ WebGLProgram::ReverseMapIdentifier(const
     // not found? return name unchanged. This case happens e.g. on bad user input, or when
     // we're not using identifier mapping, or if we didn't store an identifier in the map because
     // e.g. its mapping is trivial (as happens for short identifiers)
     reverseMappedName->Assign(name);
 }
 
 WebGLUniformInfo
 WebGLProgram::GetUniformInfoForMappedIdentifier(const nsACString& name) {
+    MOZ_ASSERT(mUniformInfoMap);
+
     nsCString mutableName(name);
     nsCString bracketPart;
     bool hadBracketPart = SplitLastSquareBracket(mutableName, bracketPart);
     // if there is a bracket, we're either an array or an entry in an array.
     if (hadBracketPart)
         mutableName.AppendLiteral("[0]");
 
     WebGLUniformInfo info;