diff --git a/content/canvas/src/WebGLContext.h b/content/canvas/src/WebGLContext.h index a3711a65bd42..85836f65a6fd 100644 --- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -1254,6 +1254,8 @@ public: friend class WebGLShader; friend class WebGLUniformLocation; friend class WebGLVertexArray; + friend class WebGLVertexArrayFake; + friend class WebGLVertexArrayGL; }; // used by DOM bindings in conjunction with GetParentObject diff --git a/content/canvas/src/WebGLContextBuffers.cpp b/content/canvas/src/WebGLContextBuffers.cpp index 680bd6df0e64..63a6f72d1be2 100644 --- a/content/canvas/src/WebGLContextBuffers.cpp +++ b/content/canvas/src/WebGLContextBuffers.cpp @@ -385,7 +385,7 @@ WebGLContext::DeleteBuffer(WebGLBuffer *buffer) static_cast(nullptr)); } - if (mBoundVertexArray->mBoundElementArrayBuffer == buffer) { + if (mBoundVertexArray->mElementArrayBuffer == buffer) { BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, static_cast(nullptr)); } @@ -433,7 +433,7 @@ WebGLContext::GetBufferSlotByTarget(GLenum target, const char* infos) return &mBoundArrayBuffer; case LOCAL_GL_ELEMENT_ARRAY_BUFFER: - return &mBoundVertexArray->mBoundElementArrayBuffer; + return &mBoundVertexArray->mElementArrayBuffer; case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER: if (!IsWebGL2()) { @@ -487,7 +487,7 @@ WebGLContext::CheckedBufferData(GLenum target, if (target == LOCAL_GL_ARRAY_BUFFER) { boundBuffer = mBoundArrayBuffer; } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) { - boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer; + boundBuffer = mBoundVertexArray->mElementArrayBuffer; } MOZ_ASSERT(boundBuffer != nullptr, "no buffer bound for this target"); diff --git a/content/canvas/src/WebGLContextDraw.cpp b/content/canvas/src/WebGLContextDraw.cpp index 56b6e4f82e55..c6f093267e2d 100644 --- a/content/canvas/src/WebGLContextDraw.cpp +++ b/content/canvas/src/WebGLContextDraw.cpp @@ -219,12 +219,12 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type, return false; } - if (!mBoundVertexArray->mBoundElementArrayBuffer) { + if (!mBoundVertexArray->mElementArrayBuffer) { ErrorInvalidOperation("%s: must have element array buffer binding", info); return false; } - WebGLBuffer& elemArrayBuffer = *mBoundVertexArray->mBoundElementArrayBuffer; + WebGLBuffer& elemArrayBuffer = *mBoundVertexArray->mElementArrayBuffer; if (!elemArrayBuffer.ByteLength()) { ErrorInvalidOperation("%s: bound element array buffer doesn't have any data", info); diff --git a/content/canvas/src/WebGLContextState.cpp b/content/canvas/src/WebGLContextState.cpp index 1c310cfcb67b..dffe5f6cf7a4 100644 --- a/content/canvas/src/WebGLContextState.cpp +++ b/content/canvas/src/WebGLContextState.cpp @@ -423,7 +423,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) } case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING: { - return WebGLObjectAsJSValue(cx, mBoundVertexArray->mBoundElementArrayBuffer.get(), rv); + return WebGLObjectAsJSValue(cx, mBoundVertexArray->mElementArrayBuffer.get(), rv); } case LOCAL_GL_RENDERBUFFER_BINDING: { diff --git a/content/canvas/src/WebGLContextUtils.cpp b/content/canvas/src/WebGLContextUtils.cpp index 26282ef1d5d4..545a6220046f 100644 --- a/content/canvas/src/WebGLContextUtils.cpp +++ b/content/canvas/src/WebGLContextUtils.cpp @@ -525,7 +525,7 @@ WebGLContext::AssertCachedBindings() AssertUintParamCorrect(gl, LOCAL_GL_ARRAY_BUFFER_BINDING, bound); MOZ_ASSERT(mBoundVertexArray); - WebGLBuffer* curBuff = mBoundVertexArray->mBoundElementArrayBuffer; + WebGLBuffer* curBuff = mBoundVertexArray->mElementArrayBuffer; bound = curBuff ? curBuff->GLName() : 0; AssertUintParamCorrect(gl, LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING, bound); diff --git a/content/canvas/src/WebGLContextValidate.cpp b/content/canvas/src/WebGLContextValidate.cpp index 066f2ee99e68..fa246ad0c349 100644 --- a/content/canvas/src/WebGLContextValidate.cpp +++ b/content/canvas/src/WebGLContextValidate.cpp @@ -1788,7 +1788,7 @@ WebGLContext::InitAndValidateGL() false); } - mDefaultVertexArray = new WebGLVertexArray(this); + mDefaultVertexArray = WebGLVertexArray::Create(this); mDefaultVertexArray->mAttribs.SetLength(mGLMaxVertexAttribs); mBoundVertexArray = mDefaultVertexArray; diff --git a/content/canvas/src/WebGLContextVertexArray.cpp b/content/canvas/src/WebGLContextVertexArray.cpp index 48d2c6f83c7f..383b758fee39 100644 --- a/content/canvas/src/WebGLContextVertexArray.cpp +++ b/content/canvas/src/WebGLContextVertexArray.cpp @@ -36,14 +36,12 @@ WebGLContext::BindVertexArray(WebGLVertexArray *array) MakeContextCurrent(); if (array) { - gl->fBindVertexArray(array->GLName()); - array->SetHasEverBeenBound(true); mBoundVertexArray = array; - } - else { - gl->fBindVertexArray(0); + } else { mBoundVertexArray = mDefaultVertexArray; } + + mBoundVertexArray->BindVertexArray(); } already_AddRefed @@ -52,12 +50,10 @@ WebGLContext::CreateVertexArray() if (IsContextLost()) return nullptr; - nsRefPtr globj = new WebGLVertexArray(this); + nsRefPtr globj = WebGLVertexArray::Create(this); MakeContextCurrent(); - gl->fGenVertexArrays(1, &globj->mGLName); - - mVertexArrays.insertBack(globj); + globj->GenVertexArray(); return globj.forget(); } diff --git a/content/canvas/src/WebGLExtensionVertexArray.cpp b/content/canvas/src/WebGLExtensionVertexArray.cpp index 3908fb5b2693..438cfb6c22f9 100644 --- a/content/canvas/src/WebGLExtensionVertexArray.cpp +++ b/content/canvas/src/WebGLExtensionVertexArray.cpp @@ -61,9 +61,9 @@ void WebGLExtensionVertexArray::BindVertexArrayOES(WebGLVertexArray* array) bool WebGLExtensionVertexArray::IsSupported(const WebGLContext* context) { - gl::GLContext* gl = context->GL(); - - return gl->IsSupported(gl::GLFeature::vertex_array_object); + // If it is not supported then it's emulated, therefore it's always 'supported' + // See - WebGLVertexArrayFake.h/cpp for the emulation + return true; } IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionVertexArray) diff --git a/content/canvas/src/WebGLVertexArray.cpp b/content/canvas/src/WebGLVertexArray.cpp index a9e27432da58..23914e1c0919 100644 --- a/content/canvas/src/WebGLVertexArray.cpp +++ b/content/canvas/src/WebGLVertexArray.cpp @@ -1,11 +1,14 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "WebGLVertexArray.h" + #include "WebGLContext.h" #include "WebGLBuffer.h" -#include "WebGLVertexArray.h" +#include "WebGLVertexArrayGL.h" +#include "WebGLVertexArrayFake.h" #include "mozilla/dom/WebGLRenderingContextBinding.h" #include "GLContext.h" @@ -22,22 +25,34 @@ WebGLVertexArray::WebGLVertexArray(WebGLContext* context) , mHasEverBeenBound(false) { SetIsDOMBinding(); + context->mVertexArrays.insertBack(this); } -void WebGLVertexArray::Delete() { - if (mGLName != 0) { - mBoundElementArrayBuffer = nullptr; - - mContext->MakeContextCurrent(); - mContext->gl->fDeleteVertexArrays(1, &mGLName); - LinkedListElement::removeFrom(mContext->mVertexArrays); +WebGLVertexArray* +WebGLVertexArray::Create(WebGLContext* context) +{ + WebGLVertexArray* array; + if (context->gl->IsSupported(gl::GLFeature::vertex_array_object)) { + array = new WebGLVertexArrayGL(context); + } else { + array = new WebGLVertexArrayFake(context); } - mBoundElementArrayBuffer = nullptr; + return array; +} + +void +WebGLVertexArray::Delete() +{ + DeleteImpl(); + + LinkedListElement::removeFrom(mContext->mVertexArrays); + mElementArrayBuffer = nullptr; mAttribs.Clear(); } -bool WebGLVertexArray::EnsureAttrib(GLuint index, const char *info) +bool +WebGLVertexArray::EnsureAttrib(GLuint index, const char *info) { if (index >= GLuint(mContext->mGLMaxVertexAttribs)) { if (index == GLuint(-1)) { @@ -58,7 +73,7 @@ bool WebGLVertexArray::EnsureAttrib(GLuint index, const char *info) NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLVertexArray, mAttribs, - mBoundElementArrayBuffer) + mElementArrayBuffer) NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLVertexArray, AddRef) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLVertexArray, Release) diff --git a/content/canvas/src/WebGLVertexArray.h b/content/canvas/src/WebGLVertexArray.h index bcfd7d1fdb53..188d0c5fca91 100644 --- a/content/canvas/src/WebGLVertexArray.h +++ b/content/canvas/src/WebGLVertexArray.h @@ -16,7 +16,7 @@ namespace mozilla { -class WebGLVertexArray MOZ_FINAL +class WebGLVertexArray : public nsWrapperCache , public WebGLRefCountedObject , public LinkedListElement @@ -25,22 +25,25 @@ class WebGLVertexArray MOZ_FINAL // ----------------------------------------------------------------------------- // PUBLIC public: + static WebGLVertexArray* Create(WebGLContext* context); - // ------------------------------------------------------------------------- - // CONSTRUCTOR & DESTRUCTOR - - WebGLVertexArray(WebGLContext *context); - - ~WebGLVertexArray() { - DeleteOnce(); + void BindVertexArray() { + SetHasEverBeenBound(true); + BindVertexArrayImpl(); }; + virtual void GenVertexArray() = 0; + virtual void BindVertexArrayImpl() = 0; + + GLuint GLName() const { return mGLName; } // ------------------------------------------------------------------------- - // IMPLMENET PARENT CLASSES + // IMPLEMENT PARENT CLASSES void Delete(); + virtual void DeleteImpl() = 0; + WebGLContext* GetParentObject() const { return Context(); } @@ -50,13 +53,11 @@ public: NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLVertexArray) NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLVertexArray) - // ------------------------------------------------------------------------- // MEMBER FUNCTIONS bool HasEverBeenBound() { return mHasEverBeenBound; } void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; } - GLuint GLName() const { return mGLName; } bool EnsureAttrib(GLuint index, const char *info); bool HasAttrib(GLuint index) { @@ -68,8 +69,13 @@ public: // ----------------------------------------------------------------------------- -// PRIVATE -private: +// PROTECTED +protected: + WebGLVertexArray(WebGLContext* context); + + virtual ~WebGLVertexArray() { + MOZ_ASSERT(IsDeleted()); + }; // ------------------------------------------------------------------------- // MEMBERS @@ -77,8 +83,7 @@ private: GLuint mGLName; bool mHasEverBeenBound; nsTArray mAttribs; - WebGLRefPtr mBoundElementArrayBuffer; - + WebGLRefPtr mElementArrayBuffer; // ------------------------------------------------------------------------- // FRIENDSHIPS diff --git a/content/canvas/src/WebGLVertexArrayFake.cpp b/content/canvas/src/WebGLVertexArrayFake.cpp new file mode 100644 index 000000000000..f1010abb6750 --- /dev/null +++ b/content/canvas/src/WebGLVertexArrayFake.cpp @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGLVertexArrayFake.h" + +#include "WebGLContext.h" +#include "GLContext.h" + +namespace mozilla { + +void +WebGLVertexArrayFake::BindVertexArrayImpl() +{ + // Go through and re-bind all buffers and setup all + // vertex attribute pointers + gl::GLContext* gl = mContext->gl; + + WebGLRefPtr prevBuffer = mContext->mBoundArrayBuffer; + mContext->BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, mElementArrayBuffer); + + for (size_t i = 0; i < mAttribs.Length(); ++i) { + const WebGLVertexAttribData& vd = mAttribs[i]; + + mContext->BindBuffer(LOCAL_GL_ARRAY_BUFFER, vd.buf); + + gl->fVertexAttribPointer(i, vd.size, vd.type, vd.normalized, + vd.stride, reinterpret_cast(vd.byteOffset)); + + if (vd.enabled) { + gl->fEnableVertexAttribArray(i); + } else { + gl->fDisableVertexAttribArray(i); + } + } + + mContext->BindBuffer(LOCAL_GL_ARRAY_BUFFER, prevBuffer); +} + +} // namespace mozilla + diff --git a/content/canvas/src/WebGLVertexArrayFake.h b/content/canvas/src/WebGLVertexArrayFake.h new file mode 100644 index 000000000000..49e4fe6d6ae2 --- /dev/null +++ b/content/canvas/src/WebGLVertexArrayFake.h @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef WEBGLVERTEXARRAYFAKE_H_ +#define WEBGLVERTEXARRAYFAKE_H_ + +#include "WebGLVertexArray.h" + +namespace mozilla { + +class WebGLVertexArrayFake MOZ_FINAL + : public WebGLVertexArray +{ +public: + virtual void BindVertexArrayImpl() MOZ_OVERRIDE; + virtual void DeleteImpl() MOZ_OVERRIDE { }; + virtual void GenVertexArray() MOZ_OVERRIDE { }; + +private: + WebGLVertexArrayFake(WebGLContext *context) + : WebGLVertexArray(context) + { } + + ~WebGLVertexArrayFake() { + DeleteOnce(); + } + + friend class WebGLVertexArray; +}; + +} // namespace mozilla + +#endif diff --git a/content/canvas/src/WebGLVertexArrayGL.cpp b/content/canvas/src/WebGLVertexArrayGL.cpp new file mode 100644 index 000000000000..172a68a22567 --- /dev/null +++ b/content/canvas/src/WebGLVertexArrayGL.cpp @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGLVertexArrayGL.h" + +#include "WebGLContext.h" +#include "GLContext.h" + +namespace mozilla { + +void +WebGLVertexArrayGL::DeleteImpl() +{ + mElementArrayBuffer = nullptr; + + mContext->MakeContextCurrent(); + mContext->gl->fDeleteVertexArrays(1, &mGLName); +} + +void +WebGLVertexArrayGL::BindVertexArrayImpl() +{ + mContext->gl->fBindVertexArray(mGLName); +} + +void +WebGLVertexArrayGL::GenVertexArray() +{ + mContext->gl->fGenVertexArrays(1, &mGLName); +} + +} // namespace mozilla diff --git a/content/canvas/src/WebGLVertexArrayGL.h b/content/canvas/src/WebGLVertexArrayGL.h new file mode 100644 index 000000000000..de839eaffec2 --- /dev/null +++ b/content/canvas/src/WebGLVertexArrayGL.h @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef WEBGLVERTEXARRAYGL_H_ +#define WEBGLVERTEXARRAYGL_H_ + +#include "WebGLVertexArray.h" + +namespace mozilla { + +class WebGLVertexArrayGL MOZ_FINAL + : public WebGLVertexArray +{ +public: + virtual void DeleteImpl() MOZ_OVERRIDE; + virtual void BindVertexArrayImpl() MOZ_OVERRIDE; + virtual void GenVertexArray() MOZ_OVERRIDE; + +private: + WebGLVertexArrayGL(WebGLContext* context) + : WebGLVertexArray(context) + { } + + ~WebGLVertexArrayGL() { + DeleteOnce(); + } + + friend class WebGLVertexArray; +}; + +} // namespace mozilla + +#endif diff --git a/content/canvas/src/moz.build b/content/canvas/src/moz.build index 8479d6f69f62..dff36a4ddbc5 100644 --- a/content/canvas/src/moz.build +++ b/content/canvas/src/moz.build @@ -79,6 +79,8 @@ if CONFIG['MOZ_WEBGL']: 'WebGLTexture.cpp', 'WebGLUniformLocation.cpp', 'WebGLVertexArray.cpp', + 'WebGLVertexArrayFake.cpp', + 'WebGLVertexArrayGL.cpp', ] LOCAL_INCLUDES += [ '/js/xpconnect/wrappers',