// Copyright 2020 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/dawn/native/CopyTextureForBrowserHelper.h"

#include <utility>

#include "dawn/native/ValidationUtils_autogen.h"
#include "src/dawn/common/Strings.h"
#include "src/dawn/native/BindGroup.h"
#include "src/dawn/native/BindGroupLayout.h"
#include "src/dawn/native/Buffer.h"
#include "src/dawn/native/CommandBuffer.h"
#include "src/dawn/native/CommandEncoder.h"
#include "src/dawn/native/CommandValidation.h"
#include "src/dawn/native/Device.h"
#include "src/dawn/native/ExternalTexture.h"
#include "src/dawn/native/InternalPipelineStore.h"
#include "src/dawn/native/Queue.h"
#include "src/dawn/native/RenderPassEncoder.h"
#include "src/dawn/native/RenderPipeline.h"
#include "src/dawn/native/Sampler.h"
#include "src/dawn/native/Texture.h"
#include "src/dawn/native/utils/WGPUHelpers.h"
#include "src/utils/compiler.h"

namespace dawn::native {
namespace {
static const char sCopyForBrowserShader[] = DAWN_MULTILINE(
    struct GammaTransferParamsInternal {
        G: f32,
        A: f32,
        B: f32,
        C: f32,
        D: f32,
        E: f32,
        F: f32,
        padding: u32,
    };

    struct Uniforms {                                                     // offset   align   size
        scale: vec2f,                                                     // 0        8       8
        offset: vec2f,                                                    // 8        8       8
        steps_mask: u32,                                                  // 16       4       4
        // implicit padding;                                              // 20               12
        conversion_matrix: mat3x3<f32>,                                   // 32       16      48
        gamma_decoding_params: GammaTransferParamsInternal,               // 80       4       32
        gamma_encoding_params: GammaTransferParamsInternal,               // 112      4       32
        gamma_decoding_for_dst_srgb_params: GammaTransferParamsInternal,  // 144      4       32
    };

    @binding(0) @group(0) var<uniform> uniforms : Uniforms;

    struct VertexOutputs {
        @location(0) texcoords : vec2f,
        @builtin(position) position : vec4f,
    };

    // Chromium uses unified equation to construct gamma decoding function
    // and gamma encoding function.
    // The logic is:
    //  if x < D
    //      linear = C * x + F
    //  nonlinear = pow(A * x + B, G) + E
    // (https://source.chromium.org/chromium/chromium/src/+/main:ui/gfx/color_transform.cc;l=541)
    // Expand the equation with sign() to make it handle all gamma conversions.
    fn gamma_conversion(v: f32, params: GammaTransferParamsInternal) -> f32 {
        // Linear part: C * x + F
        if (abs(v) < params.D) {
            return sign(v) * (params.C * abs(v) + params.F);
        }

        // Gamma part: pow(A * x + B, G) + E
        return sign(v) * (pow(params.A * abs(v) + params.B, params.G) + params.E);
    }

    @vertex
    fn vs_main(
        @builtin(vertex_index) VertexIndex : u32
    ) -> VertexOutputs {
        var texcoord = array(
            vec2f(-0.5, 0.0),
            vec2f( 1.5, 0.0),
            vec2f( 0.5, 2.0));

        var output : VertexOutputs;
        output.position = vec4f((texcoord[VertexIndex] * 2.0 - vec2f(1.0, 1.0)), 0.0, 1.0);
        output.texcoords = texcoord[VertexIndex] * uniforms.scale + uniforms.offset;

        return output;
    }

    @binding(1) @group(0) var mySampler: sampler;

    // Resource used in copyTexture entry point only.
    @binding(2) @group(0) var mySourceTexture: texture_2d<f32>;

    // Resource used in copyExternalTexture entry point only.
    @binding(2) @group(0) var mySourceExternalTexture: 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. Applying 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);  // NOLINT(build/include_what_you_use)
    }
);

// Follow the same order of skcms_TransferFunction
// https://source.chromium.org/chromium/chromium/src/+/main:third_party/skia/include/third_party/skcms/skcms.h;l=46;
struct GammaTransferParamsInternal {
    float G = 0.0;
    float A = 0.0;
    float B = 0.0;
    float C = 0.0;
    float D = 0.0;
    float E = 0.0;
    float F = 0.0;
    uint32_t padding = 0;
};

struct Uniform {
    float scaleX;
    float scaleY;
    float offsetX;
    float offsetY;
    uint32_t stepsMask = 0;
    const std::array<uint32_t, 3> padding = {};  // 12 bytes padding
    std::array<float, 12> conversionMatrix = {};
    GammaTransferParamsInternal gammaDecodingParams = {};
    GammaTransferParamsInternal gammaEncodingParams = {};
    GammaTransferParamsInternal gammaDecodingForDstSrgbParams = {};
};
static_assert(sizeof(Uniform) == 176);

enum class SourceTextureType { Texture2D, ExternalTexture };

struct TextureInfo {
    Origin3D origin;
    Extent3D size;
};

// TODO(crbug.com/dawn/856): Expand copyTextureForBrowser to support any
// non-depth, non-stencil, non-compressed texture format pair copy.
MaybeError ValidateCopyTextureSourceFormat(const wgpu::TextureFormat srcFormat) {
    switch (srcFormat) {
        case wgpu::TextureFormat::BGRA8Unorm:
        case wgpu::TextureFormat::RGBA8Unorm:
        case wgpu::TextureFormat::RGBA16Float:
            break;
        default:
            return DAWN_VALIDATION_ERROR("Source texture format (%s) is not supported.", srcFormat);
    }

    return {};
}

RenderPipelineBase* GetCachedCopyTexturePipeline(InternalPipelineStore* store,
                                                 wgpu::TextureFormat dstFormat) {
    auto pipeline = store->copyTextureForBrowserPipelines.find(dstFormat);
    if (pipeline != store->copyTextureForBrowserPipelines.end()) {
        return pipeline->second.Get();
    }
    return nullptr;
}

RenderPipelineBase* GetCachedCopyExternalTexturePipeline(InternalPipelineStore* store,
                                                         wgpu::TextureFormat dstFormat) {
    auto pipeline = store->copyExternalTextureForBrowserPipelines.find(dstFormat);
    if (pipeline != store->copyExternalTextureForBrowserPipelines.end()) {
        return pipeline->second.Get();
    }
    return nullptr;
}

ResultOrError<Ref<RenderPipelineBase>> CreateCopyForBrowserPipeline(
    DeviceBase* device,
    wgpu::TextureFormat dstFormat,
    ShaderModuleBase* shaderModule,
    const char* fragmentEntryPoint) {
    // Prepare vertex stage.
    VertexState vertex = {};
    vertex.module = shaderModule;
    vertex.entryPoint = "vs_main";

    // Prepare color state.
    ColorTargetState target = {};
    target.format = dstFormat;

    // Prepare fragment stage.
    FragmentState fragment = {};
    fragment.module = shaderModule;
    fragment.entryPoint = fragmentEntryPoint;
    fragment.targets = SpanFromRef<ColorAttachmentIndex>(target);

    // Create RenderPipeline.
    RenderPipelineDescriptor renderPipelineDesc = {};
    // Generate the layout based on shader modules.
    renderPipelineDesc.layout = nullptr;
    renderPipelineDesc.vertex = vertex;
    renderPipelineDesc.fragment = &fragment;
    renderPipelineDesc.primitive.topology = wgpu::PrimitiveTopology::TriangleList;

    return device->CreateRenderPipeline(&renderPipelineDesc);
}

ResultOrError<ShaderModuleBase*> GetOrCreateCopyForBrowserShaderModule(
    DeviceBase* device,
    InternalPipelineStore* store) {
    if (store->copyForBrowser == nullptr) {
        DAWN_TRY_ASSIGN(store->copyForBrowser,
                        utils::CreateShaderModule(device, sCopyForBrowserShader));
    }

    return store->copyForBrowser.Get();
}

ResultOrError<RenderPipelineBase*> GetOrCreateCopyTextureForBrowserPipeline(
    DeviceBase* device,
    wgpu::TextureFormat dstFormat) {
    InternalPipelineStore* store = device->GetInternalPipelineStore();
    if (GetCachedCopyTexturePipeline(store, dstFormat) == nullptr) {
        ShaderModuleBase* shaderModule;
        DAWN_TRY_ASSIGN(shaderModule, GetOrCreateCopyForBrowserShaderModule(device, store));
        Ref<RenderPipelineBase> pipeline;
        DAWN_TRY_ASSIGN(
            pipeline, CreateCopyForBrowserPipeline(device, dstFormat, shaderModule, "copyTexture"));
        store->copyTextureForBrowserPipelines.emplace(dstFormat, std::move(pipeline));
    }

    return GetCachedCopyTexturePipeline(store, dstFormat);
}

ResultOrError<RenderPipelineBase*> GetOrCreateCopyExternalTextureForBrowserPipeline(
    DeviceBase* device,
    wgpu::TextureFormat dstFormat) {
    InternalPipelineStore* store = device->GetInternalPipelineStore();
    if (GetCachedCopyExternalTexturePipeline(store, dstFormat) == nullptr) {
        ShaderModuleBase* shaderModule;
        DAWN_TRY_ASSIGN(shaderModule, GetOrCreateCopyForBrowserShaderModule(device, store));
        Ref<RenderPipelineBase> pipeline;
        DAWN_TRY_ASSIGN(pipeline, CreateCopyForBrowserPipeline(device, dstFormat, shaderModule,
                                                               "copyExternalTexture"));
        store->copyExternalTextureForBrowserPipelines.emplace(dstFormat, std::move(pipeline));
    }

    return GetCachedCopyExternalTexturePipeline(store, dstFormat);
}

// Whether the format of dst texture of CopyTextureForBrowser() is srgb or non-srgb.
bool IsSrgbDstFormat(wgpu::TextureFormat format) {
    switch (format) {
        case wgpu::TextureFormat::RGBA8UnormSrgb:
        case wgpu::TextureFormat::BGRA8UnormSrgb:
            return true;
        default:
            return false;
    }
}

template <typename T>
MaybeError DoCopyForBrowser(DeviceBase* device,
                            const TextureInfo* sourceInfo,
                            T* sourceResource,
                            const TexelCopyTextureInfo* destination,
                            const Extent3D* copySize,
                            const CopyTextureForBrowserOptions* options,
                            RenderPipelineBase* pipeline) {
    // TODO(crbug.com/dawn/856): In D3D12 and Vulkan, compatible texture format can directly
    // copy to each other. This can be a potential fast path.

    // Noop copy
    if (copySize->width == 0 || copySize->height == 0 || copySize->depthOrArrayLayers == 0) {
        return {};
    }

    // Prepare bind group layout.
    Ref<BindGroupLayoutBase> layout;
    DAWN_TRY_ASSIGN(layout, pipeline->GetBindGroupLayout(0));

    // Prepare binding 0 resource: uniform buffer.
    Uniform uniformData = {
        copySize->width / static_cast<float>(sourceInfo->size.width),
        copySize->height / static_cast<float>(sourceInfo->size.height),  // scale
        sourceInfo->origin.x / static_cast<float>(sourceInfo->size.width),
        sourceInfo->origin.y / static_cast<float>(sourceInfo->size.height)  // offset
    };

    // The NDC to framebuffer space transform maps inverts the Y coordinate such that NDC [-1, 1]
    // (resp [-1, -1]) maps to framebuffer space [0, 0] (resp [0, height-1]). So we need to undo
    // this flip when converting positions to texcoords.
    // https://www.w3.org/TR/webgpu/#coordinate-systems
    if (!options->flipY) {
        uniformData.scaleY *= -1.0;
        uniformData.offsetY += copySize->height / static_cast<float>(sourceInfo->size.height);
    }

    uint32_t stepsMask = 0u;

    // Steps to do color space conversion
    // From https://skia.org/docs/user/color/
    // - unpremultiply if the source color is premultiplied; Alpha is not involved in color
    // management, and we need to divide it out if it’s multiplied in.
    // - linearize the source color using the source color space’s transfer function
    // - convert those unpremultiplied, linear source colors to XYZ D50 gamut by multiplying by
    // a 3x3 matrix.
    // - convert those XYZ D50 colors to the destination gamut by multiplying by a 3x3 matrix.
    // - encode that color using the inverse of the destination color space’s transfer function.
    // - premultiply by alpha if the destination is premultiplied.
    // The reason to choose XYZ D50 as intermediate color space:
    // From http://www.brucelindbloom.com/index.html?WorkingSpaceInfo.html
    // "Since the Lab TIFF specification, the ICC profile specification and
    // Adobe Photoshop all use a D50"
    constexpr uint32_t kUnpremultiplyStep = 0x01;
    constexpr uint32_t kDecodeToLinearStep = 0x02;
    constexpr uint32_t kConvertToDstGamutStep = 0x04;
    constexpr uint32_t kEncodeToGammaStep = 0x08;
    constexpr uint32_t kPremultiplyStep = 0x10;
    constexpr uint32_t kDecodeForSrgbDstFormat = 0x20;
    constexpr uint32_t kClearSrcAlphaToOne = 0x40;

    if (options->srcAlphaMode == wgpu::AlphaMode::Premultiplied) {
        if (options->needsColorSpaceConversion ||
            options->dstAlphaMode == wgpu::AlphaMode::Unpremultiplied) {
            stepsMask |= kUnpremultiplyStep;
        }
    } else if (options->srcAlphaMode == wgpu::AlphaMode::Opaque) {
        // Simply clear src alpha channel to 1.0
        stepsMask |= kClearSrcAlphaToOne;
    }

    if (options->needsColorSpaceConversion) {
        stepsMask |= kDecodeToLinearStep;
        const float* decodingParams = options->srcTransferFunctionParameters;

        uniformData.gammaDecodingParams = {decodingParams[0],
                                           DAWN_UNSAFE_TODO(decodingParams[1]),
                                           DAWN_UNSAFE_TODO(decodingParams[2]),
                                           DAWN_UNSAFE_TODO(decodingParams[3]),
                                           DAWN_UNSAFE_TODO(decodingParams[4]),
                                           DAWN_UNSAFE_TODO(decodingParams[5]),
                                           DAWN_UNSAFE_TODO(decodingParams[6])};

        stepsMask |= kConvertToDstGamutStep;
        const float* matrix = options->conversionMatrix;
        uniformData.conversionMatrix = {{
            matrix[0],
            DAWN_UNSAFE_TODO(matrix[1]),
            DAWN_UNSAFE_TODO(matrix[2]),
            0.0,
            DAWN_UNSAFE_TODO(matrix[3]),
            DAWN_UNSAFE_TODO(matrix[4]),
            DAWN_UNSAFE_TODO(matrix[5]),
            0.0,
            DAWN_UNSAFE_TODO(matrix[6]),
            DAWN_UNSAFE_TODO(matrix[7]),
            DAWN_UNSAFE_TODO(matrix[8]),
            0.0,
        }};

        stepsMask |= kEncodeToGammaStep;
        const float* encodingParams = options->dstTransferFunctionParameters;

        uniformData.gammaEncodingParams = {encodingParams[0],
                                           DAWN_UNSAFE_TODO(encodingParams[1]),
                                           DAWN_UNSAFE_TODO(encodingParams[2]),
                                           DAWN_UNSAFE_TODO(encodingParams[3]),
                                           DAWN_UNSAFE_TODO(encodingParams[4]),
                                           DAWN_UNSAFE_TODO(encodingParams[5]),
                                           DAWN_UNSAFE_TODO(encodingParams[6])};
    }

    if (options->dstAlphaMode == wgpu::AlphaMode::Premultiplied) {
        if (options->needsColorSpaceConversion ||
            options->srcAlphaMode == wgpu::AlphaMode::Unpremultiplied) {
            stepsMask |= kPremultiplyStep;
        }
    }

    // Copy to *-srgb texture should keep the bytes exactly the same as copy
    // to non-srgb texture. Add an extra decode-to-linear step so that after the
    // sampler of *-srgb format texture applying encoding, the bytes keeps the same
    // as non-srgb format texture.
    // NOTE: CopyTextureForBrowser() doesn't need to accept *-srgb format texture as
    // source input. But above operation also valid for *-srgb format texture input and
    // non-srgb format dst texture.
    // TODO(crbug.com/dawn/1195): Reinterpret to non-srgb texture view on *-srgb texture
    // and use it as render attachment when possible.
    // TODO(crbug.com/dawn/1195): Opt the condition for this extra step. It is possible to
    // bypass this extra step in some cases.
    bool isSrgbDstFormat = IsSrgbDstFormat(destination->texture->GetFormat().format);
    if (isSrgbDstFormat) {
        stepsMask |= kDecodeForSrgbDstFormat;
        // Get gamma-linear conversion params from https://en.wikipedia.org/wiki/SRGB with some
        // mathematics. Order: {G, A, B, C, D, E, F, }
        uniformData.gammaDecodingForDstSrgbParams = {
            2.4f, 1.0f / 1.055f, 0.055f / 1.055f, 1.0f / 12.92f, 4.045e-02f, 0.0f, 0.0f};
    }

    // Upload uniform data
    uniformData.stepsMask = stepsMask;

    Ref<BufferBase> uniformBuffer;
    DAWN_TRY_ASSIGN(
        uniformBuffer,
        utils::CreateBufferFromData(device, wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Uniform,
                                    {uniformData}));

    // Prepare binding 1 resource: sampler
    // Use default configuration, filterMode set to Nearest for min and mag.
    SamplerDescriptor samplerDesc = {};
    Ref<SamplerBase> sampler;
    DAWN_TRY_ASSIGN(sampler, device->CreateSampler(&samplerDesc));

    // Create bind group after all binding entries are set.
    UsageValidationMode mode =
        options->internalUsage ? UsageValidationMode::Internal : UsageValidationMode::Default;
    Ref<BindGroupBase> bindGroup;
    DAWN_TRY_ASSIGN(bindGroup, utils::MakeBindGroup(
                                   device, layout,
                                   {{0, uniformBuffer}, {1, sampler}, {2, sourceResource}}, mode));

    // Create command encoder.
    CommandEncoderDescriptor commandEncoderDesc;
    DawnEncoderInternalUsageDescriptor internalUsageDesc;
    if (options->internalUsage) {
        internalUsageDesc.useInternalUsages = true;
        commandEncoderDesc.nextInChain = &internalUsageDesc;
    }
    Ref<CommandEncoder> encoder;
    DAWN_TRY_ASSIGN(encoder, device->CreateCommandEncoder(&commandEncoderDesc));

    // Prepare dst texture view as color Attachment.
    TextureViewDescriptor dstTextureViewDesc;
    dstTextureViewDesc.dimension = wgpu::TextureViewDimension::e2D;
    dstTextureViewDesc.baseMipLevel = destination->mipLevel;
    dstTextureViewDesc.mipLevelCount = 1;
    dstTextureViewDesc.baseArrayLayer = destination->origin.z;
    dstTextureViewDesc.arrayLayerCount = 1;
    Ref<TextureViewBase> dstView;

    DAWN_TRY_ASSIGN(dstView, device->CreateTextureView(destination->texture, &dstTextureViewDesc));
    // Prepare render pass color attachment descriptor.
    RenderPassColorAttachment colorAttachmentDesc;

    colorAttachmentDesc.view = dstView.Get();
    colorAttachmentDesc.loadOp = wgpu::LoadOp::Load;
    colorAttachmentDesc.storeOp = wgpu::StoreOp::Store;
    colorAttachmentDesc.clearValue = {0.0, 0.0, 0.0, 1.0};

    // Create render pass.
    RenderPassDescriptor renderPassDesc;
    renderPassDesc.colorAttachments = SpanFromRef<ColorAttachmentIndex>(colorAttachmentDesc);
    Ref<RenderPassEncoder> passEncoder = encoder->BeginRenderPass(&renderPassDesc);

    // Start pipeline and encode commands to complete
    // the copy from src texture to dst texture with transformation.
    passEncoder->APISetPipeline(pipeline);
    passEncoder->APISetBindGroup(0, bindGroup.Get());
    passEncoder->APISetViewport(
        static_cast<float>(destination->origin.x), static_cast<float>(destination->origin.y),
        static_cast<float>(copySize->width), static_cast<float>(copySize->height), 0.0f, 1.0f);
    passEncoder->APIDraw(3);
    passEncoder->End();

    // Finsh encoding.
    Ref<CommandBufferBase> commandBuffer;
    DAWN_TRY_ASSIGN(commandBuffer, encoder->Finish());
    CommandBufferBase* submitCommandBuffer = commandBuffer.Get();

    // Submit command buffer.
    device->GetQueue()->APISubmit(SpanFromRef(submitCommandBuffer));
    return {};
}

MaybeError ValidateCopyForBrowserDestination(DeviceBase* device,
                                             const TexelCopyTextureInfo& destination,
                                             const Extent3D& copySize,
                                             const CopyTextureForBrowserOptions& options) {
    DAWN_TRY(device->ValidateObject(destination.texture));
    DAWN_TRY(destination.texture->ValidateCanUseInSubmitNow());
    DAWN_TRY_CONTEXT(ValidateTexelCopyTextureInfo(device, destination, copySize),
                     "validating the TexelCopyTextureInfo for the destination");
    DAWN_TRY_CONTEXT(ValidateTextureCopyRange(device, destination, copySize),
                     "validating that the copy fits in the destination");

    UsageValidationMode mode =
        options.internalUsage ? UsageValidationMode::Internal : UsageValidationMode::Default;
    DAWN_TRY(ValidateCanUseAs(destination.texture, wgpu::TextureUsage::CopyDst, mode));
    DAWN_TRY(ValidateCanUseAs(destination.texture, wgpu::TextureUsage::RenderAttachment, mode));
    const Format& dstFormat = destination.texture->GetFormat();
    DAWN_INVALID_IF(dstFormat.aspects != Aspect::Color,
                    "The destination %s is not a color texture.", destination.texture);
    DAWN_INVALID_IF(dstFormat.GetAspectInfo(Aspect::Color).baseType != TextureComponentType::Float,
                    "The destination %s must not be an integer format.", destination.texture);
    DAWN_INVALID_IF(destination.texture->GetSampleCount() > 1,
                    "The destination texture sample count (%u) is not 1.",
                    destination.texture->GetSampleCount());

    // The valid destination formats are all color formats.
    DAWN_INVALID_IF(
        destination.aspect != wgpu::TextureAspect::All,
        "Destination %s aspect (%s) doesn't select all the aspects of the destination format.",
        destination.texture, destination.aspect);

    return {};
}

MaybeError ValidateCopyForBrowserOptions(const CopyTextureForBrowserOptions& options) {
    DAWN_INVALID_IF(options.nextInChain != nullptr, "nextInChain must be nullptr");

    DAWN_TRY(ValidateAlphaMode(options.srcAlphaMode));
    DAWN_TRY(ValidateAlphaMode(options.dstAlphaMode));

    if (options.needsColorSpaceConversion) {
        DAWN_INVALID_IF(options.srcTransferFunctionParameters == nullptr,
                        "srcTransferFunctionParameters is nullptr when doing color conversion");
        DAWN_INVALID_IF(options.conversionMatrix == nullptr,
                        "conversionMatrix is nullptr when doing color conversion");
        DAWN_INVALID_IF(options.dstTransferFunctionParameters == nullptr,
                        "dstTransferFunctionParameters is nullptr when doing color conversion");
    }
    return {};
}
}  // anonymous namespace

MaybeError ValidateCopyTextureForBrowser(DeviceBase* device,
                                         const TexelCopyTextureInfo* source,
                                         const TexelCopyTextureInfo* destination,
                                         const Extent3D* copySize,
                                         const CopyTextureForBrowserOptions* options) {
    // Validate source
    DAWN_TRY(device->ValidateObject(source->texture));
    DAWN_TRY(source->texture->ValidateCanUseInSubmitNow());
    DAWN_TRY_CONTEXT(ValidateTexelCopyTextureInfo(device, *source, *copySize),
                     "validating the TexelCopyTextureInfo for the source");
    DAWN_TRY_CONTEXT(ValidateTextureCopyRange(device, *source, *copySize),
                     "validating that the copy fits in the source");
    DAWN_INVALID_IF(source->origin.z > 0, "Source has a non-zero z origin (%u).", source->origin.z);
    DAWN_INVALID_IF(source->texture->GetSampleCount() > 1,
                    "The source texture sample count (%u) is not 1. ",
                    source->texture->GetSampleCount());
    DAWN_INVALID_IF(
        options->internalUsage && !device->HasFeature(Feature::DawnInternalUsages),
        "The internalUsage is true while the dawn-internal-usages feature is not enabled.");
    UsageValidationMode mode =
        options->internalUsage ? UsageValidationMode::Internal : UsageValidationMode::Default;
    DAWN_TRY(ValidateCanUseAs(source->texture, wgpu::TextureUsage::CopySrc, mode));
    DAWN_TRY(ValidateCanUseAs(source->texture, wgpu::TextureUsage::TextureBinding, mode));
    DAWN_TRY(ValidateCopyTextureSourceFormat(source->texture->GetFormat().format));

    // Validate destination
    DAWN_TRY(ValidateCopyForBrowserDestination(device, *destination, *copySize, *options));

    // Validate copy common rules and copySize.
    DAWN_INVALID_IF(copySize->depthOrArrayLayers > 1, "Copy is for more than one array layer (%u)",
                    copySize->depthOrArrayLayers);
    DAWN_TRY(
        ValidateTextureToTextureCopyCommonRestrictions(device, *source, *destination, *copySize));

    // Validate options
    DAWN_TRY(ValidateCopyForBrowserOptions(*options));

    return {};
}

MaybeError ValidateCopyExternalTextureForBrowser(DeviceBase* device,
                                                 const ImageCopyExternalTexture* source,
                                                 const TexelCopyTextureInfo* destination,
                                                 const Extent3D* copySize,
                                                 const CopyTextureForBrowserOptions* options) {
    // Validate source
    DAWN_TRY(device->ValidateObject(source->externalTexture));
    DAWN_TRY(source->externalTexture->ValidateCanUseInSubmitNow());

    Extent2D sourceSize = {};
    sourceSize.width = source->naturalSize.width;
    sourceSize.height = source->naturalSize.height;

    // All texture dimensions are in uint32_t so by doing checks in uint64_t we avoid
    // overflows.
    DAWN_INVALID_IF(
        static_cast<uint64_t>(source->origin.x) + static_cast<uint64_t>(copySize->width) >
                static_cast<uint64_t>(sourceSize.width) ||
            static_cast<uint64_t>(source->origin.y) + static_cast<uint64_t>(copySize->height) >
                static_cast<uint64_t>(sourceSize.height) ||
            static_cast<uint64_t>(source->origin.z) > 0,
        "Texture copy range (origin: %s, copySize: %s) touches outside of %s source size (%s).",
        source->origin, *copySize, source->externalTexture, sourceSize);
    DAWN_INVALID_IF(source->origin.z > 0, "Source has a non-zero z origin (%u).", source->origin.z);
    DAWN_INVALID_IF(
        options->internalUsage && !device->HasFeature(Feature::DawnInternalUsages),
        "The internalUsage is true while the dawn-internal-usages feature is not enabled.");

    // Validate destination
    DAWN_TRY(ValidateCopyForBrowserDestination(device, *destination, *copySize, *options));

    // Validate copySize
    DAWN_INVALID_IF(copySize->depthOrArrayLayers > 1, "Copy is for more than one array layer (%u)",
                    copySize->depthOrArrayLayers);

    // Validate options
    DAWN_TRY(ValidateCopyForBrowserOptions(*options));

    return {};
}

MaybeError DoCopyExternalTextureForBrowser(DeviceBase* device,
                                           const ImageCopyExternalTexture* source,
                                           const TexelCopyTextureInfo* destination,
                                           const Extent3D* copySize,
                                           const CopyTextureForBrowserOptions* options) {
    TextureInfo info;
    info.origin = source->origin;
    info.size = {source->naturalSize.width, source->naturalSize.height, 1};

    RenderPipelineBase* pipeline;
    DAWN_TRY_ASSIGN(pipeline, GetOrCreateCopyExternalTextureForBrowserPipeline(
                                  device, destination->texture->GetFormat().format));
    return DoCopyForBrowser<ExternalTextureBase>(device, &info, source->externalTexture,
                                                 destination, copySize, options, pipeline);
}

MaybeError DoCopyTextureForBrowser(DeviceBase* device,
                                   const TexelCopyTextureInfo* source,
                                   const TexelCopyTextureInfo* destination,
                                   const Extent3D* copySize,
                                   const CopyTextureForBrowserOptions* options) {
    TextureInfo info;
    info.origin = source->origin;
    info.size = source->texture->GetSize(source->aspect);

    Ref<TextureViewBase> srcTextureView = nullptr;
    TextureViewDescriptor srcTextureViewDesc = {};
    srcTextureViewDesc.dimension = wgpu::TextureViewDimension::e2D;
    srcTextureViewDesc.baseMipLevel = source->mipLevel;
    srcTextureViewDesc.mipLevelCount = 1;
    srcTextureViewDesc.arrayLayerCount = 1;
    DAWN_TRY_ASSIGN(srcTextureView,
                    device->CreateTextureView(source->texture, &srcTextureViewDesc));

    RenderPipelineBase* pipeline;
    DAWN_TRY_ASSIGN(pipeline, GetOrCreateCopyTextureForBrowserPipeline(
                                  device, destination->texture->GetFormat().format));

    return DoCopyForBrowser<TextureViewBase>(device, &info, srcTextureView.Get(), destination,
                                             copySize, options, pipeline);
}
}  // namespace dawn::native
