mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 890379 - [WebGL 2.0] Add existing WebGL 1 extensions as WebGL 2 features. r=jgilbert
This commit is contained in:
parent
049e48a959
commit
7315912dd4
@ -958,6 +958,11 @@ bool WebGLContext::IsExtensionSupported(JSContext *cx, WebGLExtensionID ext) con
|
||||
}
|
||||
}
|
||||
|
||||
return IsExtensionSupported(ext);
|
||||
}
|
||||
|
||||
bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
|
||||
{
|
||||
if (mDisableExtensions) {
|
||||
return false;
|
||||
}
|
||||
@ -1123,57 +1128,67 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& r
|
||||
|
||||
// step 3: if the extension hadn't been previously been created, create it now, thus enabling it
|
||||
if (!IsExtensionEnabled(ext)) {
|
||||
WebGLExtensionBase *obj = nullptr;
|
||||
switch (ext) {
|
||||
case OES_element_index_uint:
|
||||
obj = new WebGLExtensionElementIndexUint(this);
|
||||
break;
|
||||
case OES_standard_derivatives:
|
||||
obj = new WebGLExtensionStandardDerivatives(this);
|
||||
break;
|
||||
case EXT_texture_filter_anisotropic:
|
||||
obj = new WebGLExtensionTextureFilterAnisotropic(this);
|
||||
break;
|
||||
case WEBGL_lose_context:
|
||||
obj = new WebGLExtensionLoseContext(this);
|
||||
break;
|
||||
case WEBGL_compressed_texture_s3tc:
|
||||
obj = new WebGLExtensionCompressedTextureS3TC(this);
|
||||
break;
|
||||
case WEBGL_compressed_texture_atc:
|
||||
obj = new WebGLExtensionCompressedTextureATC(this);
|
||||
break;
|
||||
case WEBGL_compressed_texture_pvrtc:
|
||||
obj = new WebGLExtensionCompressedTexturePVRTC(this);
|
||||
break;
|
||||
case WEBGL_debug_renderer_info:
|
||||
obj = new WebGLExtensionDebugRendererInfo(this);
|
||||
break;
|
||||
case WEBGL_depth_texture:
|
||||
obj = new WebGLExtensionDepthTexture(this);
|
||||
break;
|
||||
case OES_texture_float:
|
||||
obj = new WebGLExtensionTextureFloat(this);
|
||||
break;
|
||||
case OES_texture_float_linear:
|
||||
obj = new WebGLExtensionTextureFloatLinear(this);
|
||||
break;
|
||||
case WEBGL_draw_buffers:
|
||||
obj = new WebGLExtensionDrawBuffers(this);
|
||||
break;
|
||||
case OES_vertex_array_object:
|
||||
obj = new WebGLExtensionVertexArray(this);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false, "should not get there.");
|
||||
}
|
||||
mExtensions.EnsureLengthAtLeast(ext + 1);
|
||||
mExtensions[ext] = obj;
|
||||
EnableExtension(ext);
|
||||
}
|
||||
|
||||
return WebGLObjectAsJSObject(cx, mExtensions[ext].get(), rv);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::EnableExtension(WebGLExtensionID ext)
|
||||
{
|
||||
mExtensions.EnsureLengthAtLeast(ext + 1);
|
||||
|
||||
MOZ_ASSERT(IsExtensionEnabled(ext) == false);
|
||||
|
||||
WebGLExtensionBase* obj = nullptr;
|
||||
switch (ext) {
|
||||
case OES_element_index_uint:
|
||||
obj = new WebGLExtensionElementIndexUint(this);
|
||||
break;
|
||||
case OES_standard_derivatives:
|
||||
obj = new WebGLExtensionStandardDerivatives(this);
|
||||
break;
|
||||
case EXT_texture_filter_anisotropic:
|
||||
obj = new WebGLExtensionTextureFilterAnisotropic(this);
|
||||
break;
|
||||
case WEBGL_lose_context:
|
||||
obj = new WebGLExtensionLoseContext(this);
|
||||
break;
|
||||
case WEBGL_compressed_texture_s3tc:
|
||||
obj = new WebGLExtensionCompressedTextureS3TC(this);
|
||||
break;
|
||||
case WEBGL_compressed_texture_atc:
|
||||
obj = new WebGLExtensionCompressedTextureATC(this);
|
||||
break;
|
||||
case WEBGL_compressed_texture_pvrtc:
|
||||
obj = new WebGLExtensionCompressedTexturePVRTC(this);
|
||||
break;
|
||||
case WEBGL_debug_renderer_info:
|
||||
obj = new WebGLExtensionDebugRendererInfo(this);
|
||||
break;
|
||||
case WEBGL_depth_texture:
|
||||
obj = new WebGLExtensionDepthTexture(this);
|
||||
break;
|
||||
case OES_texture_float:
|
||||
obj = new WebGLExtensionTextureFloat(this);
|
||||
break;
|
||||
case OES_texture_float_linear:
|
||||
obj = new WebGLExtensionTextureFloatLinear(this);
|
||||
break;
|
||||
case WEBGL_draw_buffers:
|
||||
obj = new WebGLExtensionDrawBuffers(this);
|
||||
break;
|
||||
case OES_vertex_array_object:
|
||||
obj = new WebGLExtensionVertexArray(this);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false, "should not get there.");
|
||||
}
|
||||
|
||||
mExtensions[ext] = obj;
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ClearScreen()
|
||||
{
|
||||
|
@ -390,6 +390,7 @@ public:
|
||||
void DrawArrays(GLenum mode, WebGLint first, WebGLsizei count);
|
||||
void DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
|
||||
WebGLintptr byteOffset);
|
||||
void DrawBuffers(const dom::Sequence<GLenum>& buffers);
|
||||
void Enable(WebGLenum cap);
|
||||
void EnableVertexAttribArray(WebGLuint index);
|
||||
void Flush() {
|
||||
@ -894,11 +895,15 @@ protected:
|
||||
};
|
||||
nsTArray<nsRefPtr<WebGLExtensionBase> > mExtensions;
|
||||
|
||||
// enable an extension. the extension should not be enabled before.
|
||||
void EnableExtension(WebGLExtensionID ext);
|
||||
|
||||
// returns true if the extension has been enabled by calling getExtension.
|
||||
bool IsExtensionEnabled(WebGLExtensionID ext) const;
|
||||
|
||||
// returns true if the extension is supported for this JSContext (this decides what getSupportedExtensions exposes)
|
||||
bool IsExtensionSupported(JSContext *cx, WebGLExtensionID ext) const;
|
||||
bool IsExtensionSupported(WebGLExtensionID ext) const;
|
||||
|
||||
nsTArray<WebGLenum> mCompressedTextureFormats;
|
||||
|
||||
|
264
content/canvas/src/WebGLContextFramebufferOperations.cpp
Normal file
264
content/canvas/src/WebGLContextFramebufferOperations.cpp
Normal file
@ -0,0 +1,264 @@
|
||||
/* -*- 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 "WebGLContext.h"
|
||||
#include "WebGLTexture.h"
|
||||
#include "WebGLRenderbuffer.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
void
|
||||
WebGLContext::Clear(WebGLbitfield mask)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
uint32_t m = mask & (LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
|
||||
if (mask != m)
|
||||
return ErrorInvalidValue("clear: invalid mask bits");
|
||||
|
||||
if (mBoundFramebuffer) {
|
||||
if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
|
||||
return ErrorInvalidFramebufferOperation("clear: incomplete framebuffer");
|
||||
|
||||
gl->fClear(mask);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ok, we're clearing the default framebuffer/screen.
|
||||
|
||||
bool needsClear = true;
|
||||
if (mIsScreenCleared) {
|
||||
bool isClearRedundant = true;
|
||||
if (mask & LOCAL_GL_COLOR_BUFFER_BIT) {
|
||||
if (mColorClearValue[0] != 0.0f ||
|
||||
mColorClearValue[1] != 0.0f ||
|
||||
mColorClearValue[2] != 0.0f ||
|
||||
mColorClearValue[3] != 0.0f)
|
||||
{
|
||||
isClearRedundant = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & LOCAL_GL_DEPTH_BUFFER_BIT) {
|
||||
if (mDepthClearValue != 1.0f) {
|
||||
isClearRedundant = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & LOCAL_GL_DEPTH_BUFFER_BIT) {
|
||||
if (mStencilClearValue != 0) {
|
||||
isClearRedundant = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isClearRedundant)
|
||||
needsClear = false;
|
||||
}
|
||||
|
||||
if (needsClear) {
|
||||
gl->fClear(mask);
|
||||
mIsScreenCleared = false;
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
mShouldPresent = true;
|
||||
}
|
||||
|
||||
static WebGLclampf
|
||||
GLClampFloat(WebGLclampf val)
|
||||
{
|
||||
if (val < 0.0)
|
||||
return 0.0;
|
||||
|
||||
if (val > 1.0)
|
||||
return 1.0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ClearColor(WebGLclampf r, WebGLclampf g,
|
||||
WebGLclampf b, WebGLclampf a)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
mColorClearValue[0] = GLClampFloat(r);
|
||||
mColorClearValue[1] = GLClampFloat(g);
|
||||
mColorClearValue[2] = GLClampFloat(b);
|
||||
mColorClearValue[3] = GLClampFloat(a);
|
||||
gl->fClearColor(r, g, b, a);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ClearDepth(WebGLclampf v)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
mDepthClearValue = GLClampFloat(v);
|
||||
gl->fClearDepth(v);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ClearStencil(WebGLint v)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
mStencilClearValue = v;
|
||||
gl->fClearStencil(v);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
mColorWriteMask[0] = r;
|
||||
mColorWriteMask[1] = g;
|
||||
mColorWriteMask[2] = b;
|
||||
mColorWriteMask[3] = a;
|
||||
gl->fColorMask(r, g, b, a);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::DepthMask(WebGLboolean b)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
mDepthWriteMask = b;
|
||||
gl->fDepthMask(b);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers)
|
||||
{
|
||||
const size_t buffersLength = buffers.Length();
|
||||
|
||||
if (buffersLength == 0) {
|
||||
return ErrorInvalidValue("drawBuffers: invalid <buffers> (buffers must not be empty)");
|
||||
}
|
||||
|
||||
if (mBoundFramebuffer == 0)
|
||||
{
|
||||
// OK: we are rendering in the default framebuffer
|
||||
|
||||
/* EXT_draw_buffers :
|
||||
If the GL is bound to the default framebuffer, then <buffersLength> must be 1
|
||||
and the constant must be BACK or NONE. When draw buffer zero is
|
||||
BACK, color values are written into the sole buffer for single-
|
||||
buffered contexts, or into the back buffer for double-buffered
|
||||
contexts. If DrawBuffersEXT is supplied with a constant other than
|
||||
BACK and NONE, the error INVALID_OPERATION is generated.
|
||||
*/
|
||||
if (buffersLength != 1) {
|
||||
return ErrorInvalidValue("drawBuffers: invalid <buffers> (main framebuffer: buffers.length must be 1)");
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
if (buffers[0] == LOCAL_GL_NONE) {
|
||||
const GLenum drawBuffersCommand = LOCAL_GL_NONE;
|
||||
gl->fDrawBuffers(1, &drawBuffersCommand);
|
||||
return;
|
||||
}
|
||||
else if (buffers[0] == LOCAL_GL_BACK) {
|
||||
const GLenum drawBuffersCommand = LOCAL_GL_COLOR_ATTACHMENT0;
|
||||
gl->fDrawBuffers(1, &drawBuffersCommand);
|
||||
return;
|
||||
}
|
||||
return ErrorInvalidOperation("drawBuffers: invalid operation (main framebuffer: buffers[0] must be GL_NONE or GL_BACK)");
|
||||
}
|
||||
|
||||
// OK: we are rendering in a framebuffer object
|
||||
|
||||
if (buffersLength > size_t(mGLMaxDrawBuffers)) {
|
||||
/* EXT_draw_buffers :
|
||||
The maximum number of draw buffers is implementation-dependent. The
|
||||
number of draw buffers supported can be queried by calling
|
||||
GetIntegerv with the symbolic constant MAX_DRAW_BUFFERS_EXT. An
|
||||
INVALID_VALUE error is generated if <buffersLength> is greater than
|
||||
MAX_DRAW_BUFFERS_EXT.
|
||||
*/
|
||||
return ErrorInvalidValue("drawBuffers: invalid <buffers> (buffers.length > GL_MAX_DRAW_BUFFERS)");
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < buffersLength; i++)
|
||||
{
|
||||
/* EXT_draw_buffers :
|
||||
If the GL is bound to a draw framebuffer object, the <i>th buffer listed
|
||||
in <bufs> must be COLOR_ATTACHMENT<i>_EXT or NONE. Specifying a
|
||||
buffer out of order, BACK, or COLOR_ATTACHMENT<m>_EXT where <m> is
|
||||
greater than or equal to the value of MAX_COLOR_ATTACHMENTS_EXT,
|
||||
will generate the error INVALID_OPERATION.
|
||||
*/
|
||||
/* WEBGL_draw_buffers :
|
||||
The value of the MAX_COLOR_ATTACHMENTS_WEBGL parameter must be greater than or equal to that of the MAX_DRAW_BUFFERS_WEBGL parameter.
|
||||
*/
|
||||
if (buffers[i] != LOCAL_GL_NONE &&
|
||||
buffers[i] != GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + i)) {
|
||||
return ErrorInvalidOperation("drawBuffers: invalid operation (buffers[i] must be GL_NONE or GL_COLOR_ATTACHMENTi)");
|
||||
}
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
gl->fDrawBuffers(buffersLength, buffers.Elements());
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::StencilMask(WebGLuint mask)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
mStencilWriteMaskFront = mask;
|
||||
mStencilWriteMaskBack = mask;
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fStencilMask(mask);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::StencilMaskSeparate(WebGLenum face, WebGLuint mask)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
if (!ValidateFaceEnum(face, "stencilMaskSeparate: face"))
|
||||
return;
|
||||
|
||||
switch (face) {
|
||||
case LOCAL_GL_FRONT_AND_BACK:
|
||||
mStencilWriteMaskFront = mask;
|
||||
mStencilWriteMaskBack = mask;
|
||||
break;
|
||||
case LOCAL_GL_FRONT:
|
||||
mStencilWriteMaskFront = mask;
|
||||
break;
|
||||
case LOCAL_GL_BACK:
|
||||
mStencilWriteMaskBack = mask;
|
||||
break;
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fStencilMaskSeparate(face, mask);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -227,39 +227,6 @@ WebGLContext::BindRenderbuffer(WebGLenum target, WebGLRenderbuffer *wrb)
|
||||
mBoundRenderbuffer = wrb;
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::BindVertexArray(WebGLVertexArray *array)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
if (!ValidateObjectAllowDeletedOrNull("bindVertexArrayObject", array))
|
||||
return;
|
||||
|
||||
if (array && array->IsDeleted()) {
|
||||
/* http://www.khronos.org/registry/gles/extensions/OES/OES_vertex_array_object.txt
|
||||
* BindVertexArrayOES fails and an INVALID_OPERATION error is
|
||||
* generated if array is not a name returned from a previous call to
|
||||
* GenVertexArraysOES, or if such a name has since been deleted with
|
||||
* DeleteVertexArraysOES
|
||||
*/
|
||||
ErrorInvalidOperation("bindVertexArray: can't bind a deleted array!");
|
||||
return;
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
if (array) {
|
||||
gl->fBindVertexArray(array->GLName());
|
||||
array->SetHasEverBeenBound(true);
|
||||
mBoundVertexArray = array;
|
||||
}
|
||||
else {
|
||||
gl->fBindVertexArray(0);
|
||||
mBoundVertexArray = mDefaultVertexArray;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::BindTexture(WebGLenum target, WebGLTexture *tex)
|
||||
{
|
||||
@ -645,129 +612,6 @@ WebGLContext::CheckFramebufferStatus(WebGLenum target)
|
||||
return gl->fCheckFramebufferStatus(target);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::Clear(WebGLbitfield mask)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
uint32_t m = mask & (LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
|
||||
if (mask != m)
|
||||
return ErrorInvalidValue("clear: invalid mask bits");
|
||||
|
||||
if (mBoundFramebuffer) {
|
||||
if (!mBoundFramebuffer->CheckAndInitializeRenderbuffers())
|
||||
return ErrorInvalidFramebufferOperation("clear: incomplete framebuffer");
|
||||
|
||||
gl->fClear(mask);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ok, we're clearing the default framebuffer/screen.
|
||||
|
||||
bool needsClear = true;
|
||||
if (mIsScreenCleared) {
|
||||
bool isClearRedundant = true;
|
||||
if (mask & LOCAL_GL_COLOR_BUFFER_BIT) {
|
||||
if (mColorClearValue[0] != 0.0f ||
|
||||
mColorClearValue[1] != 0.0f ||
|
||||
mColorClearValue[2] != 0.0f ||
|
||||
mColorClearValue[3] != 0.0f)
|
||||
{
|
||||
isClearRedundant = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & LOCAL_GL_DEPTH_BUFFER_BIT) {
|
||||
if (mDepthClearValue != 1.0f) {
|
||||
isClearRedundant = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & LOCAL_GL_DEPTH_BUFFER_BIT) {
|
||||
if (mStencilClearValue != 0) {
|
||||
isClearRedundant = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isClearRedundant)
|
||||
needsClear = false;
|
||||
}
|
||||
|
||||
if (needsClear) {
|
||||
gl->fClear(mask);
|
||||
mIsScreenCleared = false;
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
mShouldPresent = true;
|
||||
}
|
||||
|
||||
static WebGLclampf
|
||||
GLClampFloat(WebGLclampf val)
|
||||
{
|
||||
if (val < 0.0)
|
||||
return 0.0;
|
||||
|
||||
if (val > 1.0)
|
||||
return 1.0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ClearColor(WebGLclampf r, WebGLclampf g,
|
||||
WebGLclampf b, WebGLclampf a)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
mColorClearValue[0] = GLClampFloat(r);
|
||||
mColorClearValue[1] = GLClampFloat(g);
|
||||
mColorClearValue[2] = GLClampFloat(b);
|
||||
mColorClearValue[3] = GLClampFloat(a);
|
||||
gl->fClearColor(r, g, b, a);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ClearDepth(WebGLclampf v)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
mDepthClearValue = GLClampFloat(v);
|
||||
gl->fClearDepth(v);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ClearStencil(WebGLint v)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
mStencilClearValue = v;
|
||||
gl->fClearStencil(v);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
mColorWriteMask[0] = r;
|
||||
mColorWriteMask[1] = g;
|
||||
mColorWriteMask[2] = b;
|
||||
mColorWriteMask[3] = a;
|
||||
gl->fColorMask(r, g, b, a);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::CopyTexSubImage2D_base(WebGLenum target,
|
||||
WebGLint level,
|
||||
@ -1165,24 +1009,6 @@ WebGLContext::DeleteRenderbuffer(WebGLRenderbuffer *rbuf)
|
||||
rbuf->RequestDelete();
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::DeleteVertexArray(WebGLVertexArray *array)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
if (array == nullptr)
|
||||
return;
|
||||
|
||||
if (array->IsDeleted())
|
||||
return;
|
||||
|
||||
if (mBoundVertexArray == array)
|
||||
BindVertexArray(static_cast<WebGLVertexArray*>(nullptr));
|
||||
|
||||
array->RequestDelete();
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::DeleteTexture(WebGLTexture *tex)
|
||||
{
|
||||
@ -1271,17 +1097,6 @@ WebGLContext::DepthFunc(WebGLenum func)
|
||||
gl->fDepthFunc(func);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::DepthMask(WebGLboolean b)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
MakeContextCurrent();
|
||||
mDepthWriteMask = b;
|
||||
gl->fDepthMask(b);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::DepthRange(WebGLfloat zNear, WebGLfloat zFar)
|
||||
{
|
||||
@ -3192,20 +3007,6 @@ WebGLContext::IsRenderbuffer(WebGLRenderbuffer *rb)
|
||||
rb->HasEverBeenBound();
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::IsVertexArray(WebGLVertexArray *array)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return false;
|
||||
|
||||
if (!array)
|
||||
return false;
|
||||
|
||||
return ValidateObjectAllowDeleted("isVertexArray", array) &&
|
||||
!array->IsDeleted() &&
|
||||
array->HasEverBeenBound();
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::IsShader(WebGLShader *shader)
|
||||
{
|
||||
@ -3759,45 +3560,6 @@ WebGLContext::StencilFuncSeparate(WebGLenum face, WebGLenum func, WebGLint ref,
|
||||
gl->fStencilFuncSeparate(face, func, ref, mask);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::StencilMask(WebGLuint mask)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
mStencilWriteMaskFront = mask;
|
||||
mStencilWriteMaskBack = mask;
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fStencilMask(mask);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::StencilMaskSeparate(WebGLenum face, WebGLuint mask)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
if (!ValidateFaceEnum(face, "stencilMaskSeparate: face"))
|
||||
return;
|
||||
|
||||
switch (face) {
|
||||
case LOCAL_GL_FRONT_AND_BACK:
|
||||
mStencilWriteMaskFront = mask;
|
||||
mStencilWriteMaskBack = mask;
|
||||
break;
|
||||
case LOCAL_GL_FRONT:
|
||||
mStencilWriteMaskFront = mask;
|
||||
break;
|
||||
case LOCAL_GL_BACK:
|
||||
mStencilWriteMaskBack = mask;
|
||||
break;
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fStencilMaskSeparate(face, mask);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::StencilOp(WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass)
|
||||
{
|
||||
@ -4427,22 +4189,6 @@ WebGLContext::CreateRenderbuffer()
|
||||
return globj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<WebGLVertexArray>
|
||||
WebGLContext::CreateVertexArray()
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return nullptr;
|
||||
|
||||
nsRefPtr<WebGLVertexArray> globj = new WebGLVertexArray(this);
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fGenVertexArrays(1, &globj->mGLName);
|
||||
|
||||
mVertexArrays.insertBack(globj);
|
||||
|
||||
return globj.forget();
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::Viewport(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height)
|
||||
{
|
||||
|
@ -1049,6 +1049,14 @@ WebGLContext::InitAndValidateGL()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsWebGL2() &&
|
||||
(!IsExtensionSupported(OES_vertex_array_object) ||
|
||||
!IsExtensionSupported(WEBGL_draw_buffers)
|
||||
))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mMemoryPressureObserver
|
||||
= new WebGLMemoryPressureObserver(this);
|
||||
nsCOMPtr<nsIObserverService> observerService
|
||||
@ -1063,5 +1071,13 @@ WebGLContext::InitAndValidateGL()
|
||||
mDefaultVertexArray->mAttribBuffers.SetLength(mGLMaxVertexAttribs);
|
||||
mBoundVertexArray = mDefaultVertexArray;
|
||||
|
||||
if (IsWebGL2()) {
|
||||
EnableExtension(OES_vertex_array_object);
|
||||
EnableExtension(WEBGL_draw_buffers);
|
||||
|
||||
MOZ_ASSERT(IsExtensionEnabled(OES_vertex_array_object));
|
||||
MOZ_ASSERT(IsExtensionEnabled(WEBGL_draw_buffers));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
94
content/canvas/src/WebGLContextVertexArray.cpp
Normal file
94
content/canvas/src/WebGLContextVertexArray.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/* -*- 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 "WebGLContext.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
#include "WebGLVertexArray.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
void
|
||||
WebGLContext::BindVertexArray(WebGLVertexArray *array)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
if (!ValidateObjectAllowDeletedOrNull("bindVertexArrayObject", array))
|
||||
return;
|
||||
|
||||
if (array && array->IsDeleted()) {
|
||||
/* http://www.khronos.org/registry/gles/extensions/OES/OES_vertex_array_object.txt
|
||||
* BindVertexArrayOES fails and an INVALID_OPERATION error is
|
||||
* generated if array is not a name returned from a previous call to
|
||||
* GenVertexArraysOES, or if such a name has since been deleted with
|
||||
* DeleteVertexArraysOES
|
||||
*/
|
||||
ErrorInvalidOperation("bindVertexArray: can't bind a deleted array!");
|
||||
return;
|
||||
}
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
if (array) {
|
||||
gl->fBindVertexArray(array->GLName());
|
||||
array->SetHasEverBeenBound(true);
|
||||
mBoundVertexArray = array;
|
||||
}
|
||||
else {
|
||||
gl->fBindVertexArray(0);
|
||||
mBoundVertexArray = mDefaultVertexArray;
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<WebGLVertexArray>
|
||||
WebGLContext::CreateVertexArray()
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return nullptr;
|
||||
|
||||
nsRefPtr<WebGLVertexArray> globj = new WebGLVertexArray(this);
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fGenVertexArrays(1, &globj->mGLName);
|
||||
|
||||
mVertexArrays.insertBack(globj);
|
||||
|
||||
return globj.forget();
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::DeleteVertexArray(WebGLVertexArray *array)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return;
|
||||
|
||||
if (array == nullptr)
|
||||
return;
|
||||
|
||||
if (array->IsDeleted())
|
||||
return;
|
||||
|
||||
if (mBoundVertexArray == array)
|
||||
BindVertexArray(static_cast<WebGLVertexArray*>(nullptr));
|
||||
|
||||
array->RequestDelete();
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::IsVertexArray(WebGLVertexArray *array)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return false;
|
||||
|
||||
if (!array)
|
||||
return false;
|
||||
|
||||
return ValidateObjectAllowDeleted("isVertexArray", array) &&
|
||||
!array->IsDeleted() &&
|
||||
array->HasEverBeenBound();
|
||||
}
|
||||
|
||||
|
@ -48,77 +48,7 @@ WebGLExtensionDrawBuffers::~WebGLExtensionDrawBuffers()
|
||||
|
||||
void WebGLExtensionDrawBuffers::DrawBuffersWEBGL(const dom::Sequence<GLenum>& buffers)
|
||||
{
|
||||
const size_t buffersLength = buffers.Length();
|
||||
|
||||
if (buffersLength == 0) {
|
||||
return mContext->ErrorInvalidValue("drawBuffersWEBGL: invalid <buffers> (buffers must not be empty)");
|
||||
}
|
||||
|
||||
if (mContext->mBoundFramebuffer == 0)
|
||||
{
|
||||
// OK: we are rendering in the default framebuffer
|
||||
|
||||
/* EXT_draw_buffers :
|
||||
If the GL is bound to the default framebuffer, then <buffersLength> must be 1
|
||||
and the constant must be BACK or NONE. When draw buffer zero is
|
||||
BACK, color values are written into the sole buffer for single-
|
||||
buffered contexts, or into the back buffer for double-buffered
|
||||
contexts. If DrawBuffersEXT is supplied with a constant other than
|
||||
BACK and NONE, the error INVALID_OPERATION is generated.
|
||||
*/
|
||||
if (buffersLength != 1) {
|
||||
return mContext->ErrorInvalidValue("drawBuffersWEBGL: invalid <buffers> (main framebuffer: buffers.length must be 1)");
|
||||
}
|
||||
|
||||
mContext->MakeContextCurrent();
|
||||
|
||||
if (buffers[0] == LOCAL_GL_NONE) {
|
||||
const GLenum drawBufffersCommand = LOCAL_GL_NONE;
|
||||
mContext->GL()->fDrawBuffers(1, &drawBufffersCommand);
|
||||
return;
|
||||
}
|
||||
else if (buffers[0] == LOCAL_GL_BACK) {
|
||||
const GLenum drawBufffersCommand = LOCAL_GL_COLOR_ATTACHMENT0;
|
||||
mContext->GL()->fDrawBuffers(1, &drawBufffersCommand);
|
||||
return;
|
||||
}
|
||||
return mContext->ErrorInvalidOperation("drawBuffersWEBGL: invalid operation (main framebuffer: buffers[0] must be GL_NONE or GL_BACK)");
|
||||
}
|
||||
|
||||
// OK: we are rendering in a framebuffer object
|
||||
|
||||
if (buffersLength > size_t(mContext->mGLMaxDrawBuffers)) {
|
||||
/* EXT_draw_buffers :
|
||||
The maximum number of draw buffers is implementation-dependent. The
|
||||
number of draw buffers supported can be queried by calling
|
||||
GetIntegerv with the symbolic constant MAX_DRAW_BUFFERS_EXT. An
|
||||
INVALID_VALUE error is generated if <buffersLength> is greater than
|
||||
MAX_DRAW_BUFFERS_EXT.
|
||||
*/
|
||||
return mContext->ErrorInvalidValue("drawBuffersWEBGL: invalid <buffers> (buffers.length > GL_MAX_DRAW_BUFFERS)");
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < buffersLength; i++)
|
||||
{
|
||||
/* EXT_draw_buffers :
|
||||
If the GL is bound to a draw framebuffer object, the <i>th buffer listed
|
||||
in <bufs> must be COLOR_ATTACHMENT<i>_EXT or NONE. Specifying a
|
||||
buffer out of order, BACK, or COLOR_ATTACHMENT<m>_EXT where <m> is
|
||||
greater than or equal to the value of MAX_COLOR_ATTACHMENTS_EXT,
|
||||
will generate the error INVALID_OPERATION.
|
||||
*/
|
||||
/* WEBGL_draw_buffers :
|
||||
The value of the MAX_COLOR_ATTACHMENTS_WEBGL parameter must be greater than or equal to that of the MAX_DRAW_BUFFERS_WEBGL parameter.
|
||||
*/
|
||||
if (buffers[i] != LOCAL_GL_NONE &&
|
||||
buffers[i] != GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + i)) {
|
||||
return mContext->ErrorInvalidOperation("drawBuffersWEBGL: invalid operation (buffers[i] must be GL_NONE or GL_COLOR_ATTACHMENTi)");
|
||||
}
|
||||
}
|
||||
|
||||
mContext->MakeContextCurrent();
|
||||
|
||||
mContext->GL()->fDrawBuffers(buffersLength, buffers.Elements());
|
||||
mContext->DrawBuffers(buffers);
|
||||
}
|
||||
|
||||
bool WebGLExtensionDrawBuffers::IsSupported(const WebGLContext* context)
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define WEBGLVERTEXARRAY_H_
|
||||
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
|
||||
#include "nsWrapperCache.h"
|
||||
|
@ -35,6 +35,8 @@ if CONFIG['MOZ_WEBGL']:
|
||||
'WebGLContextUtils.cpp',
|
||||
'WebGLContextReporter.cpp',
|
||||
'WebGLContextValidate.cpp',
|
||||
'WebGLContextFramebufferOperations.cpp',
|
||||
'WebGLContextVertexArray.cpp',
|
||||
'WebGLElementArrayCache.cpp',
|
||||
'WebGLExtensionBase.cpp',
|
||||
'WebGLExtensionCompressedTextureATC.cpp',
|
||||
|
@ -8,5 +8,52 @@
|
||||
|
||||
interface WebGL2RenderingContext : WebGLRenderingContext {
|
||||
|
||||
/* draw buffers */
|
||||
const GLenum COLOR_ATTACHMENT1 = 0x8CE1;
|
||||
const GLenum COLOR_ATTACHMENT2 = 0x8CE2;
|
||||
const GLenum COLOR_ATTACHMENT3 = 0x8CE3;
|
||||
const GLenum COLOR_ATTACHMENT4 = 0x8CE4;
|
||||
const GLenum COLOR_ATTACHMENT5 = 0x8CE5;
|
||||
const GLenum COLOR_ATTACHMENT6 = 0x8CE6;
|
||||
const GLenum COLOR_ATTACHMENT7 = 0x8CE7;
|
||||
const GLenum COLOR_ATTACHMENT8 = 0x8CE8;
|
||||
const GLenum COLOR_ATTACHMENT9 = 0x8CE9;
|
||||
const GLenum COLOR_ATTACHMENT10 = 0x8CEA;
|
||||
const GLenum COLOR_ATTACHMENT11 = 0x8CEB;
|
||||
const GLenum COLOR_ATTACHMENT12 = 0x8CEC;
|
||||
const GLenum COLOR_ATTACHMENT13 = 0x8CED;
|
||||
const GLenum COLOR_ATTACHMENT14 = 0x8CEE;
|
||||
const GLenum COLOR_ATTACHMENT15 = 0x8CEF;
|
||||
|
||||
const GLenum DRAW_BUFFER0 = 0x8825;
|
||||
const GLenum DRAW_BUFFER1 = 0x8826;
|
||||
const GLenum DRAW_BUFFER2 = 0x8827;
|
||||
const GLenum DRAW_BUFFER3 = 0x8828;
|
||||
const GLenum DRAW_BUFFER4 = 0x8829;
|
||||
const GLenum DRAW_BUFFER5 = 0x882A;
|
||||
const GLenum DRAW_BUFFER6 = 0x882B;
|
||||
const GLenum DRAW_BUFFER7 = 0x882C;
|
||||
const GLenum DRAW_BUFFER8 = 0x882D;
|
||||
const GLenum DRAW_BUFFER9 = 0x882E;
|
||||
const GLenum DRAW_BUFFER10 = 0x882F;
|
||||
const GLenum DRAW_BUFFER11 = 0x8830;
|
||||
const GLenum DRAW_BUFFER12 = 0x8831;
|
||||
const GLenum DRAW_BUFFER13 = 0x8832;
|
||||
const GLenum DRAW_BUFFER14 = 0x8833;
|
||||
const GLenum DRAW_BUFFER15 = 0x8834;
|
||||
|
||||
const GLenum MAX_COLOR_ATTACHMENTS = 0x8CDF;
|
||||
const GLenum MAX_DRAW_BUFFERS = 0x8824;
|
||||
|
||||
/* vertex array objects */
|
||||
const GLenum VERTEX_ARRAY_BINDING = 0x85B5;
|
||||
|
||||
|
||||
void bindVertexArray(WebGLVertexArray? arrayObject);
|
||||
WebGLVertexArray? createVertexArray();
|
||||
void drawBuffers(sequence<GLenum> buffers);
|
||||
void deleteVertexArray(WebGLVertexArray? arrayObject);
|
||||
[WebGLHandlesContextLoss] GLboolean isVertexArray(WebGLVertexArray? arrayObject);
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user