Bug 966998 - WebGL OES_vertex_array_object windows presence is low. r=jgilbert

This commit is contained in:
Walter Litwinczyk 2014-06-05 16:38:27 -07:00
parent fa32ec8e2a
commit 38c7289d78
15 changed files with 213 additions and 47 deletions

View File

@ -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

View File

@ -385,7 +385,7 @@ WebGLContext::DeleteBuffer(WebGLBuffer *buffer)
static_cast<WebGLBuffer*>(nullptr));
}
if (mBoundVertexArray->mBoundElementArrayBuffer == buffer) {
if (mBoundVertexArray->mElementArrayBuffer == buffer) {
BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER,
static_cast<WebGLBuffer*>(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");

View File

@ -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);

View File

@ -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: {

View File

@ -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);

View File

@ -1788,7 +1788,7 @@ WebGLContext::InitAndValidateGL()
false);
}
mDefaultVertexArray = new WebGLVertexArray(this);
mDefaultVertexArray = WebGLVertexArray::Create(this);
mDefaultVertexArray->mAttribs.SetLength(mGLMaxVertexAttribs);
mBoundVertexArray = mDefaultVertexArray;

View File

@ -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<WebGLVertexArray>
@ -52,12 +50,10 @@ WebGLContext::CreateVertexArray()
if (IsContextLost())
return nullptr;
nsRefPtr<WebGLVertexArray> globj = new WebGLVertexArray(this);
nsRefPtr<WebGLVertexArray> globj = WebGLVertexArray::Create(this);
MakeContextCurrent();
gl->fGenVertexArrays(1, &globj->mGLName);
mVertexArrays.insertBack(globj);
globj->GenVertexArray();
return globj.forget();
}

View File

@ -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)

View File

@ -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<WebGLVertexArray>::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<WebGLVertexArray>::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)

View File

@ -16,7 +16,7 @@
namespace mozilla {
class WebGLVertexArray MOZ_FINAL
class WebGLVertexArray
: public nsWrapperCache
, public WebGLRefCountedObject<WebGLVertexArray>
, public LinkedListElement<WebGLVertexArray>
@ -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<WebGLVertexAttribData> mAttribs;
WebGLRefPtr<WebGLBuffer> mBoundElementArrayBuffer;
WebGLRefPtr<WebGLBuffer> mElementArrayBuffer;
// -------------------------------------------------------------------------
// FRIENDSHIPS

View File

@ -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<WebGLBuffer> 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<void*>(vd.byteOffset));
if (vd.enabled) {
gl->fEnableVertexAttribArray(i);
} else {
gl->fDisableVertexAttribArray(i);
}
}
mContext->BindBuffer(LOCAL_GL_ARRAY_BUFFER, prevBuffer);
}
} // namespace mozilla

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -79,6 +79,8 @@ if CONFIG['MOZ_WEBGL']:
'WebGLTexture.cpp',
'WebGLUniformLocation.cpp',
'WebGLVertexArray.cpp',
'WebGLVertexArrayFake.cpp',
'WebGLVertexArrayGL.cpp',
]
LOCAL_INCLUDES += [
'/js/xpconnect/wrappers',