Bumping manifests a=b2g-bump
[gecko.git] / dom / canvas / WebGLContextVertices.cpp
blobfd3ca1ebcef8bc065d03cfcca3385c0b30b4d3f8
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"
8 #include "GLContext.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;
21 using namespace dom;
23 void
24 WebGLContext::VertexAttrib1f(GLuint index, GLfloat x0)
26 if (IsContextLost())
27 return;
29 if (!ValidateAttribIndex(index, "vertexAttrib1f"))
30 return;
32 MakeContextCurrent();
34 if (index) {
35 gl->fVertexAttrib1f(index, x0);
36 } else {
37 mVertexAttrib0Vector[0] = x0;
38 mVertexAttrib0Vector[1] = 0;
39 mVertexAttrib0Vector[2] = 0;
40 mVertexAttrib0Vector[3] = 1;
41 if (gl->IsGLES())
42 gl->fVertexAttrib1f(index, x0);
46 void
47 WebGLContext::VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1)
49 if (IsContextLost())
50 return;
52 if (!ValidateAttribIndex(index, "vertexAttrib2f"))
53 return;
55 MakeContextCurrent();
57 if (index) {
58 gl->fVertexAttrib2f(index, x0, x1);
59 } else {
60 mVertexAttrib0Vector[0] = x0;
61 mVertexAttrib0Vector[1] = x1;
62 mVertexAttrib0Vector[2] = 0;
63 mVertexAttrib0Vector[3] = 1;
64 if (gl->IsGLES())
65 gl->fVertexAttrib2f(index, x0, x1);
69 void
70 WebGLContext::VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2)
72 if (IsContextLost())
73 return;
75 if (!ValidateAttribIndex(index, "vertexAttrib3f"))
76 return;
78 MakeContextCurrent();
80 if (index) {
81 gl->fVertexAttrib3f(index, x0, x1, x2);
82 } else {
83 mVertexAttrib0Vector[0] = x0;
84 mVertexAttrib0Vector[1] = x1;
85 mVertexAttrib0Vector[2] = x2;
86 mVertexAttrib0Vector[3] = 1;
87 if (gl->IsGLES())
88 gl->fVertexAttrib3f(index, x0, x1, x2);
92 void
93 WebGLContext::VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1,
94 GLfloat x2, GLfloat x3)
96 if (IsContextLost())
97 return;
99 if (!ValidateAttribIndex(index, "vertexAttrib4f"))
100 return;
102 MakeContextCurrent();
104 if (index) {
105 gl->fVertexAttrib4f(index, x0, x1, x2, x3);
106 } else {
107 mVertexAttrib0Vector[0] = x0;
108 mVertexAttrib0Vector[1] = x1;
109 mVertexAttrib0Vector[2] = x2;
110 mVertexAttrib0Vector[3] = x3;
111 if (gl->IsGLES())
112 gl->fVertexAttrib4f(index, x0, x1, x2, x3);
117 void
118 WebGLContext::VertexAttrib1fv_base(GLuint index, uint32_t arrayLength,
119 const GLfloat* ptr)
121 if (!ValidateAttribArraySetter("VertexAttrib1fv", 1, arrayLength))
122 return;
124 if (!ValidateAttribIndex(index, "vertexAttrib1fv"))
125 return;
127 MakeContextCurrent();
128 if (index) {
129 gl->fVertexAttrib1fv(index, ptr);
130 } else {
131 mVertexAttrib0Vector[0] = ptr[0];
132 mVertexAttrib0Vector[1] = GLfloat(0);
133 mVertexAttrib0Vector[2] = GLfloat(0);
134 mVertexAttrib0Vector[3] = GLfloat(1);
135 if (gl->IsGLES())
136 gl->fVertexAttrib1fv(index, ptr);
140 void
141 WebGLContext::VertexAttrib2fv_base(GLuint index, uint32_t arrayLength,
142 const GLfloat* ptr)
144 if (!ValidateAttribArraySetter("VertexAttrib2fv", 2, arrayLength))
145 return;
147 if (!ValidateAttribIndex(index, "vertexAttrib2fv"))
148 return;
150 MakeContextCurrent();
151 if (index) {
152 gl->fVertexAttrib2fv(index, ptr);
153 } else {
154 mVertexAttrib0Vector[0] = ptr[0];
155 mVertexAttrib0Vector[1] = ptr[1];
156 mVertexAttrib0Vector[2] = GLfloat(0);
157 mVertexAttrib0Vector[3] = GLfloat(1);
158 if (gl->IsGLES())
159 gl->fVertexAttrib2fv(index, ptr);
163 void
164 WebGLContext::VertexAttrib3fv_base(GLuint index, uint32_t arrayLength,
165 const GLfloat* ptr)
167 if (!ValidateAttribArraySetter("VertexAttrib3fv", 3, arrayLength))
168 return;
170 if (!ValidateAttribIndex(index, "vertexAttrib3fv"))
171 return;
173 MakeContextCurrent();
174 if (index) {
175 gl->fVertexAttrib3fv(index, ptr);
176 } else {
177 mVertexAttrib0Vector[0] = ptr[0];
178 mVertexAttrib0Vector[1] = ptr[1];
179 mVertexAttrib0Vector[2] = ptr[2];
180 mVertexAttrib0Vector[3] = GLfloat(1);
181 if (gl->IsGLES())
182 gl->fVertexAttrib3fv(index, ptr);
186 void
187 WebGLContext::VertexAttrib4fv_base(GLuint index, uint32_t arrayLength,
188 const GLfloat* ptr)
190 if (!ValidateAttribArraySetter("VertexAttrib4fv", 4, arrayLength))
191 return;
193 if (!ValidateAttribIndex(index, "vertexAttrib4fv"))
194 return;
196 MakeContextCurrent();
197 if (index) {
198 gl->fVertexAttrib4fv(index, ptr);
199 } else {
200 mVertexAttrib0Vector[0] = ptr[0];
201 mVertexAttrib0Vector[1] = ptr[1];
202 mVertexAttrib0Vector[2] = ptr[2];
203 mVertexAttrib0Vector[3] = ptr[3];
204 if (gl->IsGLES())
205 gl->fVertexAttrib4fv(index, ptr);
209 void
210 WebGLContext::EnableVertexAttribArray(GLuint index)
212 if (IsContextLost())
213 return;
215 if (!ValidateAttribIndex(index, "enableVertexAttribArray"))
216 return;
218 MakeContextCurrent();
219 InvalidateBufferFetching();
221 gl->fEnableVertexAttribArray(index);
223 MOZ_ASSERT(mBoundVertexArray);
224 mBoundVertexArray->EnsureAttrib(index);
225 mBoundVertexArray->mAttribs[index].enabled = true;
228 void
229 WebGLContext::DisableVertexAttribArray(GLuint index)
231 if (IsContextLost())
232 return;
234 if (!ValidateAttribIndex(index, "disableVertexAttribArray"))
235 return;
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;
248 JS::Value
249 WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
250 ErrorResult& rv)
252 if (IsContextLost())
253 return JS::NullValue();
255 if (!ValidateAttribIndex(index, "getVertexAttrib"))
256 return JS::NullValue();
258 MOZ_ASSERT(mBoundVertexArray);
259 mBoundVertexArray->EnsureAttrib(index);
261 MakeContextCurrent();
263 switch (pname) {
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);
296 break;
299 case LOCAL_GL_CURRENT_VERTEX_ATTRIB:
301 GLfloat vec[4] = {0, 0, 0, 1};
302 if (index) {
303 gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, &vec[0]);
304 } else {
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);
311 if (!obj) {
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);
327 default:
328 break;
331 ErrorInvalidEnumInfo("getVertexAttrib: parameter", pname);
332 return JS::NullValue();
335 WebGLsizeiptr
336 WebGLContext::GetVertexAttribOffset(GLuint index, GLenum pname)
338 if (IsContextLost())
339 return 0;
341 if (!ValidateAttribIndex(index, "getVertexAttribOffset"))
342 return 0;
344 if (pname != LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER) {
345 ErrorInvalidEnum("getVertexAttribOffset: bad parameter");
346 return 0;
349 MOZ_ASSERT(mBoundVertexArray);
350 mBoundVertexArray->EnsureAttrib(index);
351 return mBoundVertexArray->mAttribs[index].byteOffset;
354 void
355 WebGLContext::VertexAttribPointer(GLuint index, GLint size, GLenum type,
356 WebGLboolean normalized, GLsizei stride,
357 WebGLintptr byteOffset)
359 if (IsContextLost())
360 return;
362 if (!ValidateAttribIndex(index, "vertexAttribPointer"))
363 return;
365 if (!ValidateAttribPointer(false, index, size, type, normalized, stride, byteOffset, "vertexAttribPointer"))
366 return;
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;
381 vd.stride = stride;
382 vd.size = size;
383 vd.byteOffset = byteOffset;
384 vd.type = type;
385 vd.normalized = normalized;
386 vd.integer = false;
388 MakeContextCurrent();
389 gl->fVertexAttribPointer(index, size, type, normalized, stride,
390 reinterpret_cast<void*>(byteOffset));
393 void
394 WebGLContext::VertexAttribDivisor(GLuint index, GLuint divisor)
396 if (IsContextLost())
397 return;
399 if (!ValidateAttribIndex(index, "vertexAttribDivisor"))
400 return;
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);