From d35b238b9d251d35f9b15ec67a5a25c6de29e2d6 Mon Sep 17 00:00:00 2001 From: Elliott Thompson Date: Thu, 2 Mar 2023 16:02:12 +0000 Subject: [PATCH 01/14] add the active device type property to the engine --- src/platform/graphics/graphics-device.js | 7 +++++++ src/platform/graphics/webgl/webgl-graphics-device.js | 7 +++++-- src/platform/graphics/webgpu/webgpu-graphics-device.js | 3 ++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/platform/graphics/graphics-device.js b/src/platform/graphics/graphics-device.js index 2f4286c0c40..b98885f3b81 100644 --- a/src/platform/graphics/graphics-device.js +++ b/src/platform/graphics/graphics-device.js @@ -36,6 +36,13 @@ class GraphicsDevice extends EventHandler { */ isWebGPU = false; + /** + * The type of graphics device that the system could initialize. Can be one of pc.DEVICETYPE_WEBGL1, pc.DEVICETYPE_WEBGL2 or pc.DEVICETYPE_WEBGPU. + * + * @type {pc.DEVICETYPE_WEBGL1 | pc.DEVICETYPE_WEBGL2 | pc.DEVICETYPE_WEBGPU} + */ + activeDeviceType; + /** * The scope namespace for shader attributes and variables. * diff --git a/src/platform/graphics/webgl/webgl-graphics-device.js b/src/platform/graphics/webgl/webgl-graphics-device.js index c2ca41a8bb0..465bd750be2 100644 --- a/src/platform/graphics/webgl/webgl-graphics-device.js +++ b/src/platform/graphics/webgl/webgl-graphics-device.js @@ -20,7 +20,9 @@ import { UNIFORMTYPE_TEXTURE2D, UNIFORMTYPE_TEXTURECUBE, UNIFORMTYPE_FLOATARRAY, UNIFORMTYPE_TEXTURE2D_SHADOW, UNIFORMTYPE_TEXTURECUBE_SHADOW, UNIFORMTYPE_TEXTURE3D, UNIFORMTYPE_VEC2ARRAY, UNIFORMTYPE_VEC3ARRAY, UNIFORMTYPE_VEC4ARRAY, semanticToLocation, - PRIMITIVE_TRISTRIP + PRIMITIVE_TRISTRIP, + DEVICETYPE_WEBGL2, + DEVICETYPE_WEBGL1 } from '../constants.js'; import { GraphicsDevice } from '../graphics-device.js'; @@ -406,7 +408,8 @@ class WebglGraphicsDevice extends GraphicsDevice { gl = canvas.getContext(names[i], options); if (gl) { - this.webgl2 = (names[i] === 'webgl2'); + this.webgl2 = (names[i] === DEVICETYPE_WEBGL2); + this.activeDeviceType = (names[i] === DEVICETYPE_WEBGL2) ? DEVICETYPE_WEBGL2 : DEVICETYPE_WEBGL1; break; } } diff --git a/src/platform/graphics/webgpu/webgpu-graphics-device.js b/src/platform/graphics/webgpu/webgpu-graphics-device.js index 9faf7f6f71c..094a96fcc70 100644 --- a/src/platform/graphics/webgpu/webgpu-graphics-device.js +++ b/src/platform/graphics/webgpu/webgpu-graphics-device.js @@ -1,7 +1,7 @@ import { Debug, DebugHelper } from '../../../core/debug.js'; import { - PIXELFORMAT_RGBA32F, PIXELFORMAT_RGBA8, PIXELFORMAT_BGRA8, CULLFACE_BACK + PIXELFORMAT_RGBA32F, PIXELFORMAT_RGBA8, PIXELFORMAT_BGRA8, CULLFACE_BACK, DEVICETYPE_WEBGPU } from '../constants.js'; import { GraphicsDevice } from '../graphics-device.js'; import { RenderTarget } from '../render-target.js'; @@ -70,6 +70,7 @@ class WebgpuGraphicsDevice extends GraphicsDevice { constructor(canvas, options = {}) { super(canvas); this.isWebGPU = true; + this.activeDeviceType = DEVICETYPE_WEBGPU; // TODO: refactor as needed this.writeRed = true; From 061d0404b2725649de8e46b25a682058cc94242e Mon Sep 17 00:00:00 2001 From: Elliott Thompson Date: Thu, 2 Mar 2023 16:05:07 +0000 Subject: [PATCH 02/14] update the examples browser to support switching the device type --- examples/package-lock.json | 14 +-- examples/package.json | 2 +- examples/scripts/iframe/index.mustache | 4 +- examples/src/app/control-panel.tsx | 14 +-- examples/src/app/example.tsx | 118 +++++++++++++++++++++--- examples/src/app/helpers/formatters.mjs | 2 +- examples/src/static/styles.css | 31 +++++++ 7 files changed, 157 insertions(+), 28 deletions(-) diff --git a/examples/package-lock.json b/examples/package-lock.json index 674011be423..9949ffd0ad8 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -16,7 +16,7 @@ "@monaco-editor/react": "^4.4.5", "@playcanvas/eslint-config": "^1.1.1", "@playcanvas/observer": "1.3.6", - "@playcanvas/pcui": "^4.0.0", + "@playcanvas/pcui": "^4.0.3", "@rollup/plugin-alias": "^4.0.2", "@rollup/plugin-commonjs": "^22.0.0", "@rollup/plugin-node-resolve": "^13.3.0", @@ -372,9 +372,9 @@ "dev": true }, "node_modules/@playcanvas/pcui": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@playcanvas/pcui/-/pcui-4.0.0.tgz", - "integrity": "sha512-TG3VroX0TqMZSAKPazCCd3HtJamzcnKATljY+acTYSev8vv1jC5ZsjAXdlnS7xK39vDGooCs4kL5fWZf+PUK3A==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@playcanvas/pcui/-/pcui-4.0.3.tgz", + "integrity": "sha512-NuL/t+R7qF0ZrTX9m8Vx2i0LHo71N0SOYOf5ZmKq4sHKHYzK/SYTKFIIVgalbxgEsHog2YOAD6Rn2S1yOMX+PA==", "dev": true, "dependencies": { "@playcanvas/observer": "^1.3.6" @@ -5591,9 +5591,9 @@ "dev": true }, "@playcanvas/pcui": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@playcanvas/pcui/-/pcui-4.0.0.tgz", - "integrity": "sha512-TG3VroX0TqMZSAKPazCCd3HtJamzcnKATljY+acTYSev8vv1jC5ZsjAXdlnS7xK39vDGooCs4kL5fWZf+PUK3A==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@playcanvas/pcui/-/pcui-4.0.3.tgz", + "integrity": "sha512-NuL/t+R7qF0ZrTX9m8Vx2i0LHo71N0SOYOf5ZmKq4sHKHYzK/SYTKFIIVgalbxgEsHog2YOAD6Rn2S1yOMX+PA==", "dev": true, "requires": { "@playcanvas/observer": "^1.3.6" diff --git a/examples/package.json b/examples/package.json index 57abb0a7a51..a88151a3635 100644 --- a/examples/package.json +++ b/examples/package.json @@ -48,7 +48,7 @@ "@monaco-editor/react": "^4.4.5", "@playcanvas/eslint-config": "^1.1.1", "@playcanvas/observer": "1.3.6", - "@playcanvas/pcui": "^4.0.0", + "@playcanvas/pcui": "^4.0.3", "@rollup/plugin-alias": "^4.0.2", "@rollup/plugin-commonjs": "^22.0.0", "@rollup/plugin-node-resolve": "^13.3.0", diff --git a/examples/scripts/iframe/index.mustache b/examples/scripts/iframe/index.mustache index dbcfaec7255..81ab9364b82 100644 --- a/examples/scripts/iframe/index.mustache +++ b/examples/scripts/iframe/index.mustache @@ -62,7 +62,7 @@ presets: ["react", "typescript", "env"] }).code; } - window.exampleFunction = new Function('canvas', 'data', exampleFunction); + window.exampleFunction = new Function('canvas', 'deviceType', 'data', exampleFunction); } window.loadFunction = example.load; window.files = window.top.editedFiles || example.constructor.FILES; @@ -181,6 +181,8 @@ return data; } else if (arg === 'pcx') { return pcx; + } else if (arg === 'deviceType') { + return window.top.preferredGraphicsDevice || 'webgpu'; } }); window.exampleFunction.apply(this, args); diff --git a/examples/src/app/control-panel.tsx b/examples/src/app/control-panel.tsx index 40200eeb468..16dc323793b 100644 --- a/examples/src/app/control-panel.tsx +++ b/examples/src/app/control-panel.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState } from 'react'; import MonacoEditor from "@monaco-editor/react"; -import { Button, Container, Panel } from '@playcanvas/pcui/react'; +import { Button, Container } from '@playcanvas/pcui/react'; const ControlPanel = (props: any) => { const [state, setState] = useState({ @@ -17,8 +17,8 @@ const ControlPanel = (props: any) => { showCode: false, collapsed: false }); - document.getElementById('paramButton').classList.toggle('selected'); - document.getElementById('codeButton').classList.toggle('selected'); + document.getElementById('paramButton').classList.add('selected'); + document.getElementById('codeButton').classList.remove('selected'); const controls = document.getElementById('controlPanel-controls'); controls.classList.remove('pcui-hidden'); }; @@ -31,8 +31,8 @@ const ControlPanel = (props: any) => { showCode: true, collapsed: false }); - document.getElementById('paramButton').classList.toggle('selected'); - document.getElementById('codeButton').classList.toggle('selected'); + document.getElementById('paramButton').classList.remove('selected'); + document.getElementById('codeButton').classList.add('selected'); const controls = document.getElementById('controlPanel-controls'); controls.classList.add('pcui-hidden'); }; @@ -48,7 +48,7 @@ const ControlPanel = (props: any) => { } }); - return 600 && !props.controls ? 'empty' : 'null', window.top.innerWidth < 601 ? 'mobile' : null]} resizable='top' headerText={window.top.innerWidth < 601 ? (props.controls ? 'CODE & CONTROLS' : 'CODE') : 'CONTROLS'} collapsible={true} collapsed={state.collapsed}> + return { window.top.innerWidth < 601 && props.controls &&