summaryrefslogtreecommitdiffstats
path: root/dom/canvas/WebGL2Context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/WebGL2Context.cpp')
-rw-r--r--dom/canvas/WebGL2Context.cpp187
1 files changed, 187 insertions, 0 deletions
diff --git a/dom/canvas/WebGL2Context.cpp b/dom/canvas/WebGL2Context.cpp
new file mode 100644
index 000000000..f9a1eba4b
--- /dev/null
+++ b/dom/canvas/WebGL2Context.cpp
@@ -0,0 +1,187 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+
+#include "gfxPrefs.h"
+#include "GLContext.h"
+#include "mozilla/dom/WebGL2RenderingContextBinding.h"
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/Telemetry.h"
+#include "nsPrintfCString.h"
+#include "WebGLBuffer.h"
+#include "WebGLFormats.h"
+#include "WebGLTransformFeedback.h"
+
+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);
+}
+
+/*static*/ bool
+WebGL2Context::IsSupported()
+{
+ return gfxPrefs::WebGL2Enabled();
+}
+
+/*static*/ WebGL2Context*
+WebGL2Context::Create()
+{
+ return new WebGL2Context();
+}
+
+JSObject*
+WebGL2Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
+{
+ return dom::WebGL2RenderingContextBinding::Wrap(cx, this, givenProto);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WebGL 2 initialisation
+
+static const gl::GLFeature kRequiredFeatures[] = {
+ gl::GLFeature::blend_minmax,
+ gl::GLFeature::clear_buffers,
+ gl::GLFeature::copy_buffer,
+ gl::GLFeature::depth_texture,
+ gl::GLFeature::draw_instanced,
+ gl::GLFeature::draw_range_elements,
+ gl::GLFeature::element_index_uint,
+ gl::GLFeature::frag_color_float,
+ gl::GLFeature::frag_depth,
+ gl::GLFeature::framebuffer_object,
+ gl::GLFeature::get_integer_indexed,
+ gl::GLFeature::get_integer64_indexed,
+ gl::GLFeature::gpu_shader4,
+ gl::GLFeature::instanced_arrays,
+ gl::GLFeature::instanced_non_arrays,
+ gl::GLFeature::map_buffer_range, // Used by GetBufferSubData.
+ gl::GLFeature::occlusion_query2,
+ gl::GLFeature::packed_depth_stencil,
+ gl::GLFeature::query_objects,
+ gl::GLFeature::renderbuffer_color_float,
+ gl::GLFeature::renderbuffer_color_half_float,
+ gl::GLFeature::sRGB_framebuffer,
+ gl::GLFeature::sRGB_texture,
+ gl::GLFeature::sampler_objects,
+ gl::GLFeature::standard_derivatives,
+ gl::GLFeature::texture_3D,
+ gl::GLFeature::texture_3D_compressed,
+ gl::GLFeature::texture_3D_copy,
+ gl::GLFeature::texture_float,
+ gl::GLFeature::texture_half_float,
+ gl::GLFeature::texture_half_float_linear,
+ gl::GLFeature::texture_non_power_of_two,
+ gl::GLFeature::texture_storage,
+ gl::GLFeature::transform_feedback2,
+ gl::GLFeature::uniform_buffer_object,
+ gl::GLFeature::uniform_matrix_nonsquare,
+ gl::GLFeature::vertex_array_object
+};
+
+bool
+WebGLContext::InitWebGL2(FailureReason* const out_failReason)
+{
+ MOZ_ASSERT(IsWebGL2(), "WebGLContext is not a WebGL 2 context!");
+
+ std::vector<gl::GLFeature> missingList;
+
+ const auto fnGatherMissing = [&](gl::GLFeature cur) {
+ if (!gl->IsSupported(cur)) {
+ missingList.push_back(cur);
+ }
+ };
+
+ const auto fnGatherMissing2 = [&](gl::GLFeature main, gl::GLFeature alt) {
+ if (!gl->IsSupported(main) && !gl->IsSupported(alt)) {
+ missingList.push_back(main);
+ }
+ };
+
+ ////
+
+ for (const auto& cur : kRequiredFeatures) {
+ fnGatherMissing(cur);
+ }
+
+ // On desktop, we fake occlusion_query_boolean with occlusion_query if
+ // necessary. (See WebGL2ContextQueries.cpp)
+ fnGatherMissing2(gl::GLFeature::occlusion_query_boolean,
+ gl::GLFeature::occlusion_query);
+
+#ifdef XP_MACOSX
+ // On OSX, GL core profile is used. This requires texture swizzle
+ // support to emulate legacy texture formats: ALPHA, LUMINANCE,
+ // and LUMINANCE_ALPHA.
+ fnGatherMissing(gl::GLFeature::texture_swizzle);
+#endif
+
+ fnGatherMissing2(gl::GLFeature::prim_restart_fixed,
+ gl::GLFeature::prim_restart);
+
+ ////
+
+ if (missingList.size()) {
+ nsAutoCString exts;
+ for (auto itr = missingList.begin(); itr != missingList.end(); ++itr) {
+ exts.AppendLiteral("\n ");
+ exts.Append(gl::GLContext::GetFeatureName(*itr));
+ }
+
+ const nsPrintfCString reason("WebGL 2 requires support for the following"
+ " features: %s",
+ exts.BeginReading());
+ *out_failReason = FailureReason("FEATURE_FAILURE_WEBGL2_OCCL", reason);
+ return false;
+ }
+
+ // we initialise WebGL 2 related stuff.
+ gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
+ &mGLMaxTransformFeedbackSeparateAttribs);
+ gl->GetUIntegerv(LOCAL_GL_MAX_UNIFORM_BUFFER_BINDINGS,
+ &mGLMaxUniformBufferBindings);
+
+ mIndexedUniformBufferBindings.resize(mGLMaxUniformBufferBindings);
+
+ mDefaultTransformFeedback = new WebGLTransformFeedback(this, 0);
+ mBoundTransformFeedback = mDefaultTransformFeedback;
+
+ gl->fGenTransformFeedbacks(1, &mEmptyTFO);
+
+ ////
+
+ if (!gl->IsGLES()) {
+ // Desktop OpenGL requires the following to be enabled in order to
+ // support sRGB operations on framebuffers.
+ gl->fEnable(LOCAL_GL_FRAMEBUFFER_SRGB_EXT);
+ }
+
+ if (gl->IsSupported(gl::GLFeature::prim_restart_fixed)) {
+ gl->fEnable(LOCAL_GL_PRIMITIVE_RESTART_FIXED_INDEX);
+ } else {
+ MOZ_ASSERT(gl->IsSupported(gl::GLFeature::prim_restart));
+ }
+
+ //////
+
+ return true;
+}
+
+} // namespace mozilla