Bug 1858732 - Allow WebGPU to be enabled on DOM workers via a pref, disabled by default. r=webidl,webgpu-reviewers,saschanaz,nical

Differential Revision: https://phabricator.services.mozilla.com/D190830
This commit is contained in:
Andrew Osmond 2023-10-16 15:29:21 +00:00
Родитель 4a41fccf9d
Коммит 3e3244b42a
11 изменённых файлов: 111 добавлений и 89 удалений

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/dom/Promise.h"
#include "mozilla/gfx/CanvasManagerChild.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/StaticPrefs_dom.h"
#include <optional>
#include <string_view>
@ -25,6 +26,18 @@ static inline nsDependentCString ToCString(const std::string_view s) {
return {s.data(), s.length()};
}
/* static */ bool Instance::PrefEnabled(JSContext* aCx, JSObject* aObj) {
if (!StaticPrefs::dom_webgpu_enabled()) {
return false;
}
if (NS_IsMainThread()) {
return true;
}
return StaticPrefs::dom_webgpu_workers_enabled();
}
/*static*/
already_AddRefed<Instance> Instance::Create(nsIGlobalObject* aOwner) {
RefPtr<Instance> result = new Instance(aOwner);

Просмотреть файл

@ -32,6 +32,8 @@ class Instance final : public nsWrapperCache {
nsIGlobalObject* GetParentObject() const { return mOwner; }
static bool PrefEnabled(JSContext* aCx, JSObject* aObj);
static already_AddRefed<Instance> Create(nsIGlobalObject* aOwner);
already_AddRefed<dom::Promise> RequestAdapter(

Просмотреть файл

@ -3,6 +3,7 @@ subsuite = webgpu
run-if = !release_or_beta
prefs =
dom.webgpu.enabled=true
dom.webgpu.workers.enabled=true
gfx.offscreencanvas.enabled=true
support-files =
worker_wrapper.js
@ -15,7 +16,6 @@ support-files =
scheme = https
[test_basic_canvas.worker.html]
skip-if = true # Bug 1818379 - no webgpu in worker scopes, see bug 1808820
fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') || (os == 'mac')
[test_buffer_mapping.html]
fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') || (os == 'mac')
@ -39,5 +39,4 @@ fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version
[test_submit_render_empty.html]
fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') || (os == 'mac')
[test_submit_render_empty.worker.html]
skip-if = true # Bug 1818379 - no webgpu in worker scopes, see bug 1808820
fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') || (os == 'mac')

Просмотреть файл

@ -3,9 +3,9 @@ self.addEventListener("message", async function (event) {
const offscreen = event.data.offscreen;
const context = offscreen.getContext("webgpu");
const swapChainFormat = navigator.gpu.getPreferredCanvasFormat();
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const swapChainFormat = context.getPreferredFormat(adapter);
context.configure({
device,

Просмотреть файл

@ -21,7 +21,8 @@ self.addEventListener("message", async function (event) {
colorAttachments: [
{
view,
loadValue: { r: 0, g: 0, b: 0, a: 0 },
clearValue: { r: 0, g: 0, b: 0, a: 0 },
loadOp: "clear",
storeOp: "store",
},
],

Просмотреть файл

@ -11,8 +11,8 @@ dictionary GPUUncapturedErrorEventInit : EventInit {
required GPUError error;
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker*/), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUUncapturedErrorEvent: Event {
constructor(DOMString type, GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict);
readonly attribute GPUError error;

Просмотреть файл

@ -15,8 +15,8 @@ dictionary GPUObjectDescriptorBase {
USVString label = "";
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUSupportedLimits {
readonly attribute unsigned long maxTextureDimension1D;
readonly attribute unsigned long maxTextureDimension2D;
@ -52,14 +52,14 @@ interface GPUSupportedLimits {
readonly attribute unsigned long maxComputeWorkgroupsPerDimension;
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUSupportedFeatures {
readonly setlike<DOMString>;
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUAdapterInfo {
readonly attribute DOMString vendor;
readonly attribute DOMString architecture;
@ -77,7 +77,7 @@ interface GPUAdapterInfo {
};
interface mixin NavigatorGPU {
[SameObject, Pref="dom.webgpu.enabled", Exposed=(Window /* ,DedicatedWorker */), SecureContext] readonly attribute GPU gpu;
[SameObject, Func="mozilla::webgpu::Instance::PrefEnabled", Exposed=(Window, DedicatedWorker), SecureContext] readonly attribute GPU gpu;
};
// NOTE: see `dom/webidl/Navigator.webidl`
// Navigator includes NavigatorGPU;
@ -85,8 +85,8 @@ interface mixin NavigatorGPU {
// WorkerNavigator includes NavigatorGPU;
[
Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext
Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext
]
interface GPU {
[Throws]
@ -104,8 +104,8 @@ enum GPUPowerPreference {
"high-performance",
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUAdapter {
[SameObject] readonly attribute GPUSupportedFeatures features;
[SameObject] readonly attribute GPUSupportedLimits limits;
@ -138,8 +138,8 @@ enum GPUFeatureName {
"float32-filterable",
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUDevice : EventTarget {
[SameObject] readonly attribute GPUSupportedFeatures features;
[SameObject] readonly attribute GPUSupportedLimits limits;
@ -172,8 +172,8 @@ interface GPUDevice : EventTarget {
};
GPUDevice includes GPUObjectBase;
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUBuffer {
readonly attribute GPUSize64Out size;
readonly attribute GPUFlagsConstant usage;
@ -206,8 +206,8 @@ dictionary GPUBufferDescriptor
};
typedef [EnforceRange] unsigned long GPUBufferUsageFlags;
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUBufferUsage {
const GPUFlagsConstant MAP_READ = 0x0001;
const GPUFlagsConstant MAP_WRITE = 0x0002;
@ -222,15 +222,15 @@ interface GPUBufferUsage {
};
typedef [EnforceRange] unsigned long GPUMapModeFlags;
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUMapMode {
const GPUFlagsConstant READ = 0x0001;
const GPUFlagsConstant WRITE = 0x0002;
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUTexture {
GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {});
@ -265,8 +265,8 @@ enum GPUTextureDimension {
};
typedef [EnforceRange] unsigned long GPUTextureUsageFlags;
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUTextureUsage {
const GPUFlagsConstant COPY_SRC = 0x01;
const GPUFlagsConstant COPY_DST = 0x02;
@ -275,8 +275,8 @@ interface GPUTextureUsage {
const GPUFlagsConstant RENDER_ATTACHMENT = 0x10;
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUTextureView {
};
GPUTextureView includes GPUObjectBase;
@ -383,8 +383,8 @@ enum GPUTextureFormat {
"bc7-rgba-unorm-srgb",
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUSampler {
};
GPUSampler includes GPUObjectBase;
@ -430,8 +430,8 @@ enum GPUCompareFunction {
"always",
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUBindGroupLayout {
};
GPUBindGroupLayout includes GPUObjectBase;
@ -452,8 +452,8 @@ dictionary GPUBindGroupLayoutEntry {
};
typedef [EnforceRange] unsigned long GPUShaderStageFlags;
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUShaderStage {
const GPUFlagsConstant VERTEX = 0x1;
const GPUFlagsConstant FRAGMENT = 0x2;
@ -506,8 +506,8 @@ dictionary GPUStorageTextureBindingLayout {
GPUTextureViewDimension viewDimension = "2d";
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUBindGroup {
};
GPUBindGroup includes GPUObjectBase;
@ -531,8 +531,8 @@ dictionary GPUBufferBinding {
GPUSize64 size;
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUPipelineLayout {
};
GPUPipelineLayout includes GPUObjectBase;
@ -542,8 +542,8 @@ dictionary GPUPipelineLayoutDescriptor
required sequence<GPUBindGroupLayout> bindGroupLayouts;
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUShaderModule {
[Throws]
Promise<GPUCompilationInfo> compilationInfo(); // To be removed with <https://bugzilla.mozilla.org/show_bug.cgi?id=1846892>
@ -565,8 +565,8 @@ enum GPUCompilationMessageType {
"info",
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUCompilationMessage {
readonly attribute DOMString message;
readonly attribute GPUCompilationMessageType type;
@ -576,8 +576,8 @@ interface GPUCompilationMessage {
readonly attribute unsigned long long length;
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUCompilationInfo {
[Cached, Frozen, Pure]
readonly attribute sequence<GPUCompilationMessage> messages;
@ -603,8 +603,8 @@ dictionary GPUProgrammableStage {
//TODO: Serializable
// https://bugzilla.mozilla.org/show_bug.cgi?id=1696219
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUComputePipeline {
};
GPUComputePipeline includes GPUObjectBase;
@ -617,8 +617,8 @@ dictionary GPUComputePipelineDescriptor
//TODO: Serializable
// https://bugzilla.mozilla.org/show_bug.cgi?id=1696219
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPURenderPipeline {
};
GPURenderPipeline includes GPUObjectBase;
@ -686,8 +686,8 @@ dictionary GPUBlendState {
};
typedef [EnforceRange] unsigned long GPUColorWriteFlags;
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUColorWrite {
const GPUFlagsConstant RED = 0x1;
const GPUFlagsConstant GREEN = 0x2;
@ -852,8 +852,8 @@ dictionary GPUImageCopyExternalImage {
boolean flipY = false;
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUCommandBuffer {
};
GPUCommandBuffer includes GPUObjectBase;
@ -865,8 +865,8 @@ dictionary GPUCommandBufferDescriptor
interface mixin GPUCommandsMixin {
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUCommandEncoder {
GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor);
GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {});
@ -914,8 +914,8 @@ interface mixin GPUDebugCommandsMixin {
undefined insertDebugMarker(USVString markerLabel);
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUComputePassEncoder {
undefined setPipeline(GPUComputePipeline pipeline);
undefined dispatchWorkgroups(GPUSize32 workgroupCountX, optional GPUSize32 workgroupCountY = 1, optional GPUSize32 workgroupCountZ = 1);
@ -934,8 +934,8 @@ dictionary GPUComputePassDescriptor
: GPUObjectDescriptorBase {
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPURenderPassEncoder {
undefined setViewport(float x, float y,
float width, float height,
@ -1026,8 +1026,8 @@ interface mixin GPURenderCommandsMixin {
undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPURenderBundle {
};
GPURenderBundle includes GPUObjectBase;
@ -1036,8 +1036,8 @@ dictionary GPURenderBundleDescriptor
: GPUObjectDescriptorBase {
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPURenderBundleEncoder {
GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {});
};
@ -1061,8 +1061,8 @@ dictionary GPUQueueDescriptor
// https://bugzilla.mozilla.org/show_bug.cgi?id=1696216
// https://github.com/heycam/webidl/issues/961
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUQueue {
undefined submit(sequence<GPUCommandBuffer> buffers);
@ -1092,8 +1092,8 @@ interface GPUQueue {
};
GPUQueue includes GPUObjectBase;
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUQuerySet {
undefined destroy();
};
@ -1120,8 +1120,8 @@ enum GPUQueryType {
"timestamp",
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUCanvasContext {
readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas;
@ -1150,8 +1150,8 @@ enum GPUDeviceLostReason {
"destroyed",
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUDeviceLostInfo {
readonly attribute any reason; // GPUDeviceLostReason or undefined
readonly attribute DOMString message;
@ -1162,30 +1162,30 @@ partial interface GPUDevice {
readonly attribute Promise<GPUDeviceLostInfo> lost;
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUError {
readonly attribute DOMString message;
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUValidationError
: GPUError {
[Throws]
constructor(DOMString message);
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUOutOfMemoryError
: GPUError {
[Throws]
constructor(DOMString message);
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
[Func="mozilla::webgpu::Instance::PrefEnabled",
Exposed=(Window, DedicatedWorker), SecureContext]
interface GPUInternalError
: GPUError {
[Throws]
@ -1205,7 +1205,7 @@ partial interface GPUDevice {
};
partial interface GPUDevice {
[Exposed=(Window /* ,DedicatedWorker */)]
[Exposed=(Window, DedicatedWorker)]
attribute EventHandler onuncapturederror;
};

Просмотреть файл

@ -4474,6 +4474,12 @@
value: @IS_NIGHTLY_BUILD@
mirror: always
# Is support for the Web GPU API enabled on DOM workers?
- name: dom.webgpu.workers.enabled
type: RelaxedAtomicBool
value: false
mirror: always
# Are WebGPU indirect draws/dispatches enabled?
- name: dom.webgpu.indirect-dispatch.enabled
type: RelaxedAtomicBool

Просмотреть файл

@ -1,6 +1,6 @@
prefs:
if os == "mac": [dom.webgpu.enabled:true, dom.webgpu.testing.assert-hardware-adapter:true]
if os == "windows": [dom.webgpu.enabled:true, dom.webgpu.testing.assert-hardware-adapter:true]
[dom.webgpu.enabled:true]
if os == "mac": [dom.webgpu.enabled:true, dom.webgpu.workers.enabled:true, dom.webgpu.testing.assert-hardware-adapter:true]
if os == "windows": [dom.webgpu.enabled:true, dom.webgpu.workers.enabled:true, dom.webgpu.testing.assert-hardware-adapter:true]
[dom.webgpu.enabled:true, dom.webgpu.workers.enabled:true]
lsan-allowed: [Alloc, mozilla::net::nsServerSocket::CreateClientTransport]
leak-threshold: [default:51200]

Просмотреть файл

@ -1,7 +1,7 @@
prefs:
if os == "mac": [dom.webgpu.enabled:true, dom.webgpu.testing.assert-hardware-adapter:true]
if os == "windows": [dom.webgpu.enabled:true, dom.webgpu.testing.assert-hardware-adapter:true]
[dom.webgpu.enabled:true]
if os == "mac": [dom.webgpu.enabled:true, dom.webgpu.workers.enabled:true, dom.webgpu.testing.assert-hardware-adapter:true]
if os == "windows": [dom.webgpu.enabled:true, dom.webgpu.workers.enabled:true, dom.webgpu.testing.assert-hardware-adapter:true]
[dom.webgpu.enabled:true, dom.webgpu.workers.enabled:true]
tags: [webgpu]
disabled:
if release_or_beta: https://mozilla-hub.atlassian.net/browse/FFXP-223

Просмотреть файл

@ -1,6 +1,7 @@
[cts.https.html?q=webgpu:web_platform,worker,worker:worker:*]
[:]
expected: FAIL
expected:
if os == "mac": FAIL
[cts.https.html?q=webgpu:web_platform,external_texture,video:importExternalTexture,compute:*]