already_AddRefed<WebGLUniformLocation> WebGLProgram::GetUniformLocation(const nsAString& userName_wide) const { if (!ValidateGLSLVariableName(userName_wide, mContext, "getUniformLocation")) return nullptr; if (!IsLinked()) { mContext->ErrorInvalidOperation("getUniformLocation: `program` must be linked."); return nullptr; } const NS_LossyConvertUTF16toASCII userName(userName_wide); nsDependentCString baseUserName; bool isArray = false; // GLES 2.0.25, Section 2.10, p35 // If the the uniform location is an array, then the location of the first // element of that array can be retrieved by either using the name of the // uniform array, or the name of the uniform array appended with "[0]". // The ParseName() can't recognize this rule. So always initialize // arrayIndex with 0. size_t arrayIndex = 0; if (!ParseName(userName, &baseUserName, &isArray, &arrayIndex)) return nullptr; const WebGLActiveInfo* activeInfo; if (!LinkInfo()->FindUniform(baseUserName, &activeInfo)) return nullptr; const nsCString& baseMappedName = activeInfo->mBaseMappedName; nsAutoCString mappedName(baseMappedName); if (isArray) { mappedName.AppendLiteral("["); mappedName.AppendInt(uint32_t(arrayIndex)); mappedName.AppendLiteral("]"); } gl::GLContext* gl = mContext->GL(); gl->MakeCurrent(); GLint loc = gl->fGetUniformLocation(mGLName, mappedName.BeginReading()); if (loc == -1) return nullptr; RefPtr<WebGLUniformLocation> locObj = new WebGLUniformLocation(mContext, LinkInfo(), loc, arrayIndex, activeInfo); return locObj.forget(); }
void WebGLProgram::GetUniformIndices(const dom::Sequence<nsString>& uniformNames, dom::Nullable< nsTArray<GLuint> >& retval) const { const char funcName[] = "getUniformIndices"; if (!IsLinked()) { mContext->ErrorInvalidOperation("%s: `program` must be linked.", funcName); return; } size_t count = uniformNames.Length(); nsTArray<GLuint>& arr = retval.SetValue(); gl::GLContext* gl = mContext->GL(); gl->MakeCurrent(); for (size_t i = 0; i < count; i++) { const NS_LossyConvertUTF16toASCII userName(uniformNames[i]); nsDependentCString baseUserName; bool isArray; size_t arrayIndex; if (!ParseName(userName, &baseUserName, &isArray, &arrayIndex)) { arr.AppendElement(LOCAL_GL_INVALID_INDEX); continue; } webgl::UniformInfo* info; if (!LinkInfo()->FindUniform(baseUserName, &info)) { arr.AppendElement(LOCAL_GL_INVALID_INDEX); continue; } nsAutoCString mappedName(info->mActiveInfo->mBaseMappedName); if (isArray) { mappedName.AppendLiteral("["); mappedName.AppendInt(uint32_t(arrayIndex)); mappedName.AppendLiteral("]"); } const GLchar* mappedNameBytes = mappedName.BeginReading(); GLuint index = 0; gl->fGetUniformIndices(mGLName, 1, &mappedNameBytes, &index); arr.AppendElement(index); } }
already_AddRefed<WebGLUniformLocation> WebGLProgram::GetUniformLocation(const nsAString& userName_wide) const { if (!ValidateGLSLVariableName(userName_wide, mContext, "getUniformLocation")) return nullptr; if (!IsLinked()) { mContext->ErrorInvalidOperation("getUniformLocation: `program` must be linked."); return nullptr; } const NS_LossyConvertUTF16toASCII userName(userName_wide); nsDependentCString baseUserName; bool isArray; size_t arrayIndex; if (!ParseName(userName, &baseUserName, &isArray, &arrayIndex)) return nullptr; const WebGLActiveInfo* activeInfo; if (!LinkInfo()->FindUniform(baseUserName, &activeInfo)) return nullptr; const nsCString& baseMappedName = activeInfo->mBaseMappedName; nsAutoCString mappedName(baseMappedName); if (isArray) { mappedName.AppendLiteral("["); mappedName.AppendInt(uint32_t(arrayIndex)); mappedName.AppendLiteral("]"); } gl::GLContext* gl = mContext->GL(); gl->MakeCurrent(); GLint loc = gl->fGetUniformLocation(mGLName, mappedName.BeginReading()); if (loc == -1) return nullptr; RefPtr<WebGLUniformLocation> locObj = new WebGLUniformLocation(mContext, LinkInfo(), loc, activeInfo); return locObj.forget(); }
GLuint WebGLProgram::GetUniformBlockIndex(const nsAString& userName_wide) const { if (!ValidateGLSLVariableName(userName_wide, mContext, "getUniformBlockIndex")) return LOCAL_GL_INVALID_INDEX; if (!IsLinked()) { mContext->ErrorInvalidOperation("getUniformBlockIndex: `program` must be linked."); return LOCAL_GL_INVALID_INDEX; } const NS_LossyConvertUTF16toASCII userName(userName_wide); nsDependentCString baseUserName; bool isArray; size_t arrayIndex; if (!ParseName(userName, &baseUserName, &isArray, &arrayIndex)) return LOCAL_GL_INVALID_INDEX; RefPtr<const webgl::UniformBlockInfo> info; if (!LinkInfo()->FindUniformBlock(baseUserName, &info)) { return LOCAL_GL_INVALID_INDEX; } const nsCString& baseMappedName = info->mBaseMappedName; nsAutoCString mappedName(baseMappedName); if (isArray) { mappedName.AppendLiteral("["); mappedName.AppendInt(uint32_t(arrayIndex)); mappedName.AppendLiteral("]"); } gl::GLContext* gl = mContext->GL(); gl->MakeCurrent(); return gl->fGetUniformBlockIndex(mGLName, mappedName.BeginReading()); }