// Copyright 2020 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn/native/CopyTextureForBrowserHelper.h"

#include <unordered_set>
#include <utility>

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

namespace dawn::native {
namespace {
static const char sCopyForBrowserShader[] = R"(
                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. 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 {
                var color = textureSample(mySourceTexture, mySampler, texcoord);

                // TODO(crbug.com/tint/1723): Discard before sampling should be valid.
                discardIfOutsideOfCopy(texcoord);

                return transform(color);
            }

            @fragment
            fn copyExternalTexture(@location(0) texcoord : vec2f
            ) -> @location(0) vec4f {
                var color = textureSampleBaseClampToEdge(mySourceExternalTexture, mySampler, texcoord);

                // TODO(crbug.com/tint/1723): Discard before sampling should be valid.
                discardIfOutsideOfCopy(texcoord);

                return transform(color);
            }
        )";

// 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 {};
}

MaybeError ValidateCopyForBrowserDestinationFormat(const wgpu::TextureFormat dstFormat) {
    switch (dstFormat) {
        case wgpu::TextureFormat::R8Unorm:
        case wgpu::TextureFormat::R16Float:
        case wgpu::TextureFormat::R32Float:
        case wgpu::TextureFormat::RG8Unorm:
        case wgpu::TextureFormat::RG16Float:
        case wgpu::TextureFormat::RG32Float:
        case wgpu::TextureFormat::RGBA8Unorm:
        case wgpu::TextureFormat::RGBA8UnormSrgb:
        case wgpu::TextureFormat::BGRA8Unorm:
        case wgpu::TextureFormat::BGRA8UnormSrgb:
        case wgpu::TextureFormat::RGB10A2Unorm:
        case wgpu::TextureFormat::RGBA16Float:
        case wgpu::TextureFormat::RGBA32Float:
            break;
        default:
            return DAWN_VALIDATION_ERROR("Destination texture format (%s) is not supported.",
                                         dstFormat);
    }

    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 frgament stage.
    FragmentState fragment = {};
    fragment.module = shaderModule;
    fragment.entryPoint = fragmentEntryPoint;

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

    // 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;

    fragment.targetCount = 1;
    fragment.targets = &target;

    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.insert({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.insert({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 ImageCopyTexture* 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], decodingParams[1], decodingParams[2],
                                           decodingParams[3], decodingParams[4], decodingParams[5],
                                           decodingParams[6]};

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

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

        uniformData.gammaEncodingParams = {encodingParams[0], encodingParams[1], encodingParams[2],
                                           encodingParams[3], encodingParams[4], encodingParams[5],
                                           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.4, 1.0 / 1.055, 0.055 / 1.055, 1.0 / 12.92, 4.045e-02, 0.0, 0.0};
    }

    // 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.colorAttachmentCount = 1;
    renderPassDesc.colorAttachments = &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(destination->origin.x, destination->origin.y, copySize->width,
                                copySize->height, 0.0, 1.0);
    passEncoder->APIDraw(3);
    passEncoder->APIEnd();

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

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

MaybeError ValidateCopyForBrowserDestination(DeviceBase* device,
                                             const ImageCopyTexture& destination,
                                             const Extent3D& copySize,
                                             const CopyTextureForBrowserOptions& options) {
    DAWN_TRY(device->ValidateObject(destination.texture));
    DAWN_INVALID_IF(destination.texture->GetTextureState() == TextureBase::TextureState::Destroyed,
                    "Destination texture %s is destroyed.", destination.texture);
    DAWN_TRY_CONTEXT(ValidateImageCopyTexture(device, destination, copySize),
                     "validating the ImageCopyTexture 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));

    DAWN_INVALID_IF(destination.texture->GetSampleCount() > 1,
                    "The destination texture sample count (%u) is not 1.",
                    destination.texture->GetSampleCount());

    DAWN_TRY(ValidateCopyForBrowserDestinationFormat(destination.texture->GetFormat().format));

    // 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 ImageCopyTexture* source,
                                         const ImageCopyTexture* destination,
                                         const Extent3D* copySize,
                                         const CopyTextureForBrowserOptions* options) {
    // Validate source
    DAWN_TRY(device->ValidateObject(source->texture));
    DAWN_INVALID_IF(source->texture->GetTextureState() == TextureBase::TextureState::Destroyed,
                    "Source texture %s is destroyed.", source->texture);
    DAWN_TRY_CONTEXT(ValidateImageCopyTexture(device, *source, *copySize),
                     "validating the ImageCopyTexture 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(*source, *destination, *copySize));

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

    return {};
}

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

    Extent2D sourceSize;

    // TODO(crbug.com/dawn/1694): Remove this workaround that use visible rect
    // if natural size it not set after chromium side changes ready.
    if (source->naturalSize.width == 0) {
        sourceSize = source->externalTexture->GetVisibleSize();
    } else {
        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 ImageCopyTexture* destination,
                                           const Extent3D* copySize,
                                           const CopyTextureForBrowserOptions* options) {
    TextureInfo info;
    info.origin = source->origin;
    info.size = {source->naturalSize.width, source->naturalSize.height, 1};

    // TODO(crbug.com/dawn/1694): Remove this workaround that use visible rect
    // if natural size it not set after chromium side changes ready.
    if (info.size.width == 0) {
        const Extent2D& visibleSize = source->externalTexture->GetVisibleSize();
        info.size = {visibleSize.width, visibleSize.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 ImageCopyTexture* source,
                                   const ImageCopyTexture* destination,
                                   const Extent3D* copySize,
                                   const CopyTextureForBrowserOptions* options) {
    TextureInfo info;
    info.origin = source->origin;
    info.size = source->texture->GetSize();

    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
