@@ -24,12 +24,18 @@ export enum Type {
24
24
}
25
25
26
26
export interface Features {
27
- 'WEBGL_DISJOINT_QUERY_TIMER' ?: boolean ;
27
+ // Whether the disjoint_query_timer extension is an available extension.
28
+ 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_ENABLED' ?: boolean ;
29
+ // Whether the timer object from the disjoint_query_timer extension gives
30
+ // timing information that is reliable.
31
+ 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE' ?: boolean ;
32
+ // 0: No WebGL, 1: WebGL 1.0, 2: WebGL 2.0.
28
33
'WEBGL_VERSION' ?: number ;
29
34
}
30
35
31
36
export const URL_PROPERTIES : URLProperty [ ] = [
32
- { name : 'WEBGL_DISJOINT_QUERY_TIMER' , type : Type . BOOLEAN } ,
37
+ { name : 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_ENABLED' , type : Type . BOOLEAN } ,
38
+ { name : 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE' , type : Type . BOOLEAN } ,
33
39
{ name : 'WEBGL_VERSION' , type : Type . NUMBER }
34
40
] ;
35
41
@@ -38,50 +44,51 @@ export interface URLProperty {
38
44
type : Type ;
39
45
}
40
46
41
- function isWebGL2Enabled ( ) {
47
+ function getWebGLRenderingContext ( webGLVersion : number ) : WebGLRenderingContext {
48
+ if ( webGLVersion === 0 ) {
49
+ throw new Error ( 'Cannot get WebGL rendering context, WebGL is disabled.' ) ;
50
+ }
51
+
42
52
const tempCanvas = document . createElement ( 'canvas' ) ;
43
- const gl = tempCanvas . getContext ( 'webgl2' ) as WebGLRenderingContext ;
53
+ if ( webGLVersion === 1 ) {
54
+ return ( tempCanvas . getContext ( 'webgl' ) ||
55
+ tempCanvas . getContext ( 'experimental-webgl' ) ) as
56
+ WebGLRenderingContext ;
57
+ }
58
+ return tempCanvas . getContext ( 'webgl2' ) as WebGLRenderingContext ;
59
+ }
60
+
61
+ function loseContext ( gl : WebGLRenderingContext ) {
44
62
if ( gl != null ) {
45
63
const loseContextExtension = gl . getExtension ( 'WEBGL_lose_context' ) ;
46
64
if ( loseContextExtension == null ) {
47
65
throw new Error (
48
66
'Extension WEBGL_lose_context not supported on this browser.' ) ;
49
67
}
50
68
loseContextExtension . loseContext ( ) ;
51
- return true ;
52
69
}
53
- return false ;
54
70
}
55
71
56
- function isWebGL1Enabled ( ) {
57
- const tempCanvas = document . createElement ( 'canvas' ) ;
58
- const gl =
59
- ( tempCanvas . getContext ( 'webgl' ) ||
60
- tempCanvas . getContext ( 'experimental-webgl' ) ) as WebGLRenderingContext ;
72
+ function isWebGLVersionEnabled ( webGLVersion : 1 | 2 ) {
73
+ const gl = getWebGLRenderingContext ( webGLVersion ) ;
61
74
if ( gl != null ) {
62
- const loseContextExtension = gl . getExtension ( 'WEBGL_lose_context' ) ;
63
- if ( loseContextExtension == null ) {
64
- throw new Error (
65
- 'Extension WEBGL_lose_context not supported on this browser.' ) ;
66
- }
67
- loseContextExtension . loseContext ( ) ;
75
+ loseContext ( gl ) ;
68
76
return true ;
69
77
}
70
78
return false ;
71
79
}
72
80
73
- function evaluateFeature < K extends keyof Features > ( feature : K ) : Features [ K ] {
74
- if ( feature === 'WEBGL_DISJOINT_QUERY_TIMER' ) {
75
- return ! device_util . isMobile ( ) ;
76
- } else if ( feature === 'WEBGL_VERSION' ) {
77
- if ( isWebGL2Enabled ( ) ) {
78
- return 2 ;
79
- } else if ( isWebGL1Enabled ( ) ) {
80
- return 1 ;
81
- }
82
- return 0 ;
81
+ function isWebGLDisjointQueryTimerEnabled ( webGLVersion : number ) {
82
+ const gl = getWebGLRenderingContext ( webGLVersion ) ;
83
+
84
+ const extensionName = webGLVersion === 1 ? 'EXT_disjoint_timer_query' :
85
+ 'EXT_disjoint_timer_query_webgl2' ;
86
+ const ext = gl . getExtension ( extensionName ) ;
87
+ const isExtEnabled = ext != null ;
88
+ if ( gl != null ) {
89
+ loseContext ( gl ) ;
83
90
}
84
- throw new Error ( `Unknown feature ${ feature } .` ) ;
91
+ return isExtEnabled ;
85
92
}
86
93
87
94
export class Environment {
@@ -98,10 +105,33 @@ export class Environment {
98
105
return this . features [ feature ] ;
99
106
}
100
107
101
- this . features [ feature ] = evaluateFeature ( feature ) ;
108
+ this . features [ feature ] = this . evaluateFeature ( feature ) ;
102
109
103
110
return this . features [ feature ] ;
104
111
}
112
+
113
+ private evaluateFeature < K extends keyof Features > ( feature : K ) : Features [ K ] {
114
+ if ( feature === 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_ENABLED' ) {
115
+ const webGLVersion = this . get ( 'WEBGL_VERSION' ) ;
116
+
117
+ if ( webGLVersion === 0 ) {
118
+ return false ;
119
+ }
120
+
121
+ return isWebGLDisjointQueryTimerEnabled ( webGLVersion ) ;
122
+ } else if ( feature === 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE' ) {
123
+ return this . get ( 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_ENABLED' ) &&
124
+ ! device_util . isMobile ( ) ;
125
+ } else if ( feature === 'WEBGL_VERSION' ) {
126
+ if ( isWebGLVersionEnabled ( 2 ) ) {
127
+ return 2 ;
128
+ } else if ( isWebGLVersionEnabled ( 1 ) ) {
129
+ return 1 ;
130
+ }
131
+ return 0 ;
132
+ }
133
+ throw new Error ( `Unknown feature ${ feature } .` ) ;
134
+ }
105
135
}
106
136
107
137
// Expects flags from URL in the format ?dljsflags=FLAG1:1,FLAG2:true.
0 commit comments