Bug 1325301 - Validate attribute base types match data base types. - r=daoshengmu
MozReview-Commit-ID: IaJt1qIQ3LE
--- a/dom/canvas/WebGLContextDraw.cpp
+++ b/dom/canvas/WebGLContextDraw.cpp
@@ -389,16 +389,40 @@ public:
funcName);
*out_error = true;
return;
}
}
////
+ 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) {
+ mWebGL->ErrorInvalidOperation("%s: Vertex attrib %u data should have type"
+ " 0x04x, was 0x04x.",
+ funcName, loc, progAttrib.mBaseType,
+ attribDataBaseType);
+ *out_error = true;
+ return;
+ }
+ }
+
+ ////
+
mWebGL->RunContextLossTimer();
}
~ScopedDrawHelper() {
if (mDidFake) {
mWebGL->UndoFakeVertexAttrib0();
}
}
--- a/dom/canvas/WebGLProgram.cpp
+++ b/dom/canvas/WebGLProgram.cpp
@@ -78,17 +78,59 @@ AssembleName(const nsCString& baseName,
*out_name = baseName;
if (isArray) {
out_name->Append('[');
out_name->AppendInt(arrayIndex);
out_name->Append(']');
}
}
-//////////
+////
+
+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)
{
const auto& webgl = activeInfo->mWebGL;
switch (activeInfo->mElemType) {
case LOCAL_GL_SAMPLER_2D:
@@ -220,17 +262,18 @@ QueryProgramInfo(WebGLProgram* prog, gl:
///////
const bool isArray = false;
const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(webgl, elemCount,
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);
}
// Uniforms
const bool needsCheckForArrays = gl->WorkAroundDriverBugs();
GLuint numActiveUniforms = 0;
--- a/dom/canvas/WebGLProgram.h
+++ b/dom/canvas/WebGLProgram.h
@@ -33,17 +33,18 @@ class OwningUnsignedLongOrUint32ArrayOrB
template<typename> class Sequence;
} // namespace dom
namespace webgl {
struct AttribInfo final
{
const RefPtr<WebGLActiveInfo> mActiveInfo;
- uint32_t mLoc;
+ const uint32_t mLoc;
+ const GLenum mBaseType;
};
struct UniformInfo final
{
typedef decltype(WebGLContext::mBound2DTextures) TexListT;
const RefPtr<WebGLActiveInfo> mActiveInfo;
const TexListT* const mSamplerTexList;
--- a/dom/canvas/WebGLVertexArray.h
+++ b/dom/canvas/WebGLVertexArray.h
@@ -59,16 +59,17 @@ protected:
virtual void BindVertexArrayImpl() = 0;
virtual void DeleteImpl() = 0;
virtual bool IsVertexArrayImpl() const = 0;
GLuint mGLName;
nsTArray<WebGLVertexAttribData> mAttribs;
WebGLRefPtr<WebGLBuffer> mElementArrayBuffer;
+ friend class ScopedDrawHelper;
friend class WebGLContext;
friend class WebGLVertexArrayFake;
friend class WebGL2Context;
};
} // namespace mozilla
#endif // WEBGL_VERTEX_ARRAY_H_
--- a/dom/canvas/WebGLVertexAttribData.cpp
+++ b/dom/canvas/WebGLVertexAttribData.cpp
@@ -38,24 +38,47 @@ CalcBytesPerVertex(GLenum type, uint8_t
default:
MOZ_CRASH("Bad `type`.");
}
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,
uint32_t stride, uint64_t byteOffset)
{
mIntegerFunc = integerFunc;
mBuf = buf;
mType = type;
+ mBaseType = AttribPointerBaseType(integerFunc, type);
mSize = size;
mBytesPerVertex = CalcBytesPerVertex(mType, mSize);
mNormalized = normalized;
mStride = stride;
mExplicitStride = (mStride ? mStride : mBytesPerVertex);
mByteOffset = byteOffset;
}
--- a/dom/canvas/WebGLVertexAttribData.h
+++ b/dom/canvas/WebGLVertexAttribData.h
@@ -20,29 +20,31 @@ public:
bool mEnabled;
private:
bool mIntegerFunc;
public:
WebGLRefPtr<WebGLBuffer> mBuf;
private:
GLenum mType;
+ GLenum mBaseType;
uint8_t mSize; // num of mType vals per vert
uint8_t mBytesPerVertex;
bool mNormalized;
uint32_t mStride; // bytes
uint32_t mExplicitStride;
uint64_t mByteOffset;
public:
#define GETTER(X) const decltype(m##X)& X() const { return m##X; }
GETTER(IntegerFunc)
GETTER(Type)
+ GETTER(BaseType)
GETTER(Size)
GETTER(BytesPerVertex)
GETTER(Normalized)
GETTER(Stride)
GETTER(ExplicitStride)
GETTER(ByteOffset)
#undef GETTER