Skip to content

Commit 5932dec

Browse files
mvaligurskyMartin Valigursky
andauthored
GraphicsDevice properties refactor (#4013)
* refactor * import typedef * missed debug log Co-authored-by: Martin Valigursky <[email protected]>
1 parent c2add69 commit 5932dec

File tree

6 files changed

+323
-277
lines changed

6 files changed

+323
-277
lines changed

src/deprecated/deprecated.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,10 @@ Object.keys(deprecatedChunks).forEach((chunkName) => {
435435
});
436436
});
437437

438+
VertexFormat.prototype.update = function () {
439+
Debug.deprecated('pc.VertexFormat.update is deprecated, and VertexFormat cannot be changed after it has been created.');
440+
};
441+
438442
Object.defineProperties(Texture.prototype, {
439443
rgbm: {
440444
get: function () {

src/graphics/graphics-device.js

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
11
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 */
216

317
/**
418
* The graphics device manages the underlying graphics context. It is responsible for submitting
@@ -9,10 +23,288 @@ import { EventHandler } from '../core/event-handler.js';
923
* @augments EventHandler
1024
*/
1125
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+
12153
// don't stringify GraphicsDevice to JSON by JSON.stringify
13154
toJSON(key) {
14155
return undefined;
15156
}
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+
}
16308
}
17309

18310
export { GraphicsDevice };

src/graphics/vertex-buffer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class VertexBuffer {
3030

3131
this.id = id++;
3232

33-
this.impl = graphicsDevice.createVertexBufferImpl(this);
33+
this.impl = graphicsDevice.createVertexBufferImpl(this, format);
3434

3535
// marks vertex buffer as instancing data
3636
this.instancing = false;

0 commit comments

Comments
 (0)