diff --git a/src/mol-gl/webgl/compat.ts b/src/mol-gl/webgl/compat.ts index 48f6b2b67e73dee7c6e4959d8a1eb827cf352df6..c490ca1e1fd92ff05a826f8a7002cced0961d512 100644 --- a/src/mol-gl/webgl/compat.ts +++ b/src/mol-gl/webgl/compat.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ @@ -523,6 +523,31 @@ export function getFboRenderMipmap(gl: GLRenderingContext): COMPAT_fboRenderMipm return isWebGL2(gl) ? {} : gl.getExtension('OES_fbo_render_mipmap'); } +/** + * See https://registry.khronos.org/webgl/extensions/WEBGL_provoking_vertex/ + */ +export interface COMPAT_provoking_vertex { + readonly FIRST_VERTEX_CONVENTION: number; + readonly LAST_VERTEX_CONVENTION: number; + readonly PROVOKING_VERTEX: number; + provokingVertex(provokeMode: number): void; +} + +export function getProvokingVertex(gl: GLRenderingContext): COMPAT_provoking_vertex | null { + if (isWebGL2(gl)) { + const ext = gl.getExtension('WEBGL_provoking_vertex'); + if (ext) { + return { + FIRST_VERTEX_CONVENTION: ext.FIRST_VERTEX_CONVENTION_WEBGL, + LAST_VERTEX_CONVENTION: ext.LAST_VERTEX_CONVENTION_WEBGL, + PROVOKING_VERTEX: ext.PROVOKING_VERTEX_WEBGL, + provokingVertex: ext.provokingVertexWEBGL.bind(gl) + }; + } + } + return null; +} + export function getNoNonInstancedActiveAttribs(gl: GLRenderingContext): boolean { if (!isWebGL2(gl)) return false; diff --git a/src/mol-gl/webgl/context.ts b/src/mol-gl/webgl/context.ts index 951c097f027d464713ee8351fc788128230039d3..c638f03fbc0c25df2603e3309e1b898247d4e0e7 100644 --- a/src/mol-gl/webgl/context.ts +++ b/src/mol-gl/webgl/context.ts @@ -239,6 +239,11 @@ export function createContext(gl: GLRenderingContext, props: Partial<{ pixelScal throw new Error('Need "MAX_VERTEX_TEXTURE_IMAGE_UNITS" >= 8'); } + // optimize assuming flats first and last data are same or differences don't matter + // extension is only available when `FIRST_VERTEX_CONVENTION` is more efficient + const epv = extensions.provokingVertex; + epv?.provokingVertex(epv.FIRST_VERTEX_CONVENTION); + let isContextLost = false; const contextRestored = new BehaviorSubject<now.Timestamp>(0 as now.Timestamp); diff --git a/src/mol-gl/webgl/extensions.ts b/src/mol-gl/webgl/extensions.ts index e4a4eaf97ac181d14452ac55e7c72d0f1f268dcf..77da2bcbef5c8b7209c6ec07a886997be1fd95a6 100644 --- a/src/mol-gl/webgl/extensions.ts +++ b/src/mol-gl/webgl/extensions.ts @@ -1,10 +1,10 @@ /** - * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivatives, COMPAT_vertex_array_object, getInstancedArrays, getStandardDerivatives, COMPAT_element_index_uint, getElementIndexUint, COMPAT_texture_float, getTextureFloat, COMPAT_texture_float_linear, getTextureFloatLinear, COMPAT_blend_minmax, getBlendMinMax, getFragDepth, COMPAT_frag_depth, COMPAT_color_buffer_float, getColorBufferFloat, COMPAT_draw_buffers, getDrawBuffers, getShaderTextureLod, COMPAT_shader_texture_lod, getDepthTexture, COMPAT_depth_texture, COMPAT_sRGB, getSRGB, getTextureHalfFloat, getTextureHalfFloatLinear, COMPAT_texture_half_float, COMPAT_texture_half_float_linear, COMPAT_color_buffer_half_float, getColorBufferHalfFloat, getVertexArrayObject, getDisjointTimerQuery, COMPAT_disjoint_timer_query, getNoNonInstancedActiveAttribs, getDrawBuffersIndexed, COMPAT_draw_buffers_indexed, getParallelShaderCompile, COMPAT_parallel_shader_compile, getFboRenderMipmap, COMPAT_fboRenderMipmap } from './compat'; +import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivatives, COMPAT_vertex_array_object, getInstancedArrays, getStandardDerivatives, COMPAT_element_index_uint, getElementIndexUint, COMPAT_texture_float, getTextureFloat, COMPAT_texture_float_linear, getTextureFloatLinear, COMPAT_blend_minmax, getBlendMinMax, getFragDepth, COMPAT_frag_depth, COMPAT_color_buffer_float, getColorBufferFloat, COMPAT_draw_buffers, getDrawBuffers, getShaderTextureLod, COMPAT_shader_texture_lod, getDepthTexture, COMPAT_depth_texture, COMPAT_sRGB, getSRGB, getTextureHalfFloat, getTextureHalfFloatLinear, COMPAT_texture_half_float, COMPAT_texture_half_float_linear, COMPAT_color_buffer_half_float, getColorBufferHalfFloat, getVertexArrayObject, getDisjointTimerQuery, COMPAT_disjoint_timer_query, getNoNonInstancedActiveAttribs, getDrawBuffersIndexed, COMPAT_draw_buffers_indexed, getParallelShaderCompile, COMPAT_parallel_shader_compile, getFboRenderMipmap, COMPAT_fboRenderMipmap, COMPAT_provoking_vertex, getProvokingVertex } from './compat'; import { isDebugMode } from '../../mol-util/debug'; export type WebGLExtensions = { @@ -29,6 +29,7 @@ export type WebGLExtensions = { disjointTimerQuery: COMPAT_disjoint_timer_query | null parallelShaderCompile: COMPAT_parallel_shader_compile | null fboRenderMipmap: COMPAT_fboRenderMipmap | null + provokingVertex: COMPAT_provoking_vertex | null noNonInstancedActiveAttribs: boolean } @@ -121,6 +122,10 @@ export function createExtensions(gl: GLRenderingContext): WebGLExtensions { if (isDebugMode && fboRenderMipmap === null) { console.log('Could not find support for "fbo_render_mipmap"'); } + const provokingVertex = getProvokingVertex(gl); + if (isDebugMode && provokingVertex === null) { + console.log('Could not find support for "provoking_vertex"'); + } const noNonInstancedActiveAttribs = getNoNonInstancedActiveAttribs(gl); @@ -146,6 +151,7 @@ export function createExtensions(gl: GLRenderingContext): WebGLExtensions { disjointTimerQuery, parallelShaderCompile, fboRenderMipmap, + provokingVertex, noNonInstancedActiveAttribs, };