зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
861aef232d
Коммит
198fa063c2
|
@ -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) {
|
||||
|
|
|
@ -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, ¶m);
|
||||
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, ¶m);
|
||||
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();
|
||||
|
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
@ -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
|
|
@ -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, ¶m);
|
||||
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, ¶m);
|
||||
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
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче