这是indexloc提供的服务,不要输入任何密码
Skip to content

Colorspace conversions for GPUExternalTexture are arbitrarily complex #3293

@litherum

Description

@litherum

[Migrated from #3288]

Videos can embed arbitrary ICC profile information within themselves to describe the colorspace their texels are in. ICC profiles are not Turing-complete, but are arbitrarily complex - they're described as a vector of transformations of various forms. Each frame of a video can be in a different colorspace (though this is very rare).

When compiling the shader, we don't know which colorspace conversion we're going to have to be implementing in the shader.

I'm also coming from the perspective that, for the 3d video use case, if a full full-res copy is performed, that will be catastrophic enough that it would break the whole illusion of the video playback (particularly on mobile devices).

Here are some ideas:

  1. Have the browser internally support a fixed-set of classes-of-colorspaces in the code it emits, and if someone imports a GPUExternalTexture using an incompatible colorspace, then that import operation silently involves a copy (at full res, no less). Authors would have no way of knowing which browsers support which colorspaces.
    1. Have the WebGPU spec list which colorspaces must be supported.
  2. Encode ICC profile information as variable-length data, and include that with all the other GPUExternalTexture data sent to the shader (crop rect, rotation, etc.). Consume the whole ICC profile in the shader.
    1. Do this, but also special-case some of the more common colorspaces (to avoid the variable-length consumption loop in the common case).
  3. Recompile the shader at draw-call time.
    1. Use something like MTLDynamicLibrary to compile just the sample operation at draw call time. This only works on some shaders on some devices.
  4. Give authors the ability to interact with the zero-copy / one-copy distinction. Add an intentionally one-copy GPUQueue.writeTexture() overload that accepts an HTMLVideoElement (and possibly a crop rect?). This option comes in a few different flavors:
    1. Make importExternalTexture() fail when importing a video frame using an unsupported colorspace. The page can react by using the explicit one-copy writeTexture().
    2. Add a failIfMajorPerformanceCaveat bool switch into GPUExternalTextureDescriptor. This is a way for an author to say "give me the fast mode or give me nothing at all"
    3. Make failIfMajorPerformanceCaveat be the default, and add a dontFailIfMajorPerformanceCaveat bool switch instead. We'd probably have to add in a region-of-interest rect into the GPUExternalTextureDescriptor if we did this, so we didn't end up silently copying the whole image.
  5. Add the GPUExternalTextureDescriptor itself to createShaderModule(). This isn't perfect because 1) the video may not be loaded yet, and 2) each frame of the video can technically be in a different colorspace. We may be able to solve (1) by specifying the state the video needs to be in, and (2) may be rare enough that it may not be a problem.
  6. Do it like GPUTextureDescriptor.viewFormats: Give a way for an author to describe a colorspace to us, and have them do that at createShaderModule() time.

Maybe there are more possibilities!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions