alTexture: texture_external;

            fn discardIfOutsideOfCopy(texcoord : vec2f) {
                var clampedTexcoord =
                    clamp(texcoord, vec2f(0.0, 0.0), vec2f(1.0, 1.0));
                if (!all(clampedTexcoord == texcoord)) {
                    discard;
                }
            }

            fn transform(srcColor : vec4f) -> vec4f {
                var color = srcColor;
                let kUnpremultiplyStep = 0x01u;
                let kDecodeToLinearStep = 0x02u;
                let kConvertToDstGamutStep = 0x04u;
                let kEncodeToGammaStep = 0x08u;
                let kPremultiplyStep = 0x10u;
                let kDecodeForSrgbDstFormat = 0x20u;
                let kClearSrcAlphaToOne = 0x40u;

                // Unpremultiply step. Appling color space conversion op on premultiplied source texture
                // also needs to unpremultiply first.
                // This step is exclusive with clear src alpha to one step.
                if (bool(uniforms.steps_mask & kUnpremultiplyStep)) {
                    if (color.a != 0.0) {
                        color = vec4f(color.rgb / color.a, color.a);
                    }
                }

                // Linearize the source color using the source color space’s
                // transfer function if it is non-linear.
                if (bool(uniforms.steps_mask & kDecodeToLinearStep)) {
                    color = vec4f(gamma_conversion(color.r, uniforms.gamma_decoding_params),
                                      gamma_conversion(color.g, uniforms.gamma_decoding_params),
                                      gamma_conversion(color.b, uniforms.gamma_decoding_params),
                                      color.a);
                }

                // Convert unpremultiplied, linear source colors to the destination gamut by
                // multiplying by a 3x3 matrix. Calculate transformFromXYZD50 * transformToXYZD50
                // in CPU side and upload the final result in uniforms.
                if (bool(uniforms.steps_mask & kConvertToDstGamutStep)) {
                    color = vec4f(uniforms.conversion_matrix * color.rgb, color.a);
                }

                // Encode that color using the inverse of the destination color
                // space’s transfer function if it is non-linear.
                if (bool(uniforms.steps_mask & kEncodeToGammaStep)) {
                    color = vec4f(gamma_conversion(color.r, uniforms.gamma_encoding_params),
                                      gamma_conversion(color.g, uniforms.gamma_encoding_params),
                                      gamma_conversion(color.b, uniforms.gamma_encoding_params),
                                      color.a);
                }

                // Premultiply step.
                // This step is exclusive with clear src alpha to one step.
                if (bool(uniforms.steps_mask & kPremultiplyStep)) {
                    color = vec4f(color.rgb * color.a, color.a);
                }

                // Decode for copying from non-srgb formats to srgb formats
                if (bool(uniforms.steps_mask & kDecodeForSrgbDstFormat)) {
                    color = vec4f(gamma_conversion(color.r, uniforms.gamma_decoding_for_dst_srgb_params),
                                      gamma_conversion(color.g, uniforms.gamma_decoding_for_dst_srgb_params),
                                      gamma_conversion(color.b, uniforms.gamma_decoding_for_dst_srgb_params),
                                      color.a);
                }

                // Clear alpha to one step.
                // This step is exclusive with premultiply/unpremultiply step.
                if (bool(uniforms.steps_mask & kClearSrcAlphaToOne)) {
                    color.a = 1.0;
                }

                return color;
            }

            @fragment
            fn copyTexture(@location(0) texcoord : vec2f
            ) -> @location(0) vec4f {
                discardIfOutsideOfCopy(texcoord);

                var color = textureSample(mySourceTexture, mySampler, texcoord);
                return transform(color);
            }

            @fragment
            fn copyExternalTexture(@location(0) texcoord : vec2f
            ) -> @location(0) vec4f {
                discardIfOutsideOfCopy(texcoord);

                var color = textureSampleBaseClampToEdge(mySourceExternalTexture, mySampler, texcoord);
                return transform(color);
            }
        