Bug 1326378 - Infer indexed frag output location from base location on OSX. - r=ethlin a=ritu
authorJeff Gilbert <jgilbert@mozilla.com>
Thu, 29 Dec 2016 23:08:37 -0800
changeset 359266 bf12751fbad8d792d113a5b880787f5c0a17a13c
parent 359265 efe8cbe4869aaaa4bb3e503db02eed03079b4730
child 359267 127b801739dada26da3f7201317ef32461c2c36f
push id1324
push usermtabara@mozilla.com
push dateMon, 16 Jan 2017 13:07:44 +0000
treeherdermozilla-release@a01c49833940 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersethlin, ritu
bugs1326378
milestone51.0
Bug 1326378 - Infer indexed frag output location from base location on OSX. - r=ethlin a=ritu MozReview-Commit-ID: Ar07ZnNhu5d
dom/canvas/WebGLProgram.cpp
--- a/dom/canvas/WebGLProgram.cpp
+++ b/dom/canvas/WebGLProgram.cpp
@@ -649,35 +649,62 @@ WebGLProgram::GetAttribLocation(const ns
 
     const webgl::AttribInfo* info;
     if (!LinkInfo()->FindAttrib(userName, &info))
         return -1;
 
     return GLint(info->mLoc);
 }
 
+static GLint
+GetFragDataByUserName(const WebGLProgram* prog,
+                      const nsCString& userName)
+{
+    nsCString mappedName;
+    if (!prog->LinkInfo()->MapFragDataName(userName, &mappedName))
+        return -1;
+
+    return prog->mContext->gl->fGetFragDataLocation(prog->mGLName, mappedName.BeginReading());
+}
+
 GLint
 WebGLProgram::GetFragDataLocation(const nsAString& userName_wide) const
 {
     if (!ValidateGLSLVariableName(userName_wide, mContext, "getFragDataLocation"))
         return -1;
 
     if (!IsLinked()) {
         mContext->ErrorInvalidOperation("getFragDataLocation: `program` must be linked.");
         return -1;
     }
 
+
+    const auto& gl = mContext->gl;
+    gl->MakeCurrent();
+
     const NS_LossyConvertUTF16toASCII userName(userName_wide);
-    nsCString mappedName;
-    if (!LinkInfo()->MapFragDataName(userName, &mappedName))
-        return -1;
+#ifdef XP_MACOSX
+    if (gl->WorkAroundDriverBugs()) {
+        // OSX doesn't return locs for indexed names, just the base names.
+        // Indicated by failure in: conformance2/programs/gl-get-frag-data-location.html
+        bool isArray;
+        size_t arrayIndex;
+        nsCString baseUserName;
+        if (!ParseName(userName, &baseUserName, &isArray, &arrayIndex))
+            return -1;
 
-    gl::GLContext* gl = mContext->GL();
-    gl->MakeCurrent();
-    return gl->fGetFragDataLocation(mGLName, mappedName.BeginReading());
+        if (arrayIndex >= mContext->mImplMaxDrawBuffers)
+            return -1;
+
+        const auto baseLoc = GetFragDataByUserName(this, baseUserName);
+        const auto loc = baseLoc + GLint(arrayIndex);
+        return loc;
+    }
+#endif
+    return GetFragDataByUserName(this, userName);
 }
 
 void
 WebGLProgram::GetProgramInfoLog(nsAString* const out) const
 {
     CopyASCIItoUTF16(mLinkLog, *out);
 }