ServiceWorkerGlobalScope: message event - Web APIs

ServiceWorkerGlobalScope: message event
=======================================

 The **`message`** event of the `ServiceWorkerGlobalScope` interface occurs when incoming messages are received. Controlled pages can use the `ServiceWorker.postMessage()` method to send messages to service workers.
 The service worker can optionally send a response back via the `Client.postMessage()`, corresponding to the controlled page.

This event is not cancelable and does not bubble.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("message", (event) => {});

onmessage = (event) => {};
```

Event type
----------

An `ExtendableMessageEvent`. Inherits from `ExtendableEvent`.

Event

ExtendableEvent

ExtendableMessageEventEvent properties
----------------

*Inherits properties from its parent, `ExtendableEvent`*.

`ExtendableMessageEvent.data` Read only

Returns the event's data. It can be any data type. If dispatched in `messageerror` event, the property will be `null`.

`ExtendableMessageEvent.origin` Read only

Returns the origin of the `Client` that sent the message.

`ExtendableMessageEvent.lastEventId` Read only

Represents, in server-sent events, the last event ID of the event source.

`ExtendableMessageEvent.source` Read only

Returns a reference to the `Client` object that sent the message.

`ExtendableMessageEvent.ports` Read only

Returns the array containing the `MessagePort` objects representing the ports of the associated message channel.

Examples
--------

In the below example a page gets a handle to the `ServiceWorker` object via `ServiceWorkerRegistration.active`, and then calls its `postMessage()` function.

```js
// main.js
if (navigator.serviceWorker) {
  navigator.serviceWorker.register("service-worker.js");

  navigator.serviceWorker.addEventListener("message", (event) => {
    // event is a MessageEvent object
    console.log(`The service worker sent me a message: ${event.data}`);
  });

  navigator.serviceWorker.ready.then((registration) => {
    registration.active.postMessage("Hi service worker");
  });
}
```

The service worker can receive the message by listening to the `message` event:

```js
// service-worker.js
addEventListener("message", (event) => {
  // event is an ExtendableMessageEvent object
  console.log(`The client sent me a message: ${event.data}`);

  event.source.postMessage("Hi client");
});
```

Alternatively, the script can listen for the message using `onmessage`:

```js
// service-worker.js
self.onmessage = (event) => {
  // event is an ExtendableMessageEvent object
  console.log(`The client sent me a message: ${event.data}`);

  event.source.postMessage("Hi client");
};
```

Specifications
--------------

| Specification |
| --- |
| Service Workers # eventdef-serviceworkerglobalscope-message |
| Service Workers # dom-serviceworkerglobalscope-onmessage |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using Service Workers
* Service workers basic code example
* Using web workers


ServiceWorkerGlobalScope: messageerror event - Web APIs

ServiceWorkerGlobalScope: messageerror event
============================================

The **`messageerror`** event of the `ServiceWorkerGlobalScope` interface occurs when incoming messages can't be deserialized.

This event is not cancelable and does not bubble.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("messageerror", (event) => {});

onmessageerror = (event) => {};
```

Event type
----------

An `ExtendableMessageEvent`. Inherits from `ExtendableEvent`.

Event

ExtendableEvent

ExtendableMessageEventEvent properties
----------------

*Inherits properties from its parent, `ExtendableEvent`*.

`ExtendableMessageEvent.data` Read only

Returns the event's data. It can be any data type. If dispatched in `messageerror` event, the property will be `null`.

`ExtendableMessageEvent.origin` Read only

Returns the origin of the `Client` that sent the message.

`ExtendableMessageEvent.lastEventId` Read only

Represents, in server-sent events, the last event ID of the event source.

`ExtendableMessageEvent.source` Read only

Returns a reference to the `Client` object that sent the message.

`ExtendableMessageEvent.ports` Read only

Returns the array containing the `MessagePort` objects representing the ports of the associated message channel.

Examples
--------

In the below example a page gets a handle to the `ServiceWorker` object via `ServiceWorkerRegistration.active`, and then calls its `postMessage()` function.

```js
// main.js
if (navigator.serviceWorker) {
  navigator.serviceWorker.register("service-worker.js");

  navigator.serviceWorker.addEventListener("message", (event) => {
    // event is a MessageEvent object
    console.log(`The service worker sent me a message: ${event.data}`);
  });

  navigator.serviceWorker.ready.then((registration) => {
    registration.active.postMessage("Hi service worker");
  });
}
```

The service worker can listen for the message deserialization error by listening to the `messageerror` event:

```js
// service-worker.js
self.addEventListener("messageerror", (event) => {
  // event is an ExtendableMessageEvent object
  console.error("Message deserialization failed");
});
```

Alternatively, the script can listen for the message deserialization error using `onmessageerror`:

```js
// service-worker.js
self.onmessageerror = (event) => {
  // event is an ExtendableMessageEvent object
  console.error("Message deserialization failed");
};
```

Specifications
--------------

| Specification |
| --- |
| Service Workers # eventdef-serviceworkerglobalscope-messageerror |
| Service Workers # dom-serviceworkerglobalscope-onmessageerror |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `message`
* `ServiceWorker.postMessage()`
* Using Service Workers
* Service workers basic code example
* Using web workers


ServiceWorkerGlobalScope: registration property - Web APIs

ServiceWorkerGlobalScope: registration property
===============================================

The **`registration`** read-only property of the `ServiceWorkerGlobalScope` interface returns a reference to the `ServiceWorkerRegistration` object, which represents the service worker's registration.

Value
-----

A `ServiceWorkerRegistration` object.

Specifications
--------------

| Specification |
| --- |
| Service Workers # service-worker-global-scope-registration |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using Service Workers
* Service workers basic code example
* Using web workers


ServiceWorkerGlobalScope: push event - Web APIs

ServiceWorkerGlobalScope: push event
====================================

The **`push`** event is sent to a service worker's global scope (represented by the `ServiceWorkerGlobalScope` interface) when the service worker has received a push message.

This event is not cancelable and does not bubble.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("push", (event) => {});

onpush = (event) => {};
```

Event type
----------

A `PushEvent`. Inherits from `Event`.

Event

ExtendableEvent

PushEventEvent properties
----------------

*Inherits properties from its parent, `ExtendableEvent`. Additional properties:*

`PushEvent.data` Read only

Returns a reference to a `PushMessageData` object containing data sent to the `PushSubscription`.

Example
-------

This example sets up a handler for `push` events that takes JSON data, parses it, and dispatches the message for handling based on information contained within the message.

```js
self.addEventListener(
  "push",
  (event) => {
    let message = event.data.json();

    switch (message.type) {
      case "init":
        doInit();
        break;
      case "shutdown":
        doShutdown();
        break;
    }
  },
  false,
);
```

Specifications
--------------

| Specification |
| --- |
| Push API # extensions-to-the-serviceworkerglobalscope-interface |
| Push API # dom-serviceworkerglobalscope-onpush |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using the Push API
* `pushsubscriptionchange` event


ServiceWorkerGlobalScope: sync event - Web APIs

ServiceWorkerGlobalScope: sync event
====================================

The **`sync`** event of the `ServiceWorkerGlobalScope` interface is fired when the page (or worker) that registered the event with the `SyncManager` is running and as soon as network connectivity is available.

This event is not cancelable and does not bubble.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("sync", (event) => {});

onsync = (event) => {};
```

Event type
----------

A `SyncEvent`. Inherits from `ExtendableEvent` and `Event`.

Event

ExtendableEvent

SyncEventEvent properties
----------------

*Inherits properties from its ancestor, `ExtendableEvent` and `Event`*.

`SyncEvent.tag` Read only

Returns the developer-defined identifier for this `SyncEvent`.

`SyncEvent.lastChance` Read only

Returns `true` if the user agent will not make further synchronization attempts after the current attempt.

Examples
--------

The following example shows how to respond to a sync event in the service worker.

```js
self.addEventListener("sync", (event) => {
  if (event.tag === "sync-messages") {
    event.waitUntil(sendOutboxMessages());
  }
});
```

You can also set up the event handler using the `onsync` property:

```js
self.onsync = (event) => {
  // ...
};
```

Specifications
--------------

| Specification |
| --- |
| Web Background Synchronization # dom-serviceworkerglobalscope-onsync |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Richer offline experiences with the Periodic Background Sync API
* A Periodic Background Sync demo app


ServiceWorkerGlobalScope: skipWaiting() method - Web APIs

ServiceWorkerGlobalScope: skipWaiting() method
==============================================

The **`ServiceWorkerGlobalScope.skipWaiting()`** method of the `ServiceWorkerGlobalScope` forces the waiting service worker to become the active service worker.

Use this method with `Clients.claim()` to ensure that updates to the underlying service worker take effect immediately for both the current client and all other active clients.

Syntax
------

```js
skipWaiting()
```

### Parameters

None.

### Return value

A `Promise` that resolves with `undefined` after trying to activate the newly installed service worker.

Examples
--------

While `self.skipWaiting()` can be called at any point during the service worker's execution, it will only have an effect if there's a newly installed service worker that might otherwise remain in the `waiting` state. Therefore, it's common to call `self.skipWaiting()` from inside of an `InstallEvent` handler.

The following example causes a newly installed service worker to progress into the `activating` state, regardless of whether there is already an active service worker.

```js
self.addEventListener("install", (event) => {
  // The promise that skipWaiting() returns can be safely ignored.
  self.skipWaiting();

  // Perform any other actions required for your
  // service worker to install, potentially inside
  // of event.waitUntil();
});
```

Specifications
--------------

| Specification |
| --- |
| Service Workers # service-worker-global-scope-skipwaiting |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using Service Workers
* Service workers basic code example
* `Clients.claim()`
* Using web workers


ServiceWorkerGlobalScope: paymentrequest event - Web APIs

ServiceWorkerGlobalScope: paymentrequest event
==============================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`paymentrequest`** event of the `ServiceWorkerGlobalScope` interface is fired on a payment app when a payment flow has been initiated on the merchant website via the `PaymentRequest.show()` method.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("paymentrequest", (event) => {});

onpaymentrequest = (event) => {};
```

Event type
----------

A `PaymentRequestEvent`. Inherits from `ExtendableEvent`.

Event

ExtendableEvent

PaymentRequestEventExamples
--------

When the `PaymentRequest.show()` method is invoked, a `paymentrequest` event is fired on the service worker of the payment app. This event is listened for inside the payment app's service worker to begin the next stage of the payment process.

```js
let payment_request_event;
let resolver;
let client;

// `self` is the global object in service worker
self.addEventListener("paymentrequest", async (e) => {
  if (payment_request_event) {
    // If there's an ongoing payment transaction, reject it.
    resolver.reject();
  }
  // Preserve the event for future use
  payment_request_event = e;

  // ...
});
```

When a `paymentrequest` event is received, the payment app can open a payment handler window by calling `PaymentRequestEvent.openWindow()`. The payment handler window will present the customers with a payment app interface where they can authenticate, choose shipping address and options, and authorize the payment.

When the payment has been handled, `PaymentRequestEvent.respondWith()` is used to pass the payment result back to the merchant website.

See Receive a payment request event from the merchant for more details of this stage.

Specifications
--------------

| Specification |
| --- |
| Payment Handler API # the-paymentrequestevent |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Payment Handler API
* Web-based payment apps overview
* Setting up a payment method
* Life of a payment transaction
* Using the Payment Request API
* Payment processing concepts


ServiceWorkerGlobalScope: fetch event - Web APIs

ServiceWorkerGlobalScope: fetch event
=====================================

The **`fetch`** event is fired in the service worker's global scope when the main app thread makes a network request. It enables the service worker to intercept network requests and send customized responses (for example, from a local cache).

This event is not cancelable and does not bubble.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("fetch", (event) => {});

onfetch = (event) => {};
```

Description
-----------

The `fetch` event is fired in the service worker's global scope when the main app thread makes a network request. This includes not only explicit `fetch()` calls from the main thread, but also implicit network requests to load pages and subresources (such as JavaScript, CSS, and images) made by the browser following page navigation.

The event handler is passed a `FetchEvent` object, which provides access to the request as a `Request` instance.

 The `FetchEvent` also provides a `respondWith()` method, that takes a `Response` (or a `Promise` that resolves to a `Response`) as a parameter.
 This enables the service worker event handler to provide the response that is returned to the request in the main thread.

For example, the service worker can return:

* A locally cached response retrieved from the `Cache` interface.
* A response that the service worker synthesizes, using methods like `Response.json()` or the `Response()` constructor.
* A network error, using the `Response.error()` method. This will cause the `fetch()` call to reject.

The `respondWith()` method can only be called once for a given request. If multiple `fetch` event listeners are added, they will be called in the order they were registered until one of them calls `respondWith()`.

The `respondWith()` method must be called synchronously: that is, you can't call it in a `then` handler.

Typically, a `fetch` event handler will execute different strategies depending on features of the request such as its URL:

```js
function strategy1() {
  return fetch("picnic.jpg");
}

function strategy2() {
  return Response.error();
}

const pattern1 = /^\/salamander/;
const pattern2 = /^\/lizard/;

self.addEventListener("fetch", (event) => {
  const url = new URL(event.request.url);
  if (pattern1.test(url.pathname)) {
    event.respondWith(strategy1());
  } else if (pattern2.test(url.pathname)) {
    event.respondWith(strategy2());
  }
});
```

 If `respondWith()` is not called in the handler, then the user agent automatically makes the original network request.
 For example, in the code above, all requests that do not match `pattern1` or `pattern2` are made as if the service worker did not exist.

Event type
----------

A `FetchEvent`.

Examples
--------

### Cache falling back to network

This `fetch` event handler first tries to find the response in the cache. If a response is found, it returns the cached response. Otherwise, it tries to fetch the resource from the network.

```js
async function cacheThenNetwork(request) {
  const cachedResponse = await caches.match(request);
  if (cachedResponse) {
    console.log("Found response in cache:", cachedResponse);
    return cachedResponse;
  }
  console.log("Falling back to network");
  return fetch(request);
}

self.addEventListener("fetch", (event) => {
  console.log(`Handling fetch event for ${event.request.url}`);
  event.respondWith(cacheThenNetwork(event.request));
});
```

### Cache only

 This `fetch` event handler implements a "cache only" policy for scripts and stylesheets. If the request's `destination` property is `"script"` or `"style"`, the handler only looks in the cache, returning an error if the response was not found.
 All other requests go through to the network.

```js
async function cacheOnly(request) {
  const cachedResponse = await caches.match(request);
  if (cachedResponse) {
    console.log("Found response in cache:", cachedResponse);
    return cachedResponse;
  }
  return Response.error();
}

self.addEventListener("fetch", (event) => {
  if (
    event.request.destination === "script" ||
    event.request.destination === "style"
  ) {
    event.respondWith(cacheOnly(event.request));
  }
});
```

Specifications
--------------

| Specification |
| --- |
| Service Workers # dom-serviceworkerglobalscope-onfetch |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using Service Workers
* Service workers basic code example
* `fetch()` method
* `Request` interface
* `Response` interface


ServiceWorkerGlobalScope: backgroundfetchabort event - Web APIs

ServiceWorkerGlobalScope: backgroundfetchabort event
====================================================

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`backgroundfetchabort`** event of the `ServiceWorkerGlobalScope` interface is fired when the user or the app itself cancels a background fetch operation.

This event is not cancelable and does not bubble.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("backgroundfetchabort", (event) => {});

onbackgroundfetchabort = (event) => {};
```

Event type
----------

A `BackgroundFetchEvent`.

Event

ExtendableEvent

BackgroundFetchEventEvent properties
----------------

*Inherits properties from its parent, `ExtendableEvent`.*

`BackgroundFetchEvent.registration`

Returns the `BackgroundFetchRegistration` for the aborted fetch.

Description
-----------

In the background fetch API, the browser shows a UI element to the user to indicate the progress of the operation. This element also enables the user to cancel the fetch. The app itself can also cancel the fetch by calling `BackgroundFetchRegistration.abort()`.

If the fetch is canceled, the browser aborts the fetch, starts the service worker, if necessary, and fires the `backgroundfetchabort` event in the service worker's global scope.

In the handler for this event, the service worker can clean up any related data for the operation. It can also retrieve and store any successful responses (for example, using the `Cache` API). To access the response data, the service worker uses the event's `registration` property.

Examples
--------

### Cleaning up

This event handler might perform any cleanup of data associated with the aborted fetch.

```js
addEventListener("backgroundfetchabort", (event) => {
  // clean up any related data
});
```

Specifications
--------------

| Specification |
| --- |
| Background Fetch # dom-serviceworkerglobalscope-onbackgroundfetchabort |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Background Fetch API


ServiceWorkerGlobalScope: backgroundfetchsuccess event - Web APIs

ServiceWorkerGlobalScope: backgroundfetchsuccess event
======================================================

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`backgroundfetchsuccess`** event of the `ServiceWorkerGlobalScope` interface is fired when a background fetch operation has completed successfully: that is, when all network requests in the fetch have completed successfully.

This event is not cancelable and does not bubble.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("backgroundfetchsuccess", (event) => {});

onbackgroundfetchsuccess = (event) => {};
```

Event type
----------

A `BackgroundFetchUpdateUIEvent`.

Event

ExtendableEvent

BackgroundFetchEvent

BackgroundFetchUpdateUIEventEvent properties
----------------

*Inherits properties from its parent, `BackgroundFetchEvent`.*

`BackgroundFetchUpdateUIEvent.updateUI()`

Updates the UI of the element that the browser displays to show the progress of the fetch operation.

Description
-----------

When a background fetch operation completes successfully (meaning that all individual network requests have completed successfully), the browser starts the service worker, if necessary, and fires the `backgroundfetchsuccess` event in the service worker's global scope.

In the handler for this event, the service worker can retrieve and store the responses (for example, using the `Cache` API). To access the response data, the service worker uses the event's `registration` property.

In the background fetch API, the browser shows a UI element to the user to indicate the progress of the operation. In the `backgroundfetchsuccess` handler, the service worker can update that UI to show that the operation has completed successfully. To do this, the handler calls the event's `updateUI()` method, passing in a new title and/or icons.

Examples
--------

### Storing responses and updating UI

This event handler stores all responses in the cache, and updates the UI.

```js
addEventListener("backgroundfetchsuccess", (event) => {
  const registration = event.registration;

  event.waitUntil(async () => {
    // Open a cache
    const cache = await caches.open("movies");
    // Get all the records
    const records = await registration.matchAll();
    // Cache all responses
    const cachePromises = records.map(async (record) => {
      const response = await record.responseReady;
      await cache.put(record.request, response);
    });

    // Wait for caching to finish
    await Promise.all(cachePromises);

    // Update the browser's UI
    event.updateUI({ title: "Move download complete" });
  });
});
```

Specifications
--------------

| Specification |
| --- |
| Background Fetch # dom-serviceworkerglobalscope-onbackgroundfetchsuccess |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Background Fetch API


ServiceWorkerGlobalScope: notificationclick event - Web APIs

ServiceWorkerGlobalScope: notificationclick event
=================================================

The **`notificationclick`** event is fired to indicate that a system notification spawned by `ServiceWorkerRegistration.showNotification()` has been clicked.

This event is not cancelable and does not bubble.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("notificationclick", (event) => {});

onnotificationclick = (event) => {};
```

Event type
----------

A `NotificationEvent`. Inherits from `Event`.

Event

ExtendableEvent

NotificationEventEvent properties
----------------

*Inherits properties from its ancestor, `Event`*.

`NotificationEvent.notification` Read only

Returns a `Notification` object representing the notification that was clicked to fire the event.

`NotificationEvent.action` Read only

Returns the string ID of the notification button the user clicked. This value returns an empty string if the user clicked the notification somewhere other than an action button, or the notification does not have a button.

Examples
--------

You can use the `notificationclick` event in an `addEventListener` method:

```js
self.addEventListener("notificationclick", (event) => {
  console.log("On notification click: ", event.notification.tag);
  event.notification.close();

  // This looks to see if the current is already open and
  // focuses if it is
  event.waitUntil(
    clients
      .matchAll({
        type: "window",
      })
      .then((clientList) => {
        for (const client of clientList) {
          if (client.url === "/" && "focus" in client) return client.focus();
        }
        if (clients.openWindow) return clients.openWindow("/");
      }),
  );
});
```

Or use the `onnotificationclick` event handler property:

```js
self.onnotificationclick = (event) => {
  console.log("On notification click: ", event.notification.tag);
  event.notification.close();

  // This looks to see if the current is already open and
  // focuses if it is
  event.waitUntil(
    clients
      .matchAll({
        type: "window",
      })
      .then((clientList) => {
        for (const client of clientList) {
          if (client.url === "/" && "focus" in client) return client.focus();
        }
        if (clients.openWindow) return clients.openWindow("/");
      }),
  );
};
```

You can handle event actions using `event.action` within a `notificationclick` event handler:

```js
navigator.serviceWorker.register("sw.js");
Notification.requestPermission().then((result) => {
  if (result === "granted") {
    navigator.serviceWorker.ready.then((registration) => {
      // Show a notification that includes an action titled Archive.
      registration.showNotification("New mail from Alice", {
        actions: [
          {
            action: "archive",
            title: "Archive",
          },
        ],
      });
    });
  }
});

self.addEventListener(
  "notificationclick",
  (event) => {
    event.notification.close();
    if (event.action === "archive") {
      // User selected the Archive action.
      archiveEmail();
    } else {
      // User selected (e.g., clicked in) the main body of notification.
      clients.openWindow("/inbox");
    }
  },
  false,
);
```

Specifications
--------------

| Specification |
| --- |
| Notifications API Standard # activating-a-notification |
| Notifications API Standard # dom-serviceworkerglobalscope-onnotificationclick |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Service Worker API
* Notifications API


Guide to the Fullscreen API - Web APIs

Guide to the Fullscreen API
===========================

This article demonstrates how to use the Fullscreen API to place a given element into fullscreen mode, as well as how to detect when the browser enters or exits fullscreen mode.

Activating fullscreen mode
--------------------------

Given an element that you'd like to present in fullscreen mode (such as a `<video>`, for example), you can present it in fullscreen mode by calling its `requestFullscreen()` method.

Let's consider this `<video>` element:

```html
<video controls id="myvideo">
  <source src="somevideo.webm"></source>
  <source src="somevideo.mp4"></source>
</video>
```

We can put that video into fullscreen mode as follows:

```js
const elem = document.getElementById("myvideo");
if (elem.requestFullscreen) {
  elem.requestFullscreen();
}
```

This code checks for the existence of the `requestFullscreen()` method before calling it.

### Notification

When fullscreen mode is successfully engaged, the document which contains the element receives a `fullscreenchange` event. When fullscreen mode is exited, the document again receives a `fullscreenchange` event. Note that the `fullscreenchange` event doesn't provide any information itself as to whether the document is entering or exiting fullscreen mode, but if the document has a non null `fullscreenElement`, you know you're in fullscreen mode.

### When a fullscreen request fails

It's not guaranteed that you'll be able to switch into fullscreen mode. For example, `<iframe>` elements have the `allowfullscreen` attribute in order to opt-in to allowing their content to be displayed in fullscreen mode. In addition, certain kinds of content, such as windowed plug-ins, cannot be presented in fullscreen mode. Attempting to put an element which can't be displayed in fullscreen mode (or the parent or descendant of such an element) won't work. Instead, the element which requested fullscreen will receive a `mozfullscreenerror` event. When a fullscreen request fails, Firefox will log an error message to the Web Console explaining why the request failed. In Chrome and newer versions of Opera however, no such warning is generated.

**Note:** Fullscreen requests need to be called from within an event handler or otherwise they will be denied.

Getting out of full screen mode
-------------------------------

The user always has the ability to exit fullscreen mode of their own accord; see Things your users want to know. You can also do so programmatically by calling the `Document.exitFullscreen()` method.

Other information
-----------------

The `Document` provides some additional information that can be useful when developing fullscreen web applications:

`Document.fullscreenElement` / `ShadowRoot.fullscreenElement`

The `fullscreenElement` property tells you the `Element` that's currently being displayed fullscreen. If this is non-null, the document (or shadow DOM) is in fullscreen mode. If this is null, the document (or shadow DOM) is not in fullscreen mode.

`Document.fullscreenEnabled`

The `fullscreenEnabled` property tells you whether or not the document is currently in a state that would allow fullscreen mode to be requested.

### Viewport scaling in mobile browsers

Some mobile browsers while in fullscreen mode ignore viewport meta-tag settings and block user scaling; for example: a "pinch to zoom" gesture may not work on a page presented in fullscreen mode — even if, when not in fullscreen mode, the page can be scaled using pinch to zoom.

Things your users want to know
------------------------------

You'll want to be sure to let your users know that they can press the `Esc` key (or `F11`) to exit fullscreen mode.

In addition, navigating to another page, changing tabs, or switching to another application (using, for example, `Alt`-`Tab`) while in fullscreen mode exits fullscreen mode as well.

Example
-------

In this example, a video is presented in a web page. Pressing the `Return` or `Enter` key lets the user toggle between windowed and fullscreen presentation of the video.

View Live Examples

### Watching for the Enter key

When the page is loaded, this code is run to set up an event listener to watch for the `Enter` key.

```js
document.addEventListener(
  "keydown",
  (e) => {
    if (e.key === "Enter") {
      toggleFullScreen();
    }
  },
  false,
);
```

### Toggling fullscreen mode

This code is called when the user hits the `Enter` key, as seen above.

```js
function toggleFullScreen() {
  if (!document.fullscreenElement) {
    document.documentElement.requestFullscreen();
  } else if (document.exitFullscreen) {
    document.exitFullscreen();
  }
}
```

This starts by looking at the value of the `fullscreenElement` attribute on the `document`. If it's `null`, the document is currently in windowed mode, so we need to switch to fullscreen mode. Switching to fullscreen mode is done by calling `element.requestFullscreen()`.

If fullscreen mode is already active (`fullscreenElement` is non-`null`), we call `document.exitFullscreen()`.

Prefixing
---------

For the moment not all browsers are implementing the unprefixed version of the API (for vendor agnostic access to the Fullscreen API you can use Fscreen). Here is the table summarizing the prefixes and name differences between them:

| Standard | WebKit (Safari) / Blink (Chrome & Opera) / Edge | Gecko (Firefox) | Internet Explorer |
| --- | --- | --- | --- |
| `Document.fullscreen`
Deprecated
 | `webkitIsFullScreen` | `mozFullScreen` | - |
| `Document.fullscreenEnabled` | `webkitFullscreenEnabled` | `mozFullScreenEnabled` | `msFullscreenEnabled` |
| `Document.fullscreenElement` | `webkitFullscreenElement` | `mozFullScreenElement` | `msFullscreenElement` |
| `Document.exitFullscreen()` | `webkitExitFullscreen()` | `mozCancelFullScreen()` | `msExitFullscreen()` |
| `Element.requestFullscreen()` | `webkitRequestFullscreen()` | `mozRequestFullScreen()` | `msRequestFullscreen()` |

Specifications
--------------

| Specification |
| --- |
| Fullscreen API Standard # ref-for-dom-document-fullscreenenabled① |
| Fullscreen API Standard # dom-document-fullscreen |

Browser compatibility
---------------------

### api.Document.fullscreenEnabled

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### api.Document.fullscreen

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using fullscreen mode
* `Element.requestFullscreen()`
* `Document.exitFullscreen()`
* `Document.fullscreen`
* `Document.fullscreenElement`
* `:fullscreen`, `::backdrop`
* `allowfullscreen`


GPUDevice: limits property - Web APIs

GPUDevice: limits property
==========================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`limits`** read-only property of the
 `GPUDevice` interface returns a `GPUSupportedLimits` object that describes the limits supported by the device. All limit values will be included, and the limits requested during the creation of the device (i.e. when `GPUAdapter.requestDevice()` is called) will be reflected in those values.

**Note:** Not all limits will be reported as expected, even if they are supported by the underlying hardware. See `GPUAdapter.limits` for more details.

Value
-----

A `GPUSupportedLimits` object instance.

Examples
--------

In the following code we query the `GPUAdapter.limits` value of `maxBindGroups` to see if it is equal to or greater than 6. Our theoretical example app ideally needs 6 bind groups, so if the returned value is >= 6, we add a maximum limit of 6 to the `requiredLimits` object.

We then check that the expected limit has been set on the resulting device by logging its value to the console.

```js
async function init() {
  if (!navigator.gpu) {
    throw Error("WebGPU not supported.");
  }

  const adapter = await navigator.gpu.requestAdapter();
  if (!adapter) {
    throw Error("Couldn't request WebGPU adapter.");
  }

  const requiredLimits = {};

  // App ideally needs 6 bind groups, so we'll try to request what the app needs
  if (adapter.limits.maxBindGroups >= 6) {
    requiredLimits.maxBindGroups = 6;
  }

  const device = await adapter.requestDevice({
    requiredLimits,
  });

  console.log(device.limits.maxBindGroups);

  // ...
}
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-limits |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: createQuerySet() method - Web APIs

GPUDevice: createQuerySet() method
==================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`createQuerySet()`** method of the
 `GPUDevice` interface creates a `GPUQuerySet` that can be used to record the results of queries on passes, such as occlusion or timestamp queries.

Syntax
------

```js
createQuerySet(descriptor)
```

### Parameters

`descriptor`

An object containing the following properties:

`count`

A number specifying the number of queries to be managed by the resulting `GPUQuerySet`.

`label` Optional

A string providing a label that can be used to identify the object, for example in `GPUError` messages or console warnings.

`type`

An enumerated value specifying the type of queries to be managed by the resulting `GPUQuerySet`. Possible values are:

`"occlusion"`

Occlusion queries are available on render passes to query the number of fragment samples that pass all the per-fragment tests for a set of drawing commands (including scissor, sample mask, alpha to coverage, stencil, and depth tests). To run an occlusion query, an appropriate `GPUQuerySet` must be provided as the value of the `occlusionQuerySet` descriptor property when invoking `GPUCommandEncoder.beginRenderPass()` to run a render pass.

`"timestamp"`

Timestamp queries allow applications to write timestamps to a `GPUQuerySet`. To run a timestamp query, appropriate `GPUQuerySet`s must be provided inside the value of the `timestampWrites` descriptor property when invoking `GPUCommandEncoder.beginRenderPass()` to run a render pass, or `GPUCommandEncoder.beginComputePass()` to run a compute pass. Alternatively, you can run a single timestamp query at any time by invoking `GPUCommandEncoder.writeTimeStamp()` with an appropriate `GPUQuerySet` as a parameter.

To use timestamp queries, the `timestamp-query` feature must be enabled in the `GPUDevice`.

### Return value

A `GPUQuerySet` object instance.

### Validation

The following criteria must be met when calling **`createQuerySet()`**, otherwise a `GPUValidationError` is generated and an invalid `GPUQuerySet` object is returned:

* `count` is less than or equal to 4096.
Examples
--------

The following snippet creates a `GPUQuerySet` that holds 32 occlusion query results:

```js
const querySet = device.createQuerySet({
  type: "occlusion",
  count: 32,
});
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-createqueryset |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: popErrorScope() method - Web APIs

GPUDevice: popErrorScope() method
=================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`popErrorScope()`** method of the
 `GPUDevice` interface pops an existing GPU error scope from the error scope stack (originally pushed using `GPUDevice.pushErrorScope()`) and returns a `Promise` that resolves to an object describing the first error captured in the scope, or `null` if no error occurred.

Syntax
------

```js
popErrorScope()
```

### Parameters

None.

### Return value

a `Promise` that resolves to an object describing the first error captured in the scope. This can be of type:

* `GPUInternalError`
* `GPUOutOfMemoryError`
* `GPUValidationError`

If no error occurred, it resolves to `null`.

Examples
--------

The following example uses an error scope to capture a suspected validation error, logging it to the console.

```js
device.pushErrorScope("validation");

let sampler = device.createSampler({
  maxAnisotropy: 0, // Invalid, maxAnisotropy must be at least 1.
});

device.popErrorScope().then((error) => {
  if (error) {
    sampler = null;
    console.error(`An error occurred while creating sampler: ${error.message}`);
  }
});
```

See WebGPU Error Handling best practices for a lot more examples and information.

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-poperrorscope |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: createComputePipeline() method - Web APIs

GPUDevice: createComputePipeline() method
=========================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`createComputePipeline()`** method of the
 `GPUDevice` interface creates a `GPUComputePipeline` that can control the compute shader stage and be used in a `GPUComputePassEncoder`.

Syntax
------

```js
createComputePipeline(descriptor)
```

### Parameters

`descriptor`

An object containing the following properties:

`compute`

An object describing the compute shader entry point of the pipeline. This object can contain the following properties:

`constants` Optional

A sequence of record types, with the structure `(id, value)`, representing override values for WGSL constants that can be overridden in the pipeline. These behave like ordered maps. In each case, the `id` is a key used to identify or select the record, and the `constant` is an enumerated value representing a WGSL.

Depending on which constant you want to override, the `id` may take the form of the numeric ID of the constant, if one is specified, or otherwise the constant's identifier name.

A code snippet providing override values for several overridable constants might look like this:

```js
{
  // ...
  constants: {
    0: false,
    1200: 3.0,
    1300: 2.0,
    width: 20,
    depth: -1,
    height: 15,
  }
}
```

`entryPoint`

The name of the function in the `module` that this stage will use to perform its work. The corresponding shader function must have the `@compute` attribute to be identified as this entry point. See Entry Point Declaration for more information.

`module`

A `GPUShaderModule` object containing the WGSL code that this programmable stage will execute.

`label` Optional

A string providing a label that can be used to identify the object, for example in `GPUError` messages or console warnings.

`layout`

Defines the layout (structure, purpose, and type) of all the GPU resources (buffers, textures, etc.) used during the execution of the pipeline. Possible values are:

* A `GPUPipelineLayout` object, created using `GPUDevice.createPipelineLayout()`, which allows the GPU to figure out how to run the pipeline most efficiently ahead of time.
* A string of `"auto"`, which causes the pipeline to generate an implicit bind group layout based on any bindings defined in the shader code. If `"auto"` is used, the generated bind group layouts may only be used with the current pipeline.

### Return value

A `GPUComputePipeline` object instance.

### Validation

The following criteria must be met when calling **`createComputePipeline()`**, otherwise a `GPUValidationError` is generated and an invalid `GPUComputePipeline` object is returned:

* The workgroup storage size used by the `module` referenced inside the `compute` property is less than or equal to the `GPUDevice`'s `maxComputeWorkgroupStorageSize` limit.
* The `module` uses a number of compute invocations per workgroup less than or equal to the `GPUDevice`'s `maxComputeInvocationsPerWorkgroup` limit.
* The `module`'s workgroup size is less than or equal to the `GPUDevice`'s corresponding `maxComputeWorkgroupSizeX`, `maxComputeWorkgroupSizeY`, or `maxComputeWorkgroupSizeZ` limit.
Examples
--------

**Note:** The WebGPU samples feature many more examples.

### Basic example

Our basic compute demo shows a process of:

* Creating a bind group layout with `GPUDevice.createBindGroupLayout()`.
* Feeding the `bindGroupLayout` into `GPUDevice.createPipelineLayout()` to create a `GPUPipelineLayout`.
* Using that value immediately in a `createComputePipeline()` call to create a `GPUComputePipeline`.

```js
// ...

const bindGroupLayout = device.createBindGroupLayout({
  entries: [
    {
      binding: 0,
      visibility: GPUShaderStage.COMPUTE,
      buffer: {
        type: "storage",
      },
    },
  ],
});

const computePipeline = device.createComputePipeline({
  layout: device.createPipelineLayout({
    bindGroupLayouts: [bindGroupLayout],
  }),
  compute: {
    module: shaderModule,
    entryPoint: "main",
  },
});

// ...
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-createcomputepipeline |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: createBindGroupLayout() method - Web APIs

GPUDevice: createBindGroupLayout() method
=========================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`createBindGroupLayout()`** method of the
 `GPUDevice` interface creates a `GPUBindGroupLayout` that defines the structure and purpose of related GPU resources such as buffers that will be used in a pipeline, and is used as a template when creating `GPUBindGroup`s.

Syntax
------

```js
createBindGroupLayout(descriptor)
```

### Parameters

`descriptor`

An object containing the following properties:

`entries`

An array of entry objects, each one of which describes a single shader resource binding to be included in the `GPUBindGroupLayout`. Each entry will correspond to an entry defined in a `GPUBindGroup` (created via a `GPUDevice.createBindGroup()` call) that uses this `GPUBindGroupLayout` object as a template.

`label` Optional

A string providing a label that can be used to identify the object, for example in `GPUError` messages or console warnings.

### Entry objects

An entry object includes the following properties:

`binding`

A number representing a unique identifier for this particular entry, which matches the `binding` value of a corresponding `GPUBindGroup` entry. In addition, it matches the `n` index value of the corresponding `@binding(n)` attribute in the shader (`GPUShaderModule`) used in the related pipeline.

`visibility`

One or more bitwise flags defining the shader stages that a `GPUBindGroup` entry corresponding to this entry will be visible to. Possible values are:

* `GPUShaderStage.COMPUTE`: The bind group entry will be accessible to compute shaders.
* `GPUShaderStage.FRAGMENT`: The bind group entry will be accessible to fragment shaders.
* `GPUShaderStage.VERTEX`: The bind group entry will be accessible to vertex shaders.

Note that multiple stages can be specified by separating values with pipe symbols, for example:

```js
visibility: GPUShaderStage.FRAGMENT | GPUShaderStage.VERTEX;
```

"Resource layout object"

An object that defines the required binding resource type and structure of the `GPUBindGroup` entry corresponding to this entry. This property can be one of `buffer`, `externalTexture`, `sampler`, `storageTexture`, or `texture`, the object structures of which are described in the next section.

### Resource layout objects

The resource layout object can be one of the following (see also `GPUDevice.createBindGroup()` for details of how the required resources for each entry are structured):

* `buffer`: Indicates that the corresponding `GPUBindGroup` entry will be a `GPUBufferBinding` object, which contains a `GPUBuffer` plus `offset` and `size` values. A `buffer` resource layout object can contain the following properties:

`hasDynamicOffset` Optional

A boolean. If set to `true`, it indicates that this binding requires a dynamic offset, for example as set during a `GPURenderPassEncoder.setBindGroup()` call. If omitted, `hasDynamicOffset` defaults to `false`.

`minBindingSize` Optional

A number indicating the minimum allowed size, in bytes, of bound buffers. If omitted, `minBindingSize` defaults to 0. If the value is 0, minimum buffer size is ignored during pipeline creation and is instead validated by issued draw/dispatch commands.

`type` Optional

An enumerated value specifying the required type for `GPUBuffer`s bound to this binding (see `GPUDevice.createBuffer()` for more information on buffer types). Possible values are:

    + `"read-only-storage"`: A read-only buffer created with a `usage` of `GPUBufferUsage.STORAGE`.
    + `"storage"`: A writable buffer created with a `usage` of `GPUBufferUsage.STORAGE`.
    + `"uniform"`: A buffer created with a `usage` of `GPUBufferUsage.UNIFORM`.
If omitted, `type` defaults to `"uniform"`.
* `externalTexture`: Indicates that the corresponding `GPUBindGroup` entry will be a `GPUExternalTexture` object. An `externalTexture` resource layout object is empty — `{}`.
* `sampler`: Indicates that the corresponding `GPUBindGroup` entry will be a `GPUSampler` object. A `sampler` resource layout object can contain the following properties:

`type` Optional

An enumerated value specifying the required type for `GPUSampler`s bound to this binding (see `GPUDevice.createSampler()` for more information on sampler types). Possible values are:

    + `"comparison"`: A comparison sampler.
    + `"filtering"`: A filtering sampler.
    + `"non-filtering"`: A non-filtering sampler.
If omitted, `type` defaults to `"filtering"`.
* `storageTexture`: Indicates that the corresponding `GPUBindGroup` entry will be a `GPUTextureView` object. A `storageTexture` resource layout object can contain the following properties:

`access` Optional

An enumerated value specifying whether texture views bound to this binding will be bound for read and/or write access. Possible values are currently `"write-only"` and `undefined`, with the intention to add more access modes in the future. If omitted, the default value is `"write-only"`.

`format`

An enumerated value specifying the required format of texture views bound to this binding. See the specification's Texture Formats section for all the available `format` values.

`viewDimension` Optional

An enumerated value specifying the required dimension for texture views bound to this binding. Possible values are:

    + `"1d"`: The texture is viewed as a one-dimensional image.
    + `"2d"`: The texture is viewed as a single two-dimensional image.
    + `"2d-array"`: The texture is viewed as an array of two-dimensional images.
    + `"cube"`: The texture is viewed as a cubemap. The view has 6 array layers, corresponding to the `[+X, -X, +Y, -Y, +Z, -Z]` faces of the cube. Sampling is done seamlessly across the faces of the cubemap.
    + `"cube-array"`: The texture is viewed as a packed array of `n` cubemaps, each with 6 array layers corresponding to the `[+X, -X, +Y, -Y, +Z, -Z]` faces of the cube. Sampling is done seamlessly across the faces of the cubemaps.
    + `"3d"`: The texture is viewed as a three-dimensional image.
If omitted, `viewDimension` defaults to `"2d"`.
* `texture`: Indicates that the corresponding `GPUBindGroup` entry will be a `GPUTextureView` object. A `texture` resource layout object can contain the following properties:

`multisampled` Optional

A boolean. A value of `true` indicates that texture views bound to this binding must be multi-sampled. If omitted, `multisampled` defaults to `false`.

`sampleType` Optional

An enumerated value specifying the sample type required for texture views bound to this binding (see `GPUDevice.createTexture()` for more information on texture view types). Possible values are:

    + `"depth"`
    + `"float"`
    + `"sint"`
    + `"uint"`
    + `"unfilterable-float"`
If omitted, `sampleType` defaults to `"float"`.

`viewDimension` Optional

An enumerated value specifying the required dimension for texture views bound to this binding. Possible and default values are the same as for `storageTexture` resource layout objects — see above.
### Return value

A `GPUBindGroupLayout` object instance.

### Validation

The following criteria must be met when calling **`createBindGroupLayout()`**, otherwise a `GPUValidationError` is generated and an invalid `GPUBindGroupLayout` object is returned:

* Each entry's `binding` value is unique.
* Each entry's `binding` value is less than the `GPUDevice`'s `maxBindingsPerBindGroup` limit.
* The number of entries does not exceed the binding slot limits.
* Only 1 resource layout object is defined per entry.
* If an entry's `visibility` includes `GPUShaderStage.VERTEX`:
    + If its resource layout object is a `buffer`, its `type` is not `"storage"`.
    + Its resource layout object is not a `storageTexture`.
* If an entry's resource layout object is a `texture`, and its `multisampled` value is `true`:
    + Its `viewDimension` is `"2d"`.
    + Its `sampleType` is not `"float"`.
* If an entry's resource layout object is a `storageTexture`:
    + Its `viewDimension` is not `"cube"` or `"cube-array"`.
    + Its `format` is a format that supports storage usage.
Examples
--------

**Note:** The WebGPU samples feature many more examples.

### Basic example

Our basic compute demo shows an example of creating a bind group layout and then using that as a template when creating a bind group.

```js
// ...

const bindGroupLayout = device.createBindGroupLayout({
  entries: [
    {
      binding: 0,
      visibility: GPUShaderStage.COMPUTE,
      buffer: {
        type: "storage",
      },
    },
  ],
});

const bindGroup = device.createBindGroup({
  layout: bindGroupLayout,
  entries: [
    {
      binding: 0,
      resource: {
        buffer: output,
      },
    },
  ],
});

// ...
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-createbindgrouplayout |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: createRenderBundleEncoder() method - Web APIs

GPUDevice: createRenderBundleEncoder() method
=============================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`createRenderBundleEncoder()`** method of the
 `GPUDevice` interface creates a `GPURenderBundleEncoder` that can be used to pre-record bundles of commands. These can be reused in `GPURenderPassEncoder`s via the `executeBundles()` method, as many times as required.

Syntax
------

```js
createRenderBundleEncoder(descriptor)
```

### Parameters

`descriptor`

An object containing the following properties:

`colorFormats`

An array of enumerated values specifying the expected color formats for render targets. For possible values, see the `GPUTextureFormat` definition in the spec.

`depthReadOnly` Optional

A boolean. If `true`, specifies that executing any `GPURenderBundle` created by the `GPURenderBundleEncoder` will not modify the depth component of the `depthStencilFormat` when executed. If omitted, `depthReadOnly` will default to `false`.

`depthStencilFormat` Optional

An enumerated value that specifies the expected depth-or-stencil format for render targets. For possible values, see the Depth-stencil formats section of the spec.

`label` Optional

A string providing a label that can be used to identify the object, for example in `GPUError` messages or console warnings.

`sampleCount` Optional

A number representing the expected sample count for render targets.

`stencilReadOnly` Optional

A boolean. If `true`, specifies that executing any `GPURenderBundle` created by the `GPURenderBundleEncoder` will not modify the stencil component of the `depthStencilFormat` when executed. If omitted, `stencilReadOnly` will default to `false`.

### Return value

A `GPURenderBundleEncoder` object instance.

Examples
--------

In the WebGPU Samples Animometer example, numerous similar operations are done on many different objects simultaneously. A bundle of commands is encoded using the following function:

```js
function recordRenderPass(
  passEncoder: GPURenderBundleEncoder | GPURenderPassEncoder
) {
  if (settings.dynamicOffsets) {
    passEncoder.setPipeline(dynamicPipeline);
  } else {
    passEncoder.setPipeline(pipeline);
  }
  passEncoder.setVertexBuffer(0, vertexBuffer);
  passEncoder.setBindGroup(0, timeBindGroup);
  const dynamicOffsets = [0];
  for (let i = 0; i < numTriangles; ++i) {
    if (settings.dynamicOffsets) {
      dynamicOffsets[0] = i \* alignedUniformBytes;
      passEncoder.setBindGroup(1, dynamicBindGroup, dynamicOffsets);
    } else {
      passEncoder.setBindGroup(1, bindGroups[i]);
    }
    passEncoder.draw(3, 1, 0, 0);
  }
}
```

Later on, a `GPURenderBundleEncoder` is created using `createRenderBundleEncoder()`, the function is invoked, and the command bundle is recorded into a `GPURenderBundle` using `GPURenderBundleEncoder.finish()`:

```js
const renderBundleEncoder = device.createRenderBundleEncoder({
  colorFormats: [presentationFormat],
});
recordRenderPass(renderBundleEncoder);
const renderBundle = renderBundleEncoder.finish();
```

`GPURenderPassEncoder.executeBundles()` is then used to reuse the work across multiple render passes to improve performance. Study the example code listing for the full context.

```js
// ...

return function doDraw(timestamp) {
  if (startTime === undefined) {
    startTime = timestamp;
  }
  uniformTime[0] = (timestamp - startTime) / 1000;
  device.queue.writeBuffer(uniformBuffer, timeOffset, uniformTime.buffer);

  renderPassDescriptor.colorAttachments[0].view = context
    .getCurrentTexture()
    .createView();

  const commandEncoder = device.createCommandEncoder();
  const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

  if (settings.renderBundles) {
    passEncoder.executeBundles([renderBundle]);
  } else {
    recordRenderPass(passEncoder);
  }

  passEncoder.end();
  device.queue.submit([commandEncoder.finish()]);
};

// ...
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-createrenderbundleencoder |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: createTexture() method - Web APIs

GPUDevice: createTexture() method
=================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`createTexture()`** method of the
 `GPUDevice` interface creates a `GPUTexture` in which to store 1D, 2D, or 3D arrays of data, such as images, to use in GPU rendering operations.

Syntax
------

```js
createTexture(descriptor)
```

### Parameters

`descriptor`

An object containing the following properties:

`dimension` Optional

An enumerated value indicating the dimension level of the texture. Possible values are:

* `"1d"`: The texture is one-dimensional.
* `"2d"`: The texture is two-dimensional or an array of two-dimensional layers.
* `"3d"`: The texture is three-dimensional.

`dimension` defaults to `"2d"` if the value is omitted.

`format`

An enumerated value specifying the format of the texture. See the Texture formats section of the specification for all the possible values.

`label` Optional

A string providing a label that can be used to identify the object, for example in `GPUError` messages or console warnings.

`mipLevelCount` Optional

A number specifying the number of mip levels the texture will contain. If omitted, this defaults to 1.

`sampleCount` Optional

A number specifying the texture's sample count. To be valid, the value must be 1 or 4. If omitted, this defaults to 1. A value higher than 1 indicates a multi-sampled texture.

`size`

An object or array specifying the width, height, and depth/array layer count of the texture. The width value must always be specified, while the height and depth/array layer count values are optional and will default to 1 if omitted.

What follows is a sample `size` array:

```js
size: [16, 16, 2];
```

The object equivalent would look like this:

```js
size: {
  width: 16,
  height: 16,
  depthOrArrayLayers: 2
}
```

`usage`

The bitwise flags representing the allowed usages for the `GPUTexture`. The possible values are in the `GPUTexture.usage` value table.

Note that multiple possible usages can be specified by separating values with pipe symbols, for example:

```js
usage: GPUTextureUsage.COPY\_DST | GPUTextureUsage.RENDER\_ATTACHMENT;
```

`viewFormats` Optional

An array of enumerated values specifying other texture formats permitted when calling `GPUTexture.createView()` on this texture, in addition to the texture format specified in its `format` value.

### Return value

A `GPUTexture` object instance.

### Validation

The following criteria must be met when calling **`createTexture()`**, otherwise a `GPUValidationError` is generated and an invalid `GPUTexture` object is returned:

* A valid `usage` is specified.
* The values specified in `size` (width, height, or depth/array layer count) are greater than 0.
* `mipLevelCount` is greater than 0.
* `sampleCount` is equal to 1 or 4.
* If `dimension` is set to `"1d"`:
    + The `size` width value is less than or equal to the `GPUDevice`'s `maxTextureDimension1D` limit.
    + The `size` height and depth/array layer count values are equal to 1.
    + The `sampleCount` is equal to 1.
    + The `format` is not equal to a compressed format or depth-or-stencil format.
* If `dimension` is set to `"2d"`:
    + The `size` width and height values are less than or equal to the `GPUDevice`'s `maxTextureDimension2D` limit.
    + The `size` depth/array layer count value is less than or equal to the `GPUDevice`'s `maxTextureArrayLayers` limit.
* If `dimension` is set to `"3d"`:
    + The `size` width, and height, and depth/array layer count values are less than or equal to the `GPUDevice`'s `maxTextureDimension3D` limit.
    + The `sampleCount` value is equal to 1.
    + The `format` is not equal to a compressed format or depth-or-stencil format.
* The `size` width value is a multiple of the texel block width.
* The `size` height value is a multiple of the texel block height.
* If `sampleCount` is greater than 1:
    + `mipLevelCount` is equal to 1.
    + The `size` depth/array layer count value is equal to 1.
    + `usage` includes the `GPUTextureUsage.RENDER_ATTACHMENT` flag.
    + `usage` does not include the `GPUTextureUsage.STORAGE_BINDING` flag.
    + The specified format supports multi-sampling.
* The `mipLevelCount` value is less than or equal to the maximum miplevel count.
* The formats specified in `format` and `viewFormats` are compatible with one another.
* If `usage` includes the `GPUTextureUsage.RENDER_ATTACHMENT` flag:
    + `format` is a renderable format (meaning a color renderable format, or a depth-or-stencil format).
    + `dimension` is set to `"2d"`.
* If `usage` includes the `GPUTextureUsage.STORAGE_BINDING` flag:
    + The specified `format` includes the `STORAGE_BINDING` capability (see the Plain color formats table for reference).
Examples
--------

In the WebGPU samples Textured Cube sample, a texture to use on the faces of a cube is created by:

* Loading the image into an `HTMLImageElement` and creating an image bitmap using `createImageBitmap()`.
* Creating a new texture using `createTexture()`.
* Copying the image bitmap into the texture using `GPUQueue.copyExternalImageToTexture()`.

```js
//...

let cubeTexture: GPUTexture; // Sample is written in TypeScript

{
  const img = document.createElement("img");
  img.src = new URL(
    "../../../assets/img/Di-3d.png",
    import.meta.url
  ).toString();
  await img.decode();
  const imageBitmap = await createImageBitmap(img);

  cubeTexture = device.createTexture({
    size: [imageBitmap.width, imageBitmap.height, 1],
    format: "rgba8unorm",
    usage:
      GPUTextureUsage.TEXTURE\_BINDING |
      GPUTextureUsage.COPY\_DST |
      GPUTextureUsage.RENDER\_ATTACHMENT,
  });
  device.queue.copyExternalImageToTexture(
    { source: imageBitmap },
    { texture: cubeTexture },
    [imageBitmap.width, imageBitmap.height]
  );
}

//...
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-createtexture |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: createComputePipelineAsync() method - Web APIs

GPUDevice: createComputePipelineAsync() method
==============================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`createComputePipelineAsync()`** method of the
 `GPUDevice` interface returns a `Promise` that fulfills with a `GPUComputePipeline`, which can control the compute shader stage and be used in a `GPUComputePassEncoder`, once the pipeline can be used without any stalling.

**Note:** It is generally preferable to use this method over `GPUDevice.createComputePipeline()` whenever possible, as it prevents blocking of GPU operation execution on pipeline compilation.

Syntax
------

```js
createComputePipeline(descriptor)
```

### Parameters

`descriptor`

See the descriptor definition for the `GPUDevice.createComputePipeline()` method.

### Return value

A `Promise` that fulfills with a `GPUComputePipeline` object instance when the created pipeline is ready to be used without additional delay.

### Validation

If pipeline creation fails and the resulting pipeline becomes invalid as a result, the returned promise rejects with a `GPUPipelineError`:

* If this is due to an internal error, the `GPUPipelineError` will have a `reason` of `"internal"`.
* If this is due to a validation error, the `GPUPipelineError` will have a `reason` of `"validation"`.

A validation error can occur if any of the following are false:

* The workgroup storage size used by the `module` referenced inside the `compute` property is less than or equal to the `GPUDevice`'s `maxComputeWorkgroupStorageSize` limit.
* The `module` uses a number of compute invocations per workgroup less than or equal to the `GPUDevice`'s `maxComputeInvocationsPerWorkgroup` limit.
* The `module`'s workgroup size is less than or equal to the `GPUDevice`'s corresponding `maxComputeWorkgroupSizeX`, `maxComputeWorkgroupSizeY`, or `maxComputeWorkgroupSizeZ` limit.
Examples
--------

**Note:** The WebGPU samples feature many more examples.

### Basic example

The following example shows a process of:

* Creating a bind group layout with `GPUDevice.createBindGroupLayout()`.
* Feeding the `bindGroupLayout` into `GPUDevice.createPipelineLayout()` to create a `GPUPipelineLayout`.
* Using that value immediately in a `createComputePipelineAsync()` call to create a `GPUComputePipeline`.

```js
async function init() {
  // ...

  const bindGroupLayout = device.createBindGroupLayout({
    entries: [
      {
        binding: 0,
        visibility: GPUShaderStage.COMPUTE,
        buffer: {
          type: "storage",
        },
      },
    ],
  });

  const computePipeline = await device.createComputePipelineAsync({
    layout: device.createPipelineLayout({
      bindGroupLayouts: [bindGroupLayout],
    }),
    compute: {
      module: shaderModule,
      entryPoint: "main",
    },
  });

  // ...
}
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-createcomputepipelineasync |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: features property - Web APIs

GPUDevice: features property
============================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`features`** read-only property of the
 `GPUDevice` interface returns a `GPUSupportedFeatures` object that describes additional functionality supported by the device. Only features requested during the creation of the device (i.e. when `GPUAdapter.requestDevice()` is called) are included.

**Note:** Not all features will be available to WebGPU in all browsers that support it, even if the features are supported by the underlying hardware. See `GPUAdapter.features` for more details.

Value
-----

A `GPUSupportedFeatures` object instance. This is a setlike object.

Examples
--------

In the following code we check whether a `GPUAdapter` has the `texture-compression-astc` feature available. If so, we push it into the array of `requiredFeatures`, and request a device with that feature requirement using `GPUAdapter.requestDevice()`.

We then log all items in the `GPUDevice.features` set to the console. This set should only contain a single item — `texture-compression-astc` — as that was the only feature requested when the device was created.

```js
async function init() {
  if (!navigator.gpu) {
    throw Error("WebGPU not supported.");
  }

  const adapter = await navigator.gpu.requestAdapter();
  if (!adapter) {
    throw Error("Couldn't request WebGPU adapter.");
  }

  const requiredFeatures = [];

  if (adapter.features.has("texture-compression-astc")) {
    requiredFeatures.push("texture-compression-astc");
  }

  const device = await adapter.requestDevice({
    requiredFeatures,
  });

  device.features.forEach((value) => {
    console.log(value);
  });

  // ...
}
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-features |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: lost property - Web APIs

GPUDevice: lost property
========================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`lost`** read-only property of the
 `GPUDevice` interface contains a `Promise` that remains pending throughout the device's lifetime and resolves with a `GPUDeviceLostInfo` object when the device is lost.

`GPUAdapter.requestDevice()` will never return `null`, and it will reject only if the request is invalid, i.e. it exceeds the capabilities of the `GPUAdapter`. If a valid device request can't be fulfilled for some reason however it may resolve to a device that has already been lost. Additionally, devices can be lost at any time after creation for a variety of reasons (such as browser resource management or driver updates), so it's a good idea to always handle lost devices gracefully.

Many causes for lost devices are transient, so you should try getting a new device once a previous one has been lost unless the loss was caused by the application intentionally destroying the device (i.e. with `GPUDevice.destroy()`). Note that any WebGPU resources created with a previous device (buffers, textures, etc.) will need to be re-created with the new one.

**Note:** Also bear in mind that a `GPUAdapter` may become unavailable, e.g. if the physical GPU is unplugged from the system or disabled to save power. From then on, the adapter can no longer return valid devices, and will always return already-lost devices.

Value
-----

A promise that resolves with a `GPUDeviceLostInfo` object when the device is lost.

Examples
--------

```js
async function init() {
  if (!navigator.gpu) {
    throw Error("WebGPU not supported.");
  }

  const adapter = await navigator.gpu.requestAdapter();
  if (!adapter) {
    throw Error("Couldn't request WebGPU adapter.");
  }

  // Create a GPUDevice
  let device = await adapter.requestDevice(descriptor);

  // Use lost to handle lost devices
  device.lost.then((info) => {
    console.error(`WebGPU device was lost: ${info.message}`);
    device = null;

    if (info.reason !== "destroyed") {
      init();
    }
  });

  // ...
}
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-lost |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: queue property - Web APIs

GPUDevice: queue property
=========================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`queue`** read-only property of the
 `GPUDevice` interface returns the primary `GPUQueue` for the device.

Value
-----

A `GPUQueue` object instance.

Examples
--------

Basic `GPUQueue` access:

```js
async function init() {
  if (!navigator.gpu) {
    throw Error("WebGPU not supported.");
  }

  const adapter = await navigator.gpu.requestAdapter();
  if (!adapter) {
    throw Error("Couldn't request WebGPU adapter.");
  }

  // Create a GPUDevice
  const device = await adapter.requestDevice();

  // ...

  // Common queue use — end current frame by passing array of
  // command buffers to queue for execution
  device.queue.submit([commandEncoder.finish()]);

  // ...
}
```

**Note:** For more queue examples, see the `GPUQueue` reference pages.

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-queue |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: uncapturederror event - Web APIs

GPUDevice: uncapturederror event
================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`uncapturederror`** event of the `GPUDevice` interface is fired when an error is thrown that has not been observed by a GPU error scope, to provide a way to report unexpected errors.

Known error cases should be handled using `pushErrorScope()` and `popErrorScope()`.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("uncapturederror", (event) => {});

onuncapturederror = (event) => {};
```

Event type
----------

An `GPUUncapturedErrorEvent`. Inherits from `Event`.

Event

GPUUncapturedErrorEventExamples
--------

You could use something like the following as a global mechanism to pick up any errors that aren't handled by error scopes and capture them.

```js
device.addEventListener("uncapturederror", (event) => {
  // Re-surface the error.
  console.error("A WebGPU error was not captured:", event.error);

  reportErrorToServer({
    type: event.error.constructor.name,
    message: event.error.message,
  });
});
```

See WebGPU Error Handling best practices for more examples and information.

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-onuncapturederror |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: createRenderPipelineAsync() method - Web APIs

GPUDevice: createRenderPipelineAsync() method
=============================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`createRenderPipelineAsync()`** method of the
 `GPUDevice` interface returns a `Promise` that fulfills with a `GPURenderPipeline`, which can control the vertex and fragment shader stages and be used in a `GPURenderPassEncoder` or `GPURenderBundleEncoder`, once the pipeline can be used without any stalling.

**Note:** It is generally preferable to use this method over `GPUDevice.createRenderPipeline()` whenever possible, as it prevents blocking of GPU operation execution on pipeline compilation.

Syntax
------

```js
createRenderPipelineAsync(descriptor)
```

### Parameters

`descriptor`

See the descriptor definition for the `GPUDevice.createRenderPipeline()` method.

### Return value

A `Promise` that fulfills with a `GPURenderPipeline` object instance when the created pipeline is ready to be used without additional delay.

### Validation

If pipeline creation fails and the resulting pipeline becomes invalid as a result, the returned promise rejects with a `GPUPipelineError`:

* If this is due to an internal error, the `GPUPipelineError` will have a `reason` of `"internal"`.
* If this is due to a validation error, the `GPUPipelineError` will have a `reason` of `"validation"`.

A validation error can occur if any of the following are false:

* For `depthStencil` objects:
    + `format` is a `depth-or-stencil` format.
    + If `depthWriteEnabled` is `true` or `depthCompare` is not `"always"`, `format` has a depth component.
    + If `stencilFront` or `stencilBack`'s properties are not at their default values, `format` has a stencil component.
* For `fragment` objects:
    + `targets.length` is less than or equal to the `GPUDevice`'s `maxColorAttachments` limit.
    + For each `target`, `writeMask`'s numeric equivalent is less than 16.
    + If any of the used blend factor operations use the source alpha channel (for example `"src-alpha-saturated"`), the output has an alpha channel (that is, it must be a `vec4`).
Examples
--------

**Note:** The WebGPU samples feature many more examples.

### Basic example

The following example shows a basic example of the construction of a valid render pipeline descriptor object, which is then used to create a `GPURenderPipeline` via a `createRenderPipelineAsync()` call.

```js
async function init() {
  // ...

  const vertexBuffers = [
    {
      attributes: [
        {
          shaderLocation: 0, // position
          offset: 0,
          format: "float32x4",
        },
        {
          shaderLocation: 1, // color
          offset: 16,
          format: "float32x4",
        },
      ],
      arrayStride: 32,
      stepMode: "vertex",
    },
  ];

  const pipelineDescriptor = {
    vertex: {
      module: shaderModule,
      entryPoint: "vertex\_main",
      buffers: vertexBuffers,
    },
    fragment: {
      module: shaderModule,
      entryPoint: "fragment\_main",
      targets: [
        {
          format: navigator.gpu.getPreferredCanvasFormat(),
        },
      ],
    },
    primitive: {
      topology: "triangle-list",
    },
    layout: "auto",
  };

  const renderPipeline =
    await device.createRenderPipelineAsync(pipelineDescriptor);

  // ...
}
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-createrenderpipelineasync |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: pushErrorScope() method - Web APIs

GPUDevice: pushErrorScope() method
==================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`pushErrorScope()`** method of the
 `GPUDevice` interface pushes a new GPU error scope onto the device's error scope stack, allowing you to capture errors of a particular type.

Once you are done capturing errors, you can end capture by invoking `GPUDevice.popErrorScope()`. This pops the scope from the stack and returns a `Promise` that resolves to an object describing the first error captured in the scope, or `null` if no errors were captured.

Syntax
------

```js
pushErrorScope(filter)
```

### Parameters

`filter`

An enumerated value that specifies what type of error will be caught in this particular error scope. Possible values are:

`"internal"`

The error scope will catch a `GPUInternalError`.

`"out-of-memory"`

The error scope will catch a `GPUOutOfMemoryError`.

`"validation"`

The error scope will catch a `GPUValidationError`.

### Return value

None (`Undefined`).

Examples
--------

The following example uses an error scope to capture a suspected validation error, logging it to the console.

```js
device.pushErrorScope("validation");

let sampler = device.createSampler({
  maxAnisotropy: 0, // Invalid, maxAnisotropy must be at least 1.
});

device.popErrorScope().then((error) => {
  if (error) {
    sampler = null;
    console.error(`An error occurred while creating sampler: ${error.message}`);
  }
});
```

See WebGPU Error Handling best practices for a lot more examples and information.

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-pusherrorscope |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: importExternalTexture() method - Web APIs

GPUDevice: importExternalTexture() method
=========================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`importExternalTexture()`** method of the
 `GPUDevice` interface takes an `HTMLVideoElement` or a `VideoFrame` object as an input and returns a `GPUExternalTexture` wrapper object containing a snapshot of the video that can be used as a frame in GPU rendering operations.

Syntax
------

```js
importExternalTexture(descriptor)
```

### Parameters

`descriptor`

An object containing the following properties:

`colorSpace` Optional

An enumerated value specifying the color space to use for the video frame. Possible values are `"srgb"` and `"display-p3"`. If omitted, `colorSpace` defaults to `"srgb"`.

`label` Optional

A string providing a label that can be used to identify the object, for example in `GPUError` messages or console warnings.

`source`

The `HTMLVideoElement` or `VideoFrame` source of the video snapshot.

### Return value

A `GPUExternalTexture` object instance.

Note that the moment when the `GPUExternalTexture` object expires (is destroyed) depends on what its source is:

* `GPUExternalTexture` objects with an `HTMLVideoElement` source expire as soon as they are used (for example in a bind group).
* `GPUExternalTexture` objects with an `VideoFrame` source expire only when the `VideoFrame` is closed, for example via a `VideoFrame.close()` call.
### Validation

The following criteria must be met when calling **`importExternalTexture()`**, otherwise a `GPUValidationError` is generated and an invalid `GPUExternalTexture` object is returned:

* The video snapshot is usable (e.g. the video source is loaded properly, and doesn't have a width or height of 0).
### Exceptions

`SecurityError` `DOMException`

Thrown if the video source data is cross-origin.

Examples
--------

In the WebGPU samples Video Uploading sample, an `importExternalTexture()` call is used as the value of a bind group entry `resource`, specified when creating a `GPUBindGroup` via a `GPUDevice.createBindGroup()` call:

```js
//...

const uniformBindGroup = device.createBindGroup({
  layout: pipeline.getBindGroupLayout(0),
  entries: [
    {
      binding: 1,
      resource: sampler,
    },
    {
      binding: 2,
      resource: device.importExternalTexture({
        source: video,
      }),
    },
  ],
});

//...
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-importexternaltexture |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: createBuffer() method - Web APIs

GPUDevice: createBuffer() method
================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`createBuffer()`** method of the
 `GPUDevice` interface creates a `GPUBuffer` in which to store raw data to use in GPU operations.

Syntax
------

```js
createBuffer(descriptor)
```

### Parameters

`descriptor`

An object containing the following properties:

`label` Optional

A string providing a label that can be used to identify the object, for example in `GPUError` messages or console warnings.

`mappedAtCreation` Optional

A boolean. If set to `true`, the buffer will be mapped upon creation, meaning that you can set the values inside the buffer immediately by calling `GPUBuffer.getMappedRange()`. The default value is `false`.

Note that it is valid to set `mappedAtCreation: true` so you can set the buffer's initial data, even if the `GPUBufferUsage.MAP_READ` or `GPUBufferUsage.MAP_WRITE` usage flags are not set.

`size`

A number representing the size of the buffer, in bytes.

`usage`

The bitwise flags representing the allowed usages for the `GPUBuffer`. The possible values are in the `GPUBuffer.usage` value table.

Note that multiple possible usages can be specified by separating values with pipe symbols, for example:

```js
usage: GPUBufferUsage.COPY\_SRC | GPUBufferUsage.MAP\_WRITE;
```

### Return value

A `GPUBuffer` object instance.

### Validation

The following criteria must be met when calling **`createBuffer()`**, otherwise a `GPUValidationError` is generated and an invalid `GPUBuffer` object is returned:

* A valid `usage` is specified.
* `GPUBufferUsage.MAP_READ` is specified, and no additional flags are specified other than `GPUBufferUsage.COPY_DST`.
* `GPUBufferUsage.MAP_WRITE` is specified, and no additional flags are specified other than `GPUBufferUsage.COPY_SRC`.
* `mappedAtCreation: true` is specified, and the specified `size` is a multiple of 4.

**Note:** If the buffer allocation fails without any specific side-effects, a `GPUOutOfMemoryError` object is generated.

Examples
--------

In our basic compute demo, we create an output buffer to read GPU calculations to, and a staging buffer to be mapped for JavaScript access.

```js
const output = device.createBuffer({
  size: BUFFER\_SIZE,
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY\_SRC,
});

const stagingBuffer = device.createBuffer({
  size: BUFFER\_SIZE,
  usage: GPUBufferUsage.MAP\_READ | GPUBufferUsage.COPY\_DST,
});
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-createbuffer |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API


GPUDevice: createShaderModule() method - Web APIs

GPUDevice: createShaderModule() method
======================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`createShaderModule()`** method of the
 `GPUDevice` interface creates a `GPUShaderModule` from a string of WGSL source code.

Syntax
------

```js
createShaderModule(descriptor)
```

### Parameters

`descriptor`

An object containing the following properties:

`code`

A string representing the WGSL source code for the shader module.

`hints` Optional

A sequence of record types, with the structure `("string", compilationHint)`. These behave like ordered maps. In each case, the `"string"` is a key used to identify or select the record, and the `compilationHint` is either a `GPUPipelineLayout` object instance or an enumerated value of `"auto"`.

The point of `hints` is to provide information about the pipeline layout as early as possible to improve performance. The idea is to maximize the amount of compilation that can be done once by `createShaderModule()`, rather than multiple times in multiple calls to `GPUDevice.createComputePipeline()` and `GPUDevice.createRenderPipeline()`.

**Note:** Different implementations may handle `hints` in different ways, including possibly ignoring them entirely. Providing hints does not guarantee improved shader compilation performance on all browsers/systems.

`label` Optional

A string providing a label that can be used to identify the object, for example in `GPUError` messages or console warnings.

`sourceMap` Optional

A source map definition to provide developer tool integration such as source-language debugging. WGSL names (identifiers) in source maps should follow the rules defined in WGSL identifier comparison. If defined, the source map may be interpreted as a source-map-v3 format.

**Note:** Different implementations may handle `sourceMap`s in different ways, including possibly ignoring them entirely.

### Return value

A `GPUShaderModule` object instance.

Examples
--------

In our basic render demo, our shader module is created using the following code:

```js
const shaders = `
struct VertexOut {
 @builtin(position) position : vec4f,
 @location(0) color : vec4f
}

@vertex
fn vertex\_main(@location(0) position: vec4f,
 @location(1) color: vec4f) -> VertexOut
{
 var output : VertexOut;
 output.position = position;
 output.color = color;
 return output;
}

@fragment
fn fragment\_main(fragData: VertexOut) -> @location(0) vec4f
{
 return fragData.color;
}
`;

async function init() {
  if (!navigator.gpu) {
    throw Error("WebGPU not supported.");
  }

  const adapter = await navigator.gpu.requestAdapter();
  if (!adapter) {
    throw Error("Couldn't request WebGPU adapter.");
  }

  let device = await adapter.requestDevice();

  // ...
  // later on

  const shaderModule = device.createShaderModule({
    code: shaders,
  });

  // ...
}
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-createshadermodule |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API
* The WebGPU Shading Language specification


GPUDevice: createPipelineLayout() method - Web APIs

GPUDevice: createPipelineLayout() method
========================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`createPipelineLayout()`** method of the
 `GPUDevice` interface creates a `GPUPipelineLayout` that defines the `GPUBindGroupLayout`s used by a pipeline. `GPUBindGroup`s used with the pipeline during command encoding must have compatible `GPUBindGroupLayout`s.

Syntax
------

```js
createPipelineLayout(descriptor)
```

### Parameters

`descriptor`

An object containing the following properties:

`bindGroupLayouts`

An array of `GPUBindGroupLayout` objects (which are in turn created via calls to `GPUDevice.createBindGroupLayout()`). Each one corresponds to a `@group` attribute in the shader code contained in the `GPUShaderModule` used in a related pipeline.

`label` Optional

A string providing a label that can be used to identify the object, for example in `GPUError` messages or console warnings.

### Return value

A `GPUPipelineLayout` object instance.

### Validation

The following criteria must be met when calling **`createPipelineLayout()`**, otherwise a `GPUValidationError` is generated and an invalid `GPUPipelineLayout` object is returned:

* The `GPUBindGroupLayout` objects in `bindGroupLayouts` are valid.
* The number of `GPUBindGroupLayout` objects in `bindGroupLayouts` is less than the `GPUDevice`'s `maxBindGroups` limit.
Examples
--------

**Note:** The WebGPU samples feature many more examples.

### Multiple bind group layouts, bind group, and pipeline layout

The following snippet:

* Creates a `GPUBindGroupLayout` that describes a binding with a buffer, a texture, and a sampler.
* Creates a `GPUPipelineLayout` based on the `GPUBindGroupLayout`.

```js
// ...

const bindGroupLayout = device.createBindGroupLayout({
  entries: [
    {
      binding: 0,
      visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
      buffer: {},
    },
    {
      binding: 1,
      visibility: GPUShaderStage.FRAGMENT,
      texture: {},
    },
    {
      binding: 2,
      visibility: GPUShaderStage.FRAGMENT,
      sampler: {},
    },
  ],
});

const pipelineLayout = device.createPipelineLayout({
  bindGroupLayouts: [bindGroupLayout],
});

// ...
```

Specifications
--------------

| Specification |
| --- |
| WebGPU # dom-gpudevice-createpipelinelayout |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The WebGPU API