Bug 1048747 - [WebGL2] Implement uniform block/buffer. r=jgilbert, r=smaug

--HG--
extra : rebase_source : cdd24494397c9b6ce9f7103c78b8432107ddc20f
extra : source : dadf008b2b7a14d0c308ab4c8eae6001fb5f7492
extra : histedit_source : 90b49de9e294dd8e89a666fa9b3025892a6cf4e6
This commit is contained in:
Dan Glastonbury 2014-12-15 10:31:24 +10:00
parent f65c7d3575
commit 20a02b0b66
3 changed files with 284 additions and 52 deletions

View File

@ -14,6 +14,10 @@ class WebGLSampler;
class WebGLSync;
class WebGLTransformFeedback;
class WebGLVertexArrayObject;
namespace dom {
class OwningUnsignedLongOrUint32ArrayOrBoolean;
class OwningWebGLBufferOrLongLong;
}
class WebGL2Context
: public WebGLContext
@ -231,14 +235,23 @@ public:
void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer);
void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, GLintptr offset, GLsizeiptr size);
*/
void GetIndexedParameter(JSContext*, GLenum target, GLuint index, JS::MutableHandleValue retval);
void GetUniformIndices(WebGLProgram* program, const dom::Sequence<nsString>& uniformNames, dom::Nullable< nsTArray<GLuint> >& retval);
void GetActiveUniforms(WebGLProgram* program, const dom::Sequence<GLuint>& uniformIndices, GLenum pname,
void GetIndexedParameter(GLenum target, GLuint index,
dom::Nullable<dom::OwningWebGLBufferOrLongLong>& retval);
void GetUniformIndices(WebGLProgram* program,
const dom::Sequence<nsString>& uniformNames,
dom::Nullable< nsTArray<GLuint> >& retval);
void GetActiveUniforms(WebGLProgram* program,
const dom::Sequence<GLuint>& uniformIndices, GLenum pname,
dom::Nullable< nsTArray<GLint> >& retval);
GLuint GetUniformBlockIndex(WebGLProgram* program, const nsAString& uniformBlockName);
void GetActiveUniformBlockParameter(JSContext*, WebGLProgram* program, GLuint uniformBlockIndex, GLenum pname, JS::MutableHandleValue retval);
void GetActiveUniformBlockName(WebGLProgram* program, GLuint uniformBlockIndex, dom::DOMString& retval);
void UniformBlockBinding(WebGLProgram* program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
void GetActiveUniformBlockParameter(JSContext*, WebGLProgram* program,
GLuint uniformBlockIndex, GLenum pname,
dom::Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval,
ErrorResult& rv);
void GetActiveUniformBlockName(WebGLProgram* program, GLuint uniformBlockIndex,
nsAString& retval);
void UniformBlockBinding(WebGLProgram* program, GLuint uniformBlockIndex,
GLuint uniformBlockBinding);
// -------------------------------------------------------------------------

View File

@ -5,8 +5,11 @@
#include "WebGL2Context.h"
#include "GLContext.h"
#include "WebGLContext.h"
#include "WebGLProgram.h"
#include "WebGLVertexArray.h"
#include "WebGLVertexAttribData.h"
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -30,38 +33,39 @@ GLfloat PuntToFloat(GLuint u)
}
bool
WebGL2Context::ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info)
WebGL2Context::ValidateAttribPointerType(bool integerMode, GLenum type,
GLsizei* out_alignment, const char* info)
{
MOZ_ASSERT(alignment);
MOZ_ASSERT(out_alignment);
switch (type) {
case LOCAL_GL_BYTE:
case LOCAL_GL_UNSIGNED_BYTE:
*alignment = 1;
*out_alignment = 1;
return true;
case LOCAL_GL_SHORT:
case LOCAL_GL_UNSIGNED_SHORT:
*alignment = 2;
*out_alignment = 2;
return true;
case LOCAL_GL_INT:
case LOCAL_GL_UNSIGNED_INT:
*alignment = 4;
*out_alignment = 4;
return true;
}
if (!integerMode) {
switch (type) {
case LOCAL_GL_HALF_FLOAT:
*alignment = 2;
*out_alignment = 2;
return true;
case LOCAL_GL_FLOAT:
case LOCAL_GL_FIXED:
case LOCAL_GL_INT_2_10_10_10_REV:
case LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV:
*alignment = 4;
*out_alignment = 4;
return true;
}
}
@ -74,7 +78,8 @@ WebGL2Context::ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei*
// Uniforms and attributes
void
WebGL2Context::VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset)
WebGL2Context::VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride,
GLintptr offset)
{
if (IsContextLost())
return;
@ -82,8 +87,11 @@ WebGL2Context::VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsiz
if (!ValidateAttribIndex(index, "vertexAttribIPointer"))
return;
if (!ValidateAttribPointer(true, index, size, type, LOCAL_GL_FALSE, stride, offset, "vertexAttribIPointer"))
if (!ValidateAttribPointer(true, index, size, type, LOCAL_GL_FALSE, stride, offset,
"vertexAttribIPointer"))
{
return;
}
MOZ_ASSERT(mBoundVertexArray);
mBoundVertexArray->EnsureAttrib(index);
@ -123,103 +131,120 @@ WebGL2Context::Uniform3ui(WebGLUniformLocation* location, GLuint v0, GLuint v1,
}
void
WebGL2Context::Uniform4ui(WebGLUniformLocation* location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
WebGL2Context::Uniform4ui(WebGLUniformLocation* location, GLuint v0, GLuint v1,
GLuint v2, GLuint v3)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::Uniform1uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value)
WebGL2Context::Uniform1uiv(WebGLUniformLocation* location,
const dom::Sequence<GLuint>& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::Uniform2uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value)
WebGL2Context::Uniform2uiv(WebGLUniformLocation* location,
const dom::Sequence<GLuint>& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::Uniform3uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value)
WebGL2Context::Uniform3uiv(WebGLUniformLocation* location,
const dom::Sequence<GLuint>& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::Uniform4uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value)
WebGL2Context::Uniform4uiv(WebGLUniformLocation* location,
const dom::Sequence<GLuint>& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
WebGL2Context::UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose,
const dom::Float32Array& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
WebGL2Context::UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose,
const dom::Sequence<GLfloat>& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
WebGL2Context::UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose,
const dom::Float32Array& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
WebGL2Context::UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose,
const dom::Sequence<GLfloat>& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
WebGL2Context::UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose,
const dom::Float32Array& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
WebGL2Context::UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose,
const dom::Sequence<GLfloat>& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
WebGL2Context::UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose,
const dom::Float32Array& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
WebGL2Context::UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose,
const dom::Sequence<GLfloat>& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
WebGL2Context::UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose,
const dom::Float32Array& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
WebGL2Context::UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose,
const dom::Sequence<GLfloat>& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
WebGL2Context::UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose,
const dom::Float32Array& value)
{
MOZ_CRASH("Not Implemented.");
}
void
WebGL2Context::UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
WebGL2Context::UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose,
const dom::Sequence<GLfloat>& value)
{
MOZ_CRASH("Not Implemented.");
}
@ -309,13 +334,51 @@ WebGL2Context::VertexAttribI4uiv(GLuint index, const dom::Sequence<GLuint>& v)
// TODO(djg): Implemented in WebGLContext
/*
void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer);
void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, GLintptr offset, GLsizeiptr size);
void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
GLintptr offset, GLsizeiptr size);
*/
/* This doesn't belong here. It's part of state querying */
void
WebGL2Context::GetIndexedParameter(JSContext*, GLenum target, GLuint index, JS::MutableHandleValue retval)
WebGL2Context::GetIndexedParameter(GLenum target, GLuint index,
dom::Nullable<dom::OwningWebGLBufferOrLongLong>& retval)
{
MOZ_CRASH("Not Implemented.");
retval.SetNull();
if (IsContextLost())
return;
GLint64 data = 0;
MakeContextCurrent();
switch (target) {
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
if (index >= mGLMaxTransformFeedbackSeparateAttribs)
return ErrorInvalidValue("getIndexedParameter: index should be less than "
"MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS");
retval.SetValue().SetAsWebGLBuffer() =
mBoundTransformFeedbackBuffers[index].get();
return;
case LOCAL_GL_UNIFORM_BUFFER_BINDING:
if (index >= mGLMaxUniformBufferBindings)
return ErrorInvalidValue("getIndexedParameter: index should be than "
"MAX_UNIFORM_BUFFER_BINDINGS");
retval.SetValue().SetAsWebGLBuffer() = mBoundUniformBuffers[index].get();
return;
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START:
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
case LOCAL_GL_UNIFORM_BUFFER_START:
case LOCAL_GL_UNIFORM_BUFFER_SIZE:
gl->fGetInteger64i_v(target, index, &data);
retval.SetValue().SetAsLongLong() = data;
return;
}
ErrorInvalidEnumInfo("getIndexedParameter: target", target);
}
void
@ -323,7 +386,32 @@ WebGL2Context::GetUniformIndices(WebGLProgram* program,
const dom::Sequence<nsString>& uniformNames,
dom::Nullable< nsTArray<GLuint> >& retval)
{
MOZ_CRASH("Not Implemented.");
retval.SetNull();
if (IsContextLost())
return;
if (!ValidateObject("getUniformIndices: program", program))
return;
if (!uniformNames.Length())
return;
GLuint progname = program->GLName();
size_t count = uniformNames.Length();
nsTArray<GLuint>& arr = retval.SetValue();
MakeContextCurrent();
for (size_t n = 0; n < count; n++) {
NS_LossyConvertUTF16toASCII name(uniformNames[n]);
// const GLchar* glname = name.get();
const GLchar* glname = nullptr;
name.BeginReading(glname);
GLuint index = 0;
gl->fGetUniformIndices(progname, 1, &glname, &index);
arr.AppendElement(index);
}
}
void
@ -332,32 +420,159 @@ WebGL2Context::GetActiveUniforms(WebGLProgram* program,
GLenum pname,
dom::Nullable< nsTArray<GLint> >& retval)
{
MOZ_CRASH("Not Implemented.");
retval.SetNull();
if (IsContextLost())
return;
if (!ValidateObject("getActiveUniforms: program", program))
return;
size_t count = uniformIndices.Length();
if (!count)
return;
GLuint progname = program->GLName();
nsTArray<GLint>& arr = retval.SetValue();
arr.SetLength(count);
MakeContextCurrent();
gl->fGetActiveUniformsiv(progname, count, uniformIndices.Elements(), pname,
arr.Elements());
}
GLuint
WebGL2Context::GetUniformBlockIndex(WebGLProgram* program, const nsAString& uniformBlockName)
WebGL2Context::GetUniformBlockIndex(WebGLProgram* program,
const nsAString& uniformBlockName)
{
MOZ_CRASH("Not Implemented.");
return 0;
if (IsContextLost())
return 0;
if (!ValidateObject("getUniformBlockIndex: program", program))
return 0;
if (!ValidateGLSLVariableName(uniformBlockName, "getUniformBlockIndex"))
return 0;
NS_LossyConvertUTF16toASCII cname(uniformBlockName);
nsCString mappedName;
program->MapIdentifier(cname, &mappedName);
GLuint progname = program->GLName();
MakeContextCurrent();
return gl->fGetUniformBlockIndex(progname, mappedName.get());
}
static bool
GetUniformBlockActiveUniforms(gl::GLContext* gl, JSContext* cx,
WebGL2Context* owner, GLuint progname,
GLuint uniformBlockIndex,
JS::MutableHandleObject out_array)
{
GLint length = 0;
gl->fGetActiveUniformBlockiv(progname, uniformBlockIndex,
LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &length);
JS::RootedObject obj(cx, Uint32Array::Create(cx, owner, length, nullptr));
if (!obj)
return false;
JS::AutoCheckCannotGC nogc;
gl->fGetActiveUniformBlockiv(progname, uniformBlockIndex,
LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES,
(GLint*) JS_GetUint32ArrayData(obj, nogc));
out_array.set(obj);
return true;
}
void
WebGL2Context::GetActiveUniformBlockParameter(JSContext*, WebGLProgram* program,
WebGL2Context::GetActiveUniformBlockParameter(JSContext* cx, WebGLProgram* program,
GLuint uniformBlockIndex, GLenum pname,
JS::MutableHandleValue retval)
Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval,
ErrorResult& rv)
{
MOZ_CRASH("Not Implemented.");
retval.SetNull();
if (IsContextLost())
return;
if (!ValidateObject("getActiveUniformBlockParameter: program", program))
return;
GLuint progname = program->GLName();
GLint param = 0;
JS::RootedObject array(cx);
MakeContextCurrent();
switch(pname) {
case LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
case LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
gl->fGetActiveUniformBlockiv(progname, uniformBlockIndex, pname, &param);
retval.SetValue().SetAsBoolean() = (param != 0);
return;
case LOCAL_GL_UNIFORM_BLOCK_BINDING:
case LOCAL_GL_UNIFORM_BLOCK_DATA_SIZE:
case LOCAL_GL_UNIFORM_BLOCK_NAME_LENGTH:
case LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
gl->fGetActiveUniformBlockiv(progname, uniformBlockIndex, pname, &param);
retval.SetValue().SetAsUnsignedLong() = param;
return;
case LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
if (!GetUniformBlockActiveUniforms(gl, cx, this, progname, uniformBlockIndex,
&array))
{
rv = NS_ERROR_OUT_OF_MEMORY;
return;
}
DebugOnly<bool> inited = retval.SetValue().SetAsUint32Array().Init(array);
MOZ_ASSERT(inited);
return;
}
ErrorInvalidEnumInfo("getActiveUniformBlockParameter: parameter", pname);
}
void
WebGL2Context::GetActiveUniformBlockName(WebGLProgram* program, GLuint uniformBlockIndex, dom::DOMString& retval)
{
MOZ_CRASH("Not Implemented.");
}
#define WEBGL_MAX_UNIFORM_BLOCK_NAME_LENGTH 256
void
WebGL2Context::UniformBlockBinding(WebGLProgram* program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
WebGL2Context::GetActiveUniformBlockName(WebGLProgram* program, GLuint uniformBlockIndex,
nsAString& retval)
{
MOZ_CRASH("Not Implemented.");
if (IsContextLost())
return;
if (!ValidateObject("getActiveUniformBlockName: program", program))
return;
GLuint progname = program->GLName();
GLchar nameBuffer[WEBGL_MAX_UNIFORM_BLOCK_NAME_LENGTH];
GLsizei length = 0;
MakeContextCurrent();
gl->fGetActiveUniformBlockName(progname, uniformBlockIndex,
WEBGL_MAX_UNIFORM_BLOCK_NAME_LENGTH, &length,
nameBuffer);
retval.Assign(NS_ConvertASCIItoUTF16(nsDependentCString(nameBuffer)));
}
#undef WEBGL_MAX_UNIFORM_BLOCK_NAME_LENGTH
void
WebGL2Context::UniformBlockBinding(WebGLProgram* program, GLuint uniformBlockIndex,
GLuint uniformBlockBinding)
{
if (IsContextLost())
return;
if (!ValidateObject("uniformBlockBinding: program", program))
return;
GLuint progname = program->GLName();
MakeContextCurrent();
gl->fUniformBlockBinding(progname, uniformBlockIndex, uniformBlockBinding);
}

View File

@ -454,11 +454,15 @@ interface WebGL2RenderingContext : WebGLRenderingContext
/* Uniform Buffer Objects and Transform Feedback Buffers */
void bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer);
void bindBufferRange(GLenum target, GLuint index, WebGLBuffer? buffer, GLintptr offset, GLsizeiptr size);
any getIndexedParameter(GLenum target, GLuint index);
// Return from getIndexedParameter is WebGLBuffer or GLintptr or GLsizeiptr) but
// GLintptr and GLsizeiptr are the same underlying type of long long, so only specify
// GLintptr here, otherwise interface generator returns error.
(WebGLBuffer or GLintptr)? getIndexedParameter(GLenum target, GLuint index);
sequence<GLuint>? getUniformIndices(WebGLProgram? program, sequence<DOMString> uniformNames);
sequence<GLint>? getActiveUniforms(WebGLProgram? program, sequence<GLuint> uniformIndices, GLenum pname);
GLuint getUniformBlockIndex(WebGLProgram? program, DOMString uniformBlockName);
any getActiveUniformBlockParameter(WebGLProgram? program, GLuint uniformBlockIndex, GLenum pname);
[Throws]
(GLuint or Uint32Array or GLboolean)? getActiveUniformBlockParameter(WebGLProgram? program, GLuint uniformBlockIndex, GLenum pname);
DOMString? getActiveUniformBlockName(WebGLProgram? program, GLuint uniformBlockIndex);
void uniformBlockBinding(WebGLProgram? program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);