// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. library web_gl_test; import 'dart:html'; import 'dart:web_gl'; import 'package:expect/minitest.dart'; final isAngleInstancedArrays = (v) => v is AngleInstancedArrays; final isExtBlendMinMax = (v) => v is ExtBlendMinMax; final isExtFragDepth = (v) => v is ExtFragDepth; final isEXTsRgb = (v) => v is EXTsRgb; final isExtShaderTextureLod = (v) => v is ExtShaderTextureLod; final isExtTextureFilterAnisotropic = (v) => v is ExtTextureFilterAnisotropic; final isOesElementIndexUint = (v) => v is OesElementIndexUint; final isOesStandardDerivatives = (v) => v is OesStandardDerivatives; final isOesTextureFloat = (v) => v is OesTextureFloat; final isOesTextureFloatLinear = (v) => v is OesTextureFloatLinear; final isOesTextureHalfFloat = (v) => v is OesTextureHalfFloat; final isOesTextureHalfFloatLinear = (v) => v is OesTextureHalfFloatLinear; final isOesVertexArrayObject = (v) => v is OesVertexArrayObject; final isCompressedTextureAtc = (v) => v is CompressedTextureAtc; final isCompressedTextureETC1 = (v) => v is CompressedTextureETC1; final isCompressedTexturePvrtc = (v) => v is CompressedTexturePvrtc; final isCompressedTextureS3TC = (v) => v is CompressedTextureS3TC; final isDebugRendererInfo = (v) => v is DebugRendererInfo; final isDebugShaders = (v) => v is DebugShaders; final isDepthTexture = (v) => v is DepthTexture; final isDrawBuffers = (v) => v is DrawBuffers; final isLoseContext = (v) => v is LoseContext; final isFunction = predicate((v) => v is Function); // Test that various webgl extensions are available. Only test advertised // supported extensions. If the extension has methods, we just test the presence // of some methods - we don't test if functionality works. main() { if (!RenderingContext.supported) return; const allExtensions = const [ 'ANGLE_instanced_arrays', 'EXT_blend_minmax', 'EXT_color_buffer_float', 'EXT_color_buffer_half_float', 'EXT_disjoint_timer_query', 'EXT_frag_depth', 'EXT_sRGB', 'EXT_shader_texture_lod', 'EXT_texture_filter_anisotropic', 'OES_element_index_uint', 'OES_standard_derivatives', 'OES_texture_float', 'OES_texture_float_linear', 'OES_texture_half_float', 'OES_texture_half_float_linear', 'OES_vertex_array_object', 'WEBGL_color_buffer_float', 'WEBGL_compressed_texture_atc', 'WEBGL_compressed_texture_es3', 'WEBGL_compressed_texture_etc1', 'WEBGL_compressed_texture_pvrtc', 'WEBGL_compressed_texture_s3tc', 'WEBGL_debug_renderer_info', 'WEBGL_debug_shaders', 'WEBGL_depth_texture', 'WEBGL_draw_buffers', 'WEBGL_lose_context', ]; getExtension(String name) { expect(name, anyOf(allExtensions), reason: 'unknown extension'); var canvas = new CanvasElement(); var context = canvas.getContext3d(); expect(context, isNotNull); var supportedExtensions = context.getSupportedExtensions(); if (supportedExtensions.contains(name)) { var extension = context.getExtension(name); expect(extension, isNotNull); return extension; } return null; } testType(name, typeMatcher) { test('type', () { var extension = getExtension(name); if (extension == null) return; expect(extension, predicate(typeMatcher)); // Ensure that isInstanceOf is not instantiated for an erroneous type // X. If X is erroneous, there is only a warning at compile time and X is // treated as dynamic, which would make the above line pass. expect(typeMatcher(1), false, reason: 'invalid typeMatcher'); }); } group('ANGLE_instanced_arrays', () { const name = 'ANGLE_instanced_arrays'; testType(name, isAngleInstancedArrays); test('vertexAttribDivisorAngle', () { AngleInstancedArrays extension = getExtension(name); if (extension == null) return; expect(extension.vertexAttribDivisorAngle, isFunction); }); }); group('EXT_blend_minmax', () { testType('EXT_blend_minmax', isExtBlendMinMax); }); group('EXT_frag_depth', () { testType('EXT_frag_depth', isExtFragDepth); }); group('EXT_sRGB', () { testType('EXT_sRGB', isEXTsRgb); }); group('EXT_shader_texture_lod', () { testType('EXT_shader_texture_lod', isExtShaderTextureLod); }); group('EXT_texture_filter_anisotropic', () { testType('EXT_texture_filter_anisotropic', isExtTextureFilterAnisotropic); }); group('OES_element_index_uint', () { testType('OES_element_index_uint', isOesElementIndexUint); }); group('OES_standard_derivatives', () { testType('OES_standard_derivatives', isOesStandardDerivatives); }); group('OES_texture_float', () { testType('OES_texture_float', isOesTextureFloat); }); group('OES_texture_float_linear', () { testType('OES_texture_float_linear', isOesTextureFloatLinear); }); group('OES_texture_half_float', () { testType('OES_texture_half_float', isOesTextureHalfFloat); }); group('OES_texture_half_float_linear', () { testType('OES_texture_half_float_linear', isOesTextureHalfFloatLinear); }); group('OES_vertex_array_object', () { testType('OES_vertex_array_object', isOesVertexArrayObject); }); group('WEBGL_compressed_texture_atc', () { testType('WEBGL_compressed_texture_atc', isCompressedTextureAtc); }); group('WEBGL_compressed_texture_etc1', () { testType('WEBGL_compressed_texture_etc1', isCompressedTextureETC1); }); group('WEBGL_compressed_texture_pvrtc', () { testType('WEBGL_compressed_texture_pvrtc', isCompressedTexturePvrtc); }); group('WEBGL_compressed_texture_s3tc', () { testType('WEBGL_compressed_texture_s3tc', isCompressedTextureS3TC); }); group('WEBGL_debug_renderer_info', () { testType('WEBGL_debug_renderer_info', isDebugRendererInfo); }); group('WEBGL_debug_shaders', () { testType('WEBGL_debug_shaders', isDebugShaders); }); group('WEBGL_depth_texture', () { testType('WEBGL_depth_texture', isDepthTexture); }); group('WEBGL_draw_buffers', () { const name = 'WEBGL_draw_buffers'; testType(name, isDrawBuffers); test('drawBuffersWebgl', () { DrawBuffers extension = getExtension(name); if (extension == null) return; expect(extension.drawBuffersWebgl, isFunction); }); }); group('WEBGL_lose_context', () { const name = 'WEBGL_lose_context'; testType(name, isLoseContext); test('loseContext', () { LoseContext extension = getExtension(name); if (extension == null) return; expect(extension.loseContext, isFunction); }); }); }