WebGL2Context.cpp (5215B)
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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 "GLContext.h" 9 #include "WebGLBuffer.h" 10 #include "WebGLFormats.h" 11 #include "WebGLTransformFeedback.h" 12 #include "mozilla/StaticPrefs_webgl.h" 13 #include "mozilla/dom/WebGL2RenderingContextBinding.h" 14 #include "nsPrintfCString.h" 15 16 namespace mozilla { 17 18 std::unique_ptr<webgl::FormatUsageAuthority> WebGL2Context::CreateFormatUsage( 19 gl::GLContext* gl) const { 20 return webgl::FormatUsageAuthority::CreateForWebGL2(gl); 21 } 22 23 //////////////////////////////////////////////////////////////////////////////// 24 // WebGL 2 initialisation 25 26 static const gl::GLFeature kRequiredFeatures[] = { 27 gl::GLFeature::blend_minmax, 28 gl::GLFeature::clear_buffers, 29 gl::GLFeature::copy_buffer, 30 gl::GLFeature::depth_texture, 31 gl::GLFeature::draw_instanced, 32 gl::GLFeature::element_index_uint, 33 gl::GLFeature::frag_color_float, 34 gl::GLFeature::frag_depth, 35 gl::GLFeature::framebuffer_object, 36 gl::GLFeature::get_integer_indexed, 37 gl::GLFeature::get_integer64_indexed, 38 gl::GLFeature::gpu_shader4, 39 gl::GLFeature::instanced_arrays, 40 gl::GLFeature::instanced_non_arrays, 41 gl::GLFeature::map_buffer_range, // Used by GetBufferSubData. 42 gl::GLFeature::occlusion_query2, 43 gl::GLFeature::packed_depth_stencil, 44 gl::GLFeature::query_objects, 45 gl::GLFeature::sRGB, 46 gl::GLFeature::sampler_objects, 47 gl::GLFeature::standard_derivatives, 48 gl::GLFeature::texture_3D, 49 gl::GLFeature::texture_3D_compressed, 50 gl::GLFeature::texture_3D_copy, 51 gl::GLFeature::texture_float, 52 gl::GLFeature::texture_half_float, 53 gl::GLFeature::texture_half_float_linear, 54 gl::GLFeature::texture_non_power_of_two, 55 gl::GLFeature::texture_storage, 56 gl::GLFeature::transform_feedback2, 57 gl::GLFeature::uniform_buffer_object, 58 gl::GLFeature::uniform_matrix_nonsquare, 59 gl::GLFeature::vertex_array_object}; 60 61 bool WebGLContext::InitWebGL2(FailureReason* const out_failReason) { 62 MOZ_ASSERT(IsWebGL2(), "WebGLContext is not a WebGL 2 context!"); 63 64 std::vector<gl::GLFeature> missingList; 65 66 const auto fnGatherMissing = [&](gl::GLFeature cur) { 67 if (!gl->IsSupported(cur)) { 68 missingList.push_back(cur); 69 } 70 }; 71 72 const auto fnGatherMissing2 = [&](gl::GLFeature main, gl::GLFeature alt) { 73 if (!gl->IsSupported(main) && !gl->IsSupported(alt)) { 74 missingList.push_back(main); 75 } 76 }; 77 78 //// 79 80 for (const auto& cur : kRequiredFeatures) { 81 fnGatherMissing(cur); 82 } 83 84 // On desktop, we fake occlusion_query_boolean with occlusion_query if 85 // necessary. (See WebGL2ContextQueries.cpp) 86 fnGatherMissing2(gl::GLFeature::occlusion_query_boolean, 87 gl::GLFeature::occlusion_query); 88 89 #ifdef XP_MACOSX 90 // On OSX, GL core profile is used. This requires texture swizzle 91 // support to emulate legacy texture formats: ALPHA, LUMINANCE, 92 // and LUMINANCE_ALPHA. 93 fnGatherMissing(gl::GLFeature::texture_swizzle); 94 #endif 95 96 fnGatherMissing2(gl::GLFeature::prim_restart_fixed, 97 gl::GLFeature::prim_restart); 98 99 //// 100 101 if (!missingList.empty()) { 102 nsAutoCString exts; 103 for (auto itr = missingList.begin(); itr != missingList.end(); ++itr) { 104 exts.AppendLiteral("\n "); 105 exts.Append(gl::GLContext::GetFeatureName(*itr)); 106 } 107 108 const nsPrintfCString reason( 109 "WebGL 2 requires support for the following" 110 " features: %s", 111 exts.BeginReading()); 112 *out_failReason = FailureReason("FEATURE_FAILURE_WEBGL2_OCCL", reason); 113 return false; 114 } 115 116 mGLMinProgramTexelOffset = 117 gl->GetIntAs<uint32_t>(LOCAL_GL_MIN_PROGRAM_TEXEL_OFFSET); 118 mGLMaxProgramTexelOffset = 119 gl->GetIntAs<uint32_t>(LOCAL_GL_MAX_PROGRAM_TEXEL_OFFSET); 120 121 mIndexedUniformBufferBindings.resize(mLimits->maxUniformBufferBindings); 122 123 mDefaultTransformFeedback = new WebGLTransformFeedback(this, 0); 124 mBoundTransformFeedback = mDefaultTransformFeedback; 125 126 gl->fGenTransformFeedbacks(1, &mEmptyTFO); 127 128 //// 129 130 if (!gl->IsGLES()) { 131 // Desktop OpenGL requires the following to be enabled in order to 132 // support sRGB operations on framebuffers. 133 gl->fEnable(LOCAL_GL_FRAMEBUFFER_SRGB_EXT); 134 } 135 136 if (gl->IsSupported(gl::GLFeature::prim_restart_fixed)) { 137 gl->fEnable(LOCAL_GL_PRIMITIVE_RESTART_FIXED_INDEX); 138 } else { 139 MOZ_ASSERT(gl->IsSupported(gl::GLFeature::prim_restart)); 140 } 141 142 ////// 143 144 return true; 145 } 146 147 // - 148 149 /*virtual*/ 150 bool WebGL2Context::IsTexParamValid(GLenum pname) const { 151 switch (pname) { 152 case LOCAL_GL_TEXTURE_BASE_LEVEL: 153 case LOCAL_GL_TEXTURE_COMPARE_FUNC: 154 case LOCAL_GL_TEXTURE_COMPARE_MODE: 155 case LOCAL_GL_TEXTURE_IMMUTABLE_FORMAT: 156 case LOCAL_GL_TEXTURE_IMMUTABLE_LEVELS: 157 case LOCAL_GL_TEXTURE_MAX_LEVEL: 158 case LOCAL_GL_TEXTURE_WRAP_R: 159 case LOCAL_GL_TEXTURE_MAX_LOD: 160 case LOCAL_GL_TEXTURE_MIN_LOD: 161 return true; 162 163 default: 164 return WebGLContext::IsTexParamValid(pname); 165 } 166 } 167 168 } // namespace mozilla