void WebGLProgram::BindAttribLocation(GLuint loc, const nsAString& name) { if (!ValidateGLSLVariableName(name, mContext, "bindAttribLocation")) return; if (loc >= mContext->MaxVertexAttribs()) { mContext->ErrorInvalidValue("bindAttribLocation: `location` must be less than" " MAX_VERTEX_ATTRIBS."); return; } if (StringBeginsWith(name, NS_LITERAL_STRING("gl_"))) { mContext->ErrorInvalidOperation("bindAttribLocation: Can't set the location of a" " name that starts with 'gl_'."); return; } NS_LossyConvertUTF16toASCII asciiName(name); auto res = mBoundAttribLocs.insert(std::pair<nsCString, GLuint>(asciiName, loc)); const bool wasInserted = res.second; if (!wasInserted) { auto itr = res.first; itr->second = loc; } }
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(); }
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(); }
GLint WebGLProgram::GetAttribLocation(const nsAString& userName_wide) const { if (!ValidateGLSLVariableName(userName_wide, mContext, "getAttribLocation")) return -1; if (!IsLinked()) { mContext->ErrorInvalidOperation("getAttribLocation: `program` must be linked."); return -1; } const NS_LossyConvertUTF16toASCII userName(userName_wide); const webgl::AttribInfo* info; if (!LinkInfo()->FindAttrib(userName, &info)) return -1; return GLint(info->mLoc); }
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 NS_LossyConvertUTF16toASCII userName(userName_wide); nsCString mappedName; if (!LinkInfo()->FindFragData(userName, &mappedName)) return -1; gl::GLContext* gl = mContext->GL(); gl->MakeCurrent(); return gl->fGetFragDataLocation(mGLName, mappedName.BeginReading()); }
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()); }
void WebGLProgram::TransformFeedbackVaryings(const dom::Sequence<nsString>& varyings, GLenum bufferMode) { if (bufferMode != LOCAL_GL_INTERLEAVED_ATTRIBS && bufferMode != LOCAL_GL_SEPARATE_ATTRIBS) { mContext->ErrorInvalidEnum("transformFeedbackVaryings: `bufferMode` %s is " "invalid. Must be one of gl.INTERLEAVED_ATTRIBS or " "gl.SEPARATE_ATTRIBS.", mContext->EnumName(bufferMode)); return; } size_t varyingsCount = varyings.Length(); if (bufferMode == LOCAL_GL_SEPARATE_ATTRIBS && varyingsCount >= mContext->mGLMaxTransformFeedbackSeparateAttribs) { mContext->ErrorInvalidValue("transformFeedbackVaryings: Number of `varyings` exc" "eeds gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS."); return; } std::vector<nsCString> asciiVaryings; for (size_t i = 0; i < varyingsCount; i++) { if (!ValidateGLSLVariableName(varyings[i], mContext, "transformFeedbackVaryings")) return; NS_LossyConvertUTF16toASCII asciiName(varyings[i]); asciiVaryings.push_back(asciiName); } // All validated. Translate the strings and store them until // program linking. mTransformFeedbackBufferMode = bufferMode; mTransformFeedbackVaryings.swap(asciiVaryings); }