/src/mozilla-central/dom/canvas/WebGL2Context.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #include "WebGL2Context.h" |
7 | | |
8 | | #include "gfxPrefs.h" |
9 | | #include "GLContext.h" |
10 | | #include "mozilla/dom/WebGL2RenderingContextBinding.h" |
11 | | #include "mozilla/ArrayUtils.h" |
12 | | #include "mozilla/Telemetry.h" |
13 | | #include "nsPrintfCString.h" |
14 | | #include "WebGLBuffer.h" |
15 | | #include "WebGLFormats.h" |
16 | | #include "WebGLTransformFeedback.h" |
17 | | |
18 | | namespace mozilla { |
19 | | |
20 | | WebGL2Context::WebGL2Context() |
21 | | : WebGLContext() |
22 | 0 | { |
23 | 0 | MOZ_ASSERT(IsSupported(), "not supposed to create a WebGL2Context" |
24 | 0 | "context when not supported"); |
25 | 0 | } |
26 | | |
27 | | WebGL2Context::~WebGL2Context() |
28 | 0 | { |
29 | 0 |
|
30 | 0 | } |
31 | | |
32 | | UniquePtr<webgl::FormatUsageAuthority> |
33 | | WebGL2Context::CreateFormatUsage(gl::GLContext* gl) const |
34 | 0 | { |
35 | 0 | return webgl::FormatUsageAuthority::CreateForWebGL2(gl); |
36 | 0 | } |
37 | | |
38 | | /*static*/ bool |
39 | | WebGL2Context::IsSupported() |
40 | 0 | { |
41 | 0 | return gfxPrefs::WebGL2Enabled(); |
42 | 0 | } |
43 | | |
44 | | /*static*/ WebGL2Context* |
45 | | WebGL2Context::Create() |
46 | 0 | { |
47 | 0 | return new WebGL2Context(); |
48 | 0 | } |
49 | | |
50 | | JSObject* |
51 | | WebGL2Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) |
52 | 0 | { |
53 | 0 | return dom::WebGL2RenderingContext_Binding::Wrap(cx, this, givenProto); |
54 | 0 | } |
55 | | |
56 | | //////////////////////////////////////////////////////////////////////////////// |
57 | | // WebGL 2 initialisation |
58 | | |
59 | | static const gl::GLFeature kRequiredFeatures[] = { |
60 | | gl::GLFeature::blend_minmax, |
61 | | gl::GLFeature::clear_buffers, |
62 | | gl::GLFeature::copy_buffer, |
63 | | gl::GLFeature::depth_texture, |
64 | | gl::GLFeature::draw_instanced, |
65 | | gl::GLFeature::draw_range_elements, |
66 | | gl::GLFeature::element_index_uint, |
67 | | gl::GLFeature::frag_color_float, |
68 | | gl::GLFeature::frag_depth, |
69 | | gl::GLFeature::framebuffer_object, |
70 | | gl::GLFeature::get_integer_indexed, |
71 | | gl::GLFeature::get_integer64_indexed, |
72 | | gl::GLFeature::gpu_shader4, |
73 | | gl::GLFeature::instanced_arrays, |
74 | | gl::GLFeature::instanced_non_arrays, |
75 | | gl::GLFeature::map_buffer_range, // Used by GetBufferSubData. |
76 | | gl::GLFeature::occlusion_query2, |
77 | | gl::GLFeature::packed_depth_stencil, |
78 | | gl::GLFeature::query_objects, |
79 | | gl::GLFeature::renderbuffer_color_float, |
80 | | gl::GLFeature::renderbuffer_color_half_float, |
81 | | gl::GLFeature::sRGB, |
82 | | gl::GLFeature::sampler_objects, |
83 | | gl::GLFeature::standard_derivatives, |
84 | | gl::GLFeature::texture_3D, |
85 | | gl::GLFeature::texture_3D_compressed, |
86 | | gl::GLFeature::texture_3D_copy, |
87 | | gl::GLFeature::texture_float, |
88 | | gl::GLFeature::texture_half_float, |
89 | | gl::GLFeature::texture_half_float_linear, |
90 | | gl::GLFeature::texture_non_power_of_two, |
91 | | gl::GLFeature::texture_storage, |
92 | | gl::GLFeature::transform_feedback2, |
93 | | gl::GLFeature::uniform_buffer_object, |
94 | | gl::GLFeature::uniform_matrix_nonsquare, |
95 | | gl::GLFeature::vertex_array_object |
96 | | }; |
97 | | |
98 | | bool |
99 | | WebGLContext::InitWebGL2(FailureReason* const out_failReason) |
100 | 0 | { |
101 | 0 | MOZ_ASSERT(IsWebGL2(), "WebGLContext is not a WebGL 2 context!"); |
102 | 0 |
|
103 | 0 | std::vector<gl::GLFeature> missingList; |
104 | 0 |
|
105 | 0 | const auto fnGatherMissing = [&](gl::GLFeature cur) { |
106 | 0 | if (!gl->IsSupported(cur)) { |
107 | 0 | missingList.push_back(cur); |
108 | 0 | } |
109 | 0 | }; |
110 | 0 |
|
111 | 0 | const auto fnGatherMissing2 = [&](gl::GLFeature main, gl::GLFeature alt) { |
112 | 0 | if (!gl->IsSupported(main) && !gl->IsSupported(alt)) { |
113 | 0 | missingList.push_back(main); |
114 | 0 | } |
115 | 0 | }; |
116 | 0 |
|
117 | 0 | //// |
118 | 0 |
|
119 | 0 | for (const auto& cur : kRequiredFeatures) { |
120 | 0 | fnGatherMissing(cur); |
121 | 0 | } |
122 | 0 |
|
123 | 0 | // On desktop, we fake occlusion_query_boolean with occlusion_query if |
124 | 0 | // necessary. (See WebGL2ContextQueries.cpp) |
125 | 0 | fnGatherMissing2(gl::GLFeature::occlusion_query_boolean, |
126 | 0 | gl::GLFeature::occlusion_query); |
127 | 0 |
|
128 | | #ifdef XP_MACOSX |
129 | | // On OSX, GL core profile is used. This requires texture swizzle |
130 | | // support to emulate legacy texture formats: ALPHA, LUMINANCE, |
131 | | // and LUMINANCE_ALPHA. |
132 | | fnGatherMissing(gl::GLFeature::texture_swizzle); |
133 | | #endif |
134 | |
|
135 | 0 | fnGatherMissing2(gl::GLFeature::prim_restart_fixed, |
136 | 0 | gl::GLFeature::prim_restart); |
137 | 0 |
|
138 | 0 | //// |
139 | 0 |
|
140 | 0 | if (!missingList.empty()) { |
141 | 0 | nsAutoCString exts; |
142 | 0 | for (auto itr = missingList.begin(); itr != missingList.end(); ++itr) { |
143 | 0 | exts.AppendLiteral("\n "); |
144 | 0 | exts.Append(gl::GLContext::GetFeatureName(*itr)); |
145 | 0 | } |
146 | 0 |
|
147 | 0 | const nsPrintfCString reason("WebGL 2 requires support for the following" |
148 | 0 | " features: %s", |
149 | 0 | exts.BeginReading()); |
150 | 0 | *out_failReason = FailureReason("FEATURE_FAILURE_WEBGL2_OCCL", reason); |
151 | 0 | return false; |
152 | 0 | } |
153 | 0 |
|
154 | 0 | // we initialise WebGL 2 related stuff. |
155 | 0 | gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, |
156 | 0 | &mGLMaxTransformFeedbackSeparateAttribs); |
157 | 0 | gl->GetUIntegerv(LOCAL_GL_MAX_UNIFORM_BUFFER_BINDINGS, |
158 | 0 | &mGLMaxUniformBufferBindings); |
159 | 0 |
|
160 | 0 | mIndexedUniformBufferBindings.resize(mGLMaxUniformBufferBindings); |
161 | 0 |
|
162 | 0 | mDefaultTransformFeedback = new WebGLTransformFeedback(this, 0); |
163 | 0 | mBoundTransformFeedback = mDefaultTransformFeedback; |
164 | 0 |
|
165 | 0 | gl->fGenTransformFeedbacks(1, &mEmptyTFO); |
166 | 0 |
|
167 | 0 | //// |
168 | 0 |
|
169 | 0 | if (!gl->IsGLES()) { |
170 | 0 | // Desktop OpenGL requires the following to be enabled in order to |
171 | 0 | // support sRGB operations on framebuffers. |
172 | 0 | gl->fEnable(LOCAL_GL_FRAMEBUFFER_SRGB_EXT); |
173 | 0 | } |
174 | 0 |
|
175 | 0 | if (gl->IsSupported(gl::GLFeature::prim_restart_fixed)) { |
176 | 0 | gl->fEnable(LOCAL_GL_PRIMITIVE_RESTART_FIXED_INDEX); |
177 | 0 | } else { |
178 | 0 | MOZ_ASSERT(gl->IsSupported(gl::GLFeature::prim_restart)); |
179 | 0 | } |
180 | 0 |
|
181 | 0 | ////// |
182 | 0 |
|
183 | 0 | return true; |
184 | 0 | } |
185 | | |
186 | | } // namespace mozilla |