Bug 676071 - use ANGLE long identifier mapping - r=jgilbert

This also fixes the leak reported in bug 723261, and makes us avoid generating the shader translator output when we don't use it (on Android).
This commit is contained in:
Benoit Jacob 2012-03-02 15:42:49 -05:00
Родитель 0a59450680
Коммит dd24afa5ec
7 изменённых файлов: 299 добавлений и 116 удалений

Просмотреть файл

@ -63,6 +63,7 @@
#include "Layers.h"
#include "CheckedInt.h"
#include "nsDataHashtable.h"
#ifdef XP_MACOSX
#include "ForceDiscreteGPUHelperCGL.h"
@ -1627,16 +1628,25 @@ public:
}
};
struct WebGLMappedIdentifier {
nsCString original, mapped; // ASCII strings
WebGLMappedIdentifier(const nsACString& o, const nsACString& m) : original(o), mapped(m) {}
};
class WebGLShader MOZ_FINAL
: public nsIWebGLShader
, public WebGLRefCountedObject<WebGLShader>
, public WebGLContextBoundObject
{
friend class WebGLContext;
friend class WebGLProgram;
public:
WebGLShader(WebGLContext *context, WebGLenum stype)
: WebGLContextBoundObject(context)
, mType(stype)
, mNeedsTranslation(true)
, mAttribMaxNameLength(0)
{
mContext->MakeContextCurrent();
mGLName = mContext->gl->fCreateShader(mType);
@ -1693,11 +1703,45 @@ protected:
WebGLuint mGLName;
WebGLenum mType;
nsString mSource;
nsCString mTranslationLog;
nsCString mTranslationLog; // The translation log should contain only ASCII characters
bool mNeedsTranslation;
WebGLMonotonicHandle mMonotonicHandle;
nsTArray<WebGLMappedIdentifier> mAttributes;
nsTArray<WebGLMappedIdentifier> mUniforms;
int mAttribMaxNameLength;
};
/** Takes an ASCII string like "foo[i]", turns it into "foo" and returns "[i]" in bracketPart
*
* \param string input/output: the string to split, becomes the string without the bracket part
* \param bracketPart output: gets the bracket part.
*
* Notice that if there are multiple brackets like "foo[i].bar[j]", only the last bracket is split.
*/
static bool SplitLastSquareBracket(nsACString& string, nsCString& bracketPart)
{
NS_ABORT_IF_FALSE(bracketPart.Length() == 0, "SplitLastSquareBracket must be called with empty bracketPart string");
char *string_start = string.BeginWriting();
char *s = string_start + string.Length() - 1;
if (*s != ']')
return false;
while (*s != '[' && s != string_start)
s--;
if (*s != '[')
return false;
bracketPart.Assign(s);
*s = 0;
string.EndWriting();
string.SetLength(s - string_start);
return true;
}
typedef nsDataHashtable<nsCStringHashKey, nsCString> CStringHash;
class WebGLProgram MOZ_FINAL
: public nsIWebGLProgram
, public WebGLRefCountedObject<WebGLProgram>
@ -1708,10 +1752,7 @@ public:
: WebGLContextBoundObject(context)
, mLinkStatus(false)
, mGeneration(0)
, mUniformMaxNameLength(0)
, mAttribMaxNameLength(0)
, mUniformCount(0)
, mAttribCount(0)
{
mContext->MakeContextCurrent();
mGLName = mContext->gl->fCreateProgram();
@ -1790,15 +1831,107 @@ public:
}
/* Called only after LinkProgram */
bool UpdateInfo(gl::GLContext *gl);
bool UpdateInfo();
/* Getters for cached program info */
WebGLint UniformMaxNameLength() const { return mUniformMaxNameLength; }
WebGLint AttribMaxNameLength() const { return mAttribMaxNameLength; }
WebGLint UniformCount() const { return mUniformCount; }
WebGLint AttribCount() const { return mAttribCount; }
bool IsAttribInUse(unsigned i) const { return mAttribsInUse[i]; }
/* Maps identifier |name| to the mapped identifier |*mappedName|
* Both are ASCII strings.
*/
void MapIdentifier(const nsACString& name, nsCString *mappedName) {
if (!mIdentifierMap) {
// if the identifier map doesn't exist yet, build it now
mIdentifierMap = new CStringHash;
mIdentifierMap->Init();
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);
}
}
}
nsCString mutableName(name);
nsCString bracketPart;
bool hadBracketPart = SplitLastSquareBracket(mutableName, bracketPart);
if (hadBracketPart)
mutableName.AppendLiteral("[0]");
if (mIdentifierMap->Get(mutableName, mappedName)) {
if (hadBracketPart) {
nsCString mappedBracketPart;
bool mappedHadBracketPart = SplitLastSquareBracket(*mappedName, mappedBracketPart);
if (mappedHadBracketPart)
mappedName->Append(bracketPart);
}
return;
}
// not found? We might be in the situation we have a uniform array name and the GL's glGetActiveUniform
// returned its name without [0], as is allowed by desktop GL but not in ES. Let's then try with [0].
mutableName.AppendLiteral("[0]");
if (mIdentifierMap->Get(mutableName, mappedName))
return;
// 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);
}
/* Un-maps mapped identifier |name| to the original identifier |*reverseMappedName|
* Both are ASCII strings.
*/
void ReverseMapIdentifier(const nsACString& name, nsCString *reverseMappedName) {
if (!mIdentifierReverseMap) {
// if the identifier reverse map doesn't exist yet, build it now
mIdentifierReverseMap = new CStringHash;
mIdentifierReverseMap->Init();
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);
}
}
}
nsCString mutableName(name);
nsCString bracketPart;
bool hadBracketPart = SplitLastSquareBracket(mutableName, bracketPart);
if (hadBracketPart)
mutableName.AppendLiteral("[0]");
if (mIdentifierReverseMap->Get(mutableName, reverseMappedName)) {
if (hadBracketPart) {
nsCString reverseMappedBracketPart;
bool reverseMappedHadBracketPart = SplitLastSquareBracket(*reverseMappedName, reverseMappedBracketPart);
if (reverseMappedHadBracketPart)
reverseMappedName->Append(bracketPart);
}
return;
}
// not found? We might be in the situation we have a uniform array name and the GL's glGetActiveUniform
// returned its name without [0], as is allowed by desktop GL but not in ES. Let's then try with [0].
mutableName.AppendLiteral("[0]");
if (mIdentifierReverseMap->Get(mutableName, reverseMappedName))
return;
// 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);
}
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBGLPROGRAM
@ -1811,13 +1944,10 @@ protected:
CheckedUint32 mGeneration;
// post-link data
GLint mUniformMaxNameLength;
GLint mAttribMaxNameLength;
GLint mUniformCount;
GLint mAttribCount;
std::vector<bool> mAttribsInUse;
WebGLMonotonicHandle mMonotonicHandle;
nsAutoPtr<CStringHash> mIdentifierMap, mIdentifierReverseMap;
int mAttribMaxNameLength;
};
class WebGLRenderbuffer MOZ_FINAL
@ -2366,12 +2496,11 @@ class WebGLActiveInfo MOZ_FINAL
: public nsIWebGLActiveInfo
{
public:
WebGLActiveInfo(WebGLint size, WebGLenum type, const char *nameptr, PRUint32 namelength) :
WebGLActiveInfo(WebGLint size, WebGLenum type, const nsACString& name) :
mSize(size),
mType(type)
{
mName.AssignASCII(nameptr, namelength);
}
mType(type),
mName(NS_ConvertASCIItoUTF16(name))
{}
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBGLACTIVEINFO

Просмотреть файл

@ -121,7 +121,6 @@ NS_IMETHODIMP WebGLContext::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) { \
MakeContextCurrent(); gl->f##glname(a1,a2,a3,a4,a5,a6); return NS_OK; \
}
//
// WebGL API
//
@ -181,7 +180,8 @@ WebGLContext::BindAttribLocation(nsIWebGLProgram *pobj, WebGLuint location, cons
return NS_OK;
WebGLuint progname;
if (!GetGLName<WebGLProgram>("bindAttribLocation: program", pobj, &progname))
WebGLProgram *prog;
if (!GetConcreteObjectAndGLName("bindAttribLocation: program", pobj, &prog, &progname))
return NS_OK;
if (!ValidateGLSLVariableName(name, "bindAttribLocation"))
@ -190,10 +190,12 @@ WebGLContext::BindAttribLocation(nsIWebGLProgram *pobj, WebGLuint location, cons
if (!ValidateAttribIndex(location, "bindAttribLocation"))
return NS_OK;
NS_LossyConvertUTF16toASCII cname(name);
nsCString mappedName;
prog->MapIdentifier(cname, &mappedName);
MakeContextCurrent();
gl->fBindAttribLocation(progname, location, NS_LossyConvertUTF16toASCII(name).get());
gl->fBindAttribLocation(progname, location, mappedName.get());
return NS_OK;
}
@ -1852,7 +1854,8 @@ WebGLContext::GetActiveAttrib(nsIWebGLProgram *pobj, PRUint32 index, nsIWebGLAct
*retval = nsnull;
WebGLuint progname;
if (!GetGLName<WebGLProgram>("getActiveAttrib: program", pobj, &progname))
WebGLProgram *prog;
if (!GetConcreteObjectAndGLName("getActiveAttrib: program", pobj, &prog, &progname))
return NS_OK;
MakeContextCurrent();
@ -1872,7 +1875,10 @@ WebGLContext::GetActiveAttrib(nsIWebGLProgram *pobj, PRUint32 index, nsIWebGLAct
return NS_OK;
}
WebGLActiveInfo *retActiveInfo = new WebGLActiveInfo(attrsize, attrtype, name.get(), len);
nsCString reverseMappedName;
prog->ReverseMapIdentifier(nsDependentCString(name), &reverseMappedName);
WebGLActiveInfo *retActiveInfo = new WebGLActiveInfo(attrsize, attrtype, reverseMappedName);
NS_ADDREF(*retval = retActiveInfo);
return NS_OK;
@ -1916,7 +1922,8 @@ WebGLContext::GetActiveUniform(nsIWebGLProgram *pobj, PRUint32 index, nsIWebGLAc
*retval = nsnull;
WebGLuint progname;
if (!GetGLName<WebGLProgram>("getActiveUniform: program", pobj, &progname))
WebGLProgram *prog;
if (!GetConcreteObjectAndGLName("getActiveUniform: program", pobj, &prog, &progname))
return NS_OK;
MakeContextCurrent();
@ -1926,17 +1933,20 @@ WebGLContext::GetActiveUniform(nsIWebGLProgram *pobj, PRUint32 index, nsIWebGLAc
if (len == 0)
*retval = nsnull;
nsAutoArrayPtr<char> name(new char[len + 3]); // +3 because we might have to append "[0]", see below
nsAutoArrayPtr<char> name(new char[len]);
GLint attrsize = 0;
GLuint attrtype = 0;
GLint usize = 0;
GLuint utype = 0;
gl->fGetActiveUniform(progname, index, len, &len, &attrsize, &attrtype, name);
if (len == 0 || attrsize == 0 || attrtype == 0) {
gl->fGetActiveUniform(progname, index, len, &len, &usize, &utype, name);
if (len == 0 || usize == 0 || utype == 0) {
*retval = nsnull;
return NS_OK;
}
nsCString reverseMappedName;
prog->ReverseMapIdentifier(nsDependentCString(name), &reverseMappedName);
// OpenGL ES 2.0 specifies that if foo is a uniform array, GetActiveUniform returns its name as "foo[0]".
// See section 2.10 page 35 in the OpenGL ES 2.0.24 specification:
//
@ -1950,16 +1960,11 @@ WebGLContext::GetActiveUniform(nsIWebGLProgram *pobj, PRUint32 index, nsIWebGLAc
// In principle we don't need to do that on OpenGL ES, but this is such a tricky difference between the ES and non-ES
// specs that it seems probable that some ES implementers will overlook it. Since the work-around is quite cheap,
// we do it unconditionally.
if (attrsize > 1 && name[len-1] != ']') {
name[len++] = '[';
name[len++] = '0';
name[len++] = ']';
}
WebGLActiveInfo *retActiveInfo = new WebGLActiveInfo(attrsize, attrtype, name.get(), len);
if (usize > 1 && reverseMappedName.CharAt(reverseMappedName.Length()-1) != ']')
reverseMappedName.AppendLiteral("[0]");
WebGLActiveInfo *retActiveInfo = new WebGLActiveInfo(usize, utype, reverseMappedName);
NS_ADDREF(*retval = retActiveInfo);
return NS_OK;
}
@ -2009,23 +2014,25 @@ WebGLContext::GetAttribLocation(nsIWebGLProgram *pobj,
const nsAString& name,
PRInt32 *retval)
{
if (!IsContextStable())
{
*retval = -1;
return NS_OK;
}
*retval = -1;
*retval = 0;
if (!IsContextStable())
return NS_OK;
WebGLuint progname;
if (!GetGLName<WebGLProgram>("getAttribLocation: program", pobj, &progname))
WebGLProgram *prog;
if (!GetConcreteObjectAndGLName("getAttribLocation: program", pobj, &prog, &progname))
return NS_OK;
if (!ValidateGLSLVariableName(name, "getAttribLocation"))
return NS_OK;
NS_LossyConvertUTF16toASCII cname(name);
nsCString mappedName;
prog->MapIdentifier(cname, &mappedName);
MakeContextCurrent();
*retval = gl->fGetAttribLocation(progname, NS_LossyConvertUTF16toASCII(name).get());
*retval = gl->fGetAttribLocation(progname, mappedName.get());
return NS_OK;
}
@ -2980,11 +2987,14 @@ WebGLContext::GetUniformLocation(nsIWebGLProgram *pobj, const nsAString& name, n
return NS_OK;
if (!ValidateGLSLVariableName(name, "getUniformLocation"))
return NS_OK;
return NS_OK;
NS_LossyConvertUTF16toASCII cname(name);
nsCString mappedName;
prog->MapIdentifier(cname, &mappedName);
MakeContextCurrent();
GLint intlocation = gl->fGetUniformLocation(progname, NS_LossyConvertUTF16toASCII(name).get());
GLint intlocation = gl->fGetUniformLocation(progname, mappedName.get());
WebGLUniformLocation *loc = nsnull;
if (intlocation >= 0)
@ -3251,18 +3261,16 @@ WebGLContext::LinkProgram(nsIWebGLProgram *pobj)
}
MakeContextCurrent();
gl->fLinkProgram(progname);
GLint ok;
gl->fGetProgramiv(progname, LOCAL_GL_LINK_STATUS, &ok);
if (ok) {
program->SetLinkStatus(true);
program->UpdateInfo(gl);
bool updateInfoSucceeded = program->UpdateInfo();
program->SetLinkStatus(updateInfoSucceeded);
} else {
program->SetLinkStatus(false);
}
return NS_OK;
}
@ -4387,6 +4395,20 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
MakeContextCurrent();
ShShaderOutput targetShaderSourceLanguage = gl->IsGLES2() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT;
bool useShaderSourceTranslation = true;
#ifdef ANDROID
// see bug 709947. On Android, we can't use the ESSL backend because of strange crashes (might be
// an allocator mismatch). So we use the GLSL backend, and discard the output, instead just passing
// the original WebGL shader source to the GL (since that's ESSL already). The problem is that means
// we can't use shader translations on Android, in particular we can't use long identifier shortening,
// which means we can't reach 100% conformance. We need to fix that by debugging the ESSL backend
// memory crashes.
targetShaderSourceLanguage = SH_GLSL_OUTPUT;
useShaderSourceTranslation = false;
#endif
#if defined(USE_ANGLE)
if (shader->NeedsTranslation() && mShaderValidation) {
ShHandle compiler = 0;
@ -4404,20 +4426,6 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
if (mEnabledExtensions[WebGL_OES_standard_derivatives])
resources.OES_standard_derivatives = 1;
// notice that on Android, we always use SH_GLSL_OUTPUT, we never use the ESSL backend.
// see bug 709947, the reason is that 1) we dont really need a ESSL backend since the
// source is already ESSL, and 2) we ran into massive Android crashes when we used the ESSL backend.
// But if we wanted to use shader transformations on ES platforms, we would have to use the
// ESSL backend
compiler = ShConstructCompiler((ShShaderType) shader->ShaderType(),
SH_WEBGL_SPEC,
#ifdef ANDROID
SH_GLSL_OUTPUT,
#else
gl->IsGLES2() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT,
#endif
&resources);
// We're storing an actual instance of StripComments because, if we don't, the
// cleanSource nsAString instance will be destroyed before the reference is
// actually used.
@ -4431,20 +4439,29 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
// shaderSource() already checks that the source stripped of comments is in the
// 7-bit ASCII range, so we can skip the NS_IsAscii() check.
const nsCString& sourceCString = NS_LossyConvertUTF16toASCII(flatSource);
const PRUint32 maxSourceLength = (PRUint32(1)<<18) - 1;
if (sourceCString.Length() > maxSourceLength)
return ErrorInvalidValue("compileShader: source has more than %d characters", maxSourceLength);
const char *s = sourceCString.get();
int compileOptions = SH_OBJECT_CODE;
compiler = ShConstructCompiler((ShShaderType) shader->ShaderType(),
SH_WEBGL_SPEC,
targetShaderSourceLanguage,
&resources);
int compileOptions = 0;
if (useShaderSourceTranslation) {
compileOptions |= SH_OBJECT_CODE
| SH_MAP_LONG_VARIABLE_NAMES
| SH_ATTRIBUTES_UNIFORMS;
#ifdef XP_MACOSX
// work around bug 665578
if (!nsCocoaFeatures::OnLionOrLater() && gl->Vendor() == gl::GLContext::VendorATI)
compileOptions |= SH_EMULATE_BUILT_IN_FUNCTIONS;
// work around bug 665578
if (!nsCocoaFeatures::OnLionOrLater() && gl->Vendor() == gl::GLContext::VendorATI)
compileOptions |= SH_EMULATE_BUILT_IN_FUNCTIONS;
#endif
}
if (!ShCompile(compiler, &s, 1, compileOptions)) {
int len = 0;
@ -4462,11 +4479,50 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
return NS_OK;
}
/* If the GL context is really GLES2, we want to use the original provided code,
* since it's actually GLES2. We still need to validate it however, which is
* why we ran it through the above, but we don't want the desktop GLSL.
*/
if (!gl->IsGLES2()) {
int num_attributes = 0;
ShGetInfo(compiler, SH_ACTIVE_ATTRIBUTES, &num_attributes);
int num_uniforms = 0;
ShGetInfo(compiler, SH_ACTIVE_UNIFORMS, &num_uniforms);
int attrib_max_length = 0;
ShGetInfo(compiler, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &attrib_max_length);
int uniform_max_length = 0;
ShGetInfo(compiler, SH_ACTIVE_UNIFORM_MAX_LENGTH, &uniform_max_length);
int mapped_max_length = 0;
ShGetInfo(compiler, SH_MAPPED_NAME_MAX_LENGTH, &mapped_max_length);
shader->mAttribMaxNameLength = attrib_max_length;
shader->mAttributes.Clear();
shader->mUniforms.Clear();
nsAutoArrayPtr<char> attribute_name(new char[attrib_max_length+1]);
nsAutoArrayPtr<char> uniform_name(new char[uniform_max_length+1]);
nsAutoArrayPtr<char> mapped_name(new char[mapped_max_length+1]);
if (useShaderSourceTranslation) {
for (int i = 0; i < num_attributes; i++) {
int length, size;
ShDataType type;
ShGetActiveAttrib(compiler, i,
&length, &size, &type,
attribute_name,
mapped_name);
shader->mAttributes.AppendElement(WebGLMappedIdentifier(
nsDependentCString(attribute_name),
nsDependentCString(mapped_name)));
}
for (int i = 0; i < num_uniforms; i++) {
int length, size;
ShDataType type;
ShGetActiveUniform(compiler, i,
&length, &size, &type,
uniform_name,
mapped_name);
shader->mUniforms.AppendElement(WebGLMappedIdentifier(
nsDependentCString(uniform_name),
nsDependentCString(mapped_name)));
}
int len = 0;
ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &len);
@ -4478,7 +4534,10 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
const char *ts = translatedSrc2.get();
gl->fShaderSource(shadername, 1, &ts, NULL);
} else {
} else { // not useShaderSourceTranslation
// we just pass the raw untranslated shader source. We then can't use ANGLE idenfier mapping.
// that's really bad, as that means we can't be 100% conformant. We should work towards always
// using ANGLE identifier mapping.
gl->fShaderSource(shadername, 1, &s, NULL);
}

Просмотреть файл

@ -49,38 +49,46 @@
#include "angle/ShaderLang.h"
#endif
#include <algorithm>
using namespace mozilla;
/*
* Pull all the data out of the program that will be used by validate later on
* Pull data out of the program, post-linking
*/
bool
WebGLProgram::UpdateInfo(gl::GLContext *gl)
WebGLProgram::UpdateInfo()
{
gl->fGetProgramiv(mGLName, LOCAL_GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &mAttribMaxNameLength);
gl->fGetProgramiv(mGLName, LOCAL_GL_ACTIVE_UNIFORM_MAX_LENGTH, &mUniformMaxNameLength);
gl->fGetProgramiv(mGLName, LOCAL_GL_ACTIVE_UNIFORMS, &mUniformCount);
gl->fGetProgramiv(mGLName, LOCAL_GL_ACTIVE_ATTRIBUTES, &mAttribCount);
mIdentifierMap = nsnull;
mIdentifierReverseMap = nsnull;
GLint numVertexAttribs;
if (mContext->MinCapabilityMode()) {
numVertexAttribs = MINVALUE_GL_MAX_VERTEX_ATTRIBS;
} else {
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &numVertexAttribs);
}
mAttribsInUse.clear();
mAttribsInUse.resize(numVertexAttribs);
mAttribMaxNameLength = 0;
for (size_t i = 0; i < mAttachedShaders.Length(); i++)
mAttribMaxNameLength = NS_MAX(mAttribMaxNameLength, mAttachedShaders[i]->mAttribMaxNameLength);
GLint attribCount;
mContext->gl->fGetProgramiv(mGLName, LOCAL_GL_ACTIVE_ATTRIBUTES, &attribCount);
mAttribsInUse.resize(mContext->mGLMaxVertexAttribs);
std::fill(mAttribsInUse.begin(), mAttribsInUse.end(), false);
nsAutoArrayPtr<char> nameBuf(new char[mAttribMaxNameLength]);
for (int i = 0; i < mAttribCount; ++i) {
for (int i = 0; i < attribCount; ++i) {
GLint attrnamelen;
GLint attrsize;
GLenum attrtype;
gl->fGetActiveAttrib(mGLName, i, mAttribMaxNameLength, &attrnamelen, &attrsize, &attrtype, nameBuf);
mContext->gl->fGetActiveAttrib(mGLName, i, mAttribMaxNameLength, &attrnamelen, &attrsize, &attrtype, nameBuf);
if (attrnamelen > 0) {
GLint loc = gl->fGetAttribLocation(mGLName, nameBuf);
mAttribsInUse[loc] = true;
GLint loc = mContext->gl->fGetAttribLocation(mGLName, nameBuf);
NS_ABORT_IF_FALSE(loc >= 0, "major oops in managing the attributes of a WebGL program");
if (loc < mContext->mGLMaxVertexAttribs) {
mAttribsInUse[loc] = true;
} else {
mContext->ErrorInvalidOperation("program exceeds MAX_VERTEX_ATTRIBS");
return false;
}
}
}
@ -334,7 +342,7 @@ bool WebGLContext::ValidateDrawModeEnum(WebGLenum mode, const char *info)
bool WebGLContext::ValidateGLSLVariableName(const nsAString& name, const char *info)
{
const PRUint32 maxSize = 255;
const PRUint32 maxSize = 256;
if (name.Length() > maxSize) {
ErrorInvalidValue("%s: identifier is %d characters long, exceeds the maximum allowed length of %d characters",
info, name.Length(), maxSize);

Просмотреть файл

@ -1,13 +1,8 @@
conformance/context/premultiplyalpha-test.html
conformance/glsl/misc/glsl-long-variable-names.html
conformance/glsl/misc/shader-with-256-character-identifier.frag.html
conformance/glsl/misc/shader-with-long-line.html
conformance/misc/uninitialized-test.html
conformance/programs/gl-get-active-attribute.html
conformance/textures/texture-mips.html
conformance/uniforms/gl-uniform-bool.html
conformance/more/conformance/quickCheckAPI-S_V.html
conformance/more/functions/uniformfArrayLen1.html
conformance/glsl/misc/attrib-location-length-limits.html
conformance/glsl/misc/uniform-location-length-limits.html
conformance/renderbuffers/framebuffer-object-attachment.html

Просмотреть файл

@ -1,11 +1,6 @@
conformance/context/premultiplyalpha-test.html
conformance/glsl/misc/glsl-function-nodes.html
conformance/glsl/misc/glsl-long-variable-names.html
conformance/glsl/misc/shader-with-256-character-identifier.frag.html
conformance/glsl/misc/shader-with-long-line.html
conformance/more/conformance/quickCheckAPI-S_V.html
conformance/glsl/misc/attrib-location-length-limits.html
conformance/glsl/misc/uniform-location-length-limits.html
conformance/programs/program-test.html
conformance/textures/texture-mips.html
conformance/textures/texture-npot.html

Просмотреть файл

@ -1,11 +1,6 @@
conformance/context/premultiplyalpha-test.html
conformance/glsl/functions/glsl-function-atan.html
conformance/glsl/functions/glsl-function-atan-xy.html
conformance/glsl/misc/glsl-long-variable-names.html
conformance/glsl/misc/shader-with-256-character-identifier.frag.html
conformance/glsl/misc/shader-with-long-line.html
conformance/more/conformance/quickCheckAPI-S_V.html
conformance/more/functions/uniformfArrayLen1.html
conformance/glsl/misc/attrib-location-length-limits.html
conformance/glsl/misc/struct-nesting-under-maximum.html
conformance/glsl/misc/uniform-location-length-limits.html

Просмотреть файл

@ -105,3 +105,5 @@ ShGetInfoLog
ShCompile
ShGetInfo
ShConstructCompiler
ShGetActiveAttrib
ShGetActiveUniform