зеркало из https://github.com/mozilla/gecko-dev.git
bug 900767 - Implement the WebGL extension ANGLE_instanced_arrays - r=jgilbert
This commit is contained in:
Родитель
e5911a1739
Коммит
25894203e2
|
@ -197,9 +197,7 @@ WebGLContext::WebGLContext()
|
||||||
|
|
||||||
mLastUseIndex = 0;
|
mLastUseIndex = 0;
|
||||||
|
|
||||||
mBufferFetchingIsVerified = false;
|
InvalidateBufferFetching();
|
||||||
mMaxFetchedVertices = 0;
|
|
||||||
mMaxFetchedInstances = 0;
|
|
||||||
|
|
||||||
mIsScreenCleared = false;
|
mIsScreenCleared = false;
|
||||||
|
|
||||||
|
@ -1019,6 +1017,8 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
case ANGLE_instanced_arrays:
|
||||||
|
return WebGLExtensionInstancedArrays::IsSupported(this);
|
||||||
default:
|
default:
|
||||||
// For warnings-as-errors.
|
// For warnings-as-errors.
|
||||||
break;
|
break;
|
||||||
|
@ -1118,6 +1118,10 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& r
|
||||||
{
|
{
|
||||||
ext = WEBGL_draw_buffers;
|
ext = WEBGL_draw_buffers;
|
||||||
}
|
}
|
||||||
|
else if (CompareWebGLExtensionName(name, "ANGLE_instanced_arrays"))
|
||||||
|
{
|
||||||
|
ext = ANGLE_instanced_arrays;
|
||||||
|
}
|
||||||
|
|
||||||
if (ext == WebGLExtensionID_unknown_extension) {
|
if (ext == WebGLExtensionID_unknown_extension) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1184,6 +1188,9 @@ WebGLContext::EnableExtension(WebGLExtensionID ext)
|
||||||
case OES_vertex_array_object:
|
case OES_vertex_array_object:
|
||||||
obj = new WebGLExtensionVertexArray(this);
|
obj = new WebGLExtensionVertexArray(this);
|
||||||
break;
|
break;
|
||||||
|
case ANGLE_instanced_arrays:
|
||||||
|
obj = new WebGLExtensionInstancedArrays(this);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
MOZ_ASSERT(false, "should not get there.");
|
MOZ_ASSERT(false, "should not get there.");
|
||||||
}
|
}
|
||||||
|
@ -1592,6 +1599,8 @@ WebGLContext::GetSupportedExtensions(JSContext *cx, Nullable< nsTArray<nsString>
|
||||||
arr.AppendElement(NS_LITERAL_STRING("WEBGL_draw_buffers"));
|
arr.AppendElement(NS_LITERAL_STRING("WEBGL_draw_buffers"));
|
||||||
if (IsExtensionSupported(cx, OES_vertex_array_object))
|
if (IsExtensionSupported(cx, OES_vertex_array_object))
|
||||||
arr.AppendElement(NS_LITERAL_STRING("OES_vertex_array_object"));
|
arr.AppendElement(NS_LITERAL_STRING("OES_vertex_array_object"));
|
||||||
|
if (IsExtensionSupported(cx, ANGLE_instanced_arrays))
|
||||||
|
arr.AppendElement(NS_LITERAL_STRING("ANGLE_instanced_arrays"));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -815,6 +815,21 @@ public:
|
||||||
void VertexAttribDivisor(WebGLuint index, WebGLuint divisor);
|
void VertexAttribDivisor(WebGLuint index, WebGLuint divisor);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Cache the max number of vertices and instances that can be read from
|
||||||
|
// bound VBOs (result of ValidateBuffers).
|
||||||
|
bool mBufferFetchingIsVerified;
|
||||||
|
bool mBufferFetchingHasPerVertex;
|
||||||
|
uint32_t mMaxFetchedVertices;
|
||||||
|
uint32_t mMaxFetchedInstances;
|
||||||
|
|
||||||
|
inline void InvalidateBufferFetching()
|
||||||
|
{
|
||||||
|
mBufferFetchingIsVerified = false;
|
||||||
|
mBufferFetchingHasPerVertex = false;
|
||||||
|
mMaxFetchedVertices = 0;
|
||||||
|
mMaxFetchedInstances = 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool DrawArrays_check(WebGLint first, WebGLsizei count, WebGLsizei primcount, const char* info);
|
bool DrawArrays_check(WebGLint first, WebGLsizei count, WebGLsizei primcount, const char* info);
|
||||||
bool DrawElements_check(WebGLsizei count, WebGLenum type, WebGLintptr byteOffset,
|
bool DrawElements_check(WebGLsizei count, WebGLenum type, WebGLintptr byteOffset,
|
||||||
WebGLsizei primcount, const char* info);
|
WebGLsizei primcount, const char* info);
|
||||||
|
@ -895,19 +910,6 @@ protected:
|
||||||
int32_t mGLMaxColorAttachments;
|
int32_t mGLMaxColorAttachments;
|
||||||
int32_t mGLMaxDrawBuffers;
|
int32_t mGLMaxDrawBuffers;
|
||||||
|
|
||||||
// Cache the max number of vertices and isntances that can be read from
|
|
||||||
// bound VBOs (result of ValidateBuffers).
|
|
||||||
bool mBufferFetchingIsVerified;
|
|
||||||
uint32_t mMaxFetchedVertices;
|
|
||||||
uint32_t mMaxFetchedInstances;
|
|
||||||
|
|
||||||
inline void InvalidateBufferFetching()
|
|
||||||
{
|
|
||||||
mBufferFetchingIsVerified = false;
|
|
||||||
mMaxFetchedVertices = 0;
|
|
||||||
mMaxFetchedInstances = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Represents current status, or state, of the context. That is, is it lost
|
// Represents current status, or state, of the context. That is, is it lost
|
||||||
// or stable and what part of the context lost process are we currently at.
|
// or stable and what part of the context lost process are we currently at.
|
||||||
// This is used to support the WebGL spec's asyncronous nature in handling
|
// This is used to support the WebGL spec's asyncronous nature in handling
|
||||||
|
@ -942,6 +944,7 @@ protected:
|
||||||
WEBGL_depth_texture,
|
WEBGL_depth_texture,
|
||||||
WEBGL_lose_context,
|
WEBGL_lose_context,
|
||||||
WEBGL_draw_buffers,
|
WEBGL_draw_buffers,
|
||||||
|
ANGLE_instanced_arrays,
|
||||||
WebGLExtensionID_unknown_extension
|
WebGLExtensionID_unknown_extension
|
||||||
};
|
};
|
||||||
nsTArray<nsRefPtr<WebGLExtensionBase> > mExtensions;
|
nsTArray<nsRefPtr<WebGLExtensionBase> > mExtensions;
|
||||||
|
|
|
@ -995,10 +995,9 @@ WebGLContext::InitAndValidateGL()
|
||||||
if (IsWebGL2() &&
|
if (IsWebGL2() &&
|
||||||
(!IsExtensionSupported(OES_vertex_array_object) ||
|
(!IsExtensionSupported(OES_vertex_array_object) ||
|
||||||
!IsExtensionSupported(WEBGL_draw_buffers) ||
|
!IsExtensionSupported(WEBGL_draw_buffers) ||
|
||||||
|
!IsExtensionSupported(ANGLE_instanced_arrays) ||
|
||||||
!gl->IsExtensionSupported(gl::GLContext::EXT_gpu_shader4) ||
|
!gl->IsExtensionSupported(gl::GLContext::EXT_gpu_shader4) ||
|
||||||
!gl->IsExtensionSupported(gl::GLContext::EXT_blend_minmax) ||
|
!gl->IsExtensionSupported(gl::GLContext::EXT_blend_minmax) ||
|
||||||
!gl->IsExtensionSupported(gl::GLContext::XXX_draw_instanced) ||
|
|
||||||
!gl->IsExtensionSupported(gl::GLContext::XXX_instanced_arrays) ||
|
|
||||||
(gl->IsGLES2() && !gl->IsExtensionSupported(gl::GLContext::EXT_occlusion_query_boolean))
|
(gl->IsGLES2() && !gl->IsExtensionSupported(gl::GLContext::EXT_occlusion_query_boolean))
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
|
@ -1023,9 +1022,11 @@ WebGLContext::InitAndValidateGL()
|
||||||
if (IsWebGL2()) {
|
if (IsWebGL2()) {
|
||||||
EnableExtension(OES_vertex_array_object);
|
EnableExtension(OES_vertex_array_object);
|
||||||
EnableExtension(WEBGL_draw_buffers);
|
EnableExtension(WEBGL_draw_buffers);
|
||||||
|
EnableExtension(ANGLE_instanced_arrays);
|
||||||
|
|
||||||
MOZ_ASSERT(IsExtensionEnabled(OES_vertex_array_object));
|
MOZ_ASSERT(IsExtensionEnabled(OES_vertex_array_object));
|
||||||
MOZ_ASSERT(IsExtensionEnabled(WEBGL_draw_buffers));
|
MOZ_ASSERT(IsExtensionEnabled(WEBGL_draw_buffers));
|
||||||
|
MOZ_ASSERT(IsExtensionEnabled(ANGLE_instanced_arrays));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -262,7 +262,7 @@ WebGLContext::GetVertexAttrib(JSContext* cx, WebGLuint index, WebGLenum pname,
|
||||||
|
|
||||||
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
|
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
|
||||||
{
|
{
|
||||||
if (IsWebGL2())
|
if (IsExtensionEnabled(ANGLE_instanced_arrays))
|
||||||
{
|
{
|
||||||
return JS::Int32Value(mBoundVertexArray->mAttribBuffers[index].divisor);
|
return JS::Int32Value(mBoundVertexArray->mAttribBuffers[index].divisor);
|
||||||
}
|
}
|
||||||
|
@ -470,6 +470,16 @@ bool WebGLContext::DrawArrays_check(WebGLint first, WebGLsizei count, WebGLsizei
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mBufferFetchingHasPerVertex && !IsWebGL2()) {
|
||||||
|
/* http://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_instanced_arrays.txt
|
||||||
|
* If all of the enabled vertex attribute arrays that are bound to active
|
||||||
|
* generic attributes in the program have a non-zero divisor, the draw
|
||||||
|
* call should return INVALID_OPERATION.
|
||||||
|
*/
|
||||||
|
ErrorInvalidOperation("%s: at least one vertex attribute divisor should be 0", info);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
MakeContextCurrent();
|
MakeContextCurrent();
|
||||||
|
|
||||||
if (mBoundFramebuffer) {
|
if (mBoundFramebuffer) {
|
||||||
|
@ -624,6 +634,16 @@ WebGLContext::DrawElements_check(WebGLsizei count, WebGLenum type, WebGLintptr b
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mBufferFetchingHasPerVertex && !IsWebGL2()) {
|
||||||
|
/* http://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_instanced_arrays.txt
|
||||||
|
* If all of the enabled vertex attribute arrays that are bound to active
|
||||||
|
* generic attributes in the program have a non-zero divisor, the draw
|
||||||
|
* call should return INVALID_OPERATION.
|
||||||
|
*/
|
||||||
|
ErrorInvalidOperation("%s: at least one vertex attribute divisor should be 0", info);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
MakeContextCurrent();
|
MakeContextCurrent();
|
||||||
|
|
||||||
if (mBoundFramebuffer) {
|
if (mBoundFramebuffer) {
|
||||||
|
@ -674,7 +694,7 @@ WebGLContext::DrawElementsInstanced(WebGLenum mode, WebGLsizei count, WebGLenum
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetupContextLossTimer();
|
SetupContextLossTimer();
|
||||||
gl->fDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(byteOffset));
|
gl->fDrawElementsInstanced(mode, count, type, reinterpret_cast<GLvoid*>(byteOffset), primcount);
|
||||||
|
|
||||||
Draw_cleanup();
|
Draw_cleanup();
|
||||||
}
|
}
|
||||||
|
@ -722,6 +742,7 @@ WebGLContext::ValidateBufferFetching(const char *info)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasPerVertex = false;
|
||||||
uint32_t maxVertices = UINT32_MAX;
|
uint32_t maxVertices = UINT32_MAX;
|
||||||
uint32_t maxInstances = UINT32_MAX;
|
uint32_t maxInstances = UINT32_MAX;
|
||||||
uint32_t attribs = mBoundVertexArray->mAttribBuffers.Length();
|
uint32_t attribs = mBoundVertexArray->mAttribBuffers.Length();
|
||||||
|
@ -768,13 +789,16 @@ WebGLContext::ValidateBufferFetching(const char *info)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vd.divisor == 0)
|
if (vd.divisor == 0) {
|
||||||
maxVertices = std::min(maxVertices, checked_maxAllowedCount.value());
|
maxVertices = std::min(maxVertices, checked_maxAllowedCount.value());
|
||||||
else
|
hasPerVertex = true;
|
||||||
|
} else {
|
||||||
maxInstances = std::min(maxInstances, checked_maxAllowedCount.value() / vd.divisor);
|
maxInstances = std::min(maxInstances, checked_maxAllowedCount.value() / vd.divisor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mBufferFetchingIsVerified = true;
|
mBufferFetchingIsVerified = true;
|
||||||
|
mBufferFetchingHasPerVertex = hasPerVertex;
|
||||||
mMaxFetchedVertices = maxVertices;
|
mMaxFetchedVertices = maxVertices;
|
||||||
mMaxFetchedInstances = maxInstances;
|
mMaxFetchedInstances = maxInstances;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 20; 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 "WebGLContext.h"
|
||||||
|
#include "WebGLExtensions.h"
|
||||||
|
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
|
WebGLExtensionInstancedArrays::WebGLExtensionInstancedArrays(WebGLContext* context)
|
||||||
|
: WebGLExtensionBase(context)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(IsSupported(context), "should not construct WebGLExtensionInstancedArrays: "
|
||||||
|
"ANGLE_instanced_arrays unsupported.");
|
||||||
|
}
|
||||||
|
|
||||||
|
WebGLExtensionInstancedArrays::~WebGLExtensionInstancedArrays()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WebGLExtensionInstancedArrays::DrawArraysInstancedANGLE(WebGLenum mode, WebGLint first,
|
||||||
|
WebGLsizei count, WebGLsizei primcount)
|
||||||
|
{
|
||||||
|
mContext->DrawArraysInstanced(mode, first, count, primcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WebGLExtensionInstancedArrays::DrawElementsInstancedANGLE(WebGLenum mode, WebGLsizei count,
|
||||||
|
WebGLenum type, WebGLintptr offset,
|
||||||
|
WebGLsizei primcount)
|
||||||
|
{
|
||||||
|
mContext->DrawElementsInstanced(mode, count, type, offset, primcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WebGLExtensionInstancedArrays::VertexAttribDivisorANGLE(WebGLuint index, WebGLuint divisor)
|
||||||
|
{
|
||||||
|
mContext->VertexAttribDivisor(index, divisor);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WebGLExtensionInstancedArrays::IsSupported(const WebGLContext* context)
|
||||||
|
{
|
||||||
|
gl::GLContext* gl = context->GL();
|
||||||
|
|
||||||
|
return gl->IsExtensionSupported(gl::GLContext::XXX_draw_instanced) &&
|
||||||
|
gl->IsExtensionSupported(gl::GLContext::XXX_instanced_arrays);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionInstancedArrays)
|
|
@ -189,6 +189,25 @@ public:
|
||||||
DECL_WEBGL_EXTENSION_GOOP
|
DECL_WEBGL_EXTENSION_GOOP
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WebGLExtensionInstancedArrays
|
||||||
|
: public WebGLExtensionBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WebGLExtensionInstancedArrays(WebGLContext* context);
|
||||||
|
virtual ~WebGLExtensionInstancedArrays();
|
||||||
|
|
||||||
|
void DrawArraysInstancedANGLE(WebGLenum mode, WebGLint first,
|
||||||
|
WebGLsizei count, WebGLsizei primcount);
|
||||||
|
void DrawElementsInstancedANGLE(WebGLenum mode, WebGLsizei count,
|
||||||
|
WebGLenum type, WebGLintptr offset,
|
||||||
|
WebGLsizei primcount);
|
||||||
|
void VertexAttribDivisorANGLE(WebGLuint index, WebGLuint divisor);
|
||||||
|
|
||||||
|
static bool IsSupported(const WebGLContext* context);
|
||||||
|
|
||||||
|
DECL_WEBGL_EXTENSION_GOOP
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // WEBGLEXTENSIONS_H_
|
#endif // WEBGLEXTENSIONS_H_
|
||||||
|
|
|
@ -48,6 +48,7 @@ if CONFIG['MOZ_WEBGL']:
|
||||||
'WebGLExtensionDepthTexture.cpp',
|
'WebGLExtensionDepthTexture.cpp',
|
||||||
'WebGLExtensionDrawBuffers.cpp',
|
'WebGLExtensionDrawBuffers.cpp',
|
||||||
'WebGLExtensionElementIndexUint.cpp',
|
'WebGLExtensionElementIndexUint.cpp',
|
||||||
|
'WebGLExtensionInstancedArrays.cpp',
|
||||||
'WebGLExtensionLoseContext.cpp',
|
'WebGLExtensionLoseContext.cpp',
|
||||||
'WebGLExtensionStandardDerivatives.cpp',
|
'WebGLExtensionStandardDerivatives.cpp',
|
||||||
'WebGLExtensionTextureFilterAnisotropic.cpp',
|
'WebGLExtensionTextureFilterAnisotropic.cpp',
|
||||||
|
|
|
@ -1305,6 +1305,11 @@ DOMInterfaces = {
|
||||||
'headerFile': 'WebGLExtensions.h'
|
'headerFile': 'WebGLExtensions.h'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'WebGLExtensionInstancedArrays': {
|
||||||
|
'nativeType': 'mozilla::WebGLExtensionInstancedArrays',
|
||||||
|
'headerFile': 'WebGLExtensions.h'
|
||||||
|
},
|
||||||
|
|
||||||
'WebGLFramebuffer': {
|
'WebGLFramebuffer': {
|
||||||
'nativeType': 'mozilla::WebGLFramebuffer',
|
'nativeType': 'mozilla::WebGLFramebuffer',
|
||||||
'headerFile': 'WebGLFramebuffer.h'
|
'headerFile': 'WebGLFramebuffer.h'
|
||||||
|
|
|
@ -896,3 +896,12 @@ interface WebGLExtensionVertexArray {
|
||||||
[WebGLHandlesContextLoss] GLboolean isVertexArrayOES(WebGLVertexArray? arrayObject);
|
[WebGLHandlesContextLoss] GLboolean isVertexArrayOES(WebGLVertexArray? arrayObject);
|
||||||
void bindVertexArrayOES(WebGLVertexArray? arrayObject);
|
void bindVertexArrayOES(WebGLVertexArray? arrayObject);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[NoInterfaceObject]
|
||||||
|
interface WebGLExtensionInstancedArrays {
|
||||||
|
const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88FE;
|
||||||
|
|
||||||
|
void drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
|
||||||
|
void drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei primcount);
|
||||||
|
void vertexAttribDivisorANGLE(GLuint index, GLuint divisor);
|
||||||
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче