1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "WebGLContext.h"
9 #include "mozilla/CheckedInt.h"
10 #include "WebGLBuffer.h"
11 #include "WebGLFramebuffer.h"
12 #include "WebGLProgram.h"
13 #include "WebGLRenderbuffer.h"
14 #include "WebGLShader.h"
15 #include "WebGLTexture.h"
16 #include "WebGLUniformInfo.h"
17 #include "WebGLVertexArray.h"
18 #include "WebGLVertexAttribData.h"
20 using namespace mozilla
;
24 WebGLContext::VertexAttrib1f(GLuint index
, GLfloat x0
)
29 if (!ValidateAttribIndex(index
, "vertexAttrib1f"))
35 gl
->fVertexAttrib1f(index
, x0
);
37 mVertexAttrib0Vector
[0] = x0
;
38 mVertexAttrib0Vector
[1] = 0;
39 mVertexAttrib0Vector
[2] = 0;
40 mVertexAttrib0Vector
[3] = 1;
42 gl
->fVertexAttrib1f(index
, x0
);
47 WebGLContext::VertexAttrib2f(GLuint index
, GLfloat x0
, GLfloat x1
)
52 if (!ValidateAttribIndex(index
, "vertexAttrib2f"))
58 gl
->fVertexAttrib2f(index
, x0
, x1
);
60 mVertexAttrib0Vector
[0] = x0
;
61 mVertexAttrib0Vector
[1] = x1
;
62 mVertexAttrib0Vector
[2] = 0;
63 mVertexAttrib0Vector
[3] = 1;
65 gl
->fVertexAttrib2f(index
, x0
, x1
);
70 WebGLContext::VertexAttrib3f(GLuint index
, GLfloat x0
, GLfloat x1
, GLfloat x2
)
75 if (!ValidateAttribIndex(index
, "vertexAttrib3f"))
81 gl
->fVertexAttrib3f(index
, x0
, x1
, x2
);
83 mVertexAttrib0Vector
[0] = x0
;
84 mVertexAttrib0Vector
[1] = x1
;
85 mVertexAttrib0Vector
[2] = x2
;
86 mVertexAttrib0Vector
[3] = 1;
88 gl
->fVertexAttrib3f(index
, x0
, x1
, x2
);
93 WebGLContext::VertexAttrib4f(GLuint index
, GLfloat x0
, GLfloat x1
,
94 GLfloat x2
, GLfloat x3
)
99 if (!ValidateAttribIndex(index
, "vertexAttrib4f"))
102 MakeContextCurrent();
105 gl
->fVertexAttrib4f(index
, x0
, x1
, x2
, x3
);
107 mVertexAttrib0Vector
[0] = x0
;
108 mVertexAttrib0Vector
[1] = x1
;
109 mVertexAttrib0Vector
[2] = x2
;
110 mVertexAttrib0Vector
[3] = x3
;
112 gl
->fVertexAttrib4f(index
, x0
, x1
, x2
, x3
);
118 WebGLContext::VertexAttrib1fv_base(GLuint index
, uint32_t arrayLength
,
121 if (!ValidateAttribArraySetter("VertexAttrib1fv", 1, arrayLength
))
124 if (!ValidateAttribIndex(index
, "vertexAttrib1fv"))
127 MakeContextCurrent();
129 gl
->fVertexAttrib1fv(index
, ptr
);
131 mVertexAttrib0Vector
[0] = ptr
[0];
132 mVertexAttrib0Vector
[1] = GLfloat(0);
133 mVertexAttrib0Vector
[2] = GLfloat(0);
134 mVertexAttrib0Vector
[3] = GLfloat(1);
136 gl
->fVertexAttrib1fv(index
, ptr
);
141 WebGLContext::VertexAttrib2fv_base(GLuint index
, uint32_t arrayLength
,
144 if (!ValidateAttribArraySetter("VertexAttrib2fv", 2, arrayLength
))
147 if (!ValidateAttribIndex(index
, "vertexAttrib2fv"))
150 MakeContextCurrent();
152 gl
->fVertexAttrib2fv(index
, ptr
);
154 mVertexAttrib0Vector
[0] = ptr
[0];
155 mVertexAttrib0Vector
[1] = ptr
[1];
156 mVertexAttrib0Vector
[2] = GLfloat(0);
157 mVertexAttrib0Vector
[3] = GLfloat(1);
159 gl
->fVertexAttrib2fv(index
, ptr
);
164 WebGLContext::VertexAttrib3fv_base(GLuint index
, uint32_t arrayLength
,
167 if (!ValidateAttribArraySetter("VertexAttrib3fv", 3, arrayLength
))
170 if (!ValidateAttribIndex(index
, "vertexAttrib3fv"))
173 MakeContextCurrent();
175 gl
->fVertexAttrib3fv(index
, ptr
);
177 mVertexAttrib0Vector
[0] = ptr
[0];
178 mVertexAttrib0Vector
[1] = ptr
[1];
179 mVertexAttrib0Vector
[2] = ptr
[2];
180 mVertexAttrib0Vector
[3] = GLfloat(1);
182 gl
->fVertexAttrib3fv(index
, ptr
);
187 WebGLContext::VertexAttrib4fv_base(GLuint index
, uint32_t arrayLength
,
190 if (!ValidateAttribArraySetter("VertexAttrib4fv", 4, arrayLength
))
193 if (!ValidateAttribIndex(index
, "vertexAttrib4fv"))
196 MakeContextCurrent();
198 gl
->fVertexAttrib4fv(index
, ptr
);
200 mVertexAttrib0Vector
[0] = ptr
[0];
201 mVertexAttrib0Vector
[1] = ptr
[1];
202 mVertexAttrib0Vector
[2] = ptr
[2];
203 mVertexAttrib0Vector
[3] = ptr
[3];
205 gl
->fVertexAttrib4fv(index
, ptr
);
210 WebGLContext::EnableVertexAttribArray(GLuint index
)
215 if (!ValidateAttribIndex(index
, "enableVertexAttribArray"))
218 MakeContextCurrent();
219 InvalidateBufferFetching();
221 gl
->fEnableVertexAttribArray(index
);
223 MOZ_ASSERT(mBoundVertexArray
);
224 mBoundVertexArray
->EnsureAttrib(index
);
225 mBoundVertexArray
->mAttribs
[index
].enabled
= true;
229 WebGLContext::DisableVertexAttribArray(GLuint index
)
234 if (!ValidateAttribIndex(index
, "disableVertexAttribArray"))
237 MakeContextCurrent();
238 InvalidateBufferFetching();
240 if (index
|| gl
->IsGLES())
241 gl
->fDisableVertexAttribArray(index
);
243 MOZ_ASSERT(mBoundVertexArray
);
244 mBoundVertexArray
->EnsureAttrib(index
);
245 mBoundVertexArray
->mAttribs
[index
].enabled
= false;
249 WebGLContext::GetVertexAttrib(JSContext
* cx
, GLuint index
, GLenum pname
,
253 return JS::NullValue();
255 if (!ValidateAttribIndex(index
, "getVertexAttrib"))
256 return JS::NullValue();
258 MOZ_ASSERT(mBoundVertexArray
);
259 mBoundVertexArray
->EnsureAttrib(index
);
261 MakeContextCurrent();
264 case LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
:
266 return WebGLObjectAsJSValue(cx
, mBoundVertexArray
->mAttribs
[index
].buf
.get(), rv
);
269 case LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE
:
271 return JS::Int32Value(mBoundVertexArray
->mAttribs
[index
].stride
);
274 case LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE
:
276 if (!mBoundVertexArray
->mAttribs
[index
].enabled
)
277 return JS::Int32Value(4);
279 return JS::Int32Value(mBoundVertexArray
->mAttribs
[index
].size
);
282 case LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE
:
284 if (!mBoundVertexArray
->mAttribs
[index
].enabled
)
285 return JS::NumberValue(uint32_t(LOCAL_GL_FLOAT
));
287 return JS::NumberValue(uint32_t(mBoundVertexArray
->mAttribs
[index
].type
));
290 case LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR
:
292 if (IsExtensionEnabled(WebGLExtensionID::ANGLE_instanced_arrays
))
294 return JS::Int32Value(mBoundVertexArray
->mAttribs
[index
].divisor
);
299 case LOCAL_GL_CURRENT_VERTEX_ATTRIB
:
301 GLfloat vec
[4] = {0, 0, 0, 1};
303 gl
->fGetVertexAttribfv(index
, LOCAL_GL_CURRENT_VERTEX_ATTRIB
, &vec
[0]);
305 vec
[0] = mVertexAttrib0Vector
[0];
306 vec
[1] = mVertexAttrib0Vector
[1];
307 vec
[2] = mVertexAttrib0Vector
[2];
308 vec
[3] = mVertexAttrib0Vector
[3];
310 JSObject
* obj
= Float32Array::Create(cx
, this, 4, vec
);
312 rv
.Throw(NS_ERROR_OUT_OF_MEMORY
);
314 return JS::ObjectOrNullValue(obj
);
317 case LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED
:
319 return JS::BooleanValue(mBoundVertexArray
->mAttribs
[index
].enabled
);
322 case LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
:
324 return JS::BooleanValue(mBoundVertexArray
->mAttribs
[index
].normalized
);
331 ErrorInvalidEnumInfo("getVertexAttrib: parameter", pname
);
332 return JS::NullValue();
336 WebGLContext::GetVertexAttribOffset(GLuint index
, GLenum pname
)
341 if (!ValidateAttribIndex(index
, "getVertexAttribOffset"))
344 if (pname
!= LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER
) {
345 ErrorInvalidEnum("getVertexAttribOffset: bad parameter");
349 MOZ_ASSERT(mBoundVertexArray
);
350 mBoundVertexArray
->EnsureAttrib(index
);
351 return mBoundVertexArray
->mAttribs
[index
].byteOffset
;
355 WebGLContext::VertexAttribPointer(GLuint index
, GLint size
, GLenum type
,
356 WebGLboolean normalized
, GLsizei stride
,
357 WebGLintptr byteOffset
)
362 if (!ValidateAttribIndex(index
, "vertexAttribPointer"))
365 if (!ValidateAttribPointer(false, index
, size
, type
, normalized
, stride
, byteOffset
, "vertexAttribPointer"))
368 MOZ_ASSERT(mBoundVertexArray
);
369 mBoundVertexArray
->EnsureAttrib(index
);
371 InvalidateBufferFetching();
373 /* XXX make work with bufferSubData & heterogeneous types
374 if (type != mBoundArrayBuffer->GLType())
375 return ErrorInvalidOperation("vertexAttribPointer: type must match bound VBO type: %d != %d", type, mBoundArrayBuffer->GLType());
378 WebGLVertexAttribData
& vd
= mBoundVertexArray
->mAttribs
[index
];
380 vd
.buf
= mBoundArrayBuffer
;
383 vd
.byteOffset
= byteOffset
;
385 vd
.normalized
= normalized
;
388 MakeContextCurrent();
389 gl
->fVertexAttribPointer(index
, size
, type
, normalized
, stride
,
390 reinterpret_cast<void*>(byteOffset
));
394 WebGLContext::VertexAttribDivisor(GLuint index
, GLuint divisor
)
399 if (!ValidateAttribIndex(index
, "vertexAttribDivisor"))
402 MOZ_ASSERT(mBoundVertexArray
);
403 mBoundVertexArray
->EnsureAttrib(index
);
405 WebGLVertexAttribData
& vd
= mBoundVertexArray
->mAttribs
[index
];
406 vd
.divisor
= divisor
;
408 InvalidateBufferFetching();
410 MakeContextCurrent();
412 gl
->fVertexAttribDivisor(index
, divisor
);