From 6d3bae4e9a9027306a3ac953a1c79cbe899b5d95 Mon Sep 17 00:00:00 2001
From: Alexander Rose <alexander.rose@weirdbyte.de>
Date: Sun, 7 Oct 2018 11:31:04 -0700
Subject: [PATCH] wip, webgl/webgl2 compatibility layer

---
 package-lock.json                | Bin 412438 -> 412710 bytes
 package.json                     |   1 +
 src/mol-gl/webgl/buffer.ts       |  18 +++---
 src/mol-gl/webgl/compat.ts       |  95 +++++++++++++++++++++++++++++++
 src/mol-gl/webgl/context.ts      |  64 +++++++++++++--------
 src/mol-gl/webgl/render-item.ts  |  12 ++--
 src/mol-gl/webgl/texture.ts      |   2 +-
 src/mol-gl/webgl/uniform.ts      |  10 ++--
 src/mol-gl/webgl/vertex-array.ts |  20 +++----
 src/mol-view/viewer.ts           |  15 +----
 tsconfig.json                    |   5 +-
 11 files changed, 173 insertions(+), 69 deletions(-)
 create mode 100644 src/mol-gl/webgl/compat.ts

diff --git a/package-lock.json b/package-lock.json
index bd16400a15c501dd7f677b77c573da1d66053668..eef02eb8afb9f6be4baa39aacd2c15fb8fc6b413 100644
GIT binary patch
delta 397
zcmbO>O>)@`$qmm`C-+IPv6ZJLrRNw;4~%A(o_=H(lhNe=QtW~dL493)2t(Ik`a>gD
zrD-zEtPzgRC59C#u0>u+zM=l1<*C6%NnyU`>A{|nxrSvSdCB2M8E$6&#rm$P;hAP3
z5s{9Oz5xZ=7G-8dRUWyO1+J#)9z_+26;XZ>>Au-sVV)^b1s>(Lwn~%F8^}zuXWRTs
zHC=u3hggZt6}}O!lLfX*OnxwhXY=Pt_n2Uu$+FWVH}g&_HU<mWpXJ)T@MJR^oa1_-
z8_e1K{My~H=?R*Q64U4DGqP`gq|3OJ5zOB{PoHtC$@B|}jFRoyDU9veDNNh5Q<$fe
zPj`68EVEte4)e-3kV47rx06_2n@@M}XOi50Zx+ixjmZIx65Br?X4xDtSz(Xm_6LS+
zY0TSQBv`Er!HTBeo5j+%UA2pK`vRDJI`j5wJvLot7~e>E;sNpLKSkO2x0}1N-Dd>=
DJA#*C

delta 280
zcmZ2BLvq?Q$qmm`Cr>cooBY6<ZSxPcboJ>x9;{-U%lsl;!K}&mr}A$8Joz3IoHto+
zy5wfQ>BYtn5r=c!n-`yIW<&5iE_OqBn_peO7X}vJeqWDqEhCsY{k|R}$M)3*jO$Fm
z{Pu!W#`c0#rtJl(%+t!jLet|PF|%%0y34$>4Z{Da%&4)QD~08#Ify@T`h#CAV%y8-
zu;goi_+s1t9%0!M0A_B}Ve4St9w5nTT?pb&oLsP9bh}YE>-Gg8uGlsmwrvo%ZPQ`v
ZWZoWT#&((?EHnM|G8Vq=Zf<N3SOI-pWPAVs

diff --git a/package.json b/package.json
index 71b37e579..33864e84f 100644
--- a/package.json
+++ b/package.json
@@ -82,6 +82,7 @@
     "@types/node-fetch": "^2.1.2",
     "@types/react": "^16.4.14",
     "@types/react-dom": "^16.0.8",
+    "@types/webgl2": "0.0.4",
     "benchmark": "^2.1.4",
     "cpx": "^1.5.0",
     "css-loader": "^1.0.0",
diff --git a/src/mol-gl/webgl/buffer.ts b/src/mol-gl/webgl/buffer.ts
index bde6066f1..8cd11ef8c 100644
--- a/src/mol-gl/webgl/buffer.ts
+++ b/src/mol-gl/webgl/buffer.ts
@@ -113,8 +113,8 @@ export function createBuffer(ctx: Context, array: ArrayType, itemSize: BufferIte
     const _itemCount = Math.floor(_length / itemSize)
 
     function updateData(array: ArrayType) {
-        gl.bindBuffer(_bufferType, _buffer)
-        gl.bufferData(_bufferType, array, _usageHint)
+        gl.bindBuffer(_bufferType, _buffer);
+        (gl as WebGLRenderingContext).bufferData(_bufferType, array, _usageHint) // TODO remove cast when webgl2 types are fixed
     }
     updateData(array)
 
@@ -136,15 +136,15 @@ export function createBuffer(ctx: Context, array: ArrayType, itemSize: BufferIte
 
         updateData,
         updateSubData: (array: ArrayType, offset: number, count: number) => {
-            gl.bindBuffer(_bufferType, _buffer)
-            gl.bufferSubData(_bufferType, offset * _bpe, array.subarray(offset, offset + count))
+            gl.bindBuffer(_bufferType, _buffer);
+            (gl as WebGLRenderingContext).bufferSubData(_bufferType, offset * _bpe, array.subarray(offset, offset + count)) // TODO remove cast when webgl2 types are fixed
         },
 
         destroy: () => {
             if (destroyed) return
-            gl.bindBuffer(_bufferType, _buffer)
+            gl.bindBuffer(_bufferType, _buffer);
             // set size to 1 before deleting
-            gl.bufferData(_bufferType, 1, _usageHint)
+            (gl as WebGLRenderingContext).bufferData(_bufferType, 1, _usageHint) // TODO remove cast when webgl2 types are fixed
             gl.deleteBuffer(_buffer)
             destroyed = true
             ctx.bufferCount -= 1
@@ -164,7 +164,7 @@ export interface AttributeBuffer extends Buffer {
 
 export function createAttributeBuffer<T extends ArrayType, S extends BufferItemSize>(ctx: Context, array: ArrayType, itemSize: S, divisor: number, usageHint: UsageHint = 'dynamic'): AttributeBuffer {
     const { gl } = ctx
-    const { angleInstancedArrays } = ctx.extensions
+    const { instancedArrays } = ctx.extensions
 
     const buffer = createBuffer(ctx, array, itemSize, usageHint, 'attribute')
     const { _buffer, _bufferType, _dataType, _bpe } = buffer
@@ -177,12 +177,12 @@ export function createAttributeBuffer<T extends ArrayType, S extends BufferItemS
                 for (let i = 0; i < 4; ++i) {
                     gl.enableVertexAttribArray(location + i)
                     gl.vertexAttribPointer(location + i, 4, _dataType, false, 4 * 4 * _bpe, i * 4 * _bpe)
-                    angleInstancedArrays.vertexAttribDivisorANGLE(location + i, divisor)
+                    instancedArrays.vertexAttribDivisor(location + i, divisor)
                 }
             } else {
                 gl.enableVertexAttribArray(location)
                 gl.vertexAttribPointer(location, itemSize, _dataType, false, 0, 0)
-                angleInstancedArrays.vertexAttribDivisorANGLE(location, divisor)
+                instancedArrays.vertexAttribDivisor(location, divisor)
             }
         }
     }
diff --git a/src/mol-gl/webgl/compat.ts b/src/mol-gl/webgl/compat.ts
new file mode 100644
index 000000000..2ff0e6bb6
--- /dev/null
+++ b/src/mol-gl/webgl/compat.ts
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+export type GLRenderingContext = WebGLRenderingContext | WebGL2RenderingContext
+
+export function isWebGL(gl: any): gl is WebGLRenderingContext {
+    return typeof WebGLRenderingContext !== 'undefined' && gl instanceof WebGLRenderingContext
+}
+
+export function isWebGL2(gl: any): gl is WebGL2RenderingContext {
+    return typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext
+}
+
+export interface COMPAT_instanced_arrays {
+    drawArraysInstanced(mode: number, first: number, count: number, primcount: number): void;
+    drawElementsInstanced(mode: number, count: number, type: number, offset: number, primcount: number): void;
+    vertexAttribDivisor(index: number, divisor: number): void;
+    readonly VERTEX_ATTRIB_ARRAY_DIVISOR: number;
+}
+
+export function getInstancedArrays(gl: GLRenderingContext): COMPAT_instanced_arrays | null {
+    if (isWebGL2(gl)) {
+        return {
+            drawArraysInstanced: gl.drawArraysInstanced.bind(gl),
+            drawElementsInstanced: gl.drawElementsInstanced.bind(gl),
+            vertexAttribDivisor: gl.vertexAttribDivisor.bind(gl),
+            VERTEX_ATTRIB_ARRAY_DIVISOR: gl.VERTEX_ATTRIB_ARRAY_DIVISOR
+        }
+    } else {
+        const ext = gl.getExtension('ANGLE_instanced_arrays')
+        if (ext === null) return null
+        return {
+            drawArraysInstanced: ext.drawArraysInstancedANGLE.bind(ext),
+            drawElementsInstanced: ext.drawElementsInstancedANGLE.bind(ext),
+            vertexAttribDivisor: ext.vertexAttribDivisorANGLE.bind(ext),
+            VERTEX_ATTRIB_ARRAY_DIVISOR: ext.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE
+        }
+    }
+}
+
+export interface COMPAT_standard_derivatives {
+    readonly FRAGMENT_SHADER_DERIVATIVE_HINT: number;
+}
+
+export function getStandardDerivatives(gl: GLRenderingContext): COMPAT_standard_derivatives | null {
+    if (isWebGL2(gl)) {
+        return { FRAGMENT_SHADER_DERIVATIVE_HINT: gl.FRAGMENT_SHADER_DERIVATIVE_HINT }
+    } else {
+        const ext = gl.getExtension('OES_standard_derivatives')
+        if (ext === null) {
+            throw new Error('Could not get "OES_standard_derivatives" extension')
+        }
+        return { FRAGMENT_SHADER_DERIVATIVE_HINT: ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES }
+    }
+}
+
+export interface COMPAT_element_index_uint {
+}
+
+export function getElementIndexUint(gl: GLRenderingContext): COMPAT_element_index_uint | null {
+    return isWebGL2(gl) ? {} : gl.getExtension('OES_standard_derivatives')
+}
+
+export interface COMPAT_vertex_array_object {
+    readonly VERTEX_ARRAY_BINDING: number;
+    bindVertexArray(arrayObject: WebGLVertexArrayObject | null): void;
+    createVertexArray(): WebGLVertexArrayObject | null;
+    deleteVertexArray(arrayObject: WebGLVertexArrayObject): void;
+    isVertexArray(value: any): value is WebGLVertexArrayObject;
+}
+
+export function getVertexArrayObject(gl: GLRenderingContext): COMPAT_vertex_array_object | null {
+    if (isWebGL2(gl)) {
+        return {
+            VERTEX_ARRAY_BINDING: gl.VERTEX_ARRAY_BINDING,
+            bindVertexArray: gl.bindVertexArray.bind(gl),
+            createVertexArray: gl.createVertexArray.bind(gl),
+            deleteVertexArray: gl.deleteVertexArray.bind(gl),
+            isVertexArray: gl.isVertexArray.bind(gl) as (value: any) => value is WebGLVertexArrayObject // TODO change when webgl2 types are fixed
+        }
+    } else {
+        const ext = gl.getExtension('OES_vertex_array_object')
+        if (ext === null) return null
+        return {
+            VERTEX_ARRAY_BINDING: ext.VERTEX_ARRAY_BINDING_OES,
+            bindVertexArray: ext.bindVertexArrayOES.bind(ext),
+            createVertexArray: ext.createVertexArrayOES.bind(ext),
+            deleteVertexArray: ext.deleteVertexArrayOES.bind(ext),
+            isVertexArray: ext.isVertexArrayOES.bind(ext)
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/mol-gl/webgl/context.ts b/src/mol-gl/webgl/context.ts
index 69b99ac5a..0ba44529a 100644
--- a/src/mol-gl/webgl/context.ts
+++ b/src/mol-gl/webgl/context.ts
@@ -6,12 +6,24 @@
 
 import { createProgramCache, ProgramCache } from './program'
 import { createShaderCache, ShaderCache } from './shader'
+import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivatives, COMPAT_vertex_array_object, getInstancedArrays, getStandardDerivatives, getVertexArrayObject, isWebGL2, COMPAT_element_index_uint, getElementIndexUint } from './compat';
+
+export function getGLContext(canvas: HTMLCanvasElement, contextAttributes?: WebGLContextAttributes): GLRenderingContext | null {
+    function getContext(contextId: 'webgl' | 'experimental-webgl' | 'webgl2') {
+        try {
+           return canvas.getContext(contextId, contextAttributes) as GLRenderingContext | null
+        } catch (e) {
+            return null
+        }
+    }
+    return getContext('webgl2') ||  getContext('webgl') || getContext('experimental-webgl')
+}
 
 function getPixelRatio() {
     return (typeof window !== 'undefined') ? window.devicePixelRatio : 1
 }
 
-function unbindResources (gl: WebGLRenderingContext) {
+function unbindResources (gl: GLRenderingContext) {
     // bind null to all texture units
     const maxTextureImageUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS)
     for (let i = 0; i < maxTextureImageUnits; ++i) {
@@ -35,7 +47,7 @@ function unbindResources (gl: WebGLRenderingContext) {
     unbindFramebuffer(gl)
 }
 
-function unbindFramebuffer(gl: WebGLRenderingContext) {
+function unbindFramebuffer(gl: GLRenderingContext) {
     gl.bindFramebuffer(gl.FRAMEBUFFER, null)
 }
 
@@ -55,20 +67,21 @@ export function createImageData(buffer: Uint8Array, width: number, height: numbe
 }
 
 type Extensions = {
-    angleInstancedArrays: ANGLE_instanced_arrays
-    standardDerivatives: OES_standard_derivatives
-    oesElementIndexUint: OES_element_index_uint | null
-    oesVertexArrayObject: OES_vertex_array_object | null
+    instancedArrays: COMPAT_instanced_arrays
+    standardDerivatives: COMPAT_standard_derivatives
+    elementIndexUint: COMPAT_element_index_uint | null
+    vertexArrayObject: COMPAT_vertex_array_object | null
 }
 
 /** A WebGL context object, including the rendering context, resource caches and counts */
 export interface Context {
-    gl: WebGLRenderingContext
-    extensions: Extensions
-    pixelRatio: number
+    readonly gl: GLRenderingContext
+    readonly isWebGL2: boolean
+    readonly extensions: Extensions
+    readonly pixelRatio: number
 
-    shaderCache: ShaderCache
-    programCache: ProgramCache
+    readonly shaderCache: ShaderCache
+    readonly programCache: ProgramCache
 
     bufferCount: number
     framebufferCount: number
@@ -87,22 +100,24 @@ export interface Context {
     destroy: () => void
 }
 
-export function createContext(gl: WebGLRenderingContext): Context {
-    const angleInstancedArrays = gl.getExtension('ANGLE_instanced_arrays')
-    if (angleInstancedArrays === null) {
-        throw new Error('Could not get "ANGLE_instanced_arrays" extension')
+
+
+export function createContext(gl: GLRenderingContext): Context {
+    const instancedArrays = getInstancedArrays(gl)
+    if (instancedArrays === null) {
+        throw new Error('Could not find support for "instanced_arrays"')
     }
-    const standardDerivatives = gl.getExtension('OES_standard_derivatives')
+    const standardDerivatives = getStandardDerivatives(gl)
     if (standardDerivatives === null) {
-        throw new Error('Could not get "OES_standard_derivatives" extension')
+        throw new Error('Could not find support for "standard_derivatives"')
     }
-    const oesElementIndexUint = gl.getExtension('OES_element_index_uint')
-    if (oesElementIndexUint === null) {
-        console.warn('Could not get "OES_element_index_uint" extension')
+    const elementIndexUint = getElementIndexUint(gl)
+    if (elementIndexUint === null) {
+        console.warn('Could not find support for "element_index_uint"')
     }
-    const oesVertexArrayObject = gl.getExtension('OES_vertex_array_object')
-    if (oesVertexArrayObject === null) {
-        console.log('Could not get "OES_vertex_array_object" extension')
+    const vertexArrayObject = getVertexArrayObject(gl)
+    if (vertexArrayObject === null) {
+        console.log('Could not find support for "vertex_array_object"')
     }
 
     const shaderCache = createShaderCache()
@@ -114,7 +129,8 @@ export function createContext(gl: WebGLRenderingContext): Context {
 
     return {
         gl,
-        extensions: { angleInstancedArrays, standardDerivatives, oesElementIndexUint, oesVertexArrayObject },
+        isWebGL2: isWebGL2(gl),
+        extensions: { instancedArrays, standardDerivatives, elementIndexUint, vertexArrayObject },
         pixelRatio: getPixelRatio(),
 
         shaderCache,
diff --git a/src/mol-gl/webgl/render-item.ts b/src/mol-gl/webgl/render-item.ts
index 9795b85aa..6f3d3e6c8 100644
--- a/src/mol-gl/webgl/render-item.ts
+++ b/src/mol-gl/webgl/render-item.ts
@@ -50,7 +50,7 @@ const RenderVariantDefines = {
 export type RenderVariant = keyof typeof RenderVariantDefines
 
 type ProgramVariants = { [k: string]: ReferenceItem<Program> }
-type VertexArrayVariants = { [k: string]: WebGLVertexArrayObjectOES | undefined }
+type VertexArrayVariants = { [k: string]: WebGLVertexArrayObjectOES | null }
 
 interface ValueChanges {
     attributes: boolean
@@ -70,7 +70,7 @@ interface ValueChanges {
 export function createRenderItem(ctx: Context, drawMode: DrawMode, shaderCode: ShaderCode, schema: RenderableSchema, values: RenderableValues): RenderItem {
     const id = getNextRenderItemId()
     const { programCache } = ctx
-    const { angleInstancedArrays, oesVertexArrayObject } = ctx.extensions
+    const { instancedArrays, vertexArrayObject } = ctx.extensions
 
     const { attributeValues, defineValues, textureValues, uniformValues } = splitValues(schema, values)
     const versions = getValueVersions(values)
@@ -127,8 +127,8 @@ export function createRenderItem(ctx: Context, drawMode: DrawMode, shaderCode: S
             const program = programs[variant].value
             const vertexArray = vertexArrays[variant]
             program.setUniforms(uniformValues)
-            if (oesVertexArrayObject && vertexArray) {
-                oesVertexArrayObject.bindVertexArrayOES(vertexArray)
+            if (vertexArrayObject && vertexArray) {
+                vertexArrayObject.bindVertexArray(vertexArray)
                 // need to bind elements buffer explicitely since it is not always recorded in the VAO
                 if (elementsBuffer) elementsBuffer.bind()
             } else {
@@ -137,9 +137,9 @@ export function createRenderItem(ctx: Context, drawMode: DrawMode, shaderCode: S
             }
             program.bindTextures(textures)
             if (elementsBuffer) {
-                angleInstancedArrays.drawElementsInstancedANGLE(glDrawMode, drawCount, elementsBuffer._dataType, 0, instanceCount);
+                instancedArrays.drawElementsInstanced(glDrawMode, drawCount, elementsBuffer._dataType, 0, instanceCount);
             } else {
-                angleInstancedArrays.drawArraysInstancedANGLE(glDrawMode, 0, drawCount, instanceCount)
+                instancedArrays.drawArraysInstanced(glDrawMode, 0, drawCount, instanceCount)
             }
         },
         update: () => {
diff --git a/src/mol-gl/webgl/texture.ts b/src/mol-gl/webgl/texture.ts
index 72f0bc3f9..d7e94cc07 100644
--- a/src/mol-gl/webgl/texture.ts
+++ b/src/mol-gl/webgl/texture.ts
@@ -104,7 +104,7 @@ export function createTexture(ctx: Context, _format: TextureFormat, _type: Textu
             // unpack alignment of 1 since we use textures only for data
             gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
             // gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
-            gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, type, array)
+            (gl as WebGLRenderingContext).texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, type, array) // TODO remove cast when webgl2 types are fixed
             _width = width
             _height = height
             gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter)
diff --git a/src/mol-gl/webgl/uniform.ts b/src/mol-gl/webgl/uniform.ts
index b3dfeb4c9..a8a92ad23 100644
--- a/src/mol-gl/webgl/uniform.ts
+++ b/src/mol-gl/webgl/uniform.ts
@@ -39,11 +39,11 @@ function createUniformSetter(ctx: Context, program: WebGLProgram, name: string,
     switch (kind) {
         case 'f': return (value: number) => gl.uniform1f(location, value)
         case 'i': case 't2': return (value: number) => gl.uniform1i(location, value)
-        case 'v2': return (value: Vec2) => gl.uniform2fv(location, value)
-        case 'v3': return (value: Vec3) => gl.uniform3fv(location, value)
-        case 'v4': return (value: Vec4) => gl.uniform4fv(location, value)
-        case 'm3': return (value: Mat3) => gl.uniformMatrix3fv(location, false, value)
-        case 'm4': return (value: Mat4) => gl.uniformMatrix4fv(location, false, value)
+        case 'v2': return (value: Vec2) => (gl as WebGLRenderingContext).uniform2fv(location, value) // TODO remove cast when webgl2 types are fixed
+        case 'v3': return (value: Vec3) => (gl as WebGLRenderingContext).uniform3fv(location, value)
+        case 'v4': return (value: Vec4) => (gl as WebGLRenderingContext).uniform4fv(location, value)
+        case 'm3': return (value: Mat3) => (gl as WebGLRenderingContext).uniformMatrix3fv(location, false, value)
+        case 'm4': return (value: Mat4) => (gl as WebGLRenderingContext).uniformMatrix4fv(location, false, value)
     }
 }
 
diff --git a/src/mol-gl/webgl/vertex-array.ts b/src/mol-gl/webgl/vertex-array.ts
index aaf92f275..19a2adc2f 100644
--- a/src/mol-gl/webgl/vertex-array.ts
+++ b/src/mol-gl/webgl/vertex-array.ts
@@ -9,23 +9,23 @@ import { Program } from './program';
 import { AttributeBuffers, ElementsBuffer } from './buffer';
 
 export function createVertexArray(ctx: Context, program: Program, attributeBuffers: AttributeBuffers, elementsBuffer?: ElementsBuffer) {
-    const { oesVertexArrayObject } = ctx.extensions
-    let vertexArray: WebGLVertexArrayObjectOES | undefined = undefined
-    if (oesVertexArrayObject) {
-        vertexArray = oesVertexArrayObject.createVertexArrayOES()
-        oesVertexArrayObject.bindVertexArrayOES(vertexArray)
+    const { vertexArrayObject } = ctx.extensions
+    let vertexArray: WebGLVertexArrayObject | null = null
+    if (vertexArrayObject) {
+        vertexArray = vertexArrayObject.createVertexArray()
+        vertexArrayObject.bindVertexArray(vertexArray)
         if (elementsBuffer) elementsBuffer.bind()
         program.bindAttributes(attributeBuffers)
         ctx.vaoCount += 1
-        oesVertexArrayObject.bindVertexArrayOES(null!)
+        vertexArrayObject.bindVertexArray(null!)
     }
     return vertexArray
 }
 
-export function deleteVertexArray(ctx: Context, vertexArray?: WebGLVertexArrayObjectOES) {
-    const { oesVertexArrayObject } = ctx.extensions
-    if (oesVertexArrayObject && vertexArray) {
-        oesVertexArrayObject.deleteVertexArrayOES(vertexArray)
+export function deleteVertexArray(ctx: Context, vertexArray: WebGLVertexArrayObject | null) {
+    const { vertexArrayObject } = ctx.extensions
+    if (vertexArrayObject && vertexArray) {
+        vertexArrayObject.deleteVertexArray(vertexArray)
         ctx.vaoCount -= 1
     }
 }
\ No newline at end of file
diff --git a/src/mol-view/viewer.ts b/src/mol-view/viewer.ts
index fd4f1ec27..91a42cdac 100644
--- a/src/mol-view/viewer.ts
+++ b/src/mol-view/viewer.ts
@@ -16,7 +16,7 @@ import TrackballControls from './controls/trackball'
 import { Viewport } from './camera/util'
 import { PerspectiveCamera } from './camera/perspective'
 import { resizeCanvas } from './util';
-import { createContext } from 'mol-gl/webgl/context';
+import { createContext, getGLContext } from 'mol-gl/webgl/context';
 import { Representation } from 'mol-geo/representation';
 import { createRenderTarget } from 'mol-gl/webgl/render-target';
 import Scene from 'mol-gl/scene';
@@ -59,17 +59,6 @@ interface Viewer {
     dispose: () => void
 }
 
-function getWebGLContext(canvas: HTMLCanvasElement, contextAttributes?: WebGLContextAttributes) {
-    function getContext(contextId: 'webgl' | 'experimental-webgl') {
-        try {
-            return canvas.getContext(contextId, contextAttributes)
-        } catch (e) {
-            return null
-        }
-    }
-    return getContext('webgl') || getContext('experimental-webgl')
-}
-
 namespace Viewer {
     export function create(canvas: HTMLCanvasElement, container: Element): Viewer {
         const reprMap = new Map<Representation<any>, Set<RenderObject>>()
@@ -87,7 +76,7 @@ namespace Viewer {
         })
         // camera.lookAt(Vec3.create(0, 0, 0))
 
-        const gl = getWebGLContext(canvas, {
+        const gl = getGLContext(canvas, {
             alpha: false,
             antialias: true,
             depth: true,
diff --git a/tsconfig.json b/tsconfig.json
index 31421faf7..413bfe585 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -29,5 +29,8 @@
             "mol-view": ["./mol-view"]
         }
     },
-    "include": [ "**/*" ]
+    "include": [ "**/*" ],
+    "files": [
+        "./node_modules/@types/webgl2/index.d.ts"
+    ],
 }
\ No newline at end of file
-- 
GitLab