1
1
import { EventHandler } from '../core/event-handler.js' ;
2
+ import { platform } from '../core/platform.js' ;
3
+
4
+ import { ScopeSpace } from './scope-space.js' ;
5
+ import { programlib } from './program-lib/program-lib.js' ;
6
+ import { ProgramLibrary } from './program-library.js' ;
7
+
8
+ import {
9
+ PRIMITIVE_POINTS , PRIMITIVE_TRIFAN
10
+ } from './constants.js' ;
11
+ import { Debug } from '../core/debug.js' ;
12
+
13
+ const EVENT_RESIZE = 'resizecanvas' ;
14
+
15
+ /** @typedef {import('./render-target.js').RenderTarget } RenderTarget */
2
16
3
17
/**
4
18
* The graphics device manages the underlying graphics context. It is responsible for submitting
@@ -9,10 +23,288 @@ import { EventHandler } from '../core/event-handler.js';
9
23
* @augments EventHandler
10
24
*/
11
25
class GraphicsDevice extends EventHandler {
26
+ /**
27
+ * The canvas DOM element that provides the underlying WebGL context used by the graphics device.
28
+ *
29
+ * @type {HTMLCanvasElement }
30
+ */
31
+ canvas ;
32
+
33
+ /**
34
+ * The scope namespace for shader attributes and variables.
35
+ *
36
+ * @type {ScopeSpace }
37
+ */
38
+ scope ;
39
+
40
+ /**
41
+ * The maximum supported texture anisotropy setting.
42
+ *
43
+ * @type {number }
44
+ */
45
+ maxAnisotropy ;
46
+
47
+ /**
48
+ * The maximum supported dimension of a cube map.
49
+ *
50
+ * @type {number }
51
+ */
52
+ maxCubeMapSize ;
53
+
54
+ /**
55
+ * The maximum supported dimension of a texture.
56
+ *
57
+ * @type {number }
58
+ */
59
+ maxTextureSize ;
60
+
61
+ /**
62
+ * The maximum supported dimension of a 3D texture (any axis).
63
+ *
64
+ * @type {number }
65
+ */
66
+ maxVolumeSize ;
67
+
68
+ /**
69
+ * The highest shader precision supported by this graphics device. Can be 'hiphp', 'mediump' or
70
+ * 'lowp'.
71
+ *
72
+ * @type {string }
73
+ */
74
+ precision ;
75
+
76
+ /**
77
+ * True if hardware instancing is supported.
78
+ *
79
+ * @type {boolean }
80
+ */
81
+ supportsInstancing ;
82
+
83
+ /**
84
+ * True if 32-bit floating-point textures can be used as a frame buffer.
85
+ *
86
+ * @type {boolean }
87
+ */
88
+ textureFloatRenderable ;
89
+
90
+ /**
91
+ * True if 16-bit floating-point textures can be used as a frame buffer.
92
+ *
93
+ * @type {boolean }
94
+ */
95
+ textureHalfFloatRenderable ;
96
+
97
+ constructor ( canvas ) {
98
+ super ( ) ;
99
+
100
+ this . canvas = canvas ;
101
+
102
+ // local width/height without pixelRatio applied
103
+ this . _width = 0 ;
104
+ this . _height = 0 ;
105
+
106
+ this . _maxPixelRatio = 1 ;
107
+
108
+ // Array of WebGL objects that need to be re-initialized after a context restore event
109
+ this . shaders = [ ] ;
110
+ this . buffers = [ ] ;
111
+ this . textures = [ ] ;
112
+ this . targets = [ ] ;
113
+
114
+ this . _vram = {
115
+ // #if _PROFILER
116
+ texShadow : 0 ,
117
+ texAsset : 0 ,
118
+ texLightmap : 0 ,
119
+ // #endif
120
+ tex : 0 ,
121
+ vb : 0 ,
122
+ ib : 0
123
+ } ;
124
+
125
+ this . _shaderStats = {
126
+ vsCompiled : 0 ,
127
+ fsCompiled : 0 ,
128
+ linked : 0 ,
129
+ materialShaders : 0 ,
130
+ compileTime : 0
131
+ } ;
132
+
133
+ this . initializeContextCaches ( ) ;
134
+
135
+ // Profiler stats
136
+ this . _drawCallsPerFrame = 0 ;
137
+ this . _shaderSwitchesPerFrame = 0 ;
138
+
139
+ this . _primsPerFrame = [ ] ;
140
+ for ( let i = PRIMITIVE_POINTS ; i <= PRIMITIVE_TRIFAN ; i ++ ) {
141
+ this . _primsPerFrame [ i ] = 0 ;
142
+ }
143
+ this . _renderTargetCreationTime = 0 ;
144
+
145
+ // Create the ScopeNamespace for shader attributes and variables
146
+ this . scope = new ScopeSpace ( "Device" ) ;
147
+
148
+ this . programLib = new ProgramLibrary ( this ) ;
149
+ for ( const generator in programlib )
150
+ this . programLib . register ( generator , programlib [ generator ] ) ;
151
+ }
152
+
12
153
// don't stringify GraphicsDevice to JSON by JSON.stringify
13
154
toJSON ( key ) {
14
155
return undefined ;
15
156
}
157
+
158
+ initializeContextCaches ( ) {
159
+ this . indexBuffer = null ;
160
+ this . vertexBuffers = [ ] ;
161
+ this . shader = null ;
162
+ this . renderTarget = null ;
163
+ }
164
+
165
+ /**
166
+ * Retrieves the program library assigned to the specified graphics device.
167
+ *
168
+ * @returns {ProgramLibrary } The program library assigned to the device.
169
+ * @ignore
170
+ */
171
+ getProgramLibrary ( ) {
172
+ return this . programLib ;
173
+ }
174
+
175
+ /**
176
+ * Assigns a program library to the specified device. By default, a graphics device is created
177
+ * with a program library that manages all of the programs that are used to render any
178
+ * graphical primitives. However, this function allows the user to replace the existing program
179
+ * library with a new one.
180
+ *
181
+ * @param {ProgramLibrary } programLib - The program library to assign to the device.
182
+ * @ignore
183
+ */
184
+ setProgramLibrary ( programLib ) {
185
+ this . programLib = programLib ;
186
+ }
187
+
188
+ /**
189
+ * Sets the specified render target on the device. If null is passed as a parameter, the back
190
+ * buffer becomes the current target for all rendering operations.
191
+ *
192
+ * @param {RenderTarget } renderTarget - The render target to activate.
193
+ * @example
194
+ * // Set a render target to receive all rendering output
195
+ * device.setRenderTarget(renderTarget);
196
+ *
197
+ * // Set the back buffer to receive all rendering output
198
+ * device.setRenderTarget(null);
199
+ */
200
+ setRenderTarget ( renderTarget ) {
201
+ this . renderTarget = renderTarget ;
202
+ }
203
+
204
+ /**
205
+ * Queries the currently set render target on the device.
206
+ *
207
+ * @returns {RenderTarget } The current render target.
208
+ * @example
209
+ * // Get the current render target
210
+ * var renderTarget = device.getRenderTarget();
211
+ */
212
+ getRenderTarget ( ) {
213
+ return this . renderTarget ;
214
+ }
215
+
216
+ /**
217
+ * Sets the width and height of the canvas, then fires the `resizecanvas` event. Note that the
218
+ * specified width and height values will be multiplied by the value of
219
+ * {@link GraphicsDevice#maxPixelRatio} to give the final resultant width and height for the
220
+ * canvas.
221
+ *
222
+ * @param {number } width - The new width of the canvas.
223
+ * @param {number } height - The new height of the canvas.
224
+ * @ignore
225
+ */
226
+ resizeCanvas ( width , height ) {
227
+ this . _width = width ;
228
+ this . _height = height ;
229
+
230
+ const ratio = Math . min ( this . _maxPixelRatio , platform . browser ? window . devicePixelRatio : 1 ) ;
231
+ width = Math . floor ( width * ratio ) ;
232
+ height = Math . floor ( height * ratio ) ;
233
+
234
+ if ( this . canvas . width !== width || this . canvas . height !== height ) {
235
+ this . canvas . width = width ;
236
+ this . canvas . height = height ;
237
+ this . fire ( EVENT_RESIZE , width , height ) ;
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Sets the width and height of the canvas, then fires the `resizecanvas` event. Note that the
243
+ * value of {@link GraphicsDevice#maxPixelRatio} is ignored.
244
+ *
245
+ * @param {number } width - The new width of the canvas.
246
+ * @param {number } height - The new height of the canvas.
247
+ * @ignore
248
+ */
249
+ setResolution ( width , height ) {
250
+ this . _width = width ;
251
+ this . _height = height ;
252
+ this . canvas . width = width ;
253
+ this . canvas . height = height ;
254
+ this . fire ( EVENT_RESIZE , width , height ) ;
255
+ }
256
+
257
+ updateClientRect ( ) {
258
+ this . clientRect = this . canvas . getBoundingClientRect ( ) ;
259
+ }
260
+
261
+ /**
262
+ * Width of the back buffer in pixels.
263
+ *
264
+ * @type {number }
265
+ */
266
+ get width ( ) {
267
+ Debug . assert ( "GraphicsDevice.width is not implemented on current device." ) ;
268
+ return this . canvas . width ;
269
+ }
270
+
271
+ /**
272
+ * Height of the back buffer in pixels.
273
+ *
274
+ * @type {number }
275
+ */
276
+ get height ( ) {
277
+ Debug . assert ( "GraphicsDevice.height is not implemented on current device." ) ;
278
+ return this . canvas . height ;
279
+ }
280
+
281
+ /**
282
+ * Fullscreen mode.
283
+ *
284
+ * @type {boolean }
285
+ */
286
+ set fullscreen ( fullscreen ) {
287
+ Debug . assert ( "GraphicsDevice.fullscreen is not implemented on current device." ) ;
288
+ }
289
+
290
+ get fullscreen ( ) {
291
+ Debug . assert ( "GraphicsDevice.fullscreen is not implemented on current device." ) ;
292
+ return false ;
293
+ }
294
+
295
+ /**
296
+ * Maximum pixel ratio.
297
+ *
298
+ * @type {number }
299
+ */
300
+ set maxPixelRatio ( ratio ) {
301
+ this . _maxPixelRatio = ratio ;
302
+ this . resizeCanvas ( this . _width , this . _height ) ;
303
+ }
304
+
305
+ get maxPixelRatio ( ) {
306
+ return this . _maxPixelRatio ;
307
+ }
16
308
}
17
309
18
310
export { GraphicsDevice } ;
0 commit comments