GPU Information in ElectronJS

ElectronJS is an Open Source Framework used for building Cross-Platform native desktop applications using web technologies such as HTML, CSS, and JavaScript which are capable of running on Windows, macOS, and Linux operating systems. It combines the Chromium engine and NodeJS into a Single Runtime.

GPU (Graphics Processing Unit) is a specialized programmable processor used for rendering all graphical content such as images on the computer’s screen. It is designed to rapidly manipulate and alter memory to accelerate the creation of images in a frame buffer intended for output on a display device. All modern Computer systems come with built-in GPU components i.e. they can either be a part of the motherboard circuitry or they can be another component altogether which is connected to the motherboard externally. Chromium extensively uses this GPU component when displaying GPU accelerated content. Chromium uses GPUs to accelerate web-page rendering, HTML, CSS, and other graphical elements within the browser. The latest versions of Chromium use the GPU component for video rendering and processing as well. GPU consumes less power than the CPU which reduces power consumption and generates less heat overall. GPU also helps in balancing the load on the CPU by resource-sharing, therefore, allowing the CPU to perform faster and take up heavier computational tasks. Chromium browsers have a dedicated GPU tab for monitoring and displaying all GPU related information in the system. It can be accessed by visiting the chrome://gpu/ page in the browser. The electron can also access and use this GPU related Information for the application by using the Instance events and methods of the app module. This tutorial will demonstrate how to fetch, display, and control GPU related Information in Electron. 

We assume that you are familiar with the prerequisites as covered in the above-mentioned link. For Electron to work, node and npm need to be pre-installed in the system.

  • Project Structure: 
     

Project Structure

Example: Follow the Steps given in Printing in ElectronJS to set up the basic Electron Application. Copy the Boilerplate code for the main.js file and the index.html file as provided in the article. Also, perform the necessary changes mentioned for the package.json file to launch the Electron Application. We will continue building our application using the same code base. The basic steps required to set up the Electron application remain the same. 
package.json: 



{
  "name": "electron-gpu",
  "version": "1.0.0",
  "description": "GPU Information in Electron",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "keywords": [
    "electron"
  ],
  "author": "Radhesh Khanna",
  "license": "ISC",
  "dependencies": {
    "electron": "^8.3.0"
  }
}

Output:

GPU Information in Electron: The app module is used to control the application’s event lifecycle. This module is part of the Main Process. To import and use the app module in the Renderer Process, we will be using Electron remote module.

  • index.html: Add the following snippet in that file. 

html

filter_none

edit
close

play_arrow

link
brightness_4
code

<h3>GPU Information in Electron</h3>
  <button id="metrics">
    Fetch App Metrics
  </button>
  <br><br>
  <button id="basic">
    Get Basic GPU Information
  </button>
  <br><br>
  <button id="complete">
    Get Complete GPU Information
  </button>
  <br><br>
  <button id="features">
    Get GPU Feature Status
  </button>

chevron_right


  • index.js: All the buttons created in the index.html will be used to display different bits of information relating to the GPU and the application. These buttons do not have any functionality associated with them yet. To change this, add the following code in the index.js file. 

javascript

filter_none

edit
close

play_arrow

link
brightness_4
code

const electron = require('electron')
// Importing the app module using Electron remote
const app = electron.remote.app;
  
app.on('gpu-info-update', () => {
    console.log('GPU Information has been Updated');
});
  
app.on('gpu-process-crashed', (event, killed) => {
    console.log('GPU Process has crashed');
    console.log(event);
    console.log('Whether GPU Process was killed - ', killed);
});
  
var metrics = document.getElementById('metrics');
metrics.addEventListener('click', () => {
    console.dir(app.getAppMetrics());
});
  
var basic = document.getElementById('basic');
basic.addEventListener('click', () => {
    app.getGPUInfo('basic').then(basicObj => {
        console.dir(basicObj);
    });
});
  
var complete = document.getElementById('complete');
complete.addEventListener('click', () => {
    app.getGPUInfo('complete').then(completeObj => {
        console.dir(completeObj);
    });
});
  
var features = document.getElementById('features');
features.addEventListener('click', () => {
    console.dir(app.getGPUFeatureStatus());
});

chevron_right


The app.getAppMetrics() Instance method of the app module is used to return an Array of ProcessMetric objects that correspond to memory and CPU usage statistics of all the processes associated with the application. The ProcessMetric object consists of the following parameters.

  • pid: Integer The Process ID (PID) of the process. Every process running within the application is represented by a separate ProcessMetric object within the array. This parameter is important because several Instance methods of the webFrame module use the PID as an input argument. This parameter is also important for debugging and checking the system metrics of the various ongoing processes within the native system OS that are associated with the application.
  • type: String This parameter represents the type of the process running within the application. This parameter can hold any one of the following values:
    • Browser
    • Tab
    • Utility
    • Zygote
    • Sandbox helper
    • GPU
    • Pepper Plugin
    • Pepper Plugin Broker
    • Unknown
  • cpu: Object This parameter returns a CPUUsage object which represents the CPU usage of the process. This object can also be obtained from the process.getCPUUsage() Instance method of the global Process object and behaves exactly in the same manner. For more detailed Information on the CPUUsage object and its behaviour, Refer to the article: Process Object in ElectronJS.
  • creationTime: Integer This parameter represents the creation time of the process. The time is represented as number of milliseconds since the epoch. This parameter can also be obtained from the process.getCreationTime() Instance method of the global Process object and behaves exactly in the same manner. For more detailed Information on the creationTime parameter and its behaviour, refer to the article: Process Object in ElectronJS
    Note: Since the PID can be reused again by the OS after a process dies, it is useful to use both the pid parameter and the creationTime parameter to uniquely identify and distinguish a process.
  • memory This parameter returns a MemoryInfo object which represents the Memory Information of the process. This object consists of detailed information of the memory being used on the actual physical RAM by the process. It consists of the following parameters. 
    • workingSetSize: Integer This parameter represents the amount of memory currently pinned to actual physical RAM by the process.
    • peakWorkingSetSize: Integer This parameter represents the maximum amount of memory that has ever been pinned to actual physical RAM by the process.
    • privateBytes: Integer (Optional) This parameter is supported in Windows OS only. This parameter represents the amount of memory not shared by other processes, such as V8 Engine Memory Heap or HTML content.
  • sandboxed: Boolean (Optional) This parameter is supported in Windows and macOS only. This parameter represents whether the process is sandboxed on the OS level.
  • integrityLevel: String (Optional) This parameter is supported in Windows OS only. This parameter can hold any one of the following values:
    • untrusted
    • low
    • medium
    • high
    • unknown

The app.getGPUFeatureStatus() Instance method of the app module returns a GPUFeatureStatus object. This object represents the Graphics Feature Status of the GPU from the chome://gpu page in the Chromium browser. 
 



Note: The GPUFeatureStatus object consists of the exact same parameters as shown in the above image. The values displayed for the parameters of the GPUFeatureStatus object are in abbreviated format and might differ from what is shown in the image. These parameters can hold any one of the following values with their respective color codes: 

  • disabled_software: Yellow Software only. Hardware acceleration is disabled.
  • disabled_off: Red
  • disabled_off_ok: Yellow
  • unavailable_software: Yellow Software only, hardware acceleration unavailable.
  • unavailable_off: Red
  • unavailable_off_ok: Yellow
  • enabled_readback: Yellow Hardware-accelerated but at reduced performance.
  • enabled_force: Green Hardware-accelerated on all pages.
  • enabled: Green Hardware accelerated.
  • enabled_on: Green
  • enabled_force_on: Green Force enabled.

The app.disableHardwareAcceleration() Instance method of the app module disables Hardware acceleration for the entire application. This Instance method can only be used before the ready event of the app module is emitted. Hence, this method needs to be called in the main.js file (Main Process). 

javascript

filter_none

edit
close

play_arrow

link
brightness_4
code

const { app, BrowserWindow } = require('electron')
app.disableHardwareAcceleration();

chevron_right


In an Electron application, Chromium disables 3D APIs (e.g. WebGL) until a restart of the application on a per-domain basis if the GPU processes crash too frequently. This is the default behaviour of Chromium. There can be a variety of reasons which can cause the GPU processes to crash frequently including problems in the System hardware or overuse of system resources. The app.disableDomainBlockingFor3DAPIs() Instance method of the app module disables this default behaviour of Chromium. This Instance method can only be used before the ready event of the app module is emitted. Hence, this method needs to be called in the main.js file (Main Process). 

javascript

filter_none

edit
close

play_arrow

link
brightness_4
code

const { app, BrowserWindow } = require('electron')
app.disableHardwareAcceleration();
app.disableDomainBlockingFor3DAPIs();

chevron_right


The app.getGPUInfo(info) Instance method fetches and returns the GPU Information from Chromium related to the Electron application. This Instance method returns a Promise and it is resolved to an object containing the relevant information based on the info: String parameter provided. Refer to the output for a better understanding. The info parameter can hold any one of the following values: 

  • complete: The Promise returned is fulfilled with an object containing all the GPU Information as mentioned in the official Chromium’s GPUInfo object documentation. This includes the version and driver information that’s shown on chrome://gpu page of the Chromium browser. When info: complete, the Instance method takes a much longer time to execute as compared to info: basic. Refer to the Output for better understanding. 
     
Output for GPU Driver and Version Information - 1

GPU Driver and Version Information – 1

  •  
Output for GPU Driver and Version Information - 2

GPU Driver and Version Information – 2

  • basic: The Promise returned is fulfilled with an object containing only a fewer and more essential parameters than the object returned when requested with info: complete. This value should be used if only basic information like vendorId parameter or driverId parameter is needed. The sample parameters returned are displayed below: 
{ auxAttributes:
   { amdSwitchable: true,
     canSupportThreadedTextureMailbox: false,
     directComposition: false,
     directRendering: true,
     glResetNotificationStrategy: 0,
     inProcessGpu: true,
     initializationTime: 0,
     jpegDecodeAcceleratorSupported: false,
     optimus: false,
     passthroughCmdDecoder: false,
     sandboxed: false,
     softwareRendering: false,
     supportsOverlays: false,
     videoDecodeAcceleratorFlags: 0 },
gpuDevice:
   [ { active: true, deviceId: 26657, vendorId: 4098 },
     { active: false, deviceId: 3366, vendorId: 32902 } ],
machineModelName: 'MacBookPro',
machineModelVersion: '11.5' }

The app module emits the following Instance Events which are related to the GPU

  • gpu-info-update: Event This Instance event is emitted whenever there is a change in any GPU related information for the different processes within the application. Based on the usage, functionality and the number of processes active within the application, this Instance event can be emitted multiple times.
  • gpu-process-crashed: Event This Instance event is emitted whenever the GPU process crashes or is killed by the native OS. This can cause the application to hang if not handled and hence we can use this Instance event to take necessary action and make the application exit cleanly. This event returns the following parameters.
    • event: Event The global Event object.
    • killed: Boolean This parameter represents whether the Process was killed.

At this point, upon launching the Electron application, we should be able to fetch and display all GPU related Information in the console output. 
Output: 

Note – We have used the console.dir() JavaScript method to output and display an object in the Console window of Chrome DevTools. To display objects, this method is preferred over the console.log() method. 

For more detailed information. Refer to the article: Difference between console.dir and console.log.

full-stack-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.