Bug 1325301 (flattened) - Validate attribute base types match data base types. - r=bz,daoshengmu

Flattened with:
* Clean up generic vertex attribs. - r=bz,daoshengmu
* Remove EnsureAttrib() and friends. - r=daoshengmu
* Simplify EnumName behavior and usage and add ErrorInvalidEnumArg(). - r=daoshengmu
This commit is contained in:
Jeff Gilbert 2016-12-21 19:42:07 -08:00
Родитель 59ad1b29d3
Коммит 0b065a7b71
27 изменённых файлов: 416 добавлений и 457 удалений

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

@ -243,8 +243,10 @@ public:
////////////////
// GL 3.0 & ES 3.0
void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w,
const char* funcName = nullptr);
void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w,
const char* funcName = nullptr);
void VertexAttribI4iv(GLuint index, const Int32ListU& list) {
const auto& arr = Int32Arr::From(list);

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

@ -325,9 +325,11 @@ WebGL2Context::ReadBuffer(GLenum mode)
if (mode != LOCAL_GL_NONE &&
mode != LOCAL_GL_BACK)
{
nsCString enumName;
EnumName(mode, &enumName);
ErrorInvalidOperation("%s: If READ_FRAMEBUFFER is null, `mode` must be BACK or"
" NONE. Was %s",
funcName, EnumName(mode));
" NONE. Was %s.",
funcName, enumName.BeginReading());
return;
}

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

@ -139,7 +139,7 @@ WebGL2Context::GetSamplerParameter(JSContext*, const WebGLSampler& sampler, GLen
return;
default:
ErrorInvalidEnum("%s: invalid pname: %s", funcName, EnumName(pname));
ErrorInvalidEnumArg(funcName, "pname", pname);
return;
}
}

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

@ -161,7 +161,7 @@ ValidateUniformEnum(WebGLContext* webgl, GLenum pname, const char* info)
return true;
default:
webgl->ErrorInvalidEnum("%s: invalid pname: %s", info, webgl->EnumName(pname));
webgl->ErrorInvalidEnumArg(info, "pname", pname);
return false;
}
}

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

@ -76,7 +76,6 @@ WebGL2Context::VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsiz
}
MOZ_ASSERT(mBoundVertexArray);
mBoundVertexArray->EnsureAttrib(index);
InvalidateBufferFetching();
@ -90,56 +89,4 @@ WebGL2Context::VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsiz
offset);
}
void
WebGL2Context::VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
{
if (IsContextLost())
return;
if (!ValidateAttribIndex(index, "vertexAttribI4i"))
return;
mVertexAttribType[index] = LOCAL_GL_INT;
MakeContextCurrent();
if (index) {
gl->fVertexAttribI4i(index, x, y, z, w);
} else {
mVertexAttrib0Vector[0] = BitwiseCast<GLfloat>(x);
mVertexAttrib0Vector[1] = BitwiseCast<GLfloat>(y);
mVertexAttrib0Vector[2] = BitwiseCast<GLfloat>(z);
mVertexAttrib0Vector[3] = BitwiseCast<GLfloat>(w);
if (gl->IsGLES()) {
gl->fVertexAttribI4i(index, x, y, z, w);
}
}
}
void
WebGL2Context::VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
{
if (IsContextLost())
return;
if (!ValidateAttribIndex(index, "vertexAttribI4ui"))
return;
mVertexAttribType[index] = LOCAL_GL_UNSIGNED_INT;
MakeContextCurrent();
if (index) {
gl->fVertexAttribI4ui(index, x, y, z, w);
} else {
mVertexAttrib0Vector[0] = BitwiseCast<GLfloat>(x);
mVertexAttrib0Vector[1] = BitwiseCast<GLfloat>(y);
mVertexAttrib0Vector[2] = BitwiseCast<GLfloat>(z);
mVertexAttrib0Vector[3] = BitwiseCast<GLfloat>(w);
if (gl->IsGLES()) {
gl->fVertexAttribI4ui(index, x, y, z, w);
}
}
}
} // namespace mozilla

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

@ -143,18 +143,6 @@ WebGLContext::WebGLContext()
mActiveTexture = 0;
mVertexAttrib0Vector[0] = 0;
mVertexAttrib0Vector[1] = 0;
mVertexAttrib0Vector[2] = 0;
mVertexAttrib0Vector[3] = 1;
mFakeVertexAttrib0BufferObjectVector[0] = 0;
mFakeVertexAttrib0BufferObjectVector[1] = 0;
mFakeVertexAttrib0BufferObjectVector[2] = 0;
mFakeVertexAttrib0BufferObjectVector[3] = 1;
mFakeVertexAttrib0BufferObjectSize = 0;
mFakeVertexAttrib0BufferObject = 0;
mFakeVertexAttrib0BufferStatus = WebGLVertexAttrib0Status::Default;
mStencilRefFront = 0;
mStencilRefBack = 0;
mStencilValueMaskFront = 0;

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

@ -408,17 +408,17 @@ public:
void ErrorOutOfMemory(const char* fmt = 0, ...);
void ErrorImplementationBug(const char* fmt = 0, ...);
void ErrorInvalidEnumArg(const char* funcName, const char* argName, GLenum val);
const char* ErrorName(GLenum error);
/**
* Return displayable name for GLenum.
* This version is like gl::GLenumToStr but with out the GL_ prefix to
* keep consistency with how errors are reported from WebGL.
* Returns hex formatted version of glenum if glenum is unknown.
*/
// Returns nullptr if glenum is unknown.
static const char* EnumName(GLenum glenum);
// Returns hex formatted version of glenum if glenum is unknown.
static void EnumName(GLenum glenum, nsACString* out_name);
static void EnumName(GLenum val, nsCString* out_name);
void DummyReadFramebufferOperation(const char* funcName);
@ -1286,44 +1286,65 @@ public:
WebGLsizeiptr GetVertexAttribOffset(GLuint index, GLenum pname);
void VertexAttrib1f(GLuint index, GLfloat x0);
void VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1);
void VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2);
void VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2,
GLfloat x3);
////
void VertexAttrib1fv(GLuint idx, const dom::Float32Array& arr) {
arr.ComputeLengthAndData();
VertexAttrib1fv_base(idx, arr.LengthAllowShared(), arr.DataAllowShared());
void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w,
const char* funcName = nullptr);
////
void VertexAttrib1f(GLuint index, GLfloat x) {
VertexAttrib4f(index, x, 0, 0, 1, "vertexAttrib1f");
}
void VertexAttrib1fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
VertexAttrib1fv_base(idx, arr.Length(), arr.Elements());
void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {
VertexAttrib4f(index, x, y, 0, 1, "vertexAttrib2f");
}
void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
VertexAttrib4f(index, x, y, z, 1, "vertexAttrib3f");
}
void VertexAttrib2fv(GLuint idx, const dom::Float32Array& arr) {
arr.ComputeLengthAndData();
VertexAttrib2fv_base(idx, arr.LengthAllowShared(), arr.DataAllowShared());
}
void VertexAttrib2fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
VertexAttrib2fv_base(idx, arr.Length(), arr.Elements());
////
void VertexAttrib1fv(GLuint index, const Float32ListU& list) {
const char funcName[] = "vertexAttrib1fv";
const auto& arr = Float32Arr::From(list);
if (!ValidateAttribArraySetter(funcName, 1, arr.elemCount))
return;
VertexAttrib4f(index, arr.elemBytes[0], 0, 0, 1, funcName);
}
void VertexAttrib3fv(GLuint idx, const dom::Float32Array& arr) {
arr.ComputeLengthAndData();
VertexAttrib3fv_base(idx, arr.LengthAllowShared(), arr.DataAllowShared());
}
void VertexAttrib3fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
VertexAttrib3fv_base(idx, arr.Length(), arr.Elements());
void VertexAttrib2fv(GLuint index, const Float32ListU& list) {
const char funcName[] = "vertexAttrib2fv";
const auto& arr = Float32Arr::From(list);
if (!ValidateAttribArraySetter(funcName, 2, arr.elemCount))
return;
VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], 0, 1, funcName);
}
void VertexAttrib4fv(GLuint idx, const dom::Float32Array& arr) {
arr.ComputeLengthAndData();
VertexAttrib4fv_base(idx, arr.LengthAllowShared(), arr.DataAllowShared());
void VertexAttrib3fv(GLuint index, const Float32ListU& list) {
const char funcName[] = "vertexAttrib3fv";
const auto& arr = Float32Arr::From(list);
if (!ValidateAttribArraySetter(funcName, 3, arr.elemCount))
return;
VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], arr.elemBytes[2], 1,
funcName);
}
void VertexAttrib4fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
VertexAttrib4fv_base(idx, arr.Length(), arr.Elements());
void VertexAttrib4fv(GLuint index, const Float32ListU& list) {
const char funcName[] = "vertexAttrib4fv";
const auto& arr = Float32Arr::From(list);
if (!ValidateAttribArraySetter(funcName, 4, arr.elemCount))
return;
VertexAttrib4f(index, arr.elemBytes[0], arr.elemBytes[1], arr.elemBytes[2],
arr.elemBytes[3], funcName);
}
////
void VertexAttribPointer(GLuint index, GLint size, GLenum type,
WebGLboolean normalized, GLsizei stride,
WebGLintptr byteOffset);
@ -1361,8 +1382,8 @@ private:
// -----------------------------------------------------------------------------
// PROTECTED
protected:
WebGLVertexAttrib0Status WhatDoesVertexAttrib0Need();
bool DoFakeVertexAttrib0(GLuint vertexCount);
WebGLVertexAttrib0Status WhatDoesVertexAttrib0Need() const;
bool DoFakeVertexAttrib0(const char* funcName, GLuint vertexCount);
void UndoFakeVertexAttrib0();
inline void InvalidateBufferFetching()
@ -1409,7 +1430,7 @@ protected:
webgl::ShaderValidator* CreateShaderValidator(GLenum shaderType) const;
// some GL constants
int32_t mGLMaxVertexAttribs;
uint32_t mGLMaxVertexAttribs;
int32_t mGLMaxTextureUnits;
int32_t mGLMaxTextureImageUnits;
int32_t mGLMaxVertexTextureImageUnits;
@ -1873,16 +1894,17 @@ public:
protected:
// Generic Vertex Attributes
UniquePtr<GLenum[]> mVertexAttribType;
GLfloat mVertexAttrib0Vector[4];
GLfloat mFakeVertexAttrib0BufferObjectVector[4];
size_t mFakeVertexAttrib0BufferObjectSize;
GLuint mFakeVertexAttrib0BufferObject;
WebGLVertexAttrib0Status mFakeVertexAttrib0BufferStatus;
// Though CURRENT_VERTEX_ATTRIB is listed under "Vertex Shader State" in the spec
// state tables, this isn't vertex shader /object/ state. This array is merely state
// useful to vertex shaders, but is global state.
UniquePtr<GLenum[]> mGenericVertexAttribTypes;
uint8_t mGenericVertexAttrib0Data[sizeof(float) * 4];
GLuint mFakeVertexAttrib0BufferObject;
size_t mFakeVertexAttrib0BufferObjectSize;
bool mFakeVertexAttrib0DataDefined;
uint8_t mFakeVertexAttrib0Data[sizeof(float) * 4];
void GetVertexAttribFloat(GLuint index, GLfloat* out_result);
void GetVertexAttribInt(GLuint index, GLint* out_result);
void GetVertexAttribUint(GLuint index, GLuint* out_result);
JSObject* GetVertexAttribFloat32Array(JSContext* cx, GLuint index);
JSObject* GetVertexAttribInt32Array(JSContext* cx, GLuint index);
JSObject* GetVertexAttribUint32Array(JSContext* cx, GLuint index);

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

@ -506,10 +506,8 @@ WebGLContext::DeleteBuffer(WebGLBuffer* buffer)
}
}
for (int32_t i = 0; i < mGLMaxVertexAttribs; i++) {
if (mBoundVertexArray->HasAttrib(i)) {
fnClearIfBuffer(mBoundVertexArray->mAttribs[i].mBuf);
}
for (auto& cur : mBoundVertexArray->mAttribs) {
fnClearIfBuffer(cur.mBuf);
}
////

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

@ -346,7 +346,7 @@ public:
////
const size_t requiredVerts = firstVertex + vertCount;
if (!mWebGL->DoFakeVertexAttrib0(requiredVerts)) {
if (!mWebGL->DoFakeVertexAttrib0(funcName, requiredVerts)) {
*out_error = true;
return;
}
@ -394,6 +394,33 @@ public:
////
for (const auto& progAttrib : mWebGL->mActiveProgramLinkInfo->attribs) {
const auto& loc = progAttrib.mLoc;
const auto& attribData = mWebGL->mBoundVertexArray->mAttribs[loc];
GLenum attribDataBaseType;
if (attribData.mEnabled) {
attribDataBaseType = attribData.BaseType();
} else {
attribDataBaseType = mWebGL->mGenericVertexAttribTypes[loc];
}
if (attribDataBaseType != progAttrib.mBaseType) {
nsCString progType, dataType;
WebGLContext::EnumName(progAttrib.mBaseType, &progType);
WebGLContext::EnumName(attribDataBaseType, &dataType);
mWebGL->ErrorInvalidOperation("%s: Vertex attrib %u requires data of type"
" %s, but is being supplied with type %s.",
funcName, loc, progType.BeginReading(),
dataType.BeginReading());
*out_error = true;
return;
}
}
////
mWebGL->RunContextLossTimer();
}
@ -686,9 +713,11 @@ WebGLContext::DrawElements_check(const char* funcName, GLenum mode, GLsizei vert
// Bug 1008310 - Check if buffer has been used with a different previous type
if (elemArrayBuffer.IsElementArrayUsedWithMultipleTypes()) {
nsCString typeName;
WebGLContext::EnumName(type, &typeName);
GenerateWarning("%s: bound element array buffer previously used with a type other than "
"%s, this will affect performance.",
funcName, WebGLContext::EnumName(type));
funcName, typeName.BeginReading());
}
return true;
@ -957,23 +986,25 @@ WebGLContext::ValidateBufferFetching(const char* info)
}
WebGLVertexAttrib0Status
WebGLContext::WhatDoesVertexAttrib0Need()
WebGLContext::WhatDoesVertexAttrib0Need() const
{
MOZ_ASSERT(mCurrentProgram);
MOZ_ASSERT(mActiveProgramLinkInfo);
const auto& isAttribArray0Enabled = mBoundVertexArray->mAttribs[0].mEnabled;
// work around Mac OSX crash, see bug 631420
#ifdef XP_MACOSX
if (gl->WorkAroundDriverBugs() &&
mBoundVertexArray->IsAttribArrayEnabled(0) &&
isAttribArray0Enabled &&
!mBufferFetch_IsAttrib0Active)
{
return WebGLVertexAttrib0Status::EmulatedUninitializedArray;
}
#endif
if (MOZ_LIKELY(gl->IsGLES() ||
mBoundVertexArray->IsAttribArrayEnabled(0)))
if (MOZ_LIKELY(!gl->IsCompatibilityProfile() ||
isAttribArray0Enabled))
{
return WebGLVertexAttrib0Status::Default;
}
@ -984,10 +1015,13 @@ WebGLContext::WhatDoesVertexAttrib0Need()
}
bool
WebGLContext::DoFakeVertexAttrib0(GLuint vertexCount)
WebGLContext::DoFakeVertexAttrib0(const char* funcName, GLuint vertexCount)
{
WebGLVertexAttrib0Status whatDoesAttrib0Need = WhatDoesVertexAttrib0Need();
if (!vertexCount) {
vertexCount = 1;
}
const auto whatDoesAttrib0Need = WhatDoesVertexAttrib0Need();
if (MOZ_LIKELY(whatDoesAttrib0Need == WebGLVertexAttrib0Status::Default))
return true;
@ -1000,88 +1034,101 @@ WebGLContext::DoFakeVertexAttrib0(GLuint vertexCount)
mAlreadyWarnedAboutFakeVertexAttrib0 = true;
}
CheckedUint32 checked_dataSize = CheckedUint32(vertexCount) * 4 * sizeof(GLfloat);
if (!mFakeVertexAttrib0BufferObject) {
gl->fGenBuffers(1, &mFakeVertexAttrib0BufferObject);
mFakeVertexAttrib0BufferObjectSize = 0;
}
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mFakeVertexAttrib0BufferObject);
////
switch (mGenericVertexAttribTypes[0]) {
case LOCAL_GL_FLOAT:
gl->fVertexAttribPointer(0, 4, LOCAL_GL_FLOAT, false, 0, 0);
break;
case LOCAL_GL_INT:
gl->fVertexAttribIPointer(0, 4, LOCAL_GL_INT, 0, 0);
break;
case LOCAL_GL_UNSIGNED_INT:
gl->fVertexAttribIPointer(0, 4, LOCAL_GL_UNSIGNED_INT, 0, 0);
break;
default:
MOZ_CRASH();
}
////
const auto bytesPerVert = sizeof(mFakeVertexAttrib0Data);
const auto checked_dataSize = CheckedUint32(vertexCount) * bytesPerVert;
if (!checked_dataSize.isValid()) {
ErrorOutOfMemory("Integer overflow trying to construct a fake vertex attrib 0 array for a draw-operation "
"with %d vertices. Try reducing the number of vertices.", vertexCount);
return false;
}
const auto dataSize = checked_dataSize.value();
GLuint dataSize = checked_dataSize.value();
if (!mFakeVertexAttrib0BufferObject) {
gl->fGenBuffers(1, &mFakeVertexAttrib0BufferObject);
if (mFakeVertexAttrib0BufferObjectSize < dataSize) {
gl->fBufferData(LOCAL_GL_ARRAY_BUFFER, dataSize, nullptr, LOCAL_GL_DYNAMIC_DRAW);
mFakeVertexAttrib0BufferObjectSize = dataSize;
mFakeVertexAttrib0DataDefined = false;
}
// if the VBO status is already exactly what we need, or if the only difference is that it's initialized and
// we don't need it to be, then consider it OK
bool vertexAttrib0BufferStatusOK =
mFakeVertexAttrib0BufferStatus == whatDoesAttrib0Need ||
(mFakeVertexAttrib0BufferStatus == WebGLVertexAttrib0Status::EmulatedInitializedArray &&
whatDoesAttrib0Need == WebGLVertexAttrib0Status::EmulatedUninitializedArray);
if (whatDoesAttrib0Need == WebGLVertexAttrib0Status::EmulatedUninitializedArray)
return true;
if (!vertexAttrib0BufferStatusOK ||
mFakeVertexAttrib0BufferObjectSize < dataSize ||
mFakeVertexAttrib0BufferObjectVector[0] != mVertexAttrib0Vector[0] ||
mFakeVertexAttrib0BufferObjectVector[1] != mVertexAttrib0Vector[1] ||
mFakeVertexAttrib0BufferObjectVector[2] != mVertexAttrib0Vector[2] ||
mFakeVertexAttrib0BufferObjectVector[3] != mVertexAttrib0Vector[3])
////
if (mFakeVertexAttrib0DataDefined &&
memcmp(mFakeVertexAttrib0Data, mGenericVertexAttrib0Data, bytesPerVert) == 0)
{
mFakeVertexAttrib0BufferStatus = whatDoesAttrib0Need;
mFakeVertexAttrib0BufferObjectSize = dataSize;
mFakeVertexAttrib0BufferObjectVector[0] = mVertexAttrib0Vector[0];
mFakeVertexAttrib0BufferObjectVector[1] = mVertexAttrib0Vector[1];
mFakeVertexAttrib0BufferObjectVector[2] = mVertexAttrib0Vector[2];
mFakeVertexAttrib0BufferObjectVector[3] = mVertexAttrib0Vector[3];
return true;
}
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mFakeVertexAttrib0BufferObject);
////
GetAndFlushUnderlyingGLErrors();
const UniqueBuffer data(malloc(dataSize));
if (!data) {
ErrorOutOfMemory("%s: Failed to allocate fake vertex attrib 0 array.",
funcName);
return false;
}
auto itr = (uint8_t*)data.get();
const auto itrEnd = itr + dataSize;
while (itr != itrEnd) {
memcpy(itr, mGenericVertexAttrib0Data, bytesPerVert);
itr += bytesPerVert;
}
if (mFakeVertexAttrib0BufferStatus == WebGLVertexAttrib0Status::EmulatedInitializedArray) {
auto array = MakeUniqueFallible<GLfloat[]>(4 * vertexCount);
if (!array) {
ErrorOutOfMemory("Fake attrib0 array.");
return false;
}
for(size_t i = 0; i < vertexCount; ++i) {
array[4 * i + 0] = mVertexAttrib0Vector[0];
array[4 * i + 1] = mVertexAttrib0Vector[1];
array[4 * i + 2] = mVertexAttrib0Vector[2];
array[4 * i + 3] = mVertexAttrib0Vector[3];
}
gl->fBufferData(LOCAL_GL_ARRAY_BUFFER, dataSize, array.get(), LOCAL_GL_DYNAMIC_DRAW);
} else {
gl->fBufferData(LOCAL_GL_ARRAY_BUFFER, dataSize, nullptr, LOCAL_GL_DYNAMIC_DRAW);
}
GLenum error = GetAndFlushUnderlyingGLErrors();
{
gl::GLContext::LocalErrorScope errorScope(*gl);
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0);
gl->fBufferSubData(LOCAL_GL_ARRAY_BUFFER, 0, dataSize, data.get());
// note that we do this error checking and early return AFTER having restored the buffer binding above
if (error) {
ErrorOutOfMemory("Ran out of memory trying to construct a fake vertex attrib 0 array for a draw-operation "
"with %d vertices. Try reducing the number of vertices.", vertexCount);
const auto err = errorScope.GetError();
if (err) {
ErrorOutOfMemory("%s: Failed to upload fake vertex attrib 0 data.", funcName);
return false;
}
}
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mFakeVertexAttrib0BufferObject);
gl->fVertexAttribPointer(0, 4, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, 0);
////
memcpy(mFakeVertexAttrib0Data, mGenericVertexAttrib0Data, bytesPerVert);
mFakeVertexAttrib0DataDefined = true;
return true;
}
void
WebGLContext::UndoFakeVertexAttrib0()
{
WebGLVertexAttrib0Status whatDoesAttrib0Need = WhatDoesVertexAttrib0Need();
const auto whatDoesAttrib0Need = WhatDoesVertexAttrib0Need();
if (MOZ_LIKELY(whatDoesAttrib0Need == WebGLVertexAttrib0Status::Default))
return;
if (mBoundVertexArray->HasAttrib(0) && mBoundVertexArray->mAttribs[0].mBuf) {
if (mBoundVertexArray->mAttribs[0].mBuf) {
const WebGLVertexAttribData& attrib0 = mBoundVertexArray->mAttribs[0];
gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, attrib0.mBuf->mGLName);
attrib0.DoVertexAttribPointer(gl, 0);

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

@ -246,12 +246,13 @@ WebGLContext::ErrorName(GLenum error)
}
}
// This version is 'fallible' and will return NULL if glenum is not recognized.
const char*
WebGLContext::EnumName(GLenum glenum)
// This version is fallible and will return nullptr if unrecognized.
static const char*
GetEnumName(GLenum val)
{
switch (glenum) {
switch (val) {
#define XX(x) case LOCAL_GL_##x: return #x
XX(NONE);
XX(ALPHA);
XX(ATC_RGB);
XX(ATC_RGBA_EXPLICIT_ALPHA);
@ -273,6 +274,7 @@ WebGLContext::EnumName(GLenum glenum)
XX(DRAW_FRAMEBUFFER);
XX(ETC1_RGB8_OES);
XX(FLOAT);
XX(INT);
XX(FRAMEBUFFER);
XX(HALF_FLOAT);
XX(LUMINANCE);
@ -574,16 +576,24 @@ WebGLContext::EnumName(GLenum glenum)
return nullptr;
}
void
WebGLContext::EnumName(GLenum glenum, nsACString* out_name)
/*static*/ void
WebGLContext::EnumName(GLenum val, nsCString* out_name)
{
const char* name = EnumName(glenum);
const char* name = GetEnumName(val);
if (name) {
*out_name = nsDependentCString(name);
} else {
nsPrintfCString enumAsHex("<enum 0x%04x>", glenum);
*out_name = enumAsHex;
*out_name = name;
return;
}
*out_name = nsPrintfCString("<enum 0x%04x>", val);
}
void
WebGLContext::ErrorInvalidEnumArg(const char* funcName, const char* argName, GLenum val)
{
nsCString enumName;
EnumName(val, &enumName);
ErrorInvalidEnum("%s: Bad `%s`: %s", funcName, argName, enumName.BeginReading());
}
bool

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

@ -543,7 +543,7 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
if (MinCapabilityMode())
mGLMaxVertexAttribs = MINVALUE_GL_MAX_VERTEX_ATTRIBS;
else
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &mGLMaxVertexAttribs);
gl->GetUIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &mGLMaxVertexAttribs);
if (mGLMaxVertexAttribs < 8) {
const nsPrintfCString reason("GL_MAX_VERTEX_ATTRIBS: %d is < 8!",
@ -740,13 +740,6 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
return false;
}
// Default value for all disabled vertex attributes is [0, 0, 0, 1]
mVertexAttribType = MakeUnique<GLenum[]>(mGLMaxVertexAttribs);
for (int32_t index = 0; index < mGLMaxVertexAttribs; ++index) {
mVertexAttribType[index] = LOCAL_GL_FLOAT;
VertexAttrib4f(index, 0, 0, 0, 1);
}
mDefaultVertexArray = WebGLVertexArray::Create(this);
mDefaultVertexArray->mAttribs.SetLength(mGLMaxVertexAttribs);
mBoundVertexArray = mDefaultVertexArray;
@ -783,6 +776,15 @@ WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
mPrimRestartTypeBytes = 0;
mGenericVertexAttribTypes.reset(new GLenum[mGLMaxVertexAttribs]);
std::fill_n(mGenericVertexAttribTypes.get(), mGLMaxVertexAttribs, LOCAL_GL_FLOAT);
static const float kDefaultGenericVertexAttribData[4] = { 0, 0, 0, 1 };
memcpy(mGenericVertexAttrib0Data, kDefaultGenericVertexAttribData,
sizeof(mGenericVertexAttrib0Data));
mFakeVertexAttrib0BufferObject = 0;
return true;
}
@ -809,8 +811,7 @@ WebGLContext::ValidateFramebufferTarget(GLenum target,
return true;
}
ErrorInvalidEnum("%s: Invalid target: %s (0x%04x).", info, EnumName(target),
target);
ErrorInvalidEnumArg(info, "target", target);
return false;
}

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

@ -20,50 +20,15 @@
namespace mozilla {
void
WebGLContext::GetVertexAttribFloat(GLuint index, GLfloat* out_result)
{
if (index) {
gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, out_result);
} else {
out_result[0] = mVertexAttrib0Vector[0];
out_result[1] = mVertexAttrib0Vector[1];
out_result[2] = mVertexAttrib0Vector[2];
out_result[3] = mVertexAttrib0Vector[3];
}
}
void
WebGLContext::GetVertexAttribInt(GLuint index, GLint* out_result)
{
if (index) {
gl->fGetVertexAttribIiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, out_result);
} else {
out_result[0] = BitwiseCast<GLint>(mVertexAttrib0Vector[0]);
out_result[1] = BitwiseCast<GLint>(mVertexAttrib0Vector[1]);
out_result[2] = BitwiseCast<GLint>(mVertexAttrib0Vector[2]);
out_result[3] = BitwiseCast<GLint>(mVertexAttrib0Vector[3]);
}
}
void
WebGLContext::GetVertexAttribUint(GLuint index, GLuint* out_result)
{
if (index) {
gl->fGetVertexAttribIuiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, out_result);
} else {
out_result[0] = BitwiseCast<GLuint>(mVertexAttrib0Vector[0]);
out_result[1] = BitwiseCast<GLuint>(mVertexAttrib0Vector[1]);
out_result[2] = BitwiseCast<GLuint>(mVertexAttrib0Vector[2]);
out_result[3] = BitwiseCast<GLuint>(mVertexAttrib0Vector[3]);
}
}
JSObject*
WebGLContext::GetVertexAttribFloat32Array(JSContext* cx, GLuint index)
{
GLfloat attrib[4];
GetVertexAttribFloat(index, &attrib[0]);
if (index) {
gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, attrib);
} else {
memcpy(attrib, mGenericVertexAttrib0Data, sizeof(mGenericVertexAttrib0Data));
}
return dom::Float32Array::Create(cx, this, 4, attrib);
}
@ -71,218 +36,122 @@ JSObject*
WebGLContext::GetVertexAttribInt32Array(JSContext* cx, GLuint index)
{
GLint attrib[4];
GetVertexAttribInt(index, &attrib[0]);
if (index) {
gl->fGetVertexAttribIiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, attrib);
} else {
memcpy(attrib, mGenericVertexAttrib0Data, sizeof(mGenericVertexAttrib0Data));
}
return dom::Int32Array::Create(cx, this, 4, attrib);
}
JSObject*
WebGLContext::GetVertexAttribUint32Array(JSContext* cx, GLuint index) {
WebGLContext::GetVertexAttribUint32Array(JSContext* cx, GLuint index)
{
GLuint attrib[4];
GetVertexAttribUint(index, &attrib[0]);
if (index) {
gl->fGetVertexAttribIuiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, attrib);
} else {
memcpy(attrib, mGenericVertexAttrib0Data, sizeof(mGenericVertexAttrib0Data));
}
return dom::Uint32Array::Create(cx, this, 4, attrib);
}
////////////////////////////////////////
void
WebGLContext::VertexAttrib1f(GLuint index, GLfloat x0)
WebGLContext::VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w,
const char* funcName)
{
if (!funcName) {
funcName = "vertexAttrib4f";
}
if (IsContextLost())
return;
if (!ValidateAttribIndex(index, "vertexAttrib1f"))
if (!ValidateAttribIndex(index, funcName))
return;
mVertexAttribType[index] = LOCAL_GL_FLOAT;
////
MakeContextCurrent();
gl->MakeCurrent();
if (index || !gl->IsCompatibilityProfile()) {
gl->fVertexAttrib4f(index, x, y, z, w);
}
if (index) {
gl->fVertexAttrib1f(index, x0);
} else {
mVertexAttrib0Vector[0] = x0;
mVertexAttrib0Vector[1] = 0;
mVertexAttrib0Vector[2] = 0;
mVertexAttrib0Vector[3] = 1;
if (gl->IsGLES())
gl->fVertexAttrib1f(index, x0);
////
mGenericVertexAttribTypes[index] = LOCAL_GL_FLOAT;
if (!index) {
const float data[4] = { x, y, z, w };
memcpy(mGenericVertexAttrib0Data, data, sizeof(data));
}
}
void
WebGLContext::VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1)
WebGL2Context::VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w,
const char* funcName)
{
if (!funcName) {
funcName = "vertexAttribI4i";
}
if (IsContextLost())
return;
if (!ValidateAttribIndex(index, "vertexAttrib2f"))
if (!ValidateAttribIndex(index, funcName))
return;
mVertexAttribType[index] = LOCAL_GL_FLOAT;
////
MakeContextCurrent();
gl->MakeCurrent();
if (index || !gl->IsCompatibilityProfile()) {
gl->fVertexAttribI4i(index, x, y, z, w);
}
if (index) {
gl->fVertexAttrib2f(index, x0, x1);
} else {
mVertexAttrib0Vector[0] = x0;
mVertexAttrib0Vector[1] = x1;
mVertexAttrib0Vector[2] = 0;
mVertexAttrib0Vector[3] = 1;
if (gl->IsGLES())
gl->fVertexAttrib2f(index, x0, x1);
////
mGenericVertexAttribTypes[index] = LOCAL_GL_INT;
if (!index) {
const int32_t data[4] = { x, y, z, w };
memcpy(mGenericVertexAttrib0Data, data, sizeof(data));
}
}
void
WebGLContext::VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2)
WebGL2Context::VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w,
const char* funcName)
{
if (!funcName) {
funcName = "vertexAttribI4ui";
}
if (IsContextLost())
return;
if (!ValidateAttribIndex(index, "vertexAttrib3f"))
if (!ValidateAttribIndex(index, funcName))
return;
mVertexAttribType[index] = LOCAL_GL_FLOAT;
////
MakeContextCurrent();
gl->MakeCurrent();
if (index || !gl->IsCompatibilityProfile()) {
gl->fVertexAttribI4ui(index, x, y, z, w);
}
if (index) {
gl->fVertexAttrib3f(index, x0, x1, x2);
} else {
mVertexAttrib0Vector[0] = x0;
mVertexAttrib0Vector[1] = x1;
mVertexAttrib0Vector[2] = x2;
mVertexAttrib0Vector[3] = 1;
if (gl->IsGLES())
gl->fVertexAttrib3f(index, x0, x1, x2);
////
mGenericVertexAttribTypes[index] = LOCAL_GL_UNSIGNED_INT;
if (!index) {
const uint32_t data[4] = { x, y, z, w };
memcpy(mGenericVertexAttrib0Data, data, sizeof(data));
}
}
void
WebGLContext::VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1,
GLfloat x2, GLfloat x3)
{
if (IsContextLost())
return;
if (!ValidateAttribIndex(index, "vertexAttrib4f"))
return;
mVertexAttribType[index] = LOCAL_GL_FLOAT;
MakeContextCurrent();
if (index) {
gl->fVertexAttrib4f(index, x0, x1, x2, x3);
} else {
mVertexAttrib0Vector[0] = x0;
mVertexAttrib0Vector[1] = x1;
mVertexAttrib0Vector[2] = x2;
mVertexAttrib0Vector[3] = x3;
if (gl->IsGLES())
gl->fVertexAttrib4f(index, x0, x1, x2, x3);
}
}
void
WebGLContext::VertexAttrib1fv_base(GLuint index, uint32_t arrayLength,
const GLfloat* ptr)
{
if (!ValidateAttribArraySetter("VertexAttrib1fv", 1, arrayLength))
return;
if (!ValidateAttribIndex(index, "vertexAttrib1fv"))
return;
mVertexAttribType[index] = LOCAL_GL_FLOAT;
MakeContextCurrent();
if (index) {
gl->fVertexAttrib1fv(index, ptr);
} else {
mVertexAttrib0Vector[0] = ptr[0];
mVertexAttrib0Vector[1] = GLfloat(0);
mVertexAttrib0Vector[2] = GLfloat(0);
mVertexAttrib0Vector[3] = GLfloat(1);
if (gl->IsGLES())
gl->fVertexAttrib1fv(index, ptr);
}
}
void
WebGLContext::VertexAttrib2fv_base(GLuint index, uint32_t arrayLength,
const GLfloat* ptr)
{
if (!ValidateAttribArraySetter("VertexAttrib2fv", 2, arrayLength))
return;
if (!ValidateAttribIndex(index, "vertexAttrib2fv"))
return;
mVertexAttribType[index] = LOCAL_GL_FLOAT;
MakeContextCurrent();
if (index) {
gl->fVertexAttrib2fv(index, ptr);
} else {
mVertexAttrib0Vector[0] = ptr[0];
mVertexAttrib0Vector[1] = ptr[1];
mVertexAttrib0Vector[2] = GLfloat(0);
mVertexAttrib0Vector[3] = GLfloat(1);
if (gl->IsGLES())
gl->fVertexAttrib2fv(index, ptr);
}
}
void
WebGLContext::VertexAttrib3fv_base(GLuint index, uint32_t arrayLength,
const GLfloat* ptr)
{
if (!ValidateAttribArraySetter("VertexAttrib3fv", 3, arrayLength))
return;
if (!ValidateAttribIndex(index, "vertexAttrib3fv"))
return;
mVertexAttribType[index] = LOCAL_GL_FLOAT;
MakeContextCurrent();
if (index) {
gl->fVertexAttrib3fv(index, ptr);
} else {
mVertexAttrib0Vector[0] = ptr[0];
mVertexAttrib0Vector[1] = ptr[1];
mVertexAttrib0Vector[2] = ptr[2];
mVertexAttrib0Vector[3] = GLfloat(1);
if (gl->IsGLES())
gl->fVertexAttrib3fv(index, ptr);
}
}
void
WebGLContext::VertexAttrib4fv_base(GLuint index, uint32_t arrayLength,
const GLfloat* ptr)
{
if (!ValidateAttribArraySetter("VertexAttrib4fv", 4, arrayLength))
return;
if (!ValidateAttribIndex(index, "vertexAttrib4fv"))
return;
mVertexAttribType[index] = LOCAL_GL_FLOAT;
MakeContextCurrent();
if (index) {
gl->fVertexAttrib4fv(index, ptr);
} else {
mVertexAttrib0Vector[0] = ptr[0];
mVertexAttrib0Vector[1] = ptr[1];
mVertexAttrib0Vector[2] = ptr[2];
mVertexAttrib0Vector[3] = ptr[3];
if (gl->IsGLES())
gl->fVertexAttrib4fv(index, ptr);
}
}
////////////////////////////////////////
void
WebGLContext::EnableVertexAttribArray(GLuint index)
@ -299,7 +168,6 @@ WebGLContext::EnableVertexAttribArray(GLuint index)
gl->fEnableVertexAttribArray(index);
MOZ_ASSERT(mBoundVertexArray);
mBoundVertexArray->EnsureAttrib(index);
mBoundVertexArray->mAttribs[index].mEnabled = true;
}
@ -315,12 +183,11 @@ WebGLContext::DisableVertexAttribArray(GLuint index)
MakeContextCurrent();
InvalidateBufferFetching();
if (index || gl->IsGLES()) {
if (index || !gl->IsCompatibilityProfile()) {
gl->fDisableVertexAttribArray(index);
}
MOZ_ASSERT(mBoundVertexArray);
mBoundVertexArray->EnsureAttrib(index);
mBoundVertexArray->mAttribs[index].mEnabled = false;
}
@ -328,14 +195,14 @@ JS::Value
WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
ErrorResult& rv)
{
const char funcName[] = "getVertexAttrib";
if (IsContextLost())
return JS::NullValue();
if (!ValidateAttribIndex(index, "getVertexAttrib"))
if (!ValidateAttribIndex(index, funcName))
return JS::NullValue();
MOZ_ASSERT(mBoundVertexArray);
mBoundVertexArray->EnsureAttrib(index);
MakeContextCurrent();
@ -369,7 +236,7 @@ WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
case LOCAL_GL_CURRENT_VERTEX_ATTRIB:
{
JS::RootedObject obj(cx);
switch (mVertexAttribType[index]) {
switch (mGenericVertexAttribTypes[index]) {
case LOCAL_GL_FLOAT:
obj = GetVertexAttribFloat32Array(cx, index);
break;
@ -417,7 +284,6 @@ WebGLContext::GetVertexAttribOffset(GLuint index, GLenum pname)
}
MOZ_ASSERT(mBoundVertexArray);
mBoundVertexArray->EnsureAttrib(index);
return mBoundVertexArray->mAttribs[index].ByteOffset();
}
@ -436,7 +302,6 @@ WebGLContext::VertexAttribPointer(GLuint index, GLint size, GLenum type,
return;
MOZ_ASSERT(mBoundVertexArray);
mBoundVertexArray->EnsureAttrib(index);
InvalidateBufferFetching();
@ -465,7 +330,6 @@ WebGLContext::VertexAttribDivisor(GLuint index, GLuint divisor)
return;
MOZ_ASSERT(mBoundVertexArray);
mBoundVertexArray->EnsureAttrib(index);
WebGLVertexAttribData& vd = mBoundVertexArray->mAttribs[index];
vd.mDivisor = divisor;

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

@ -423,13 +423,14 @@ WebGLFBAttachPoint::GetParameter(const char* funcName, WebGLContext* webgl, JSCo
default:
break;
}
nsCString attachmentName;
WebGLContext::EnumName(attachment, &attachmentName);
if (webgl->IsWebGL2()) {
webgl->ErrorInvalidOperation("%s: No attachment at %s.", funcName,
webgl->EnumName(attachment));
attachmentName.BeginReading());
} else {
webgl->ErrorInvalidEnum("%s: No attachment at %s.", funcName,
webgl->EnumName(attachment));
attachmentName.BeginReading());
}
return JS::NullValue();
}

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

@ -83,7 +83,49 @@ AssembleName(const nsCString& baseName, bool isArray, size_t arrayIndex,
}
}
//////////
////
static GLenum
AttribBaseType(GLenum attribType)
{
switch (attribType) {
case LOCAL_GL_FLOAT:
case LOCAL_GL_FLOAT_VEC2:
case LOCAL_GL_FLOAT_VEC3:
case LOCAL_GL_FLOAT_VEC4:
case LOCAL_GL_FLOAT_MAT2:
case LOCAL_GL_FLOAT_MAT2x3:
case LOCAL_GL_FLOAT_MAT2x4:
case LOCAL_GL_FLOAT_MAT3x2:
case LOCAL_GL_FLOAT_MAT3:
case LOCAL_GL_FLOAT_MAT3x4:
case LOCAL_GL_FLOAT_MAT4x2:
case LOCAL_GL_FLOAT_MAT4x3:
case LOCAL_GL_FLOAT_MAT4:
return LOCAL_GL_FLOAT;
case LOCAL_GL_INT:
case LOCAL_GL_INT_VEC2:
case LOCAL_GL_INT_VEC3:
case LOCAL_GL_INT_VEC4:
return LOCAL_GL_INT;
case LOCAL_GL_UNSIGNED_INT:
case LOCAL_GL_UNSIGNED_INT_VEC2:
case LOCAL_GL_UNSIGNED_INT_VEC3:
case LOCAL_GL_UNSIGNED_INT_VEC4:
return LOCAL_GL_UNSIGNED_INT;
default:
MOZ_ASSERT(false, "unexpected attrib elemType");
return 0;
}
}
////
/*static*/ const webgl::UniformInfo::TexListT*
webgl::UniformInfo::GetTexList(WebGLActiveInfo* activeInfo)
@ -225,7 +267,8 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
elemType, isArray,
userName,
mappedName);
const webgl::AttribInfo attrib = {activeInfo, uint32_t(loc)};
const GLenum baseType = AttribBaseType(elemType);
const webgl::AttribInfo attrib = {activeInfo, uint32_t(loc), baseType};
info->attribs.push_back(attrib);
}

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

@ -38,7 +38,8 @@ namespace webgl {
struct AttribInfo final
{
const RefPtr<WebGLActiveInfo> mActiveInfo;
uint32_t mLoc;
const uint32_t mLoc;
const GLenum mBaseType;
};
struct UniformInfo final
@ -122,6 +123,7 @@ class WebGLProgram final
, public LinkedListElement<WebGLProgram>
{
friend class WebGLTransformFeedback;
friend struct webgl::LinkedProgramInfo;
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLProgram)

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

@ -136,8 +136,7 @@ WebGLQuery::GetQueryParameter(GLenum pname, JS::MutableHandleValue retval) const
break;
default:
mContext->ErrorInvalidEnum("%s: Invalid pname: %s", funcName,
mContext->EnumName(pname));
mContext->ErrorInvalidEnumArg(funcName, "pname", pname);
return;
}

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

@ -133,12 +133,11 @@ ValidateSamplerParameterParams(WebGLContext* webgl, const char* funcName, GLenum
break;
default:
webgl->ErrorInvalidEnum("%s: invalid pname: %s", funcName,
webgl->EnumName(pname));
webgl->ErrorInvalidEnumArg(funcName, "pname", pname);
return false;
}
webgl->ErrorInvalidEnum("%s: invalid param: %s", funcName, webgl->EnumName(paramInt));
webgl->ErrorInvalidEnumArg(funcName, "param", paramInt);
return false;
}

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

@ -89,6 +89,7 @@ public:
public:
const GLuint mGLName;
const GLenum mType;
protected:
nsString mSource;
nsCString mCleanSource;

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

@ -24,6 +24,7 @@ WebGLVertexArray::WebGLVertexArray(WebGLContext* webgl)
: WebGLRefCountedObject(webgl)
, mGLName(0)
{
mAttribs.SetLength(mContext->mGLMaxVertexAttribs);
mContext->mVertexArrays.insertBack(this);
}
@ -55,16 +56,6 @@ WebGLVertexArray::IsVertexArray() const
return IsVertexArrayImpl();
}
void
WebGLVertexArray::EnsureAttrib(GLuint index)
{
MOZ_ASSERT(index < GLuint(mContext->mGLMaxVertexAttribs));
if (index >= mAttribs.Length()) {
mAttribs.SetLength(index + 1);
}
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLVertexArray,
mAttribs,
mElementArrayBuffer)

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

@ -33,14 +33,6 @@ public:
BindVertexArrayImpl();
};
void EnsureAttrib(GLuint index);
bool HasAttrib(GLuint index) const {
return index < mAttribs.Length();
}
bool IsAttribArrayEnabled(GLuint index) const {
return HasAttrib(index) && mAttribs[index].mEnabled;
}
// Implement parent classes:
void Delete();
bool IsVertexArray() const;
@ -72,6 +64,7 @@ protected:
nsTArray<WebGLVertexAttribData> mAttribs;
WebGLRefPtr<WebGLBuffer> mElementArrayBuffer;
friend class ScopedDrawHelper;
friend class WebGLContext;
friend class WebGLVertexArrayFake;
friend class WebGL2Context;

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

@ -43,6 +43,28 @@ CalcBytesPerVertex(GLenum type, uint8_t size)
return bytesPerType * size;
}
static GLenum
AttribPointerBaseType(bool integerFunc, GLenum type)
{
if (!integerFunc)
return LOCAL_GL_FLOAT;
switch (type) {
case LOCAL_GL_BYTE:
case LOCAL_GL_SHORT:
case LOCAL_GL_INT:
return LOCAL_GL_INT;
case LOCAL_GL_UNSIGNED_BYTE:
case LOCAL_GL_UNSIGNED_SHORT:
case LOCAL_GL_UNSIGNED_INT:
return LOCAL_GL_UNSIGNED_INT;
default:
MOZ_CRASH();
}
}
void
WebGLVertexAttribData::VertexAttribPointer(bool integerFunc, WebGLBuffer* buf,
uint8_t size, GLenum type, bool normalized,
@ -51,6 +73,7 @@ WebGLVertexAttribData::VertexAttribPointer(bool integerFunc, WebGLBuffer* buf,
mIntegerFunc = integerFunc;
mBuf = buf;
mType = type;
mBaseType = AttribPointerBaseType(integerFunc, type);
mSize = size;
mBytesPerVertex = CalcBytesPerVertex(mType, mSize);
mNormalized = normalized;

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

@ -25,6 +25,7 @@ public:
WebGLRefPtr<WebGLBuffer> mBuf;
private:
GLenum mType;
GLenum mBaseType;
uint8_t mSize; // num of mType vals per vert
uint8_t mBytesPerVertex;
bool mNormalized;
@ -38,6 +39,7 @@ public:
GETTER(IntegerFunc)
GETTER(Type)
GETTER(BaseType)
GETTER(Size)
GETTER(BytesPerVertex)
GETTER(Normalized)

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

@ -40,6 +40,14 @@ void main()
gl_Position = vec4(p.x + a.x + a.y + a.z + a.w, p.y, 0.0, 10.0);
}
</script>
<script id='vshader_unsigned' type='x-shader/x-vertex'>#version 300 es
layout(location=0) in ivec2 p;
layout(location=1) in uvec4 a;
void main()
{
gl_Position = vec4(p.x + int(a.x + a.y + a.z + a.w), p.y, 0.0, 10.0);
}
</script>
<script id='fshader' type='x-shader/x-fragment'>#version 300 es
precision mediump float;
layout(location=0) out vec4 oColor;
@ -69,7 +77,8 @@ function runTest() {
testFailed('could not create context');
return;
}
var program = wtu.setupProgram(gl, ['vshader', 'fshader'])
var program = wtu.setupProgram(gl, ['vshader', 'fshader']);
var program_unsigned = wtu.setupProgram(gl, ['vshader_unsigned', 'fshader']);
gl.enableVertexAttribArray(0);
var pos = gl.createBuffer();
@ -83,6 +92,11 @@ function runTest() {
var tests = ['vertexAttribI4i', 'vertexAttribI4ui', 'vertexAttribI4iv', 'vertexAttribI4uiv'];
for (var ii = 0; ii < 4; ++ii) {
if (ii % 2 == 0) {
gl.useProgram(program);
} else {
gl.useProgram(program_unsigned);
}
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if (ii < 2) {
gl[tests[ii]](1, vals[ii][0], vals[ii][1], vals[ii][2], vals[ii][3]);

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

@ -51,6 +51,17 @@ void main()
}
</script>
<script id="vshader_unsigned" type="x-shader/x-vertex">#version 300 es
layout(location=0) in uvec4 aPosition;
layout(location=1) in vec4 aColor;
out vec4 vColor;
void main()
{
gl_Position = vec4(aPosition);
vColor = aColor;
}
</script>
<script id="fshader" type="x-shader/x-fragment">#version 300 es
precision mediump float;
in vec4 vColor;
@ -70,6 +81,7 @@ function init()
var wtu = WebGLTestUtils;
var gl = wtu.create3DContext("example", undefined, 2);
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]);
var program_unsigned = wtu.setupProgram(gl, ["vshader_unsigned", "fshader"], ["vPosition"]);
var tests = [
{ data: new Int32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
@ -116,6 +128,11 @@ function init()
var stride = test.componentSize * kNumComponents + test.componentSize * ss;
debug("");
debug("check with " + wtu.glEnumToString(gl, test.type) + " at offset: " + offset + " with stride:" + stride);
if (test.type == gl.INT || test.type == gl.SHORT || test.type == gl.BYTE) {
gl.useProgram(program);
} else {
gl.useProgram(program_unsigned);
}
gl.vertexAttrib4fv(1, color);
var data = new Uint8Array(test.componentSize * kNumVerts * kNumComponents + stride * (kNumVerts - 1));
var view = new Uint8Array(test.data.buffer);

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

@ -5928,7 +5928,6 @@ fail-if = (os == 'android')
[generated/test_conformance__attribs__gl-enable-vertex-attrib.html]
[generated/test_conformance__attribs__gl-matrix-attributes.html]
[generated/test_conformance__attribs__gl-vertex-attrib-render.html]
fail-if = (os == 'linux')
[generated/test_conformance__attribs__gl-vertex-attrib-zero-issues.html]
[generated/test_conformance__attribs__gl-vertex-attrib.html]
[generated/test_conformance__attribs__gl-vertexattribpointer-offsets.html]

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

@ -475,8 +475,6 @@ fail-if = (os == 'b2g')
########################################################################
########################################################################
# Linux
[generated/test_conformance__attribs__gl-vertex-attrib-render.html]
fail-if = (os == 'linux')
[generated/test_conformance__glsl__constructors__glsl-construct-vec-mat-corner-cases.html]
# mozalloc_abort in libglsl.so
skip-if = (os == 'linux')

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

@ -693,17 +693,13 @@ interface WebGLRenderingContextBase {
void validateProgram(WebGLProgram program);
void vertexAttrib1f(GLuint indx, GLfloat x);
void vertexAttrib1fv(GLuint indx, Float32Array values);
void vertexAttrib1fv(GLuint indx, sequence<GLfloat> values);
void vertexAttrib1fv(GLuint indx, Float32List values);
void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
void vertexAttrib2fv(GLuint indx, Float32Array values);
void vertexAttrib2fv(GLuint indx, sequence<GLfloat> values);
void vertexAttrib2fv(GLuint indx, Float32List values);
void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
void vertexAttrib3fv(GLuint indx, Float32Array values);
void vertexAttrib3fv(GLuint indx, sequence<GLfloat> values);
void vertexAttrib3fv(GLuint indx, Float32List values);
void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void vertexAttrib4fv(GLuint indx, Float32Array values);
void vertexAttrib4fv(GLuint indx, sequence<GLfloat> values);
void vertexAttrib4fv(GLuint indx, Float32List values);
void vertexAttribPointer(GLuint indx, GLint size, GLenum type,
GLboolean normalized, GLsizei stride, GLintptr offset);