1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/canvas/src/WebGLContextVertices.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,425 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "WebGLContext.h" 1.10 + 1.11 +#include "GLContext.h" 1.12 +#include "mozilla/CheckedInt.h" 1.13 +#include "WebGLBuffer.h" 1.14 +#include "WebGLFramebuffer.h" 1.15 +#include "WebGLProgram.h" 1.16 +#include "WebGLRenderbuffer.h" 1.17 +#include "WebGLShader.h" 1.18 +#include "WebGLTexture.h" 1.19 +#include "WebGLUniformInfo.h" 1.20 +#include "WebGLVertexArray.h" 1.21 +#include "WebGLVertexAttribData.h" 1.22 + 1.23 +using namespace mozilla; 1.24 +using namespace dom; 1.25 + 1.26 +void 1.27 +WebGLContext::VertexAttrib1f(GLuint index, GLfloat x0) 1.28 +{ 1.29 + if (IsContextLost()) 1.30 + return; 1.31 + 1.32 + MakeContextCurrent(); 1.33 + 1.34 + if (index) { 1.35 + gl->fVertexAttrib1f(index, x0); 1.36 + } else { 1.37 + mVertexAttrib0Vector[0] = x0; 1.38 + mVertexAttrib0Vector[1] = 0; 1.39 + mVertexAttrib0Vector[2] = 0; 1.40 + mVertexAttrib0Vector[3] = 1; 1.41 + if (gl->IsGLES()) 1.42 + gl->fVertexAttrib1f(index, x0); 1.43 + } 1.44 +} 1.45 + 1.46 +void 1.47 +WebGLContext::VertexAttrib2f(GLuint index, GLfloat x0, GLfloat x1) 1.48 +{ 1.49 + if (IsContextLost()) 1.50 + return; 1.51 + 1.52 + MakeContextCurrent(); 1.53 + 1.54 + if (index) { 1.55 + gl->fVertexAttrib2f(index, x0, x1); 1.56 + } else { 1.57 + mVertexAttrib0Vector[0] = x0; 1.58 + mVertexAttrib0Vector[1] = x1; 1.59 + mVertexAttrib0Vector[2] = 0; 1.60 + mVertexAttrib0Vector[3] = 1; 1.61 + if (gl->IsGLES()) 1.62 + gl->fVertexAttrib2f(index, x0, x1); 1.63 + } 1.64 +} 1.65 + 1.66 +void 1.67 +WebGLContext::VertexAttrib3f(GLuint index, GLfloat x0, GLfloat x1, GLfloat x2) 1.68 +{ 1.69 + if (IsContextLost()) 1.70 + return; 1.71 + 1.72 + MakeContextCurrent(); 1.73 + 1.74 + if (index) { 1.75 + gl->fVertexAttrib3f(index, x0, x1, x2); 1.76 + } else { 1.77 + mVertexAttrib0Vector[0] = x0; 1.78 + mVertexAttrib0Vector[1] = x1; 1.79 + mVertexAttrib0Vector[2] = x2; 1.80 + mVertexAttrib0Vector[3] = 1; 1.81 + if (gl->IsGLES()) 1.82 + gl->fVertexAttrib3f(index, x0, x1, x2); 1.83 + } 1.84 +} 1.85 + 1.86 +void 1.87 +WebGLContext::VertexAttrib4f(GLuint index, GLfloat x0, GLfloat x1, 1.88 + GLfloat x2, GLfloat x3) 1.89 +{ 1.90 + if (IsContextLost()) 1.91 + return; 1.92 + 1.93 + MakeContextCurrent(); 1.94 + 1.95 + if (index) { 1.96 + gl->fVertexAttrib4f(index, x0, x1, x2, x3); 1.97 + } else { 1.98 + mVertexAttrib0Vector[0] = x0; 1.99 + mVertexAttrib0Vector[1] = x1; 1.100 + mVertexAttrib0Vector[2] = x2; 1.101 + mVertexAttrib0Vector[3] = x3; 1.102 + if (gl->IsGLES()) 1.103 + gl->fVertexAttrib4f(index, x0, x1, x2, x3); 1.104 + } 1.105 +} 1.106 + 1.107 + 1.108 +void 1.109 +WebGLContext::VertexAttrib1fv_base(GLuint idx, uint32_t arrayLength, 1.110 + const GLfloat* ptr) 1.111 +{ 1.112 + if (!ValidateAttribArraySetter("VertexAttrib1fv", 1, arrayLength)) 1.113 + return; 1.114 + 1.115 + MakeContextCurrent(); 1.116 + if (idx) { 1.117 + gl->fVertexAttrib1fv(idx, ptr); 1.118 + } else { 1.119 + mVertexAttrib0Vector[0] = ptr[0]; 1.120 + mVertexAttrib0Vector[1] = GLfloat(0); 1.121 + mVertexAttrib0Vector[2] = GLfloat(0); 1.122 + mVertexAttrib0Vector[3] = GLfloat(1); 1.123 + if (gl->IsGLES()) 1.124 + gl->fVertexAttrib1fv(idx, ptr); 1.125 + } 1.126 +} 1.127 + 1.128 +void 1.129 +WebGLContext::VertexAttrib2fv_base(GLuint idx, uint32_t arrayLength, 1.130 + const GLfloat* ptr) 1.131 +{ 1.132 + if (!ValidateAttribArraySetter("VertexAttrib2fv", 2, arrayLength)) 1.133 + return; 1.134 + 1.135 + MakeContextCurrent(); 1.136 + if (idx) { 1.137 + gl->fVertexAttrib2fv(idx, ptr); 1.138 + } else { 1.139 + mVertexAttrib0Vector[0] = ptr[0]; 1.140 + mVertexAttrib0Vector[1] = ptr[1]; 1.141 + mVertexAttrib0Vector[2] = GLfloat(0); 1.142 + mVertexAttrib0Vector[3] = GLfloat(1); 1.143 + if (gl->IsGLES()) 1.144 + gl->fVertexAttrib2fv(idx, ptr); 1.145 + } 1.146 +} 1.147 + 1.148 +void 1.149 +WebGLContext::VertexAttrib3fv_base(GLuint idx, uint32_t arrayLength, 1.150 + const GLfloat* ptr) 1.151 +{ 1.152 + if (!ValidateAttribArraySetter("VertexAttrib3fv", 3, arrayLength)) 1.153 + return; 1.154 + 1.155 + MakeContextCurrent(); 1.156 + if (idx) { 1.157 + gl->fVertexAttrib3fv(idx, ptr); 1.158 + } else { 1.159 + mVertexAttrib0Vector[0] = ptr[0]; 1.160 + mVertexAttrib0Vector[1] = ptr[1]; 1.161 + mVertexAttrib0Vector[2] = ptr[2]; 1.162 + mVertexAttrib0Vector[3] = GLfloat(1); 1.163 + if (gl->IsGLES()) 1.164 + gl->fVertexAttrib3fv(idx, ptr); 1.165 + } 1.166 +} 1.167 + 1.168 +void 1.169 +WebGLContext::VertexAttrib4fv_base(GLuint idx, uint32_t arrayLength, 1.170 + const GLfloat* ptr) 1.171 +{ 1.172 + if (!ValidateAttribArraySetter("VertexAttrib4fv", 4, arrayLength)) 1.173 + return; 1.174 + 1.175 + MakeContextCurrent(); 1.176 + if (idx) { 1.177 + gl->fVertexAttrib4fv(idx, ptr); 1.178 + } else { 1.179 + mVertexAttrib0Vector[0] = ptr[0]; 1.180 + mVertexAttrib0Vector[1] = ptr[1]; 1.181 + mVertexAttrib0Vector[2] = ptr[2]; 1.182 + mVertexAttrib0Vector[3] = ptr[3]; 1.183 + if (gl->IsGLES()) 1.184 + gl->fVertexAttrib4fv(idx, ptr); 1.185 + } 1.186 +} 1.187 + 1.188 +void 1.189 +WebGLContext::EnableVertexAttribArray(GLuint index) 1.190 +{ 1.191 + if (IsContextLost()) 1.192 + return; 1.193 + 1.194 + if (!ValidateAttribIndex(index, "enableVertexAttribArray")) 1.195 + return; 1.196 + 1.197 + MakeContextCurrent(); 1.198 + InvalidateBufferFetching(); 1.199 + 1.200 + gl->fEnableVertexAttribArray(index); 1.201 + MOZ_ASSERT(mBoundVertexArray->HasAttrib(index)); // should have been validated earlier 1.202 + mBoundVertexArray->mAttribs[index].enabled = true; 1.203 +} 1.204 + 1.205 +void 1.206 +WebGLContext::DisableVertexAttribArray(GLuint index) 1.207 +{ 1.208 + if (IsContextLost()) 1.209 + return; 1.210 + 1.211 + if (!ValidateAttribIndex(index, "disableVertexAttribArray")) 1.212 + return; 1.213 + 1.214 + MakeContextCurrent(); 1.215 + InvalidateBufferFetching(); 1.216 + 1.217 + if (index || gl->IsGLES()) 1.218 + gl->fDisableVertexAttribArray(index); 1.219 + 1.220 + MOZ_ASSERT(mBoundVertexArray->HasAttrib(index)); // should have been validated earlier 1.221 + mBoundVertexArray->mAttribs[index].enabled = false; 1.222 +} 1.223 + 1.224 + 1.225 +JS::Value 1.226 +WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname, 1.227 + ErrorResult& rv) 1.228 +{ 1.229 + if (IsContextLost()) 1.230 + return JS::NullValue(); 1.231 + 1.232 + if (!ValidateAttribIndex(index, "getVertexAttrib")) 1.233 + return JS::NullValue(); 1.234 + 1.235 + MakeContextCurrent(); 1.236 + 1.237 + switch (pname) { 1.238 + case LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 1.239 + { 1.240 + return WebGLObjectAsJSValue(cx, mBoundVertexArray->mAttribs[index].buf.get(), rv); 1.241 + } 1.242 + 1.243 + case LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE: 1.244 + { 1.245 + return JS::Int32Value(mBoundVertexArray->mAttribs[index].stride); 1.246 + } 1.247 + 1.248 + case LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE: 1.249 + { 1.250 + if (!ValidateAttribIndex(index, "getVertexAttrib")) 1.251 + return JS::NullValue(); 1.252 + 1.253 + if (!mBoundVertexArray->mAttribs[index].enabled) 1.254 + return JS::Int32Value(4); 1.255 + 1.256 + // Don't break; fall through. 1.257 + } 1.258 + case LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE: 1.259 + { 1.260 + GLint i = 0; 1.261 + gl->fGetVertexAttribiv(index, pname, &i); 1.262 + if (pname == LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE) 1.263 + return JS::Int32Value(i); 1.264 + MOZ_ASSERT(pname == LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE); 1.265 + return JS::NumberValue(uint32_t(i)); 1.266 + } 1.267 + 1.268 + case LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR: 1.269 + { 1.270 + if (IsExtensionEnabled(WebGLExtensionID::ANGLE_instanced_arrays)) 1.271 + { 1.272 + return JS::Int32Value(mBoundVertexArray->mAttribs[index].divisor); 1.273 + } 1.274 + break; 1.275 + } 1.276 + 1.277 + case LOCAL_GL_CURRENT_VERTEX_ATTRIB: 1.278 + { 1.279 + GLfloat vec[4] = {0, 0, 0, 1}; 1.280 + if (index) { 1.281 + gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, &vec[0]); 1.282 + } else { 1.283 + vec[0] = mVertexAttrib0Vector[0]; 1.284 + vec[1] = mVertexAttrib0Vector[1]; 1.285 + vec[2] = mVertexAttrib0Vector[2]; 1.286 + vec[3] = mVertexAttrib0Vector[3]; 1.287 + } 1.288 + JSObject* obj = Float32Array::Create(cx, this, 4, vec); 1.289 + if (!obj) { 1.290 + rv.Throw(NS_ERROR_OUT_OF_MEMORY); 1.291 + } 1.292 + return JS::ObjectOrNullValue(obj); 1.293 + } 1.294 + 1.295 + case LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED: 1.296 + { 1.297 + return JS::BooleanValue(mBoundVertexArray->mAttribs[index].enabled); 1.298 + } 1.299 + 1.300 + case LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 1.301 + { 1.302 + return JS::BooleanValue(mBoundVertexArray->mAttribs[index].normalized); 1.303 + } 1.304 + 1.305 + default: 1.306 + break; 1.307 + } 1.308 + 1.309 + ErrorInvalidEnumInfo("getVertexAttrib: parameter", pname); 1.310 + 1.311 + return JS::NullValue(); 1.312 +} 1.313 + 1.314 +WebGLsizeiptr 1.315 +WebGLContext::GetVertexAttribOffset(GLuint index, GLenum pname) 1.316 +{ 1.317 + if (IsContextLost()) 1.318 + return 0; 1.319 + 1.320 + if (!ValidateAttribIndex(index, "getVertexAttribOffset")) 1.321 + return 0; 1.322 + 1.323 + if (pname != LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER) { 1.324 + ErrorInvalidEnum("getVertexAttribOffset: bad parameter"); 1.325 + return 0; 1.326 + } 1.327 + 1.328 + return mBoundVertexArray->mAttribs[index].byteOffset; 1.329 +} 1.330 + 1.331 +void 1.332 +WebGLContext::VertexAttribPointer(GLuint index, GLint size, GLenum type, 1.333 + WebGLboolean normalized, GLsizei stride, 1.334 + WebGLintptr byteOffset) 1.335 +{ 1.336 + if (IsContextLost()) 1.337 + return; 1.338 + 1.339 + if (mBoundArrayBuffer == nullptr) 1.340 + return ErrorInvalidOperation("vertexAttribPointer: must have valid GL_ARRAY_BUFFER binding"); 1.341 + 1.342 + GLsizei requiredAlignment = 1; 1.343 + switch (type) { 1.344 + case LOCAL_GL_BYTE: 1.345 + case LOCAL_GL_UNSIGNED_BYTE: 1.346 + requiredAlignment = 1; 1.347 + break; 1.348 + case LOCAL_GL_SHORT: 1.349 + case LOCAL_GL_UNSIGNED_SHORT: 1.350 + requiredAlignment = 2; 1.351 + break; 1.352 + // XXX case LOCAL_GL_FIXED: 1.353 + case LOCAL_GL_FLOAT: 1.354 + requiredAlignment = 4; 1.355 + break; 1.356 + default: 1.357 + return ErrorInvalidEnumInfo("vertexAttribPointer: type", type); 1.358 + } 1.359 + 1.360 + // requiredAlignment should always be a power of two. 1.361 + GLsizei requiredAlignmentMask = requiredAlignment - 1; 1.362 + 1.363 + if (!ValidateAttribIndex(index, "vertexAttribPointer")) { 1.364 + return; 1.365 + } 1.366 + 1.367 + if (size < 1 || size > 4) 1.368 + return ErrorInvalidValue("vertexAttribPointer: invalid element size"); 1.369 + 1.370 + if (stride < 0 || stride > 255) // see WebGL spec section 6.6 "Vertex Attribute Data Stride" 1.371 + return ErrorInvalidValue("vertexAttribPointer: negative or too large stride"); 1.372 + 1.373 + if (byteOffset < 0) 1.374 + return ErrorInvalidValue("vertexAttribPointer: negative offset"); 1.375 + 1.376 + if (stride & requiredAlignmentMask) { 1.377 + return ErrorInvalidOperation("vertexAttribPointer: stride doesn't satisfy the alignment " 1.378 + "requirement of given type"); 1.379 + } 1.380 + 1.381 + if (byteOffset & requiredAlignmentMask) { 1.382 + return ErrorInvalidOperation("vertexAttribPointer: byteOffset doesn't satisfy the alignment " 1.383 + "requirement of given type"); 1.384 + 1.385 + } 1.386 + 1.387 + InvalidateBufferFetching(); 1.388 + 1.389 + /* XXX make work with bufferSubData & heterogeneous types 1.390 + if (type != mBoundArrayBuffer->GLType()) 1.391 + return ErrorInvalidOperation("vertexAttribPointer: type must match bound VBO type: %d != %d", type, mBoundArrayBuffer->GLType()); 1.392 + */ 1.393 + 1.394 + WebGLVertexAttribData &vd = mBoundVertexArray->mAttribs[index]; 1.395 + 1.396 + vd.buf = mBoundArrayBuffer; 1.397 + vd.stride = stride; 1.398 + vd.size = size; 1.399 + vd.byteOffset = byteOffset; 1.400 + vd.type = type; 1.401 + vd.normalized = normalized; 1.402 + 1.403 + MakeContextCurrent(); 1.404 + 1.405 + gl->fVertexAttribPointer(index, size, type, normalized, 1.406 + stride, 1.407 + reinterpret_cast<void*>(byteOffset)); 1.408 +} 1.409 + 1.410 +void 1.411 +WebGLContext::VertexAttribDivisor(GLuint index, GLuint divisor) 1.412 +{ 1.413 + if (IsContextLost()) 1.414 + return; 1.415 + 1.416 + if (!ValidateAttribIndex(index, "vertexAttribDivisor")) { 1.417 + return; 1.418 + } 1.419 + 1.420 + WebGLVertexAttribData& vd = mBoundVertexArray->mAttribs[index]; 1.421 + vd.divisor = divisor; 1.422 + 1.423 + InvalidateBufferFetching(); 1.424 + 1.425 + MakeContextCurrent(); 1.426 + 1.427 + gl->fVertexAttribDivisor(index, divisor); 1.428 +}