Bug 1477756 - Initial out-of-process WebGL implementation. r=mccr8,handyman

Splits WebGLContext into ClientWebGLContext and HostWebGLContext.  The Client enables the JS-control of a WebGL context in a content procecss while the Host executes the WebGL graphics operations (via a WebGLContext that maintains much of the existing code) in the compositor process.  At this point, the cross-process behavior is disabled -- this series of patches is an incremental step toward that final goal.

Differential Revision: https://phabricator.services.mozilla.com/D54018

--HG--
extra : moz-landing-system : lando
This commit is contained in:
David Parks 2020-01-08 22:19:14 +00:00
Родитель 861aef232d
Коммит 198fa063c2
157 изменённых файлов: 14434 добавлений и 3727 удалений

Просмотреть файл

@ -1045,33 +1045,33 @@ DOMInterfaces = {
},
'WebGLActiveInfo': {
'nativeType': 'mozilla::WebGLActiveInfo',
'nativeType': 'mozilla::ClientWebGLActiveInfo',
'headerFile': 'WebGLActiveInfo.h'
},
'WebGLBuffer': {
'nativeType': 'mozilla::WebGLBuffer',
'headerFile': 'WebGLBuffer.h'
'nativeType': 'mozilla::ClientWebGLBuffer',
'headerFile': 'ClientWebGLContext.h'
},
'EXT_float_blend': {
'nativeType': 'mozilla::WebGLExtensionFloatBlend',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionFloatBlend',
'headerFile': 'ClientWebGLExtensions.h'
},
'EXT_texture_compression_bptc': {
'nativeType': 'mozilla::WebGLExtensionCompressedTextureBPTC',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionCompressedTextureBPTC',
'headerFile': 'ClientWebGLExtensions.h'
},
'EXT_texture_compression_rgtc': {
'nativeType': 'mozilla::WebGLExtensionCompressedTextureRGTC',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionCompressedTextureRGTC',
'headerFile': 'ClientWebGLExtensions.h'
},
'OES_fbo_render_mipmap': {
'nativeType': 'mozilla::WebGLExtensionFBORenderMipmap',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionFBORenderMipmap',
'headerFile': 'ClientWebGLExtensions.h'
},
'OVR_multiview2': {
@ -1080,48 +1080,48 @@ DOMInterfaces = {
},
'WEBGL_compressed_texture_astc': {
'nativeType': 'mozilla::WebGLExtensionCompressedTextureASTC',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionCompressedTextureASTC',
'headerFile': 'ClientWebGLExtensions.h'
},
'WEBGL_compressed_texture_etc': {
'nativeType': 'mozilla::WebGLExtensionCompressedTextureES3',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionCompressedTextureES3',
'headerFile': 'ClientWebGLExtensions.h'
},
'WEBGL_compressed_texture_etc1': {
'nativeType': 'mozilla::WebGLExtensionCompressedTextureETC1',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionCompressedTextureETC1',
'headerFile': 'ClientWebGLExtensions.h'
},
'WEBGL_compressed_texture_pvrtc': {
'nativeType': 'mozilla::WebGLExtensionCompressedTexturePVRTC',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionCompressedTexturePVRTC',
'headerFile': 'ClientWebGLExtensions.h'
},
'WEBGL_compressed_texture_s3tc': {
'nativeType': 'mozilla::WebGLExtensionCompressedTextureS3TC',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionCompressedTextureS3TC',
'headerFile': 'ClientWebGLExtensions.h'
},
'WEBGL_compressed_texture_s3tc_srgb': {
'nativeType': 'mozilla::WebGLExtensionCompressedTextureS3TC_SRGB',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionCompressedTextureS3TC_SRGB',
'headerFile': 'ClientWebGLExtensions.h'
},
'WEBGL_depth_texture': {
'nativeType': 'mozilla::WebGLExtensionDepthTexture',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionDepthTexture',
'headerFile': 'ClientWebGLExtensions.h'
},
'WEBGL_debug_renderer_info': {
'nativeType': 'mozilla::WebGLExtensionDebugRendererInfo',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionDebugRendererInfo',
'headerFile': 'ClientWebGLExtensions.h'
},
'WEBGL_debug_shaders': {
'nativeType': 'mozilla::WebGLExtensionDebugShaders',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionDebugShaders',
'headerFile': 'ClientWebGLExtensions.h'
},
'WEBGL_explicit_present': {
@ -1130,174 +1130,174 @@ DOMInterfaces = {
},
'OES_element_index_uint': {
'nativeType': 'mozilla::WebGLExtensionElementIndexUint',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionElementIndexUint',
'headerFile': 'ClientWebGLExtensions.h'
},
'EXT_frag_depth': {
'nativeType': 'mozilla::WebGLExtensionFragDepth',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionFragDepth',
'headerFile': 'ClientWebGLExtensions.h'
},
'WEBGL_lose_context': {
'nativeType': 'mozilla::WebGLExtensionLoseContext',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionLoseContext',
'headerFile': 'ClientWebGLExtensions.h'
},
'EXT_sRGB': {
'nativeType': 'mozilla::WebGLExtensionSRGB',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionSRGB',
'headerFile': 'ClientWebGLExtensions.h'
},
'OES_standard_derivatives': {
'nativeType': 'mozilla::WebGLExtensionStandardDerivatives',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionStandardDerivatives',
'headerFile': 'ClientWebGLExtensions.h'
},
'EXT_shader_texture_lod': {
'nativeType': 'mozilla::WebGLExtensionShaderTextureLod',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionShaderTextureLod',
'headerFile': 'ClientWebGLExtensions.h'
},
'EXT_texture_filter_anisotropic': {
'nativeType': 'mozilla::WebGLExtensionTextureFilterAnisotropic',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionTextureFilterAnisotropic',
'headerFile': 'ClientWebGLExtensions.h'
},
'OES_texture_float': {
'nativeType': 'mozilla::WebGLExtensionTextureFloat',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionTextureFloat',
'headerFile': 'ClientWebGLExtensions.h'
},
'OES_texture_float_linear': {
'nativeType': 'mozilla::WebGLExtensionTextureFloatLinear',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionTextureFloatLinear',
'headerFile': 'ClientWebGLExtensions.h'
},
'OES_texture_half_float': {
'nativeType': 'mozilla::WebGLExtensionTextureHalfFloat',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionTextureHalfFloat',
'headerFile': 'ClientWebGLExtensions.h'
},
'OES_texture_half_float_linear': {
'nativeType': 'mozilla::WebGLExtensionTextureHalfFloatLinear',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionTextureHalfFloatLinear',
'headerFile': 'ClientWebGLExtensions.h'
},
'WEBGL_color_buffer_float': {
'nativeType': 'mozilla::WebGLExtensionColorBufferFloat',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionColorBufferFloat',
'headerFile': 'ClientWebGLExtensions.h'
},
'EXT_color_buffer_half_float': {
'nativeType': 'mozilla::WebGLExtensionColorBufferHalfFloat',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionColorBufferHalfFloat',
'headerFile': 'ClientWebGLExtensions.h'
},
'EXT_color_buffer_float': {
'nativeType': 'mozilla::WebGLExtensionEXTColorBufferFloat',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionEXTColorBufferFloat',
'headerFile': 'ClientWebGLExtensions.h'
},
'WEBGL_draw_buffers': {
'nativeType': 'mozilla::WebGLExtensionDrawBuffers',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionDrawBuffers',
'headerFile': 'ClientWebGLExtensions.h'
},
'OES_vertex_array_object': {
'nativeType': 'mozilla::WebGLExtensionVertexArray',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionVertexArray',
'headerFile': 'ClientWebGLExtensions.h'
},
'ANGLE_instanced_arrays': {
'nativeType': 'mozilla::WebGLExtensionInstancedArrays',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionInstancedArrays',
'headerFile': 'ClientWebGLExtensions.h'
},
'EXT_blend_minmax': {
'nativeType': 'mozilla::WebGLExtensionBlendMinMax',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionBlendMinMax',
'headerFile': 'ClientWebGLExtensions.h'
},
'EXT_disjoint_timer_query': {
'nativeType': 'mozilla::WebGLExtensionDisjointTimerQuery',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionDisjointTimerQuery',
'headerFile': 'ClientWebGLExtensions.h'
},
'MOZ_debug': {
'nativeType': 'mozilla::WebGLExtensionMOZDebug',
'headerFile': 'WebGLExtensions.h'
'nativeType': 'mozilla::ClientWebGLExtensionMOZDebug',
'headerFile': 'ClientWebGLExtensions.h'
},
'WebGLFramebuffer': {
'nativeType': 'mozilla::WebGLFramebuffer',
'headerFile': 'WebGLFramebuffer.h'
'nativeType': 'mozilla::ClientWebGLFramebuffer',
'headerFile': 'ClientWebGLContext.h'
},
'WebGLProgram': {
'nativeType': 'mozilla::WebGLProgram',
'headerFile': 'WebGLProgram.h'
'nativeType': 'mozilla::ClientWebGLProgram',
'headerFile': 'ClientWebGLContext.h'
},
'WebGLQuery': {
'nativeType': 'mozilla::WebGLQuery',
'headerFile': 'WebGLQuery.h'
'nativeType': 'mozilla::ClientWebGLQuery',
'headerFile': 'ClientWebGLContext.h'
},
'WebGLRenderbuffer': {
'nativeType': 'mozilla::WebGLRenderbuffer',
'headerFile': 'WebGLRenderbuffer.h'
'nativeType': 'mozilla::ClientWebGLRenderbuffer',
'headerFile': 'ClientWebGLContext.h'
},
'WebGLRenderingContext': {
'nativeType': 'mozilla::WebGLContext',
'headerFile': 'WebGLContext.h',
'nativeType': 'mozilla::ClientWebGLContext',
'headerFile': 'ClientWebGLContext.h',
},
'WebGL2RenderingContext': {
'nativeType': 'mozilla::WebGL2Context',
'headerFile': 'WebGL2Context.h',
'nativeType': 'mozilla::ClientWebGLContext',
'headerFile': 'ClientWebGLContext.h',
},
'WebGLSampler': {
'nativeType': 'mozilla::WebGLSampler',
'headerFile': 'WebGLSampler.h'
'nativeType': 'mozilla::ClientWebGLSampler',
'headerFile': 'ClientWebGLContext.h'
},
'WebGLShader': {
'nativeType': 'mozilla::WebGLShader',
'headerFile': 'WebGLShader.h'
'nativeType': 'mozilla::ClientWebGLShader',
'headerFile': 'ClientWebGLContext.h'
},
'WebGLShaderPrecisionFormat': {
'nativeType': 'mozilla::WebGLShaderPrecisionFormat',
'nativeType': 'mozilla::ClientWebGLShaderPrecisionFormat',
'headerFile': 'WebGLShaderPrecisionFormat.h',
'wrapperCache': False
},
'WebGLSync': {
'nativeType': 'mozilla::WebGLSync',
'headerFile': 'WebGLSync.h'
'nativeType': 'mozilla::ClientWebGLSync',
'headerFile': 'ClientWebGLContext.h'
},
'WebGLTexture': {
'nativeType': 'mozilla::WebGLTexture',
'headerFile': 'WebGLTexture.h'
'nativeType': 'mozilla::ClientWebGLTexture',
'headerFile': 'ClientWebGLContext.h'
},
'WebGLTransformFeedback': {
'nativeType': 'mozilla::WebGLTransformFeedback',
'headerFile': 'WebGLTransformFeedback.h'
'nativeType': 'mozilla::ClientWebGLTransformFeedback',
'headerFile': 'ClientWebGLContext.h'
},
'WebGLUniformLocation': {
'nativeType': 'mozilla::WebGLUniformLocation',
'headerFile': 'WebGLUniformLocation.h'
'nativeType': 'mozilla::ClientWebGLUniformLocation',
'headerFile': 'ClientWebGLContext.h'
},
'WebGLVertexArrayObject': {
'nativeType': 'mozilla::WebGLVertexArray',
'headerFile': 'WebGLVertexArray.h'
'nativeType': 'mozilla::ClientWebGLVertexArray',
'headerFile': 'ClientWebGLContext.h'
},
# WebGPU

Просмотреть файл

@ -7,6 +7,7 @@
#include "ImageBitmapRenderingContext.h"
#include "ImageEncoder.h"
#include "mozilla/dom/CanvasRenderingContext2D.h"
#include "mozilla/GfxMessageUtils.h"
#include "mozilla/Telemetry.h"
#include "mozilla/UniquePtr.h"
#include "MozFramebuffer.h"
@ -14,8 +15,7 @@
#include "nsDOMJSUtils.h"
#include "nsIScriptContext.h"
#include "nsJSUtils.h"
#include "WebGL1Context.h"
#include "WebGL2Context.h"
#include "ClientWebGLContext.h"
namespace mozilla {
namespace dom {
@ -126,7 +126,7 @@ CanvasRenderingContextHelper::CreateContextHelper(
case CanvasContextType::WebGL1:
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1);
ret = WebGL1Context::Create();
ret = ClientWebGLContext::Create(WEBGL1);
if (!ret) return nullptr;
break;
@ -134,7 +134,7 @@ CanvasRenderingContextHelper::CreateContextHelper(
case CanvasContextType::WebGL2:
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1);
ret = WebGL2Context::Create();
ret = ClientWebGLContext::Create(WEBGL2);
if (!ret) return nullptr;
break;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "ClientWebGLExtensions.h"
namespace mozilla {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(ClientWebGLExtensionBase)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(ClientWebGLExtensionBase, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(ClientWebGLExtensionBase, Release)
DEFINE_WEBGL_EXTENSION_GOOP(ANGLE_instanced_arrays,
WebGLExtensionInstancedArrays)
DEFINE_WEBGL_EXTENSION_GOOP(EXT_blend_minmax, WebGLExtensionBlendMinMax)
DEFINE_WEBGL_EXTENSION_GOOP(EXT_color_buffer_float,
WebGLExtensionEXTColorBufferFloat)
DEFINE_WEBGL_EXTENSION_GOOP(EXT_color_buffer_half_float,
WebGLExtensionColorBufferHalfFloat)
DEFINE_WEBGL_EXTENSION_GOOP(EXT_texture_compression_bptc,
WebGLExtensionCompressedTextureBPTC)
DEFINE_WEBGL_EXTENSION_GOOP(EXT_texture_compression_rgtc,
WebGLExtensionCompressedTextureRGTC)
DEFINE_WEBGL_EXTENSION_GOOP(EXT_frag_depth, WebGLExtensionFragDepth)
DEFINE_WEBGL_EXTENSION_GOOP(EXT_sRGB, WebGLExtensionSRGB)
DEFINE_WEBGL_EXTENSION_GOOP(EXT_shader_texture_lod,
WebGLExtensionShaderTextureLod)
DEFINE_WEBGL_EXTENSION_GOOP(EXT_texture_filter_anisotropic,
WebGLExtensionTextureFilterAnisotropic)
DEFINE_WEBGL_EXTENSION_GOOP(EXT_disjoint_timer_query,
WebGLExtensionDisjointTimerQuery)
DEFINE_WEBGL_EXTENSION_GOOP(MOZ_debug, WebGLExtensionMOZDebug)
DEFINE_WEBGL_EXTENSION_GOOP(OES_element_index_uint,
WebGLExtensionElementIndexUint)
DEFINE_WEBGL_EXTENSION_GOOP(OES_standard_derivatives,
WebGLExtensionStandardDerivatives)
DEFINE_WEBGL_EXTENSION_GOOP(OES_texture_float, WebGLExtensionTextureFloat)
DEFINE_WEBGL_EXTENSION_GOOP(OES_texture_float_linear,
WebGLExtensionTextureFloatLinear)
DEFINE_WEBGL_EXTENSION_GOOP(OES_texture_half_float,
WebGLExtensionTextureHalfFloat)
DEFINE_WEBGL_EXTENSION_GOOP(OES_texture_half_float_linear,
WebGLExtensionTextureHalfFloatLinear)
DEFINE_WEBGL_EXTENSION_GOOP(OES_vertex_array_object, WebGLExtensionVertexArray)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_color_buffer_float,
WebGLExtensionColorBufferFloat)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_compressed_texture_astc,
WebGLExtensionCompressedTextureASTC)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_compressed_texture_etc,
WebGLExtensionCompressedTextureES3)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_compressed_texture_etc1,
WebGLExtensionCompressedTextureETC1)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_compressed_texture_pvrtc,
WebGLExtensionCompressedTexturePVRTC)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_compressed_texture_s3tc,
WebGLExtensionCompressedTextureS3TC)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_compressed_texture_s3tc_srgb,
WebGLExtensionCompressedTextureS3TC_SRGB)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_debug_renderer_info,
WebGLExtensionDebugRendererInfo)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_debug_shaders, WebGLExtensionDebugShaders)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_depth_texture, WebGLExtensionDepthTexture)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_draw_buffers, WebGLExtensionDrawBuffers)
DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_lose_context, WebGLExtensionLoseContext)
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,229 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 CLIENTWEBGLEXTENSIONS_H_
#define CLIENTWEBGLEXTENSIONS_H_
#include "WebGLExtensions.h"
#include "ClientWebGLContext.h"
namespace mozilla {
/**
* The ClientWebGLExtension... classes back the JS Extension classes. They
* direct their calls to the ClientWebGLContext, adding a boolean first
* parameter, set to true, to indicate that an extension was the origin of
* the call.
*/
class ClientWebGLExtensionBase : public nsWrapperCache {
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(ClientWebGLExtensionBase)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(ClientWebGLExtensionBase)
ClientWebGLExtensionBase(RefPtr<ClientWebGLContext> aClient)
: mContext(aClient) {}
ClientWebGLContext* GetParentObject() const { return mContext; }
protected:
friend ClientWebGLContext;
virtual ~ClientWebGLExtensionBase() {}
RefPtr<ClientWebGLContext> mContext;
};
// To be used for implementations of ClientWebGLExtensionBase
#define DECLARE_WEBGL_EXTENSION_GOOP(_Extension) \
protected: \
virtual ~Client##_Extension() {} \
\
public: \
virtual JSObject* WrapObject(JSContext* cx, \
JS::Handle<JSObject*> givenProto) override; \
Client##_Extension(RefPtr<ClientWebGLContext> aClient);
// To be used for implementations of ClientWebGLExtensionBase
#define DEFINE_WEBGL_EXTENSION_GOOP(_WebGLBindingType, _Extension) \
JSObject* Client##_Extension::WrapObject(JSContext* cx, \
JS::Handle<JSObject*> givenProto) { \
return dom::_WebGLBindingType##_Binding::Wrap(cx, this, givenProto); \
} \
Client##_Extension::Client##_Extension(RefPtr<ClientWebGLContext> aClient) \
: ClientWebGLExtensionBase(aClient) {}
// Many extensions have no methods. This is a shorthand for declaring client
// versions of such classes.
#define DECLARE_SIMPLE_WEBGL_EXTENSION(_Extension) \
class Client##_Extension : public ClientWebGLExtensionBase { \
protected: \
virtual ~Client##_Extension() {} \
\
public: \
virtual JSObject* WrapObject(JSContext* cx, \
JS::Handle<JSObject*> givenProto) override; \
Client##_Extension(RefPtr<ClientWebGLContext> aClient); \
};
////
class ClientWebGLExtensionCompressedTextureASTC
: public ClientWebGLExtensionBase {
DECLARE_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureASTC)
void GetSupportedProfiles(dom::Nullable<nsTArray<nsString> >& retval) const {
mContext->GetASTCExtensionSupportedProfiles(retval);
}
};
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionFloatBlend)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTextureBPTC)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTextureES3)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTextureETC1)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTexturePVRTC)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTextureRGTC)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionFBORenderMipmap)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTextureS3TC)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTextureS3TC_SRGB)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionDebugRendererInfo)
class ClientWebGLExtensionDebugShaders : public ClientWebGLExtensionBase {
DECLARE_WEBGL_EXTENSION_GOOP(WebGLExtensionDebugShaders)
void GetTranslatedShaderSource(const ClientWebGLShader& shader,
nsAString& retval) const {
mContext->GetTranslatedShaderSource(shader, retval);
}
};
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionDepthTexture)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionElementIndexUint)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionEXTColorBufferFloat)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionFragDepth)
class ClientWebGLExtensionLoseContext : public ClientWebGLExtensionBase {
DECLARE_WEBGL_EXTENSION_GOOP(WebGLExtensionLoseContext)
void LoseContext() { mContext->LoseContext(); }
void RestoreContext() { mContext->RestoreContext(); }
};
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionSRGB)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionStandardDerivatives)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionShaderTextureLod)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionTextureFilterAnisotropic)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionTextureFloat)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionTextureFloatLinear)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionTextureHalfFloat)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionTextureHalfFloatLinear)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionColorBufferFloat)
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionColorBufferHalfFloat)
class ClientWebGLExtensionDrawBuffers : public ClientWebGLExtensionBase {
DECLARE_WEBGL_EXTENSION_GOOP(WebGLExtensionDrawBuffers)
void DrawBuffersWEBGL(const dom::Sequence<GLenum>& buffers) {
mContext->DrawBuffers(buffers, true);
}
};
class ClientWebGLExtensionVertexArray : public ClientWebGLExtensionBase {
DECLARE_WEBGL_EXTENSION_GOOP(WebGLExtensionVertexArray)
already_AddRefed<ClientWebGLVertexArray> CreateVertexArrayOES() {
return mContext->CreateVertexArray(true);
}
void DeleteVertexArrayOES(ClientWebGLVertexArray* array) {
mContext->DeleteVertexArray(array, true);
}
bool IsVertexArrayOES(const ClientWebGLVertexArray* array) {
return mContext->IsVertexArray(array, true);
}
void BindVertexArrayOES(ClientWebGLVertexArray* array) {
mContext->BindVertexArray(array, true);
}
};
class ClientWebGLExtensionInstancedArrays : public ClientWebGLExtensionBase {
DECLARE_WEBGL_EXTENSION_GOOP(WebGLExtensionInstancedArrays)
void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count,
GLsizei primcount) {
mContext->DrawArraysInstanced(mode, first, count, primcount, true);
}
void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type,
WebGLintptr offset, GLsizei primcount) {
mContext->DrawElementsInstanced(mode, count, type, offset, primcount,
WebGLContextEndpoint::drawElementsInstanced,
true);
}
void VertexAttribDivisorANGLE(GLuint index, GLuint divisor) {
mContext->VertexAttribDivisor(index, divisor, true);
}
};
DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionBlendMinMax)
class ClientWebGLExtensionDisjointTimerQuery : public ClientWebGLExtensionBase {
DECLARE_WEBGL_EXTENSION_GOOP(WebGLExtensionDisjointTimerQuery)
already_AddRefed<ClientWebGLQuery> CreateQueryEXT() const {
return mContext->CreateQuery(true);
}
void DeleteQueryEXT(ClientWebGLQuery* query) const {
mContext->DeleteQuery(query, true);
}
bool IsQueryEXT(const ClientWebGLQuery* query) const {
return mContext->IsQuery(query, true);
}
void BeginQueryEXT(GLenum target, ClientWebGLQuery& query) const {
mContext->BeginQuery(target, query, true);
}
void EndQueryEXT(GLenum target) const { mContext->EndQuery(target, true); }
void QueryCounterEXT(ClientWebGLQuery& query, GLenum target) const {
mContext->QueryCounter(query, target);
}
void GetQueryEXT(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval) const {
mContext->GetQuery(cx, target, pname, retval, true);
}
void GetQueryObjectEXT(JSContext* cx, const ClientWebGLQuery& query,
GLenum pname, JS::MutableHandleValue retval) const {
mContext->GetQueryParameter(cx, query, pname, retval, true);
}
};
class ClientWebGLExtensionMOZDebug : public ClientWebGLExtensionBase {
DECLARE_WEBGL_EXTENSION_GOOP(WebGLExtensionMOZDebug)
void GetParameter(JSContext* cx, GLenum pname,
JS::MutableHandle<JS::Value> retval,
ErrorResult& er) const {
mContext->MOZDebugGetParameter(cx, pname, retval, er);
}
};
} // namespace mozilla
#endif // CLIENTWEBGLEXTENSIONS_H_

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,803 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 HOSTWEBGLCONTEXT_H_
#define HOSTWEBGLCONTEXT_H_
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/HashTable.h"
#include "mozilla/GfxMessageUtils.h"
#include "mozilla/HashTable.h"
#include "nsString.h"
#include "WebGLContext.h"
#include "WebGL2Context.h"
#include "WebGLContextEndpoint.h"
#include "mozilla/dom/WebGLTypes.h"
#include "WebGLActiveInfo.h"
#include "WebGLErrorQueue.h"
#include "WebGLShaderPrecisionFormat.h"
#ifndef WEBGL_BRIDGE_LOG_
# define WEBGL_BRIDGE_LOG_(lvl, ...) \
MOZ_LOG(mozilla::gWebGLBridgeLog, lvl, (__VA_ARGS__))
# define WEBGL_BRIDGE_LOGD(...) WEBGL_BRIDGE_LOG_(LogLevel::Debug, __VA_ARGS__)
# define WEBGL_BRIDGE_LOGE(...) WEBGL_BRIDGE_LOG_(LogLevel::Error, __VA_ARGS__)
#endif // WEBGL_BRIDGE_LOG_
namespace mozilla {
class HostWebGLCommandSink;
extern LazyLogModule gWebGLBridgeLog;
namespace layers {
class CompositableHost;
}
/**
* Host endpoint of a WebGLContext. HostWebGLContext owns a WebGLContext
* that it uses to execute commands sent from its ClientWebGLContext.
*
* The HostWebGLContext provides host implementions of methods from the
* WebGLContextEndpoint.
* A HostWebGLContext continuously issues a Task to the Compositor thread that
* causes it to drain its queue of commands. It also maintains a map of WebGL
* objects (e.g. ObjectIdMap<WebGLShader>) that it uses associate them with
* their cross-process IDs.
*
* This class is not an implementation of the
* nsICanvasRenderingContextInternal DOM class. That is the
* ClientWebGLContext.
*/
class HostWebGLContext : public WebGLContextEndpoint {
public:
static UniquePtr<HostWebGLContext> Create(
WebGLVersion aVersion,
UniquePtr<HostWebGLCommandSink>&& aCommandSink = nullptr,
UniquePtr<HostWebGLErrorSource>&& aErrorSource = nullptr);
virtual ~HostWebGLContext();
WebGLContext* GetWebGLContext() { return mContext; }
protected:
HostWebGLContext(WebGLVersion aVersion, RefPtr<WebGLContext> aContext,
UniquePtr<HostWebGLCommandSink>&& aCommandSink,
UniquePtr<HostWebGLErrorSource>&& aErrorSource);
// These are null only if we are running single-process WebGL
UniquePtr<HostWebGLCommandSink> mCommandSink;
UniquePtr<HostWebGLErrorSource> mErrorSource;
// The host-side of an object ID map for types for which the client
// generates the IDs. (This is the majority of the types of objects that
// we maintain across processes.)
template <typename ObjectType>
class ObjectIdMap {
public:
using IdType = WebGLId<ObjectType>;
using PtrType = ObjectType*;
using RefType = RefPtr<ObjectType>;
using AlreadyAddRefedType = already_AddRefed<ObjectType>;
virtual IdType Insert(RefType&& aObj, const IdType& aId) {
// asynchronous contructors must never fail
MOZ_ASSERT(aId && aObj &&
((aObj->Id() == aId.Id()) || (aObj->Id() == 0)));
aObj->mId = aId.Id();
Unused << mMap.put(aId, std::move(aObj));
return aId;
}
PtrType Find(const IdType& aId) const {
if (!aId) {
return nullptr;
}
auto it = mMap.lookup(aId);
return it ? it->value().get() : nullptr;
}
void Remove(const IdType& aId) {
if (!aId) {
return;
}
auto it = mMap.lookup(aId);
if (!it) {
return;
}
MOZ_ASSERT(it->value()->Id() == aId.Id());
// NB: We leave it->value()->Id() as is because it may be resurrected
// if the WebGLContext still holds a reference to it and later returns it.
mMap.remove(it);
}
protected:
using IdMap = HashMap<WebGLId<ObjectType>, RefPtr<ObjectType>>;
IdMap mMap;
};
// The host-side of an object ID map for types for which the host
// generates the IDs.
template <typename ObjectType>
class HostGenObjectIdMap : public ObjectIdMap<ObjectType> {
public:
using BaseType = ObjectIdMap<ObjectType>;
using IdType = typename BaseType::IdType;
using RefType = typename BaseType::RefType;
using AlreadyAddRefedType = typename BaseType::AlreadyAddRefedType;
HostGenObjectIdMap() : mNextId(1) {}
// Generate or resurrect aObj.
IdType Insert(RefType&& aObj, const IdType& aId) override {
MOZ_ASSERT((!aId) && aObj);
uint64_t curId;
if (aObj->Id()) {
curId = aObj->Id();
} else {
curId = mNextId;
++mNextId;
aObj->mId = curId;
}
IdType ret(curId);
Unused << BaseType::mMap.put(ret, std::move(aObj));
return ret;
}
private:
uint64_t mNextId;
};
#define DECLARE_OBJECT_ID_MAP_FUNCS(_WebGLType) \
WebGLId<WebGL##_WebGLType> Insert(RefPtr<WebGL##_WebGLType>&& aObj, \
const WebGLId<WebGL##_WebGLType>& aId = \
WebGLId<WebGL##_WebGLType>::Invalid()) \
const; \
WebGL##_WebGLType* Find(const WebGLId<WebGL##_WebGLType>& aId) const; \
void Remove(const WebGLId<WebGL##_WebGLType>& aId) const;
// Use this when failure to find an object by ID is a fatal error.
template <typename WebGLType>
WebGLType* MustFind(const WebGLId<WebGLType>& aId) const {
auto ret = Find(aId);
MOZ_RELEASE_ASSERT(ret);
return ret;
}
// Defines a host-side Object ID Map (client generates the IDs) and a few
// convenient methods that forward to them. If _WebGLType needs IDs to be
// generated on the host side then use DEFINE_HOST_GEN_OBJECT_ID_MAP.
#define DEFINE_OBJECT_ID_MAP(_WebGLType) \
mutable ObjectIdMap<WebGL##_WebGLType> m##_WebGLType##Map; \
DECLARE_OBJECT_ID_MAP_FUNCS(_WebGLType)
DEFINE_OBJECT_ID_MAP(Framebuffer);
DEFINE_OBJECT_ID_MAP(Program);
DEFINE_OBJECT_ID_MAP(Query);
DEFINE_OBJECT_ID_MAP(Renderbuffer);
DEFINE_OBJECT_ID_MAP(Sampler);
DEFINE_OBJECT_ID_MAP(Shader);
DEFINE_OBJECT_ID_MAP(Sync);
DEFINE_OBJECT_ID_MAP(TransformFeedback);
DEFINE_OBJECT_ID_MAP(VertexArray);
#undef DEFINE_OBJECT_ID_MAP
// Defines a host-side Object ID Map (host generates the IDs) and a few
// convenient methods that forward to them.
#define DEFINE_HOST_GEN_OBJECT_ID_MAP(_WebGLType) \
mutable HostGenObjectIdMap<WebGL##_WebGLType> m##_WebGLType##Map; \
DECLARE_OBJECT_ID_MAP_FUNCS(_WebGLType)
DEFINE_HOST_GEN_OBJECT_ID_MAP(Buffer);
DEFINE_HOST_GEN_OBJECT_ID_MAP(Texture);
DEFINE_HOST_GEN_OBJECT_ID_MAP(UniformLocation);
#undef DEFINE_HOST_GEN_OBJECT_ID_MAP
#undef DECLARE_OBJECT_ID_MAP_FUNCS
template <typename T>
nsTArray<WebGLId<T>> MapArrayOfObjectsToIds(
const nsTArray<RefPtr<T>>& objects) {
nsTArray<WebGLId<T>> ret;
for (auto& object : objects) {
ret.AppendElement(object ? object->GetWebGLId() : WebGLId<T>::Invalid());
}
return ret;
}
// -------------------------------------------------------------------------
// RPC Framework
// -------------------------------------------------------------------------
public:
CommandResult RunCommandsForDuration(TimeDuration aDuration);
// This must be called if this is a Host for a single-process context
void SetClientContext(ClientWebGLContext* aClientContext) {
MOZ_ASSERT(!mCommandSink);
mClientContext = aClientContext;
}
// -------------------------------------------------------------------------
// Host-side methods. Calls in the client are forwarded to the host.
// -------------------------------------------------------------------------
public:
// ------------------------- Creation/Destruction -------------------------
// When the client releases its handle to this, we release ours. Note that
// we may later ressurrect the object if the WebGLContext or some other
// internal class still holds a reference to it. In that case, we will still
// keep the old ID.
template <typename WebGLType>
void ReleaseWebGLObject(const WebGLId<WebGLType>& o) {
Remove(o);
}
// ------------------------- Composition -------------------------
void Present();
Maybe<ICRData> InitializeCanvasRenderer(layers::LayersBackend backend);
void SetContextOptions(const WebGLContextOptions& options);
SetDimensionsData SetDimensions(int32_t signedWidth, int32_t signedHeight);
gfx::IntSize DrawingBufferSize();
void SetCompositableHost(RefPtr<layers::CompositableHost>& aCompositableHost);
void OnMemoryPressure();
void AllowContextRestore();
void DidRefresh();
// ------------------------- GL State -------------------------
bool IsContextLost() const;
void Disable(GLenum cap);
void Enable(GLenum cap);
bool IsEnabled(GLenum cap);
MaybeWebGLVariant GetParameter(GLenum pname);
void AttachShader(const WebGLId<WebGLProgram>& progId,
const WebGLId<WebGLShader>& shaderId);
void BindAttribLocation(const WebGLId<WebGLProgram>& progId, GLuint location,
const nsString& name);
void BindFramebuffer(GLenum target, const WebGLId<WebGLFramebuffer>& fb);
void BindRenderbuffer(GLenum target, const WebGLId<WebGLRenderbuffer>& fb);
void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
void BlendEquation(GLenum mode);
void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
void BlendFunc(GLenum sfactor, GLenum dfactor);
void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha,
GLenum dstAlpha);
GLenum CheckFramebufferStatus(GLenum target);
void Clear(GLbitfield mask);
void ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a);
void ClearDepth(GLclampf v);
void ClearStencil(GLint v);
void ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b,
WebGLboolean a);
void CompileShader(const WebGLId<WebGLShader>& shaderId);
void CreateFramebuffer(const WebGLId<WebGLFramebuffer>& aId);
void CreateProgram(const WebGLId<WebGLProgram>& aId);
void CreateRenderbuffer(const WebGLId<WebGLRenderbuffer>& aId);
void CreateShader(GLenum aType, const WebGLId<WebGLShader>& aId);
void CullFace(GLenum face);
void DeleteFramebuffer(const WebGLId<WebGLFramebuffer>& fb);
void DeleteProgram(const WebGLId<WebGLProgram>& prog);
void DeleteRenderbuffer(const WebGLId<WebGLRenderbuffer>& rb);
void DeleteShader(const WebGLId<WebGLShader>& shader);
void DepthFunc(GLenum func);
void DepthMask(WebGLboolean b);
void DepthRange(GLclampf zNear, GLclampf zFar);
void DetachShader(const WebGLId<WebGLProgram>& progId,
const WebGLId<WebGLShader>& shaderId);
void Flush();
void Finish();
void FramebufferRenderbuffer(GLenum target, GLenum attachment,
GLenum rbTarget,
const WebGLId<WebGLRenderbuffer>& rb);
void FramebufferTexture2D(GLenum target, GLenum attachment,
GLenum texImageTarget,
const WebGLId<WebGLTexture>& tex, GLint level);
void FrontFace(GLenum mode);
Maybe<WebGLActiveInfo> GetActiveAttrib(const WebGLId<WebGLProgram>& progId,
GLuint index);
Maybe<WebGLActiveInfo> GetActiveUniform(const WebGLId<WebGLProgram>& progId,
GLuint index);
MaybeAttachedShaders GetAttachedShaders(const WebGLId<WebGLProgram>& progId);
GLint GetAttribLocation(const WebGLId<WebGLProgram>& progId,
const nsString& name);
MaybeWebGLVariant GetBufferParameter(GLenum target, GLenum pname);
GLenum GetError();
MaybeWebGLVariant GetFramebufferAttachmentParameter(GLenum target,
GLenum attachment,
GLenum pname);
MaybeWebGLVariant GetProgramParameter(const WebGLId<WebGLProgram>& progId,
GLenum pname);
nsString GetProgramInfoLog(const WebGLId<WebGLProgram>& progId);
MaybeWebGLVariant GetRenderbufferParameter(GLenum target, GLenum pname);
MaybeWebGLVariant GetShaderParameter(const WebGLId<WebGLShader>& shaderId,
GLenum pname);
MaybeWebGLVariant GetShaderPrecisionFormat(GLenum shadertype,
GLenum precisiontype);
nsString GetShaderInfoLog(const WebGLId<WebGLShader>& shaderId);
nsString GetShaderSource(const WebGLId<WebGLShader>& shaderId);
MaybeWebGLVariant GetUniform(const WebGLId<WebGLProgram>& progId,
const WebGLId<WebGLUniformLocation>& locId);
WebGLId<WebGLUniformLocation> GetUniformLocation(
const WebGLId<WebGLProgram>& progId, const nsString& name);
void Hint(GLenum target, GLenum mode);
void LineWidth(GLfloat width);
void LinkProgram(const WebGLId<WebGLProgram>& progId);
WebGLPixelStore PixelStorei(GLenum pname, GLint param);
void PolygonOffset(GLfloat factor, GLfloat units);
void SampleCoverage(GLclampf value, WebGLboolean invert);
void Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
void ShaderSource(const WebGLId<WebGLShader>& shaderId,
const nsString& source);
void StencilFunc(GLenum func, GLint ref, GLuint mask);
void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
void StencilMask(GLuint mask);
void StencilMaskSeparate(GLenum face, GLuint mask);
void StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass);
void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
GLenum dppass);
void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
// ------------------------- Buffer Objects -------------------------
void BindBuffer(GLenum target, const WebGLId<WebGLBuffer>& buffer);
void BindBufferBase(GLenum target, GLuint index,
const WebGLId<WebGLBuffer>& buffer);
void BindBufferRange(GLenum target, GLuint index,
const WebGLId<WebGLBuffer>& buffer, WebGLintptr offset,
WebGLsizeiptr size);
WebGLId<WebGLBuffer> CreateBuffer();
void DeleteBuffer(const WebGLId<WebGLBuffer>& buf);
void CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
GLintptr readOffset, GLintptr writeOffset,
GLsizeiptr size);
Maybe<UniquePtr<RawBuffer<>>> GetBufferSubData(GLenum target,
GLintptr srcByteOffset,
size_t byteLen);
void BufferData(GLenum target, const RawBuffer<>& data, GLenum usage);
void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
const RawBuffer<>& srcData);
// -------------------------- Framebuffer Objects --------------------------
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
void FramebufferTextureLayer(GLenum target, GLenum attachment,
const WebGLId<WebGLTexture>& textureId,
GLint level, GLint layer);
void InvalidateFramebuffer(GLenum target,
const nsTArray<GLenum>& attachments);
void InvalidateSubFramebuffer(GLenum target,
const nsTArray<GLenum>& attachments, GLint x,
GLint y, GLsizei width, GLsizei height);
void ReadBuffer(GLenum mode);
// ----------------------- Renderbuffer objects -----------------------
Maybe<nsTArray<int32_t>> GetInternalformatParameter(GLenum target,
GLenum internalformat,
GLenum pname);
void RenderbufferStorage_base(GLenum target, GLsizei samples,
GLenum internalFormat, GLsizei width,
GLsizei height, FuncScopeId aFuncId);
// --------------------------- Texture objects ---------------------------
void ActiveTexture(GLenum texUnit);
void BindTexture(GLenum texTarget, const WebGLId<WebGLTexture>& tex);
WebGLId<WebGLTexture> CreateTexture();
void DeleteTexture(const WebGLId<WebGLTexture>& tex);
void GenerateMipmap(GLenum texTarget);
void CopyTexImage2D(GLenum target, GLint level, GLenum internalFormat,
GLint x, GLint y, uint32_t width, uint32_t height,
uint32_t depth);
void TexStorage(uint8_t funcDims, GLenum target, GLsizei levels,
GLenum internalFormat, GLsizei width, GLsizei height,
GLsizei depth, FuncScopeId aFuncId);
void TexImage(uint8_t funcDims, GLenum target, GLint level,
GLenum internalFormat, GLsizei width, GLsizei height,
GLsizei depth, GLint border, GLenum unpackFormat,
GLenum unpackType, MaybeWebGLTexUnpackVariant&& src,
FuncScopeId aFuncId);
void TexSubImage(uint8_t funcDims, GLenum target, GLint level, GLint xOffset,
GLint yOffset, GLint zOffset, GLsizei width, GLsizei height,
GLsizei depth, GLenum unpackFormat, GLenum unpackType,
MaybeWebGLTexUnpackVariant&& src, FuncScopeId aFuncId);
void CompressedTexImage(uint8_t funcDims, GLenum target, GLint level,
GLenum internalFormat, GLsizei width, GLsizei height,
GLsizei depth, GLint border,
MaybeWebGLTexUnpackVariant&& src,
const Maybe<GLsizei>& expectedImageSize,
FuncScopeId aFuncId);
void CompressedTexSubImage(uint8_t funcDims, GLenum target, GLint level,
GLint xOffset, GLint yOffset, GLint zOffset,
GLsizei width, GLsizei height, GLsizei depth,
GLenum unpackFormat,
MaybeWebGLTexUnpackVariant&& src,
const Maybe<GLsizei>& expectedImageSize,
FuncScopeId aFuncId);
void CopyTexSubImage(uint8_t funcDims, GLenum target, GLint level,
GLint xOffset, GLint yOffset, GLint zOffset, GLint x,
GLint y, uint32_t width, uint32_t height, uint32_t depth,
FuncScopeId aFuncId);
MaybeWebGLVariant GetTexParameter(GLenum texTarget, GLenum pname);
void TexParameter_base(GLenum texTarget, GLenum pname,
const FloatOrInt& param);
// ------------------- Programs and shaders --------------------------------
void UseProgram(const WebGLId<WebGLProgram>& prog);
void ValidateProgram(const WebGLId<WebGLProgram>& progId);
GLint GetFragDataLocation(const WebGLId<WebGLProgram>& progId,
const nsString& name);
// ------------------------ Uniforms and attributes ------------------------
void UniformNfv(const nsCString& funcName, uint8_t N,
const WebGLId<WebGLUniformLocation>& loc,
const RawBuffer<const float>& arr, GLuint elemOffset,
GLuint elemCountOverride);
void UniformNiv(const nsCString& funcName, uint8_t N,
const WebGLId<WebGLUniformLocation>& loc,
const RawBuffer<const int32_t>& arr, GLuint elemOffset,
GLuint elemCountOverride);
void UniformNuiv(const nsCString& funcName, uint8_t N,
const WebGLId<WebGLUniformLocation>& loc,
const RawBuffer<const uint32_t>& arr, GLuint elemOffset,
GLuint elemCountOverride);
void UniformMatrixAxBfv(const nsCString& funcName, uint8_t A, uint8_t B,
const WebGLId<WebGLUniformLocation>& loc,
bool transpose, const RawBuffer<const float>& arr,
GLuint elemOffset, GLuint elemCountOverride);
void UniformFVec(const WebGLId<WebGLUniformLocation>& aLoc,
const nsTArray<float>& vec);
void UniformIVec(const WebGLId<WebGLUniformLocation>& aLoc,
const nsTArray<int32_t>& vec);
void UniformUIVec(const WebGLId<WebGLUniformLocation>& aLoc,
const nsTArray<uint32_t>& vec);
void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w,
FuncScopeId aFuncId);
void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w,
FuncScopeId aFuncId = FuncScopeId::vertexAttribI4i);
void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w,
FuncScopeId aFuncId = FuncScopeId::vertexAttribI4ui);
void VertexAttribDivisor(GLuint index, GLuint divisor,
bool aFromExtension = false);
MaybeWebGLVariant GetIndexedParameter(GLenum target, GLuint index);
MaybeWebGLVariant GetUniformIndices(const WebGLId<WebGLProgram>& progId,
const nsTArray<nsString>& uniformNames);
MaybeWebGLVariant GetActiveUniforms(const WebGLId<WebGLProgram>& progId,
const nsTArray<GLuint>& uniformIndices,
GLenum pname);
GLuint GetUniformBlockIndex(const WebGLId<WebGLProgram>& progId,
const nsString& uniformBlockName);
MaybeWebGLVariant GetActiveUniformBlockParameter(
const WebGLId<WebGLProgram>& progId, GLuint uniformBlockIndex,
GLenum pname);
nsString GetActiveUniformBlockName(const WebGLId<WebGLProgram>& progId,
GLuint uniformBlockIndex);
void UniformBlockBinding(const WebGLId<WebGLProgram>& progId,
GLuint uniformBlockIndex,
GLuint uniformBlockBinding);
void EnableVertexAttribArray(GLuint index);
void DisableVertexAttribArray(GLuint index);
MaybeWebGLVariant GetVertexAttrib(GLuint index, GLenum pname);
WebGLsizeiptr GetVertexAttribOffset(GLuint index, GLenum pname);
void VertexAttribAnyPointer(bool isFuncInt, GLuint index, GLint size,
GLenum type, bool normalized, GLsizei stride,
WebGLintptr byteOffset, FuncScopeId aFuncId);
// --------------------------- Buffer Operations --------------------------
void ClearBufferfv(GLenum buffer, GLint drawBuffer,
const RawBuffer<const float>& src, GLuint srcElemOffset);
void ClearBufferiv(GLenum buffer, GLint drawBuffer,
const RawBuffer<const int32_t>& src, GLuint srcElemOffset);
void ClearBufferuiv(GLenum buffer, GLint drawBuffer,
const RawBuffer<const uint32_t>& src,
GLuint srcElemOffset);
void ClearBufferfi(GLenum buffer, GLint drawBuffer, GLfloat depth,
GLint stencil);
// ------------------------------ Readback -------------------------------
void ReadPixels1(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, WebGLsizeiptr offset);
Maybe<UniquePtr<RawBuffer<>>> ReadPixels2(GLint x, GLint y, GLsizei width,
GLsizei height, GLenum format,
GLenum type, size_t byteLen);
// ----------------------------- Sampler -----------------------------------
void CreateSampler(const WebGLId<WebGLSampler>& aId);
void DeleteSampler(const WebGLId<WebGLSampler>& aId);
void BindSampler(GLuint unit, const WebGLId<WebGLSampler>& sampler);
void SamplerParameteri(const WebGLId<WebGLSampler>& samplerId, GLenum pname,
GLint param);
void SamplerParameterf(const WebGLId<WebGLSampler>& samplerId, GLenum pname,
GLfloat param);
MaybeWebGLVariant GetSamplerParameter(const WebGLId<WebGLSampler>& samplerId,
GLenum pname);
// ------------------------------- GL Sync ---------------------------------
WebGLId<WebGLSync> FenceSync(const WebGLId<WebGLSync>& aId, GLenum condition,
GLbitfield flags);
void DeleteSync(const WebGLId<WebGLSync>& sync);
GLenum ClientWaitSync(const WebGLId<WebGLSync>& sync, GLbitfield flags,
GLuint64 timeout);
void WaitSync(const WebGLId<WebGLSync>& sync, GLbitfield flags,
GLint64 timeout);
MaybeWebGLVariant GetSyncParameter(const WebGLId<WebGLSync>& sync,
GLenum pname);
// -------------------------- Transform Feedback ---------------------------
void CreateTransformFeedback(const WebGLId<WebGLTransformFeedback>& aId);
void DeleteTransformFeedback(const WebGLId<WebGLTransformFeedback>& tf);
void BindTransformFeedback(GLenum target,
const WebGLId<WebGLTransformFeedback>& tf);
void BeginTransformFeedback(GLenum primitiveMode);
void EndTransformFeedback();
void PauseTransformFeedback();
void ResumeTransformFeedback();
void TransformFeedbackVaryings(const WebGLId<WebGLProgram>& prog,
const nsTArray<nsString>& varyings,
GLenum bufferMode);
Maybe<WebGLActiveInfo> GetTransformFeedbackVarying(
const WebGLId<WebGLProgram>& prog, GLuint index);
// ------------------------------ WebGL Debug
// ------------------------------------
void EnqueueError(GLenum aGLError, const nsCString& aMsg);
void EnqueueWarning(const nsCString& aMsg);
void ReportOOMAndLoseContext();
// -------------------------------------------------------------------------
// Host-side extension methods. Calls in the client are forwarded to the
// host. Some extension methods are also available in WebGL2 Contexts. For
// them, the final parameter is a boolean indicating if the call originated
// from an extension.
// -------------------------------------------------------------------------
// Misc. Extensions
void EnableExtension(dom::CallerType callerType, WebGLExtensionID ext);
const Maybe<ExtensionSets> GetSupportedExtensions();
void DrawBuffers(const nsTArray<GLenum>& buffers,
bool aFromExtension = false);
Maybe<nsTArray<nsString>> GetASTCExtensionSupportedProfiles() const;
nsString GetTranslatedShaderSource(const WebGLId<WebGLShader>& shader) const;
void LoseContext(bool isSimulated = true);
void RestoreContext();
MaybeWebGLVariant MOZDebugGetParameter(GLenum pname) const;
// VertexArrayObjectEXT
void BindVertexArray(const WebGLId<WebGLVertexArray>& array,
bool aFromExtension = false);
void CreateVertexArray(const WebGLId<WebGLVertexArray>& aId,
bool aFromExtension = false);
void DeleteVertexArray(const WebGLId<WebGLVertexArray>& array,
bool aFromExtension = false);
// InstancedElementsEXT
void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
GLsizei primcount, bool aFromExtension = false);
void DrawElementsInstanced(
GLenum mode, GLsizei count, GLenum type, WebGLintptr offset,
GLsizei primcount,
FuncScopeId aFuncId = FuncScopeId::drawElementsInstanced,
bool aFromExtension = false);
void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
GLenum type, WebGLintptr byteOffset);
// GLQueryEXT
void CreateQuery(const WebGLId<WebGLQuery>& aId,
bool aFromExtension = false) const;
void DeleteQuery(const WebGLId<WebGLQuery>& query,
bool aFromExtension = false) const;
void BeginQuery(GLenum target, const WebGLId<WebGLQuery>& query,
bool aFromExtension = false) const;
void EndQuery(GLenum target, bool aFromExtension = false) const;
void QueryCounter(const WebGLId<WebGLQuery>& query, GLenum target) const;
MaybeWebGLVariant GetQuery(GLenum target, GLenum pname,
bool aFromExtension = false) const;
MaybeWebGLVariant GetQueryParameter(const WebGLId<WebGLQuery>& query,
GLenum pname,
bool aFromExtension = false) const;
// -------------------------------------------------------------------------
// Client-side methods. Calls in the Host are forwarded to the client.
// -------------------------------------------------------------------------
public:
void PostWarning(const nsCString& aWarningMsg);
void PostContextCreationError(const nsCString& aMsg);
void OnLostContext();
void OnRestoredContext();
// Etc
public:
already_AddRefed<layers::SharedSurfaceTextureClient> GetVRFrame();
protected:
static WebGLContext* MakeWebGLContext(WebGLVersion aVersion);
const WebGL2Context* GetWebGL2Context() const {
MOZ_RELEASE_ASSERT(mContext->IsWebGL2(), "Requires WebGL2 context");
return static_cast<WebGL2Context*>(mContext.get());
}
WebGL2Context* GetWebGL2Context() {
const auto* constThis = this;
return const_cast<WebGL2Context*>(constThis->GetWebGL2Context());
}
mozilla::ipc::Shmem PopShmem() { return mShmemStack.PopLastElement(); }
RefPtr<WebGLContext> mContext;
nsTArray<mozilla::ipc::Shmem> mShmemStack;
ClientWebGLContext* mClientContext;
};
} // namespace mozilla
#endif // HOSTWEBGLCONTEXT_H_

Просмотреть файл

@ -17,8 +17,6 @@
#include "CanvasUtils.h"
#include "GLContext.h"
#include "GLScreenBuffer.h"
#include "WebGL1Context.h"
#include "WebGL2Context.h"
namespace mozilla {
namespace dom {
@ -119,30 +117,8 @@ already_AddRefed<nsISupports> OffscreenCanvas::GetContext(
mCanvasRenderer->SetContextType(contextType);
if (contextType == CanvasContextType::WebGL1 ||
contextType == CanvasContextType::WebGL2) {
WebGLContext* webGL = static_cast<WebGLContext*>(mCurrentContext.get());
gl::GLContext* gl = webGL->GL();
mCanvasRenderer->mContext = mCurrentContext;
mCanvasRenderer->SetActiveEventTarget();
mCanvasRenderer->mGLContext = gl;
mCanvasRenderer->SetIsAlphaPremultiplied(webGL->IsPremultAlpha() ||
!gl->Caps().alpha);
if (RefPtr<ImageBridgeChild> imageBridge =
ImageBridgeChild::GetSingleton()) {
TextureFlags flags = TextureFlags::ORIGIN_BOTTOM_LEFT;
mCanvasClient = imageBridge->CreateCanvasClient(
CanvasClient::CanvasClientTypeShSurf, flags);
mCanvasRenderer->SetCanvasClient(mCanvasClient);
gl::GLScreenBuffer* screen = gl->Screen();
gl::SurfaceCaps caps = screen->mCaps;
auto forwarder = mCanvasClient->GetForwarder();
UniquePtr<gl::SurfaceFactory> factory =
gl::GLScreenBuffer::CreateFactory(gl, caps, forwarder, flags);
if (factory) screen->Morph(std::move(factory));
}
MOZ_ASSERT_UNREACHABLE("WebGL OffscreenCanvas not yet supported.");
return nullptr;
}
}
@ -186,7 +162,8 @@ void OffscreenCanvas::CommitFrameToCompositor() {
CanvasContextType contentType = mCanvasRenderer->GetContextType();
if (mCurrentContext && (contentType == CanvasContextType::WebGL1 ||
contentType == CanvasContextType::WebGL2)) {
static_cast<WebGLContext*>(mCurrentContext.get())->PresentScreenBuffer();
MOZ_ASSERT_UNREACHABLE("WebGL OffscreenCanvas not yet supported.");
return;
}
if (mCanvasRenderer && mCanvasRenderer->mGLContext) {

38
dom/canvas/PWebGL.ipdl Normal file
Просмотреть файл

@ -0,0 +1,38 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* 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 protocol PCompositorBridge;
include protocol PLayerTransaction;
using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
namespace mozilla {
namespace dom {
/**
* Represents the connection between a WebGLChild actor that issues WebGL
* command from the content process, and a WebGLParent in the compositor
* process that runs the commands.
*/
sync protocol PWebGL
{
manager PCompositorBridge;
parent:
async __delete__();
// DLP: TODO: Does this need to be sync?
sync UpdateCompositableHandle(PLayerTransaction aLayerTrans,
CompositableHandle aHandle);
child:
// Tell client that this queue needs to be shut down
async QueueFailed();
};
} // dom
} // mozilla

Просмотреть файл

@ -0,0 +1,14 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "ProducerConsumerQueue.h"
namespace mozilla {
namespace webgl {
mozilla::LazyLogModule gPCQLog("pcq");
} // namespace webgl
} // namespace mozilla

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -16,6 +16,7 @@
#include "WebGLFormats.h"
#include "WebGLTexelConversions.h"
#include "WebGLTexture.h"
#include "ProducerConsumerQueue.h"
namespace mozilla {
namespace webgl {
@ -263,19 +264,19 @@ static uint32_t FallbackOnZero(uint32_t val, uint32_t fallback) {
return (val ? val : fallback);
}
TexUnpackBlob::TexUnpackBlob(const WebGLContext* webgl, TexImageTarget target,
uint32_t rowLength, uint32_t width,
uint32_t height, uint32_t depth,
TexUnpackBlob::TexUnpackBlob(const WebGLPixelStore& pixelStore,
TexImageTarget target, uint32_t rowLength,
uint32_t width, uint32_t height, uint32_t depth,
gfxAlphaType srcAlphaType)
: mAlignment(webgl->mPixelStore_UnpackAlignment),
: mAlignment(pixelStore.mUnpackAlignment),
mRowLength(rowLength),
mImageHeight(FallbackOnZero(
ZeroOn2D(target, webgl->mPixelStore_UnpackImageHeight), height))
ZeroOn2D(target, pixelStore.mUnpackImageHeight), height))
,
mSkipPixels(webgl->mPixelStore_UnpackSkipPixels),
mSkipRows(webgl->mPixelStore_UnpackSkipRows),
mSkipImages(ZeroOn2D(target, webgl->mPixelStore_UnpackSkipImages))
mSkipPixels(pixelStore.mUnpackSkipPixels),
mSkipRows(pixelStore.mUnpackSkipRows),
mSkipImages(ZeroOn2D(target, pixelStore.mUnpackSkipImages))
,
mWidth(width),
@ -321,7 +322,7 @@ bool TexUnpackBlob::ConvertIfNeeded(
if (!rowLength || !rowCount) return true;
const auto srcIsPremult = (mSrcAlphaType == gfxAlphaType::Premult);
const auto& dstIsPremult = webgl->mPixelStore_PremultiplyAlpha;
const auto& dstIsPremult = webgl->mPixelStore.mPremultiplyAlpha;
const auto fnHasPremultMismatch = [&]() {
if (mSrcAlphaType == gfxAlphaType::Opaque) return false;
@ -330,8 +331,9 @@ bool TexUnpackBlob::ConvertIfNeeded(
return srcIsPremult != dstIsPremult;
};
const auto srcOrigin = (webgl->mPixelStore_FlipY ? gl::OriginPos::TopLeft
: gl::OriginPos::BottomLeft);
const auto srcOrigin =
(webgl->mPixelStore.mFlipY ? gl::OriginPos::TopLeft
: gl::OriginPos::BottomLeft);
const auto dstOrigin = gl::OriginPos::BottomLeft;
if (srcFormat != dstFormat) {
@ -398,22 +400,19 @@ static GLenum DoTexOrSubImage(bool isSubImage, gl::GLContext* gl,
//////////////////////////////////////////////////////////////////////////////////////////
// TexUnpackBytes
TexUnpackBytes::TexUnpackBytes(const WebGLContext* webgl, TexImageTarget target,
uint32_t width, uint32_t height, uint32_t depth,
TexUnpackBytes::TexUnpackBytes(const WebGLPixelStore& pixelStore,
TexImageTarget target, uint32_t width,
uint32_t height, uint32_t depth,
bool isClientData, const uint8_t* ptr,
size_t availBytes)
: TexUnpackBlob(webgl, target,
FallbackOnZero(webgl->mPixelStore_UnpackRowLength, width),
width, height, depth, gfxAlphaType::NonPremult),
mIsClientData(isClientData),
mPtr(ptr),
mAvailBytes(availBytes) {}
: TexUnpackBlob(pixelStore, target,
FallbackOnZero(pixelStore.mUnpackRowLength, width), width,
height, depth, gfxAlphaType::NonPremult),
mPtr(RawBuffer<const uint8_t>(availBytes, ptr)) {}
bool TexUnpackBytes::Validate(WebGLContext* webgl,
const webgl::PackingInfo& pi) {
if (mIsClientData && !mPtr) return true;
return ValidateUnpackBytes(webgl, pi, mAvailBytes, this);
return ValidateUnpackBytes(webgl, pi, mPtr.Length(), this);
}
bool TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec,
@ -428,21 +427,21 @@ bool TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec,
const auto format = FormatForPackingInfo(pi);
const auto bytesPerPixel = webgl::BytesPerPixel(pi);
const uint8_t* uploadPtr = mPtr;
const uint8_t* uploadPtr = mPtr.Data();
UniqueBuffer tempBuffer;
do {
if (!mIsClientData || !mPtr) break;
if (!mPtr) break;
if (!webgl->mPixelStore_FlipY && !webgl->mPixelStore_PremultiplyAlpha) {
if (!webgl->mPixelStore.mFlipY && !webgl->mPixelStore.mPremultiplyAlpha) {
break;
}
if (webgl->mPixelStore_UnpackImageHeight ||
webgl->mPixelStore_UnpackSkipImages ||
webgl->mPixelStore_UnpackRowLength ||
webgl->mPixelStore_UnpackSkipRows ||
webgl->mPixelStore_UnpackSkipPixels) {
if (webgl->mPixelStore.mUnpackImageHeight ||
webgl->mPixelStore.mUnpackSkipImages ||
webgl->mPixelStore.mUnpackRowLength ||
webgl->mPixelStore.mUnpackSkipRows ||
webgl->mPixelStore.mUnpackSkipPixels) {
webgl->ErrorInvalidOperation(
"Non-DOM-Element uploads with alpha-premult"
" or y-flip do not support subrect selection.");
@ -457,8 +456,8 @@ bool TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec,
const uint32_t rowCount = mHeight * mDepth;
const auto stride =
RoundUpToMultipleOf(rowLength * bytesPerPixel, mAlignment);
if (!ConvertIfNeeded(webgl, rowLength, rowCount, format, mPtr, stride,
format, stride, &uploadPtr, &tempBuffer)) {
if (!ConvertIfNeeded(webgl, rowLength, rowCount, format, mPtr.Data(),
stride, format, stride, &uploadPtr, &tempBuffer)) {
return false;
}
} while (false);
@ -563,15 +562,15 @@ bool TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec,
// Reset all our modified state.
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
webgl->mPixelStore_UnpackAlignment);
webgl->mPixelStore.mUnpackAlignment);
gl->fPixelStorei(LOCAL_GL_UNPACK_IMAGE_HEIGHT,
webgl->mPixelStore_UnpackImageHeight);
webgl->mPixelStore.mUnpackImageHeight);
gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH,
webgl->mPixelStore_UnpackRowLength);
webgl->mPixelStore.mUnpackRowLength);
gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_IMAGES,
webgl->mPixelStore_UnpackSkipImages);
webgl->mPixelStore.mUnpackSkipImages);
gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_ROWS,
webgl->mPixelStore_UnpackSkipRows);
webgl->mPixelStore.mUnpackSkipRows);
return true;
}
@ -581,10 +580,11 @@ bool TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec,
// TexUnpackImage
TexUnpackImage::TexUnpackImage(const WebGLContext* webgl, TexImageTarget target,
uint32_t width, uint32_t height, uint32_t depth,
uint32_t rowLength, uint32_t width,
uint32_t height, uint32_t depth,
layers::Image* image, gfxAlphaType srcAlphaType)
: TexUnpackBlob(webgl, target, image->GetSize().width, width, height, depth,
srcAlphaType),
: TexUnpackBlob(webgl->GetPixelStore(), target, rowLength, width, height,
depth, srcAlphaType),
mImage(image) {}
TexUnpackImage::~TexUnpackImage() {}
@ -592,9 +592,7 @@ TexUnpackImage::~TexUnpackImage() {}
bool TexUnpackImage::Validate(WebGLContext* webgl,
const webgl::PackingInfo& pi) {
if (!ValidatePIForDOM(webgl, pi)) return false;
const auto fullRows = mImage->GetSize().height;
return ValidateUnpackPixels(webgl, fullRows, 0, this);
return ValidateUnpackPixels(webgl, mImage->GetSize().height, 0, this);
}
bool TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec,
@ -628,9 +626,9 @@ bool TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec,
break;
}
if (webgl->mPixelStore_UnpackSkipPixels ||
webgl->mPixelStore_UnpackSkipRows ||
webgl->mPixelStore_UnpackSkipImages) {
if (webgl->mPixelStore.mUnpackSkipPixels ||
webgl->mPixelStore.mUnpackSkipRows ||
webgl->mPixelStore.mUnpackSkipImages) {
fallbackReason = "non-zero UNPACK_SKIP_* not yet supported";
break;
}
@ -639,7 +637,7 @@ bool TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec,
if (mSrcAlphaType == gfxAlphaType::Opaque) return false;
const bool srcIsPremult = (mSrcAlphaType == gfxAlphaType::Premult);
const auto& dstIsPremult = webgl->mPixelStore_PremultiplyAlpha;
const auto& dstIsPremult = webgl->mPixelStore.mPremultiplyAlpha;
if (srcIsPremult == dstIsPremult) return false;
if (dstIsPremult) {
@ -686,8 +684,8 @@ bool TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec,
const gfx::IntSize dstSize(mWidth, mHeight);
const auto dstOrigin =
(webgl->mPixelStore_FlipY ? gl::OriginPos::TopLeft
: gl::OriginPos::BottomLeft);
(webgl->mPixelStore.mFlipY ? gl::OriginPos::TopLeft
: gl::OriginPos::BottomLeft);
if (!gl->BlitHelper()->BlitImageToFramebuffer(mImage, dstSize, dstOrigin)) {
fallbackReason = "likely bug: failed to blit";
break;
@ -702,7 +700,7 @@ bool TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec,
"Failed to hit GPU-copy fast-path: %s (src type %u)", fallbackReason,
uint32_t(mImage->GetFormat()));
if (webgl->mPixelStore_RequireFastPath) {
if (webgl->mPixelStore.mRequireFastPath) {
webgl->ErrorInvalidOperation("%s", perfMsg.BeginReading());
return false;
}
@ -724,8 +722,8 @@ bool TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec,
return false;
}
const TexUnpackSurface surfBlob(webgl, target, mWidth, mHeight, mDepth,
dataSurf, mSrcAlphaType);
const TexUnpackSurface surfBlob(webgl->GetPixelStore(), target, mWidth,
mHeight, mDepth, dataSurf, mSrcAlphaType);
return surfBlob.TexOrSubImage(isSubImage, needsRespec, tex, target, level,
dui, xOffset, yOffset, zOffset, pi, out_error);
@ -735,21 +733,31 @@ bool TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec,
////////////////////////////////////////////////////////////////////////////////
// TexUnpackSurface
TexUnpackSurface::TexUnpackSurface(const WebGLContext* webgl,
TexUnpackSurface::TexUnpackSurface(const WebGLPixelStore& pixelStore,
TexImageTarget target, uint32_t width,
uint32_t height, uint32_t depth,
gfx::DataSourceSurface* surf,
gfxAlphaType srcAlphaType)
: TexUnpackBlob(webgl, target, surf->GetSize().width, width, height, depth,
srcAlphaType),
mSurf(surf) {}
: TexUnpackBlob(pixelStore, target, surf->GetSize().width, width, height,
depth, srcAlphaType),
mSize(surf->GetSize()),
mFormat(surf->GetFormat()),
mStride(0),
mMap(new gfx::DataSourceSurface::ScopedMap(
surf, gfx::DataSourceSurface::MapType::READ)) {
if ((!mMap) || (!mMap->IsMapped())) {
return;
}
mStride = mMap->GetStride();
mData = RawBuffer<>(mSize.height * mStride, mMap->GetData());
}
//////////
static bool GetFormatForSurf(gfx::SourceSurface* surf,
static bool GetFormatForSurf(gfx::SurfaceFormat surfFormat,
WebGLTexelFormat* const out_texelFormat,
uint8_t* const out_bpp) {
const auto surfFormat = surf->GetFormat();
switch (surfFormat) {
case gfx::SurfaceFormat::B8G8R8A8:
*out_texelFormat = WebGLTexelFormat::BGRA8;
@ -799,7 +807,7 @@ bool TexUnpackSurface::Validate(WebGLContext* webgl,
const webgl::PackingInfo& pi) {
if (!ValidatePIForDOM(webgl, pi)) return false;
const auto fullRows = mSurf->GetSize().height;
const auto fullRows = mSize.height;
return ValidateUnpackPixels(webgl, fullRows, 0, this);
}
@ -812,8 +820,8 @@ bool TexUnpackSurface::TexOrSubImage(
////
const auto rowLength = mSurf->GetSize().width;
const auto rowCount = mSurf->GetSize().height;
const auto rowLength = mSize.width;
const auto rowCount = mSize.height;
const auto& dstBPP = webgl::BytesPerPixel(dstPI);
const auto dstFormat = FormatForPackingInfo(dstPI);
@ -822,23 +830,17 @@ bool TexUnpackSurface::TexOrSubImage(
WebGLTexelFormat srcFormat;
uint8_t srcBPP;
if (!GetFormatForSurf(mSurf, &srcFormat, &srcBPP)) {
if (!GetFormatForSurf(mFormat, &srcFormat, &srcBPP)) {
webgl->ErrorImplementationBug(
"GetFormatForSurf failed for"
" WebGLTexelFormat::%u.",
uint32_t(mSurf->GetFormat()));
uint32_t(mFormat));
return false;
}
gfx::DataSourceSurface::ScopedMap map(mSurf,
gfx::DataSourceSurface::MapType::READ);
if (!map.IsMapped()) {
webgl->ErrorOutOfMemory("Failed to map source surface for upload.");
return false;
}
const auto& srcBegin = map.GetData();
const auto& srcStride = map.GetStride();
MOZ_ASSERT(mData && mStride);
const auto& srcBegin = mData.Data();
const auto& srcStride = mStride;
////
@ -885,14 +887,15 @@ bool TexUnpackSurface::TexOrSubImage(
yOffset, zOffset, mWidth, mHeight, mDepth, dstBegin);
gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
webgl->mPixelStore_UnpackAlignment);
webgl->mPixelStore.mUnpackAlignment);
if (webgl->IsWebGL2()) {
gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH,
webgl->mPixelStore_UnpackRowLength);
webgl->mPixelStore.mUnpackRowLength);
}
return true;
}
} // namespace webgl
} // namespace mozilla

Просмотреть файл

@ -13,6 +13,7 @@
namespace mozilla {
class ClientWebGLContext;
class UniqueBuffer;
class WebGLContext;
class WebGLTexture;
@ -23,6 +24,14 @@ class HTMLCanvasElement;
class HTMLVideoElement;
} // namespace dom
namespace ipc {
template <typename T>
struct PcqParamTraits;
class ConsumerView;
class ProducerView;
struct PcqStatus;
} // namespace ipc
namespace gfx {
class DataSourceSurface;
} // namespace gfx
@ -39,29 +48,28 @@ struct DriverUnpackInfo;
class TexUnpackBlob {
public:
const uint32_t mAlignment;
const uint32_t mRowLength;
const uint32_t mImageHeight;
const uint32_t mSkipPixels;
const uint32_t mSkipRows;
const uint32_t mSkipImages;
const uint32_t mWidth;
const uint32_t mHeight;
const uint32_t mDepth;
uint32_t mAlignment = 0;
uint32_t mRowLength = 0;
uint32_t mImageHeight = 0;
uint32_t mSkipPixels = 0;
uint32_t mSkipRows = 0;
uint32_t mSkipImages = 0;
uint32_t mWidth = 0;
uint32_t mHeight = 0;
uint32_t mDepth = 0;
const gfxAlphaType mSrcAlphaType;
gfxAlphaType mSrcAlphaType;
bool mNeedsExactUpload;
protected:
TexUnpackBlob(const WebGLContext* webgl, TexImageTarget target,
TexUnpackBlob(const WebGLPixelStore& pixelStore, TexImageTarget target,
uint32_t rowLength, uint32_t width, uint32_t height,
uint32_t depth, gfxAlphaType srcAlphaType);
public:
virtual ~TexUnpackBlob() {}
// For IPC
TexUnpackBlob() {}
protected:
bool ConvertIfNeeded(WebGLContext* webgl, const uint32_t rowLength,
const uint32_t rowCount, WebGLTexelFormat srcFormat,
const uint8_t* const srcBegin, const ptrdiff_t srcStride,
@ -71,6 +79,10 @@ class TexUnpackBlob {
UniqueBuffer* const out_anchoredBuffer) const;
public:
virtual ~TexUnpackBlob() {}
virtual TexUnpackBytes* AsTexUnpackBytes() { return nullptr; }
virtual bool HasData() const { return true; }
virtual bool Validate(WebGLContext* webgl, const webgl::PackingInfo& pi) = 0;
@ -88,15 +100,18 @@ class TexUnpackBlob {
class TexUnpackBytes final : public TexUnpackBlob {
public:
const bool mIsClientData;
const uint8_t* const mPtr;
const size_t mAvailBytes;
RawBuffer<const uint8_t> mPtr;
TexUnpackBytes(const WebGLContext* webgl, TexImageTarget target,
TexUnpackBytes(const WebGLPixelStore& pixelStore, TexImageTarget target,
uint32_t width, uint32_t height, uint32_t depth,
bool isClientData, const uint8_t* ptr, size_t availBytes);
virtual bool HasData() const override { return !mIsClientData || bool(mPtr); }
// For IPC
TexUnpackBytes() {}
TexUnpackBytes* AsTexUnpackBytes() override { return this; }
virtual bool HasData() const override { return mPtr && mPtr.Data(); }
virtual bool Validate(WebGLContext* webgl,
const webgl::PackingInfo& pi) override;
@ -110,11 +125,12 @@ class TexUnpackBytes final : public TexUnpackBlob {
class TexUnpackImage final : public TexUnpackBlob {
public:
const RefPtr<layers::Image> mImage;
RefPtr<layers::Image> mImage;
TexUnpackImage(const WebGLContext* webgl, TexImageTarget target,
uint32_t width, uint32_t height, uint32_t depth,
layers::Image* image, gfxAlphaType srcAlphaType);
uint32_t rowLength, uint32_t width, uint32_t height,
uint32_t depth, layers::Image* image,
gfxAlphaType srcAlphaType);
~TexUnpackImage(); // Prevent needing to define layers::Image in the header.
@ -128,14 +144,24 @@ class TexUnpackImage final : public TexUnpackBlob {
GLenum* const out_error) const override;
};
// If constructed from a surface, the surface is mapped as long as this object
// exists.
class TexUnpackSurface final : public TexUnpackBlob {
public:
const RefPtr<gfx::DataSourceSurface> mSurf;
gfx::IntSize mSize;
gfx::SurfaceFormat mFormat;
RawBuffer<> mData;
int32_t mStride;
// Map may be null in host process because memory is mapped in the client
UniquePtr<gfx::DataSourceSurface::ScopedMap> mMap;
TexUnpackSurface(const WebGLContext* webgl, TexImageTarget target,
TexUnpackSurface(const WebGLPixelStore& pixelStore, TexImageTarget target,
uint32_t width, uint32_t height, uint32_t depth,
gfx::DataSourceSurface* surf, gfxAlphaType srcAlphaType);
// For PcqParamTraits
TexUnpackSurface() : mStride(0), mMap(nullptr) {}
virtual bool Validate(WebGLContext* webgl,
const webgl::PackingInfo& pi) override;
virtual bool TexOrSubImage(bool isSubImage, bool needsRespec,
@ -147,6 +173,7 @@ class TexUnpackSurface final : public TexUnpackBlob {
};
} // namespace webgl
} // namespace mozilla
#endif // TEX_UNPACK_BLOB_H_

Просмотреть файл

@ -11,21 +11,9 @@
namespace mozilla {
/*static*/
WebGL1Context* WebGL1Context::Create() { return new WebGL1Context(); }
WebGL1Context::WebGL1Context() : WebGLContext() {}
WebGL1Context::~WebGL1Context() {}
UniquePtr<webgl::FormatUsageAuthority> WebGL1Context::CreateFormatUsage(
gl::GLContext* gl) const {
return webgl::FormatUsageAuthority::CreateForWebGL1(gl);
}
JSObject* WebGL1Context::WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto) {
return dom::WebGLRenderingContext_Binding::Wrap(cx, this, givenProto);
}
} // namespace mozilla

Просмотреть файл

@ -9,25 +9,22 @@
#include "WebGLContext.h"
namespace mozilla {
class HostWebGLContext;
class WebGL1Context : public WebGLContext {
public:
static WebGL1Context* Create();
static WebGL1Context* Create() { return new WebGL1Context(); }
private:
WebGL1Context();
WebGL1Context() {}
virtual UniquePtr<webgl::FormatUsageAuthority> CreateFormatUsage(
gl::GLContext* gl) const override;
public:
virtual ~WebGL1Context();
virtual ~WebGL1Context(){};
virtual bool IsWebGL2() const override { return false; }
// nsWrapperCache
virtual JSObject* WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto) override;
};
} // namespace mozilla

Просмотреть файл

@ -17,14 +17,6 @@
namespace mozilla {
WebGL2Context::WebGL2Context() : WebGLContext() {
MOZ_ASSERT(IsSupported(),
"not supposed to create a WebGL2Context"
"context when not supported");
}
WebGL2Context::~WebGL2Context() {}
UniquePtr<webgl::FormatUsageAuthority> WebGL2Context::CreateFormatUsage(
gl::GLContext* gl) const {
return webgl::FormatUsageAuthority::CreateForWebGL2(gl);
@ -33,14 +25,6 @@ UniquePtr<webgl::FormatUsageAuthority> WebGL2Context::CreateFormatUsage(
/*static*/
bool WebGL2Context::IsSupported() { return StaticPrefs::webgl_enable_webgl2(); }
/*static*/
WebGL2Context* WebGL2Context::Create() { return new WebGL2Context(); }
JSObject* WebGL2Context::WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto) {
return dom::WebGL2RenderingContext_Binding::Wrap(cx, this, givenProto);
}
////////////////////////////////////////////////////////////////////////////////
// WebGL 2 initialisation

Просмотреть файл

@ -11,6 +11,7 @@
namespace mozilla {
class ErrorResult;
class HostWebGLContext;
class WebGLSampler;
class WebGLSync;
class WebGLTransformFeedback;
@ -22,19 +23,13 @@ class OwningWebGLBufferOrLongLong;
class WebGL2Context : public WebGLContext {
public:
virtual ~WebGL2Context();
virtual ~WebGL2Context(){};
static bool IsSupported();
static WebGL2Context* Create();
static WebGL2Context* Create() { return new WebGL2Context(); }
virtual bool IsWebGL2() const override { return true; }
// -------------------------------------------------------------------------
// IMPLEMENT nsWrapperCache
virtual JSObject* WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto) override;
// -------------------------------------------------------------------------
// Buffer objects - WebGL2ContextBuffers.cpp
@ -48,9 +43,9 @@ class WebGL2Context : public WebGLContext {
const BufferT& data);
public:
void GetBufferSubData(GLenum target, WebGLintptr srcByteOffset,
const dom::ArrayBufferView& dstData,
GLuint dstElemOffset, GLuint dstElemCountOverride);
Maybe<UniquePtr<RawBuffer<>>> GetBufferSubData(GLenum target,
WebGLintptr srcByteOffset,
size_t byteLen);
// -------------------------------------------------------------------------
// Framebuffer objects - WebGL2ContextFramebuffers.cpp
@ -59,241 +54,39 @@ class WebGL2Context : public WebGLContext {
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
virtual JS::Value GetFramebufferAttachmentParameter(JSContext* cx,
GLenum target,
GLenum attachment,
GLenum pname,
ErrorResult& rv) override;
virtual MaybeWebGLVariant GetFramebufferAttachmentParameter(
GLenum target, GLenum attachment, GLenum pname) override;
// Make the inline version from the superclass visible here.
using WebGLContext::GetFramebufferAttachmentParameter;
void InvalidateFramebuffer(GLenum target,
const dom::Sequence<GLenum>& attachments,
ErrorResult& rv);
const nsTArray<GLenum>& attachments);
void InvalidateSubFramebuffer(GLenum target,
const dom::Sequence<GLenum>& attachments,
GLint x, GLint y, GLsizei width, GLsizei height,
ErrorResult& rv);
const nsTArray<GLenum>& attachments, GLint x,
GLint y, GLsizei width, GLsizei height);
void ReadBuffer(GLenum mode);
// -------------------------------------------------------------------------
// Renderbuffer objects - WebGL2ContextRenderbuffers.cpp
void GetInternalformatParameter(JSContext*, GLenum target,
GLenum internalformat, GLenum pname,
JS::MutableHandleValue retval,
ErrorResult& rv);
void RenderbufferStorageMultisample(GLenum target, GLsizei samples,
GLenum internalFormat, GLsizei width,
GLsizei height) {
const FuncScope funcScope(*this, "renderbufferStorageMultisample");
RenderbufferStorage_base(target, samples, internalFormat, width, height);
}
Maybe<nsTArray<int32_t>> GetInternalformatParameter(GLenum target,
GLenum internalformat,
GLenum pname);
// -------------------------------------------------------------------------
// Texture objects - WebGL2ContextTextures.cpp
void TexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat,
GLsizei width, GLsizei height) {
const FuncScope funcScope(*this, "TexStorage2D");
const uint8_t funcDims = 2;
const GLsizei depth = 1;
TexStorage(funcDims, target, levels, internalFormat, width, height, depth);
}
void TexStorage3D(GLenum target, GLsizei levels, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth) {
const FuncScope funcScope(*this, "TexStorage3D");
const uint8_t funcDims = 3;
TexStorage(funcDims, target, levels, internalFormat, width, height, depth);
}
protected:
void TexStorage(uint8_t funcDims, GLenum target, GLsizei levels,
GLenum internalFormat, GLsizei width, GLsizei height,
GLsizei depth);
////////////////////////////////////
public:
void CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLsizei imageSize,
WebGLintptr offset) {
const FuncScope funcScope(*this, "compressedTexImage3D");
const uint8_t funcDims = 3;
const TexImageSourceAdapter src(&offset, 0, 0);
CompressedTexImage(funcDims, target, level, internalFormat, width, height,
depth, border, src, Some(imageSize));
}
template <typename T>
void CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, const T& anySrc,
GLuint viewElemOffset = 0,
GLuint viewElemLengthOverride = 0) {
const FuncScope funcScope(*this, "compressedTexImage3D");
const uint8_t funcDims = 3;
const TexImageSourceAdapter src(&anySrc, viewElemOffset,
viewElemLengthOverride);
CompressedTexImage(funcDims, target, level, internalFormat, width, height,
depth, border, src, Nothing());
}
void CompressedTexSubImage3D(GLenum target, GLint level, GLint xOffset,
GLint yOffset, GLint zOffset, GLsizei width,
GLsizei height, GLsizei depth,
GLenum unpackFormat, GLsizei imageSize,
WebGLintptr offset) {
const FuncScope funcScope(*this, "compressedTexSubImage3D");
const uint8_t funcDims = 3;
const TexImageSourceAdapter src(&offset, 0, 0);
CompressedTexSubImage(funcDims, target, level, xOffset, yOffset, zOffset,
width, height, depth, unpackFormat, src,
Some(imageSize));
}
template <typename T>
void CompressedTexSubImage3D(GLenum target, GLint level, GLint xOffset,
GLint yOffset, GLint zOffset, GLsizei width,
GLsizei height, GLsizei depth,
GLenum unpackFormat, const T& anySrc,
GLuint viewElemOffset = 0,
GLuint viewElemLengthOverride = 0) {
const FuncScope funcScope(*this, "compressedTexSubImage3D");
const uint8_t funcDims = 3;
const TexImageSourceAdapter src(&anySrc, viewElemOffset,
viewElemLengthOverride);
CompressedTexSubImage(funcDims, target, level, xOffset, yOffset, zOffset,
width, height, depth, unpackFormat, src, Nothing());
}
////////////////////////////////////
void CopyTexSubImage3D(GLenum target, GLint level, GLint xOffset,
GLint yOffset, GLint zOffset, GLint x, GLint y,
GLsizei width, GLsizei height) {
const FuncScope funcScope(*this, "copyTexSubImage3D");
const uint8_t funcDims = 3;
CopyTexSubImage(funcDims, target, level, xOffset, yOffset, zOffset, x, y,
width, height);
}
////////////////////////////////////
template <typename T>
void TexImage3D(GLenum target, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth, GLint border,
GLenum unpackFormat, GLenum unpackType, const T& anySrc,
ErrorResult& out_error) {
const TexImageSourceAdapter src(&anySrc, &out_error);
TexImage3D(target, level, internalFormat, width, height, depth, border,
unpackFormat, unpackType, src);
}
void TexImage3D(GLenum target, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth, GLint border,
GLenum unpackFormat, GLenum unpackType,
const dom::ArrayBufferView& view, GLuint viewElemOffset,
ErrorResult&) {
const TexImageSourceAdapter src(&view, viewElemOffset);
TexImage3D(target, level, internalFormat, width, height, depth, border,
unpackFormat, unpackType, src);
}
protected:
void TexImage3D(GLenum target, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth, GLint border,
GLenum unpackFormat, GLenum unpackType,
const TexImageSource& src) {
const FuncScope funcScope(*this, "texImage3D");
const uint8_t funcDims = 3;
TexImage(funcDims, target, level, internalFormat, width, height, depth,
border, unpackFormat, unpackType, src);
}
////////////////////////////////////
public:
template <typename T>
void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
GLint zOffset, GLsizei width, GLsizei height,
GLsizei depth, GLenum unpackFormat, GLenum unpackType,
const T& anySrc, ErrorResult& out_error) {
const TexImageSourceAdapter src(&anySrc, &out_error);
TexSubImage3D(target, level, xOffset, yOffset, zOffset, width, height,
depth, unpackFormat, unpackType, src);
}
void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
GLint zOffset, GLsizei width, GLsizei height,
GLsizei depth, GLenum unpackFormat, GLenum unpackType,
const dom::Nullable<dom::ArrayBufferView>& maybeSrcView,
GLuint srcElemOffset, ErrorResult&) {
const FuncScope funcScope(*this, "texSubImage3D");
if (IsContextLost()) return;
if (!ValidateNonNull("src", maybeSrcView)) return;
const auto& srcView = maybeSrcView.Value();
const TexImageSourceAdapter src(&srcView, srcElemOffset);
TexSubImage3D(target, level, xOffset, yOffset, zOffset, width, height,
depth, unpackFormat, unpackType, src);
}
protected:
void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset,
GLint zOffset, GLsizei width, GLsizei height,
GLsizei depth, GLenum unpackFormat, GLenum unpackType,
const TexImageSource& src) {
const FuncScope funcScope(*this, "texSubImage3D");
const uint8_t funcDims = 3;
TexSubImage(funcDims, target, level, xOffset, yOffset, zOffset, width,
height, depth, unpackFormat, unpackType, src);
}
public:
// -------------------------------------------------------------------------
// Programs and shaders - WebGL2ContextPrograms.cpp
GLint GetFragDataLocation(const WebGLProgram& program, const nsAString& name);
// -------------------------------------------------------------------------
// Uniforms and attributes - WebGL2ContextUniforms.cpp
void VertexAttribIPointer(GLuint index, GLint size, GLenum type,
GLsizei stride, WebGLintptr byteOffset) {
const FuncScope funcScope(*this, "vertexAttribIPointer");
const bool isFuncInt = true;
const bool normalized = false;
VertexAttribAnyPointer(isFuncInt, index, size, type, normalized, stride,
byteOffset);
}
////////////////
GLint GetFragDataLocation(const WebGLProgram& prog, const nsAString& name);
// GL 3.0 & ES 3.0
void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
void VertexAttribI4iv(GLuint index, const Int32ListU& list) {
const FuncScope funcScope(*this, "VertexAttribI4iv");
const auto& arr = Int32Arr::From(list);
if (!ValidateAttribArraySetter(4, arr.elemCount)) return;
const auto& itr = arr.elemBytes;
VertexAttribI4i(index, itr[0], itr[1], itr[2], itr[3]);
}
void VertexAttribI4uiv(GLuint index, const Uint32ListU& list) {
const FuncScope funcScope(*this, "vertexAttribI4uiv");
const auto& arr = Uint32Arr::From(list);
if (!ValidateAttribArraySetter(4, arr.elemCount)) return;
const auto& itr = arr.elemBytes;
VertexAttribI4ui(index, itr[0], itr[1], itr[2], itr[3]);
}
// -------------------------------------------------------------------------
// Writing to the drawing buffer
@ -315,13 +108,13 @@ class WebGL2Context : public WebGLContext {
return;
}
DrawElements(mode, count, type, byteOffset);
DrawElementsInstanced(mode, count, type, byteOffset, 1);
}
// ------------------------------------------------------------------------
// Multiple Render Targets - WebGL2ContextMRTs.cpp
/* Implemented in WebGLContext
void DrawBuffers(const dom::Sequence<GLenum>& buffers);
void DrawBuffers(const nsTArray<GLenum>& buffers);
*/
private:
@ -329,29 +122,16 @@ class WebGL2Context : public WebGLContext {
size_t availElemCount, GLuint elemOffset,
GLenum funcType);
void ClearBufferfv(GLenum buffer, GLint drawBuffer, const Float32Arr& src,
GLuint srcElemOffset);
void ClearBufferiv(GLenum buffer, GLint drawBuffer, const Int32Arr& src,
GLuint srcElemOffset);
void ClearBufferuiv(GLenum buffer, GLint drawBuffer, const Uint32Arr& src,
GLuint srcElemOffset);
public:
void ClearBufferfv(GLenum buffer, GLint drawBuffer, const Float32ListU& list,
GLuint srcElemOffset) {
ClearBufferfv(buffer, drawBuffer, Float32Arr::From(list), srcElemOffset);
}
void ClearBufferiv(GLenum buffer, GLint drawBuffer, const Int32ListU& list,
GLuint srcElemOffset) {
ClearBufferiv(buffer, drawBuffer, Int32Arr::From(list), srcElemOffset);
}
void ClearBufferuiv(GLenum buffer, GLint drawBuffer, const Uint32ListU& list,
GLuint srcElemOffset) {
ClearBufferuiv(buffer, drawBuffer, Uint32Arr::From(list), srcElemOffset);
}
void ClearBufferfi(GLenum buffer, GLint drawBuffer, GLfloat depth,
GLint stencil);
void ClearBufferfv(GLenum buffer, GLint drawBuffer,
const RawBuffer<const float>& src, GLuint srcElemOffset);
void ClearBufferiv(GLenum buffer, GLint drawBuffer,
const RawBuffer<const int32_t>& src, GLuint srcElemOffset);
void ClearBufferuiv(GLenum buffer, GLint drawBuffer,
const RawBuffer<const uint32_t>& src,
GLuint srcElemOffset);
// -------------------------------------------------------------------------
// Sampler Objects - WebGL2ContextSamplers.cpp
@ -362,8 +142,8 @@ class WebGL2Context : public WebGLContext {
void BindSampler(GLuint unit, WebGLSampler* sampler);
void SamplerParameteri(WebGLSampler& sampler, GLenum pname, GLint param);
void SamplerParameterf(WebGLSampler& sampler, GLenum pname, GLfloat param);
void GetSamplerParameter(JSContext*, const WebGLSampler& sampler,
GLenum pname, JS::MutableHandleValue retval);
MaybeWebGLVariant GetSamplerParameter(const WebGLSampler& sampler,
GLenum pname);
// -------------------------------------------------------------------------
// Sync objects - WebGL2ContextSync.cpp
@ -377,8 +157,7 @@ class WebGL2Context : public WebGLContext {
GLenum ClientWaitSync(const WebGLSync& sync, GLbitfield flags,
GLuint64 timeout);
void WaitSync(const WebGLSync& sync, GLbitfield flags, GLint64 timeout);
void GetSyncParameter(JSContext*, const WebGLSync& sync, GLenum pname,
JS::MutableHandleValue retval);
MaybeWebGLVariant GetSyncParameter(const WebGLSync& sync, GLenum pname);
// -------------------------------------------------------------------------
// Transform Feedback - WebGL2ContextTransformFeedback.cpp
@ -392,9 +171,9 @@ class WebGL2Context : public WebGLContext {
void PauseTransformFeedback();
void ResumeTransformFeedback();
void TransformFeedbackVaryings(WebGLProgram& program,
const dom::Sequence<nsString>& varyings,
const nsTArray<nsString>& varyings,
GLenum bufferMode);
already_AddRefed<WebGLActiveInfo> GetTransformFeedbackVarying(
Maybe<WebGLActiveInfo> GetTransformFeedbackVarying(
const WebGLProgram& program, GLuint index);
// -------------------------------------------------------------------------
@ -406,27 +185,24 @@ class WebGL2Context : public WebGLContext {
void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
WebGLintptr offset, WebGLsizeiptr size);
*/
virtual JS::Value GetParameter(JSContext* cx, GLenum pname,
ErrorResult& rv) override;
MaybeWebGLVariant GetParameter(GLenum pname) override;
// Make the inline version from the superclass visible here.
using WebGLContext::GetParameter;
void GetIndexedParameter(JSContext* cx, GLenum target, GLuint index,
JS::MutableHandleValue retval, ErrorResult& rv);
void GetUniformIndices(const WebGLProgram& program,
const dom::Sequence<nsString>& uniformNames,
dom::Nullable<nsTArray<GLuint> >& retval);
void GetActiveUniforms(JSContext* cx, const WebGLProgram& program,
const dom::Sequence<GLuint>& uniformIndices,
GLenum pname, JS::MutableHandleValue retval);
MaybeWebGLVariant GetIndexedParameter(GLenum target, GLuint index);
MaybeWebGLVariant GetUniformIndices(const WebGLProgram& program,
const nsTArray<nsString>& uniformNames);
MaybeWebGLVariant GetActiveUniforms(const WebGLProgram& program,
const nsTArray<GLuint>& uniformIndices,
GLenum pname);
GLuint GetUniformBlockIndex(const WebGLProgram& program,
const nsAString& uniformBlockName);
void GetActiveUniformBlockParameter(JSContext*, const WebGLProgram& program,
GLuint uniformBlockIndex, GLenum pname,
JS::MutableHandleValue retval,
ErrorResult& rv);
void GetActiveUniformBlockName(const WebGLProgram& program,
GLuint uniformBlockIndex, nsAString& retval);
MaybeWebGLVariant GetActiveUniformBlockParameter(const WebGLProgram& program,
GLuint uniformBlockIndex,
GLenum pname);
nsString GetActiveUniformBlockName(const WebGLProgram& program,
GLuint uniformBlockIndex);
void UniformBlockBinding(WebGLProgram& program, GLuint uniformBlockIndex,
GLuint uniformBlockBinding);
@ -441,7 +217,12 @@ class WebGL2Context : public WebGLContext {
*/
private:
WebGL2Context();
WebGL2Context() {
MOZ_ASSERT(IsSupported(),
"not supposed to create a WebGL2Context"
"context when not supported");
}
virtual UniquePtr<webgl::FormatUsageAuthority> CreateFormatUsage(
gl::GLContext* gl) const override;

Просмотреть файл

@ -5,6 +5,7 @@
#include "WebGL2Context.h"
#include "ClientWebGLContext.h"
#include "GLContext.h"
#include "WebGLBuffer.h"
#include "WebGLTransformFeedback.h"
@ -84,35 +85,22 @@ void WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
writeBuffer->ResetLastUpdateFenceId();
}
void WebGL2Context::GetBufferSubData(GLenum target, WebGLintptr srcByteOffset,
const dom::ArrayBufferView& dstData,
GLuint dstElemOffset,
GLuint dstElemCountOverride) {
Maybe<UniquePtr<RawBuffer<>>> WebGL2Context::GetBufferSubData(
GLenum target, WebGLintptr srcByteOffset, size_t byteLen) {
const FuncScope funcScope(*this, "getBufferSubData");
if (IsContextLost()) return;
if (!ValidateNonNegative("srcByteOffset", srcByteOffset)) return;
uint8_t* bytes;
size_t byteLen;
if (!ValidateArrayBufferView(dstData, dstElemOffset, dstElemCountOverride,
LOCAL_GL_INVALID_VALUE, &bytes, &byteLen)) {
return;
}
////
if (IsContextLost()) return Nothing();
const auto& buffer = ValidateBufferSelection(target);
if (!buffer) return;
if (!buffer) return Nothing();
if (!buffer->ValidateRange(srcByteOffset, byteLen)) return;
if (!buffer->ValidateRange(srcByteOffset, byteLen)) return Nothing();
////
if (!CheckedInt<GLintptr>(srcByteOffset).isValid() ||
!CheckedInt<GLsizeiptr>(byteLen).isValid()) {
ErrorOutOfMemory("offset or size too large for platform.");
return;
return Nothing();
}
const GLsizeiptr glByteLen(byteLen);
@ -138,6 +126,12 @@ void WebGL2Context::GetBufferSubData(GLenum target, WebGLintptr srcByteOffset,
////
uint8_t* bytes = new uint8_t[byteLen];
if (!bytes) {
ErrorOutOfMemory("Could not allocate temp array");
return Nothing();
}
const ScopedLazyBind readBind(gl, target, buffer);
if (byteLen) {
@ -162,6 +156,9 @@ void WebGL2Context::GetBufferSubData(GLenum target, WebGLintptr srcByteOffset,
gl->fBindTransformFeedback(LOCAL_GL_TRANSFORM_FEEDBACK, tfo);
}
}
UniquePtr<RawBuffer<>> ret = MakeUnique<RawBuffer<>>(byteLen, bytes, true);
return Some(std::move(ret));
}
} // namespace mozilla

Просмотреть файл

@ -66,13 +66,6 @@ void WebGL2Context::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1,
dstY0, dstX1, dstY1, mask, filter);
}
JS::Value WebGL2Context::GetFramebufferAttachmentParameter(
JSContext* cx, GLenum target, GLenum attachment, GLenum pname,
ErrorResult& out_error) {
return WebGLContext::GetFramebufferAttachmentParameter(cx, target, attachment,
pname, out_error);
}
////
static bool ValidateBackbufferAttachmentEnum(WebGLContext* webgl,
@ -113,8 +106,8 @@ static bool ValidateFramebufferAttachmentEnum(WebGLContext* webgl,
}
bool WebGLContext::ValidateInvalidateFramebuffer(
GLenum target, const dom::Sequence<GLenum>& attachments,
ErrorResult* const out_rv, std::vector<GLenum>* const scopedVector,
GLenum target, const nsTArray<GLenum>& attachments,
std::vector<GLenum>* const scopedVector,
GLsizei* const out_glNumAttachments,
const GLenum** const out_glAttachments) {
if (IsContextLost()) return false;
@ -189,14 +182,14 @@ bool WebGLContext::ValidateInvalidateFramebuffer(
return true;
}
void WebGL2Context::InvalidateFramebuffer(
GLenum target, const dom::Sequence<GLenum>& attachments, ErrorResult& rv) {
void WebGL2Context::InvalidateFramebuffer(GLenum target,
const nsTArray<GLenum>& attachments) {
const FuncScope funcScope(*this, "invalidateFramebuffer");
std::vector<GLenum> scopedVector;
GLsizei glNumAttachments;
const GLenum* glAttachments;
if (!ValidateInvalidateFramebuffer(target, attachments, &rv, &scopedVector,
if (!ValidateInvalidateFramebuffer(target, attachments, &scopedVector,
&glNumAttachments, &glAttachments)) {
return;
}
@ -217,14 +210,14 @@ void WebGL2Context::InvalidateFramebuffer(
}
void WebGL2Context::InvalidateSubFramebuffer(
GLenum target, const dom::Sequence<GLenum>& attachments, GLint x, GLint y,
GLsizei width, GLsizei height, ErrorResult& rv) {
GLenum target, const nsTArray<GLenum>& attachments, GLint x, GLint y,
GLsizei width, GLsizei height) {
const FuncScope funcScope(*this, "invalidateSubFramebuffer");
std::vector<GLenum> scopedVector;
GLsizei glNumAttachments;
const GLenum* glAttachments;
if (!ValidateInvalidateFramebuffer(target, attachments, &rv, &scopedVector,
if (!ValidateInvalidateFramebuffer(target, attachments, &scopedVector,
&glNumAttachments, &glAttachments)) {
return;
}

Просмотреть файл

@ -86,7 +86,8 @@ bool WebGL2Context::ValidateClearBuffer(GLenum buffer, GLint drawBuffer,
////
void WebGL2Context::ClearBufferfv(GLenum buffer, GLint drawBuffer,
const Float32Arr& src, GLuint srcElemOffset) {
const RawBuffer<const float>& src,
GLuint srcElemOffset) {
const FuncScope funcScope(*this, "clearBufferfv");
if (IsContextLost()) return;
@ -95,7 +96,7 @@ void WebGL2Context::ClearBufferfv(GLenum buffer, GLint drawBuffer,
return;
}
if (!ValidateClearBuffer(buffer, drawBuffer, src.elemCount, srcElemOffset,
if (!ValidateClearBuffer(buffer, drawBuffer, src.Length(), srcElemOffset,
LOCAL_GL_FLOAT)) {
return;
}
@ -105,12 +106,13 @@ void WebGL2Context::ClearBufferfv(GLenum buffer, GLint drawBuffer,
}
ScopedDrawCallWrapper wrapper(*this);
const auto ptr = src.elemBytes + srcElemOffset;
const auto ptr = &src[0] + srcElemOffset;
gl->fClearBufferfv(buffer, drawBuffer, ptr);
}
void WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawBuffer,
const Int32Arr& src, GLuint srcElemOffset) {
const RawBuffer<const int32_t>& src,
GLuint srcElemOffset) {
const FuncScope funcScope(*this, "clearBufferiv");
if (IsContextLost()) return;
@ -119,7 +121,7 @@ void WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawBuffer,
return;
}
if (!ValidateClearBuffer(buffer, drawBuffer, src.elemCount, srcElemOffset,
if (!ValidateClearBuffer(buffer, drawBuffer, src.Length(), srcElemOffset,
LOCAL_GL_INT)) {
return;
}
@ -130,25 +132,26 @@ void WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawBuffer,
}
ScopedDrawCallWrapper wrapper(*this);
const auto ptr = src.elemBytes + srcElemOffset;
const auto ptr = &src[0] + srcElemOffset;
gl->fClearBufferiv(buffer, drawBuffer, ptr);
}
void WebGL2Context::ClearBufferuiv(GLenum buffer, GLint drawBuffer,
const Uint32Arr& src, GLuint srcElemOffset) {
const RawBuffer<const uint32_t>& src,
GLuint srcElemOffset) {
const FuncScope funcScope(*this, "clearBufferuiv");
if (IsContextLost()) return;
if (buffer != LOCAL_GL_COLOR)
return ErrorInvalidEnum("`buffer` must be COLOR.");
if (!ValidateClearBuffer(buffer, drawBuffer, src.elemCount, srcElemOffset,
if (!ValidateClearBuffer(buffer, drawBuffer, src.Length(), srcElemOffset,
LOCAL_GL_UNSIGNED_INT)) {
return;
}
ScopedDrawCallWrapper wrapper(*this);
const auto ptr = src.elemBytes + srcElemOffset;
const auto ptr = &src[0] + srcElemOffset;
gl->fClearBufferuiv(buffer, drawBuffer, ptr);
}

Просмотреть файл

@ -98,12 +98,10 @@ void WebGLContext::EndQuery(GLenum target) {
query->EndQuery();
}
void WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval) {
MaybeWebGLVariant WebGLContext::GetQuery(GLenum target, GLenum pname) {
const FuncScope funcScope(*this, "getQuery");
retval.setNull();
if (IsContextLost()) return;
if (IsContextLost()) return Nothing();
switch (pname) {
case LOCAL_GL_CURRENT_QUERY_EXT: {
@ -112,20 +110,17 @@ void WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname,
// Doesn't seem illegal to ask about, but is always null.
// TIMESTAMP has no slot, so ValidateQuerySlotByTarget would generate
// INVALID_ENUM.
return;
return Nothing();
}
const auto& slot = ValidateQuerySlotByTarget(target);
if (!slot || !*slot) return;
if (!slot || !*slot) return Nothing();
const auto& query = *slot;
if (target != query->Target()) return;
if (target != query->Target()) return Nothing();
JS::Rooted<JS::Value> v(cx);
dom::GetOrCreateDOMReflector(cx, slot->get(), &v);
retval.set(v);
return AsSomeVariant(std::move(query));
}
return;
case LOCAL_GL_QUERY_COUNTER_BITS_EXT:
if (!IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query))
@ -134,7 +129,7 @@ void WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname,
if (target != LOCAL_GL_TIME_ELAPSED_EXT &&
target != LOCAL_GL_TIMESTAMP_EXT) {
ErrorInvalidEnumInfo("target", target);
return;
return Nothing();
}
{
@ -144,27 +139,25 @@ void WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname,
if (!Has64BitTimestamps() && bits > 32) {
bits = 32;
}
retval.set(JS::Int32Value(bits));
return AsSomeVariant(bits);
}
return;
default:
break;
}
ErrorInvalidEnumInfo("pname", pname);
return Nothing();
}
void WebGLContext::GetQueryParameter(JSContext*, const WebGLQuery& query,
GLenum pname,
JS::MutableHandleValue retval) {
MaybeWebGLVariant WebGLContext::GetQueryParameter(const WebGLQuery& query,
GLenum pname) {
const FuncScope funcScope(*this, "getQueryParameter");
retval.setNull();
if (IsContextLost()) return;
if (IsContextLost()) return Nothing();
if (!ValidateObject("query", query)) return;
if (!ValidateObject("query", query)) return Nothing();
query.GetQueryParameter(pname, retval);
return query.GetQueryParameter(pname);
}
} // namespace mozilla

Просмотреть файл

@ -12,19 +12,14 @@
namespace mozilla {
void WebGL2Context::GetInternalformatParameter(JSContext* cx, GLenum target,
GLenum internalformat,
GLenum pname,
JS::MutableHandleValue retval,
ErrorResult& out_rv) {
Maybe<nsTArray<int32_t>> WebGL2Context::GetInternalformatParameter(
GLenum target, GLenum internalformat, GLenum pname) {
const FuncScope funcScope(*this, "getInternalfomratParameter");
retval.setObjectOrNull(nullptr);
if (IsContextLost()) return;
if (IsContextLost()) return Nothing();
if (target != LOCAL_GL_RENDERBUFFER) {
ErrorInvalidEnum("`target` must be RENDERBUFFER.");
return;
return Nothing();
}
// GLES 3.0.4 $4.4.4 p212:
@ -55,31 +50,31 @@ void WebGL2Context::GetInternalformatParameter(JSContext* cx, GLenum target,
"`internalformat` must be color-, depth-, or stencil-renderable, was: "
"0x%04x.",
internalformat);
return;
return Nothing();
}
if (pname != LOCAL_GL_SAMPLES) {
ErrorInvalidEnum("`pname` must be SAMPLES.");
return;
}
std::vector<GLint> samples;
const auto maxSamples = usage->MaxSamples(*gl);
if (maxSamples) { // It might be force-set to 0 for validation reasons!
GLint sampleCount = 0;
gl->fGetInternalformativ(LOCAL_GL_RENDERBUFFER, internalformat,
LOCAL_GL_NUM_SAMPLE_COUNTS, 1, &sampleCount);
samples.resize(uint32_t(sampleCount));
gl->fGetInternalformativ(LOCAL_GL_RENDERBUFFER, internalformat,
LOCAL_GL_SAMPLES, samples.size(), samples.data());
return Nothing();
}
JSObject* obj =
dom::Int32Array::Create(cx, this, samples.size(), samples.data());
if (!obj) {
out_rv = NS_ERROR_OUT_OF_MEMORY;
nsTArray<int32_t> obj;
GLint sampleCount = 0;
gl->fGetInternalformativ(LOCAL_GL_RENDERBUFFER, internalformat,
LOCAL_GL_NUM_SAMPLE_COUNTS, 1, &sampleCount);
if (sampleCount > 0) {
GLint* samples =
static_cast<GLint*>(obj.AppendElements(sampleCount, fallible));
// If we don't have 'samples' then we will return a zero-length array, which
// will be interpreted by the ClientWebGLContext as an out-of-memory
// condition.
if (samples) {
gl->fGetInternalformativ(LOCAL_GL_RENDERBUFFER, internalformat,
LOCAL_GL_SAMPLES, sampleCount, samples);
}
}
retval.setObjectOrNull(obj);
return Some(obj);
}
} // namespace mozilla

Просмотреть файл

@ -75,15 +75,12 @@ void WebGL2Context::SamplerParameterf(WebGLSampler& sampler, GLenum pname,
sampler.SamplerParameter(pname, FloatOrInt(param));
}
void WebGL2Context::GetSamplerParameter(JSContext*, const WebGLSampler& sampler,
GLenum pname,
JS::MutableHandleValue retval) {
MaybeWebGLVariant WebGL2Context::GetSamplerParameter(
const WebGLSampler& sampler, GLenum pname) {
const FuncScope funcScope(*this, "getSamplerParameter");
retval.setNull();
if (IsContextLost()) return Nothing();
if (IsContextLost()) return;
if (!ValidateObject("sampler", sampler)) return;
if (!ValidateObject("sampler", sampler)) return Nothing();
////
@ -97,21 +94,18 @@ void WebGL2Context::GetSamplerParameter(JSContext*, const WebGLSampler& sampler,
case LOCAL_GL_TEXTURE_COMPARE_FUNC: {
GLint param = 0;
gl->fGetSamplerParameteriv(sampler.mGLName, pname, &param);
retval.set(JS::Int32Value(param));
return AsSomeVariant(param);
}
return;
case LOCAL_GL_TEXTURE_MIN_LOD:
case LOCAL_GL_TEXTURE_MAX_LOD: {
GLfloat param = 0;
gl->fGetSamplerParameterfv(sampler.mGLName, pname, &param);
retval.set(JS::Float32Value(param));
return AsSomeVariant(param);
}
return;
default:
ErrorInvalidEnumInfo("pname", pname);
return;
return Nothing();
}
}

Просмотреть файл

@ -16,15 +16,14 @@
namespace mozilla {
JS::Value WebGL2Context::GetParameter(JSContext* cx, GLenum pname,
ErrorResult& rv) {
MaybeWebGLVariant WebGL2Context::GetParameter(GLenum pname) {
const FuncScope funcScope(*this, "getParameter");
// The following cases are handled in WebGLContext::GetParameter():
// case LOCAL_GL_MAX_COLOR_ATTACHMENTS:
// case LOCAL_GL_MAX_DRAW_BUFFERS:
// case LOCAL_GL_DRAW_BUFFERi:
if (IsContextLost()) return JS::NullValue();
if (IsContextLost()) return Nothing();
switch (pname) {
/* GLboolean */
@ -33,23 +32,24 @@ JS::Value WebGL2Context::GetParameter(JSContext* cx, GLenum pname,
case LOCAL_GL_SAMPLE_COVERAGE: {
realGLboolean b = 0;
gl->fGetBooleanv(pname, &b);
return JS::BooleanValue(bool(b));
return AsSomeVariant(bool(b));
}
case LOCAL_GL_TRANSFORM_FEEDBACK_ACTIVE:
return JS::BooleanValue(mBoundTransformFeedback->mIsActive);
return AsSomeVariant(mBoundTransformFeedback->mIsActive);
case LOCAL_GL_TRANSFORM_FEEDBACK_PAUSED:
return JS::BooleanValue(mBoundTransformFeedback->mIsPaused);
return AsSomeVariant(mBoundTransformFeedback->mIsPaused);
/* GLenum */
case LOCAL_GL_READ_BUFFER: {
if (!mBoundReadFramebuffer) return JS::Int32Value(mDefaultFB_ReadBuffer);
if (!mBoundReadFramebuffer)
return AsSomeVariant(std::move(mDefaultFB_ReadBuffer));
if (!mBoundReadFramebuffer->ColorReadBuffer())
return JS::Int32Value(LOCAL_GL_NONE);
return AsSomeVariant(LOCAL_GL_NONE);
return JS::Int32Value(
mBoundReadFramebuffer->ColorReadBuffer()->mAttachmentPoint);
return AsSomeVariant(std::move(
mBoundReadFramebuffer->ColorReadBuffer()->mAttachmentPoint));
}
case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
@ -81,41 +81,41 @@ JS::Value WebGL2Context::GetParameter(JSContext* cx, GLenum pname,
case LOCAL_GL_UNPACK_ROW_LENGTH: {
GLint val;
gl->fGetIntegerv(pname, &val);
return JS::Int32Value(val);
return AsSomeVariant(val);
}
case LOCAL_GL_UNPACK_SKIP_IMAGES:
return JS::Int32Value(mPixelStore_UnpackSkipImages);
return AsSomeVariant(mPixelStore.mUnpackSkipImages);
case LOCAL_GL_UNPACK_SKIP_PIXELS:
return JS::Int32Value(mPixelStore_UnpackSkipPixels);
return AsSomeVariant(mPixelStore.mUnpackSkipPixels);
case LOCAL_GL_UNPACK_SKIP_ROWS:
return JS::Int32Value(mPixelStore_UnpackSkipRows);
return AsSomeVariant(mPixelStore.mUnpackSkipRows);
case LOCAL_GL_MAX_3D_TEXTURE_SIZE:
return JS::Int32Value(mGLMax3DTextureSize);
return AsSomeVariant(mGLMax3DTextureSize);
case LOCAL_GL_MAX_ARRAY_TEXTURE_LAYERS:
return JS::Int32Value(mGLMaxArrayTextureLayers);
return AsSomeVariant(mGLMaxArrayTextureLayers);
case LOCAL_GL_MAX_VARYING_COMPONENTS: {
// On OS X Core Profile this is buggy. The spec says that the
// value is 4 * GL_MAX_VARYING_VECTORS
GLint val;
gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, &val);
return JS::Int32Value(4 * val);
return AsSomeVariant(4 * val);
}
/* GLint64 */
case LOCAL_GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL:
return JS::NumberValue(kMaxClientWaitSyncTimeoutNS);
return AsSomeVariant(kMaxClientWaitSyncTimeoutNS);
case LOCAL_GL_MAX_ELEMENT_INDEX:
// GL_MAX_ELEMENT_INDEX becomes available in GL 4.3 or via ES3
// compatibility
if (!gl->IsSupported(gl::GLFeature::ES3_compatibility))
return JS::NumberValue(UINT32_MAX);
return AsSomeVariant(UINT32_MAX);
/*** fall through to fGetInteger64v ***/
[[fallthrough]];
@ -125,72 +125,71 @@ JS::Value WebGL2Context::GetParameter(JSContext* cx, GLenum pname,
case LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE: {
GLint64 val;
gl->fGetInteger64v(pname, &val);
return JS::DoubleValue(static_cast<double>(val));
return AsSomeVariant(static_cast<double>(val));
}
/* GLuint64 */
case LOCAL_GL_MAX_SERVER_WAIT_TIMEOUT: {
GLuint64 val;
gl->fGetInteger64v(pname, (GLint64*)&val);
return JS::DoubleValue(static_cast<double>(val));
return AsSomeVariant(static_cast<double>(val));
}
case LOCAL_GL_COPY_READ_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundCopyReadBuffer.get(), rv);
return AsSomeVariant(std::move(mBoundCopyReadBuffer.get()));
case LOCAL_GL_COPY_WRITE_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundCopyWriteBuffer.get(), rv);
return AsSomeVariant(std::move(mBoundCopyWriteBuffer.get()));
case LOCAL_GL_PIXEL_PACK_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundPixelPackBuffer.get(), rv);
return AsSomeVariant(std::move(mBoundPixelPackBuffer.get()));
case LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundPixelUnpackBuffer.get(), rv);
return AsSomeVariant(std::move(mBoundPixelUnpackBuffer.get()));
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundTransformFeedbackBuffer.get(), rv);
return AsSomeVariant(std::move(mBoundTransformFeedbackBuffer.get()));
case LOCAL_GL_UNIFORM_BUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundUniformBuffer.get(), rv);
return AsSomeVariant(std::move(mBoundUniformBuffer.get()));
// DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
case LOCAL_GL_READ_FRAMEBUFFER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundReadFramebuffer.get(), rv);
return AsSomeVariant(std::move(mBoundReadFramebuffer.get()));
case LOCAL_GL_SAMPLER_BINDING:
return WebGLObjectAsJSValue(cx, mBoundSamplers[mActiveTexture].get(), rv);
return AsSomeVariant(std::move(mBoundSamplers[mActiveTexture].get()));
case LOCAL_GL_TEXTURE_BINDING_2D_ARRAY:
return WebGLObjectAsJSValue(
cx, mBound2DArrayTextures[mActiveTexture].get(), rv);
return AsSomeVariant(
std::move(mBound2DArrayTextures[mActiveTexture].get()));
case LOCAL_GL_TEXTURE_BINDING_3D:
return WebGLObjectAsJSValue(cx, mBound3DTextures[mActiveTexture].get(),
rv);
return AsSomeVariant(std::move(mBound3DTextures[mActiveTexture].get()));
case LOCAL_GL_TRANSFORM_FEEDBACK_BINDING: {
const WebGLTransformFeedback* tf = mBoundTransformFeedback;
WebGLTransformFeedback* tf = mBoundTransformFeedback;
if (tf == mDefaultTransformFeedback) {
tf = nullptr;
}
return WebGLObjectAsJSValue(cx, tf, rv);
return AsSomeVariant(std::move(tf));
}
case LOCAL_GL_VERTEX_ARRAY_BINDING: {
WebGLVertexArray* vao = (mBoundVertexArray != mDefaultVertexArray)
? mBoundVertexArray.get()
: nullptr;
return WebGLObjectAsJSValue(cx, vao, rv);
return AsSomeVariant(std::move(vao));
}
case LOCAL_GL_VERSION:
return StringValue(cx, "WebGL 2.0", rv);
return AsSomeVariant(nsCString("WebGL 2.0"));
case LOCAL_GL_SHADING_LANGUAGE_VERSION:
return StringValue(cx, "WebGL GLSL ES 3.00", rv);
return AsSomeVariant(nsCString("WebGL GLSL ES 3.00"));
default:
return WebGLContext::GetParameter(cx, pname, rv);
return WebGLContext::GetParameter(pname);
}
}

Просмотреть файл

@ -107,22 +107,19 @@ void WebGL2Context::WaitSync(const WebGLSync& sync, GLbitfield flags,
gl->fWaitSync(sync.mGLName, flags, LOCAL_GL_TIMEOUT_IGNORED);
}
void WebGL2Context::GetSyncParameter(JSContext*, const WebGLSync& sync,
GLenum pname,
JS::MutableHandleValue retval) {
MaybeWebGLVariant WebGL2Context::GetSyncParameter(const WebGLSync& sync,
GLenum pname) {
const FuncScope funcScope(*this, "getSyncParameter");
retval.setNull();
if (IsContextLost()) return;
if (IsContextLost()) return Nothing();
if (!ValidateObject("sync", sync)) return;
if (!ValidateObject("sync", sync)) return Nothing();
////
const bool canBeAvailable =
(sync.mCanBeAvailable || StaticPrefs::webgl_allow_immediate_queries());
if (!canBeAvailable && pname == LOCAL_GL_SYNC_STATUS) {
retval.set(JS::Int32Value(LOCAL_GL_UNSIGNALED));
return;
return AsSomeVariant(LOCAL_GL_UNSIGNALED);
}
GLint result = 0;
@ -137,12 +134,11 @@ void WebGL2Context::GetSyncParameter(JSContext*, const WebGLSync& sync,
sync.MarkSignaled();
}
retval.set(JS::Int32Value(result));
return;
return AsSomeVariant(result);
default:
ErrorInvalidEnumInfo("pname", pname);
return;
return Nothing();
}
}

Просмотреть файл

@ -110,7 +110,7 @@ void WebGL2Context::ResumeTransformFeedback() {
}
void WebGL2Context::TransformFeedbackVaryings(
WebGLProgram& program, const dom::Sequence<nsString>& varyings,
WebGLProgram& program, const nsTArray<nsString>& varyings,
GLenum bufferMode) {
const FuncScope funcScope(*this, "transformFeedbackVaryings");
if (IsContextLost()) return;
@ -120,12 +120,12 @@ void WebGL2Context::TransformFeedbackVaryings(
program.TransformFeedbackVaryings(varyings, bufferMode);
}
already_AddRefed<WebGLActiveInfo> WebGL2Context::GetTransformFeedbackVarying(
Maybe<WebGLActiveInfo> WebGL2Context::GetTransformFeedbackVarying(
const WebGLProgram& program, GLuint index) {
const FuncScope funcScope(*this, "getTransformFeedbackVarying");
if (IsContextLost()) return nullptr;
if (IsContextLost()) return Nothing();
if (!ValidateObject("program", program)) return nullptr;
if (!ValidateObject("program", program)) return Nothing();
return program.GetTransformFeedbackVarying(index);
}

Просмотреть файл

@ -54,13 +54,11 @@ void WebGLContext::Uniform4ui(WebGLUniformLocation* loc, GLuint v0, GLuint v1,
// -------------------------------------------------------------------------
// Uniform Buffer Objects and Transform Feedback Buffers
void WebGL2Context::GetIndexedParameter(JSContext* cx, GLenum target,
GLuint index,
JS::MutableHandleValue retval,
ErrorResult& out_error) {
MaybeWebGLVariant WebGL2Context::GetIndexedParameter(GLenum target,
GLuint index) {
const FuncScope funcScope(*this, "getIndexedParameter");
retval.set(JS::NullValue());
if (IsContextLost()) return;
MaybeWebGLVariant ret;
if (IsContextLost()) return ret;
const std::vector<IndexedBufferBinding>* bindings;
switch (target) {
@ -78,61 +76,55 @@ void WebGL2Context::GetIndexedParameter(JSContext* cx, GLenum target,
default:
ErrorInvalidEnumInfo("target", target);
return;
return ret;
}
if (index >= bindings->size()) {
ErrorInvalidValue("`index` must be < %s.",
"MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS");
return;
return ret;
}
const auto& binding = (*bindings)[index];
JS::Value ret = JS::NullValue();
switch (target) {
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
case LOCAL_GL_UNIFORM_BUFFER_BINDING:
if (binding.mBufferBinding) {
ret = WebGLObjectAsJSValue(cx, binding.mBufferBinding.get(), out_error);
ret = AsSomeVariant(binding.mBufferBinding.get());
}
break;
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START:
case LOCAL_GL_UNIFORM_BUFFER_START:
ret = JS::NumberValue(binding.mRangeStart);
ret = AsSomeVariant(binding.mRangeStart);
break;
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
case LOCAL_GL_UNIFORM_BUFFER_SIZE:
ret = JS::NumberValue(binding.mRangeSize);
ret = AsSomeVariant(binding.mRangeSize);
break;
}
retval.set(ret);
return ret;
}
void WebGL2Context::GetUniformIndices(
const WebGLProgram& program, const dom::Sequence<nsString>& uniformNames,
dom::Nullable<nsTArray<GLuint> >& retval) {
MaybeWebGLVariant WebGL2Context::GetUniformIndices(
const WebGLProgram& program, const nsTArray<nsString>& uniformNames) {
const FuncScope funcScope(*this, "getUniformIndices");
retval.SetNull();
if (IsContextLost()) return;
if (IsContextLost()) return Nothing();
if (!ValidateObject("program", program)) return;
if (!ValidateObject("program", program)) return Nothing();
if (!uniformNames.Length()) return;
if (!uniformNames.Length()) return Nothing();
program.GetUniformIndices(uniformNames, retval);
return program.GetUniformIndices(uniformNames);
}
void WebGL2Context::GetActiveUniforms(
JSContext* cx, const WebGLProgram& program,
const dom::Sequence<GLuint>& uniformIndices, GLenum pname,
JS::MutableHandleValue retval) {
MaybeWebGLVariant WebGL2Context::GetActiveUniforms(
const WebGLProgram& program, const nsTArray<GLuint>& uniformIndices,
GLenum pname) {
const FuncScope funcScope(*this, "getActiveUniforms");
retval.setNull();
if (IsContextLost()) return;
if (IsContextLost()) return Nothing();
switch (pname) {
case LOCAL_GL_UNIFORM_TYPE:
@ -146,61 +138,70 @@ void WebGL2Context::GetActiveUniforms(
default:
ErrorInvalidEnumInfo("pname", pname);
return;
return Nothing();
}
if (!ValidateObject("program", program)) return;
if (!ValidateObject("program", program)) return Nothing();
if (!program.IsLinked()) {
ErrorInvalidOperation("`program` must be linked.");
return;
return Nothing();
}
const auto& numActiveUniforms = program.LinkInfo()->uniforms.size();
for (const auto& curIndex : uniformIndices) {
if (curIndex >= numActiveUniforms) {
ErrorInvalidValue("Too-large active uniform index queried.");
return;
return Nothing();
}
}
const auto& count = uniformIndices.Length();
JS::Rooted<JSObject*> array(cx, JS::NewArrayObject(cx, count));
UniquePtr<GLint[]> samples(new GLint[count]);
if (!array || !samples) {
ErrorOutOfMemory("Failed to allocate buffers.");
return;
}
retval.setObject(*array);
gl->fGetActiveUniformsiv(program.mGLName, count, uniformIndices.Elements(),
pname, samples.get());
MaybeWebGLVariant ret;
switch (pname) {
case LOCAL_GL_UNIFORM_TYPE:
case LOCAL_GL_UNIFORM_SIZE:
case LOCAL_GL_UNIFORM_BLOCK_INDEX:
case LOCAL_GL_UNIFORM_OFFSET:
case LOCAL_GL_UNIFORM_ARRAY_STRIDE:
case LOCAL_GL_UNIFORM_MATRIX_STRIDE:
for (size_t i = 0; i < count; ++i) {
JS::RootedValue value(cx);
value = JS::Int32Value(samples[i]);
if (!JS_DefineElement(cx, array, i, value, JSPROP_ENUMERATE)) return;
case LOCAL_GL_UNIFORM_MATRIX_STRIDE: {
ret = AsSomeVariant(nsTArray<int32_t>());
nsTArray<int32_t>& variantArray = ret.ref().as<nsTArray<int32_t>>();
GLint* array = variantArray.AppendElements(count);
if (!array) {
ErrorOutOfMemory("Failed to allocate return array.");
return Nothing();
}
break;
case LOCAL_GL_UNIFORM_IS_ROW_MAJOR:
for (size_t i = 0; i < count; ++i) {
JS::RootedValue value(cx);
value = JS::BooleanValue(samples[i]);
if (!JS_DefineElement(cx, array, i, value, JSPROP_ENUMERATE)) return;
gl->fGetActiveUniformsiv(program.mGLName, count,
uniformIndices.Elements(), pname, array);
} break;
case LOCAL_GL_UNIFORM_IS_ROW_MAJOR: {
ret = AsSomeVariant(nsTArray<bool>());
nsTArray<bool>& variantArray = ret.ref().as<nsTArray<bool>>();
GLint* intArray = new GLint[count];
if (!intArray) {
ErrorOutOfMemory("Failed to allocate int buffer.");
return Nothing();
}
break;
gl->fGetActiveUniformsiv(program.mGLName, count,
uniformIndices.Elements(), pname, intArray);
bool* boolArray = variantArray.AppendElements(count);
if (!boolArray) {
ErrorOutOfMemory("Failed to allocate return array.");
return Nothing();
}
for (uint32_t i = 0; i < count; ++i) {
boolArray[i] = intArray[i];
}
} break;
default:
MOZ_CRASH("Invalid pname");
}
return ret;
}
GLuint WebGL2Context::GetUniformBlockIndex(const WebGLProgram& program,
@ -213,14 +214,12 @@ GLuint WebGL2Context::GetUniformBlockIndex(const WebGLProgram& program,
return program.GetUniformBlockIndex(uniformBlockName);
}
void WebGL2Context::GetActiveUniformBlockParameter(
JSContext* cx, const WebGLProgram& program, GLuint uniformBlockIndex,
GLenum pname, JS::MutableHandleValue out_retval, ErrorResult& out_error) {
MaybeWebGLVariant WebGL2Context::GetActiveUniformBlockParameter(
const WebGLProgram& program, GLuint uniformBlockIndex, GLenum pname) {
const FuncScope funcScope(*this, "getActiveUniformBlockParameter");
out_retval.setNull();
if (IsContextLost()) return;
if (IsContextLost()) return Nothing();
if (!ValidateObject("program", program)) return;
if (!ValidateObject("program", program)) return Nothing();
switch (pname) {
case LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
@ -228,29 +227,24 @@ void WebGL2Context::GetActiveUniformBlockParameter(
case LOCAL_GL_UNIFORM_BLOCK_BINDING:
case LOCAL_GL_UNIFORM_BLOCK_DATA_SIZE:
case LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
out_retval.set(
program.GetActiveUniformBlockParam(uniformBlockIndex, pname));
return;
return program.GetActiveUniformBlockParam(uniformBlockIndex, pname);
case LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
out_retval.set(program.GetActiveUniformBlockActiveUniforms(
cx, uniformBlockIndex, &out_error));
return;
return program.GetActiveUniformBlockActiveUniforms(uniformBlockIndex);
}
ErrorInvalidEnumInfo("parameter", pname);
return Nothing();
}
void WebGL2Context::GetActiveUniformBlockName(const WebGLProgram& program,
GLuint uniformBlockIndex,
nsAString& retval) {
nsString WebGL2Context::GetActiveUniformBlockName(const WebGLProgram& program,
GLuint uniformBlockIndex) {
const FuncScope funcScope(*this, "getActiveUniformBlockName");
retval.SetIsVoid(true);
if (IsContextLost()) return;
if (IsContextLost()) return EmptyString();
if (!ValidateObject("program", program)) return;
if (!ValidateObject("program", program)) return EmptyString();
program.GetActiveUniformBlockName(uniformBlockIndex, retval);
return program.GetActiveUniformBlockName(uniformBlockIndex);
}
void WebGL2Context::UniformBlockBinding(WebGLProgram& program,

Просмотреть файл

@ -146,12 +146,10 @@ static webgl::AttribBaseType ElemBaseType(const GLenum elemType) {
}
}
WebGLActiveInfo::WebGLActiveInfo(WebGLContext* webgl, GLint elemCount,
GLenum elemType, bool isArray,
WebGLActiveInfo::WebGLActiveInfo(GLint elemCount, GLenum elemType, bool isArray,
const nsACString& baseUserName,
const nsACString& baseMappedName)
: mWebGL(webgl),
mElemCount(elemCount),
: mElemCount(elemCount),
mElemType(elemType),
mBaseUserName(baseUserName),
mIsArray(isArray),
@ -159,6 +157,15 @@ WebGLActiveInfo::WebGLActiveInfo(WebGLContext* webgl, GLint elemCount,
mBaseMappedName(baseMappedName),
mBaseType(ElemBaseType(mElemType)) {}
WebGLActiveInfo::WebGLActiveInfo(const WebGLActiveInfo& aOther)
: mElemCount(aOther.mElemCount),
mElemType(aOther.mElemType),
mBaseUserName(aOther.mBaseUserName),
mIsArray(aOther.mIsArray),
mElemSize(aOther.mElemSize),
mBaseMappedName(aOther.mBaseMappedName),
mBaseType(aOther.mBaseType) {}
bool WebGLActiveInfo::IsSampler() const {
switch (mElemType) {
case LOCAL_GL_SAMPLER_2D:
@ -185,14 +192,14 @@ bool WebGLActiveInfo::IsSampler() const {
////////////////////////////////////////////////////////////////////////////////
JSObject* WebGLActiveInfo::WrapObject(JSContext* js,
JS::Handle<JSObject*> givenProto) {
JSObject* ClientWebGLActiveInfo::WrapObject(JSContext* js,
JS::Handle<JSObject*> givenProto) {
return dom::WebGLActiveInfo_Binding::Wrap(js, this, givenProto);
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLActiveInfo)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(ClientWebGLActiveInfo)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLActiveInfo, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLActiveInfo, Release)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(ClientWebGLActiveInfo, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(ClientWebGLActiveInfo, Release)
} // namespace mozilla

Просмотреть файл

@ -16,38 +16,34 @@
namespace mozilla {
namespace ipc {
template <typename T>
struct PcqParamTraits;
}
class WebGLContext;
class WebGLActiveInfo final : public nsWrapperCache {
class WebGLActiveInfo {
public:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLActiveInfo)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLActiveInfo)
virtual JSObject* WrapObject(JSContext* js,
JS::Handle<JSObject*> givenProto) override;
WebGLContext* GetParentObject() const { return mWebGL; }
WebGLContext* const mWebGL;
// ActiveInfo state:
const uint32_t mElemCount; // `size`
const GLenum mElemType; // `type`
const nsCString
mBaseUserName; // `name`, but ASCII, and without any final "[0]".
uint32_t mElemCount; // `size`
GLenum mElemType; // `type`
nsCString mBaseUserName; // `name`, but ASCII, and without any final "[0]".
// Not actually part of ActiveInfo:
const bool mIsArray;
const uint8_t mElemSize;
const nsCString mBaseMappedName; // Without any final "[0]".
const webgl::AttribBaseType mBaseType = webgl::AttribBaseType::Float;
bool mIsArray;
uint8_t mElemSize;
nsCString mBaseMappedName; // Without any final "[0]".
webgl::AttribBaseType mBaseType = webgl::AttribBaseType::Float;
bool IsSampler() const;
WebGLActiveInfo(WebGLContext* webgl, GLint elemCount, GLenum elemType,
bool isArray, const nsACString& baseUserName,
WebGLActiveInfo(GLint elemCount, GLenum elemType, bool isArray,
const nsACString& baseUserName,
const nsACString& baseMappedName);
WebGLActiveInfo(const WebGLActiveInfo& aOther);
/* GLES 2.0.25, p33:
* This command will return as much information about active
* attributes as possible. If no information is available, length will
@ -56,9 +52,7 @@ class WebGLActiveInfo final : public nsWrapperCache {
*
* It's the same for GetActiveUniform.
*/
static WebGLActiveInfo* CreateInvalid(WebGLContext* webgl) {
return new WebGLActiveInfo(webgl);
}
static WebGLActiveInfo CreateInvalid() { return WebGLActiveInfo(); }
// WebIDL attributes
GLint Size() const { return mElemCount; }
@ -70,18 +64,46 @@ class WebGLActiveInfo final : public nsWrapperCache {
if (mIsArray) retval.AppendLiteral("[0]");
}
private:
explicit WebGLActiveInfo(WebGLContext* webgl)
: mWebGL(webgl),
mElemCount(0),
protected:
friend mozilla::ipc::PcqParamTraits<WebGLActiveInfo>;
friend Maybe<WebGLActiveInfo>;
explicit WebGLActiveInfo()
: mElemCount(0),
mElemType(0),
mBaseUserName(""),
mIsArray(false),
mElemSize(0),
mBaseMappedName("") {}
};
// Private destructor, to discourage deletion outside of Release():
~WebGLActiveInfo() {}
class ClientWebGLActiveInfo final : public WebGLActiveInfo,
public nsWrapperCache {
public:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(ClientWebGLActiveInfo)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(ClientWebGLActiveInfo)
virtual JSObject* WrapObject(JSContext* js,
JS::Handle<JSObject*> givenProto) override;
ClientWebGLContext* GetParentObject() const { return mWebGL; }
ClientWebGLActiveInfo(ClientWebGLContext* webgl, GLint elemCount,
GLenum elemType, bool isArray,
const nsACString& baseUserName,
const nsACString& baseMappedName)
: WebGLActiveInfo(elemCount, elemType, isArray, baseUserName,
baseMappedName),
mWebGL(webgl) {}
ClientWebGLActiveInfo(ClientWebGLContext* webgl,
const WebGLActiveInfo& aOther)
: WebGLActiveInfo(aOther), mWebGL(webgl) {}
ClientWebGLContext* const mWebGL;
protected:
~ClientWebGLActiveInfo() {}
};
//////////

Просмотреть файл

@ -386,14 +386,4 @@ void WebGLBuffer::ResetLastUpdateFenceId() const {
mLastUpdateFenceId = mContext->mNextFenceId;
}
JSObject* WebGLBuffer::WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto) {
return dom::WebGLBuffer_Binding::Wrap(cx, this, givenProto);
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLBuffer)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLBuffer, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLBuffer, Release)
} // namespace mozilla

Просмотреть файл

@ -17,8 +17,7 @@
namespace mozilla {
class WebGLBuffer final : public nsWrapperCache,
public WebGLRefCountedObject<WebGLBuffer>,
class WebGLBuffer final : public WebGLRefCountedObject<WebGLBuffer>,
public LinkedListElement<WebGLBuffer> {
friend class WebGLContext;
friend class WebGL2Context;
@ -43,11 +42,6 @@ class WebGLBuffer final : public nsWrapperCache,
uint32_t indexCount) const;
bool ValidateRange(size_t byteOffset, size_t byteLen) const;
WebGLContext* GetParentObject() const { return mContext; }
virtual JSObject* WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto) override;
bool ValidateCanBindToTarget(GLenum target);
void BufferData(GLenum target, uint64_t size, const void* data, GLenum usage);
void BufferSubData(GLenum target, uint64_t dstByteOffset, uint64_t dataLen,
@ -57,8 +51,7 @@ class WebGLBuffer final : public nsWrapperCache,
const GLenum mGLName;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLBuffer)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLBuffer)
NS_INLINE_DECL_REFCOUNTING(WebGLBuffer)
protected:
~WebGLBuffer();

37
dom/canvas/WebGLChild.cpp Normal file
Просмотреть файл

@ -0,0 +1,37 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "WebGLChild.h"
#include "ClientWebGLContext.h"
#include "nsICanvasRenderingContextInternal.h"
#include "nsQueryObject.h"
namespace mozilla {
namespace dom {
mozilla::ipc::IPCResult WebGLChild::RecvQueueFailed() {
mozilla::ClientWebGLContext* context = GetContext();
if (context) {
context->OnQueueFailed();
}
return Send__delete__(this) ? IPC_OK() : IPC_FAIL_NO_REASON(this);
}
mozilla::ClientWebGLContext* WebGLChild::GetContext() {
nsCOMPtr<nsICanvasRenderingContextInternal> ret = do_QueryReferent(mContext);
if (!ret) {
return nullptr;
}
return static_cast<mozilla::ClientWebGLContext*>(ret.get());
}
void WebGLChild::SetContext(mozilla::ClientWebGLContext* aContext) {
mContext = do_GetWeakReference(aContext);
}
} // namespace dom
} // namespace mozilla

33
dom/canvas/WebGLChild.h Normal file
Просмотреть файл

@ -0,0 +1,33 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 WEBGLCHILD_H_
#define WEBGLCHILD_H_
#include "mozilla/dom/PWebGLChild.h"
#include "nsWeakReference.h"
namespace mozilla {
class ClientWebGLContext;
namespace dom {
class WebGLChild : public PWebGLChild {
public:
mozilla::ipc::IPCResult RecvQueueFailed();
mozilla::ClientWebGLContext* GetContext();
protected:
friend mozilla::ClientWebGLContext;
void SetContext(mozilla::ClientWebGLContext* aContext);
nsWeakPtr mContext;
};
} // namespace dom
} // namespace mozilla
#endif // WEBGLCHILD_H_

Просмотреть файл

@ -0,0 +1,924 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 WEBGLCOMMANDQUEUE_H_
#define WEBGLCOMMANDQUEUE_H_
#include "mozilla/dom/ProducerConsumerQueue.h"
#include "mozilla/ipc/IPDLParamTraits.h"
// Get around a bug in Clang related to __thiscall method pointers
#if defined(_M_IX86)
# define SINK_FCN_CC __thiscall
#else
# define SINK_FCN_CC
#endif
namespace mozilla {
using mozilla::ipc::IPDLParamTraits;
using mozilla::webgl::Consumer;
using mozilla::webgl::PcqStatus;
using mozilla::webgl::Producer;
using mozilla::webgl::ProducerConsumerQueue;
template <typename Derived, typename SinkType>
struct FunctionDispatcher;
template <typename Derived, typename SinkType>
struct MethodDispatcher;
enum CommandResult { Success, TimeExpired, QueueEmpty, Error };
enum CommandSyncType { ASYNC, SYNC };
/**
* A CommandQueue is a ProducerConsumerQueue where the contents are commands.
* Its endpoints are called mSource and mSink and can be sent to other
* processes via IPDL, the same way ProducerConsumerQueues can.
* Source and Sink are generic and will work with well with others but
* CommandSource and CommandSink are designed for use with them.
* CommandSource offers asynchronous Insert methods that can be used
* to add commands into the queue. CommandSink offers ProcessOne, ProcessAll,
* etc for draining the queue. See CommandSource and CommandSink for more.
*
* NB: When used with IPDL, Sources and Sinks must be labeled "shmemholder"
* (same as with Producers and Consumers).
*/
template <typename Source, typename Sink>
class CommandQueue {
public:
using SelfType = CommandQueue<Source, Sink>;
using Source = Source;
using Sink = Sink;
// Technically, we're just mapping the Producer and Consumer in aPcq
// by calling the Source and Sink type's constructors on them, respectively,
// and passing aArgs as constructor parameters.
template <typename... Args>
static UniquePtr<SelfType> Create(UniquePtr<ProducerConsumerQueue>&& aPcq,
Args&... aArgs) {
// Prefer WrapUnique to MakeUnique since it allows client code to declare
// a private constructor and give this class friend status.
UniquePtr<Source> source =
WrapUnique(new Source(std::move(aPcq->mProducer), aArgs...));
if (!source) {
return nullptr;
}
UniquePtr<Sink> sink =
WrapUnique(new Sink(std::move(aPcq->mConsumer), aArgs...));
if (!sink) {
return nullptr;
}
return WrapUnique(new CommandQueue(std::move(source), std::move(sink)));
}
UniquePtr<Source> mSource;
UniquePtr<Sink> mSink;
protected:
CommandQueue(UniquePtr<Source>&& aSource, UniquePtr<Sink>&& aSink)
: mSource(std::move(aSource)), mSink(std::move(aSink)) {
MOZ_ASSERT(mSource && mSink);
}
};
class BasicSource {
public:
BasicSource(UniquePtr<Producer>&& aProducer)
: mProducer(std::move(aProducer)) {
MOZ_ASSERT(mProducer);
}
virtual ~BasicSource() {}
// For IPDL:
BasicSource() {}
friend struct mozilla::ipc::IPDLParamTraits<BasicSource>;
protected:
UniquePtr<Producer> mProducer;
};
class BasicSink {
public:
BasicSink(UniquePtr<Consumer>&& aConsumer) : mConsumer(std::move(aConsumer)) {
MOZ_ASSERT(mConsumer);
}
virtual ~BasicSink() {}
// For IPDL:
BasicSink() {}
friend struct mozilla::ipc::IPDLParamTraits<BasicSink>;
protected:
UniquePtr<Consumer> mConsumer;
};
/**
* A CommandSource is obtained from a CommandQueue. Use it by inserting a
* command (represented by type Command) using InsertCommand, which also
* needs all parameters to the command. They are then serialized and sent
* to the CommandSink, which must understand the Command+Args combination
* to execute it.
*/
template <typename Command>
class CommandSource : public BasicSource {
public:
CommandSource(UniquePtr<Producer>&& aProducer)
: BasicSource(std::move(aProducer)) {}
template <typename... Args>
PcqStatus InsertCommand(Command aCommand, Args&&... aArgs) {
return this->mProducer->TryWaitInsert(Nothing() /* wait forever */,
aCommand, aArgs...);
}
template <>
PcqStatus InsertCommand<>(Command aCommand) {
return this->mProducer->TryWaitInsert(Nothing() /* wait forever */,
aCommand);
}
template <typename... Args>
PcqStatus RunCommand(Command aCommand, Args&&... aArgs) {
return InsertCommand(aCommand, std::forward<Args>(aArgs)...);
}
// For IPDL:
CommandSource() {}
};
/**
* A CommandSink is obtained from a CommandQueue. It executes commands that
* originated in its CommandSource. Use this class by calling one of the
* Process methods, which will autonomously deserialize, dispatch and
* post-process the execution. This class handles deserialization -- dispatch
* and processing are to be provided by a subclass in its implementation of the
* pure-virtual DispatchCommand method. DispatchCommand implementations can
* easily run functions and methods using arguments taken from the command
* queue by calling the Dispatch methods in this class.
*/
template <typename Command>
class CommandSink : public BasicSink {
public:
CommandSink(UniquePtr<Consumer>&& aConsumer)
: BasicSink(std::move(aConsumer)) {}
/**
* Attempts to process the next command in the queue, if one is available.
*/
CommandResult ProcessOne(Maybe<TimeDuration> aTimeout) {
Command command;
PcqStatus status = (aTimeout.isNothing() || aTimeout.value())
? this->mConsumer->TryWaitRemove(aTimeout, command)
: this->mConsumer->TryRemove(command);
if (status == PcqStatus::Success) {
if (DispatchCommand(command)) {
return CommandResult::Success;
}
return CommandResult::Error;
}
if (status == PcqStatus::PcqNotReady) {
return CommandResult::QueueEmpty;
}
if (status == PcqStatus::PcqOOMError) {
ReportOOM();
}
return CommandResult::Error;
}
CommandResult ProcessOneNow() { return ProcessOne(Some(TimeDuration(0))); }
/**
* Drains the queue until the queue is empty or an error occurs, whichever
* comes first.
* Returns the result of the last attempt to process a command, which will
* be either QueueEmpty or Error.
*/
CommandResult ProcessAll() {
CommandResult result;
do {
result = ProcessOneNow();
} while (result == CommandResult::Success);
return result;
}
/**
* Drains the queue until aDuration expires, the queue is empty, or an error
* occurs, whichever comes first.
* Returns the result of the last attempt to process a command.
*/
CommandResult ProcessUpToDuration(TimeDuration aDuration) {
TimeStamp start = TimeStamp::Now();
TimeStamp now = start;
CommandResult result;
do {
result = ProcessOne(Some(aDuration - (now - start)));
now = TimeStamp::Now();
} while ((result == CommandResult::Success) && ((now - start) < aDuration));
return result;
}
// For IPDL:
CommandSink() {}
// non-void return value, non-const method variant
template <typename T, typename ReturnType, typename... Args>
bool DispatchAsyncMethod(T& aObj, ReturnType (T::*aMethod)(Args...)) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!ReadArgs(args)) {
return false;
}
CallMethod(aObj, aMethod, args, std::index_sequence_for<Args...>{});
return true;
}
// non-void return value, const method variant
template <typename T, typename ReturnType, typename... Args>
bool DispatchAsyncMethod(const T& aObj,
ReturnType (T::*aMethod)(Args...) const) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!ReadArgs(args)) {
return false;
}
CallMethod(aObj, aMethod, args, std::index_sequence_for<Args...>{});
return true;
}
template <typename ReturnType, typename... Args>
bool DispatchAsyncFunction(ReturnType (*aFunc)(Args...)) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!ReadArgs(args)) {
return false;
}
CallFunction(aObj, aFunc, args, std::index_sequence_for<Args...>{});
return true;
}
// void return value, non-const method variant
template <typename T, typename... Args>
bool DispatchAsyncMethod(T* aObj, void (T::*aMethod)(Args...)) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!ReadArgs(args)) {
return false;
}
CallVoidMethod(aObj, aMethod, args, std::index_sequence_for<Args...>{});
return true;
}
// void return value, const method variant
template <typename T, typename... Args>
bool DispatchAsyncMethod(const T* aObj, void (T::*aMethod)(Args...) const) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!ReadArgs(args)) {
return false;
}
CallVoidMethod(aObj, aMethod, args, std::index_sequence_for<Args...>{});
return true;
}
// void return value form of above
template <typename... Args>
bool DispatchAsyncFunction(void (*aFunc)(Args...)) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!ReadArgs(args)) {
return false;
}
CallVoidFunction(aFunc, args, std::index_sequence_for<Args...>{});
return true;
}
protected:
/**
* Implementations will usually be something like a big switch statement
* that calls one of the Dispatch methods in this class.
*/
virtual bool DispatchCommand(Command command) = 0;
/**
* Implementations can override this to detect out-of-memory during
* deserialization.
*/
virtual void ReportOOM() {}
template <typename... Args, size_t... Indices>
PcqStatus CallTryRemove(std::tuple<Args...>& aArgs,
std::index_sequence<Indices...>) {
PcqStatus status = mConsumer->TryRemove(std::get<Indices>(aArgs)...);
// The CommandQueue inserts the command and the args together as an atomic
// operation. We already read the command so the args must also be
// available.
MOZ_ASSERT(status != PcqStatus::PcqNotReady);
return status;
}
template <>
PcqStatus CallTryRemove(std::tuple<>& aArgs,
std::make_integer_sequence<size_t, 0>) {
return PcqStatus::Success;
}
template <typename T, typename MethodType, typename... Args,
size_t... Indices,
typename ReturnType =
typename mozilla::FunctionTypeTraits<MethodType>::ReturnType>
ReturnType CallMethod(T& aObj, MethodType aMethod, std::tuple<Args...>& aArgs,
std::index_sequence<Indices...>) {
return (aObj.*aMethod)(std::forward<Args>(std::get<Indices>(aArgs))...);
}
template <typename FunctionType, typename... Args, size_t... Indices,
typename ReturnType =
typename mozilla::FunctionTypeTraits<FunctionType>::ReturnType>
ReturnType CallFunction(FunctionType aFun, std::tuple<Args...>& aArgs,
std::index_sequence<Indices...>) {
return (*aFunc)(std::forward<Args>(std::get<Indices>(aArgs))...);
}
template <typename T, typename MethodType, typename... Args,
size_t... Indices>
void CallVoidMethod(T& aObj, MethodType aMethod, std::tuple<Args...>& aArgs,
std::index_sequence<Indices...>) {
(aObj.*aMethod)(std::forward<Args>(std::get<Indices>(aArgs))...);
}
template <typename FunctionType, typename... Args, size_t... Indices>
void CallVoidFunction(FunctionType aFun, std::tuple<Args...>& aArgs,
std::index_sequence<Indices...>) {
(*aFunc)(std::forward<Args>(std::get<Indices>(aArgs))...);
}
template <typename... Args>
bool ReadArgs(std::tuple<Args...>& aArgs) {
PcqStatus status = CallTryRemove(aArgs, std::index_sequence_for<Args...>{});
return IsSuccess(status);
}
};
enum SyncResponse : uint8_t { RESPONSE_NAK, RESPONSE_ACK };
/**
* This is the Source for a SyncCommandSink. It takes an extra PCQ,
* the ResponsePcq, and uses it to receive synchronous responses from
* the sink. The ResponsePcq is a regular ProducerConsumerQueue,
* not a CommandQueue.
*/
template <typename Command>
class SyncCommandSource : public CommandSource<Command> {
public:
using BaseType = CommandSource<Command>;
SyncCommandSource(UniquePtr<Producer>&& aProducer,
UniquePtr<ProducerConsumerQueue>& aResponsePcq)
: CommandSource<Command>(std::move(aProducer)),
mConsumer(std::move(aResponsePcq->mConsumer)) {
MOZ_ASSERT(mConsumer);
}
template <typename... Args>
PcqStatus RunAsyncCommand(Command aCommand, Args&&... aArgs) {
return this->RunCommand(aCommand, std::forward<Args>(aArgs)...);
}
template <typename... Args>
PcqStatus RunVoidSyncCommand(Command aCommand, Args&&... aArgs) {
PcqStatus status = RunAsyncCommand(aCommand, std::forward<Args>(aArgs)...);
return IsSuccess(status) ? this->ReadSyncResponse() : status;
}
template <typename ResultType, typename... Args>
PcqStatus RunSyncCommand(Command aCommand, ResultType& aReturn,
Args&&... aArgs) {
PcqStatus status =
RunVoidSyncCommand(aCommand, std::forward<Args>(aArgs)...);
return IsSuccess(status) ? this->ReadResult(aReturn) : status;
}
// for IPDL:
SyncCommandSource() {}
friend struct mozilla::ipc::IPDLParamTraits<SyncCommandSource<Command>>;
protected:
PcqStatus ReadSyncResponse() {
SyncResponse response;
PcqStatus status =
mConsumer->TryWaitRemove(Nothing() /* wait forever */, response);
MOZ_ASSERT(status != PcqStatus::PcqNotReady);
if (IsSuccess(status) && response != RESPONSE_ACK) {
return PcqStatus::PcqFatalError;
}
return status;
}
template <typename T>
PcqStatus ReadResult(T& aResult) {
PcqStatus status = mConsumer->TryRemove(aResult);
// The Sink posts the response code and result as an atomic transaction. We
// already read the response code so the result must be available.
MOZ_ASSERT(status != PcqStatus::PcqNotReady);
return status;
}
UniquePtr<Consumer> mConsumer;
};
/**
* This is the Sink for a SyncCommandSource. It takes an extra PCQ, the
* ResponsePcq, and uses it to issue synchronous responses to the client.
* Subclasses can use the DispatchSync methods in this class in their
* DispatchCommand implementations.
* The ResponsePcq is not a CommandQueue.
*/
template <typename Command>
class SyncCommandSink : public CommandSink<Command> {
using BaseType = CommandSink<Command>;
public:
SyncCommandSink(UniquePtr<Consumer>&& aConsumer,
UniquePtr<ProducerConsumerQueue>& aResponsePcq)
: CommandSink<Command>(std::move(aConsumer)),
mProducer(std::move(aResponsePcq->mProducer)) {
MOZ_ASSERT(mProducer);
}
// for IPDL:
SyncCommandSink() {}
friend struct mozilla::ipc::IPDLParamTraits<SyncCommandSink<Command>>;
// Places RESPONSE_ACK and the typed return value, or RESPONSE_NAK, in
// the response queue,
// __cdecl/__thiscall non-const method variant.
template <typename T, typename ReturnType, typename... Args>
bool DispatchSyncMethod(T& aObj,
ReturnType SINK_FCN_CC (T::*aMethod)(Args...)) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!BaseType::ReadArgs(args)) {
WriteNAK();
return false;
}
ReturnType response = BaseType::CallMethod(
aObj, aMethod, args, std::index_sequence_for<Args...>{});
return WriteACK(response);
}
// __cdecl/__thiscall const method variant.
template <typename T, typename ReturnType, typename... Args>
bool DispatchSyncMethod(const T& aObj,
ReturnType SINK_FCN_CC (T::*aMethod)(Args...) const) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!BaseType::ReadArgs(args)) {
WriteNAK();
return false;
}
ReturnType response = BaseType::CallMethod(
aObj, aMethod, args, std::index_sequence_for<Args...>{});
return WriteACK(response);
}
#if defined(_M_IX86)
// __stdcall non-const method variant.
template <typename T, typename ReturnType, typename... Args>
bool DispatchSyncMethod(T& aObj,
ReturnType __stdcall (T::*aMethod)(Args...)) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!BaseType::ReadArgs(args)) {
WriteNAK();
return false;
}
ReturnType response = BaseType::CallMethod(
aObj, aMethod, args, std::index_sequence_for<Args...>{});
return WriteACK(response);
}
// __stdcall const method variant.
template <typename T, typename ReturnType, typename... Args>
bool DispatchSyncMethod(const T& aObj,
ReturnType __stdcall (T::*aMethod)(Args...) const) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!BaseType::ReadArgs(args)) {
WriteNAK();
return false;
}
ReturnType response = BaseType::CallMethod(
aObj, aMethod, args, std::index_sequence_for<Args...>{});
return WriteACK(response);
}
#endif
template <typename ReturnType, typename... Args>
bool DispatchSyncFunction(ReturnType (*aFunc)(Args...)) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!BaseType::ReadArgs(args)) {
WriteNAK();
return false;
}
ReturnType response =
BaseType::CallFunction(aFunc, args, std::index_sequence_for<Args...>{});
return WriteACK(response);
}
// __cdecl/__thiscall non-const void method variant
template <typename T, typename... Args>
bool DispatchSyncMethod(T& aObj, void SINK_FCN_CC (T::*aMethod)(Args...)) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!BaseType::ReadArgs(args)) {
WriteNAK();
return false;
}
BaseType::CallVoidMethod(aObj, aMethod, args,
std::index_sequence_for<Args...>{});
return WriteACK();
}
// __cdecl/__thiscall const void method variant
template <typename T, typename... Args>
bool DispatchSyncMethod(const T& aObj,
void SINK_FCN_CC (T::*aMethod)(Args...) const) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!BaseType::ReadArgs(args)) {
WriteNAK();
return false;
}
BaseType::CallVoidMethod(aObj, aMethod, args,
std::index_sequence_for<Args...>{});
return WriteACK();
}
#if defined(_M_IX86)
// __stdcall non-const void method variant
template <typename T, typename... Args>
bool DispatchSyncMethod(T& aObj, void __stdcall (T::*aMethod)(Args...)) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!BaseType::ReadArgs(args)) {
WriteNAK();
return false;
}
BaseType::CallVoidMethod(aObj, aMethod, args,
std::index_sequence_for<Args...>{});
return WriteACK();
}
// __stdcall const void method variant
template <typename T, typename... Args>
bool DispatchSyncMethod(const T& aObj,
void __stdcall (T::*aMethod)(Args...) const) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!BaseType::ReadArgs(args)) {
WriteNAK();
return false;
}
BaseType::CallVoidMethod(aObj, aMethod, args,
std::index_sequence_for<Args...>{});
return WriteACK();
}
#endif
template <typename... Args>
bool DispatchSyncFunction(void (*aFunc)(Args...)) {
std::tuple<typename RemoveCV<typename RemoveReference<Args>::Type>::Type...>
args;
if (!BaseType::ReadArgs(args)) {
WriteNAK();
return false;
}
BaseType::CallVoidFunction(aFunc, args, std::index_sequence_for<Args...>{});
return WriteACK();
}
protected:
template <typename... Args>
bool WriteArgs(const Args&... aArgs) {
return IsSuccess(mProducer->TryInsert(aArgs...));
}
template <typename... Args>
bool WriteACK(const Args&... aArgs) {
SyncResponse ack = RESPONSE_ACK;
return WriteArgs(ack, aArgs...);
}
bool WriteNAK() {
SyncResponse nak = RESPONSE_NAK;
return WriteArgs(nak);
}
UniquePtr<Producer> mProducer;
};
/**
* Can be used by a sink to find and execute the handler for a given commandId.
*/
template <typename Derived>
struct CommandDispatchDriver {
/**
* Find and run the command.
*/
template <size_t commandId, typename... Args>
static MOZ_ALWAYS_INLINE bool DispatchCommandHelper(size_t aId,
Args&... aArgs) {
if (commandId == aId) {
return Derived::template Dispatch<commandId>(aArgs...);
}
return Derived::template DispatchCommand<commandId + 1>(aId, aArgs...);
}
};
/**
* This CommandDispatcher provides helper methods that subclasses can
* use to dispatch sync/async commands to a function via a CommandSink.
* See DECLARE_FUNCTION_DISPATCHER and DEFINE_FUNCTION_DISPATCHER.
*/
template <typename Derived, typename _SinkType>
struct FunctionDispatcher {
using SinkType = _SinkType;
template <CommandSyncType syncType>
struct DispatchFunction;
// Specialization for dispatching asynchronous functions
template <>
struct DispatchFunction<CommandSyncType::ASYNC> {
template <typename FunctionType>
static MOZ_ALWAYS_INLINE bool Run(SinkType& aSink, FunctionType function) {
return aSink.DispatchAsyncFunction(function);
}
};
// Specialization for dispatching synchronous functions
template <>
struct DispatchFunction<CommandSyncType::SYNC> {
template <typename FunctionType>
static MOZ_ALWAYS_INLINE bool Run(SinkType& aSink, FunctionType function) {
return aSink.DispatchSyncFunction(function);
}
};
};
/**
* This CommandDispatcher provides helper methods that subclasses can
* use to dispatch sync/async commands to a method via a CommandSink.
* See DECLARE_METHOD_DISPATCHER and DEFINE_METHOD_DISPATCHER.
*/
template <typename Derived, typename _SinkType>
struct MethodDispatcher {
using SinkType = _SinkType;
template <CommandSyncType syncType>
struct DispatchMethod;
// Specialization for dispatching asynchronous methods
template <>
struct DispatchMethod<CommandSyncType::ASYNC> {
template <typename MethodType, typename ObjectType>
static MOZ_ALWAYS_INLINE bool Run(SinkType& aSink, MethodType mMethod,
ObjectType& aObj) {
return aSink.DispatchAsyncMethod(aObj, mMethod);
}
};
// Specialization for dispatching synchronous methods
template <>
struct DispatchMethod<CommandSyncType::SYNC> {
template <typename MethodType, typename ObjectType>
static MOZ_ALWAYS_INLINE bool Run(SinkType& aSink, MethodType aMethod,
ObjectType& aObj) {
return aSink.DispatchSyncMethod(aObj, aMethod);
}
};
};
// Declares a FunctionDispatcher with the given name and CommandSink type.
#define DECLARE_FUNCTION_DISPATCHER(_DISPATCHER, _SINKTYPE) \
struct _DISPATCHER : public FunctionDispatcher<_DISPATCHER, _SINKTYPE> { \
template <size_t commandId = 0> \
static MOZ_ALWAYS_INLINE bool DispatchCommand(size_t aId) { \
MOZ_ASSERT_UNREACHABLE("Unhandled command ID"); \
return false; \
} \
template <size_t commandId> \
static MOZ_ALWAYS_INLINE bool Dispatch(SinkType& aSink); \
template <size_t commandId> \
struct FuncInfo; \
template <size_t commandId> \
static constexpr CommandSyncType SyncType(); \
template <typename FuncType, FuncType func> \
static constexpr size_t Id(); \
};
// Declares a MethodDispatcher with the given name and CommandSink type.
// The ObjectType is the type of the object this class will dispatch methods to.
#define DECLARE_METHOD_DISPATCHER(_DISPATCHER, _SINKTYPE, _OBJECTTYPE) \
struct _DISPATCHER : public MethodDispatcher<_DISPATCHER, _SINKTYPE> { \
using ObjectType = _OBJECTTYPE; \
template <size_t commandId = 0> \
static MOZ_ALWAYS_INLINE bool DispatchCommand(size_t aId, SinkType& aSink, \
ObjectType& aObj) { \
MOZ_ASSERT_UNREACHABLE("Unhandled command ID"); \
return false; \
} \
template <size_t commandId> \
static MOZ_ALWAYS_INLINE bool Dispatch(SinkType& aSink, ObjectType& aObj); \
template <size_t commandId> \
struct MethodInfo; \
template <size_t commandId> \
static constexpr CommandSyncType SyncType(); \
template <typename MethodType, MethodType method> \
static constexpr size_t Id(); \
};
// Defines a handler in the given dispatcher for the command with the given
// id. The handler uses a CommandSink to read parameters, call the
// given function using the given synchronization protocol, and provide
// compile-time lookup of the ID by function.
#define DEFINE_FUNCTION_DISPATCHER(_DISPATCHER, _ID, _FUNC, _SYNC) \
template <> \
bool _DISPATCHER::DispatchCommand<_ID>(size_t aId, SinkType & aSink) { \
return CommandDispatchDriver<_DISPATCHER>::DispatchCommandHelper(aId, \
aSink); \
} \
template <> \
bool _DISPATCHER::Dispatch<_ID>(SinkType & aSink) { \
return DispatchFunction<_SYNC>::Run(aSink, &_FUNC); \
} \
template <> \
struct _DISPATCHER::FuncInfo<_ID> { \
using FuncType = decltype(&_FUNC); \
}; \
template <> \
constexpr CommandSyncType _DISPATCHER::SyncType<_ID>() { \
return _SYNC; \
} \
template <> \
constexpr size_t _DISPATCHER::Id<decltype(&_FUNC), &_FUNC>() { \
return _ID; \
}
// Defines a handler in the given dispatcher for the command with the given
// id. The handler uses a CommandSink to read parameters, call the
// given method using the given synchronization protocol, and provide
// compile-time lookup of the ID by class method.
#define DEFINE_METHOD_DISPATCHER(_DISPATCHER, _ID, _METHOD, _SYNC) \
template <> \
bool _DISPATCHER::DispatchCommand<_ID>(size_t aId, SinkType & aSink, \
ObjectType & aObj) { \
return CommandDispatchDriver<_DISPATCHER>::DispatchCommandHelper<_ID>( \
aId, aSink, aObj); \
} \
template <> \
bool _DISPATCHER::Dispatch<_ID>(SinkType & aSink, ObjectType & aObj) { \
return DispatchMethod<_SYNC>::Run(aSink, &_METHOD, aObj); \
} \
template <> \
struct _DISPATCHER::MethodInfo<_ID> { \
using MethodType = decltype(&_METHOD); \
}; \
template <> \
constexpr CommandSyncType _DISPATCHER::SyncType<_ID>() { \
return _SYNC; \
} \
template <> \
constexpr size_t _DISPATCHER::Id<decltype(&_METHOD), &_METHOD>() { \
return _ID; \
}
namespace ipc {
template <typename T>
struct IPDLParamTraits;
template <>
struct IPDLParamTraits<mozilla::BasicSource> {
public:
typedef mozilla::BasicSource paramType;
static void Write(IPC::Message* aMsg, IProtocol* aActor,
const paramType& aParam) {
MOZ_ASSERT(aParam.mProducer);
WriteIPDLParam(aMsg, aActor, *aParam.mProducer.get());
}
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
IProtocol* aActor, paramType* aResult) {
Producer* producer = new Producer;
bool ret = ReadIPDLParam(aMsg, aIter, aActor, producer);
aResult->mProducer.reset(producer);
return ret;
}
};
template <>
struct IPDLParamTraits<mozilla::BasicSink> {
public:
typedef mozilla::BasicSink paramType;
static void Write(IPC::Message* aMsg, IProtocol* aActor,
const paramType& aParam) {
MOZ_ASSERT(aParam.mConsumer);
WriteIPDLParam(aMsg, aActor, *aParam.mConsumer.get());
}
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
IProtocol* aActor, paramType* aResult) {
Consumer* consumer = new Consumer;
bool ret = ReadIPDLParam(aMsg, aIter, aActor, consumer);
aResult->mConsumer.reset(consumer);
return ret;
}
};
template <typename Command>
struct IPDLParamTraits<mozilla::CommandSource<Command>>
: public IPDLParamTraits<mozilla::BasicSource> {
public:
typedef mozilla::CommandSource<Command> paramType;
};
template <typename Command>
struct IPDLParamTraits<mozilla::CommandSink<Command>>
: public IPDLParamTraits<mozilla::BasicSink> {
public:
typedef mozilla::CommandSink<Command> paramType;
};
template <typename Command>
struct IPDLParamTraits<mozilla::SyncCommandSource<Command>>
: public IPDLParamTraits<mozilla::CommandSource<Command>> {
public:
typedef mozilla::SyncCommandSource<Command> paramType;
typedef typename paramType::BaseType paramBaseType;
static void Write(IPC::Message* aMsg, IProtocol* aActor,
const paramType& aParam) {
WriteIPDLParam(aMsg, aActor, static_cast<const paramBaseType&>(aParam));
WriteIPDLParam(aMsg, aActor, aParam.mConsumer);
}
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
IProtocol* aActor, paramType* aParam) {
bool result =
ReadIPDLParam(aMsg, aIter, aActor, static_cast<paramBaseType*>(aParam));
return result && ReadIPDLParam(aMsg, aIter, aActor, &aParam->mConsumer);
}
};
template <typename Command>
struct IPDLParamTraits<mozilla::SyncCommandSink<Command>>
: public IPDLParamTraits<mozilla::CommandSink<Command>> {
public:
typedef mozilla::SyncCommandSink<Command> paramType;
typedef typename paramType::BaseType paramBaseType;
static void Write(IPC::Message* aMsg, IProtocol* aActor,
const paramType& aParam) {
WriteIPDLParam(aMsg, aActor, static_cast<const paramBaseType&>(aParam));
WriteIPDLParam(aMsg, aActor, aParam.mProducer);
}
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
IProtocol* aActor, paramType* aParam) {
bool result =
ReadIPDLParam(aMsg, aIter, aActor, static_cast<paramBaseType*>(aParam));
return result && ReadIPDLParam(aMsg, aIter, aActor, &aParam->mProducer);
}
};
} // namespace ipc
} // namespace mozilla
#endif // WEBGLCOMMANDQUEUE_H_

Просмотреть файл

@ -9,6 +9,7 @@
#include <queue>
#include "AccessCheck.h"
#include "CompositableHost.h"
#include "gfxConfig.h"
#include "gfxContext.h"
#include "gfxCrashReporterUtils.h"
@ -45,10 +46,12 @@
#include "nsIGfxInfo.h"
#include "nsIWidget.h"
#include "nsServiceManagerUtils.h"
#include "SharedSurfaceGL.h"
#include "SVGObserverUtils.h"
#include "prenv.h"
#include "ScopedGLHelpers.h"
#include "VRManagerChild.h"
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/TextureClientSharedSurface.h"
#include "mozilla/layers/WebRenderUserData.h"
@ -56,9 +59,12 @@
// Local
#include "CanvasUtils.h"
#include "ClientWebGLContext.h"
#include "HostWebGLContext.h"
#include "WebGL1Context.h"
#include "WebGLActiveInfo.h"
#include "WebGLBuffer.h"
#include "WebGLChild.h"
#include "WebGLContextLossHandler.h"
#include "WebGLContextUtils.h"
#include "WebGLExtensions.h"
@ -129,16 +135,11 @@ WebGLContext::WebGLContext()
mAllowFBInvalidation(StaticPrefs::webgl_allow_fb_invalidation()),
mMsaaSamples((uint8_t)StaticPrefs::webgl_msaa_samples()) {
mGeneration = 0;
mInvalidated = false;
mCapturedFrameInvalidated = false;
mShouldPresent = true;
mResetLayer = true;
mOptionsFrozen = false;
mDisableExtensions = false;
mIsMesa = false;
mWebGLError = 0;
mVRReady = false;
mXRCompatible = false;
mViewportX = 0;
mViewportY = 0;
@ -156,9 +157,8 @@ WebGLContext::WebGLContext()
}
mAllowContextRestore = true;
mDisallowContextRestore = false;
mLastLossWasSimulated = false;
mLoseContextOnMemoryPressure = false;
mCanLoseContextInForeground = true;
mAlreadyGeneratedWarnings = 0;
mAlreadyWarnedAboutFakeVertexAttrib0 = false;
@ -172,20 +172,12 @@ WebGLContext::WebGLContext()
mMaxWarnings = 0;
}
mLastUseIndex = 0;
mDisableFragHighP = false;
mDrawCallsSinceLastFlush = 0;
}
WebGLContext::~WebGLContext() {
if (NS_IsMainThread()) {
// XXX mtseng: bug 709490, not thread safe
WebGLMemoryTracker::RemoveWebGLContext(this);
}
RemovePostRefreshObserver();
DestroyResourcesAndContext();
}
@ -292,7 +284,7 @@ void WebGLContext::DestroyResourcesAndContext() {
mDynDGpuManager = nullptr;
}
void WebGLContext::Invalidate() {
void ClientWebGLContext::Invalidate() {
if (!mCanvasElement) return;
mCapturedFrameInvalidated = true;
@ -717,33 +709,12 @@ bool WebGLContext::EnsureDefaultFB() {
void WebGLContext::ThrowEvent_WebGLContextCreationError(
const nsACString& text) {
RefPtr<EventTarget> target = mCanvasElement;
if (!target && mOffscreenCanvas) {
target = mOffscreenCanvas;
} else if (!target) {
GenerateWarning("Failed to create WebGL context: %s", text.BeginReading());
return;
}
const auto kEventName = NS_LITERAL_STRING("webglcontextcreationerror");
WebGLContextEventInit eventInit;
// eventInit.mCancelable = true; // The spec says this, but it's silly.
eventInit.mStatusMessage = NS_ConvertASCIItoUTF16(text);
const RefPtr<WebGLContextEvent> event =
WebGLContextEvent::Constructor(target, kEventName, eventInit);
event->SetTrusted(true);
target->DispatchEvent(*event);
//////
GenerateWarning("Failed to create WebGL context: %s", text.BeginReading());
MOZ_ASSERT(mHost);
mHost->PostContextCreationError(nsCString(text));
}
NS_IMETHODIMP
WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
WebGLContext::DoSetDimensionsData WebGLContext::DoSetDimensions(
int32_t signedWidth, int32_t signedHeight) {
const FuncScope funcScope(*this, "<SetDimensions>");
(void)IsContextLost(); // We handle this ourselves.
@ -754,7 +725,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
}
GenerateWarning(
"Canvas size is too large (seems like a negative value wrapped)");
return NS_ERROR_OUT_OF_MEMORY;
return {NS_ERROR_OUT_OF_MEMORY, false};
}
uint32_t width = signedWidth;
@ -762,9 +733,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
// Early success return cases
// May have a OffscreenCanvas instead of an HTMLCanvasElement
if (GetCanvas()) GetCanvas()->InvalidateCanvas();
// Zero-sized surfaces can cause problems.
if (width == 0) width = 1;
@ -774,17 +742,17 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
if (gl) {
if (uint32_t(mRequestedSize.width) == width &&
uint32_t(mRequestedSize.height) == height) {
return NS_OK;
return {NS_OK, false};
}
if (IsContextLost()) return NS_OK;
if (IsContextLost()) return {NS_OK, false};
// If we've already drawn, we should commit the current buffer.
PresentScreenBuffer(gl->Screen());
PresentScreenBuffer();
if (IsContextLost()) {
GenerateWarning("WebGL context was lost due to swap failure.");
return NS_OK;
return {NS_OK, false};
}
// Kill our current default fb(s), for later lazy allocation.
@ -792,7 +760,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
mDefaultFB = nullptr;
mResetLayer = true;
return NS_OK;
return {NS_OK, false};
}
nsCString failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_UNKOWN");
@ -804,14 +772,6 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
// At this point we know that we're not just resizing an existing context,
// we are initializing a new context.
// if we exceeded either the global or the per-principal limit for WebGL
// contexts, lose the oldest-used context now to free resources. Note that we
// can't do that in the WebGLContext constructor as we don't have a canvas
// element yet there. Here is the right place to do so, as we are about to
// create the OpenGL context and that is what can fail if we already have too
// many.
LoseOldestWebGLContextIfLimitExceeded();
// We're going to create an entirely new context. If our
// generation is not 0 right now (that is, if this isn't the first
// context we're creating), we may have to dispatch a context lost
@ -825,7 +785,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_TOO_MANY");
const nsLiteralCString text("Too many WebGL contexts created this run.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
return {NS_ERROR_FAILURE, true};
}
// increment the generation number - Do this early because later
@ -846,7 +806,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
}
const nsLiteralCString text("WebGL is currently disabled.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
return {NS_ERROR_FAILURE, true};
}
if (StaticPrefs::webgl_disable_fail_if_major_performance_caveat()) {
@ -861,7 +821,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
"failIfMajorPerformanceCaveat: Compositor is not"
" hardware-accelerated.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
return {NS_ERROR_FAILURE, true};
}
}
@ -888,7 +848,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
}
failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_REASON");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
return {NS_ERROR_FAILURE, true};
}
MOZ_ASSERT(gl);
@ -902,7 +862,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
"failIfMajorPerformanceCaveat: Driver is not"
" hardware-accelerated.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
return {NS_ERROR_FAILURE, true};
}
#ifdef XP_WIN
@ -914,7 +874,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_DXGL_INTEROP2");
const nsLiteralCString text("Caveat: WGL without DXGLInterop2.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
return {NS_ERROR_FAILURE, true};
}
#endif
}
@ -927,7 +887,7 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBGL_BACKBUFFER");
const nsLiteralCString text("Initializing WebGL backbuffer failed.");
ThrowEvent_WebGLContextCreationError(text);
return NS_ERROR_FAILURE;
return {NS_ERROR_FAILURE, true};
}
if (GLContext::ShouldSpew()) {
@ -1000,10 +960,15 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) {
failureId = NS_LITERAL_CSTRING("SUCCESS");
gl->ResetSyncCallCount("WebGLContext Initialization");
return NS_OK;
return {NS_OK, true};
}
void WebGLContext::LoseOldestWebGLContextIfLimitExceeded() {
void WebGLContext::SetCompositableHost(
RefPtr<layers::CompositableHost>& aCompositableHost) {
mCompositableHost = aCompositableHost;
}
void ClientWebGLContext::LoseOldestWebGLContextIfLimitExceeded() {
const auto maxWebGLContexts = StaticPrefs::webgl_max_contexts();
auto maxWebGLContextsPerPrincipal =
StaticPrefs::webgl_max_contexts_per_principal();
@ -1023,11 +988,13 @@ void WebGLContext::LoseOldestWebGLContextIfLimitExceeded() {
// couldn't distinguish older ones when choosing which one to lose first.
UpdateLastUseIndex();
WebGLMemoryTracker::ContextsArrayType& contexts =
WebGLMemoryTracker::Contexts();
CompositorBridgeChild* cbc = CompositorBridgeChild::Get();
MOZ_ASSERT(cbc);
nsTArray<PWebGLChild*> childArray;
cbc->ManagedPWebGLChild(childArray);
// quick exit path, should cover a majority of cases
if (contexts.Length() <= maxWebGLContextsPerPrincipal) return;
if (childArray.Length() <= maxWebGLContextsPerPrincipal) return;
// note that here by "context" we mean "non-lost context". See the check for
// IsContextLost() below. Indeed, the point of this function is to maybe lose
@ -1035,59 +1002,64 @@ void WebGLContext::LoseOldestWebGLContextIfLimitExceeded() {
uint64_t oldestIndex = UINT64_MAX;
uint64_t oldestIndexThisPrincipal = UINT64_MAX;
const WebGLContext* oldestContext = nullptr;
const WebGLContext* oldestContextThisPrincipal = nullptr;
ClientWebGLContext* oldestContext = nullptr;
ClientWebGLContext* oldestContextThisPrincipal = nullptr;
size_t numContexts = 0;
size_t numContextsThisPrincipal = 0;
for (size_t i = 0; i < contexts.Length(); ++i) {
for (size_t i = 0; i < childArray.Length(); ++i) {
ClientWebGLContext* context =
static_cast<WebGLChild*>(childArray[i])->GetContext();
MOZ_ASSERT(context);
if (!context) {
continue;
}
// don't want to lose ourselves.
if (contexts[i] == this) continue;
if (context == this) continue;
if (!contexts[i]->gl) continue;
if (!contexts[i]->GetCanvas()) {
if (!context->GetCanvas()) {
// Zombie context: the canvas is already destroyed, but something else
// (typically the compositor) is still holding on to the context.
// Killing zombies is a no-brainer.
const_cast<WebGLContext*>(contexts[i])->LoseContext();
context->LoseContext();
continue;
}
numContexts++;
if (contexts[i]->mLastUseIndex < oldestIndex) {
oldestIndex = contexts[i]->mLastUseIndex;
oldestContext = contexts[i];
if (context->mLastUseIndex < oldestIndex) {
oldestIndex = context->mLastUseIndex;
oldestContext = context;
}
nsIPrincipal* ourPrincipal = GetCanvas()->NodePrincipal();
nsIPrincipal* theirPrincipal = contexts[i]->GetCanvas()->NodePrincipal();
nsIPrincipal* theirPrincipal = context->GetCanvas()->NodePrincipal();
bool samePrincipal;
nsresult rv = ourPrincipal->Equals(theirPrincipal, &samePrincipal);
if (NS_SUCCEEDED(rv) && samePrincipal) {
numContextsThisPrincipal++;
if (contexts[i]->mLastUseIndex < oldestIndexThisPrincipal) {
oldestIndexThisPrincipal = contexts[i]->mLastUseIndex;
oldestContextThisPrincipal = contexts[i];
if (context->mLastUseIndex < oldestIndexThisPrincipal) {
oldestIndexThisPrincipal = context->mLastUseIndex;
oldestContextThisPrincipal = context;
}
}
}
if (numContextsThisPrincipal > maxWebGLContextsPerPrincipal) {
GenerateWarning(
PostWarning(nsPrintfCString(
"Exceeded %u live WebGL contexts for this principal, losing the "
"least recently used one.",
maxWebGLContextsPerPrincipal);
maxWebGLContextsPerPrincipal));
MOZ_ASSERT(oldestContextThisPrincipal); // if we reach this point, this
// can't be null
const_cast<WebGLContext*>(oldestContextThisPrincipal)->LoseContext();
oldestContextThisPrincipal->LoseContext();
} else if (numContexts > maxWebGLContexts) {
GenerateWarning(
"Exceeded %u live WebGL contexts, losing the least "
"recently used one.",
maxWebGLContexts);
PostWarning(
nsPrintfCString("Exceeded %u live WebGL contexts, losing the least "
"recently used one.",
maxWebGLContexts));
MOZ_ASSERT(oldestContext); // if we reach this point, this can't be null
const_cast<WebGLContext*>(oldestContext)->LoseContext();
oldestContext->LoseContext();
}
}
@ -1411,12 +1383,54 @@ void WebGLContext::BlitBackbufferToCurDriverFB() const {
}
}
Maybe<ICRData> WebGLContext::InitializeCanvasRenderer(
layers::LayersBackend backend) {
if (!gl) {
return Nothing();
}
ICRData ret;
ret.size = DrawingBufferSize();
ret.hasAlpha = mOptions.alpha;
ret.supportsAlpha = gl->Caps().alpha;
ret.isPremultAlpha = IsPremultAlpha();
TextureFlags flags = TextureFlags::ORIGIN_BOTTOM_LEFT;
if ((!IsPremultAlpha()) && mOptions.alpha) {
flags |= TextureFlags::NON_PREMULTIPLIED;
}
// NB: This is weak. Creating TextureClient objects in the host-side
// WebGLContext class... but these are different concepts of host/client.
// Host/ClientWebGLContext represent cross-process communication but
// TextureHost/Client represent synchronous texture access, which can
// be uniprocess and, for us, is. Also note that TextureClient couldn't
// be in the content process like ClientWebGLContext since TextureClient
// uses a GL context.
UniquePtr<gl::SurfaceFactory> factory = gl::GLScreenBuffer::CreateFactory(
gl, gl->Caps(), nullptr, backend, gl->IsANGLE(), flags);
mBackend = backend;
if (!factory) {
// Absolutely must have a factory here, so create a basic one
factory = MakeUnique<gl::SurfaceFactory_Basic>(gl, gl->Caps(), flags);
mBackend = LayersBackend::LAYERS_BASIC;
}
gl->Screen()->Morph(std::move(factory));
mVRReady = true;
return Some(ret);
}
// For an overview of how WebGL compositing works, see:
// https://wiki.mozilla.org/Platform/GFX/WebGL/Compositing
bool WebGLContext::PresentScreenBuffer(GLScreenBuffer* const targetScreen) {
const FuncScope funcScope(*this, "<PresentScreenBuffer>");
if (IsContextLost()) return false;
mDrawCallsSinceLastFlush = 0;
if (!mShouldPresent) return false;
ReportActivity();
@ -1464,18 +1478,94 @@ bool WebGLContext::PresentScreenBuffer(GLScreenBuffer* const targetScreen) {
return true;
}
// Prepare the context for capture before compositing
void WebGLContext::BeginComposition(GLScreenBuffer* const screen) {
// Present our screenbuffer, if needed.
PresentScreenBuffer(screen);
mDrawCallsSinceLastFlush = 0;
RefPtr<DataSourceSurface> GetTempSurface(const IntSize& aSize,
SurfaceFormat& aFormat) {
uint32_t stride = GetAlignedStride<8>(aSize.width, BytesPerPixel(aFormat));
return Factory::CreateDataSourceSurfaceWithStride(aSize, aFormat, stride);
}
// Clean up the context after captured for compositing
void WebGLContext::EndComposition() {
// Mark ourselves as no longer invalidated.
MarkContextClean();
UpdateLastUseIndex();
void WriteFrontToFile(gl::GLContext* gl, GLScreenBuffer* screen,
const char* fname, bool needsPremult) {
auto frontbuffer = screen->Front()->Surf();
IntSize readSize(frontbuffer->mSize);
SurfaceFormat format = frontbuffer->mHasAlpha ? SurfaceFormat::B8G8R8A8
: SurfaceFormat::B8G8R8X8;
RefPtr<DataSourceSurface> resultSurf = GetTempSurface(readSize, format);
if (NS_WARN_IF(!resultSurf)) {
MOZ_ASSERT_UNREACHABLE("FAIL");
return;
}
if (!gl->Readback(frontbuffer, resultSurf)) {
NS_WARNING("Failed to read back canvas surface.");
MOZ_ASSERT_UNREACHABLE("FAIL");
return;
}
if (needsPremult) {
gfxUtils::PremultiplyDataSurface(resultSurf, resultSurf);
}
MOZ_ASSERT(resultSurf);
gfxUtils::WriteAsPNG(resultSurf, fname);
}
bool WebGLContext::Present() {
if (!PresentScreenBuffer()) {
return false;
}
if (XRE_IsContentProcess()) {
// That's all!
return true;
}
// Set the CompositableHost to use the front buffer as the display,
TextureFlags flags = TextureFlags::ORIGIN_BOTTOM_LEFT;
if ((!IsPremultAlpha()) && mOptions.alpha) {
flags |= TextureFlags::NON_PREMULTIPLIED;
}
const auto& screen = gl->Screen();
if (!screen->Front()->Surf()) {
GenerateWarning(
"Present failed due to missing front buffer. Losing context.");
ForceLoseContext();
return false;
}
if (mBackend == LayersBackend::LAYERS_NONE) {
GenerateWarning(
"Present was not given a valid compositor layer type. Losing context.");
ForceLoseContext();
return false;
}
// TODO: I probably need to hold onto screen->Front()->Surf() somehow
layers::SurfaceDescriptor surfaceDescriptor;
screen->Front()->Surf()->ToSurfaceDescriptor(&surfaceDescriptor);
if (!mCompositableHost) {
return false;
}
wr::MaybeExternalImageId noExternalImageId = Nothing();
RefPtr<TextureHost> host = TextureHost::Create(
surfaceDescriptor, null_t(), nullptr, mBackend, flags, noExternalImageId);
if (!host) {
GenerateWarning("Present failed to create TextuteHost. Losing context.");
ForceLoseContext();
return false;
}
AutoTArray<CompositableHost::TimedTexture, 1> textures;
CompositableHost::TimedTexture* t = textures.AppendElement();
t->mTexture = host;
t->mTimeStamp = TimeStamp::Now();
t->mPictureRect = nsIntRect(nsIntPoint(0, 0), nsIntSize(host->GetSize()));
t->mFrameID = 0;
t->mProducerID = 0;
mCompositableHost->UseTextureHost(textures);
return true;
}
void WebGLContext::DummyReadFramebufferOperation() {
@ -1581,12 +1671,9 @@ void WebGLContext::EnqueueUpdateContextLossStatus() {
// At a bare minimum, from context lost to context restores, it would take 3
// full timer iterations: detection, webglcontextlost, webglcontextrestored.
void WebGLContext::UpdateContextLossStatus() {
if (!mCanvasElement && !mOffscreenCanvas) {
// the canvas is gone. That happens when the page was closed before we got
// this timer event. In this case, there's nothing to do here, just don't
// crash.
return;
}
MOZ_ASSERT(mHost);
mContextLossHandler.ClearTimer();
if (mContextStatus == ContextStatus::NotLost) {
// We don't know that we're lost, but we might be, so we need to
// check. If we're guilty, don't allow restores, though.
@ -1607,32 +1694,15 @@ void WebGLContext::UpdateContextLossStatus() {
if (mContextStatus == ContextStatus::LostAwaitingEvent) {
// The context has been lost and we haven't yet triggered the
// callback, so do that now.
const auto kEventName = NS_LITERAL_STRING("webglcontextlost");
const auto kCanBubble = CanBubble::eYes;
const auto kIsCancelable = Cancelable::eYes;
bool useDefaultHandler;
if (mCanvasElement) {
nsContentUtils::DispatchTrustedEvent(
mCanvasElement->OwnerDoc(), static_cast<nsIContent*>(mCanvasElement),
kEventName, kCanBubble, kIsCancelable, &useDefaultHandler);
} else {
// OffscreenCanvas case
RefPtr<Event> event = new Event(mOffscreenCanvas, nullptr, nullptr);
event->InitEvent(kEventName, kCanBubble, kIsCancelable);
event->SetTrusted(true);
useDefaultHandler = mOffscreenCanvas->DispatchEvent(
*event, CallerType::System, IgnoreErrors());
}
mHost->OnLostContext();
// We sent the callback, so we're just 'regular lost' now.
mContextStatus = ContextStatus::Lost;
// If we're told to use the default handler, it means the script
// didn't bother to handle the event. In this case, we shouldn't
// auto-restore the context.
if (useDefaultHandler) mAllowContextRestore = false;
// Fall through.
// This is cleared if the context lost event handler permits it
// (i.e. is not the default handler)
mDisallowContextRestore = true;
return;
}
if (mContextStatus == ContextStatus::Lost) {
@ -1641,7 +1711,7 @@ void WebGLContext::UpdateContextLossStatus() {
// and supposed to.
// Are we allowed to restore the context?
if (!mAllowContextRestore) return;
if (mDisallowContextRestore || (!mAllowContextRestore)) return;
// If we're only simulated-lost, we shouldn't auto-restore, and
// instead we should wait for restoreContext() to be called.
@ -1655,8 +1725,9 @@ void WebGLContext::UpdateContextLossStatus() {
// Context is lost, but we should try to restore it.
if (mAllowContextRestore) {
if (NS_FAILED(
SetDimensions(mRequestedSize.width, mRequestedSize.height))) {
DoSetDimensionsData sdData =
DoSetDimensions(mRequestedSize.width, mRequestedSize.height);
if (NS_FAILED(sdData.result)) {
// Assume broken forever.
mAllowContextRestore = false;
}
@ -1670,20 +1741,7 @@ void WebGLContext::UpdateContextLossStatus() {
// Revival!
mContextStatus = ContextStatus::NotLost;
if (mCanvasElement) {
nsContentUtils::DispatchTrustedEvent(
mCanvasElement->OwnerDoc(), static_cast<nsIContent*>(mCanvasElement),
NS_LITERAL_STRING("webglcontextrestored"), CanBubble::eYes,
Cancelable::eYes);
} else {
RefPtr<Event> event = new Event(mOffscreenCanvas, nullptr, nullptr);
event->InitEvent(NS_LITERAL_STRING("webglcontextrestored"),
CanBubble::eYes, Cancelable::eYes);
event->SetTrusted(true);
mOffscreenCanvas->DispatchEvent(*event);
}
mHost->OnRestoredContext();
return;
}
}
@ -1706,6 +1764,7 @@ void WebGLContext::ForceRestoreContext() {
printf_stderr("WebGL(%p)::ForceRestoreContext\n", this);
mContextStatus = ContextStatus::LostAwaitingRestore;
mAllowContextRestore = true; // Hey, you did say 'force'.
mDisallowContextRestore = false;
// Queue up a task, since we know the status changed.
EnqueueUpdateContextLossStatus();
@ -1928,8 +1987,6 @@ ScopedDrawCallWrapper::~ScopedDrawCallWrapper() {
if (mWebGL.mBoundDrawFramebuffer) return;
mWebGL.mResolvedDefaultFB = nullptr;
mWebGL.Invalidate();
mWebGL.mShouldPresent = true;
}
@ -2108,27 +2165,27 @@ CheckedUint32 WebGLContext::GetUnpackSize(bool isFunc3D, uint32_t width,
////////////////
const auto& maybeRowLength = mPixelStore_UnpackRowLength;
const auto& maybeImageHeight = mPixelStore_UnpackImageHeight;
const auto& maybeRowLength = mPixelStore.mUnpackRowLength;
const auto& maybeImageHeight = mPixelStore.mUnpackImageHeight;
const auto usedPixelsPerRow =
CheckedUint32(mPixelStore_UnpackSkipPixels) + width;
CheckedUint32(mPixelStore.mUnpackSkipPixels) + width;
const auto stridePixelsPerRow =
(maybeRowLength ? CheckedUint32(maybeRowLength) : usedPixelsPerRow);
const auto usedRowsPerImage =
CheckedUint32(mPixelStore_UnpackSkipRows) + height;
CheckedUint32(mPixelStore.mUnpackSkipRows) + height;
const auto strideRowsPerImage =
(maybeImageHeight ? CheckedUint32(maybeImageHeight) : usedRowsPerImage);
const uint32_t skipImages = (isFunc3D ? mPixelStore_UnpackSkipImages : 0);
const uint32_t skipImages = (isFunc3D ? mPixelStore.mUnpackSkipImages : 0);
const CheckedUint32 usedImages = CheckedUint32(skipImages) + depth;
////////////////
CheckedUint32 strideBytesPerRow = bytesPerPixel * stridePixelsPerRow;
strideBytesPerRow =
RoundUpToMultipleOf(strideBytesPerRow, mPixelStore_UnpackAlignment);
RoundUpToMultipleOf(strideBytesPerRow, mPixelStore.mUnpackAlignment);
const CheckedUint32 strideBytesPerImage =
strideBytesPerRow * strideRowsPerImage;
@ -2164,21 +2221,14 @@ WebGLContext::GetVRFrame() {
if (!mVRScreen) {
auto caps = gl->Screen()->mCaps;
mVRScreen = GLScreenBuffer::Create(gl, gfx::IntSize(1, 1), caps);
RefPtr<ImageBridgeChild> imageBridge = ImageBridgeChild::GetSingleton();
if (imageBridge) {
TextureFlags flags = TextureFlags::ORIGIN_BOTTOM_LEFT;
UniquePtr<gl::SurfaceFactory> factory =
gl::GLScreenBuffer::CreateFactory(gl, caps, imageBridge.get(), flags);
mVRScreen->Morph(std::move(factory));
}
}
MOZ_ASSERT(mVRScreen);
// Swap buffers as though composition has occurred.
// We will then share the resulting front buffer to be submitted to the VR
// compositor.
BeginComposition(mVRScreen.get());
EndComposition();
PresentScreenBuffer(mVRScreen.get());
if (IsContextLost()) return nullptr;
@ -2206,8 +2256,7 @@ WebGLContext::GetVRFrame() {
* We will then share the resulting front buffer to be submitted to the VR
* compositor.
*/
BeginComposition();
EndComposition();
PresentScreenBuffer();
gl::GLScreenBuffer* screen = gl->Screen();
if (!screen) return nullptr;
@ -2230,24 +2279,20 @@ void WebGLContext::EnsureVRReady() {
// compositor renders a WebGL canvas for the first time. This causes canvases
// not added to the DOM not to work properly with WebVR. Here we mimic what
// InitializeCanvasRenderer does internally as a workaround.
const auto imageBridge = ImageBridgeChild::GetSingleton();
if (imageBridge) {
const auto caps = gl->Screen()->mCaps;
auto flags = TextureFlags::ORIGIN_BOTTOM_LEFT;
if (!IsPremultAlpha() && mOptions.alpha) {
flags |= TextureFlags::NON_PREMULTIPLIED;
}
auto factory =
gl::GLScreenBuffer::CreateFactory(gl, caps, imageBridge.get(), flags);
gl->Screen()->Morph(std::move(factory));
#if defined(MOZ_WIDGET_ANDROID)
// On Android we are using a different GLScreenBuffer for WebVR, so we need
// a resize here because PresentScreenBuffer() may not be called for the
// gl->Screen() after we set the new factory.
gl->Screen()->Resize(DrawingBufferSize());
#endif
mVRReady = true;
const auto caps = gl->Screen()->mCaps;
auto flags = TextureFlags::ORIGIN_BOTTOM_LEFT;
if (!IsPremultAlpha() && mOptions.alpha) {
flags |= TextureFlags::NON_PREMULTIPLIED;
}
auto factory = gl::GLScreenBuffer::CreateFactory(gl, caps, nullptr, flags);
gl->Screen()->Morph(std::move(factory));
#if defined(MOZ_WIDGET_ANDROID)
// On Android we are using a different GLScreenBuffer for WebVR, so we need
// a resize here because PresentScreenBuffer() may not be called for the
// gl->Screen() after we set the new factory.
gl->Screen()->Resize(DrawingBufferSize());
#endif
mVRReady = true;
}
////////////////////////////////////////////////////////////////////////////////
@ -2292,6 +2337,36 @@ bool WebGLContext::ValidateArrayBufferView(const dom::ArrayBufferView& view,
return true;
}
bool ClientWebGLContext::ValidateArrayBufferView(
const dom::ArrayBufferView& view, GLuint elemOffset,
GLuint elemCountOverride, const GLenum errorEnum, uint8_t** const out_bytes,
size_t* const out_byteLen) {
view.ComputeLengthAndData();
uint8_t* const bytes = view.DataAllowShared();
const size_t byteLen = view.LengthAllowShared();
const auto& elemSize = SizeOfViewElem(view);
size_t elemCount = byteLen / elemSize;
if (elemOffset > elemCount) {
EnqueueErrorInvalidValue("Invalid offset into ArrayBufferView.");
return false;
}
elemCount -= elemOffset;
if (elemCountOverride) {
if (elemCountOverride > elemCount) {
EnqueueErrorInvalidValue("Invalid sub-length for ArrayBufferView.");
return false;
}
elemCount = elemCountOverride;
}
*out_bytes = bytes + (elemOffset * elemSize);
*out_byteLen = elemCount * elemSize;
return true;
}
////
void WebGLContext::UpdateMaxDrawBuffers() {
@ -2438,12 +2513,7 @@ webgl::AvailabilityRunnable* WebGLContext::EnsureAvailabilityRunnable() {
RefPtr<webgl::AvailabilityRunnable> runnable =
new webgl::AvailabilityRunnable(this);
Document* document = GetOwnerDoc();
if (document) {
document->Dispatch(TaskCategory::Other, runnable.forget());
} else {
NS_DispatchToCurrentThread(runnable.forget());
}
NS_DispatchToCurrentThread(runnable.forget());
}
return mAvailabilityRunnable;
}
@ -2567,46 +2637,4 @@ void DynDGpuManager::DispatchTick(
}
} // namespace webgl
////////////////////////////////////////////////////////////////////////////////
// XPCOM goop
void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& callback,
const std::vector<IndexedBufferBinding>& field,
const char* name, uint32_t flags) {
for (const auto& cur : field) {
ImplCycleCollectionTraverse(callback, cur.mBufferBinding, name, flags);
}
}
void ImplCycleCollectionUnlink(std::vector<IndexedBufferBinding>& field) {
field.clear();
}
////
NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLContext)
NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLContext)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(
WebGLContext, mCanvasElement, mOffscreenCanvas, mExtensions,
mBound2DTextures, mBoundCubeMapTextures, mBound3DTextures,
mBound2DArrayTextures, mBoundSamplers, mBoundArrayBuffer,
mBoundCopyReadBuffer, mBoundCopyWriteBuffer, mBoundPixelPackBuffer,
mBoundPixelUnpackBuffer, mBoundTransformFeedback,
mBoundTransformFeedbackBuffer, mBoundUniformBuffer, mCurrentProgram,
mBoundDrawFramebuffer, mBoundReadFramebuffer, mBoundRenderbuffer,
mBoundVertexArray, mDefaultVertexArray, mQuerySlot_SamplesPassed,
mQuerySlot_TFPrimsWritten, mQuerySlot_TimeElapsed)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLContext)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
// If the exact way we cast to nsISupports here ever changes, fix our
// ToSupports() method.
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports,
nsICanvasRenderingContextInternal)
NS_INTERFACE_MAP_END
} // namespace mozilla

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -3,7 +3,7 @@
* 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 "ClientWebGLContext.h"
#include <limits>
@ -246,75 +246,21 @@ void WebGLContext::BindBufferRangeImpl(GLenum target, GLuint index,
void WebGLContext::BufferDataImpl(GLenum target, uint64_t dataLen,
const uint8_t* data, GLenum usage) {
const FuncScope funcScope(*this, "bufferData");
if (IsContextLost()) return;
const auto& buffer = ValidateBufferSelection(target);
if (!buffer) return;
buffer->BufferData(target, dataLen, data, usage);
}
////
void WebGLContext::BufferData(GLenum target, WebGLsizeiptr size, GLenum usage) {
const FuncScope funcScope(*this, "bufferData");
if (IsContextLost()) return;
if (!ValidateNonNegative("size", size)) return;
////
const auto checkedSize = CheckedInt<size_t>(size);
if (!checkedSize.isValid())
return ErrorOutOfMemory("size too large for platform.");
#if defined(XP_MACOSX)
// bug 1573048
if (gl->WorkAroundDriverBugs() && size > 1200000000) {
return ErrorOutOfMemory(
"Allocations larger than 1200000000 fail on macOS.");
}
#endif
const UniqueBuffer zeroBuffer(calloc(checkedSize.value(), 1u));
if (!zeroBuffer) return ErrorOutOfMemory("Failed to allocate zeros.");
BufferDataImpl(target, uint64_t{checkedSize.value()},
(const uint8_t*)zeroBuffer.get(), usage);
}
void WebGLContext::BufferData(GLenum target,
const dom::Nullable<dom::ArrayBuffer>& maybeSrc,
GLenum usage) {
const FuncScope funcScope(*this, "bufferData");
if (IsContextLost()) return;
if (!ValidateNonNull("src", maybeSrc)) return;
const auto& src = maybeSrc.Value();
src.ComputeLengthAndData();
BufferDataImpl(target, src.LengthAllowShared(), src.DataAllowShared(), usage);
}
void WebGLContext::BufferData(GLenum target, const dom::ArrayBufferView& src,
GLenum usage, GLuint srcElemOffset,
GLuint srcElemCountOverride) {
const FuncScope funcScope(*this, "bufferData");
if (IsContextLost()) return;
uint8_t* bytes;
size_t byteLen;
if (!ValidateArrayBufferView(src, srcElemOffset, srcElemCountOverride,
LOCAL_GL_INVALID_VALUE, &bytes, &byteLen)) {
return;
}
BufferDataImpl(target, byteLen, bytes, usage);
}
////////////////////////////////////////
void WebGLContext::BufferSubDataImpl(GLenum target, WebGLsizeiptr dstByteOffset,
uint64_t dataLen, const uint8_t* data) {
const FuncScope funcScope(*this, "bufferSubData");
if (IsContextLost()) return;
if (!ValidateNonNegative("byteOffset", dstByteOffset)) return;
@ -324,35 +270,6 @@ void WebGLContext::BufferSubDataImpl(GLenum target, WebGLsizeiptr dstByteOffset,
buffer->BufferSubData(target, uint64_t(dstByteOffset), dataLen, data);
}
////
void WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
const dom::ArrayBuffer& src) {
const FuncScope funcScope(*this, "bufferSubData");
if (IsContextLost()) return;
src.ComputeLengthAndData();
BufferSubDataImpl(target, dstByteOffset, src.LengthAllowShared(),
src.DataAllowShared());
}
void WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
const dom::ArrayBufferView& src,
GLuint srcElemOffset,
GLuint srcElemCountOverride) {
const FuncScope funcScope(*this, "bufferSubData");
if (IsContextLost()) return;
uint8_t* bytes;
size_t byteLen;
if (!ValidateArrayBufferView(src, srcElemOffset, srcElemCountOverride,
LOCAL_GL_INVALID_VALUE, &bytes, &byteLen)) {
return;
}
BufferSubDataImpl(target, dstByteOffset, byteLen, bytes);
}
////////////////////////////////////////
already_AddRefed<WebGLBuffer> WebGLContext::CreateBuffer() {

Просмотреть файл

@ -0,0 +1,123 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 WEBGLCONTEXTENDPOINT_H_
#define WEBGLCONTEXTENDPOINT_H_
#include "mozilla/GfxMessageUtils.h"
#include "nsString.h"
#include "mozilla/dom/WebGLTypes.h"
namespace mozilla {
class ClientWebGLContext;
class HostWebGLContext;
class WebGLActiveInfo;
class WebGLBuffer;
class WebGLContext;
class WebGLQuery;
class WebGLShader;
class WebGLShaderPrecisionFormat;
class WebGLTexture;
class WebGLVertexArray;
namespace dom {
class Float32ArrayOrUnrestrictedFloatSequence;
class Int32ArrayOrLongSequence;
class Uint32ArrayOrUnsignedLongSequence;
}
namespace layers {
class CanvasRenderer;
class Layer;
class LayerManager;
class WebRenderCanvasData;
}
/**
* Pure virtual interface for host and client WebGLContext endpoints.
*/
class WebGLContextEndpoint {
public:
WebGLVersion GetVersion() { return mVersion; }
// When we want to let the host know the "real" method that called it, we
// pass one of these. This information should only be used for diagnostic
// purposes (e.g. warning and error messages)
enum FuncScopeId {
FuncScopeIdError = 0,
compressedTexImage2D,
compressedTexImage3D,
compressedTexSubImage2D,
compressedTexSubImage3D,
copyTexSubImage2D,
copyTexSubImage3D,
drawElements,
drawElementsInstanced,
drawRangeElements,
renderbufferStorage,
renderbufferStorageMultisample,
texImage2D,
texImage3D,
TexStorage2D,
TexStorage3D,
texSubImage2D,
texSubImage3D,
vertexAttrib1f,
vertexAttrib1fv,
vertexAttrib2f,
vertexAttrib2fv,
vertexAttrib3f,
vertexAttrib3fv,
vertexAttrib4f,
vertexAttrib4fv,
vertexAttribI4i,
vertexAttribI4iv,
vertexAttribI4ui,
vertexAttribI4uiv,
vertexAttribIPointer,
vertexAttribPointer
};
protected:
static const char* GetFuncScopeName(FuncScopeId aId) {
#define FUNC_SCOPE_NAME(_name) [FuncScopeId::_name] = #_name,
static constexpr const char* const FuncScopeNames[] = {
FUNC_SCOPE_NAME(compressedTexImage2D) FUNC_SCOPE_NAME(compressedTexImage3D) FUNC_SCOPE_NAME(
compressedTexSubImage2D) FUNC_SCOPE_NAME(compressedTexSubImage3D)
FUNC_SCOPE_NAME(copyTexSubImage2D) FUNC_SCOPE_NAME(copyTexSubImage3D) FUNC_SCOPE_NAME(
drawElements) FUNC_SCOPE_NAME(drawElementsInstanced)
FUNC_SCOPE_NAME(drawRangeElements) FUNC_SCOPE_NAME(
renderbufferStorage) FUNC_SCOPE_NAME(renderbufferStorageMultisample)
FUNC_SCOPE_NAME(texImage2D) FUNC_SCOPE_NAME(texImage3D) FUNC_SCOPE_NAME(
TexStorage2D) FUNC_SCOPE_NAME(TexStorage3D) FUNC_SCOPE_NAME(texSubImage2D)
FUNC_SCOPE_NAME(texSubImage3D) FUNC_SCOPE_NAME(vertexAttrib1f)
FUNC_SCOPE_NAME(vertexAttrib1fv) FUNC_SCOPE_NAME(vertexAttrib2f)
FUNC_SCOPE_NAME(vertexAttrib2fv) FUNC_SCOPE_NAME(vertexAttrib3f)
FUNC_SCOPE_NAME(vertexAttrib3fv) FUNC_SCOPE_NAME(vertexAttrib4f)
FUNC_SCOPE_NAME(vertexAttrib4fv) FUNC_SCOPE_NAME(
vertexAttribI4i) FUNC_SCOPE_NAME(vertexAttribI4iv)
FUNC_SCOPE_NAME(vertexAttribI4ui)
FUNC_SCOPE_NAME(vertexAttribI4uiv)
FUNC_SCOPE_NAME(vertexAttribIPointer)
FUNC_SCOPE_NAME(vertexAttribPointer)};
#undef FUNC_SCOPE_NAME
if (static_cast<uint32_t>(aId) < static_cast<uint32_t>(arraysize(FuncScopeNames))) {
return FuncScopeNames[aId];
}
return "<Illegal FuncScope ID>";
}
protected:
WebGLContextEndpoint(WebGLVersion aVersion) : mVersion(aVersion) {}
virtual ~WebGLContextEndpoint(){};
WebGLVersion mVersion;
};
} // namespace mozilla
#endif // WEBGLCONTEXTENDPOINT_H_

Просмотреть файл

@ -4,8 +4,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLContext.h"
#include "WebGLContextEndpoint.h"
#include "WebGLContextUtils.h"
#include "WebGLExtensions.h"
#include "ClientWebGLExtensions.h"
#include "GLContext.h"
#include "nsString.h"
@ -16,7 +18,8 @@
namespace mozilla {
/*static*/ const char* WebGLContext::GetExtensionString(WebGLExtensionID ext) {
/*static*/ const char* ClientWebGLContext::GetExtensionString(
WebGLExtensionID ext) {
typedef EnumeratedArray<WebGLExtensionID, WebGLExtensionID::Max, const char*>
names_array_t;
@ -275,12 +278,12 @@ WebGLExtensionBase* WebGLContext::EnableSupportedExtension(
return extension;
}
void WebGLContext::GetExtension(JSContext* cx, const nsAString& wideName,
JS::MutableHandle<JSObject*> retval,
dom::CallerType callerType, ErrorResult& rv) {
void ClientWebGLContext::GetExtension(JSContext* cx, const nsAString& wideName,
JS::MutableHandle<JSObject*> retval,
dom::CallerType callerType,
ErrorResult& rv) {
retval.set(nullptr);
const FuncScope funcScope(*this, "getExtension");
if (IsContextLost()) return;
const FuncScope funcScope(this, "getExtension");
NS_LossyConvertUTF16toASCII name(wideName);
@ -298,15 +301,12 @@ void WebGLContext::GetExtension(JSContext* cx, const nsAString& wideName,
if (ext == WebGLExtensionID::Max) return;
// step 2: check if the extension is supported
if (!IsExtensionSupported(callerType, ext)) return;
// step 3: if the extension hadn't been previously been created, create it
// now, thus enabling it
WebGLExtensionBase* extObj = EnableSupportedExtension(callerType, ext);
// step 2: if the extension hadn't been previously been created then we
// have to tell the host we are using it
ClientWebGLExtensionBase* extObj = GetExtension(callerType, ext, true);
if (!extObj) return;
// Step 4: Enable any implied extensions.
// Step 3: Enable any implied extensions.
switch (ext) {
case WebGLExtensionID::EXT_color_buffer_float:
EnableSupportedExtension(callerType, WebGLExtensionID::EXT_float_blend,
@ -337,7 +337,7 @@ void WebGLContext::GetExtension(JSContext* cx, const nsAString& wideName,
retval.set(WebGLObjectAsJSObject(cx, extObj, rv));
}
void WebGLContext::EnableExtension(WebGLExtensionID ext) {
void WebGLContext::CreateExtension(WebGLExtensionID ext) {
MOZ_ASSERT(IsExtensionEnabled(ext) == false);
WebGLExtensionBase* obj = nullptr;
@ -466,24 +466,101 @@ void WebGLContext::EnableExtension(WebGLExtensionID ext) {
mExtensions[ext] = obj;
}
void WebGLContext::GetSupportedExtensions(
dom::Nullable<nsTArray<nsString> >& retval, dom::CallerType callerType) {
retval.SetNull();
const Maybe<ExtensionSets> WebGLContext::GetSupportedExtensions() {
const FuncScope funcScope(*this, "getSupportedExtensions");
if (IsContextLost()) return;
nsTArray<nsString>& arr = retval.SetValue();
if (IsContextLost()) return Nothing();
Maybe<ExtensionSets> ret = Some(ExtensionSets());
auto& sets = ret.ref();
for (size_t i = 0; i < size_t(WebGLExtensionID::Max); i++) {
const auto extension = WebGLExtensionID(i);
if (extension == WebGLExtensionID::MOZ_debug)
continue; // Hide MOZ_debug from this list.
if (IsExtensionSupported(callerType, extension)) {
const char* extStr = GetExtensionString(extension);
arr.AppendElement(NS_ConvertUTF8toUTF16(extStr));
if (IsExtensionSupported(dom::CallerType::NonSystem, extension)) {
sets.mNonSystem.AppendElement(extension);
} else if (IsExtensionSupported(dom::CallerType::System, extension)) {
sets.mSystem.AppendElement(extension);
}
}
return ret;
}
ClientWebGLExtensionBase* ClientWebGLContext::UseExtension(
WebGLExtensionID ext) {
switch (ext) {
// ANGLE_
case WebGLExtensionID::ANGLE_instanced_arrays:
return new ClientWebGLExtensionInstancedArrays(this);
// EXT_
case WebGLExtensionID::EXT_blend_minmax:
return new ClientWebGLExtensionBlendMinMax(this);
case WebGLExtensionID::EXT_color_buffer_float:
return new ClientWebGLExtensionEXTColorBufferFloat(this);
case WebGLExtensionID::EXT_color_buffer_half_float:
return new ClientWebGLExtensionColorBufferHalfFloat(this);
case WebGLExtensionID::EXT_disjoint_timer_query:
return new ClientWebGLExtensionDisjointTimerQuery(this);
case WebGLExtensionID::EXT_frag_depth:
return new ClientWebGLExtensionFragDepth(this);
case WebGLExtensionID::EXT_shader_texture_lod:
return new ClientWebGLExtensionShaderTextureLod(this);
case WebGLExtensionID::EXT_sRGB:
return new ClientWebGLExtensionSRGB(this);
case WebGLExtensionID::EXT_texture_compression_bptc:
return new ClientWebGLExtensionCompressedTextureBPTC(this);
case WebGLExtensionID::EXT_texture_compression_rgtc:
return new ClientWebGLExtensionCompressedTextureRGTC(this);
case WebGLExtensionID::EXT_texture_filter_anisotropic:
return new ClientWebGLExtensionTextureFilterAnisotropic(this);
// MOZ_
case WebGLExtensionID::MOZ_debug:
return new ClientWebGLExtensionMOZDebug(this);
// OES_
case WebGLExtensionID::OES_element_index_uint:
return new ClientWebGLExtensionElementIndexUint(this);
case WebGLExtensionID::OES_standard_derivatives:
return new ClientWebGLExtensionStandardDerivatives(this);
case WebGLExtensionID::OES_texture_float:
return new ClientWebGLExtensionTextureFloat(this);
case WebGLExtensionID::OES_texture_float_linear:
return new ClientWebGLExtensionTextureFloatLinear(this);
case WebGLExtensionID::OES_texture_half_float:
return new ClientWebGLExtensionTextureHalfFloat(this);
case WebGLExtensionID::OES_texture_half_float_linear:
return new ClientWebGLExtensionTextureHalfFloatLinear(this);
case WebGLExtensionID::OES_vertex_array_object:
return new ClientWebGLExtensionVertexArray(this);
// WEBGL_
case WebGLExtensionID::WEBGL_color_buffer_float:
return new ClientWebGLExtensionColorBufferFloat(this);
case WebGLExtensionID::WEBGL_compressed_texture_astc:
return new ClientWebGLExtensionCompressedTextureASTC(this);
case WebGLExtensionID::WEBGL_compressed_texture_etc:
return new ClientWebGLExtensionCompressedTextureES3(this);
case WebGLExtensionID::WEBGL_compressed_texture_etc1:
return new ClientWebGLExtensionCompressedTextureETC1(this);
case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
return new ClientWebGLExtensionCompressedTexturePVRTC(this);
case WebGLExtensionID::WEBGL_compressed_texture_s3tc:
return new ClientWebGLExtensionCompressedTextureS3TC(this);
case WebGLExtensionID::WEBGL_compressed_texture_s3tc_srgb:
return new ClientWebGLExtensionCompressedTextureS3TC_SRGB(this);
case WebGLExtensionID::WEBGL_debug_renderer_info:
return new ClientWebGLExtensionDebugRendererInfo(this);
case WebGLExtensionID::WEBGL_debug_shaders:
return new ClientWebGLExtensionDebugShaders(this);
case WebGLExtensionID::WEBGL_depth_texture:
return new ClientWebGLExtensionDepthTexture(this);
case WebGLExtensionID::WEBGL_draw_buffers:
return new ClientWebGLExtensionDrawBuffers(this);
case WebGLExtensionID::WEBGL_lose_context:
return new ClientWebGLExtensionLoseContext(this);
default:
MOZ_ASSERT_UNREACHABLE("illegal extension enum");
return nullptr;
}
}
} // namespace mozilla

Просмотреть файл

@ -140,7 +140,7 @@ void WebGLContext::DepthMask(WebGLboolean b) {
gl->fDepthMask(b);
}
void WebGLContext::DrawBuffers(const dom::Sequence<GLenum>& buffers) {
void WebGLContext::DrawBuffers(const nsTArray<GLenum>& buffers) {
const FuncScope funcScope(*this, "drawBuffers");
if (IsContextLost()) return;

Просмотреть файл

@ -659,36 +659,34 @@ void WebGLContext::FrontFace(GLenum mode) {
gl->fFrontFace(mode);
}
already_AddRefed<WebGLActiveInfo> WebGLContext::GetActiveAttrib(
const WebGLProgram& prog, GLuint index) {
Maybe<WebGLActiveInfo> WebGLContext::GetActiveAttrib(const WebGLProgram& prog,
GLuint index) {
const FuncScope funcScope(*this, "getActiveAttrib");
if (IsContextLost()) return nullptr;
if (IsContextLost()) return Nothing();
if (!ValidateObject("program", prog)) return nullptr;
if (!ValidateObject("program", prog)) return Nothing();
return prog.GetActiveAttrib(index);
}
already_AddRefed<WebGLActiveInfo> WebGLContext::GetActiveUniform(
const WebGLProgram& prog, GLuint index) {
Maybe<WebGLActiveInfo> WebGLContext::GetActiveUniform(const WebGLProgram& prog,
GLuint index) {
const FuncScope funcScope(*this, "getActiveUniform");
if (IsContextLost()) return nullptr;
if (IsContextLost()) return Nothing();
if (!ValidateObject("program", prog)) return nullptr;
if (!ValidateObject("program", prog)) return Nothing();
return prog.GetActiveUniform(index);
}
void WebGLContext::GetAttachedShaders(
const WebGLProgram& prog,
dom::Nullable<nsTArray<RefPtr<WebGLShader>>>& retval) {
retval.SetNull();
MaybeAttachedShaders WebGLContext::GetAttachedShaders(
const WebGLProgram& prog) {
const FuncScope funcScope(*this, "getAttachedShaders");
if (IsContextLost()) return;
if (IsContextLost()) return Nothing();
if (!ValidateObject("prog", prog)) return;
if (!ValidateObject("prog", prog)) return Nothing();
prog.GetAttachedShaders(&retval.SetValue());
return prog.GetAttachedShaders();
}
GLint WebGLContext::GetAttribLocation(const WebGLProgram& prog,
@ -701,41 +699,39 @@ GLint WebGLContext::GetAttribLocation(const WebGLProgram& prog,
return prog.GetAttribLocation(name);
}
JS::Value WebGLContext::GetBufferParameter(GLenum target, GLenum pname) {
MaybeWebGLVariant WebGLContext::GetBufferParameter(GLenum target,
GLenum pname) {
const FuncScope funcScope(*this, "getBufferParameter");
if (IsContextLost()) return JS::NullValue();
if (IsContextLost()) return Nothing();
const auto& slot = ValidateBufferSlot(target);
if (!slot) return JS::NullValue();
if (!slot) return Nothing();
const auto& buffer = *slot;
if (!buffer) {
ErrorInvalidOperation("Buffer for `target` is null.");
return JS::NullValue();
return Nothing();
}
switch (pname) {
case LOCAL_GL_BUFFER_SIZE:
return JS::NumberValue(buffer->ByteLength());
return AsSomeVariant(buffer->ByteLength());
case LOCAL_GL_BUFFER_USAGE:
return JS::NumberValue(buffer->Usage());
return AsSomeVariant(buffer->Usage());
default:
ErrorInvalidEnumInfo("pname", pname);
return JS::NullValue();
return Nothing();
}
}
JS::Value WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
GLenum target,
GLenum attachment,
GLenum pname,
ErrorResult& rv) {
MaybeWebGLVariant WebGLContext::GetFramebufferAttachmentParameter(
GLenum target, GLenum attachment, GLenum pname) {
const FuncScope funcScope(*this, "getFramebufferAttachmentParameter");
if (IsContextLost()) return JS::NullValue();
if (IsContextLost()) return Nothing();
if (!ValidateFramebufferTarget(target)) return JS::NullValue();
if (!ValidateFramebufferTarget(target)) return Nothing();
WebGLFramebuffer* fb;
switch (target) {
@ -752,7 +748,7 @@ JS::Value WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
MOZ_CRASH("GFX: Bad target.");
}
if (fb) return fb->GetAttachmentParameter(cx, target, attachment, pname, &rv);
if (fb) return fb->GetAttachmentParameter(target, attachment, pname);
////////////////////////////////////
@ -760,7 +756,7 @@ JS::Value WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
ErrorInvalidOperation(
"Querying against the default framebuffer is not"
" allowed in WebGL 1.");
return JS::NullValue();
return Nothing();
}
switch (attachment) {
@ -773,7 +769,7 @@ JS::Value WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
ErrorInvalidEnum(
"For the default framebuffer, can only query COLOR, DEPTH,"
" or STENCIL.");
return JS::NullValue();
return Nothing();
}
switch (pname) {
@ -783,114 +779,115 @@ JS::Value WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
break;
case LOCAL_GL_DEPTH:
if (!mOptions.depth) {
return JS::Int32Value(LOCAL_GL_NONE);
return AsSomeVariant(LOCAL_GL_NONE);
}
break;
case LOCAL_GL_STENCIL:
if (!mOptions.stencil) {
return JS::Int32Value(LOCAL_GL_NONE);
return AsSomeVariant(LOCAL_GL_NONE);
}
break;
default:
ErrorInvalidEnum(
"With the default framebuffer, can only query COLOR, DEPTH,"
" or STENCIL for GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE");
return JS::NullValue();
return Nothing();
}
return JS::Int32Value(LOCAL_GL_FRAMEBUFFER_DEFAULT);
return AsSomeVariant(LOCAL_GL_FRAMEBUFFER_DEFAULT);
////////////////
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
if (attachment == LOCAL_GL_BACK) return JS::NumberValue(8);
return JS::NumberValue(0);
if (attachment == LOCAL_GL_BACK) return AsSomeVariant(8);
return AsSomeVariant(0);
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
if (attachment == LOCAL_GL_BACK) {
if (mOptions.alpha) {
return JS::NumberValue(8);
return AsSomeVariant(8);
}
ErrorInvalidOperation(
"The default framebuffer doesn't contain an alpha buffer");
return JS::NullValue();
return Nothing();
}
return JS::NumberValue(0);
return AsSomeVariant(0);
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
if (attachment == LOCAL_GL_DEPTH) {
if (mOptions.depth) {
return JS::NumberValue(24);
return AsSomeVariant(24);
}
ErrorInvalidOperation(
"The default framebuffer doesn't contain an depth buffer");
return JS::NullValue();
return Nothing();
}
return JS::NumberValue(0);
return AsSomeVariant(0);
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
if (attachment == LOCAL_GL_STENCIL) {
if (mOptions.stencil) {
return JS::NumberValue(8);
return AsSomeVariant(8);
}
ErrorInvalidOperation(
"The default framebuffer doesn't contain an stencil buffer");
return JS::NullValue();
return Nothing();
}
return JS::NumberValue(0);
return AsSomeVariant(0);
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
if (attachment == LOCAL_GL_STENCIL) {
if (mOptions.stencil) {
return JS::NumberValue(LOCAL_GL_UNSIGNED_INT);
return AsSomeVariant(LOCAL_GL_UNSIGNED_INT);
}
ErrorInvalidOperation(
"The default framebuffer doesn't contain an stencil buffer");
} else if (attachment == LOCAL_GL_DEPTH) {
if (mOptions.depth) {
return JS::NumberValue(LOCAL_GL_UNSIGNED_NORMALIZED);
return AsSomeVariant(LOCAL_GL_UNSIGNED_NORMALIZED);
}
ErrorInvalidOperation(
"The default framebuffer doesn't contain an depth buffer");
} else { // LOCAL_GL_BACK
return JS::NumberValue(LOCAL_GL_UNSIGNED_NORMALIZED);
return AsSomeVariant(LOCAL_GL_UNSIGNED_NORMALIZED);
}
return JS::NullValue();
return Nothing();
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
if (attachment == LOCAL_GL_STENCIL) {
if (!mOptions.stencil) {
ErrorInvalidOperation(
"The default framebuffer doesn't contain an stencil buffer");
return JS::NullValue();
return Nothing();
}
} else if (attachment == LOCAL_GL_DEPTH) {
if (!mOptions.depth) {
ErrorInvalidOperation(
"The default framebuffer doesn't contain an depth buffer");
return JS::NullValue();
return Nothing();
}
}
return JS::NumberValue(LOCAL_GL_LINEAR);
return AsSomeVariant(LOCAL_GL_LINEAR);
}
ErrorInvalidEnumInfo("pname", pname);
return JS::NullValue();
return Nothing();
}
JS::Value WebGLContext::GetRenderbufferParameter(GLenum target, GLenum pname) {
MaybeWebGLVariant WebGLContext::GetRenderbufferParameter(GLenum target,
GLenum pname) {
const FuncScope funcScope(*this, "getRenderbufferParameter");
if (IsContextLost()) return JS::NullValue();
if (IsContextLost()) return Nothing();
if (target != LOCAL_GL_RENDERBUFFER) {
ErrorInvalidEnumInfo("target", target);
return JS::NullValue();
return Nothing();
}
if (!mBoundRenderbuffer) {
ErrorInvalidOperation("No renderbuffer is bound.");
return JS::NullValue();
return Nothing();
}
switch (pname) {
@ -909,7 +906,7 @@ JS::Value WebGLContext::GetRenderbufferParameter(GLenum target, GLenum pname) {
case LOCAL_GL_RENDERBUFFER_INTERNAL_FORMAT: {
// RB emulation means we have to ask the RB itself.
GLint i = mBoundRenderbuffer->GetRenderbufferParameter(target, pname);
return JS::Int32Value(i);
return AsSomeVariant(i);
}
default:
@ -917,7 +914,7 @@ JS::Value WebGLContext::GetRenderbufferParameter(GLenum target, GLenum pname) {
}
ErrorInvalidEnumInfo("pname", pname);
return JS::NullValue();
return Nothing();
}
already_AddRefed<WebGLTexture> WebGLContext::CreateTexture() {
@ -970,40 +967,38 @@ GLenum WebGLContext::GetError() {
return err;
}
JS::Value WebGLContext::GetProgramParameter(const WebGLProgram& prog,
GLenum pname) {
MaybeWebGLVariant WebGLContext::GetProgramParameter(const WebGLProgram& prog,
GLenum pname) {
const FuncScope funcScope(*this, "getProgramParameter");
if (IsContextLost()) return JS::NullValue();
if (IsContextLost()) return Nothing();
if (!ValidateObjectAllowDeleted("program", prog)) return JS::NullValue();
if (!ValidateObjectAllowDeleted("program", prog)) return Nothing();
return prog.GetProgramParameter(pname);
}
void WebGLContext::GetProgramInfoLog(const WebGLProgram& prog,
nsAString& retval) {
retval.SetIsVoid(true);
nsString WebGLContext::GetProgramInfoLog(const WebGLProgram& prog) {
const FuncScope funcScope(*this, "getProgramInfoLog");
if (IsContextLost()) return;
if (IsContextLost()) return EmptyString();
if (!ValidateObject("program", prog)) return;
if (!ValidateObject("program", prog)) return EmptyString();
prog.GetProgramInfoLog(&retval);
return prog.GetProgramInfoLog();
}
JS::Value WebGLContext::GetUniform(JSContext* js, const WebGLProgram& prog,
const WebGLUniformLocation& loc) {
MaybeWebGLVariant WebGLContext::GetUniform(const WebGLProgram& prog,
const WebGLUniformLocation& loc) {
const FuncScope funcScope(*this, "getUniform");
if (IsContextLost()) return JS::NullValue();
if (IsContextLost()) return Nothing();
if (!ValidateObject("program", prog)) return JS::NullValue();
if (!ValidateObject("program", prog)) return Nothing();
if (!ValidateObjectAllowDeleted("location", loc)) return JS::NullValue();
if (!ValidateObjectAllowDeleted("location", loc)) return Nothing();
if (!loc.ValidateForProgram(&prog)) return JS::NullValue();
if (!loc.ValidateForProgram(&prog)) return Nothing();
return loc.GetUniform(js);
return loc.GetUniform();
}
already_AddRefed<WebGLUniformLocation> WebGLContext::GetUniformLocation(
@ -1136,80 +1131,80 @@ void WebGLContext::LinkProgram(WebGLProgram& prog) {
}
}
void WebGLContext::PixelStorei(GLenum pname, GLint param) {
WebGLPixelStore WebGLContext::PixelStorei(GLenum pname, GLint param) {
const FuncScope funcScope(*this, "pixelStorei");
if (IsContextLost()) return;
if (IsContextLost()) return mPixelStore;
if (IsWebGL2()) {
uint32_t* pValueSlot = nullptr;
switch (pname) {
case LOCAL_GL_UNPACK_IMAGE_HEIGHT:
pValueSlot = &mPixelStore_UnpackImageHeight;
pValueSlot = &mPixelStore.mUnpackImageHeight;
break;
case LOCAL_GL_UNPACK_SKIP_IMAGES:
pValueSlot = &mPixelStore_UnpackSkipImages;
pValueSlot = &mPixelStore.mUnpackSkipImages;
break;
case LOCAL_GL_UNPACK_ROW_LENGTH:
pValueSlot = &mPixelStore_UnpackRowLength;
pValueSlot = &mPixelStore.mUnpackRowLength;
break;
case LOCAL_GL_UNPACK_SKIP_ROWS:
pValueSlot = &mPixelStore_UnpackSkipRows;
pValueSlot = &mPixelStore.mUnpackSkipRows;
break;
case LOCAL_GL_UNPACK_SKIP_PIXELS:
pValueSlot = &mPixelStore_UnpackSkipPixels;
pValueSlot = &mPixelStore.mUnpackSkipPixels;
break;
case LOCAL_GL_PACK_ROW_LENGTH:
pValueSlot = &mPixelStore_PackRowLength;
pValueSlot = &mPixelStore.mPackRowLength;
break;
case LOCAL_GL_PACK_SKIP_ROWS:
pValueSlot = &mPixelStore_PackSkipRows;
pValueSlot = &mPixelStore.mPackSkipRows;
break;
case LOCAL_GL_PACK_SKIP_PIXELS:
pValueSlot = &mPixelStore_PackSkipPixels;
pValueSlot = &mPixelStore.mPackSkipPixels;
break;
}
if (pValueSlot) {
if (!ValidateNonNegative("param", param)) return;
if (!ValidateNonNegative("param", param)) return mPixelStore;
gl->fPixelStorei(pname, param);
*pValueSlot = param;
return;
return mPixelStore;
}
}
switch (pname) {
case UNPACK_FLIP_Y_WEBGL:
mPixelStore_FlipY = bool(param);
return;
mPixelStore.mFlipY = bool(param);
return mPixelStore;
case UNPACK_PREMULTIPLY_ALPHA_WEBGL:
mPixelStore_PremultiplyAlpha = bool(param);
return;
mPixelStore.mPremultiplyAlpha = bool(param);
return mPixelStore;
case UNPACK_COLORSPACE_CONVERSION_WEBGL:
switch (param) {
case LOCAL_GL_NONE:
case BROWSER_DEFAULT_WEBGL:
mPixelStore_ColorspaceConversion = param;
return;
mPixelStore.mColorspaceConversion = param;
return mPixelStore;
default:
ErrorInvalidEnumInfo("colorspace conversion parameter", param);
return;
return mPixelStore;
}
case UNPACK_REQUIRE_FASTPATH:
if (IsExtensionEnabled(WebGLExtensionID::MOZ_debug)) {
mPixelStore_RequireFastPath = bool(param);
return;
mPixelStore.mRequireFastPath = bool(param);
return mPixelStore;
}
break;
@ -1221,16 +1216,16 @@ void WebGLContext::PixelStorei(GLenum pname, GLint param) {
case 4:
case 8:
if (pname == LOCAL_GL_PACK_ALIGNMENT)
mPixelStore_PackAlignment = param;
mPixelStore.mPackAlignment = param;
else if (pname == LOCAL_GL_UNPACK_ALIGNMENT)
mPixelStore_UnpackAlignment = param;
mPixelStore.mUnpackAlignment = param;
gl->fPixelStorei(pname, param);
return;
return mPixelStore;
default:
ErrorInvalidValue("Invalid pack/unpack alignment value.");
return;
return mPixelStore;
}
default:
@ -1238,6 +1233,7 @@ void WebGLContext::PixelStorei(GLenum pname, GLint param) {
}
ErrorInvalidEnumInfo("pname", pname);
return mPixelStore;
}
bool WebGLContext::DoReadPixelsAndConvert(const webgl::FormatInfo* srcFormat,
@ -1273,65 +1269,9 @@ bool WebGLContext::DoReadPixelsAndConvert(const webgl::FormatInfo* srcFormat,
const auto tailRowOffset = (char*)dest + rowStride * bodyHeight;
gl->fReadPixels(x, y + bodyHeight, width, 1, format, destType, tailRowOffset);
gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, mPixelStore_PackAlignment);
gl->fPixelStorei(LOCAL_GL_PACK_ROW_LENGTH, mPixelStore_PackRowLength);
gl->fPixelStorei(LOCAL_GL_PACK_SKIP_ROWS, mPixelStore_PackSkipRows);
return true;
}
static bool GetJSScalarFromGLType(GLenum type,
js::Scalar::Type* const out_scalarType) {
switch (type) {
case LOCAL_GL_BYTE:
*out_scalarType = js::Scalar::Int8;
return true;
case LOCAL_GL_UNSIGNED_BYTE:
*out_scalarType = js::Scalar::Uint8;
return true;
case LOCAL_GL_SHORT:
*out_scalarType = js::Scalar::Int16;
return true;
case LOCAL_GL_HALF_FLOAT:
case LOCAL_GL_HALF_FLOAT_OES:
case LOCAL_GL_UNSIGNED_SHORT:
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
*out_scalarType = js::Scalar::Uint16;
return true;
case LOCAL_GL_UNSIGNED_INT:
case LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV:
case LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV:
case LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV:
case LOCAL_GL_UNSIGNED_INT_24_8:
*out_scalarType = js::Scalar::Uint32;
return true;
case LOCAL_GL_INT:
*out_scalarType = js::Scalar::Int32;
return true;
case LOCAL_GL_FLOAT:
*out_scalarType = js::Scalar::Float32;
return true;
default:
return false;
}
}
bool WebGLContext::ReadPixels_SharedPrecheck(CallerType aCallerType,
ErrorResult& out_error) {
if (mCanvasElement && mCanvasElement->IsWriteOnly() &&
aCallerType != CallerType::System) {
GenerateWarning("readPixels: Not allowed");
out_error.Throw(NS_ERROR_DOM_SECURITY_ERR);
return false;
}
gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, mPixelStore.mPackAlignment);
gl->fPixelStorei(LOCAL_GL_PACK_ROW_LENGTH, mPixelStore.mPackRowLength);
gl->fPixelStorei(LOCAL_GL_PACK_SKIP_ROWS, mPixelStore.mPackSkipRows);
return true;
}
@ -1348,10 +1288,10 @@ bool WebGLContext::ValidatePackSize(uint32_t width, uint32_t height,
// GLES 3.0.4, p116 (PACK_ functions like UNPACK_)
const auto rowLength =
(mPixelStore_PackRowLength ? mPixelStore_PackRowLength : width);
const auto skipPixels = mPixelStore_PackSkipPixels;
const auto skipRows = mPixelStore_PackSkipRows;
const auto alignment = mPixelStore_PackAlignment;
(mPixelStore.mPackRowLength ? mPixelStore.mPackRowLength : width);
const auto skipPixels = mPixelStore.mPackSkipPixels;
const auto skipRows = mPixelStore.mPackSkipRows;
const auto alignment = mPixelStore.mPackAlignment;
const auto usedPixelsPerRow = CheckedUint32(skipPixels) + width;
const auto usedRowsPerImage = CheckedUint32(skipRows) + height;
@ -1378,56 +1318,34 @@ bool WebGLContext::ValidatePackSize(uint32_t width, uint32_t height,
return true;
}
void WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const dom::ArrayBufferView& dstView,
GLuint dstElemOffset, CallerType aCallerType,
ErrorResult& out_error) {
Maybe<UniquePtr<RawBuffer<>>> WebGLContext::ReadPixels(
GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
size_t byteLen) {
const FuncScope funcScope(*this, "readPixels");
if (IsContextLost()) return;
if (!ReadPixels_SharedPrecheck(aCallerType, out_error)) return;
if (IsContextLost()) return Nothing();
if (mBoundPixelPackBuffer) {
ErrorInvalidOperation("PIXEL_PACK_BUFFER must be null.");
return;
return Nothing();
}
////
js::Scalar::Type reqScalarType;
if (!GetJSScalarFromGLType(type, &reqScalarType)) {
ErrorInvalidEnumInfo("type", type);
return;
// TODO: Allocate the Shmem earlier so we can use it here instead of copying
uint8_t* bytes = new uint8_t[byteLen];
if (!bytes) {
ErrorOutOfMemory("ReadPixels could not allocate temp memory");
return Nothing();
}
const auto& viewElemType = dstView.Type();
if (viewElemType != reqScalarType) {
ErrorInvalidOperation("`pixels` type does not match `type`.");
return;
}
////
uint8_t* bytes;
size_t byteLen;
if (!ValidateArrayBufferView(dstView, dstElemOffset, 0,
LOCAL_GL_INVALID_VALUE, &bytes, &byteLen))
return;
////
UniquePtr<RawBuffer<>> buf = MakeUnique<RawBuffer<>>(byteLen, bytes, true);
ReadPixelsImpl(x, y, width, height, format, type, bytes, byteLen);
return Some(std::move(buf));
}
void WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, WebGLsizeiptr offset,
CallerType aCallerType, ErrorResult& out_error) {
GLenum format, GLenum type,
WebGLsizeiptr offset) {
const FuncScope funcScope(*this, "readPixels");
if (IsContextLost()) return;
if (!ReadPixels_SharedPrecheck(aCallerType, out_error)) return;
const auto& buffer = ValidateBufferSelection(LOCAL_GL_PIXEL_PACK_BUFFER);
if (!buffer) return;
@ -1651,21 +1569,21 @@ void WebGLContext::ReadPixelsImpl(GLint x, GLint y, GLsizei rawWidth,
// Read only the in-bounds pixels.
if (IsWebGL2()) {
if (!mPixelStore_PackRowLength) {
if (!mPixelStore.mPackRowLength) {
gl->fPixelStorei(LOCAL_GL_PACK_ROW_LENGTH,
mPixelStore_PackSkipPixels + width);
mPixelStore.mPackSkipPixels + width);
}
gl->fPixelStorei(LOCAL_GL_PACK_SKIP_PIXELS,
mPixelStore_PackSkipPixels + writeX);
mPixelStore.mPackSkipPixels + writeX);
gl->fPixelStorei(LOCAL_GL_PACK_SKIP_ROWS,
mPixelStore_PackSkipRows + writeY);
mPixelStore.mPackSkipRows + writeY);
DoReadPixelsAndConvert(srcFormat->format, readX, readY, rwWidth, rwHeight,
packFormat, packType, dest, dataLen, rowStride);
gl->fPixelStorei(LOCAL_GL_PACK_ROW_LENGTH, mPixelStore_PackRowLength);
gl->fPixelStorei(LOCAL_GL_PACK_SKIP_PIXELS, mPixelStore_PackSkipPixels);
gl->fPixelStorei(LOCAL_GL_PACK_SKIP_ROWS, mPixelStore_PackSkipRows);
gl->fPixelStorei(LOCAL_GL_PACK_ROW_LENGTH, mPixelStore.mPackRowLength);
gl->fPixelStorei(LOCAL_GL_PACK_SKIP_PIXELS, mPixelStore.mPackSkipPixels);
gl->fPixelStorei(LOCAL_GL_PACK_SKIP_ROWS, mPixelStore.mPackSkipRows);
} else {
// I *did* say "hilariously slow".
@ -1933,16 +1851,17 @@ static bool ValidateArrOffsetAndCount(WebGLContext* webgl, size_t elemsAvail,
}
void WebGLContext::UniformNiv(const char* funcName, uint8_t N,
WebGLUniformLocation* loc, const Int32Arr& arr,
WebGLUniformLocation* loc,
const RawBuffer<const GLint>& arr,
GLuint elemOffset, GLuint elemCountOverride) {
const FuncScope funcScope(*this, funcName);
size_t elemCount;
if (!ValidateArrOffsetAndCount(this, arr.elemCount, elemOffset,
if (!ValidateArrOffsetAndCount(this, arr.Length(), elemOffset,
elemCountOverride, &elemCount)) {
return;
}
const auto elemBytes = arr.elemBytes + elemOffset;
const auto elemBytes = arr.Data() + elemOffset;
uint32_t numElementsToUpload;
if (!ValidateUniformArraySetter(loc, N, webgl::AttribBaseType::Int, elemCount,
@ -1964,16 +1883,17 @@ void WebGLContext::UniformNiv(const char* funcName, uint8_t N,
}
void WebGLContext::UniformNuiv(const char* funcName, uint8_t N,
WebGLUniformLocation* loc, const Uint32Arr& arr,
WebGLUniformLocation* loc,
const RawBuffer<const GLuint>& arr,
GLuint elemOffset, GLuint elemCountOverride) {
const FuncScope funcScope(*this, funcName);
size_t elemCount;
if (!ValidateArrOffsetAndCount(this, arr.elemCount, elemOffset,
if (!ValidateArrOffsetAndCount(this, arr.Length(), elemOffset,
elemCountOverride, &elemCount)) {
return;
}
const auto elemBytes = arr.elemBytes + elemOffset;
const auto elemBytes = arr.Data() + elemOffset;
uint32_t numElementsToUpload;
if (!ValidateUniformArraySetter(loc, N, webgl::AttribBaseType::UInt,
@ -1991,16 +1911,17 @@ void WebGLContext::UniformNuiv(const char* funcName, uint8_t N,
}
void WebGLContext::UniformNfv(const char* funcName, uint8_t N,
WebGLUniformLocation* loc, const Float32Arr& arr,
WebGLUniformLocation* loc,
const RawBuffer<const GLfloat>& arr,
GLuint elemOffset, GLuint elemCountOverride) {
const FuncScope funcScope(*this, funcName);
size_t elemCount;
if (!ValidateArrOffsetAndCount(this, arr.elemCount, elemOffset,
if (!ValidateArrOffsetAndCount(this, arr.Length(), elemOffset,
elemCountOverride, &elemCount)) {
return;
}
const auto elemBytes = arr.elemBytes + elemOffset;
const auto elemBytes = arr.Data() + elemOffset;
uint32_t numElementsToUpload;
if (!ValidateUniformArraySetter(loc, N, webgl::AttribBaseType::Float,
@ -2031,16 +1952,17 @@ static inline void MatrixAxBToRowMajor(const uint8_t width,
void WebGLContext::UniformMatrixAxBfv(const char* funcName, uint8_t A,
uint8_t B, WebGLUniformLocation* loc,
const bool transpose,
const Float32Arr& arr, GLuint elemOffset,
const RawBuffer<const float>& arr,
GLuint elemOffset,
GLuint elemCountOverride) {
const FuncScope funcScope(*this, funcName);
size_t elemCount;
if (!ValidateArrOffsetAndCount(this, arr.elemCount, elemOffset,
if (!ValidateArrOffsetAndCount(this, arr.Length(), elemOffset,
elemCountOverride, &elemCount)) {
return;
}
const auto elemBytes = arr.elemBytes + elemOffset;
const auto elemBytes = arr.Data() + elemOffset;
uint32_t numMatsToUpload;
if (!ValidateUniformMatrixArraySetter(loc, A, B, webgl::AttribBaseType::Float,
@ -2174,33 +2096,30 @@ void WebGLContext::CompileShader(WebGLShader& shader) {
shader.CompileShader();
}
JS::Value WebGLContext::GetShaderParameter(const WebGLShader& shader,
GLenum pname) {
MaybeWebGLVariant WebGLContext::GetShaderParameter(const WebGLShader& shader,
GLenum pname) {
const FuncScope funcScope(*this, "getShaderParameter");
if (IsContextLost()) return JS::NullValue();
if (IsContextLost()) return Nothing();
if (!ValidateObjectAllowDeleted("shader", shader)) return JS::NullValue();
if (!ValidateObjectAllowDeleted("shader", shader)) return Nothing();
return shader.GetShaderParameter(pname);
}
void WebGLContext::GetShaderInfoLog(const WebGLShader& shader,
nsAString& retval) {
retval.SetIsVoid(true);
nsString WebGLContext::GetShaderInfoLog(const WebGLShader& shader) {
const FuncScope funcScope(*this, "getShaderInfoLog");
if (IsContextLost()) return;
if (IsContextLost()) return EmptyString();
if (!ValidateObject("shader", shader)) return;
if (!ValidateObject("shader", shader)) return EmptyString();
shader.GetShaderInfoLog(&retval);
return shader.GetShaderInfoLog();
}
already_AddRefed<WebGLShaderPrecisionFormat>
WebGLContext::GetShaderPrecisionFormat(GLenum shadertype,
GLenum precisiontype) {
Maybe<WebGLShaderPrecisionFormat> WebGLContext::GetShaderPrecisionFormat(
GLenum shadertype, GLenum precisiontype) {
const FuncScope funcScope(*this, "getShaderPrecisionFormat");
if (IsContextLost()) return nullptr;
if (IsContextLost()) return Nothing();
switch (shadertype) {
case LOCAL_GL_FRAGMENT_SHADER:
@ -2208,7 +2127,7 @@ WebGLContext::GetShaderPrecisionFormat(GLenum shadertype,
break;
default:
ErrorInvalidEnumInfo("shadertype", shadertype);
return nullptr;
return Nothing();
}
switch (precisiontype) {
@ -2221,7 +2140,7 @@ WebGLContext::GetShaderPrecisionFormat(GLenum shadertype,
break;
default:
ErrorInvalidEnumInfo("precisiontype", precisiontype);
return nullptr;
return Nothing();
}
GLint range[2], precision;
@ -2236,21 +2155,20 @@ WebGLContext::GetShaderPrecisionFormat(GLenum shadertype,
gl->fGetShaderPrecisionFormat(shadertype, precisiontype, range, &precision);
}
RefPtr<WebGLShaderPrecisionFormat> retShaderPrecisionFormat =
new WebGLShaderPrecisionFormat(this, range[0], range[1], precision);
return retShaderPrecisionFormat.forget();
return Some(WebGLShaderPrecisionFormat(range[0], range[1], precision));
}
void WebGLContext::GetShaderSource(const WebGLShader& shader,
nsAString& retval) {
retval.SetIsVoid(true);
nsString WebGLContext::GetShaderSource(const WebGLShader& shader) {
nsString retVoid;
retVoid.SetIsVoid(true);
const FuncScope funcScope(*this, "getShaderSource");
if (IsContextLost()) return;
if (IsContextLost()) return retVoid;
if (!ValidateObject("shader", shader)) return;
if (!ValidateObject("shader", shader)) return retVoid;
shader.GetShaderSource(&retval);
return shader.GetShaderSource();
}
void WebGLContext::ShaderSource(WebGLShader& shader, const nsAString& source) {

Просмотреть файл

@ -4,100 +4,40 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLContextLossHandler.h"
#include "mozilla/DebugOnly.h"
#include "nsINamed.h"
#include "nsISupportsImpl.h"
#include "nsITimer.h"
#include "nsThreadUtils.h"
#include "WebGLContext.h"
namespace mozilla {
class WatchdogTimerEvent final : public nsITimerCallback, public nsINamed {
const WeakPtr<WebGLContextLossHandler> mHandler;
public:
NS_DECL_ISUPPORTS
explicit WatchdogTimerEvent(WebGLContextLossHandler* handler)
: mHandler(handler) {}
NS_IMETHOD GetName(nsACString& aName) override {
aName.AssignLiteral("WatchdogTimerEvent");
return NS_OK;
void MaybeUpdateContextLoss(WeakPtr<WebGLContext> weakCxt) {
RefPtr<WebGLContext> cxt = weakCxt.get();
if (!cxt) {
return;
}
private:
virtual ~WatchdogTimerEvent() {}
NS_IMETHOD Notify(nsITimer*) override {
if (mHandler) {
mHandler->TimerCallback();
}
return NS_OK;
}
};
NS_IMPL_ISUPPORTS(WatchdogTimerEvent, nsITimerCallback, nsINamed)
////////////////////////////////////////
WebGLContextLossHandler::WebGLContextLossHandler(WebGLContext* webgl)
: mWebGL(webgl),
mTimer(NS_NewTimer()),
mTimerPending(false),
mShouldRunTimerAgain(false)
#ifdef DEBUG
,
mEventTarget(GetCurrentThreadSerialEventTarget())
#endif
{
MOZ_ASSERT(mEventTarget);
cxt->UpdateContextLossStatus();
}
WebGLContextLossHandler::~WebGLContextLossHandler() {
const DebugOnly<nsISerialEventTarget*> callingThread =
GetCurrentThreadSerialEventTarget();
MOZ_ASSERT(!callingThread || mEventTarget->IsOnCurrentThread());
WebGLContextLossHandler::WebGLContextLossHandler(WebGLContext* webgl) {
MOZ_ASSERT(webgl);
WeakPtr<WebGLContext> weakCxt = webgl;
mRunnable = NS_NewRunnableFunction("WebGLContextLossHandler", [weakCxt]() {
MaybeUpdateContextLoss(weakCxt);
});
MOZ_ASSERT(mRunnable);
}
WebGLContextLossHandler::~WebGLContextLossHandler() {}
////////////////////
void WebGLContextLossHandler::RunTimer() {
MOZ_ASSERT(mEventTarget->IsOnCurrentThread());
// If the timer was already running, don't restart it here. Instead,
// wait until the previous call is done, then fire it one more time.
// This is also an optimization to prevent unnecessary
// cross-communication between threads.
if (mTimerPending) {
mShouldRunTimerAgain = true;
return;
}
const RefPtr<WatchdogTimerEvent> event = new WatchdogTimerEvent(this);
const uint32_t kDelayMS = 1000;
mTimer->InitWithCallback(event, kDelayMS, nsITimer::TYPE_ONE_SHOT);
mTimerPending = true;
}
////////////////////
void WebGLContextLossHandler::TimerCallback() {
MOZ_ASSERT(mEventTarget->IsOnCurrentThread());
mTimerPending = false;
const bool runOnceMore = mShouldRunTimerAgain;
mShouldRunTimerAgain = false;
mWebGL->UpdateContextLossStatus();
if (runOnceMore && !mTimerPending) {
RunTimer();
MOZ_ASSERT(MessageLoop::current());
// Only create a new task if one isn't already queued.
if (mTimerIsScheduled.compareExchange(false, true)) {
MessageLoop::current()->PostDelayedTask(do_AddRef(mRunnable), kDelayMS);
}
}
void WebGLContextLossHandler::ClearTimer() { mTimerIsScheduled = false; }
} // namespace mozilla

Просмотреть файл

@ -6,27 +6,18 @@
#ifndef WEBGL_CONTEXT_LOSS_HANDLER_H_
#define WEBGL_CONTEXT_LOSS_HANDLER_H_
#include "mozilla/Atomics.h"
#include "mozilla/WeakPtr.h"
#include "nsCOMPtr.h"
class nsIThread;
class nsITimer;
#include "mozilla/RefPtr.h"
#include "nsThreadUtils.h"
namespace mozilla {
class WebGLContext;
class WebGLContextLossHandler final
: public SupportsWeakPtr<WebGLContextLossHandler> {
WebGLContext* const mWebGL;
const nsCOMPtr<nsITimer>
mTimer; // If we don't hold a ref to the timer, it will think
bool mTimerPending; // that it's been discarded, and be canceled 'for our
bool mShouldRunTimerAgain; // convenience'.
#ifdef DEBUG
nsISerialEventTarget* const mEventTarget;
#endif
friend class WatchdogTimerEvent;
RefPtr<Runnable> mRunnable;
Atomic<bool> mTimerIsScheduled;
public:
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebGLContextLossHandler)
@ -35,9 +26,8 @@ class WebGLContextLossHandler final
~WebGLContextLossHandler();
void RunTimer();
private:
void TimerCallback();
// Allow future queueing of context loss timer.
void ClearTimer();
};
} // namespace mozilla

Просмотреть файл

@ -68,18 +68,17 @@ bool WebGLContext::GetStencilBits(GLint* const out_stencilBits) const {
return true;
}
JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
ErrorResult& rv) {
MaybeWebGLVariant WebGLContext::GetParameter(GLenum pname) {
const FuncScope funcScope(*this, "getParameter");
if (IsContextLost()) return JS::NullValue();
if (IsContextLost()) return Nothing();
if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) {
if (pname == LOCAL_GL_MAX_COLOR_ATTACHMENTS) {
return JS::Int32Value(mGLMaxColorAttachments);
return AsSomeVariant(mGLMaxColorAttachments);
} else if (pname == LOCAL_GL_MAX_DRAW_BUFFERS) {
return JS::Int32Value(mGLMaxDrawBuffers);
return AsSomeVariant(mGLMaxDrawBuffers);
} else if (pname >= LOCAL_GL_DRAW_BUFFER0 &&
pname < GLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers)) {
@ -91,7 +90,7 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
} else {
gl->fGetIntegerv(pname, &ret);
}
return JS::Int32Value(ret);
return AsSomeVariant(ret);
}
}
@ -101,7 +100,7 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
WebGLVertexArray* vao = (mBoundVertexArray != mDefaultVertexArray)
? mBoundVertexArray.get()
: nullptr;
return WebGLObjectAsJSValue(cx, vao, rv);
return AsSomeVariant(vao);
}
}
@ -116,7 +115,7 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
}
// TODO: JS doesn't support 64-bit integers. Be lossy and
// cast to double (53 bits)
return JS::NumberValue(val);
return AsSomeVariant(val);
}
case LOCAL_GL_GPU_DISJOINT_EXT: {
@ -124,7 +123,8 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
if (gl->IsExtensionSupported(gl::GLContext::EXT_disjoint_timer_query)) {
gl->fGetBooleanv(pname, &val);
}
return JS::BooleanValue(val);
bool boolVal = static_cast<bool>(val);
return AsSomeVariant(boolVal);
}
default:
@ -157,7 +157,7 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
bool hasRetVal = false;
nsAutoString ret;
nsString ret;
if (overridePref) {
nsresult res = Preferences::GetString(overridePref, ret);
if (NS_SUCCEEDED(res) && ret.Length() > 0) hasRetVal = true;
@ -170,7 +170,7 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
hasRetVal = true;
}
return StringValue(cx, ret, rv);
return AsSomeVariant(std::move(ret));
}
}
}
@ -180,7 +180,7 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
if (pname == LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT) {
GLint i = 0;
gl->fGetIntegerv(pname, &i);
return JS::Int32Value(i);
return AsSomeVariant(i);
}
}
@ -188,7 +188,8 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
if (pname == LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) {
GLfloat f = 0.f;
gl->fGetFloatv(pname, &f);
return JS::NumberValue(f);
double df = static_cast<double>(f);
return AsSomeVariant(df);
}
}
@ -198,11 +199,11 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
//
case LOCAL_GL_VENDOR:
case LOCAL_GL_RENDERER:
return StringValue(cx, "Mozilla", rv);
return AsSomeVariant(nsCString("Mozilla"));
case LOCAL_GL_VERSION:
return StringValue(cx, "WebGL 1.0", rv);
return AsSomeVariant(nsCString("WebGL 1.0"));
case LOCAL_GL_SHADING_LANGUAGE_VERSION:
return StringValue(cx, "WebGL GLSL ES 1.0", rv);
return AsSomeVariant(nsCString("WebGL GLSL ES 1.0"));
////////////////////////////////
// Single-value params
@ -228,19 +229,17 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
case LOCAL_GL_BLEND_EQUATION_ALPHA: {
GLint i = 0;
gl->fGetIntegerv(pname, &i);
return JS::NumberValue(uint32_t(i));
return AsSomeVariant(uint32_t(i));
}
case LOCAL_GL_GENERATE_MIPMAP_HINT:
return JS::NumberValue(mGenerateMipmapHint);
return AsSomeVariant(mGenerateMipmapHint);
case LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT:
case LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE: {
const webgl::FormatUsageInfo* usage;
uint32_t width, height;
if (!BindCurFBForColorRead(&usage, &width, &height,
LOCAL_GL_INVALID_OPERATION))
return JS::NullValue();
if (!BindCurFBForColorRead(&usage, &width, &height)) return Nothing();
const auto implPI = ValidImplementationColorReadPI(usage);
@ -250,14 +249,14 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
} else {
ret = implPI.type;
}
return JS::NumberValue(uint32_t(ret));
return AsSomeVariant(uint32_t(ret));
}
// int
case LOCAL_GL_STENCIL_REF:
case LOCAL_GL_STENCIL_BACK_REF: {
GLint stencilBits = 0;
if (!GetStencilBits(&stencilBits)) return JS::NullValue();
if (!GetStencilBits(&stencilBits)) return Nothing();
// Assuming stencils have 8 bits
const GLint stencilMask = (1 << stencilBits) - 1;
@ -265,7 +264,7 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
GLint refValue = 0;
gl->fGetIntegerv(pname, &refValue);
return JS::Int32Value(refValue & stencilMask);
return AsSomeVariant(refValue & stencilMask);
}
case LOCAL_GL_SAMPLE_BUFFERS:
@ -285,8 +284,8 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
if (samples && pname == LOCAL_GL_SAMPLE_BUFFERS) {
samples = Some(uint32_t(bool(samples.value())));
}
if (!samples) return JS::NullValue();
return JS::NumberValue(samples.value());
if (!samples) return Nothing();
return AsSomeVariant(samples.value());
}
case LOCAL_GL_STENCIL_CLEAR_VALUE:
@ -295,7 +294,7 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
case LOCAL_GL_SUBPIXEL_BITS: {
GLint i = 0;
gl->fGetIntegerv(pname, &i);
return JS::Int32Value(i);
return AsSomeVariant(i);
}
case LOCAL_GL_RED_BITS:
@ -377,38 +376,38 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
break;
}
}
return JS::Int32Value(ret);
return AsSomeVariant(ret);
}
case LOCAL_GL_MAX_TEXTURE_SIZE:
return JS::Int32Value(mGLMaxTextureSize);
return AsSomeVariant(mGLMaxTextureSize);
case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
return JS::Int32Value(mGLMaxCubeMapTextureSize);
return AsSomeVariant(mGLMaxCubeMapTextureSize);
case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
return JS::Int32Value(mGLMaxRenderbufferSize);
return AsSomeVariant(mGLMaxRenderbufferSize);
case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
return JS::Int32Value(mGLMaxVertexTextureImageUnits);
return AsSomeVariant(mGLMaxVertexTextureImageUnits);
case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS:
return JS::Int32Value(mGLMaxFragmentTextureImageUnits);
return AsSomeVariant(mGLMaxFragmentTextureImageUnits);
case LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
return JS::Int32Value(mGLMaxCombinedTextureImageUnits);
return AsSomeVariant(mGLMaxCombinedTextureImageUnits);
case LOCAL_GL_MAX_VERTEX_ATTRIBS:
return JS::Int32Value(mGLMaxVertexAttribs);
return AsSomeVariant(mGLMaxVertexAttribs);
case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS:
return JS::Int32Value(mGLMaxVertexUniformVectors);
return AsSomeVariant(mGLMaxVertexUniformVectors);
case LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
return JS::Int32Value(mGLMaxFragmentUniformVectors);
return AsSomeVariant(mGLMaxFragmentUniformVectors);
case LOCAL_GL_MAX_VARYING_VECTORS:
return JS::Int32Value(mGLMaxFragmentInputVectors);
return AsSomeVariant(mGLMaxFragmentInputVectors);
case LOCAL_GL_MAX_VIEWS_OVR:
if (IsExtensionEnabled(WebGLExtensionID::OVR_multiview2)) {
@ -417,35 +416,28 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
break;
case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS: {
uint32_t length = mCompressedTextureFormats.Length();
JSObject* obj = dom::Uint32Array::Create(
cx, this, length, mCompressedTextureFormats.Elements());
if (!obj) {
rv = NS_ERROR_OUT_OF_MEMORY;
}
return JS::ObjectOrNullValue(obj);
return AsSomeVariant(mCompressedTextureFormats);
}
// unsigned int. here we may have to return very large values like 2^32-1
// that can't be represented as javascript integer values. We just return
// them as doubles and javascript doesn't care.
case LOCAL_GL_STENCIL_BACK_VALUE_MASK:
return JS::DoubleValue(
mStencilValueMaskBack); // pass as FP value to allow large values
// such as 2^32-1.
return AsSomeVariant((double)mStencilValueMaskBack);
// pass as FP value to allow large values such as 2^32-1.
case LOCAL_GL_STENCIL_BACK_WRITEMASK:
return JS::DoubleValue(mStencilWriteMaskBack);
return AsSomeVariant((double)mStencilWriteMaskBack);
case LOCAL_GL_STENCIL_VALUE_MASK:
return JS::DoubleValue(mStencilValueMaskFront);
return AsSomeVariant((double)mStencilValueMaskFront);
case LOCAL_GL_STENCIL_WRITEMASK:
return JS::DoubleValue(mStencilWriteMaskFront);
return AsSomeVariant((double)mStencilWriteMaskFront);
// float
case LOCAL_GL_LINE_WIDTH:
return JS::DoubleValue(mLineWidth);
return AsSomeVariant((double)mLineWidth);
case LOCAL_GL_DEPTH_CLEAR_VALUE:
case LOCAL_GL_POLYGON_OFFSET_FACTOR:
@ -453,14 +445,14 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
case LOCAL_GL_SAMPLE_COVERAGE_VALUE: {
GLfloat f = 0.f;
gl->fGetFloatv(pname, &f);
return JS::DoubleValue(f);
return AsSomeVariant((double)f);
}
// bool
case LOCAL_GL_DEPTH_TEST:
return JS::BooleanValue(mDepthTestEnabled);
return AsSomeVariant((bool)mDepthTestEnabled);
case LOCAL_GL_STENCIL_TEST:
return JS::BooleanValue(mStencilTestEnabled);
return AsSomeVariant((bool)mStencilTestEnabled);
case LOCAL_GL_BLEND:
case LOCAL_GL_CULL_FACE:
@ -473,18 +465,18 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
case LOCAL_GL_DEPTH_WRITEMASK: {
realGLboolean b = 0;
gl->fGetBooleanv(pname, &b);
return JS::BooleanValue(bool(b));
return AsSomeVariant(bool(b));
}
// bool, WebGL-specific
case UNPACK_FLIP_Y_WEBGL:
return JS::BooleanValue(mPixelStore_FlipY);
return AsSomeVariant((bool)mPixelStore.mFlipY);
case UNPACK_PREMULTIPLY_ALPHA_WEBGL:
return JS::BooleanValue(mPixelStore_PremultiplyAlpha);
return AsSomeVariant((bool)mPixelStore.mPremultiplyAlpha);
// uint, WebGL-specific
case UNPACK_COLORSPACE_CONVERSION_WEBGL:
return JS::NumberValue(uint32_t(mPixelStore_ColorspaceConversion));
return AsSomeVariant(uint32_t(mPixelStore.mColorspaceConversion));
////////////////////////////////
// Complex values
@ -493,6 +485,7 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
case LOCAL_GL_DEPTH_RANGE:
case LOCAL_GL_ALIASED_POINT_SIZE_RANGE:
case LOCAL_GL_ALIASED_LINE_WIDTH_RANGE: {
Float32Array2 obj;
GLfloat fv[2] = {0};
switch (pname) {
case LOCAL_GL_ALIASED_POINT_SIZE_RANGE:
@ -508,90 +501,82 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
gl->fGetFloatv(pname, fv);
break;
}
JSObject* obj = dom::Float32Array::Create(cx, this, 2, fv);
if (!obj) {
rv = NS_ERROR_OUT_OF_MEMORY;
for (uint32_t i = 0; i < 2; ++i) {
obj[i] = fv[i];
}
return JS::ObjectOrNullValue(obj);
return AsSomeVariant(obj);
}
// 4 floats
case LOCAL_GL_COLOR_CLEAR_VALUE:
case LOCAL_GL_BLEND_COLOR: {
Float32Array2 obj;
GLfloat fv[4] = {0};
gl->fGetFloatv(pname, fv);
JSObject* obj = dom::Float32Array::Create(cx, this, 4, fv);
if (!obj) {
rv = NS_ERROR_OUT_OF_MEMORY;
for (uint32_t i = 0; i < 4; ++i) {
obj[i] = fv[i];
}
return JS::ObjectOrNullValue(obj);
return AsSomeVariant(obj);
}
// 2 ints
case LOCAL_GL_MAX_VIEWPORT_DIMS: {
Int32Array2 obj;
GLint iv[2] = {GLint(mGLMaxViewportDims[0]),
GLint(mGLMaxViewportDims[1])};
JSObject* obj = dom::Int32Array::Create(cx, this, 2, iv);
if (!obj) {
rv = NS_ERROR_OUT_OF_MEMORY;
for (uint32_t i = 0; i < 2; ++i) {
obj[i] = iv[i];
}
return JS::ObjectOrNullValue(obj);
return AsSomeVariant(obj);
}
// 4 ints
case LOCAL_GL_SCISSOR_BOX:
case LOCAL_GL_VIEWPORT: {
Int32Array4 obj;
GLint iv[4] = {0};
gl->fGetIntegerv(pname, iv);
JSObject* obj = dom::Int32Array::Create(cx, this, 4, iv);
if (!obj) {
rv = NS_ERROR_OUT_OF_MEMORY;
for (uint32_t i = 0; i < 4; ++i) {
obj[i] = iv[i];
}
return JS::ObjectOrNullValue(obj);
return AsSomeVariant(obj);
}
// 4 bools
case LOCAL_GL_COLOR_WRITEMASK: {
const bool vals[4] = {
BoolArray4 obj = {
bool(mColorWriteMask & (1 << 0)), bool(mColorWriteMask & (1 << 1)),
bool(mColorWriteMask & (1 << 2)), bool(mColorWriteMask & (1 << 3))};
JS::Rooted<JS::Value> arr(cx);
if (!dom::ToJSValue(cx, vals, &arr)) {
rv = NS_ERROR_OUT_OF_MEMORY;
}
return arr;
return AsSomeVariant(obj);
}
case LOCAL_GL_ARRAY_BUFFER_BINDING: {
return WebGLObjectAsJSValue(cx, mBoundArrayBuffer.get(), rv);
return AsSomeVariant(mBoundArrayBuffer);
}
case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING: {
return WebGLObjectAsJSValue(
cx, mBoundVertexArray->mElementArrayBuffer.get(), rv);
return AsSomeVariant(mBoundVertexArray->mElementArrayBuffer);
}
case LOCAL_GL_RENDERBUFFER_BINDING: {
return WebGLObjectAsJSValue(cx, mBoundRenderbuffer.get(), rv);
return AsSomeVariant(mBoundRenderbuffer);
}
// DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING.
case LOCAL_GL_FRAMEBUFFER_BINDING: {
return WebGLObjectAsJSValue(cx, mBoundDrawFramebuffer.get(), rv);
return AsSomeVariant(mBoundDrawFramebuffer);
}
case LOCAL_GL_CURRENT_PROGRAM: {
return WebGLObjectAsJSValue(cx, mCurrentProgram.get(), rv);
return AsSomeVariant(mCurrentProgram);
}
case LOCAL_GL_TEXTURE_BINDING_2D: {
return WebGLObjectAsJSValue(cx, mBound2DTextures[mActiveTexture].get(),
rv);
return AsSomeVariant(mBound2DTextures[mActiveTexture]);
}
case LOCAL_GL_TEXTURE_BINDING_CUBE_MAP: {
return WebGLObjectAsJSValue(
cx, mBoundCubeMapTextures[mActiveTexture].get(), rv);
return AsSomeVariant(mBoundCubeMapTextures[mActiveTexture]);
}
default:
@ -599,7 +584,7 @@ JS::Value WebGLContext::GetParameter(JSContext* cx, GLenum pname,
}
ErrorInvalidEnumInfo("pname", pname);
return JS::NullValue();
return Nothing();
}
bool WebGLContext::IsEnabled(GLenum cap) {

Просмотреть файл

@ -235,18 +235,19 @@ void WebGLContext::GenerateMipmap(GLenum rawTexTarget) {
tex->GenerateMipmap();
}
JS::Value WebGLContext::GetTexParameter(GLenum rawTexTarget, GLenum pname) {
MaybeWebGLVariant WebGLContext::GetTexParameter(GLenum rawTexTarget,
GLenum pname) {
const FuncScope funcScope(*this, "getTexParameter");
const uint8_t funcDims = 0;
TexTarget texTarget;
WebGLTexture* tex;
if (!ValidateTexTarget(this, funcDims, rawTexTarget, &texTarget, &tex))
return JS::NullValue();
return Nothing();
if (!IsTexParamValid(pname)) {
ErrorInvalidEnumInfo("pname", pname);
return JS::NullValue();
return Nothing();
}
return tex->GetTexParameter(texTarget, pname);
@ -272,27 +273,35 @@ void WebGLContext::CompressedTexImage(uint8_t funcDims, GLenum rawTarget,
GLint level, GLenum internalFormat,
GLsizei width, GLsizei height,
GLsizei depth, GLint border,
const TexImageSource& src,
UniquePtr<webgl::TexUnpackBytes>&& src,
const Maybe<GLsizei>& expectedImageSize) {
if (!src) {
ErrorImplementationBug("No TexUnpackBytes received");
return;
}
TexImageTarget target;
WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcDims, rawTarget, &target, &tex)) return;
tex->CompressedTexImage(target, level, internalFormat, width, height, depth,
border, src, expectedImageSize);
border, std::move(src), expectedImageSize);
}
void WebGLContext::CompressedTexSubImage(
uint8_t funcDims, GLenum rawTarget, GLint level, GLint xOffset,
GLint yOffset, GLint zOffset, GLsizei width, GLsizei height, GLsizei depth,
GLenum unpackFormat, const TexImageSource& src,
GLenum unpackFormat, UniquePtr<webgl::TexUnpackBytes>&& src,
const Maybe<GLsizei>& expectedImageSize) {
if (!src) {
ErrorImplementationBug("No TexUnpackBytes received");
return;
}
TexImageTarget target;
WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcDims, rawTarget, &target, &tex)) return;
tex->CompressedTexSubImage(target, level, xOffset, yOffset, zOffset, width,
height, depth, unpackFormat, src,
height, depth, unpackFormat, std::move(src),
expectedImageSize);
}
@ -300,7 +309,8 @@ void WebGLContext::CompressedTexSubImage(
void WebGLContext::CopyTexImage2D(GLenum rawTarget, GLint level,
GLenum internalFormat, GLint x, GLint y,
GLsizei width, GLsizei height, GLint border) {
uint32_t width, uint32_t height,
uint32_t depth) {
const FuncScope funcScope(*this, "copyTexImage2D");
const uint8_t funcDims = 2;
@ -309,49 +319,50 @@ void WebGLContext::CopyTexImage2D(GLenum rawTarget, GLint level,
if (!ValidateTexImageTarget(this, funcDims, rawTarget, &target, &tex)) return;
tex->CopyTexImage2D(target, level, internalFormat, x, y, width, height,
border);
depth);
}
void WebGLContext::CopyTexSubImage(uint8_t funcDims, GLenum rawTarget,
GLint level, GLint xOffset, GLint yOffset,
GLint zOffset, GLint x, GLint y,
GLsizei width, GLsizei height) {
uint32_t width, uint32_t height,
uint32_t depth) {
TexImageTarget target;
WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcDims, rawTarget, &target, &tex)) return;
tex->CopyTexSubImage(target, level, xOffset, yOffset, zOffset, x, y, width,
height);
height, depth);
}
////
void WebGLContext::TexImage(uint8_t funcDims, GLenum rawTarget, GLint level,
GLenum internalFormat, GLsizei width,
GLsizei height, GLsizei depth, GLint border,
GLenum internalFormat, uint32_t width,
uint32_t height, uint32_t depth, GLint border,
GLenum unpackFormat, GLenum unpackType,
const TexImageSource& src) {
UniquePtr<webgl::TexUnpackBlob>&& src) {
TexImageTarget target;
WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcDims, rawTarget, &target, &tex)) return;
const webgl::PackingInfo pi = {unpackFormat, unpackType};
tex->TexImage(target, level, internalFormat, width, height, depth, border, pi,
src);
std::move(src));
}
void WebGLContext::TexSubImage(uint8_t funcDims, GLenum rawTarget, GLint level,
GLint xOffset, GLint yOffset, GLint zOffset,
GLsizei width, GLsizei height, GLsizei depth,
uint32_t width, uint32_t height, uint32_t depth,
GLenum unpackFormat, GLenum unpackType,
const TexImageSource& src) {
UniquePtr<webgl::TexUnpackBlob>&& src) {
TexImageTarget target;
WebGLTexture* tex;
if (!ValidateTexImageTarget(this, funcDims, rawTarget, &target, &tex)) return;
const webgl::PackingInfo pi = {unpackFormat, unpackType};
tex->TexSubImage(target, level, xOffset, yOffset, zOffset, width, height,
depth, pi, src);
depth, pi, std::move(src));
}
} // namespace mozilla

Просмотреть файл

@ -5,7 +5,7 @@
#include "WebGLContextUtils.h"
#include "WebGLContext.h"
#include "HostWebGLContext.h"
#include "GLContext.h"
#include "jsapi.h"
#include "js/Warnings.h" // JS::WarnASCII
@ -40,16 +40,6 @@ TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget) {
}
}
JS::Value StringValue(JSContext* cx, const char* chars, ErrorResult& rv) {
JSString* str = JS_NewStringCopyZ(cx, chars);
if (!str) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return JS::NullValue();
}
return JS::StringValue(str);
}
void WebGLContext::GenerateWarning(const char* fmt, ...) const {
va_list ap;
va_start(ap, fmt);
@ -68,25 +58,18 @@ void WebGLContext::GenerateWarning(const char* fmt, va_list ap) const {
VsprintfLiteral(buf, fmt, ap);
// JS::WarnASCII will print to stderr for us.
if (!mCanvasElement) {
return;
}
dom::AutoJSAPI api;
if (!api.Init(mCanvasElement->OwnerDoc()->GetScopeObject())) {
return;
}
JSContext* cx = api.cx();
const auto funcName = FuncName();
JS::WarnASCII(cx, "WebGL warning: %s: %s", funcName, buf);
nsCString msg;
msg.AppendPrintf("WebGL warning: %s: %s", funcName, buf);
if (!ShouldGenerateWarnings()) {
JS::WarnASCII(cx,
"WebGL: No further warnings will be reported for this WebGL "
"context. (already reported %d warnings)",
mAlreadyGeneratedWarnings);
msg.AppendPrintf(
"WebGL: No further warnings will be reported for"
" this WebGL context."
" (already reported %d warnings)",
mAlreadyGeneratedWarnings);
}
mHost->PostWarning(msg);
}
bool WebGLContext::ShouldGenerateWarnings() const {
@ -98,14 +81,6 @@ bool WebGLContext::ShouldGenerateWarnings() const {
void WebGLContext::GeneratePerfWarning(const char* fmt, ...) const {
if (!ShouldGeneratePerfWarnings()) return;
if (!mCanvasElement) return;
dom::AutoJSAPI api;
if (!api.Init(mCanvasElement->OwnerDoc()->GetScopeObject())) return;
JSContext* cx = api.cx();
////
va_list ap;
va_start(ap, fmt);
@ -117,15 +92,18 @@ void WebGLContext::GeneratePerfWarning(const char* fmt, ...) const {
////
const auto funcName = FuncName();
JS::WarnASCII(cx, "WebGL perf warning: %s: %s", funcName, buf);
nsCString msg;
msg.AppendPrintf("WebGL perf warning: %s: %s", funcName, buf);
mNumPerfWarnings++;
if (!ShouldGeneratePerfWarnings()) {
JS::WarnASCII(cx,
"WebGL: After reporting %u, no further perf warnings will be "
"reported for this WebGL context.",
uint32_t(mNumPerfWarnings));
msg.AppendPrintf(
"WebGL: After reporting %u, no further perf warnings will"
" be reported for this WebGL context.",
uint32_t(mNumPerfWarnings));
}
mHost->PostWarning(msg);
}
void WebGLContext::SynthesizeGLError(GLenum err) const {
@ -733,27 +711,27 @@ void WebGLContext::AssertCachedGlobalState() const {
int4[2] == mViewportWidth && int4[3] == mViewportHeight);
AssertUintParamCorrect(gl, LOCAL_GL_PACK_ALIGNMENT,
mPixelStore_PackAlignment);
mPixelStore.mPackAlignment);
AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_ALIGNMENT,
mPixelStore_UnpackAlignment);
mPixelStore.mUnpackAlignment);
if (IsWebGL2()) {
AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_IMAGE_HEIGHT,
mPixelStore_UnpackImageHeight);
mPixelStore.mUnpackImageHeight);
AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_SKIP_IMAGES,
mPixelStore_UnpackSkipImages);
mPixelStore.mUnpackSkipImages);
AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_ROW_LENGTH,
mPixelStore_UnpackRowLength);
mPixelStore.mUnpackRowLength);
AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_SKIP_ROWS,
mPixelStore_UnpackSkipRows);
mPixelStore.mUnpackSkipRows);
AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_SKIP_PIXELS,
mPixelStore_UnpackSkipPixels);
mPixelStore.mUnpackSkipPixels);
AssertUintParamCorrect(gl, LOCAL_GL_PACK_ROW_LENGTH,
mPixelStore_PackRowLength);
mPixelStore.mPackRowLength);
AssertUintParamCorrect(gl, LOCAL_GL_PACK_SKIP_ROWS,
mPixelStore_PackSkipRows);
mPixelStore.mPackSkipRows);
AssertUintParamCorrect(gl, LOCAL_GL_PACK_SKIP_PIXELS,
mPixelStore_PackSkipPixels);
mPixelStore.mPackSkipPixels);
}
MOZ_ASSERT(!gl::GLContext::IsBadCallError(errorScope.GetError()));
@ -799,14 +777,4 @@ const char* InfoFrom(WebGLTexImageFunc func, WebGLTexDimensions dims) {
////
JS::Value StringValue(JSContext* cx, const nsAString& str, ErrorResult& er) {
JSString* jsStr = JS_NewUCStringCopyN(cx, str.BeginReading(), str.Length());
if (!jsStr) {
er.Throw(NS_ERROR_OUT_OF_MEMORY);
return JS::NullValue();
}
return JS::StringValue(jsStr);
}
} // namespace mozilla

Просмотреть файл

@ -10,6 +10,7 @@
#include "mozilla/Assertions.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/TypedArray.h"
#include "WebGLStrongTypes.h"
@ -29,9 +30,6 @@ namespace mozilla {
// Returns GL_NONE if passed an invalid texture image target
TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget);
// Helper function to create a JS::Value from a C string
JS::Value StringValue(JSContext* cx, const char* str, ErrorResult& rv);
struct GLComponents {
unsigned char mComponents;
@ -53,42 +51,12 @@ struct GLComponents {
bool IsSubsetOf(const GLComponents& other) const;
};
template <typename WebGLObjectType>
JS::Value WebGLContext::WebGLObjectAsJSValue(JSContext* cx,
const WebGLObjectType* object,
ErrorResult& rv) const {
if (!object) return JS::NullValue();
MOZ_ASSERT(this == object->mContext);
JS::Rooted<JS::Value> v(cx);
JS::Rooted<JSObject*> wrapper(cx, GetWrapper());
JSAutoRealm ar(cx, wrapper);
if (!dom::GetOrCreateDOMReflector(cx, const_cast<WebGLObjectType*>(object),
&v)) {
rv.Throw(NS_ERROR_FAILURE);
return JS::NullValue();
}
return v;
}
template <typename WebGLObjectType>
JSObject* WebGLContext::WebGLObjectAsJSObject(JSContext* cx,
const WebGLObjectType* object,
ErrorResult& rv) const {
JS::Value v = WebGLObjectAsJSValue(cx, object, rv);
if (v.isNull()) return nullptr;
return &v.toObject();
}
/**
* Return the displayable name for the texture function that is the
* source for validation.
*/
const char* InfoFrom(WebGLTexImageFunc func, WebGLTexDimensions dims);
JS::Value StringValue(JSContext* cx, const nsAString& str, ErrorResult& er);
} // namespace mozilla
#endif // WEBGL_CONTEXT_UTILS_H_

Просмотреть файл

@ -226,7 +226,7 @@ bool WebGLContext::ValidateUniformArraySetter(
if (!loc->ValidateArrayLength(setterElemSize, setterArraySize)) return false;
const auto& elemCount = loc->mInfo->mActiveInfo->mElemCount;
const auto& elemCount = loc->mInfo->mActiveInfo.mElemCount;
MOZ_ASSERT(elemCount > loc->mArrayIndex);
const uint32_t uniformElemCount = elemCount - loc->mArrayIndex;
@ -255,7 +255,7 @@ bool WebGLContext::ValidateUniformMatrixArraySetter(
return false;
}
const auto& elemCount = loc->mInfo->mActiveInfo->mElemCount;
const auto& elemCount = loc->mInfo->mActiveInfo.mElemCount;
MOZ_ASSERT(elemCount > loc->mArrayIndex);
const uint32_t uniformElemCount = elemCount - loc->mArrayIndex;
@ -627,22 +627,22 @@ bool WebGLContext::InitAndValidateGL(FailureReason* const out_failReason) {
mDefaultVertexArray->BindVertexArray();
mDefaultVertexArray->mAttribs.resize(mGLMaxVertexAttribs);
mPixelStore_FlipY = false;
mPixelStore_PremultiplyAlpha = false;
mPixelStore_ColorspaceConversion = BROWSER_DEFAULT_WEBGL;
mPixelStore_RequireFastPath = false;
mPixelStore.mFlipY = false;
mPixelStore.mPremultiplyAlpha = false;
mPixelStore.mColorspaceConversion = BROWSER_DEFAULT_WEBGL;
mPixelStore.mRequireFastPath = false;
// GLES 3.0.4, p259:
mPixelStore_UnpackImageHeight = 0;
mPixelStore_UnpackSkipImages = 0;
mPixelStore_UnpackRowLength = 0;
mPixelStore_UnpackSkipRows = 0;
mPixelStore_UnpackSkipPixels = 0;
mPixelStore_UnpackAlignment = 4;
mPixelStore_PackRowLength = 0;
mPixelStore_PackSkipRows = 0;
mPixelStore_PackSkipPixels = 0;
mPixelStore_PackAlignment = 4;
mPixelStore.mUnpackImageHeight = 0;
mPixelStore.mUnpackSkipImages = 0;
mPixelStore.mUnpackRowLength = 0;
mPixelStore.mUnpackSkipRows = 0;
mPixelStore.mUnpackSkipPixels = 0;
mPixelStore.mUnpackAlignment = 4;
mPixelStore.mPackRowLength = 0;
mPixelStore.mPackSkipRows = 0;
mPixelStore.mPackSkipPixels = 0;
mPixelStore.mPackAlignment = 4;
mPrimRestartTypeBytes = 0;

Просмотреть файл

@ -14,6 +14,7 @@
#include "WebGLRenderbuffer.h"
#include "WebGLShader.h"
#include "WebGLTexture.h"
#include "WebGLTypes.h"
#include "WebGLVertexArray.h"
#include "WebGLVertexAttribData.h"
@ -43,39 +44,37 @@ static bool ValidateAttribIndex(WebGLContext& webgl, GLuint index) {
return valid;
}
JSObject* WebGLContext::GetVertexAttribFloat32Array(JSContext* cx,
GLuint index) {
GLfloat attrib[4];
Float32Array4&& WebGLContext::GetVertexAttribFloat32Array(GLuint index) {
Float32Array4 attrib;
if (index) {
gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, attrib);
gl->fGetVertexAttribfv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, &attrib[0]);
} else {
memcpy(attrib, mGenericVertexAttrib0Data,
memcpy(&attrib[0], mGenericVertexAttrib0Data,
sizeof(mGenericVertexAttrib0Data));
}
return dom::Float32Array::Create(cx, this, 4, attrib);
return std::move(attrib);
}
JSObject* WebGLContext::GetVertexAttribInt32Array(JSContext* cx, GLuint index) {
GLint attrib[4];
Int32Array4&& WebGLContext::GetVertexAttribInt32Array(GLuint index) {
Int32Array4 attrib;
if (index) {
gl->fGetVertexAttribIiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, attrib);
gl->fGetVertexAttribIiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, &attrib[0]);
} else {
memcpy(attrib, mGenericVertexAttrib0Data,
memcpy(&attrib[0], mGenericVertexAttrib0Data,
sizeof(mGenericVertexAttrib0Data));
}
return dom::Int32Array::Create(cx, this, 4, attrib);
return std::move(attrib);
}
JSObject* WebGLContext::GetVertexAttribUint32Array(JSContext* cx,
GLuint index) {
GLuint attrib[4];
Uint32Array4&& WebGLContext::GetVertexAttribUint32Array(GLuint index) {
Uint32Array4 attrib;
if (index) {
gl->fGetVertexAttribIuiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, attrib);
gl->fGetVertexAttribIuiv(index, LOCAL_GL_CURRENT_VERTEX_ATTRIB, &attrib[0]);
} else {
memcpy(attrib, mGenericVertexAttrib0Data,
memcpy(&attrib[0], mGenericVertexAttrib0Data,
sizeof(mGenericVertexAttrib0Data));
}
return dom::Uint32Array::Create(cx, this, 4, attrib);
return std::move(attrib);
}
////////////////////////////////////////
@ -182,81 +181,70 @@ void WebGLContext::DisableVertexAttribArray(GLuint index) {
mBoundVertexArray->InvalidateCaches();
}
JS::Value WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index,
GLenum pname, ErrorResult& rv) {
MaybeWebGLVariant WebGLContext::GetVertexAttrib(GLuint index, GLenum pname) {
const FuncScope funcScope(*this, "getVertexAttrib");
if (IsContextLost()) return JS::NullValue();
if (IsContextLost()) return Nothing();
if (!ValidateAttribIndex(*this, index)) return JS::NullValue();
if (!ValidateAttribIndex(*this, index)) return Nothing();
MOZ_ASSERT(mBoundVertexArray);
switch (pname) {
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
return WebGLObjectAsJSValue(
cx, mBoundVertexArray->mAttribs[index].mBuf.get(), rv);
return AsSomeVariant(std::move(mBoundVertexArray->mAttribs[index].mBuf));
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE:
return JS::Int32Value(mBoundVertexArray->mAttribs[index].Stride());
return AsSomeVariant(
static_cast<int32_t>(mBoundVertexArray->mAttribs[index].Stride()));
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE:
return JS::Int32Value(mBoundVertexArray->mAttribs[index].Size());
return AsSomeVariant(
static_cast<int32_t>(mBoundVertexArray->mAttribs[index].Size()));
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE:
return JS::Int32Value(mBoundVertexArray->mAttribs[index].Type());
return AsSomeVariant(
static_cast<int32_t>(mBoundVertexArray->mAttribs[index].Type()));
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_INTEGER:
if (IsWebGL2())
return JS::BooleanValue(
mBoundVertexArray->mAttribs[index].IntegerFunc());
return AsSomeVariant(static_cast<bool>(
mBoundVertexArray->mAttribs[index].IntegerFunc()));
break;
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
if (IsWebGL2() ||
IsExtensionEnabled(WebGLExtensionID::ANGLE_instanced_arrays)) {
return JS::Int32Value(mBoundVertexArray->mAttribs[index].mDivisor);
return AsSomeVariant(
static_cast<int32_t>(mBoundVertexArray->mAttribs[index].mDivisor));
}
break;
case LOCAL_GL_CURRENT_VERTEX_ATTRIB: {
JS::RootedObject obj(cx);
switch (mGenericVertexAttribTypes[index]) {
case webgl::AttribBaseType::Float:
obj = GetVertexAttribFloat32Array(cx, index);
break;
return AsSomeVariant(std::move(GetVertexAttribFloat32Array(index)));
case webgl::AttribBaseType::Int:
obj = GetVertexAttribInt32Array(cx, index);
break;
return AsSomeVariant(std::move(GetVertexAttribInt32Array(index)));
case webgl::AttribBaseType::UInt:
obj = GetVertexAttribUint32Array(cx, index);
break;
return AsSomeVariant(std::move(GetVertexAttribUint32Array(index)));
case webgl::AttribBaseType::Boolean:
MOZ_CRASH("impossible");
}
if (!obj) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return JS::NullValue();
}
return JS::ObjectValue(*obj);
}
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED:
return JS::BooleanValue(mBoundVertexArray->mAttribs[index].mEnabled);
return AsSomeVariant(mBoundVertexArray->mAttribs[index].mEnabled);
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
return JS::BooleanValue(mBoundVertexArray->mAttribs[index].Normalized());
return AsSomeVariant(mBoundVertexArray->mAttribs[index].Normalized());
default:
break;
}
ErrorInvalidEnumInfo("pname", pname);
return JS::NullValue();
return Nothing();
}
WebGLsizeiptr WebGLContext::GetVertexAttribOffset(GLuint index, GLenum pname) {

Просмотреть файл

@ -0,0 +1,28 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "WebGLCrossProcessCommandQueue.h"
#include "WebGLMethodDispatcher.h"
namespace mozilla {
HostWebGLCommandSink::HostWebGLCommandSink(
UniquePtr<Consumer>&& aConsumer,
UniquePtr<ProducerConsumerQueue>& aResponsePcq)
: SyncCommandSink(std::move(aConsumer), aResponsePcq) {}
bool HostWebGLCommandSink::DispatchCommand(size_t command) {
if (!mHostContext) {
return false;
}
return WebGLMethodDispatcher::DispatchCommand(command, *this, *mHostContext);
}
void HostWebGLCommandSink::ReportOOM() {
mHostContext->ReportOOMAndLoseContext();
}
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 WEBGLCROSSPROCESSCOMMANDQUEUE_H_
#define WEBGLCROSSPROCESSCOMMANDQUEUE_H_
#include "mozilla/dom/WebGLCommandQueue.h"
namespace mozilla {
namespace layers {
class PCompositorBridgeParent;
}
class HostWebGLContext;
using mozilla::webgl::ProducerConsumerQueue;
/**
* The source for the WebGL Command Queue.
*/
using ClientWebGLCommandSource = SyncCommandSource<size_t>;
/**
* The sink for the WebGL Command Queue. This object is created in the client
* and sent to the host, where it needs to be given a HostWebGLContext that it
* then uses for executing methods. Add new commands to DispatchCommand using
* the WEBGL_SYNC_COMMAND and WEBGL_ASYNC_COMMAND macros.
*/
class HostWebGLCommandSink : public SyncCommandSink<size_t> {
public:
HostWebGLCommandSink(UniquePtr<Consumer>&& aConsumer,
UniquePtr<ProducerConsumerQueue>& aResponsePcq);
~HostWebGLCommandSink() {}
void SetHostContext(HostWebGLContext* aHostContext) {
mHostContext = aHostContext;
}
protected:
// For IPDL:
friend struct mozilla::ipc::IPDLParamTraits<HostWebGLCommandSink>;
friend class mozilla::layers::PCompositorBridgeParent;
HostWebGLCommandSink() {}
bool DispatchCommand(size_t command) override;
void ReportOOM() override;
HostWebGLContext* mHostContext;
};
/**
* Factory for the WebGL command queue.
*/
using WebGLCrossProcessCommandQueue =
CommandQueue<ClientWebGLCommandSource, HostWebGLCommandSink>;
namespace ipc {
template <>
struct IPDLParamTraits<mozilla::HostWebGLCommandSink>
: public IPDLParamTraits<mozilla::SyncCommandSink<size_t>> {
public:
typedef mozilla::HostWebGLCommandSink paramType;
};
} // namespace ipc
} // namespace mozilla
#endif // WEBGLCROSSPROCESSCOMMANDQUEUE_H_

Просмотреть файл

@ -0,0 +1,39 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "WebGLErrorQueue.h"
#include "ClientWebGLContext.h"
namespace mozilla {
ClientWebGLErrorSink::ClientWebGLErrorSink(UniquePtr<Consumer>&& aConsumer)
: CommandSink(std::move(aConsumer)) {}
void ClientWebGLErrorSink::SetClientWebGLContext(
RefPtr<ClientWebGLContext>& aClientContext) {
mClientContext = aClientContext;
}
bool ClientWebGLErrorSink::DispatchCommand(WebGLErrorCommand command) {
if (!mClientContext) {
return false;
}
#define WEBGL_ERROR_HANDLER(_cmd, _method) \
case _cmd: \
return DispatchAsyncMethod(*mClientContext.get(), \
&ClientWebGLContext::_method);
switch (command) {
WEBGL_ERROR_HANDLER(OnLostContext, OnLostContext)
WEBGL_ERROR_HANDLER(OnRestoredContext, OnRestoredContext)
WEBGL_ERROR_HANDLER(CreationError, PostContextCreationError)
WEBGL_ERROR_HANDLER(Warning, PostWarning)
default:
return false;
}
}
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,58 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 WEBGLERRORQUEUE_H_
#define WEBGLERRORQUEUE_H_
#include "WebGLCommandQueue.h"
namespace mozilla {
class ClientWebGLContext;
using mozilla::webgl::PcqStatus;
enum WebGLErrorCommand {
CreationError,
OnLostContext,
OnRestoredContext,
Warning
};
/**
* This is the source for the WebGL error and warning queue. When an
* asynchronous error or warning occurs in the host, such as the GL context
* being lost or a diagnostic message being printed, it is inserted into this
* queue to be asynchronously retrieved by the client in the content process,
* where it is communicated to the relevant DOM objects.
*/
using HostWebGLErrorSource = CommandSource<WebGLErrorCommand>;
/**
* This is the sink for the WebGL error and warning queue.
* Before this sink can handle events, it needs to have its ClientWebGLContext
* set.
*/
class ClientWebGLErrorSink : public CommandSink<WebGLErrorCommand> {
public:
ClientWebGLErrorSink(UniquePtr<Consumer>&& aConsumer);
void SetClientWebGLContext(RefPtr<ClientWebGLContext>& aClientContext);
protected:
bool DispatchCommand(WebGLErrorCommand command) override;
RefPtr<ClientWebGLContext> mClientContext;
};
/**
* Factory for the WebGL error and warning queue.
*/
using WebGLErrorQueue =
CommandQueue<HostWebGLErrorSource, ClientWebGLErrorSink>;
} // namespace mozilla
#endif // WEBGLERRORQUEUE_H_

Просмотреть файл

@ -23,6 +23,4 @@ bool WebGLExtensionBlendMinMax::IsSupported(const WebGLContext* webgl) {
return webgl->GL()->IsSupported(gl::GLFeature::blend_minmax);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionBlendMinMax, EXT_blend_minmax)
} // namespace mozilla

Просмотреть файл

@ -52,7 +52,4 @@ bool WebGLExtensionColorBufferFloat::IsSupported(const WebGLContext* webgl) {
gl->IsSupported(gl::GLFeature::frag_color_float);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionColorBufferFloat,
WEBGL_color_buffer_float)
} // namespace mozilla

Просмотреть файл

@ -56,7 +56,4 @@ bool WebGLExtensionColorBufferHalfFloat::IsSupported(
gl->IsSupported(gl::GLFeature::frag_color_float);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionColorBufferHalfFloat,
EXT_color_buffer_half_float)
} // namespace mozilla

Просмотреть файл

@ -65,24 +65,23 @@ WebGLExtensionCompressedTextureASTC::WebGLExtensionCompressedTextureASTC(
WebGLExtensionCompressedTextureASTC::~WebGLExtensionCompressedTextureASTC() {}
void WebGLExtensionCompressedTextureASTC::GetSupportedProfiles(
dom::Nullable<nsTArray<nsString> >& retval) const {
retval.SetNull();
if (mIsLost) {
Maybe<nsTArray<nsString>>
WebGLExtensionCompressedTextureASTC::GetSupportedProfiles() const {
if (mIsLost || !mContext) {
if (mContext) {
mContext->ErrorInvalidOperation("%s: Extension is lost.",
"drawElementsInstancedANGLE");
}
return;
return {};
}
nsTArray<nsString>& arr = retval.SetValue();
nsTArray<nsString> arr;
arr.AppendElement(NS_LITERAL_STRING("ldr"));
if (mContext->gl->IsExtensionSupported(
gl::GLContext::KHR_texture_compression_astc_hdr)) {
arr.AppendElement(NS_LITERAL_STRING("hdr"));
}
return Some(arr);
}
bool WebGLExtensionCompressedTextureASTC::IsSupported(
@ -92,7 +91,4 @@ bool WebGLExtensionCompressedTextureASTC::IsSupported(
gl::GLContext::KHR_texture_compression_astc_ldr);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureASTC,
WEBGL_compressed_texture_astc)
} // namespace mozilla

Просмотреть файл

@ -42,7 +42,4 @@ bool WebGLExtensionCompressedTextureBPTC::IsSupported(
return webgl->gl->IsSupported(gl::GLFeature::texture_compression_bptc);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureBPTC,
EXT_texture_compression_bptc)
} // namespace mozilla

Просмотреть файл

@ -59,7 +59,4 @@ WebGLExtensionCompressedTextureES3::WebGLExtensionCompressedTextureES3(
WebGLExtensionCompressedTextureES3::~WebGLExtensionCompressedTextureES3() {}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureES3,
WEBGL_compressed_texture_etc)
} // namespace mozilla

Просмотреть файл

@ -35,7 +35,4 @@ WebGLExtensionCompressedTextureETC1::WebGLExtensionCompressedTextureETC1(
WebGLExtensionCompressedTextureETC1::~WebGLExtensionCompressedTextureETC1() {}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureETC1,
WEBGL_compressed_texture_etc1)
} // namespace mozilla

Просмотреть файл

@ -38,7 +38,4 @@ WebGLExtensionCompressedTexturePVRTC::WebGLExtensionCompressedTexturePVRTC(
WebGLExtensionCompressedTexturePVRTC::~WebGLExtensionCompressedTexturePVRTC() {}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTexturePVRTC,
WEBGL_compressed_texture_pvrtc)
} // namespace mozilla

Просмотреть файл

@ -42,7 +42,4 @@ bool WebGLExtensionCompressedTextureRGTC::IsSupported(
return webgl->gl->IsSupported(gl::GLFeature::texture_compression_rgtc);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureRGTC,
EXT_texture_compression_rgtc)
} // namespace mozilla

Просмотреть файл

@ -52,7 +52,4 @@ bool WebGLExtensionCompressedTextureS3TC::IsSupported(
gl::GLContext::ANGLE_texture_compression_dxt5);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureS3TC,
WEBGL_compressed_texture_s3tc)
} // namespace mozilla

Просмотреть файл

@ -52,7 +52,4 @@ bool WebGLExtensionCompressedTextureS3TC_SRGB::IsSupported(
gl->IsExtensionSupported(gl::GLContext::EXT_texture_compression_s3tc);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureS3TC_SRGB,
WEBGL_compressed_texture_s3tc_srgb)
} // namespace mozilla

Просмотреть файл

@ -16,7 +16,4 @@ WebGLExtensionDebugRendererInfo::WebGLExtensionDebugRendererInfo(
WebGLExtensionDebugRendererInfo::~WebGLExtensionDebugRendererInfo() {}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDebugRendererInfo,
WEBGL_debug_renderer_info)
} // namespace mozilla

Просмотреть файл

@ -19,20 +19,17 @@ WebGLExtensionDebugShaders::~WebGLExtensionDebugShaders() {}
// If no source has been defined, compileShader() has not been called, or the
// translation has failed for shader, an empty string is returned; otherwise,
// return the translated source.
void WebGLExtensionDebugShaders::GetTranslatedShaderSource(
const WebGLShader& shader, nsAString& retval) const {
retval.SetIsVoid(true);
if (mIsLost || !mContext) return;
nsString WebGLExtensionDebugShaders::GetTranslatedShaderSource(
const WebGLShader& shader) const {
if (mIsLost) return {};
const WebGLContext::FuncScope funcScope(*mContext,
"getShaderTranslatedSource");
MOZ_ASSERT(!mContext->IsContextLost());
if (!mContext->ValidateObject("shader", shader)) return;
if (!mContext->ValidateObject("shader", shader)) return EmptyString();
shader.GetShaderTranslatedSource(&retval);
return shader.GetShaderTranslatedSource();
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDebugShaders, WEBGL_debug_shaders)
} // namespace mozilla

Просмотреть файл

@ -50,6 +50,4 @@ bool WebGLExtensionDepthTexture::IsSupported(const WebGLContext* const webgl) {
gl->IsExtensionSupported(gl::GLContext::ANGLE_depth_texture);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDepthTexture, WEBGL_depth_texture)
} // namespace mozilla

Просмотреть файл

@ -77,26 +77,22 @@ void WebGLExtensionDisjointTimerQuery::QueryCounterEXT(WebGLQuery& query,
query.QueryCounter(target);
}
void WebGLExtensionDisjointTimerQuery::GetQueryEXT(
JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval) const {
retval.setNull();
if (mIsLost || !mContext) return;
MaybeWebGLVariant WebGLExtensionDisjointTimerQuery::GetQueryEXT(
GLenum target, GLenum pname) const {
if (mIsLost || !mContext) return {};
const WebGLContext::FuncScope funcScope(*mContext, "getQueryEXT");
MOZ_ASSERT(!mContext->IsContextLost());
mContext->GetQuery(cx, target, pname, retval);
return mContext->GetQuery(target, pname);
}
void WebGLExtensionDisjointTimerQuery::GetQueryObjectEXT(
JSContext* cx, const WebGLQuery& query, GLenum pname,
JS::MutableHandleValue retval) const {
retval.setNull();
if (mIsLost || !mContext) return;
MaybeWebGLVariant WebGLExtensionDisjointTimerQuery::GetQueryObjectEXT(
const WebGLQuery& query, GLenum pname) const {
if (mIsLost || !mContext) return {};
const WebGLContext::FuncScope funcScope(*mContext, "getQueryObjectEXT");
MOZ_ASSERT(!mContext->IsContextLost());
mContext->GetQueryParameter(cx, query, pname, retval);
return mContext->GetQueryParameter(query, pname);
}
bool WebGLExtensionDisjointTimerQuery::IsSupported(const WebGLContext* webgl) {
@ -107,7 +103,4 @@ bool WebGLExtensionDisjointTimerQuery::IsSupported(const WebGLContext* webgl) {
gl::GLFeature::query_counter); // provides GL_TIMESTAMP
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDisjointTimerQuery,
EXT_disjoint_timer_query)
} // namespace mozilla

Просмотреть файл

@ -25,7 +25,7 @@ WebGLExtensionDrawBuffers::WebGLExtensionDrawBuffers(WebGLContext* webgl)
WebGLExtensionDrawBuffers::~WebGLExtensionDrawBuffers() {}
void WebGLExtensionDrawBuffers::DrawBuffersWEBGL(
const dom::Sequence<GLenum>& buffers) {
const nsTArray<GLenum>& buffers) {
if (mIsLost) {
if (mContext) {
mContext->ErrorInvalidOperation("drawBuffersWEBGL: Extension is lost.");
@ -48,6 +48,4 @@ bool WebGLExtensionDrawBuffers::IsSupported(const WebGLContext* webgl) {
return gl->IsSupported(gl::GLFeature::draw_buffers);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDrawBuffers, WEBGL_draw_buffers)
} // namespace mozilla

Просмотреть файл

@ -48,7 +48,4 @@ bool WebGLExtensionEXTColorBufferFloat::IsSupported(const WebGLContext* webgl) {
return gl->IsSupported(gl::GLFeature::EXT_color_buffer_float);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionEXTColorBufferFloat,
EXT_color_buffer_float)
} // namespace mozilla

Просмотреть файл

@ -17,7 +17,4 @@ WebGLExtensionElementIndexUint::WebGLExtensionElementIndexUint(
WebGLExtensionElementIndexUint::~WebGLExtensionElementIndexUint() {}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionElementIndexUint,
OES_element_index_uint)
} // namespace mozilla

Просмотреть файл

@ -30,6 +30,4 @@ bool WebGLExtensionFragDepth::IsSupported(const WebGLContext* webgl) {
return gl->IsSupported(gl::GLFeature::frag_depth);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionFragDepth, EXT_frag_depth)
} // namespace mozilla

Просмотреть файл

@ -67,6 +67,4 @@ bool WebGLExtensionInstancedArrays::IsSupported(const WebGLContext* webgl) {
gl->IsSupported(gl::GLFeature::instanced_arrays);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionInstancedArrays, ANGLE_instanced_arrays)
} // namespace mozilla

Просмотреть файл

@ -25,6 +25,4 @@ void WebGLExtensionLoseContext::RestoreContext() {
mContext->RestoreContext();
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionLoseContext, WEBGL_lose_context)
} // namespace mozilla

Просмотреть файл

@ -17,10 +17,8 @@ WebGLExtensionMOZDebug::WebGLExtensionMOZDebug(WebGLContext* webgl)
WebGLExtensionMOZDebug::~WebGLExtensionMOZDebug() {}
void WebGLExtensionMOZDebug::GetParameter(JSContext* cx, GLenum pname,
JS::MutableHandle<JS::Value> retval,
ErrorResult& er) const {
if (mIsLost || !mContext) return;
MaybeWebGLVariant WebGLExtensionMOZDebug::GetParameter(GLenum pname) const {
if (mIsLost || !mContext) return {};
const WebGLContext::FuncScope funcScope(*mContext, "MOZ_debug.getParameter");
MOZ_ASSERT(!mContext->IsContextLost());
@ -43,36 +41,31 @@ void WebGLExtensionMOZDebug::GetParameter(JSContext* cx, GLenum pname,
ret.Append(NS_ConvertUTF8toUTF16(rawExt));
}
}
retval.set(StringValue(cx, ret, er));
return;
return AsSomeVariant(ret);
}
case LOCAL_GL_RENDERER:
case LOCAL_GL_VENDOR:
case LOCAL_GL_VERSION: {
const auto raw = (const char*)gl->fGetString(pname);
retval.set(StringValue(cx, NS_ConvertUTF8toUTF16(raw), er));
return;
nsString ret = NS_ConvertUTF8toUTF16(raw);
return AsSomeVariant(ret);
}
case dom::MOZ_debug_Binding::WSI_INFO: {
nsCString info;
gl->GetWSIInfo(&info);
retval.set(StringValue(cx, NS_ConvertUTF8toUTF16(info), er));
return;
nsString ret = NS_ConvertUTF8toUTF16(info);
return AsSomeVariant(ret);
}
case dom::MOZ_debug_Binding::DOES_INDEX_VALIDATION:
retval.set(JS::BooleanValue(mContext->mNeedsIndexValidation));
return;
return AsSomeVariant(std::move(mContext->mNeedsIndexValidation));
default:
mContext->ErrorInvalidEnumInfo("pname", pname);
retval.set(JS::NullValue());
return;
return Nothing();
}
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionMOZDebug, MOZ_debug)
} // namespace mozilla

Просмотреть файл

@ -58,6 +58,4 @@ bool WebGLExtensionSRGB::IsSupported(const WebGLContext* const webgl) {
return webgl->gl->IsSupported(gl::GLFeature::sRGB);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionSRGB, EXT_sRGB)
} // namespace mozilla

Просмотреть файл

@ -31,7 +31,4 @@ bool WebGLExtensionShaderTextureLod::IsSupported(const WebGLContext* webgl) {
return gl->IsSupported(gl::GLFeature::shader_texture_lod);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionShaderTextureLod,
EXT_shader_texture_lod)
} // namespace mozilla

Просмотреть файл

@ -17,7 +17,4 @@ WebGLExtensionStandardDerivatives::WebGLExtensionStandardDerivatives(
WebGLExtensionStandardDerivatives::~WebGLExtensionStandardDerivatives() {}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionStandardDerivatives,
OES_standard_derivatives)
} // namespace mozilla

Просмотреть файл

@ -18,7 +18,4 @@ WebGLExtensionTextureFilterAnisotropic::WebGLExtensionTextureFilterAnisotropic(
WebGLExtensionTextureFilterAnisotropic::
~WebGLExtensionTextureFilterAnisotropic() {}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureFilterAnisotropic,
EXT_texture_filter_anisotropic)
} // namespace mozilla

Просмотреть файл

@ -125,6 +125,4 @@ bool WebGLExtensionTextureFloat::IsSupported(const WebGLContext* webgl) {
return true;
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureFloat, OES_texture_float)
} // namespace mozilla

Просмотреть файл

@ -32,7 +32,4 @@ WebGLExtensionTextureFloatLinear::WebGLExtensionTextureFloatLinear(
WebGLExtensionTextureFloatLinear::~WebGLExtensionTextureFloatLinear() {}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureFloatLinear,
OES_texture_float_linear)
} // namespace mozilla

Просмотреть файл

@ -130,7 +130,4 @@ bool WebGLExtensionTextureHalfFloat::IsSupported(const WebGLContext* webgl) {
return true;
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureHalfFloat,
OES_texture_half_float)
} // namespace mozilla

Просмотреть файл

@ -27,7 +27,4 @@ WebGLExtensionTextureHalfFloatLinear::WebGLExtensionTextureHalfFloatLinear(
WebGLExtensionTextureHalfFloatLinear::~WebGLExtensionTextureHalfFloatLinear() {}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureHalfFloatLinear,
OES_texture_half_float_linear)
} // namespace mozilla

Просмотреть файл

@ -44,6 +44,4 @@ void WebGLExtensionVertexArray::BindVertexArrayOES(WebGLVertexArray* array) {
mContext->BindVertexArray(array);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionVertexArray, OES_vertex_array_object)
} // namespace mozilla

Просмотреть файл

@ -13,7 +13,7 @@
namespace mozilla {
WebGLExtensionBase::WebGLExtensionBase(WebGLContext* webgl)
: WebGLContextBoundObject(webgl), mIsLost(false), mIsExplicit(false) {}
: WebGLContextBoundObject(webgl) {}
WebGLExtensionBase::~WebGLExtensionBase() {}
@ -23,11 +23,6 @@ void WebGLExtensionBase::MarkLost() {
OnMarkLost();
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLExtensionBase)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLExtensionBase, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLExtensionBase, Release)
// -
WebGLExtensionExplicitPresent::WebGLExtensionExplicitPresent(
@ -46,8 +41,6 @@ void WebGLExtensionExplicitPresent::Present() const {
mContext->PresentScreenBuffer();
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionExplicitPresent, WEBGL_explicit_present)
// -
WebGLExtensionFloatBlend::WebGLExtensionFloatBlend(WebGLContext* const webgl)
@ -68,8 +61,6 @@ bool WebGLExtensionFloatBlend::IsSupported(const WebGLContext* const webgl) {
return gl->IsExtensionSupported(gl::GLContext::EXT_float_blend);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionFloatBlend, EXT_float_blend)
// -
WebGLExtensionFBORenderMipmap::WebGLExtensionFBORenderMipmap(
@ -90,8 +81,6 @@ bool WebGLExtensionFBORenderMipmap::IsSupported(
return gl->IsExtensionSupported(gl::GLContext::OES_fbo_render_mipmap);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionFBORenderMipmap, OES_fbo_render_mipmap)
// -
WebGLExtensionMultiview::WebGLExtensionMultiview(WebGLContext* const webgl)
@ -123,6 +112,4 @@ void WebGLExtensionMultiview::FramebufferTextureMultiviewOVR(
baseViewIndex, numViews);
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionMultiview, OVR_multiview2)
} // namespace mozilla

Просмотреть файл

@ -34,13 +34,10 @@ class WebGLShader;
class WebGLTexture;
class WebGLVertexArray;
class WebGLExtensionBase : public nsWrapperCache,
public WebGLContextBoundObject {
class WebGLExtensionBase : public WebGLContextBoundObject<WebGLExtensionBase> {
public:
explicit WebGLExtensionBase(WebGLContext* webgl);
WebGLContext* GetParentObject() const { return mContext; }
void MarkLost();
void SetExplicit() {
@ -50,31 +47,18 @@ class WebGLExtensionBase : public nsWrapperCache,
bool IsExplicit() { return mIsExplicit; }
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLExtensionBase)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLExtensionBase)
NS_INLINE_DECL_REFCOUNTING(WebGLExtensionBase)
protected:
virtual ~WebGLExtensionBase();
virtual void OnMarkLost() {}
bool mIsLost;
virtual void OnSetExplicit() {}
bool mIsExplicit;
bool mIsLost = false;
bool mIsExplicit = false;
};
#define DECL_WEBGL_EXTENSION_GOOP \
virtual JSObject* WrapObject(JSContext* cx, \
JS::Handle<JSObject*> givenProto) override;
#define IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionType, WebGLBindingType) \
JSObject* WebGLExtensionType::WrapObject(JSContext* cx, \
JS::Handle<JSObject*> givenProto) { \
return dom::WebGLBindingType##_Binding::Wrap(cx, this, givenProto); \
}
////
class WebGLExtensionCompressedTextureASTC : public WebGLExtensionBase {
@ -82,11 +66,9 @@ class WebGLExtensionCompressedTextureASTC : public WebGLExtensionBase {
explicit WebGLExtensionCompressedTextureASTC(WebGLContext* webgl);
virtual ~WebGLExtensionCompressedTextureASTC();
void GetSupportedProfiles(dom::Nullable<nsTArray<nsString> >& retval) const;
Maybe<nsTArray<nsString>> GetSupportedProfiles() const;
static bool IsSupported(const WebGLContext* webgl);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionCompressedTextureBPTC final : public WebGLExtensionBase {
@ -94,32 +76,24 @@ class WebGLExtensionCompressedTextureBPTC final : public WebGLExtensionBase {
explicit WebGLExtensionCompressedTextureBPTC(WebGLContext* webgl);
static bool IsSupported(const WebGLContext* webgl);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionCompressedTextureES3 : public WebGLExtensionBase {
public:
explicit WebGLExtensionCompressedTextureES3(WebGLContext*);
virtual ~WebGLExtensionCompressedTextureES3();
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionCompressedTextureETC1 : public WebGLExtensionBase {
public:
explicit WebGLExtensionCompressedTextureETC1(WebGLContext*);
virtual ~WebGLExtensionCompressedTextureETC1();
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionCompressedTexturePVRTC : public WebGLExtensionBase {
public:
explicit WebGLExtensionCompressedTexturePVRTC(WebGLContext*);
virtual ~WebGLExtensionCompressedTexturePVRTC();
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionCompressedTextureRGTC final : public WebGLExtensionBase {
@ -127,8 +101,6 @@ class WebGLExtensionCompressedTextureRGTC final : public WebGLExtensionBase {
explicit WebGLExtensionCompressedTextureRGTC(WebGLContext* webgl);
static bool IsSupported(const WebGLContext* webgl);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionCompressedTextureS3TC : public WebGLExtensionBase {
@ -137,8 +109,6 @@ class WebGLExtensionCompressedTextureS3TC : public WebGLExtensionBase {
virtual ~WebGLExtensionCompressedTextureS3TC();
static bool IsSupported(const WebGLContext*);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionCompressedTextureS3TC_SRGB : public WebGLExtensionBase {
@ -147,16 +117,12 @@ class WebGLExtensionCompressedTextureS3TC_SRGB : public WebGLExtensionBase {
virtual ~WebGLExtensionCompressedTextureS3TC_SRGB();
static bool IsSupported(const WebGLContext*);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionDebugRendererInfo : public WebGLExtensionBase {
public:
explicit WebGLExtensionDebugRendererInfo(WebGLContext*);
virtual ~WebGLExtensionDebugRendererInfo();
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionDebugShaders : public WebGLExtensionBase {
@ -164,10 +130,7 @@ class WebGLExtensionDebugShaders : public WebGLExtensionBase {
explicit WebGLExtensionDebugShaders(WebGLContext*);
virtual ~WebGLExtensionDebugShaders();
void GetTranslatedShaderSource(const WebGLShader& shader,
nsAString& retval) const;
DECL_WEBGL_EXTENSION_GOOP
nsString GetTranslatedShaderSource(const WebGLShader& shader) const;
};
class WebGLExtensionDepthTexture : public WebGLExtensionBase {
@ -176,16 +139,12 @@ class WebGLExtensionDepthTexture : public WebGLExtensionBase {
virtual ~WebGLExtensionDepthTexture();
static bool IsSupported(const WebGLContext*);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionElementIndexUint : public WebGLExtensionBase {
public:
explicit WebGLExtensionElementIndexUint(WebGLContext*);
virtual ~WebGLExtensionElementIndexUint();
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionExplicitPresent : public WebGLExtensionBase {
@ -195,8 +154,6 @@ class WebGLExtensionExplicitPresent : public WebGLExtensionBase {
static bool IsSupported(const WebGLContext*);
void Present() const;
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionEXTColorBufferFloat : public WebGLExtensionBase {
@ -205,8 +162,6 @@ class WebGLExtensionEXTColorBufferFloat : public WebGLExtensionBase {
virtual ~WebGLExtensionEXTColorBufferFloat() {}
static bool IsSupported(const WebGLContext*);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionFBORenderMipmap : public WebGLExtensionBase {
@ -215,8 +170,6 @@ class WebGLExtensionFBORenderMipmap : public WebGLExtensionBase {
virtual ~WebGLExtensionFBORenderMipmap();
static bool IsSupported(const WebGLContext*);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionFloatBlend : public WebGLExtensionBase {
@ -225,8 +178,6 @@ class WebGLExtensionFloatBlend : public WebGLExtensionBase {
virtual ~WebGLExtensionFloatBlend();
static bool IsSupported(const WebGLContext*);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionFragDepth : public WebGLExtensionBase {
@ -235,8 +186,6 @@ class WebGLExtensionFragDepth : public WebGLExtensionBase {
virtual ~WebGLExtensionFragDepth();
static bool IsSupported(const WebGLContext* context);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionLoseContext : public WebGLExtensionBase {
@ -246,8 +195,6 @@ class WebGLExtensionLoseContext : public WebGLExtensionBase {
void LoseContext();
void RestoreContext();
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionSRGB : public WebGLExtensionBase {
@ -256,16 +203,12 @@ class WebGLExtensionSRGB : public WebGLExtensionBase {
virtual ~WebGLExtensionSRGB();
static bool IsSupported(const WebGLContext* context);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionStandardDerivatives : public WebGLExtensionBase {
public:
explicit WebGLExtensionStandardDerivatives(WebGLContext*);
virtual ~WebGLExtensionStandardDerivatives();
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionShaderTextureLod : public WebGLExtensionBase {
@ -274,16 +217,12 @@ class WebGLExtensionShaderTextureLod : public WebGLExtensionBase {
virtual ~WebGLExtensionShaderTextureLod();
static bool IsSupported(const WebGLContext* context);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionTextureFilterAnisotropic : public WebGLExtensionBase {
public:
explicit WebGLExtensionTextureFilterAnisotropic(WebGLContext*);
virtual ~WebGLExtensionTextureFilterAnisotropic();
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionTextureFloat : public WebGLExtensionBase {
@ -294,16 +233,12 @@ class WebGLExtensionTextureFloat : public WebGLExtensionBase {
virtual ~WebGLExtensionTextureFloat();
static bool IsSupported(const WebGLContext*);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionTextureFloatLinear : public WebGLExtensionBase {
public:
explicit WebGLExtensionTextureFloatLinear(WebGLContext*);
virtual ~WebGLExtensionTextureFloatLinear();
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionTextureHalfFloat : public WebGLExtensionBase {
@ -314,16 +249,12 @@ class WebGLExtensionTextureHalfFloat : public WebGLExtensionBase {
virtual ~WebGLExtensionTextureHalfFloat();
static bool IsSupported(const WebGLContext*);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionTextureHalfFloatLinear : public WebGLExtensionBase {
public:
explicit WebGLExtensionTextureHalfFloatLinear(WebGLContext*);
virtual ~WebGLExtensionTextureHalfFloatLinear();
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionColorBufferFloat : public WebGLExtensionBase {
@ -334,10 +265,7 @@ class WebGLExtensionColorBufferFloat : public WebGLExtensionBase {
static bool IsSupported(const WebGLContext*);
void SetRenderable(const webgl::FormatRenderableState);
void OnSetExplicit() override;
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionColorBufferHalfFloat : public WebGLExtensionBase {
@ -348,10 +276,7 @@ class WebGLExtensionColorBufferHalfFloat : public WebGLExtensionBase {
static bool IsSupported(const WebGLContext*);
void SetRenderable(const webgl::FormatRenderableState);
void OnSetExplicit() override;
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionDrawBuffers : public WebGLExtensionBase {
@ -359,11 +284,9 @@ class WebGLExtensionDrawBuffers : public WebGLExtensionBase {
explicit WebGLExtensionDrawBuffers(WebGLContext*);
virtual ~WebGLExtensionDrawBuffers();
void DrawBuffersWEBGL(const dom::Sequence<GLenum>& buffers);
void DrawBuffersWEBGL(const nsTArray<GLenum>& buffers);
static bool IsSupported(const WebGLContext*);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionVertexArray : public WebGLExtensionBase {
@ -375,8 +298,6 @@ class WebGLExtensionVertexArray : public WebGLExtensionBase {
void DeleteVertexArrayOES(WebGLVertexArray* array);
bool IsVertexArrayOES(const WebGLVertexArray* array);
void BindVertexArrayOES(WebGLVertexArray* array);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionInstancedArrays : public WebGLExtensionBase {
@ -391,8 +312,6 @@ class WebGLExtensionInstancedArrays : public WebGLExtensionBase {
void VertexAttribDivisorANGLE(GLuint index, GLuint divisor);
static bool IsSupported(const WebGLContext* webgl);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionBlendMinMax : public WebGLExtensionBase {
@ -401,8 +320,6 @@ class WebGLExtensionBlendMinMax : public WebGLExtensionBase {
virtual ~WebGLExtensionBlendMinMax();
static bool IsSupported(const WebGLContext*);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionDisjointTimerQuery : public WebGLExtensionBase {
@ -416,14 +333,11 @@ class WebGLExtensionDisjointTimerQuery : public WebGLExtensionBase {
void BeginQueryEXT(GLenum target, WebGLQuery& query) const;
void EndQueryEXT(GLenum target) const;
void QueryCounterEXT(WebGLQuery& query, GLenum target) const;
void GetQueryEXT(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval) const;
void GetQueryObjectEXT(JSContext* cx, const WebGLQuery& query, GLenum pname,
JS::MutableHandleValue retval) const;
MaybeWebGLVariant GetQueryEXT(GLenum target, GLenum pname) const;
MaybeWebGLVariant GetQueryObjectEXT(const WebGLQuery& query,
GLenum pname) const;
static bool IsSupported(const WebGLContext*);
DECL_WEBGL_EXTENSION_GOOP
};
class WebGLExtensionMOZDebug final : public WebGLExtensionBase {
@ -431,12 +345,78 @@ class WebGLExtensionMOZDebug final : public WebGLExtensionBase {
explicit WebGLExtensionMOZDebug(WebGLContext* webgl);
virtual ~WebGLExtensionMOZDebug();
void GetParameter(JSContext* cx, GLenum pname,
JS::MutableHandle<JS::Value> retval, ErrorResult& er) const;
DECL_WEBGL_EXTENSION_GOOP
MaybeWebGLVariant GetParameter(GLenum pname) const;
};
template <WebGLExtensionID ext>
struct WebGLExtensionClassMap;
#define DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(_extensionID, _extensionClass) \
template <> \
struct WebGLExtensionClassMap<WebGLExtensionID::_extensionID> { \
using Type = _extensionClass; \
};
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(ANGLE_instanced_arrays,
WebGLExtensionInstancedArrays)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(EXT_blend_minmax,
WebGLExtensionBlendMinMax)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(EXT_color_buffer_float,
WebGLExtensionColorBufferFloat)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(EXT_color_buffer_half_float,
WebGLExtensionColorBufferHalfFloat)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(EXT_texture_compression_bptc,
WebGLExtensionCompressedTextureBPTC)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(EXT_texture_compression_rgtc,
WebGLExtensionCompressedTextureRGTC)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(EXT_frag_depth, WebGLExtensionFragDepth)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(EXT_sRGB, WebGLExtensionSRGB)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(EXT_shader_texture_lod,
WebGLExtensionShaderTextureLod)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(EXT_texture_filter_anisotropic,
WebGLExtensionTextureFilterAnisotropic)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(EXT_disjoint_timer_query,
WebGLExtensionDisjointTimerQuery)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(MOZ_debug, WebGLExtensionMOZDebug)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(OES_element_index_uint,
WebGLExtensionElementIndexUint)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(OES_standard_derivatives,
WebGLExtensionStandardDerivatives)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(OES_texture_float,
WebGLExtensionTextureFloat)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(OES_texture_float_linear,
WebGLExtensionTextureFloatLinear)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(OES_texture_half_float,
WebGLExtensionTextureHalfFloat)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(OES_texture_half_float_linear,
WebGLExtensionTextureHalfFloatLinear)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(OES_vertex_array_object,
WebGLExtensionVertexArray)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(WEBGL_color_buffer_float,
WebGLExtensionEXTColorBufferFloat)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(WEBGL_compressed_texture_astc,
WebGLExtensionCompressedTextureASTC)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(WEBGL_compressed_texture_etc,
WebGLExtensionCompressedTextureES3)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(WEBGL_compressed_texture_etc1,
WebGLExtensionCompressedTextureETC1)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(WEBGL_compressed_texture_pvrtc,
WebGLExtensionCompressedTexturePVRTC)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(WEBGL_compressed_texture_s3tc,
WebGLExtensionCompressedTextureS3TC)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(WEBGL_compressed_texture_s3tc_srgb,
WebGLExtensionCompressedTextureS3TC_SRGB)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(WEBGL_debug_renderer_info,
WebGLExtensionDebugRendererInfo)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(WEBGL_debug_shaders,
WebGLExtensionDebugShaders)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(WEBGL_depth_texture,
WebGLExtensionDepthTexture)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(WEBGL_draw_buffers,
WebGLExtensionDrawBuffers)
DEFINE_WEBGL_EXTENSION_CLASS_MAP_ENTRY(WEBGL_lose_context,
WebGLExtensionLoseContext)
class WebGLExtensionMultiview : public WebGLExtensionBase {
public:
explicit WebGLExtensionMultiview(WebGLContext*);
@ -447,8 +427,6 @@ class WebGLExtensionMultiview : public WebGLExtensionBase {
WebGLTexture* texture, GLint level,
GLint baseViewIndex,
GLsizei numViews) const;
DECL_WEBGL_EXTENSION_GOOP
};
} // namespace mozilla

Просмотреть файл

@ -18,6 +18,7 @@
#include "WebGLContext.h"
#include "WebGLContextUtils.h"
#include "WebGLExtensions.h"
#include "WebGLFormats.h"
#include "WebGLRenderbuffer.h"
#include "WebGLTexture.h"
@ -255,10 +256,10 @@ void WebGLFBAttachPoint::DoAttachment(gl::GLContext* const gl) const {
}
}
JS::Value WebGLFBAttachPoint::GetParameter(WebGLContext* webgl, JSContext* cx,
GLenum target, GLenum attachment,
GLenum pname,
ErrorResult* const out_error) const {
MaybeWebGLVariant WebGLFBAttachPoint::GetParameter(WebGLContext* webgl,
GLenum target,
GLenum attachment,
GLenum pname) const {
if (!HasAttachment()) {
// Divergent between GLES 3 and 2.
@ -273,10 +274,10 @@ JS::Value WebGLFBAttachPoint::GetParameter(WebGLContext* webgl, JSContext* cx,
// queries will generate an INVALID_OPERATION error."
switch (pname) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
return JS::Int32Value(LOCAL_GL_NONE);
return AsSomeVariant(LOCAL_GL_NONE);
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
if (webgl->IsWebGL2()) return JS::NullValue();
if (webgl->IsWebGL2()) return Nothing();
break;
@ -292,25 +293,25 @@ JS::Value WebGLFBAttachPoint::GetParameter(WebGLContext* webgl, JSContext* cx,
webgl->ErrorInvalidEnum("No attachment at %s.",
attachmentName.BeginReading());
}
return JS::NullValue();
return Nothing();
}
bool isPNameValid = false;
switch (pname) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
return JS::Int32Value(mTexturePtr ? LOCAL_GL_TEXTURE
: LOCAL_GL_RENDERBUFFER);
return AsSomeVariant(mTexturePtr ? LOCAL_GL_TEXTURE
: LOCAL_GL_RENDERBUFFER);
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
return (mTexturePtr ? webgl->WebGLObjectAsJSValue(cx, mTexturePtr.get(),
*out_error)
: webgl->WebGLObjectAsJSValue(
cx, mRenderbufferPtr.get(), *out_error));
if (mTexturePtr) {
return AsSomeVariant(mTexturePtr);
}
return AsSomeVariant(mRenderbufferPtr);
//////
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
if (mTexturePtr) return JS::Int32Value(MipLevel());
if (mTexturePtr) return AsSomeVariant(MipLevel());
break;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
@ -319,7 +320,7 @@ JS::Value WebGLFBAttachPoint::GetParameter(WebGLContext* webgl, JSContext* cx,
if (mTexturePtr->Target() == LOCAL_GL_TEXTURE_CUBE_MAP) {
face = LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + Layer();
}
return JS::Int32Value(face);
return AsSomeVariant(face);
}
break;
@ -363,16 +364,16 @@ JS::Value WebGLFBAttachPoint::GetParameter(WebGLContext* webgl, JSContext* cx,
if (!isPNameValid) {
webgl->ErrorInvalidEnum("Invalid pname: 0x%04x", pname);
return JS::NullValue();
return Nothing();
}
const auto& imageInfo = *GetImageInfo();
const auto& usage = imageInfo.mFormat;
if (!usage) {
if (pname == LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING)
return JS::NumberValue(LOCAL_GL_LINEAR);
return AsSomeVariant(LOCAL_GL_LINEAR);
return JS::NullValue();
return Nothing();
}
auto format = usage->format;
@ -460,7 +461,7 @@ JS::Value WebGLFBAttachPoint::GetParameter(WebGLContext* webgl, JSContext* cx,
break;
}
return JS::Int32Value(ret);
return AsSomeVariant(ret);
}
////////////////////////////////////////////////////////////////////////////////
@ -1069,7 +1070,7 @@ void WebGLFramebuffer::RefreshReadBuffer() const {
////
void WebGLFramebuffer::DrawBuffers(const dom::Sequence<GLenum>& buffers) {
void WebGLFramebuffer::DrawBuffers(const nsTArray<GLenum>& buffers) {
if (buffers.Length() > mContext->mGLMaxDrawBuffers) {
// "An INVALID_VALUE error is generated if `n` is greater than
// MAX_DRAW_BUFFERS."
@ -1166,16 +1167,16 @@ void WebGLFramebuffer::FramebufferAttach(const GLenum attachEnum,
InvalidateCaches();
}
JS::Value WebGLFramebuffer::GetAttachmentParameter(
JSContext* cx, GLenum target, GLenum attachEnum, GLenum pname,
ErrorResult* const out_error) {
MaybeWebGLVariant WebGLFramebuffer::GetAttachmentParameter(GLenum target,
GLenum attachEnum,
GLenum pname) {
const auto maybeAttach = GetAttachPoint(attachEnum);
if (!maybeAttach || attachEnum == LOCAL_GL_NONE) {
mContext->ErrorInvalidEnum(
"Can only query COLOR_ATTACHMENTi,"
" DEPTH_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT, or"
" STENCIL_ATTACHMENT for a framebuffer.");
return JS::NullValue();
return Nothing();
}
auto attach = maybeAttach.value();
@ -1188,7 +1189,7 @@ JS::Value WebGLFramebuffer::GetAttachmentParameter(
" FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE"
" against DEPTH_STENCIL_ATTACHMENT is an"
" error.");
return JS::NullValue();
return Nothing();
}
if (mDepthAttachment.Renderbuffer() != mStencilAttachment.Renderbuffer() ||
@ -1196,14 +1197,13 @@ JS::Value WebGLFramebuffer::GetAttachmentParameter(
mContext->ErrorInvalidOperation(
"DEPTH_ATTACHMENT and STENCIL_ATTACHMENT"
" have different objects bound.");
return JS::NullValue();
return Nothing();
}
attach = &mDepthAttachment;
}
return attach->GetParameter(mContext, cx, target, attachEnum, pname,
out_error);
return attach->GetParameter(mContext, target, attachEnum, pname);
}
////////////////////
@ -1581,48 +1581,4 @@ void WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl, GLint srcX0,
}
}
////////////////////////////////////////////////////////////////////////////////
// Goop.
JSObject* WebGLFramebuffer::WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto) {
return dom::WebGLFramebuffer_Binding::Wrap(cx, this, givenProto);
}
inline void ImplCycleCollectionUnlink(mozilla::WebGLFBAttachPoint& field) {
field.Unlink();
}
inline void ImplCycleCollectionTraverse(
nsCycleCollectionTraversalCallback& callback,
const mozilla::WebGLFBAttachPoint& field, const char* name,
uint32_t flags = 0) {
CycleCollectionNoteChild(callback, field.Texture(), name, flags);
CycleCollectionNoteChild(callback, field.Renderbuffer(), name, flags);
}
template <typename C>
inline void ImplCycleCollectionUnlink(C& field) {
for (auto& cur : field) {
cur.Unlink();
}
}
template <typename C>
inline void ImplCycleCollectionTraverse(
nsCycleCollectionTraversalCallback& callback, const C& field,
const char* name, uint32_t flags = 0) {
for (auto& cur : field) {
ImplCycleCollectionTraverse(callback, cur, name, flags);
}
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLFramebuffer, mDepthAttachment,
mStencilAttachment,
mDepthStencilAttachment,
mColorAttachments)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLFramebuffer, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLFramebuffer, Release)
} // namespace mozilla

Просмотреть файл

@ -97,9 +97,8 @@ class WebGLFBAttachPoint final {
void DoAttachment(gl::GLContext* gl) const;
JS::Value GetParameter(WebGLContext* webgl, JSContext* cx, GLenum target,
GLenum attachment, GLenum pname,
ErrorResult* const out_error) const;
MaybeWebGLVariant GetParameter(WebGLContext* webgl, GLenum target,
GLenum attachment, GLenum pname) const;
bool IsEquivalentForFeedback(const WebGLFBAttachPoint& other) const {
if (!HasAttachment() | !other.HasAttachment()) return false;
@ -135,8 +134,7 @@ class WebGLFBAttachPoint final {
};
};
class WebGLFramebuffer final : public nsWrapperCache,
public WebGLRefCountedObject<WebGLFramebuffer>,
class WebGLFramebuffer final : public WebGLRefCountedObject<WebGLFramebuffer>,
public LinkedListElement<WebGLFramebuffer>,
public SupportsWeakPtr<WebGLFramebuffer>,
public CacheInvalidator {
@ -194,15 +192,10 @@ class WebGLFramebuffer final : public nsWrapperCache,
////
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLFramebuffer)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLFramebuffer)
NS_INLINE_DECL_REFCOUNTING(WebGLFramebuffer)
WebGLFramebuffer(WebGLContext* webgl, GLuint fbo);
WebGLContext* GetParentObject() const { return mContext; }
virtual JSObject* WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto) override;
private:
~WebGLFramebuffer() {
DeleteOnce();
@ -272,12 +265,11 @@ class WebGLFramebuffer final : public nsWrapperCache,
FBStatus CheckFramebufferStatus() const;
void FramebufferAttach(GLenum attachEnum,
const webgl::FbAttachInfo& toAttach);
void DrawBuffers(const dom::Sequence<GLenum>& buffers);
void DrawBuffers(const nsTArray<GLenum>& buffers);
void ReadBuffer(GLenum attachPoint);
JS::Value GetAttachmentParameter(JSContext* cx, GLenum target,
GLenum attachment, GLenum pname,
ErrorResult* const out_error);
MaybeWebGLVariant GetAttachmentParameter(GLenum target, GLenum attachment,
GLenum pname);
static void BlitFramebuffer(WebGLContext* webgl, GLint srcX0, GLint srcY0,
GLint srcX1, GLint srcY1, GLint dstX0,

Просмотреть файл

@ -0,0 +1,236 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 WEBGLMETHODDISPATCHER_H_
#define WEBGLMETHODDISPATCHER_H_
#include "TexUnpackBlob.h"
#include "WebGLCrossProcessCommandQueue.h"
#include "HostWebGLContext.h"
#include "WebGLPcqParamTraits.h"
namespace mozilla {
// The WebGLMethodDispatcher will dispatch commands read from the
// HostWebGLCommandSink and issue them to a given HostWebGLContext.
DECLARE_METHOD_DISPATCHER(WebGLMethodDispatcher, HostWebGLCommandSink,
HostWebGLContext)
// Defines each method the WebGLMethodDispatcher handles. The COUNTER value
// is used as a cross-process ID for each of the methods.
#define DEFINE_METHOD_HELPER(_METHOD, _SYNC) \
DEFINE_METHOD_DISPATCHER(WebGLMethodDispatcher, __COUNTER__, _METHOD, _SYNC)
#define DEFINE_ASYNC(_METHOD) \
DEFINE_METHOD_HELPER(_METHOD, CommandSyncType::ASYNC)
#define DEFINE_SYNC(_METHOD) \
DEFINE_METHOD_HELPER(_METHOD, CommandSyncType::SYNC)
DEFINE_SYNC(HostWebGLContext::IsContextLost)
DEFINE_ASYNC(HostWebGLContext::Disable)
DEFINE_ASYNC(HostWebGLContext::Enable)
DEFINE_SYNC(HostWebGLContext::IsEnabled)
DEFINE_ASYNC(HostWebGLContext::SetContextOptions)
DEFINE_SYNC(HostWebGLContext::InitializeCanvasRenderer)
DEFINE_SYNC(HostWebGLContext::SetDimensions)
DEFINE_SYNC(HostWebGLContext::DrawingBufferSize)
DEFINE_SYNC(HostWebGLContext::OnMemoryPressure)
DEFINE_SYNC(HostWebGLContext::GetSupportedExtensions)
DEFINE_SYNC(HostWebGLContext::Present)
DEFINE_ASYNC(HostWebGLContext::AllowContextRestore)
DEFINE_ASYNC(HostWebGLContext::DidRefresh)
DEFINE_SYNC(HostWebGLContext::GetParameter)
DEFINE_ASYNC(HostWebGLContext::AttachShader)
DEFINE_ASYNC(HostWebGLContext::BindAttribLocation)
DEFINE_ASYNC(HostWebGLContext::BindFramebuffer)
DEFINE_ASYNC(HostWebGLContext::BindRenderbuffer)
DEFINE_ASYNC(HostWebGLContext::BlendColor)
DEFINE_ASYNC(HostWebGLContext::BlendEquation)
DEFINE_ASYNC(HostWebGLContext::BlendEquationSeparate)
DEFINE_ASYNC(HostWebGLContext::BlendFunc)
DEFINE_ASYNC(HostWebGLContext::BlendFuncSeparate)
DEFINE_SYNC(HostWebGLContext::CheckFramebufferStatus)
DEFINE_ASYNC(HostWebGLContext::Clear)
DEFINE_ASYNC(HostWebGLContext::ClearColor)
DEFINE_ASYNC(HostWebGLContext::ClearDepth)
DEFINE_ASYNC(HostWebGLContext::ClearStencil)
DEFINE_ASYNC(HostWebGLContext::ColorMask)
DEFINE_ASYNC(HostWebGLContext::CompileShader)
DEFINE_ASYNC(HostWebGLContext::CreateFramebuffer)
DEFINE_ASYNC(HostWebGLContext::CreateProgram)
DEFINE_ASYNC(HostWebGLContext::CreateRenderbuffer)
DEFINE_ASYNC(HostWebGLContext::CreateShader)
DEFINE_ASYNC(HostWebGLContext::CullFace)
DEFINE_ASYNC(HostWebGLContext::DeleteFramebuffer)
DEFINE_ASYNC(HostWebGLContext::DeleteProgram)
DEFINE_ASYNC(HostWebGLContext::DeleteRenderbuffer)
DEFINE_ASYNC(HostWebGLContext::DeleteShader)
DEFINE_ASYNC(HostWebGLContext::DepthFunc)
DEFINE_ASYNC(HostWebGLContext::DepthMask)
DEFINE_ASYNC(HostWebGLContext::DepthRange)
DEFINE_ASYNC(HostWebGLContext::DetachShader)
DEFINE_ASYNC(HostWebGLContext::Flush)
DEFINE_SYNC(HostWebGLContext::Finish)
DEFINE_ASYNC(HostWebGLContext::FramebufferRenderbuffer)
DEFINE_ASYNC(HostWebGLContext::FramebufferTexture2D)
DEFINE_ASYNC(HostWebGLContext::FrontFace)
DEFINE_SYNC(HostWebGLContext::GetActiveAttrib)
DEFINE_SYNC(HostWebGLContext::GetActiveUniform)
DEFINE_SYNC(HostWebGLContext::GetAttachedShaders)
DEFINE_SYNC(HostWebGLContext::GetAttribLocation)
DEFINE_SYNC(HostWebGLContext::GetBufferParameter)
DEFINE_SYNC(HostWebGLContext::GetError)
DEFINE_SYNC(HostWebGLContext::GetFramebufferAttachmentParameter)
DEFINE_SYNC(HostWebGLContext::GetProgramParameter)
DEFINE_SYNC(HostWebGLContext::GetProgramInfoLog)
DEFINE_SYNC(HostWebGLContext::GetRenderbufferParameter)
DEFINE_SYNC(HostWebGLContext::GetShaderParameter)
DEFINE_SYNC(HostWebGLContext::GetShaderPrecisionFormat)
DEFINE_SYNC(HostWebGLContext::GetShaderInfoLog)
DEFINE_SYNC(HostWebGLContext::GetShaderSource)
DEFINE_SYNC(HostWebGLContext::GetUniform)
DEFINE_SYNC(HostWebGLContext::GetUniformLocation)
DEFINE_ASYNC(HostWebGLContext::Hint)
DEFINE_ASYNC(HostWebGLContext::LineWidth)
DEFINE_ASYNC(HostWebGLContext::LinkProgram)
DEFINE_SYNC(HostWebGLContext::PixelStorei)
DEFINE_ASYNC(HostWebGLContext::PolygonOffset)
DEFINE_ASYNC(HostWebGLContext::SampleCoverage)
DEFINE_ASYNC(HostWebGLContext::Scissor)
DEFINE_ASYNC(HostWebGLContext::ShaderSource)
DEFINE_ASYNC(HostWebGLContext::StencilFunc)
DEFINE_ASYNC(HostWebGLContext::StencilFuncSeparate)
DEFINE_ASYNC(HostWebGLContext::StencilMask)
DEFINE_ASYNC(HostWebGLContext::StencilMaskSeparate)
DEFINE_ASYNC(HostWebGLContext::StencilOp)
DEFINE_ASYNC(HostWebGLContext::StencilOpSeparate)
DEFINE_ASYNC(HostWebGLContext::Viewport)
DEFINE_ASYNC(HostWebGLContext::BindBuffer)
DEFINE_ASYNC(HostWebGLContext::BindBufferBase)
DEFINE_ASYNC(HostWebGLContext::BindBufferRange)
DEFINE_SYNC(HostWebGLContext::CreateBuffer)
DEFINE_ASYNC(HostWebGLContext::DeleteBuffer)
DEFINE_ASYNC(HostWebGLContext::CopyBufferSubData)
DEFINE_ASYNC(HostWebGLContext::GetBufferSubData)
DEFINE_ASYNC(HostWebGLContext::BufferData)
DEFINE_ASYNC(HostWebGLContext::BufferSubData)
DEFINE_ASYNC(HostWebGLContext::BlitFramebuffer)
DEFINE_ASYNC(HostWebGLContext::FramebufferTextureLayer)
DEFINE_ASYNC(HostWebGLContext::InvalidateFramebuffer)
DEFINE_ASYNC(HostWebGLContext::InvalidateSubFramebuffer)
DEFINE_ASYNC(HostWebGLContext::ReadBuffer)
DEFINE_SYNC(HostWebGLContext::GetInternalformatParameter)
DEFINE_ASYNC(HostWebGLContext::RenderbufferStorage_base)
DEFINE_ASYNC(HostWebGLContext::ActiveTexture)
DEFINE_ASYNC(HostWebGLContext::BindTexture)
DEFINE_SYNC(HostWebGLContext::CreateTexture)
DEFINE_ASYNC(HostWebGLContext::DeleteTexture)
DEFINE_ASYNC(HostWebGLContext::GenerateMipmap)
DEFINE_ASYNC(HostWebGLContext::CopyTexImage2D)
DEFINE_ASYNC(HostWebGLContext::TexStorage)
DEFINE_ASYNC(HostWebGLContext::TexImage)
DEFINE_ASYNC(HostWebGLContext::TexSubImage)
DEFINE_ASYNC(HostWebGLContext::CompressedTexImage)
DEFINE_ASYNC(HostWebGLContext::CompressedTexSubImage)
DEFINE_ASYNC(HostWebGLContext::CopyTexSubImage)
DEFINE_SYNC(HostWebGLContext::GetTexParameter)
DEFINE_ASYNC(HostWebGLContext::TexParameter_base)
DEFINE_ASYNC(HostWebGLContext::UseProgram)
DEFINE_ASYNC(HostWebGLContext::ValidateProgram)
DEFINE_SYNC(HostWebGLContext::GetFragDataLocation)
DEFINE_ASYNC(HostWebGLContext::UniformNfv)
DEFINE_ASYNC(HostWebGLContext::UniformNiv)
DEFINE_ASYNC(HostWebGLContext::UniformNuiv)
DEFINE_ASYNC(HostWebGLContext::UniformMatrixAxBfv)
DEFINE_ASYNC(HostWebGLContext::UniformFVec)
DEFINE_ASYNC(HostWebGLContext::UniformIVec)
DEFINE_ASYNC(HostWebGLContext::UniformUIVec)
DEFINE_ASYNC(HostWebGLContext::VertexAttrib4f)
DEFINE_ASYNC(HostWebGLContext::VertexAttribI4i)
DEFINE_ASYNC(HostWebGLContext::VertexAttribI4ui)
DEFINE_ASYNC(HostWebGLContext::VertexAttribDivisor)
DEFINE_SYNC(HostWebGLContext::GetIndexedParameter)
DEFINE_SYNC(HostWebGLContext::GetUniformIndices)
DEFINE_SYNC(HostWebGLContext::GetActiveUniforms)
DEFINE_SYNC(HostWebGLContext::GetUniformBlockIndex)
DEFINE_SYNC(HostWebGLContext::GetActiveUniformBlockParameter)
DEFINE_SYNC(HostWebGLContext::GetActiveUniformBlockName)
DEFINE_ASYNC(HostWebGLContext::UniformBlockBinding)
DEFINE_ASYNC(HostWebGLContext::EnableVertexAttribArray)
DEFINE_ASYNC(HostWebGLContext::DisableVertexAttribArray)
DEFINE_SYNC(HostWebGLContext::GetVertexAttrib)
DEFINE_SYNC(HostWebGLContext::GetVertexAttribOffset)
DEFINE_ASYNC(HostWebGLContext::VertexAttribAnyPointer)
DEFINE_ASYNC(HostWebGLContext::ClearBufferfv)
DEFINE_ASYNC(HostWebGLContext::ClearBufferiv)
DEFINE_ASYNC(HostWebGLContext::ClearBufferuiv)
DEFINE_ASYNC(HostWebGLContext::ClearBufferfi)
DEFINE_ASYNC(HostWebGLContext::ReadPixels1)
DEFINE_ASYNC(HostWebGLContext::ReadPixels2)
DEFINE_ASYNC(HostWebGLContext::CreateSampler)
DEFINE_ASYNC(HostWebGLContext::DeleteSampler)
DEFINE_ASYNC(HostWebGLContext::BindSampler)
DEFINE_ASYNC(HostWebGLContext::SamplerParameteri)
DEFINE_ASYNC(HostWebGLContext::SamplerParameterf)
DEFINE_SYNC(HostWebGLContext::GetSamplerParameter)
DEFINE_SYNC(HostWebGLContext::FenceSync)
DEFINE_ASYNC(HostWebGLContext::DeleteSync)
DEFINE_SYNC(HostWebGLContext::ClientWaitSync)
DEFINE_ASYNC(HostWebGLContext::WaitSync)
DEFINE_SYNC(HostWebGLContext::GetSyncParameter)
DEFINE_ASYNC(HostWebGLContext::CreateTransformFeedback)
DEFINE_ASYNC(HostWebGLContext::DeleteTransformFeedback)
DEFINE_ASYNC(HostWebGLContext::BindTransformFeedback)
DEFINE_ASYNC(HostWebGLContext::BeginTransformFeedback)
DEFINE_ASYNC(HostWebGLContext::EndTransformFeedback)
DEFINE_ASYNC(HostWebGLContext::PauseTransformFeedback)
DEFINE_ASYNC(HostWebGLContext::ResumeTransformFeedback)
DEFINE_ASYNC(HostWebGLContext::TransformFeedbackVaryings)
DEFINE_SYNC(HostWebGLContext::GetTransformFeedbackVarying)
DEFINE_ASYNC(HostWebGLContext::EnableExtension)
DEFINE_ASYNC(HostWebGLContext::EnqueueError)
DEFINE_ASYNC(HostWebGLContext::EnqueueWarning)
DEFINE_ASYNC(HostWebGLContext::DrawBuffers)
DEFINE_SYNC(HostWebGLContext::GetASTCExtensionSupportedProfiles)
DEFINE_SYNC(HostWebGLContext::GetTranslatedShaderSource)
DEFINE_ASYNC(HostWebGLContext::LoseContext)
DEFINE_SYNC(HostWebGLContext::MOZDebugGetParameter)
DEFINE_ASYNC(HostWebGLContext::RestoreContext)
DEFINE_ASYNC(HostWebGLContext::BindVertexArray)
DEFINE_ASYNC(HostWebGLContext::CreateVertexArray)
DEFINE_ASYNC(HostWebGLContext::DeleteVertexArray)
DEFINE_ASYNC(HostWebGLContext::DrawArraysInstanced)
DEFINE_ASYNC(HostWebGLContext::DrawElementsInstanced)
DEFINE_ASYNC(HostWebGLContext::DrawRangeElements)
DEFINE_ASYNC(HostWebGLContext::CreateQuery)
DEFINE_ASYNC(HostWebGLContext::DeleteQuery)
DEFINE_ASYNC(HostWebGLContext::BeginQuery)
DEFINE_ASYNC(HostWebGLContext::EndQuery)
DEFINE_ASYNC(HostWebGLContext::QueryCounter)
DEFINE_SYNC(HostWebGLContext::GetQuery)
DEFINE_SYNC(HostWebGLContext::GetQueryParameter)
#define DEFINE_RELEASE_ASYNC(_TYPE) \
DEFINE_ASYNC(HostWebGLContext::ReleaseWebGLObject<WebGL##_TYPE>)
DEFINE_RELEASE_ASYNC(Buffer)
DEFINE_RELEASE_ASYNC(Framebuffer)
DEFINE_RELEASE_ASYNC(Program)
DEFINE_RELEASE_ASYNC(Query)
DEFINE_RELEASE_ASYNC(Renderbuffer)
DEFINE_RELEASE_ASYNC(Sampler)
DEFINE_RELEASE_ASYNC(Shader)
DEFINE_RELEASE_ASYNC(Sync)
DEFINE_RELEASE_ASYNC(Texture)
DEFINE_RELEASE_ASYNC(TransformFeedback)
DEFINE_RELEASE_ASYNC(UniformLocation)
DEFINE_RELEASE_ASYNC(VertexArray)
#undef DEFINE_METHOD_HELPER
#undef DEFINE_ASYNC
#undef DEFINE_SYNC
} // namespace mozilla
#endif // WEBGLMETHODDISPATCHER_H_

Просмотреть файл

@ -1,20 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "WebGLObjectModel.h"
#include "WebGLContext.h"
namespace mozilla {
WebGLContextBoundObject::WebGLContextBoundObject(WebGLContext* webgl)
: mContext(webgl), mContextGeneration(webgl->Generation()) {}
bool WebGLContextBoundObject::IsCompatibleWithContext(
const WebGLContext* other) const {
return (mContext == other && mContextGeneration == other->Generation());
}
} // namespace mozilla

Просмотреть файл

@ -21,22 +21,27 @@ class WebGLContext;
// This class is a mixin for objects that are tied to a specific
// context (which is to say, all of them). They provide initialization
// as well as comparison with the current context.
class WebGLContextBoundObject {
template <typename Derived>
class WebGLContextBoundObject : public WebGLId<Derived> {
public:
const WeakPtr<WebGLContext> mContext;
explicit WebGLContextBoundObject(WebGLContext* webgl)
: mContext(webgl), mContextGeneration(webgl->Generation()) {}
bool IsCompatibleWithContext(const WebGLContext* other) const {
return (mContext == other && mContextGeneration == other->Generation());
}
private:
friend class HostWebGLContext;
const uint32_t mContextGeneration;
public:
explicit WebGLContextBoundObject(WebGLContext* webgl);
bool IsCompatibleWithContext(const WebGLContext* other) const;
};
////
class WebGLDeletableObject : public WebGLContextBoundObject {
class WebGLDeletableObject {
template <typename>
friend class WebGLRefCountedObject;
@ -47,8 +52,7 @@ class WebGLDeletableObject : public WebGLContextBoundObject {
////
explicit WebGLDeletableObject(WebGLContext* webgl)
: WebGLContextBoundObject(webgl), mDeletionStatus(Default) {}
explicit WebGLDeletableObject() : mDeletionStatus(Default) {}
~WebGLDeletableObject() {
MOZ_ASSERT(mDeletionStatus == Deleted,
@ -139,7 +143,8 @@ class WebGLDeletableObject : public WebGLContextBoundObject {
*/
template <typename Derived>
class WebGLRefCountedObject : public WebGLDeletableObject {
class WebGLRefCountedObject : public WebGLContextBoundObject<Derived>,
public WebGLDeletableObject {
friend class WebGLContext;
template <typename T>
friend void ClearLinkedList(LinkedList<T>& list);
@ -149,7 +154,7 @@ class WebGLRefCountedObject : public WebGLDeletableObject {
public:
explicit WebGLRefCountedObject(WebGLContext* webgl)
: WebGLDeletableObject(webgl) {}
: WebGLContextBoundObject<Derived>(webgl), WebGLDeletableObject() {}
~WebGLRefCountedObject() {
MOZ_ASSERT(mWebGLRefCnt == 0,

138
dom/canvas/WebGLParent.cpp Normal file
Просмотреть файл

@ -0,0 +1,138 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "WebGLParent.h"
#include "mozilla/layers/LayerTransactionParent.h"
#include "mozilla/layers/TextureClientSharedSurface.h"
#include "HostWebGLContext.h"
namespace mozilla {
namespace dom {
/* static */ WebGLParent* WebGLParent::Create(
WebGLVersion aVersion,
UniquePtr<mozilla::HostWebGLCommandSink>&& aCommandSink,
UniquePtr<mozilla::HostWebGLErrorSource>&& aErrorSource) {
UniquePtr<HostWebGLContext> host = HostWebGLContext::Create(
aVersion, std::move(aCommandSink), std::move(aErrorSource));
if (!host) {
WEBGL_BRIDGE_LOGE("Failed to create HostWebGLContext");
return nullptr;
}
WebGLParent* parent(new WebGLParent(std::move(host)));
if (!parent->BeginCommandQueueDrain()) {
WEBGL_BRIDGE_LOGE("Failed to start WebGL command queue drain");
return nullptr;
}
return parent;
}
WebGLParent::WebGLParent(UniquePtr<HostWebGLContext>&& aHost)
: mHost(std::move(aHost)) {}
bool WebGLParent::BeginCommandQueueDrain() {
if (mRunCommandsRunnable) {
// already running
return true;
}
WeakPtr<WebGLParent> weakThis = this;
mRunCommandsRunnable = NS_NewRunnableFunction(
"RunWebGLCommands", [weakThis]() { MaybeRunCommandQueue(weakThis); });
if (!mRunCommandsRunnable) {
MOZ_ASSERT_UNREACHABLE("Failed to create RunWebGLCommands Runnable");
return false;
}
// Start the recurring runnable.
return RunCommandQueue();
}
/* static */ bool WebGLParent::MaybeRunCommandQueue(
const WeakPtr<WebGLParent>& weakWebGLParent) {
// We don't have to worry about WebGLParent being deleted from under us
// as its not thread-safe so we must be the only thread using it. In fact,
// WeakRef cannot atomically promote to a RefPtr so it is not thread safe
// either.
if (weakWebGLParent) {
// This will re-issue the task if the queue is still running.
return weakWebGLParent->RunCommandQueue();
}
// Context was deleted. Do not re-issue the task.
return true;
}
bool WebGLParent::RunCommandQueue() {
if (!mRunCommandsRunnable) {
// The actor finished. Do not re-issue the task.
return true;
}
// Drain the queue for up to kMaxWebGLCommandTimeSliceMs, then
// repeat no sooner than kDrainDelayMs later.
// TODO: Tune these.
static const uint32_t kMaxWebGLCommandTimeSliceMs = 1;
static const uint32_t kDrainDelayMs = 0;
TimeDuration timeSlice =
TimeDuration::FromMilliseconds(kMaxWebGLCommandTimeSliceMs);
CommandResult result = mHost->RunCommandsForDuration(timeSlice);
bool success = (result == CommandResult::Success) ||
(result == CommandResult::QueueEmpty);
if (!success) {
// Tell client that this WebGLParent needs to be shut down
WEBGL_BRIDGE_LOGE("WebGLParent failed while running commands");
Unused << SendQueueFailed();
mRunCommandsRunnable = nullptr;
return false;
}
// Re-issue the task
MOZ_ASSERT(mRunCommandsRunnable);
MOZ_ASSERT(MessageLoop::current());
MessageLoop::current()->PostDelayedTask(do_AddRef(mRunCommandsRunnable),
kDrainDelayMs);
return true;
}
mozilla::ipc::IPCResult WebGLParent::Recv__delete__() {
mHost = nullptr;
return IPC_OK();
}
void WebGLParent::ActorDestroy(ActorDestroyReason aWhy) { mHost = nullptr; }
mozilla::ipc::IPCResult WebGLParent::RecvUpdateCompositableHandle(
layers::PLayerTransactionParent* aLayerTransaction,
const CompositableHandle& aHandle) {
auto layerTrans =
static_cast<layers::LayerTransactionParent*>(aLayerTransaction);
RefPtr<layers::CompositableHost> compositableHost(
layerTrans->FindCompositable(aHandle));
if (!compositableHost) {
return IPC_FAIL(this, "Failed to find CompositableHost for WebGL instance");
}
mHost->SetCompositableHost(compositableHost);
return IPC_OK();
}
already_AddRefed<layers::SharedSurfaceTextureClient> WebGLParent::GetVRFrame() {
if (!mHost) {
return nullptr;
}
return mHost->GetVRFrame();
}
} // namespace dom
} // namespace mozilla

62
dom/canvas/WebGLParent.h Normal file
Просмотреть файл

@ -0,0 +1,62 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 WEBGLPARENT_H_
#define WEBGLPARENT_H_
#include "mozilla/GfxMessageUtils.h"
#include "mozilla/dom/PWebGLParent.h"
#include "mozilla/dom/WebGLCrossProcessCommandQueue.h"
#include "mozilla/dom/WebGLErrorQueue.h"
#include "mozilla/WeakPtr.h"
namespace mozilla {
class HostWebGLContext;
namespace layers {
class SharedSurfaceTextureClient;
}
namespace dom {
class WebGLParent : public PWebGLParent, public SupportsWeakPtr<WebGLParent> {
public:
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebGLParent)
static WebGLParent* Create(
WebGLVersion aVersion,
UniquePtr<mozilla::HostWebGLCommandSink>&& aCommandSink,
UniquePtr<mozilla::HostWebGLErrorSource>&& aErrorSource);
already_AddRefed<layers::SharedSurfaceTextureClient> GetVRFrame();
protected:
friend PWebGLParent;
WebGLParent(UniquePtr<HostWebGLContext>&& aHost);
bool BeginCommandQueueDrain();
static bool MaybeRunCommandQueue(const WeakPtr<WebGLParent>& weakWebGLParent);
bool RunCommandQueue();
mozilla::ipc::IPCResult RecvUpdateCompositableHandle(
layers::PLayerTransactionParent* aLayerTransaction,
const CompositableHandle& aHandle);
mozilla::ipc::IPCResult Recv__delete__() override;
void ActorDestroy(ActorDestroyReason aWhy) override;
UniquePtr<HostWebGLContext> mHost;
// Runnable that repeatedly processes our WebGL command queue
RefPtr<Runnable> mRunCommandsRunnable;
};
} // namespace dom
} // namespace mozilla
#endif // WEBGLPARENT_H_

Просмотреть файл

@ -0,0 +1,323 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 WEBGLPCQPARAMTRAITS_H_
#define WEBGLPCQPARAMTRAITS_H_
#include "mozilla/dom/ProducerConsumerQueue.h"
#include "TexUnpackBlob.h"
#include "WebGLActiveInfo.h"
#include "WebGLContext.h"
#include "WebGLTypes.h"
namespace mozilla {
namespace webgl {
template <typename T>
struct PcqParamTraits;
template <typename WebGLType>
struct IsTriviallySerializable<WebGLId<WebGLType>> : TrueType {};
template <>
struct IsTriviallySerializable<FloatOrInt> : TrueType {};
template <>
struct IsTriviallySerializable<WebGLShaderPrecisionFormat> : TrueType {};
template <>
struct IsTriviallySerializable<WebGLContextOptions> : TrueType {};
template <>
struct IsTriviallySerializable<WebGLPixelStore> : TrueType {};
template <>
struct IsTriviallySerializable<WebGLTexImageData> : TrueType {};
template <>
struct IsTriviallySerializable<WebGLTexPboOffset> : TrueType {};
template <>
struct IsTriviallySerializable<SetDimensionsData> : TrueType {};
template <>
struct IsTriviallySerializable<ICRData> : TrueType {};
template <>
struct IsTriviallySerializable<gfx::IntSize> : TrueType {};
template <>
struct IsTriviallySerializable<webgl::TexUnpackBlob> : TrueType {};
template <>
struct PcqParamTraits<ExtensionSets> {
using ParamType = ExtensionSets;
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
aProducerView.WriteParam(aArg.mNonSystem);
return aProducerView.WriteParam(aArg.mSystem);
}
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
aConsumerView.ReadParam(aArg ? &aArg->mNonSystem : nullptr);
return aConsumerView.ReadParam(aArg ? &aArg->mSystem : nullptr);
}
template <typename View>
static size_t MinSize(View& aView, const ParamType* aArg) {
return aView.MinSizeParam(aArg ? (&aArg->mNonSystem) : nullptr) +
aView.MinSizeParam(aArg ? (&aArg->mSystem) : nullptr);
}
};
template <>
struct PcqParamTraits<WebGLActiveInfo> {
using ParamType = WebGLActiveInfo;
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
aProducerView.WriteParam(aArg.mElemCount);
aProducerView.WriteParam(aArg.mElemType);
aProducerView.WriteParam(aArg.mBaseUserName);
aProducerView.WriteParam(aArg.mIsArray);
aProducerView.WriteParam(aArg.mElemSize);
aProducerView.WriteParam(aArg.mBaseMappedName);
return aProducerView.WriteParam(aArg.mBaseType);
}
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
aConsumerView.ReadParam(aArg ? &aArg->mElemCount : nullptr);
aConsumerView.ReadParam(aArg ? &aArg->mElemType : nullptr);
aConsumerView.ReadParam(aArg ? &aArg->mBaseUserName : nullptr);
aConsumerView.ReadParam(aArg ? &aArg->mIsArray : nullptr);
aConsumerView.ReadParam(aArg ? &aArg->mElemSize : nullptr);
aConsumerView.ReadParam(aArg ? &aArg->mBaseMappedName : nullptr);
return aConsumerView.ReadParam(aArg ? &aArg->mBaseType : nullptr);
}
template <typename View>
static size_t MinSize(View& aView, const ParamType* aArg) {
return aView.MinSizeParam(aArg ? &aArg->mElemCount : nullptr) +
aView.MinSizeParam(aArg ? &aArg->mElemType : nullptr) +
aView.MinSizeParam(aArg ? &aArg->mBaseUserName : nullptr) +
aView.MinSizeParam(aArg ? &aArg->mIsArray : nullptr) +
aView.MinSizeParam(aArg ? &aArg->mElemSize : nullptr) +
aView.MinSizeParam(aArg ? &aArg->mBaseMappedName : nullptr) +
aView.MinSizeParam(aArg ? &aArg->mBaseType : nullptr);
}
};
template <typename T>
struct PcqParamTraits<RawBuffer<T>> {
using ParamType = RawBuffer<T>;
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
aProducerView.WriteParam(aArg.mLength);
return (aArg.mLength > 0)
? aProducerView.Write(aArg.mData, aArg.mLength * sizeof(T))
: aProducerView.Status();
}
template <typename ElementType =
typename RemoveCV<typename ParamType::ElementType>::Type>
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
size_t len;
PcqStatus status = aConsumerView.ReadParam(&len);
if (!status) {
return status;
}
if (len == 0) {
if (aArg) {
aArg->mLength = 0;
aArg->mData = nullptr;
}
return PcqStatus::Success;
}
if (!aArg) {
return aConsumerView.Read(nullptr, len * sizeof(T));
}
struct RawBufferReadMatcher {
PcqStatus operator()(RefPtr<mozilla::ipc::SharedMemoryBasic>& smem) {
if (!smem) {
return PcqStatus::PcqFatalError;
}
mArg->mSmem = smem;
mArg->mData = static_cast<ElementType*>(smem->memory());
mArg->mLength = mLength;
mArg->mOwnsData = false;
return PcqStatus::Success;
}
PcqStatus operator()() {
mArg->mSmem = nullptr;
ElementType* buf = new ElementType[mLength];
mArg->mData = buf;
mArg->mLength = mLength;
mArg->mOwnsData = true;
return mConsumerView.Read(buf, mLength * sizeof(T));
}
ConsumerView& mConsumerView;
ParamType* mArg;
size_t mLength;
};
return aConsumerView.ReadVariant(
len * sizeof(T), RawBufferReadMatcher{aConsumerView, aArg, len});
}
template <typename View>
static size_t MinSize(View& aView, const ParamType* aArg) {
return aView.template MinSizeParam<size_t>() +
aView.MinSizeBytes(aArg ? aArg->mLength * sizeof(T) : 0);
}
};
enum TexUnpackTypes : uint8_t { Bytes, Surface, Image, Pbo };
template <>
struct PcqParamTraits<webgl::TexUnpackBytes> {
using ParamType = webgl::TexUnpackBytes;
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
// Write TexUnpackBlob base class, then the RawBuffer.
aProducerView.WriteParam(static_cast<const webgl::TexUnpackBlob&>(aArg));
return aProducerView.WriteParam(aArg.mPtr);
}
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
// Read TexUnpackBlob base class, then the RawBuffer.
aConsumerView.ReadParam(static_cast<webgl::TexUnpackBlob*>(aArg));
return aConsumerView.ReadParam(aArg ? &aArg->mPtr : nullptr);
}
template <typename View>
static size_t MinSize(View& aView, const ParamType* aArg) {
return aView.MinSizeParam(static_cast<const webgl::TexUnpackBlob*>(aArg)) +
aView.MinSizeParam(aArg ? &aArg->mPtr : nullptr);
}
};
template <>
struct PcqParamTraits<webgl::TexUnpackSurface> {
using ParamType = webgl::TexUnpackSurface;
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
aProducerView.WriteParam(static_cast<const webgl::TexUnpackBlob&>(aArg));
aProducerView.WriteParam(aArg.mSize);
aProducerView.WriteParam(aArg.mFormat);
aProducerView.WriteParam(aArg.mData);
return aProducerView.WriteParam(aArg.mStride);
}
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
aConsumerView.ReadParam(static_cast<webgl::TexUnpackBlob*>(aArg));
aConsumerView.ReadParam(aArg ? &aArg->mSize : nullptr);
aConsumerView.ReadParam(aArg ? &aArg->mFormat : nullptr);
aConsumerView.ReadParam(aArg ? &aArg->mData : nullptr);
return aConsumerView.ReadParam(aArg ? &aArg->mStride : nullptr);
}
template <typename View>
static size_t MinSize(View& aView, const ParamType* aArg) {
return aView.MinSizeParam(static_cast<const webgl::TexUnpackBlob*>(aArg)) +
aView.MinSizeParam(aArg ? &aArg->mSize : nullptr) +
aView.MinSizeParam(aArg ? &aArg->mFormat : nullptr) +
aView.MinSizeParam(aArg ? &aArg->mData : nullptr) +
aView.MinSizeParam(aArg ? &aArg->mStride : nullptr);
}
};
// Specialization of PcqParamTraits that adapts the TexUnpack type in order to
// efficiently convert types. For example, a TexUnpackSurface may deserialize
// as a TexUnpackBytes.
template <>
struct PcqParamTraits<WebGLTexUnpackVariant> {
using ParamType = WebGLTexUnpackVariant;
static PcqStatus Write(ProducerView& aProducerView, const ParamType& aArg) {
struct TexUnpackWriteMatcher {
PcqStatus operator()(const UniquePtr<webgl::TexUnpackBytes>& x) {
mProducerView.WriteParam(TexUnpackTypes::Bytes);
return mProducerView.WriteParam(x);
}
PcqStatus operator()(const UniquePtr<webgl::TexUnpackSurface>& x) {
mProducerView.WriteParam(TexUnpackTypes::Surface);
return mProducerView.WriteParam(x);
}
PcqStatus operator()(const UniquePtr<webgl::TexUnpackImage>& x) {
MOZ_ASSERT_UNREACHABLE("TODO:");
return PcqStatus::PcqFatalError;
}
PcqStatus operator()(const WebGLTexPboOffset& x) {
mProducerView.WriteParam(TexUnpackTypes::Pbo);
return mProducerView.WriteParam(x);
}
ProducerView& mProducerView;
};
return aArg.match(TexUnpackWriteMatcher{aProducerView});
}
static PcqStatus Read(ConsumerView& aConsumerView, ParamType* aArg) {
if (!aArg) {
// Not a great estimate but we can't do much better.
return aConsumerView.template ReadParam<TexUnpackTypes>();
}
TexUnpackTypes unpackType;
if (!aConsumerView.ReadParam(&unpackType)) {
return aConsumerView.Status();
}
switch (unpackType) {
case TexUnpackTypes::Bytes:
*aArg = AsVariant(UniquePtr<webgl::TexUnpackBytes>());
return aConsumerView.ReadParam(
&aArg->as<UniquePtr<webgl::TexUnpackBytes>>());
case TexUnpackTypes::Surface:
*aArg = AsVariant(UniquePtr<webgl::TexUnpackSurface>());
return aConsumerView.ReadParam(
&aArg->as<UniquePtr<webgl::TexUnpackSurface>>());
case TexUnpackTypes::Image:
MOZ_ASSERT_UNREACHABLE("TODO:");
return PcqStatus::PcqFatalError;
case TexUnpackTypes::Pbo:
*aArg = AsVariant(WebGLTexPboOffset());
return aConsumerView.ReadParam(&aArg->as<WebGLTexPboOffset>());
}
MOZ_ASSERT_UNREACHABLE("Illegal texture unpack type");
return PcqStatus::PcqFatalError;
}
template <typename View>
static size_t MinSize(View& aView, const ParamType* aArg) {
size_t ret = aView.template MinSizeParam<TexUnpackTypes>();
if (!aArg) {
return ret;
}
struct TexUnpackMinSizeMatcher {
size_t operator()(const UniquePtr<webgl::TexUnpackBytes>& x) {
return mView.MinSizeParam(&x);
}
size_t operator()(const UniquePtr<webgl::TexUnpackSurface>& x) {
return mView.MinSizeParam(&x);
}
size_t operator()(const UniquePtr<webgl::TexUnpackImage>& x) {
MOZ_ASSERT_UNREACHABLE("TODO:");
return 0;
}
size_t operator()(const WebGLTexPboOffset& x) {
return mView.MinSizeParam(&x);
}
View& mView;
};
return ret + aArg->match(TexUnpackMinSizeMatcher{aView});
}
};
} // namespace webgl
} // namespace mozilla
#endif // WEBGLPCQPARAMTRAITS_H_

Просмотреть файл

@ -78,34 +78,31 @@ static void AssembleName(const nsCString& baseName, bool isArray,
////
/*static*/
const webgl::UniformInfo::TexListT* webgl::UniformInfo::GetTexList(
WebGLActiveInfo* activeInfo) {
const auto& webgl = activeInfo->mWebGL;
/*static*/ const webgl::UniformInfo::TexListT* webgl::UniformInfo::GetTexList(
const WebGLContext* aWebGL, WebGLActiveInfo* activeInfo) {
switch (activeInfo->mElemType) {
case LOCAL_GL_SAMPLER_2D:
case LOCAL_GL_SAMPLER_2D_SHADOW:
case LOCAL_GL_INT_SAMPLER_2D:
case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D:
return &webgl->mBound2DTextures;
return &aWebGL->mBound2DTextures;
case LOCAL_GL_SAMPLER_CUBE:
case LOCAL_GL_SAMPLER_CUBE_SHADOW:
case LOCAL_GL_INT_SAMPLER_CUBE:
case LOCAL_GL_UNSIGNED_INT_SAMPLER_CUBE:
return &webgl->mBoundCubeMapTextures;
return &aWebGL->mBoundCubeMapTextures;
case LOCAL_GL_SAMPLER_3D:
case LOCAL_GL_INT_SAMPLER_3D:
case LOCAL_GL_UNSIGNED_INT_SAMPLER_3D:
return &webgl->mBound3DTextures;
return &aWebGL->mBound3DTextures;
case LOCAL_GL_SAMPLER_2D_ARRAY:
case LOCAL_GL_SAMPLER_2D_ARRAY_SHADOW:
case LOCAL_GL_INT_SAMPLER_2D_ARRAY:
case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
return &webgl->mBound2DArrayTextures;
return &aWebGL->mBound2DArrayTextures;
default:
return nullptr;
@ -151,13 +148,14 @@ static webgl::TextureBaseType SamplerBaseType(const GLenum elemType) {
}
}
webgl::UniformInfo::UniformInfo(WebGLActiveInfo* activeInfo)
webgl::UniformInfo::UniformInfo(const WebGLContext* webgl,
WebGLActiveInfo& activeInfo)
: mActiveInfo(activeInfo),
mSamplerTexList(GetTexList(activeInfo)),
mTexBaseType(SamplerBaseType(mActiveInfo->mElemType)),
mIsShadowSampler(IsShadowSampler(mActiveInfo->mElemType)) {
mSamplerTexList(GetTexList(webgl, &activeInfo)),
mTexBaseType(SamplerBaseType(mActiveInfo.mElemType)),
mIsShadowSampler(IsShadowSampler(mActiveInfo.mElemType)) {
if (mSamplerTexList) {
mSamplerValues.assign(mActiveInfo->mElemCount, 0);
mSamplerValues.assign(mActiveInfo.mElemCount, 0);
}
}
@ -281,8 +279,8 @@ static RefPtr<const webgl::LinkedProgramInfo> QueryProgramInfo(
///////
const bool isArray = false;
const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(
webgl, elemCount, elemType, isArray, userName, mappedName);
const WebGLActiveInfo activeInfo(elemCount, elemType, isArray, userName,
mappedName);
const webgl::AttribInfo attrib = {activeInfo, loc};
info->attribs.push_back(attrib);
@ -361,10 +359,10 @@ static RefPtr<const webgl::LinkedProgramInfo> QueryProgramInfo(
///////
const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(
webgl, elemCount, elemType, isArray, baseUserName, baseMappedName);
WebGLActiveInfo activeInfo(elemCount, elemType, isArray, baseUserName,
baseMappedName);
auto* uniform = new webgl::UniformInfo(activeInfo);
auto* uniform = new webgl::UniformInfo(webgl, activeInfo);
info->uniforms.push_back(uniform);
if (uniform->mSamplerTexList) {
@ -464,8 +462,8 @@ static RefPtr<const webgl::LinkedProgramInfo> QueryProgramInfo(
mappedName.BeginReading());
#endif
const RefPtr<WebGLActiveInfo> activeInfo = new WebGLActiveInfo(
webgl, elemCount, elemType, isArray, baseUserName, mappedName);
WebGLActiveInfo activeInfo(elemCount, elemType, isArray, baseUserName,
mappedName);
info->transformFeedbackVaryings.push_back(activeInfo);
}
}
@ -646,7 +644,7 @@ webgl::LinkedProgramInfo::GetDrawFetchLimits() const {
attribDataBaseType = webgl->mGenericVertexAttribTypes[loc];
}
const auto& progBaseType = progAttrib.mActiveInfo->mBaseType;
const auto& progBaseType = progAttrib.mActiveInfo.mBaseType;
if ((attribDataBaseType != progBaseType) &
(progBaseType != webgl::AttribBaseType::Boolean)) {
const auto& dataType = ToString(attribDataBaseType);
@ -787,11 +785,9 @@ void WebGLProgram::DetachShader(const WebGLShader* shader) {
mContext->gl->fDetachShader(mGLName, shader->mGLName);
}
already_AddRefed<WebGLActiveInfo> WebGLProgram::GetActiveAttrib(
GLuint index) const {
Maybe<WebGLActiveInfo> WebGLProgram::GetActiveAttrib(GLuint index) const {
if (!mMostRecentLinkInfo) {
RefPtr<WebGLActiveInfo> ret = WebGLActiveInfo::CreateInvalid(mContext);
return ret.forget();
return Some(WebGLActiveInfo::CreateInvalid());
}
const auto& attribs = mMostRecentLinkInfo->attribs;
@ -799,19 +795,16 @@ already_AddRefed<WebGLActiveInfo> WebGLProgram::GetActiveAttrib(
if (index >= attribs.size()) {
mContext->ErrorInvalidValue("`index` (%i) must be less than %s (%zu).",
index, "ACTIVE_ATTRIBS", attribs.size());
return nullptr;
return Nothing();
}
RefPtr<WebGLActiveInfo> ret = attribs[index].mActiveInfo;
return ret.forget();
return Some(attribs[index].mActiveInfo);
}
already_AddRefed<WebGLActiveInfo> WebGLProgram::GetActiveUniform(
GLuint index) const {
Maybe<WebGLActiveInfo> WebGLProgram::GetActiveUniform(GLuint index) const {
if (!mMostRecentLinkInfo) {
// According to the spec, this can return null.
RefPtr<WebGLActiveInfo> ret = WebGLActiveInfo::CreateInvalid(mContext);
return ret.forget();
return Some(WebGLActiveInfo::CreateInvalid());
}
const auto& uniforms = mMostRecentLinkInfo->uniforms;
@ -819,20 +812,24 @@ already_AddRefed<WebGLActiveInfo> WebGLProgram::GetActiveUniform(
if (index >= uniforms.size()) {
mContext->ErrorInvalidValue("`index` (%i) must be less than %s (%zu).",
index, "ACTIVE_UNIFORMS", uniforms.size());
return nullptr;
return Nothing();
}
RefPtr<WebGLActiveInfo> ret = uniforms[index]->mActiveInfo;
return ret.forget();
return Some(uniforms[index]->mActiveInfo);
}
void WebGLProgram::GetAttachedShaders(
nsTArray<RefPtr<WebGLShader>>* const out) const {
out->TruncateLength(0);
MaybeAttachedShaders WebGLProgram::GetAttachedShaders() const {
MaybeAttachedShaders ret;
ret.emplace();
Array<WebGLId<WebGLShader>, 2>& out = ret.ref();
if (mVertShader) out->AppendElement(mVertShader);
if (mFragShader) out->AppendElement(mFragShader);
if (mVertShader) {
out[0] = mVertShader.get();
}
if (mFragShader) {
out[1] = mFragShader.get();
}
return ret;
}
GLint WebGLProgram::GetAttribLocation(const nsAString& userName_wide) const {
@ -872,8 +869,10 @@ GLint WebGLProgram::GetFragDataLocation(const nsAString& userName_wide) const {
return -1;
}
void WebGLProgram::GetProgramInfoLog(nsAString* const out) const {
CopyASCIItoUTF16(mLinkLog, *out);
nsString WebGLProgram::GetProgramInfoLog() const {
nsString out;
CopyASCIItoUTF16(mLinkLog, out);
return out;
}
static GLint GetProgramiv(gl::GLContext* gl, GLuint program, GLenum pname) {
@ -882,55 +881,55 @@ static GLint GetProgramiv(gl::GLContext* gl, GLuint program, GLenum pname) {
return ret;
}
JS::Value WebGLProgram::GetProgramParameter(GLenum pname) const {
MaybeWebGLVariant WebGLProgram::GetProgramParameter(GLenum pname) const {
gl::GLContext* gl = mContext->gl;
if (mContext->IsWebGL2()) {
switch (pname) {
case LOCAL_GL_ACTIVE_UNIFORM_BLOCKS:
if (!IsLinked()) return JS::NumberValue(0);
return JS::NumberValue(LinkInfo()->uniformBlocks.size());
if (!IsLinked()) return AsSomeVariant(0);
return AsSomeVariant(LinkInfo()->uniformBlocks.size());
case LOCAL_GL_TRANSFORM_FEEDBACK_VARYINGS:
if (!IsLinked()) return JS::NumberValue(0);
return JS::NumberValue(LinkInfo()->transformFeedbackVaryings.size());
if (!IsLinked()) return AsSomeVariant(0);
return AsSomeVariant(LinkInfo()->transformFeedbackVaryings.size());
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
if (!IsLinked()) return JS::NumberValue(LOCAL_GL_INTERLEAVED_ATTRIBS);
return JS::NumberValue(LinkInfo()->transformFeedbackBufferMode);
if (!IsLinked()) return AsSomeVariant(LOCAL_GL_INTERLEAVED_ATTRIBS);
return AsSomeVariant(LinkInfo()->transformFeedbackBufferMode);
}
}
switch (pname) {
case LOCAL_GL_ATTACHED_SHADERS:
return JS::NumberValue(int(bool(mVertShader.get())) +
int(bool(mFragShader)));
return AsSomeVariant(int(bool(mVertShader.get())) +
int(bool(mFragShader)));
case LOCAL_GL_ACTIVE_UNIFORMS:
if (!IsLinked()) return JS::NumberValue(0);
return JS::NumberValue(LinkInfo()->uniforms.size());
if (!IsLinked()) return AsSomeVariant(0);
return AsSomeVariant(LinkInfo()->uniforms.size());
case LOCAL_GL_ACTIVE_ATTRIBUTES:
if (!IsLinked()) return JS::NumberValue(0);
return JS::NumberValue(LinkInfo()->attribs.size());
if (!IsLinked()) return AsSomeVariant(0);
return AsSomeVariant(LinkInfo()->attribs.size());
case LOCAL_GL_DELETE_STATUS:
return JS::BooleanValue(IsDeleteRequested());
return AsSomeVariant(IsDeleteRequested());
case LOCAL_GL_LINK_STATUS:
return JS::BooleanValue(IsLinked());
return AsSomeVariant(IsLinked());
case LOCAL_GL_VALIDATE_STATUS:
#ifdef XP_MACOSX
// See comment in ValidateProgram.
if (gl->WorkAroundDriverBugs()) return JS::BooleanValue(true);
if (gl->WorkAroundDriverBugs()) return AsSomeVariant(true);
#endif
// Todo: Implement this in our code.
return JS::BooleanValue(bool(GetProgramiv(gl, mGLName, pname)));
return AsSomeVariant(bool(GetProgramiv(gl, mGLName, pname)));
default:
mContext->ErrorInvalidEnumInfo("pname", pname);
return JS::NullValue();
return Nothing();
}
}
@ -961,36 +960,36 @@ GLuint WebGLProgram::GetUniformBlockIndex(
return gl->fGetUniformBlockIndex(mGLName, mappedName.BeginReading());
}
void WebGLProgram::GetActiveUniformBlockName(GLuint uniformBlockIndex,
nsAString& retval) const {
nsString WebGLProgram::GetActiveUniformBlockName(
GLuint uniformBlockIndex) const {
if (!IsLinked()) {
mContext->ErrorInvalidOperation("`program` must be linked.");
return;
return EmptyString();
}
const webgl::LinkedProgramInfo* linkInfo = LinkInfo();
GLuint uniformBlockCount = (GLuint)linkInfo->uniformBlocks.size();
if (uniformBlockIndex >= uniformBlockCount) {
mContext->ErrorInvalidValue("index %u invalid.", uniformBlockIndex);
return;
return EmptyString();
}
const auto& blockInfo = linkInfo->uniformBlocks[uniformBlockIndex];
retval.Assign(NS_ConvertASCIItoUTF16(blockInfo->mUserName));
return NS_ConvertASCIItoUTF16(blockInfo->mUserName);
}
JS::Value WebGLProgram::GetActiveUniformBlockParam(GLuint uniformBlockIndex,
GLenum pname) const {
MaybeWebGLVariant WebGLProgram::GetActiveUniformBlockParam(
GLuint uniformBlockIndex, GLenum pname) const {
if (!IsLinked()) {
mContext->ErrorInvalidOperation("`program` must be linked.");
return JS::NullValue();
return Nothing();
}
const webgl::LinkedProgramInfo* linkInfo = LinkInfo();
GLuint uniformBlockCount = (GLuint)linkInfo->uniformBlocks.size();
if (uniformBlockIndex >= uniformBlockCount) {
mContext->ErrorInvalidValue("Index %u invalid.", uniformBlockIndex);
return JS::NullValue();
return Nothing();
}
gl::GLContext* gl = mContext->GL();
@ -1000,32 +999,31 @@ JS::Value WebGLProgram::GetActiveUniformBlockParam(GLuint uniformBlockIndex,
case LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
case LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
gl->fGetActiveUniformBlockiv(mGLName, uniformBlockIndex, pname, &param);
return JS::BooleanValue(bool(param));
return AsSomeVariant(bool(param));
case LOCAL_GL_UNIFORM_BLOCK_BINDING:
case LOCAL_GL_UNIFORM_BLOCK_DATA_SIZE:
case LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
gl->fGetActiveUniformBlockiv(mGLName, uniformBlockIndex, pname, &param);
return JS::NumberValue(param);
return AsSomeVariant(param);
default:
MOZ_CRASH("bad `pname`.");
}
}
JS::Value WebGLProgram::GetActiveUniformBlockActiveUniforms(
JSContext* cx, GLuint uniformBlockIndex,
ErrorResult* const out_error) const {
MaybeWebGLVariant WebGLProgram::GetActiveUniformBlockActiveUniforms(
GLuint uniformBlockIndex) const {
if (!IsLinked()) {
mContext->ErrorInvalidOperation("`program` must be linked.");
return JS::NullValue();
return Nothing();
}
const webgl::LinkedProgramInfo* linkInfo = LinkInfo();
GLuint uniformBlockCount = (GLuint)linkInfo->uniformBlocks.size();
if (uniformBlockIndex >= uniformBlockCount) {
mContext->ErrorInvalidValue("Index %u invalid.", uniformBlockIndex);
return JS::NullValue();
return Nothing();
}
gl::GLContext* gl = mContext->GL();
@ -1033,22 +1031,15 @@ JS::Value WebGLProgram::GetActiveUniformBlockActiveUniforms(
gl->fGetActiveUniformBlockiv(mGLName, uniformBlockIndex,
LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS,
&activeUniformCount);
JS::RootedObject obj(
cx, dom::Uint32Array::Create(cx, mContext, activeUniformCount, nullptr));
if (!obj) {
*out_error = NS_ERROR_OUT_OF_MEMORY;
return JS::NullValue();
}
dom::Uint32Array result;
DebugOnly<bool> inited = result.Init(obj);
MOZ_ASSERT(inited);
result.ComputeLengthAndData();
MaybeWebGLVariant ret = AsSomeVariant(nsTArray<uint32_t>());
nsTArray<uint32_t>& array = ret.ref().as<nsTArray<uint32_t>>();
array.AppendElements(activeUniformCount);
gl->fGetActiveUniformBlockiv(mGLName, uniformBlockIndex,
LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES,
(GLint*)result.Data());
(GLint*)&array[0]);
return JS::ObjectValue(*obj);
return ret;
}
already_AddRefed<WebGLUniformLocation> WebGLProgram::GetUniformLocation(
@ -1082,16 +1073,17 @@ already_AddRefed<WebGLUniformLocation> WebGLProgram::GetUniformLocation(
return locObj.forget();
}
void WebGLProgram::GetUniformIndices(
const dom::Sequence<nsString>& uniformNames,
dom::Nullable<nsTArray<GLuint>>& retval) const {
MaybeWebGLVariant WebGLProgram::GetUniformIndices(
const nsTArray<nsString>& uniformNames) const {
if (!IsLinked()) {
mContext->ErrorInvalidOperation("`program` must be linked.");
return;
return Nothing();
}
MaybeWebGLVariant ret = AsSomeVariant(nsTArray<uint32_t>());
nsTArray<uint32_t>& arr = ret.ref().as<nsTArray<uint32_t>>();
size_t count = uniformNames.Length();
nsTArray<GLuint>& arr = retval.SetValue();
gl::GLContext* gl = mContext->GL();
@ -1112,6 +1104,8 @@ void WebGLProgram::GetUniformIndices(
gl->fGetUniformIndices(mGLName, 1, &mappedNameBegin, &index);
arr.AppendElement(index);
}
return ret;
}
void WebGLProgram::UniformBlockBinding(GLuint uniformBlockIndex,
@ -1330,10 +1324,10 @@ bool WebGLProgram::ValidateAfterTentativeLink(
// Check if the attrib name conflicting to uniform name
for (const auto& attrib : linkInfo->attribs) {
const auto& attribName = attrib.mActiveInfo->mBaseUserName;
const auto& attribName = attrib.mActiveInfo.mBaseUserName;
for (const auto& uniform : linkInfo->uniforms) {
const auto& uniformName = uniform->mActiveInfo->mBaseUserName;
const auto& uniformName = uniform->mActiveInfo.mBaseUserName;
if (attribName == uniformName) {
*out_linkLog = nsPrintfCString(
"Attrib name conflicts with uniform name:"
@ -1348,7 +1342,7 @@ bool WebGLProgram::ValidateAfterTentativeLink(
for (const auto& attrib : linkInfo->attribs) {
if (attrib.mLoc == -1) continue;
const auto& elemType = attrib.mActiveInfo->mElemType;
const auto& elemType = attrib.mActiveInfo.mElemType;
const auto numUsedLocs = NumUsedLocationsByElemType(elemType);
for (uint32_t i = 0; i < numUsedLocs; i++) {
const uint32_t usedLoc = attrib.mLoc + i;
@ -1356,10 +1350,10 @@ bool WebGLProgram::ValidateAfterTentativeLink(
const auto res = attribsByLoc.insert({usedLoc, &attrib});
const bool& didInsert = res.second;
if (!didInsert) {
const auto& aliasingName = attrib.mActiveInfo->mBaseUserName;
const auto& aliasingName = attrib.mActiveInfo.mBaseUserName;
const auto& itrExisting = res.first;
const auto& existingInfo = itrExisting->second;
const auto& existingName = existingInfo->mActiveInfo->mBaseUserName;
const auto& existingName = existingInfo->mActiveInfo.mBaseUserName;
*out_linkLog = nsPrintfCString(
"Attrib \"%s\" aliases locations used by"
" attrib \"%s\".",
@ -1391,8 +1385,8 @@ bool WebGLProgram::ValidateAfterTentativeLink(
}
std::vector<size_t> componentsPerVert;
std::set<const WebGLActiveInfo*> alreadyUsed;
for (const auto& wideUserName : mNextLink_TransformFeedbackVaryings) {
std::set<nsString> alreadyUsed;
for (const nsString& wideUserName : mNextLink_TransformFeedbackVaryings) {
if (componentsPerVert.empty() ||
mNextLink_TransformFeedbackBufferMode == LOCAL_GL_SEPARATE_ATTRIBS) {
componentsPerVert.push_back(0);
@ -1400,16 +1394,18 @@ bool WebGLProgram::ValidateAfterTentativeLink(
////
const WebGLActiveInfo* curInfo = nullptr;
WebGLActiveInfo curInfo = WebGLActiveInfo::CreateInvalid();
bool found = false;
for (const auto& info : linkInfo->transformFeedbackVaryings) {
const NS_ConvertASCIItoUTF16 info_wideUserName(info->mBaseUserName);
const NS_ConvertASCIItoUTF16 info_wideUserName(info.mBaseUserName);
if (info_wideUserName == wideUserName) {
curInfo = info.get();
curInfo = info;
found = true;
break;
}
}
if (!curInfo) {
if (!found) {
const NS_LossyConvertUTF16toASCII asciiUserName(wideUserName);
*out_linkLog = nsPrintfCString(
"Transform feedback varying \"%s\" not"
@ -1418,7 +1414,7 @@ bool WebGLProgram::ValidateAfterTentativeLink(
return false;
}
const auto insertResPair = alreadyUsed.insert(curInfo);
const auto insertResPair = alreadyUsed.insert(wideUserName);
const auto& didInsert = insertResPair.second;
if (!didInsert) {
const NS_LossyConvertUTF16toASCII asciiUserName(wideUserName);
@ -1431,8 +1427,8 @@ bool WebGLProgram::ValidateAfterTentativeLink(
////
size_t varyingComponents = NumComponents(curInfo->mElemType);
varyingComponents *= curInfo->mElemCount;
size_t varyingComponents = NumComponents(curInfo.mElemType);
varyingComponents *= curInfo.mElemCount;
auto& totalComponentsForIndex = *(componentsPerVert.rbegin());
totalComponentsForIndex += varyingComponents;
@ -1549,8 +1545,8 @@ bool WebGLProgram::FindUniformByMappedName(const nsACString& mappedName,
return false;
}
void WebGLProgram::TransformFeedbackVaryings(
const dom::Sequence<nsString>& varyings, GLenum bufferMode) {
void WebGLProgram::TransformFeedbackVaryings(const nsTArray<nsString>& varyings,
GLenum bufferMode) {
const auto& gl = mContext->gl;
switch (bufferMode) {
@ -1580,24 +1576,23 @@ void WebGLProgram::TransformFeedbackVaryings(
mNextLink_TransformFeedbackBufferMode = bufferMode;
}
already_AddRefed<WebGLActiveInfo> WebGLProgram::GetTransformFeedbackVarying(
Maybe<WebGLActiveInfo> WebGLProgram::GetTransformFeedbackVarying(
GLuint index) const {
// No docs in the WebGL 2 spec for this function. Taking the language for
// getActiveAttrib, which states that the function returns null on any error.
if (!IsLinked()) {
mContext->ErrorInvalidOperation("`program` must be linked.");
return nullptr;
return Nothing();
}
if (index >= LinkInfo()->transformFeedbackVaryings.size()) {
mContext->ErrorInvalidValue(
"`index` is greater or "
"equal to TRANSFORM_FEEDBACK_VARYINGS.");
return nullptr;
return Nothing();
}
RefPtr<WebGLActiveInfo> ret = LinkInfo()->transformFeedbackVaryings[index];
return ret.forget();
return Some(LinkInfo()->transformFeedbackVaryings[index]);
}
bool WebGLProgram::UnmapUniformBlockName(const nsCString& mappedName,
@ -1631,7 +1626,7 @@ bool webgl::LinkedProgramInfo::FindAttrib(
// VS inputs cannot be arrays or structures.
// `userName` is thus always `baseUserName`.
for (const auto& attrib : attribs) {
if (attrib.mActiveInfo->mBaseUserName == userName) {
if (attrib.mActiveInfo.mBaseUserName == userName) {
*out = &attrib;
return true;
}
@ -1650,14 +1645,14 @@ bool webgl::LinkedProgramInfo::FindUniform(
webgl::UniformInfo* info = nullptr;
for (const auto& uniform : uniforms) {
if (uniform->mActiveInfo->mBaseUserName == baseUserName) {
if (uniform->mActiveInfo.mBaseUserName == baseUserName) {
info = uniform;
break;
}
}
if (!info) return false;
const auto& baseMappedName = info->mActiveInfo->mBaseMappedName;
const auto& baseMappedName = info->mActiveInfo.mBaseMappedName;
AssembleName(baseMappedName, isArray, arrayIndex, out_mappedName);
*out_arrayIndex = arrayIndex;
@ -1665,16 +1660,4 @@ bool webgl::LinkedProgramInfo::FindUniform(
return true;
}
////////////////////////////////////////////////////////////////////////////////
JSObject* WebGLProgram::WrapObject(JSContext* js,
JS::Handle<JSObject*> givenProto) {
return dom::WebGLProgram_Binding::Wrap(js, this, givenProto);
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLProgram, mVertShader, mFragShader)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLProgram, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLProgram, Release)
} // namespace mozilla

Просмотреть файл

@ -18,12 +18,14 @@
#include "nsWrapperCache.h"
#include "CacheInvalidator.h"
#include "WebGLActiveInfo.h"
#include "WebGLContext.h"
#include "WebGLObjectModel.h"
namespace mozilla {
class ErrorResult;
class WebGLActiveInfo;
class WebGLContext;
class WebGLProgram;
class WebGLShader;
class WebGLUniformLocation;
@ -41,14 +43,14 @@ namespace webgl {
enum class TextureBaseType : uint8_t;
struct AttribInfo final {
const RefPtr<WebGLActiveInfo> mActiveInfo;
const WebGLActiveInfo mActiveInfo;
const GLint mLoc; // -1 for active built-ins
};
struct UniformInfo final {
typedef decltype(WebGLContext::mBound2DTextures) TexListT;
const RefPtr<WebGLActiveInfo> mActiveInfo;
const WebGLActiveInfo mActiveInfo;
const TexListT* const mSamplerTexList;
const webgl::TextureBaseType mTexBaseType;
const bool mIsShadowSampler;
@ -56,10 +58,11 @@ struct UniformInfo final {
std::vector<uint32_t> mSamplerValues;
protected:
static const TexListT* GetTexList(WebGLActiveInfo* activeInfo);
static const TexListT* GetTexList(const WebGLContext* aWebGL,
WebGLActiveInfo* activeInfo);
public:
explicit UniformInfo(WebGLActiveInfo* activeInfo);
explicit UniformInfo(const WebGLContext* aWebGL, WebGLActiveInfo& activeInfo);
};
struct UniformBlockInfo final {
@ -106,7 +109,7 @@ struct LinkedProgramInfo final : public RefCounted<LinkedProgramInfo>,
std::vector<AttribInfo> attribs;
std::vector<UniformInfo*> uniforms; // Owns its contents.
std::vector<UniformBlockInfo*> uniformBlocks; // Owns its contents.
std::vector<RefPtr<WebGLActiveInfo>> transformFeedbackVaryings;
std::vector<WebGLActiveInfo> transformFeedbackVaryings;
std::unordered_map<uint8_t, const FragOutputInfo> fragOutputs;
uint8_t zLayerCount = 1;
@ -138,15 +141,13 @@ struct LinkedProgramInfo final : public RefCounted<LinkedProgramInfo>,
} // namespace webgl
class WebGLProgram final : public nsWrapperCache,
public WebGLRefCountedObject<WebGLProgram>,
class WebGLProgram final : public WebGLRefCountedObject<WebGLProgram>,
public LinkedListElement<WebGLProgram> {
friend class WebGLTransformFeedback;
friend struct webgl::LinkedProgramInfo;
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLProgram)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLProgram)
NS_INLINE_DECL_REFCOUNTING(WebGLProgram)
explicit WebGLProgram(WebGLContext* webgl);
@ -156,25 +157,23 @@ class WebGLProgram final : public nsWrapperCache,
void AttachShader(WebGLShader* shader);
void BindAttribLocation(GLuint index, const nsAString& name);
void DetachShader(const WebGLShader* shader);
already_AddRefed<WebGLActiveInfo> GetActiveAttrib(GLuint index) const;
already_AddRefed<WebGLActiveInfo> GetActiveUniform(GLuint index) const;
void GetAttachedShaders(nsTArray<RefPtr<WebGLShader>>* const out) const;
Maybe<WebGLActiveInfo> GetActiveAttrib(GLuint index) const;
Maybe<WebGLActiveInfo> GetActiveUniform(GLuint index) const;
MaybeAttachedShaders GetAttachedShaders() const;
GLint GetAttribLocation(const nsAString& name) const;
GLint GetFragDataLocation(const nsAString& name) const;
void GetProgramInfoLog(nsAString* const out) const;
JS::Value GetProgramParameter(GLenum pname) const;
nsString GetProgramInfoLog() const;
MaybeWebGLVariant GetProgramParameter(GLenum pname) const;
GLuint GetUniformBlockIndex(const nsAString& name) const;
void GetActiveUniformBlockName(GLuint uniformBlockIndex,
nsAString& name) const;
JS::Value GetActiveUniformBlockParam(GLuint uniformBlockIndex,
GLenum pname) const;
JS::Value GetActiveUniformBlockActiveUniforms(
JSContext* cx, GLuint uniformBlockIndex,
ErrorResult* const out_error) const;
nsString GetActiveUniformBlockName(GLuint uniformBlockIndex) const;
MaybeWebGLVariant GetActiveUniformBlockParam(GLuint uniformBlockIndex,
GLenum pname) const;
MaybeWebGLVariant GetActiveUniformBlockActiveUniforms(
GLuint uniformBlockIndex) const;
already_AddRefed<WebGLUniformLocation> GetUniformLocation(
const nsAString& name) const;
void GetUniformIndices(const dom::Sequence<nsString>& uniformNames,
dom::Nullable<nsTArray<GLuint>>& retval) const;
MaybeWebGLVariant GetUniformIndices(
const nsTArray<nsString>& uniformNames) const;
void UniformBlockBinding(GLuint uniformBlockIndex,
GLuint uniformBlockBinding) const;
@ -195,10 +194,9 @@ class WebGLProgram final : public nsWrapperCache,
bool UnmapUniformBlockName(const nsCString& mappedName,
nsCString* const out_userName) const;
void TransformFeedbackVaryings(const dom::Sequence<nsString>& varyings,
void TransformFeedbackVaryings(const nsTArray<nsString>& varyings,
GLenum bufferMode);
already_AddRefed<WebGLActiveInfo> GetTransformFeedbackVarying(
GLuint index) const;
Maybe<WebGLActiveInfo> GetTransformFeedbackVarying(GLuint index) const;
void EnumerateFragOutputs(
std::map<nsCString, const nsCString>& out_FragOutputs) const;
@ -212,11 +210,6 @@ class WebGLProgram final : public nsWrapperCache,
const auto& VertShader() const { return mVertShader; }
const auto& FragShader() const { return mFragShader; }
WebGLContext* GetParentObject() const { return mContext; }
virtual JSObject* WrapObject(JSContext* js,
JS::Handle<JSObject*> givenProto) override;
private:
~WebGLProgram();

Просмотреть файл

@ -91,8 +91,7 @@ void WebGLQuery::EndQuery() {
availRunnable->mQueries.push_back(this);
}
void WebGLQuery::GetQueryParameter(GLenum pname,
JS::MutableHandleValue retval) const {
MaybeWebGLVariant WebGLQuery::GetQueryParameter(GLenum pname) const {
switch (pname) {
case LOCAL_GL_QUERY_RESULT_AVAILABLE:
case LOCAL_GL_QUERY_RESULT:
@ -100,16 +99,18 @@ void WebGLQuery::GetQueryParameter(GLenum pname,
default:
mContext->ErrorInvalidEnumInfo("pname", pname);
return;
return Nothing();
}
if (!mTarget) {
mContext->ErrorInvalidOperation("Query has never been active.");
return;
return Nothing();
}
if (mActiveSlot)
return mContext->ErrorInvalidOperation("Query is still active.");
if (mActiveSlot) {
mContext->ErrorInvalidOperation("Query is still active.");
return Nothing();
}
// End of validation
////
@ -119,9 +120,9 @@ void WebGLQuery::GetQueryParameter(GLenum pname,
(mCanBeAvailable || StaticPrefs::webgl_allow_immediate_queries());
if (!canBeAvailable) {
if (pname == LOCAL_GL_QUERY_RESULT_AVAILABLE) {
retval.set(JS::BooleanValue(false));
return AsSomeVariant(false);
}
return;
return Nothing();
}
const auto& gl = mContext->gl;
@ -130,8 +131,7 @@ void WebGLQuery::GetQueryParameter(GLenum pname,
switch (pname) {
case LOCAL_GL_QUERY_RESULT_AVAILABLE:
gl->fGetQueryObjectuiv(mGLName, pname, (GLuint*)&val);
retval.set(JS::BooleanValue(bool(val)));
return;
return AsSomeVariant(static_cast<bool>(val));
case LOCAL_GL_QUERY_RESULT:
switch (mTarget) {
@ -154,13 +154,9 @@ void WebGLQuery::GetQueryParameter(GLenum pname,
case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
case LOCAL_GL_TIME_ELAPSED_EXT:
case LOCAL_GL_TIMESTAMP_EXT:
retval.set(JS::NumberValue(val));
break;
default:
MOZ_CRASH("Bad `mTarget`.");
return AsSomeVariant(val);
}
return;
MOZ_CRASH("Bad `mTarget`.");
default:
MOZ_CRASH("Bad `pname`.");
@ -206,16 +202,4 @@ void WebGLQuery::QueryCounter(GLenum target) {
availRunnable->mQueries.push_back(this);
}
////
JSObject* WebGLQuery::WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto) {
return dom::WebGLQuery_Binding::Wrap(cx, this, givenProto);
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLQuery)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLQuery, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLQuery, Release)
} // namespace mozilla

Просмотреть файл

@ -17,8 +17,7 @@ namespace webgl {
class AvailabilityRunnable;
} // namespace webgl
class WebGLQuery final : public nsWrapperCache,
public WebGLRefCountedObject<WebGLQuery>,
class WebGLQuery final : public WebGLRefCountedObject<WebGLQuery>,
public LinkedListElement<WebGLQuery> {
friend class webgl::AvailabilityRunnable;
friend class WebGLRefCountedObject<WebGLQuery>;
@ -39,8 +38,7 @@ class WebGLQuery final : public nsWrapperCache,
////
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLQuery)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLQuery)
NS_INLINE_DECL_REFCOUNTING(WebGLQuery)
explicit WebGLQuery(WebGLContext* webgl);
@ -51,16 +49,12 @@ class WebGLQuery final : public nsWrapperCache,
void Delete();
public:
WebGLContext* GetParentObject() const { return mContext; }
virtual JSObject* WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto) override;
////
void BeginQuery(GLenum target, WebGLRefPtr<WebGLQuery>& slot);
void DeleteQuery();
void EndQuery();
void GetQueryParameter(GLenum pname, JS::MutableHandleValue retval) const;
MaybeWebGLVariant GetQueryParameter(GLenum pname) const;
bool IsQuery() const;
void QueryCounter(GLenum target);
};

Просмотреть файл

@ -23,11 +23,6 @@ static GLenum DepthFormatForDepthStencilEmu(gl::GLContext* gl) {
return LOCAL_GL_DEPTH_COMPONENT24;
}
JSObject* WebGLRenderbuffer::WrapObject(JSContext* cx,
JS::Handle<JSObject*> givenProto) {
return dom::WebGLRenderbuffer_Binding::Wrap(cx, this, givenProto);
}
static GLuint DoCreateRenderbuffer(gl::GLContext* gl) {
MOZ_ASSERT(gl->IsCurrent());
@ -261,9 +256,4 @@ GLint WebGLRenderbuffer::GetRenderbufferParameter(RBTarget target,
return 0;
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLRenderbuffer)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLRenderbuffer, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLRenderbuffer, Release)
} // namespace mozilla

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше