UNPKG

pixi.js

Version:

<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">

1 lines 12.6 kB
{"version":3,"file":"ExternalSource.mjs","sources":["../../../../../../src/rendering/renderers/shared/texture/sources/ExternalSource.ts"],"sourcesContent":["import { GlTexture } from '../../../gl/texture/GlTexture';\nimport { GPUTextureGpuData } from '../../../gpu/texture/GpuTextureSystem';\nimport { type Renderer, RendererType } from '../../../types';\nimport { TextureSource } from './TextureSource';\n\n// Shared placeholders - created lazily, reused by all ExternalSource instances\nconst placeholderGl: Record<number, WebGLTexture> = Object.create(null);\nconst placeholderGpu: Record<number, GPUTexture> = Object.create(null);\n\nfunction getPlaceholder(renderer: Renderer): GPUTexture | WebGLTexture\n{\n if (renderer.type === RendererType.WEBGPU)\n {\n placeholderGpu[renderer.uid] ||= (renderer as any).gpu.device.createTexture({\n label: 'ExternalSource placeholder',\n size: { width: 1, height: 1 },\n format: 'rgba8unorm',\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,\n });\n\n return placeholderGpu[renderer.uid];\n }\n\n if (!placeholderGl[renderer.uid])\n {\n const gl = (renderer as any).gl as WebGLRenderingContext;\n const texture = gl.createTexture();\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n\n placeholderGl[renderer.uid] = texture;\n }\n\n return placeholderGl[renderer.uid];\n}\n\n/**\n * Options for creating an ExternalSource.\n * @category rendering\n * @advanced\n */\nexport interface ExternalSourceOptions\n{\n /**\n * The external GPU texture (GPUTexture for WebGPU, WebGLTexture for WebGL).\n * If not provided, a shared 1x1 placeholder texture will be used until\n * `updateGPUTexture()` is called.\n * @advanced\n */\n resource?: GPUTexture | WebGLTexture;\n /**\n * The renderer this texture will be used with\n * @advanced\n */\n renderer: Renderer;\n /**\n * Width of the texture. Auto-detected for GPUTexture, required for WebGLTexture.\n * @advanced\n */\n width?: number;\n /**\n * Height of the texture. Auto-detected for GPUTexture, required for WebGLTexture.\n * @advanced\n */\n height?: number;\n /**\n * Optional label for debugging\n * @advanced\n */\n label?: string;\n}\n\n/**\n * A texture source that uses a GPU texture from an external library (e.g., Three.js).\n *\n * This allows sharing textures between PixiJS and other WebGL/WebGPU libraries without\n * re-uploading pixel data. The renderer is required so that ExternalSource can\n * pre-populate the GPU data and validate context ownership.\n * @example\n * ```typescript\n * // WebGPU - dimensions auto-detected\n * const texture = new Texture({\n * source: new ExternalSource({\n * resource: threeJsGpuTexture,\n * renderer: renderer,\n * })\n * });\n *\n * // WebGL - must provide dimensions (WebGLTexture is opaque)\n * const texture = new Texture({\n * source: new ExternalSource({\n * resource: threeJsGlTexture,\n * renderer: renderer,\n * width: 512,\n * height: 512,\n * })\n * });\n *\n * // Update to a new external texture\n * (texture.source as ExternalSource).updateGPUTexture(newExternalTexture);\n * ```\n * @category rendering\n * @advanced\n */\nexport class ExternalSource extends TextureSource<GPUTexture | WebGLTexture>\n{\n private readonly _renderer: Renderer;\n\n constructor({ resource, renderer, label, width, height }: ExternalSourceOptions)\n {\n resource ||= getPlaceholder(renderer);\n width ||= width ?? (resource as GPUTexture)?.width ?? 1;\n height ||= height ?? (resource as GPUTexture)?.height ?? 1;\n\n // Only pass the minimal required options to TextureSource\n super({\n resource,\n width,\n height,\n label,\n // External textures shouldn't be garbage collected - the external library owns them\n autoGarbageCollect: false,\n });\n\n this._renderer = renderer;\n\n // Pre-populate _gpuData\n this._initGpuData(resource);\n }\n\n /**\n * Test if a resource is a valid external GPU texture.\n * @param resource - The resource to test\n * @returns True if the resource is a GPUTexture or WebGLTexture\n */\n public static test(resource: unknown): resource is GPUTexture | WebGLTexture\n {\n return (\n (globalThis.GPUTexture && resource instanceof GPUTexture)\n || (globalThis.WebGLTexture && resource instanceof WebGLTexture)\n );\n }\n\n private _validateTexture(resource: GPUTexture | WebGLTexture): void\n {\n const renderer = this._renderer;\n const isWebGPU = !!(renderer as any).gpu;\n const isGPUTexture = globalThis.GPUTexture && resource instanceof GPUTexture;\n const isWebGLTexture = globalThis.WebGLTexture && resource instanceof WebGLTexture;\n\n if (isWebGPU && isWebGLTexture)\n {\n throw new Error('Cannot use WebGLTexture with a WebGPU renderer');\n }\n\n if (!isWebGPU && isGPUTexture)\n {\n throw new Error('Cannot use GPUTexture with a WebGL renderer');\n }\n\n // WebGL context ownership check\n if (!isWebGPU)\n {\n const gl = (renderer as any).gl;\n\n if (gl && !gl.isTexture(resource as WebGLTexture))\n {\n throw new Error('WebGLTexture does not belong to this renderer\\'s WebGL context');\n }\n }\n }\n\n private _initGpuData(resource: GPUTexture | WebGLTexture): void\n {\n const renderer = this._renderer;\n\n this._validateTexture(resource);\n\n if ((renderer as any).gpu)\n {\n // WebGPU\n this._gpuData[renderer.uid] = new GPUTextureGpuData(resource as GPUTexture);\n }\n else\n {\n // WebGL\n this._gpuData[renderer.uid] = new GlTexture(resource as WebGLTexture);\n }\n }\n\n /**\n * Update the external GPU texture reference.\n * Call this when the external library provides a new texture.\n * @param gpuTexture - The new GPU texture\n * @param width - New width (required for WebGLTexture, auto-detected for GPUTexture)\n * @param height - New height (required for WebGLTexture, auto-detected for GPUTexture)\n */\n public updateGPUTexture(gpuTexture: GPUTexture | WebGLTexture, width?: number, height?: number): void\n {\n const renderer = this._renderer;\n const gpuData = this._gpuData[renderer.uid];\n\n // Update the resource property to reflect the new texture\n this.resource = gpuTexture;\n\n if ((renderer as any).gpu)\n {\n // WebGPU - validate and update\n this._validateTexture(gpuTexture);\n\n const data = gpuData as GPUTextureGpuData;\n\n if (data.gpuTexture !== gpuTexture)\n {\n data.gpuTexture = gpuTexture as GPUTexture;\n data.textureView = null;\n\n // Invalidate bind group hash\n const textureSystem = (renderer as any).texture;\n\n if (textureSystem?._bindGroupHash)\n {\n textureSystem._bindGroupHash[this.uid] = null;\n }\n }\n\n // Update dimensions from GPUTexture (or use provided values)\n const newWidth = width ?? (gpuTexture as GPUTexture).width;\n const newHeight = height ?? (gpuTexture as GPUTexture).height;\n\n this.resize(newWidth, newHeight);\n }\n else\n {\n // WebGL - validate and update the texture reference\n this._validateTexture(gpuTexture);\n\n const data = gpuData as GlTexture;\n\n data.texture = gpuTexture as WebGLTexture;\n\n // WebGL: dimensions must be provided (WebGLTexture is opaque)\n if (width !== undefined && height !== undefined)\n {\n this.resize(width, height);\n }\n }\n\n this.emit('update', this);\n }\n\n public override destroy(): void\n {\n // Never destroy the GPU texture:\n // - Placeholder is shared across all instances\n // - External textures are owned by the external library\n const renderer = this._renderer;\n\n delete this._gpuData[renderer.uid];\n\n super.destroy();\n }\n}\n"],"names":[],"mappings":"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"}