You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebGPU:C/C++与浏览器间纹理句柄互传的可行性及实现方法

WebGPU纹理跨进程(C++/浏览器)共享方案

核心结论

两个方向的纹理共享均可行:

  • C++(Node扩展)创建的WebGPU纹理可通过共享句柄传递给浏览器端WebGPU
  • 浏览器端WebGPU纹理也可通过共享句柄传递给C++原生WebGPU

Electron环境下,共享句柄的平台表现为:

  • macOS:IOSurface
  • Windows:共享D3D11纹理的HANDLE

一、C++端创建WebGPU纹理并传递给浏览器端

实现步骤

  1. 初始化C++端WebGPU环境
    基于wgpu-native或Electron提供的WebGPU C接口初始化WGPUDevice,确保设备支持共享纹理特性。

  2. 创建可共享的WebGPU纹理
    配置纹理描述符时,需指定支持共享的usage,并开启共享属性:

#include <webgpu/webgpu.h>

WGPUTextureDescriptor textureDesc = {};
textureDesc.nextInChain = nullptr;
textureDesc.label = "SharedTextureFromCPP";
textureDesc.dimension = WGPUTextureDimension_2D;
textureDesc.size.width = 1920;
textureDesc.size.height = 1080;
textureDesc.size.depthOrArrayLayers = 1;
textureDesc.mipLevelCount = 1;
textureDesc.sampleCount = 1;
textureDesc.format = WGPUTextureFormat_BGRA8Unorm;
// 必须包含拷贝目标和渲染附件(根据实际需求调整)
textureDesc.usage = WGPUTextureUsage_CopyDst | WGPUTextureUsage_RenderAttachment | WGPUTextureUsage_TextureBinding;

// 创建纹理
WGPUTexture texture = wgpuDeviceCreateTexture(device, &textureDesc);

// 获取共享句柄
WGPUSharedTextureHandle sharedHandle = wgpuTextureGetSharedTextureHandle(texture);

// 平台特定转换:macOS转为IOSurfaceRef,Windows转为HANDLE
#ifdef __APPLE__
IOSurfaceRef iosurface = reinterpret_cast<IOSurfaceRef>(sharedHandle);
uint32_t ioSurfaceID = IOSurfaceGetID(iosurface);
// 将ioSurfaceID通过IPC传给渲染进程
#elif _WIN32
HANDLE d3dSharedHandle = reinterpret_cast<HANDLE>(sharedHandle);
// 将d3dSharedHandle的数值(uint64_t)通过IPC传给渲染进程
#endif
  1. 浏览器端导入共享纹理
    渲染进程接收IPC传递的句柄后,用WebGPU API导入:
// 假设从主进程接收的句柄:macOS为ioSurfaceID,Windows为d3dHandleValue
async function importSharedTextureFromCPP(sharedHandleData) {
  const adapter = await navigator.gpu.requestAdapter();
  const device = await adapter.requestDevice();

  const textureDesc = {
    label: "ImportedSharedTexture",
    size: [1920, 1080],
    format: "bgra8unorm",
    usage: GPUTextureUsage.COPY_SRC | GPUTextureUsage.RENDER_ATTACHMENT
  };

  let sharedTexture;
  if (process.platform === "darwin") {
    sharedTexture = device.createFromSharedTextureHandle(
      sharedHandleData,
      textureDesc
    );
  } else if (process.platform === "win32") {
    sharedTexture = device.createFromSharedTextureHandle(
      BigInt(sharedHandleData),
      textureDesc
    );
  }

  // 后续可将纹理绑定到渲染管线或Canvas
  const textureView = sharedTexture.createView();
  // ... 渲染逻辑
}

二、浏览器端创建WebGPU纹理并传递给C++原生WebGPU

实现步骤

  1. 浏览器端创建可共享纹理
    创建纹理时开启shared属性,并指定合适的usage:
async function createSharedTextureForCPP() {
  const adapter = await navigator.gpu.requestAdapter();
  const device = await adapter.requestDevice();

  const textureDesc = {
    label: "SharedTextureFromBrowser",
    size: [1920, 1080],
    format: "bgra8unorm",
    usage: GPUTextureUsage.COPY_SRC | GPUTextureUsage.RENDER_ATTACHMENT,
    shared: true // 开启共享
  };

  const texture = device.createTexture(textureDesc);
  // 获取共享句柄
  const sharedHandle = await texture.getSharedTextureHandle();

  // 将句柄序列化为可IPC传输的数据
  let handleData;
  if (process.platform === "darwin") {
    // macOS下获取IOSurface ID
    handleData = await sharedHandle.getIOSurfaceID();
  } else if (process.platform === "win32") {
    // Windows下获取HANDLE数值
    handleData = Number(await sharedHandle.getHandle());
  }

  // 通过IPC将handleData传给主进程
  ipcRenderer.send("send-shared-texture-handle", handleData);
}
  1. C++端导入共享纹理
    主进程接收句柄后,用WebGPU C接口导入:
#include <webgpu/webgpu.h>

// 假设从渲染进程接收的句柄数据:macOS为ioSurfaceID,Windows为d3dHandleValue
void importSharedTextureFromBrowser(WGPUDevice device, uint64_t handleData) {
  WGPUSharedTextureHandleImportDescriptor importDesc = {};
  importDesc.nextInChain = nullptr;
  importDesc.label = "ImportedFromBrowser";
  importDesc.format = WGPUTextureFormat_BGRA8Unorm;
  importDesc.dimension = WGPUTextureDimension_2D;
  importDesc.size = {1920, 1080, 1};
  importDesc.mipLevelCount = 1;
  importDesc.sampleCount = 1;
  // 导入后的纹理usage
  importDesc.usage = WGPUTextureUsage_CopyDst | WGPUTextureUsage_RenderAttachment;

#ifdef __APPLE__
  // macOS通过IOSurface ID导入
  IOSurfaceRef iosurface = IOSurfaceLookup(handleData);
  importDesc.handle = reinterpret_cast<WGPUSharedTextureHandle>(iosurface);
#elif _WIN32
  // Windows通过HANDLE导入
  HANDLE d3dHandle = reinterpret_cast<HANDLE>(handleData);
  importDesc.handle = reinterpret_cast<WGPUSharedTextureHandle>(d3dHandle);
#endif

  WGPUTexture texture = wgpuDeviceImportSharedTextureHandle(device, &importDesc);
  // 后续使用纹理进行原生渲染或处理
}

内容的提问来源于stack exchange,提问作者Benoît Lahoz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 01:03:13