// 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 <string>
#include <vector>

#include "src/dawn/common/Constants.h"
#include "src/dawn/common/Math.h"
#include "src/dawn/tests/DawnTest.h"
#include "src/dawn/utils/ComboRenderPipelineDescriptor.h"
#include "src/dawn/utils/TestUtils.h"
#include "src/dawn/utils/TextureUtils.h"
#include "src/dawn/utils/WGPUHelpers.h"

// TODO(dawn:2205) Remove these stream operators if we move them to a standard location.
namespace wgpu {
std::ostream& operator<<(std::ostream& o, Origin3D origin) {
    o << origin.x << ", " << origin.y << ", " << origin.z;
    return o;
}

std::ostream& operator<<(std::ostream& o, Extent3D copySize) {
    o << copySize.width << ", " << copySize.height << ", " << copySize.depthOrArrayLayers;
    return o;
}
}  // namespace wgpu

namespace dawn {
namespace {

static constexpr wgpu::TextureFormat kTextureFormat = wgpu::TextureFormat::RGBA8Unorm;

// Set default texture size to single line texture for color conversion tests.
static constexpr uint64_t kDefaultTextureWidth = 10;
static constexpr uint64_t kDefaultTextureHeight = 1;

enum class ColorSpace : uint32_t {
    SRGB = 0x00,
    DisplayP3 = 0x01,
};

using SrcFormat = wgpu::TextureFormat;
using DstFormat = wgpu::TextureFormat;
using SrcOrigin = wgpu::Origin3D;
using DstOrigin = wgpu::Origin3D;
using CopySize = wgpu::Extent3D;
using FlipY = bool;
using SrcColorSpace = ColorSpace;
using DstColorSpace = ColorSpace;
using SrcAlphaMode = wgpu::AlphaMode;
using DstAlphaMode = wgpu::AlphaMode;

std::ostream& operator<<(std::ostream& o, ColorSpace space) {
    o << static_cast<uint32_t>(space);
    return o;
}

DAWN_TEST_PARAM_STRUCT(AlphaTestParams, SrcAlphaMode, DstAlphaMode);
DAWN_TEST_PARAM_STRUCT(FormatTestParams, SrcFormat, DstFormat);
DAWN_TEST_PARAM_STRUCT(SubRectTestParams, SrcOrigin, DstOrigin, CopySize, FlipY);
DAWN_TEST_PARAM_STRUCT(ColorSpaceTestParams,
                       DstFormat,
                       SrcColorSpace,
                       DstColorSpace,
                       SrcAlphaMode,
                       DstAlphaMode);

// Color Space table
struct ColorSpaceInfo {
    ColorSpace index;
    std::array<float, 9> toXYZD50;             // 3x3 row major transform matrix
    std::array<float, 9> fromXYZD50;           // inverse transform matrix of toXYZD50, precomputed
    std::array<float, 7> gammaDecodingParams;  // Follow { A, B, G, E, epsilon, C, F } order
    std::array<float, 7> gammaEncodingParams;  // inverse op of decoding, precomputed
    bool isNonLinear;
    bool isExtended;  // For extended color space.
};
static constexpr size_t kSupportedColorSpaceCount = 2;
static constexpr std::array<ColorSpaceInfo, kSupportedColorSpaceCount> ColorSpaceTable = {{
    // sRGB,
    // Got primary attributes from https://drafts.csswg.org/css-color/#predefined-sRGB
    // Use matrices from
    // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html#WSMatrices
    // Get gamma-linear conversion params from https://en.wikipedia.org/wiki/SRGB with some
    // mathematics.
    {
        //
        ColorSpace::SRGB,
        {{
            //
            0.4360747, 0.3850649, 0.1430804,  //
            0.2225045, 0.7168786, 0.0606169,  //
            0.0139322, 0.0971045, 0.7141733   //
        }},

        {{
            //
            3.1338561, -1.6168667, -0.4906146,  //
            -0.9787684, 1.9161415, 0.0334540,   //
            0.0719453, -0.2289914, 1.4052427    //
        }},

        // {G, A, B, C, D, E, F, }
        {{2.4, 1.0 / 1.055, 0.055 / 1.055, 1.0 / 12.92, 4.045e-02, 0.0, 0.0}},

        {{1.0 / 2.4, 1.13711 /*pow(1.055, 2.4)*/, 0.0, 12.92f, 3.1308e-03, -0.055, 0.0}},

        true,
        true  //
    },

    // Display P3, got primary attributes from
    // https://www.w3.org/TR/css-color-4/#valdef-color-display-p3
    // Use equations found in
    // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html,
    // Use Bradford method to do D65 to D50 transform.
    // Get matrices with help of http://www.russellcottrell.com/photo/matrixCalculator.htm
    // Gamma-linear conversion params is the same as Srgb.
    {
        //
        ColorSpace::DisplayP3,
        {{
            //
            0.5151114, 0.2919612, 0.1571274,  //
            0.2411865, 0.6922440, 0.0665695,  //
            -0.0010491, 0.0418832, 0.7842659  //
        }},

        {{
            //
            2.4039872, -0.9898498, -0.3976181,  //
            -0.8422138, 1.7988188, 0.0160511,   //
            0.0481937, -0.0973889, 1.2736887    //
        }},

        // {G, A, B, C, D, E, F, }
        {{2.4, 1.0 / 1.055, 0.055 / 1.055, 1.0 / 12.92, 4.045e-02, 0.0, 0.0}},

        {{1.0 / 2.4, 1.13711 /*pow(1.055, 2.4)*/, 0.0, 12.92f, 3.1308e-03, -0.055, 0.0}},

        true,
        false  //
    }
    //
}};

template <typename Parent>
class CopyTextureForBrowserTests : public Parent {
  protected:
    struct TextureSpec {
        wgpu::Origin3D copyOrigin = {};
        wgpu::Extent3D textureSize = {kDefaultTextureWidth, kDefaultTextureHeight};
        uint32_t level = 0;
        wgpu::TextureFormat format = kTextureFormat;
    };

    enum class TextureCopyRole {
        SOURCE,
        DEST,
    };

    // Source texture contains red pixels and dst texture contains green pixels at start.
    static std::vector<utils::RGBA8> GetTextureData(
        const utils::TextureDataCopyLayout& layout,
        TextureCopyRole textureRole,
        wgpu::AlphaMode srcAlphaMode = wgpu::AlphaMode::Premultiplied,
        wgpu::AlphaMode dstAlphaMode = wgpu::AlphaMode::Unpremultiplied) {
        std::array<uint8_t, 4> alpha = {0, 102, 153, 255};  // 0.0, 0.4, 0.6, 1.0
        std::vector<utils::RGBA8> textureData(layout.texelBlockCount);
        for (uint32_t layer = 0; layer < layout.mipSize.depthOrArrayLayers; ++layer) {
            const uint32_t sliceOffset = layout.texelBlocksPerImage * layer;
            for (uint32_t y = 0; y < layout.mipSize.height; ++y) {
                const uint32_t rowOffset = layout.texelBlocksPerRow * y;
                for (uint32_t x = 0; x < layout.mipSize.width; ++x) {
                    // Source textures will have variable pixel data to cover cases like
                    // flipY.
                    if (textureRole == TextureCopyRole::SOURCE) {
                        if (srcAlphaMode == wgpu::AlphaMode::Unpremultiplied &&
                            dstAlphaMode == wgpu::AlphaMode::Premultiplied) {
                            // We expect each channel in dst
                            // texture will equal to the alpha channel value.
                            textureData[sliceOffset + rowOffset + x] = utils::RGBA8(
                                static_cast<uint8_t>(255), static_cast<uint8_t>(255),
                                static_cast<uint8_t>(255), static_cast<uint8_t>(alpha[x % 4]));
                        } else if (srcAlphaMode == wgpu::AlphaMode::Premultiplied &&
                                   dstAlphaMode == wgpu::AlphaMode::Unpremultiplied) {
                            // We expect each channel in dst
                            // texture will equal to 1.0.
                            textureData[sliceOffset + rowOffset + x] =
                                utils::RGBA8(static_cast<uint8_t>(alpha[x % 4]),
                                             static_cast<uint8_t>(alpha[x % 4]),
                                             static_cast<uint8_t>(alpha[x % 4]),
                                             static_cast<uint8_t>(alpha[x % 4]));
                        } else {
                            textureData[sliceOffset + rowOffset + x] = utils::RGBA8(
                                static_cast<uint8_t>((x + layer * x) % 256),
                                static_cast<uint8_t>((y + layer * y) % 256),
                                static_cast<uint8_t>(x % 256), static_cast<uint8_t>(x % 256));
                        }
                    } else {  // Dst textures will have be init as `green` to ensure subrect
                              // copy not cross bound.
                        textureData[sliceOffset + rowOffset + x] =
                            utils::RGBA8(static_cast<uint8_t>(0), static_cast<uint8_t>(255),
                                         static_cast<uint8_t>(0), static_cast<uint8_t>(255));
                    }
                }
            }
        }

        return textureData;
    }

    void SetUp() override {
        Parent::SetUp();

        // TODO(crbug.com/40238674): Fails on Pixel 10 gles on compilation so it must be skipped at
        // this level.
        DAWN_SUPPRESS_TEST_IF(this->IsImgTec() && this->IsOpenGLES());

        pipeline = MakeTestPipeline();

        uint32_t uniformBufferData[] = {
            0,  // copy have flipY option
            4,  // channelCount
            0,
            0,  // uvec2, subrect copy src origin
            0,
            0,  // uvec2, subrect copy dst origin
            0,
            0,                                                      // uvec2, subrect copy size
            static_cast<uint32_t>(wgpu::AlphaMode::Premultiplied),  // srcAlphaMode
            static_cast<uint32_t>(wgpu::AlphaMode::Premultiplied),  // dstAlphaMode
        };

        wgpu::BufferDescriptor uniformBufferDesc = {};
        uniformBufferDesc.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Uniform;
        uniformBufferDesc.size = sizeof(uniformBufferData);
        uniformBuffer = this->device.CreateBuffer(&uniformBufferDesc);
    }

    // Do the bit-by-bit comparison between the source and destination texture with GPU (compute
    // shader) instead of CPU after executing CopyTextureForBrowser() to avoid the errors caused by
    // comparing a value generated on CPU to the one generated on GPU.
    wgpu::ComputePipeline MakeTestPipeline() {
        std::string shader =
            R"(
            struct Uniforms {
                dstTextureFlipY : u32,
                channelCount    : u32,
                srcCopyOrigin   : vec2u,
                dstCopyOrigin   : vec2u,
                copySize        : vec2u,
                srcAlphaMode    : u32,
                dstAlphaMode    : u32,
            }
            struct OutputBuf {
                result : array<u32>
            }
            @group(0) @binding(0) var src : texture_2d<f32>;
            @group(0) @binding(1) var dst : texture_2d<f32>;
            @group(0) @binding(2) var<storage, read_write> output : OutputBuf;
            @group(0) @binding(3) var<uniform> uniforms : Uniforms;
            fn aboutEqual(value : f32, expect : f32) -> bool {
                // The value diff should be smaller than the hard coded tolerance.
                return abs(value - expect) < 0.01;
            }
            @compute @workgroup_size(1, 1, 1)
            fn main(@builtin(global_invocation_id) GlobalInvocationID : vec3u) {
                let srcSize = textureDimensions(src);
                let dstSize = textureDimensions(dst);
                let dstTexCoord = vec2u(GlobalInvocationID.xy);
                let nonCoveredColor = vec4f(0.0, 1.0, 0.0, 1.0); // should be green

                var success : bool = true;
                if (dstTexCoord.x < uniforms.dstCopyOrigin.x ||
                    dstTexCoord.y < uniforms.dstCopyOrigin.y ||
                    dstTexCoord.x >= uniforms.dstCopyOrigin.x + uniforms.copySize.x ||
                    dstTexCoord.y >= uniforms.dstCopyOrigin.y + uniforms.copySize.y) {
                    success = success &&
                              all(textureLoad(dst, vec2i(dstTexCoord), 0) == nonCoveredColor);
                } else {
                    // Calculate source texture coord.
                    var srcTexCoordInRect = dstTexCoord - uniforms.dstCopyOrigin;

                    // Note that |flipY| equals flip src texture in copy sub rect.
                    if (uniforms.dstTextureFlipY == 1u) {
                        srcTexCoordInRect.y = uniforms.copySize.y - srcTexCoordInRect.y - 1;
                    }

                    var srcTexCoord = srcTexCoordInRect + uniforms.srcCopyOrigin;

                    var srcColor = textureLoad(src, vec2i(srcTexCoord), 0);
                    var dstColor = textureLoad(dst, vec2i(dstTexCoord), 0);

                    // Expect the dst texture channels should be all equal to alpha value
                    // after premultiply.
                    let premultiplied = )" +
            std::to_string(static_cast<uint32_t>(wgpu::AlphaMode::Premultiplied)) + R"(u;
                    let unpremultiplied = )" +
            std::to_string(static_cast<uint32_t>(wgpu::AlphaMode::Unpremultiplied)) + R"(u;
                    let opaque = )" +
            std::to_string(static_cast<uint32_t>(wgpu::AlphaMode::Opaque)) + R"(u;
                    if (uniforms.srcAlphaMode == opaque) {
                        srcColor.a = 1.0;
                    }

                    if (uniforms.srcAlphaMode == unpremultiplied && uniforms.dstAlphaMode == premultiplied) {
                        srcColor = vec4f(srcColor.rgb * srcColor.a, srcColor.a);
                    }

                    if (uniforms.srcAlphaMode == premultiplied && uniforms.dstAlphaMode == unpremultiplied) {
                        if (srcColor.a != 0.0) {
                            srcColor = vec4f(srcColor.rgb / srcColor.a, srcColor.a);
                        }
                    }

                    // Not use loop and variable index format to workaround
                    // crbug.com/tint/638.
                    switch(uniforms.channelCount) {
                        case 1u: {
                            success = success && aboutEqual(dstColor.r, srcColor.r);
                            break;
                        }
                        case 2u: {
                            success = success &&
                                      aboutEqual(dstColor.r, srcColor.r) &&
                                      aboutEqual(dstColor.g, srcColor.g);
                            break;
                        }
                        case 4u: {
                            success = success &&
                                      aboutEqual(dstColor.r, srcColor.r) &&
                                      aboutEqual(dstColor.g, srcColor.g) &&
                                      aboutEqual(dstColor.b, srcColor.b) &&
                                      aboutEqual(dstColor.a, srcColor.a);
                            break;
                        }
                        default: {
                            break;
                        }
                    }
                }
                let outputIndex = GlobalInvocationID.y * u32(dstSize.x) + GlobalInvocationID.x;
                if (success) {
                    output.result[outputIndex] = 1u;
                } else {
                    output.result[outputIndex] = 0u;
                }
            }
         )";
        wgpu::ShaderModule csModule = utils::CreateShaderModule(this->device, shader.c_str());

        wgpu::ComputePipelineDescriptor csDesc;
        csDesc.compute.module = csModule;

        return this->device.CreateComputePipeline(&csDesc);
    }
    static uint32_t GetTextureFormatComponentCount(wgpu::TextureFormat format) {
        switch (format) {
            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:
            case wgpu::TextureFormat::RGBA16Unorm:
            case wgpu::TextureFormat::RGBA16Snorm:
            case wgpu::TextureFormat::RGBA8Snorm:
                return 4;
            case wgpu::TextureFormat::RG11B10Ufloat:
                return 3;
            case wgpu::TextureFormat::RG8Unorm:
            case wgpu::TextureFormat::RG16Float:
            case wgpu::TextureFormat::RG32Float:
            case wgpu::TextureFormat::RG16Unorm:
            case wgpu::TextureFormat::RG16Snorm:
            case wgpu::TextureFormat::RG8Snorm:
                return 2;
            case wgpu::TextureFormat::R8Unorm:
            case wgpu::TextureFormat::R16Float:
            case wgpu::TextureFormat::R32Float:
            case wgpu::TextureFormat::R16Unorm:
            case wgpu::TextureFormat::R16Snorm:
            case wgpu::TextureFormat::R8Snorm:
                return 1;
            default:
                DAWN_UNREACHABLE();
        }
    }

    wgpu::Texture CreateTexture(const TextureSpec& spec, wgpu::TextureUsage usage) {
        // Create and initialize src texture.
        wgpu::TextureDescriptor descriptor;
        descriptor.size = spec.textureSize;
        descriptor.format = spec.format;
        descriptor.mipLevelCount = spec.level + 1;
        descriptor.usage = usage;
        wgpu::Texture texture = this->device.CreateTexture(&descriptor);
        return texture;
    }

    wgpu::Texture CreateAndInitTexture(const TextureSpec& spec,
                                       wgpu::TextureUsage usage,
                                       utils::TextureDataCopyLayout copyLayout,
                                       void const* init,
                                       uint32_t initBytes) {
        wgpu::Texture texture = CreateTexture(spec, usage);

        wgpu::TexelCopyTextureInfo imageTextureInit =
            utils::CreateTexelCopyTextureInfo(texture, spec.level, {0, 0});

        wgpu::TexelCopyBufferLayout texelCopyBufferLayout;
        texelCopyBufferLayout.offset = 0;
        texelCopyBufferLayout.bytesPerRow = copyLayout.bytesPerRow;
        texelCopyBufferLayout.rowsPerImage = copyLayout.rowsPerImage;

        this->device.GetQueue().WriteTexture(&imageTextureInit, init, initBytes,
                                             &texelCopyBufferLayout, &copyLayout.mipSize);
        return texture;
    }

    void RunCopyExternalImageToTexture(
        const TextureSpec& srcSpec,
        wgpu::Texture srcTexture,
        const TextureSpec& dstSpec,
        wgpu::Texture dstTexture,
        const wgpu::Extent3D& copySize,
        const wgpu::CopyTextureForBrowserOptions options,
        const wgpu::TextureAspect aspect = wgpu::TextureAspect::All) {
        wgpu::TexelCopyTextureInfo srcTexelCopyTextureInfo = utils::CreateTexelCopyTextureInfo(
            srcTexture, srcSpec.level, srcSpec.copyOrigin, aspect);
        wgpu::TexelCopyTextureInfo dstTexelCopyTextureInfo = utils::CreateTexelCopyTextureInfo(
            dstTexture, dstSpec.level, dstSpec.copyOrigin, aspect);
        this->device.GetQueue().CopyTextureForBrowser(
            &srcTexelCopyTextureInfo, &dstTexelCopyTextureInfo, &copySize, &options);
    }

    void CheckResultInBuiltInComputePipeline(const TextureSpec& srcSpec,
                                             wgpu::Texture srcTexture,
                                             const TextureSpec& dstSpec,
                                             wgpu::Texture dstTexture,
                                             const wgpu::Extent3D& copySize,
                                             const wgpu::CopyTextureForBrowserOptions options) {
        // Update uniform buffer based on test config
        uint32_t uniformBufferData[] = {
            options.flipY,                                   // copy have flipY option
            GetTextureFormatComponentCount(dstSpec.format),  // channelCount
            srcSpec.copyOrigin.x,
            srcSpec.copyOrigin.y,  // src texture copy origin
            dstSpec.copyOrigin.x,
            dstSpec.copyOrigin.y,  // dst texture copy origin
            copySize.width,
            copySize.height,  // copy size
            static_cast<uint32_t>(options.srcAlphaMode),
            static_cast<uint32_t>(options.dstAlphaMode)};

        this->device.GetQueue().WriteBuffer(uniformBuffer, 0, uniformBufferData,
                                            sizeof(uniformBufferData));

        // Create output buffer to store result
        wgpu::BufferDescriptor outputDesc;
        outputDesc.size = dstSpec.textureSize.width * dstSpec.textureSize.height * sizeof(uint32_t);
        outputDesc.usage =
            wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
        wgpu::Buffer outputBuffer = this->device.CreateBuffer(&outputDesc);

        // Create texture views for test.
        wgpu::TextureViewDescriptor srcTextureViewDesc = {};
        srcTextureViewDesc.baseMipLevel = srcSpec.level;
        wgpu::TextureView srcTextureView = srcTexture.CreateView(&srcTextureViewDesc);

        wgpu::TextureViewDescriptor dstTextureViewDesc = {};
        dstTextureViewDesc.baseMipLevel = dstSpec.level;
        wgpu::TextureView dstTextureView = dstTexture.CreateView(&dstTextureViewDesc);

        // Create bind group based on the config.
        wgpu::BindGroup bindGroup = utils::MakeBindGroup(
            this->device, pipeline.GetBindGroupLayout(0),
            {{0, srcTextureView}, {1, dstTextureView}, {2, outputBuffer}, {3, uniformBuffer}});

        // Start a pipeline to check pixel value in bit form.
        wgpu::CommandEncoder testEncoder = this->device.CreateCommandEncoder();

        wgpu::CommandBuffer testCommands;
        {
            wgpu::CommandEncoder encoder = this->device.CreateCommandEncoder();
            wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
            pass.SetPipeline(pipeline);
            pass.SetBindGroup(0, bindGroup);
            pass.DispatchWorkgroups(dstSpec.textureSize.width,
                                    dstSpec.textureSize.height);  // Verify dst texture content
            pass.End();

            testCommands = encoder.Finish();
        }
        this->device.GetQueue().Submit(1, &testCommands);

        std::vector<uint32_t> expectResult(dstSpec.textureSize.width * dstSpec.textureSize.height,
                                           1);
        EXPECT_BUFFER_U32_RANGE_EQ(expectResult.data(), outputBuffer, 0,
                                   dstSpec.textureSize.width * dstSpec.textureSize.height);
    }

    void DoTest(const TextureSpec& srcSpec,
                const TextureSpec& dstSpec,
                const wgpu::Extent3D& copySize = {kDefaultTextureWidth, kDefaultTextureHeight},
                const wgpu::CopyTextureForBrowserOptions options = {}) {
        // Create and initialize src texture.
        const utils::TextureDataCopyLayout srcCopyLayout =
            utils::GetTextureDataCopyLayoutForTextureAtLevel(
                kTextureFormat,
                {srcSpec.textureSize.width, srcSpec.textureSize.height,
                 copySize.depthOrArrayLayers},
                srcSpec.level);

        std::vector<utils::RGBA8> srcTextureArrayCopyData = GetTextureData(
            srcCopyLayout, TextureCopyRole::SOURCE, options.srcAlphaMode, options.dstAlphaMode);

        wgpu::TextureUsage srcUsage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
                                      wgpu::TextureUsage::TextureBinding;
        wgpu::Texture srcTexture =
            CreateAndInitTexture(srcSpec, srcUsage, srcCopyLayout, srcTextureArrayCopyData.data(),
                                 srcTextureArrayCopyData.size() * sizeof(utils::RGBA8));

        bool testSubRectCopy = srcSpec.copyOrigin.x > 0 || srcSpec.copyOrigin.y > 0 ||
                               dstSpec.copyOrigin.x > 0 || dstSpec.copyOrigin.y > 0 ||
                               srcSpec.textureSize.width > copySize.width ||
                               srcSpec.textureSize.height > copySize.height ||
                               dstSpec.textureSize.width > copySize.width ||
                               dstSpec.textureSize.height > copySize.height;

        // Create and init dst texture.
        wgpu::Texture dstTexture;
        wgpu::TextureUsage dstUsage =
            wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::TextureBinding |
            wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;

        if (testSubRectCopy) {
            // For subrect copy tests, dst texture use kTextureFormat always.
            const utils::TextureDataCopyLayout dstCopyLayout =
                utils::GetTextureDataCopyLayoutForTextureAtLevel(
                    kTextureFormat,
                    {dstSpec.textureSize.width, dstSpec.textureSize.height,
                     copySize.depthOrArrayLayers},
                    dstSpec.level);

            const std::vector<utils::RGBA8> dstTextureArrayCopyData =
                GetTextureData(dstCopyLayout, TextureCopyRole::DEST);
            dstTexture = CreateAndInitTexture(
                dstSpec, dstUsage, dstCopyLayout, dstTextureArrayCopyData.data(),
                dstTextureArrayCopyData.size() * sizeof(utils::RGBA8));
        } else {
            dstTexture = CreateTexture(dstSpec, dstUsage);
        }

        // Perform the texture to texture copy
        RunCopyExternalImageToTexture(srcSpec, srcTexture, dstSpec, dstTexture, copySize, options);

        // Check Result
        CheckResultInBuiltInComputePipeline(srcSpec, srcTexture, dstSpec, dstTexture, copySize,
                                            options);
    }

    wgpu::Buffer uniformBuffer;
    wgpu::ComputePipeline pipeline;
};

class CopyTextureForBrowser_Basic : public CopyTextureForBrowserTests<DawnTest> {
  protected:
    void DoBasicCopyTest(const wgpu::Extent3D& copySize,
                         const wgpu::CopyTextureForBrowserOptions options = {}) {
        TextureSpec textureSpec;
        textureSpec.textureSize = copySize;

        DoTest(textureSpec, textureSpec, copySize, options);
    }
};

class CopyTextureForBrowser_Formats
    : public CopyTextureForBrowserTests<DawnTestWithParams<FormatTestParams>> {
  protected:
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        std::vector<wgpu::FeatureName> requiredFeatures = {};
        if (SupportsFeatures({wgpu::FeatureName::TextureFormatsTier1})) {
            requiredFeatures.push_back(wgpu::FeatureName::TextureFormatsTier1);
        }
        return requiredFeatures;
    }

    bool IsDstFormatSrgbFormats() {
        return GetParam().mDstFormat == wgpu::TextureFormat::RGBA8UnormSrgb ||
               GetParam().mDstFormat == wgpu::TextureFormat::BGRA8UnormSrgb;
    }

    wgpu::TextureFormat GetNonSrgbFormat(wgpu::TextureFormat format) {
        switch (format) {
            case wgpu::TextureFormat::RGBA8UnormSrgb:
                return wgpu::TextureFormat::RGBA8Unorm;
            case wgpu::TextureFormat::BGRA8UnormSrgb:
                return wgpu::TextureFormat::BGRA8Unorm;
            default:
                return format;
        }
    }

    wgpu::Texture CreateAndInitSourceTextureForColorFormatConversion(
        const TextureSpec& srcSpec,
        wgpu::TextureUsage srcUsage,
        utils::TextureDataCopyLayout srcCopyLayout) {
        // Create and init source texture.
        // This fixed source texture data is for color conversion tests.
        // The source data can fill a texture in default width and height.
        std::vector<utils::RGBA8> srcRGBA8UnormTextureArrayCopyData{
            // Take RGBA8Unorm as example:
            // R channel has different values
            utils::RGBA8(0, 255, 255, 255),    // r = 0.0
            utils::RGBA8(102, 255, 255, 255),  // r = 0.4
            utils::RGBA8(153, 255, 255, 255),  // r = 0.6

            // G channel has different values
            utils::RGBA8(255, 0, 255, 255),    // g = 0.0
            utils::RGBA8(255, 102, 255, 255),  // g = 0.4
            utils::RGBA8(255, 153, 255, 255),  // g = 0.6

            // B channel has different values
            utils::RGBA8(255, 255, 0, 255),    // b = 0.0
            utils::RGBA8(255, 255, 102, 255),  // b = 0.4
            utils::RGBA8(255, 255, 153, 255),  // b = 0.6

            // A channel set to 0
            utils::RGBA8(255, 255, 255, 0)  // a = 0
        };

        std::vector<uint16_t> srcRGBA16FloatTextureArrayCopyData{
            // R channel has different values
            // r = 0.0
            Float32ToFloat16(0.0), Float32ToFloat16(1.0), Float32ToFloat16(1.0),
            Float32ToFloat16(1.0),

            // r = 0.4
            Float32ToFloat16(0.4), Float32ToFloat16(1.0), Float32ToFloat16(1.0),
            Float32ToFloat16(1.0),

            // r = 0.6
            Float32ToFloat16(0.6), Float32ToFloat16(1.0), Float32ToFloat16(1.0),
            Float32ToFloat16(1.0),

            // G channel has different values
            // g = 0.0
            Float32ToFloat16(1.0), Float32ToFloat16(0.0), Float32ToFloat16(1.0),
            Float32ToFloat16(1.0),

            // g = 0.4
            Float32ToFloat16(1.0), Float32ToFloat16(0.4), Float32ToFloat16(1.0),
            Float32ToFloat16(1.0),

            // g = 0.6
            Float32ToFloat16(1.0), Float32ToFloat16(0.6), Float32ToFloat16(1.0),
            Float32ToFloat16(1.0),

            // B channel has different values
            // b = 0.0
            Float32ToFloat16(1.0), Float32ToFloat16(1.0), Float32ToFloat16(0.0),
            Float32ToFloat16(1.0),

            // b = 0.4
            Float32ToFloat16(1.0), Float32ToFloat16(1.0), Float32ToFloat16(0.4),
            Float32ToFloat16(1.0),

            // b = 0.6
            Float32ToFloat16(1.0), Float32ToFloat16(1.0), Float32ToFloat16(0.6),
            Float32ToFloat16(1.0),

            // A channel set to 0
            // a = 0
            Float32ToFloat16(1.0), Float32ToFloat16(1.0), Float32ToFloat16(1.0),
            Float32ToFloat16(0.0)};

        switch (srcSpec.format) {
            case wgpu::TextureFormat::RGBA8Unorm:
            case wgpu::TextureFormat::BGRA8Unorm:
                return CreateAndInitTexture(
                    srcSpec, srcUsage, srcCopyLayout, srcRGBA8UnormTextureArrayCopyData.data(),
                    srcRGBA8UnormTextureArrayCopyData.size() * sizeof(utils::RGBA8));
            case wgpu::TextureFormat::RGBA16Float:
                return CreateAndInitTexture(
                    srcSpec, srcUsage, srcCopyLayout, srcRGBA16FloatTextureArrayCopyData.data(),
                    srcRGBA16FloatTextureArrayCopyData.size() * sizeof(uint16_t));
            default:
                DAWN_UNREACHABLE();
        }
    }

    void DoColorConversionTest() {
        TextureSpec srcTextureSpec;
        srcTextureSpec.format = GetParam().mSrcFormat;

        TextureSpec dstTextureSpec;
        dstTextureSpec.format = GetParam().mDstFormat;
        DAWN_TEST_UNSUPPORTED_IF(!utils::IsRenderableFormat(device, dstTextureSpec.format));

        wgpu::Extent3D copySize = {kDefaultTextureWidth, kDefaultTextureHeight};
        wgpu::CopyTextureForBrowserOptions options = {};

        const utils::TextureDataCopyLayout srcCopyLayout =
            utils::GetTextureDataCopyLayoutForTextureAtLevel(
                srcTextureSpec.format,
                {srcTextureSpec.textureSize.width, srcTextureSpec.textureSize.height,
                 copySize.depthOrArrayLayers},
                srcTextureSpec.level);

        wgpu::TextureUsage srcUsage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
                                      wgpu::TextureUsage::TextureBinding;
        wgpu::Texture srcTexture = CreateAndInitSourceTextureForColorFormatConversion(
            srcTextureSpec, srcUsage, srcCopyLayout);

        // Create dst texture.
        wgpu::Texture dstTexture = CreateTexture(
            dstTextureSpec, wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::TextureBinding |
                                wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc);

        // (Off-topic) spot-test the defaulting of TexelCopyTextureInfo.aspect.
        wgpu::TextureAspect aspect = wgpu::TextureAspect::Undefined;
        // Perform the texture to texture copy
        RunCopyExternalImageToTexture(srcTextureSpec, srcTexture, dstTextureSpec, dstTexture,
                                      copySize, options, aspect);

        wgpu::Texture result;
        TextureSpec resultSpec = dstTextureSpec;

        // To construct the expected value for the case that dst texture is srgb format,
        // we need to ensure it is byte level equal to the comparable non-srgb format texture.
        // We schedule an copy from srgb texture to non-srgb texture which keeps the bytes
        // same and bypass the sampler to do gamma correction when comparing the expected values
        // in compute shader.
        if (IsDstFormatSrgbFormats()) {
            resultSpec.format = GetNonSrgbFormat(dstTextureSpec.format);
            wgpu::Texture intermediateTexture = CreateTexture(
                resultSpec, wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::TextureBinding |
                                wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc);

            wgpu::CommandEncoder encoder = device.CreateCommandEncoder();

            // Perform the texture to texture copy
            wgpu::TexelCopyTextureInfo dstTexelCopyTextureInfo =
                utils::CreateTexelCopyTextureInfo(dstTexture, 0, {0, 0, 0});
            wgpu::TexelCopyTextureInfo intermediateTexelCopyTextureInfo =
                utils::CreateTexelCopyTextureInfo(intermediateTexture, 0, {0, 0, 0});

            encoder.CopyTextureToTexture(&dstTexelCopyTextureInfo,
                                         &intermediateTexelCopyTextureInfo,
                                         &(dstTextureSpec.textureSize));
            wgpu::CommandBuffer commands = encoder.Finish();
            queue.Submit(1, &commands);

            result = intermediateTexture;
        } else {
            result = dstTexture;
        }

        // Check Result
        CheckResultInBuiltInComputePipeline(srcTextureSpec, srcTexture, resultSpec, result,
                                            copySize, options);
    }
};

class CopyTextureForBrowser_SubRects
    : public CopyTextureForBrowserTests<DawnTestWithParams<SubRectTestParams>> {
  protected:
    void DoCopySubRectTest() {
        TextureSpec srcTextureSpec;
        srcTextureSpec.copyOrigin = GetParam().mSrcOrigin;
        srcTextureSpec.textureSize = {6, 7};

        TextureSpec dstTextureSpec;
        dstTextureSpec.copyOrigin = GetParam().mDstOrigin;
        dstTextureSpec.textureSize = {8, 5};
        wgpu::CopyTextureForBrowserOptions options = {};
        options.flipY = GetParam().mFlipY;

        wgpu::Extent3D copySize = GetParam().mCopySize;

        DoTest(srcTextureSpec, dstTextureSpec, copySize, options);
    }
};

class CopyTextureForBrowser_AlphaMode
    : public CopyTextureForBrowserTests<DawnTestWithParams<AlphaTestParams>> {
  protected:
    void DoAlphaModeTest() {
        constexpr uint32_t kWidth = 10;
        constexpr uint32_t kHeight = 10;

        TextureSpec textureSpec;
        textureSpec.textureSize = {kWidth, kHeight};

        wgpu::CopyTextureForBrowserOptions options = {};
        options.srcAlphaMode = GetParam().mSrcAlphaMode;
        options.dstAlphaMode = GetParam().mDstAlphaMode;

        DoTest(textureSpec, textureSpec, {kWidth, kHeight}, options);
    }
};

class CopyTextureForBrowser_ColorSpace
    : public CopyTextureForBrowserTests<DawnTestWithParams<ColorSpaceTestParams>> {
  protected:
    const ColorSpaceInfo& GetColorSpaceInfo(ColorSpace colorSpace) {
        uint32_t index = static_cast<uint32_t>(colorSpace);
        DAWN_ASSERT(index < ColorSpaceTable.size());
        DAWN_ASSERT(ColorSpaceTable[index].index == colorSpace);
        return ColorSpaceTable[index];
    }

    std::array<float, 9> GetConversionMatrix(ColorSpace src, ColorSpace dst) {
        const ColorSpaceInfo& srcColorSpace = GetColorSpaceInfo(src);
        const ColorSpaceInfo& dstColorSpace = GetColorSpaceInfo(dst);

        const std::array<float, 9> toXYZD50 = srcColorSpace.toXYZD50;
        const std::array<float, 9> fromXYZD50 = dstColorSpace.fromXYZD50;

        // Fuse the transform matrix. The color space transformation equation is:
        // Pixels = fromXYZD50 * toXYZD50 * Pixels.
        // Calculate fromXYZD50 * toXYZD50 to simplify
        // Add a padding in each row for Mat3x3 in wgsl uniform(mat3x3, Align(16), Size(48)).
        std::array<float, 9> fuseMatrix = {};

        // Mat3x3 * Mat3x3
        for (uint32_t row = 0; row < 3; ++row) {
            for (uint32_t col = 0; col < 3; ++col) {
                // Transpose the matrix from row major to column major for wgsl.
                fuseMatrix[col * 3 + row] = fromXYZD50[row * 3 + 0] * toXYZD50[col] +
                                            fromXYZD50[row * 3 + 1] * toXYZD50[3 + col] +
                                            fromXYZD50[row * 3 + 2] * toXYZD50[3 * 2 + col];
            }
        }

        return fuseMatrix;
    }

    // TODO(crbug.com/dawn/1140): Generate source data automatically.
    std::vector<utils::RGBA8> GetSourceData(wgpu::AlphaMode srcTextureAlphaMode) {
        if (srcTextureAlphaMode == wgpu::AlphaMode::Premultiplied) {
            return std::vector<utils::RGBA8>{
                utils::RGBA8(0, 102, 102, 102),  // a = 0.4
                utils::RGBA8(102, 0, 0, 102),    // a = 0.4
                utils::RGBA8(153, 0, 0, 153),    // a = 0.6
                utils::RGBA8(255, 0, 0, 255),    // a = 1.0

                utils::RGBA8(153, 0, 153, 153),  // a = 0.6
                utils::RGBA8(0, 102, 0, 102),    // a = 0.4
                utils::RGBA8(0, 153, 0, 153),    // a = 0.6
                utils::RGBA8(0, 255, 0, 255),    // a = 1.0

                utils::RGBA8(255, 255, 0, 255),  // a = 1.0
                utils::RGBA8(0, 0, 102, 102),    // a = 0.4
                utils::RGBA8(0, 0, 153, 153),    // a = 0.6
                utils::RGBA8(0, 0, 255, 255),    // a = 1.0
            };
        }

        return std::vector<utils::RGBA8>{
            // Take RGBA8Unorm as example:
            // R channel has different values
            utils::RGBA8(0, 255, 255, 255),  // r = 0.0
            utils::RGBA8(102, 0, 0, 255),    // r = 0.4
            utils::RGBA8(153, 0, 0, 255),    // r = 0.6
            utils::RGBA8(255, 0, 0, 255),    // r = 1.0

            // G channel has different values
            utils::RGBA8(255, 0, 255, 255),  // g = 0.0
            utils::RGBA8(0, 102, 0, 255),    // g = 0.4
            utils::RGBA8(0, 153, 0, 255),    // g = 0.6
            utils::RGBA8(0, 255, 0, 255),    // g = 1.0

            // B channel has different values
            utils::RGBA8(255, 255, 0, 255),  // b = 0.0
            utils::RGBA8(0, 0, 102, 255),    // b = 0.4
            utils::RGBA8(0, 0, 153, 255),    // b = 0.6
            utils::RGBA8(0, 0, 255, 255),    // b = 1.0
        };
    }

    // TODO(crbug.com/dawn/1140): Current expected values are from ColorSync utils
    // tool on Mac. Should implement CPU or compute shader algorithm to do color
    // conversion and use the result as expected data.
    std::vector<float> GetExpectedData(ColorSpace srcColorSpace,
                                       ColorSpace dstColorSpace,
                                       wgpu::AlphaMode srcTextureAlphaMode,
                                       wgpu::AlphaMode dstTextureAlphaMode) {
        if (srcTextureAlphaMode == wgpu::AlphaMode::Premultiplied) {
            return GetExpectedDataForPremultipliedSource(srcColorSpace, dstColorSpace,
                                                         dstTextureAlphaMode);
        }

        return GetExpectedDataForSeparateSource(srcColorSpace, dstColorSpace);
    }

    std::vector<float> GeneratePremultipliedResult(std::vector<float> result) {
        // Four channels per pixel
        for (uint32_t i = 0; i < result.size(); i += 4) {
            result[i] *= result[i + 3];
            result[i + 1] *= result[i + 3];
            result[i + 2] *= result[i + 3];
        }

        return result;
    }

    std::vector<float> GetExpectedDataForPremultipliedSource(ColorSpace srcColorSpace,
                                                             ColorSpace dstColorSpace,
                                                             wgpu::AlphaMode dstTextureAlphaMode) {
        if (srcColorSpace == dstColorSpace) {
            std::vector<float> expected = {
                0.0, 1.0, 1.0, 0.4,  //
                1.0, 0.0, 0.0, 0.4,  //
                1.0, 0.0, 0.0, 0.6,  //
                1.0, 0.0, 0.0, 1.0,  //

                1.0, 0.0, 1.0, 0.6,  //
                0.0, 1.0, 0.0, 0.4,  //
                0.0, 1.0, 0.0, 0.6,  //
                0.0, 1.0, 0.0, 1.0,  //

                1.0, 1.0, 0.0, 1.0,  //
                0.0, 0.0, 1.0, 0.4,  //
                0.0, 0.0, 1.0, 0.6,  //
                0.0, 0.0, 1.0, 1.0,  //
            };

            return dstTextureAlphaMode == wgpu::AlphaMode::Premultiplied
                       ? GeneratePremultipliedResult(expected)
                       : expected;
        }

        switch (srcColorSpace) {
            case ColorSpace::DisplayP3: {
                switch (dstColorSpace) {
                    case ColorSpace::SRGB: {
                        std::vector<float> expected = {
                            -0.5118, 1.0183,  1.0085,  0.4,  //
                            1.093,   -0.2267, -0.1501, 0.4,  //
                            1.093,   -0.2267, -0.1501, 0.6,  //
                            1.093,   -0.2267, -0.1501, 1.0,  //

                            1.093,   -0.2266, 1.0337,  0.6,  //
                            -0.5118, 1.0183,  -0.3107, 0.4,  //
                            -0.5118, 1.0183,  -0.3107, 0.6,  //
                            -0.5118, 1.0183,  -0.3107, 1.0,  //

                            0.9999,  1.0001,  -0.3462, 1.0,  //
                            0.0002,  0.0004,  1.0419,  0.4,  //
                            0.0002,  0.0004,  1.0419,  0.6,  //
                            0.0002,  0.0004,  1.0419,  1.0,  //
                        };

                        return dstTextureAlphaMode == wgpu::AlphaMode::Premultiplied
                                   ? GeneratePremultipliedResult(expected)
                                   : expected;
                    }
                    default:
                        DAWN_UNREACHABLE();
                }
            }
            default:
                break;
        }
        DAWN_UNREACHABLE();
    }

    std::vector<float> GetExpectedDataForSeparateSource(ColorSpace srcColorSpace,
                                                        ColorSpace dstColorSpace) {
        if (srcColorSpace == dstColorSpace) {
            return std::vector<float>{
                0.0, 1.0, 1.0, 1.0,  //
                0.4, 0.0, 0.0, 1.0,  //
                0.6, 0.0, 0.0, 1.0,  //
                1.0, 0.0, 0.0, 1.0,  //

                1.0, 0.0, 1.0, 1.0,  //
                0.0, 0.4, 0.0, 1.0,  //
                0.0, 0.6, 0.0, 1.0,  //
                0.0, 1.0, 0.0, 1.0,  //

                1.0, 1.0, 0.0, 1.0,  //
                0.0, 0.0, 0.4, 1.0,  //
                0.0, 0.0, 0.6, 1.0,  //
                0.0, 0.0, 1.0, 1.0,  //
            };
        }

        switch (srcColorSpace) {
            case ColorSpace::DisplayP3: {
                switch (dstColorSpace) {
                    case ColorSpace::SRGB: {
                        return std::vector<float>{
                            -0.5118, 1.0183,  1.0085,  1.0,  //
                            0.4401,  -0.0665, -0.0337, 1.0,  //
                            0.6578,  -0.1199, -0.0723, 1.0,  //
                            1.093,   -0.2267, -0.1501, 1.0,  //

                            1.093,   -0.2266, 1.0337,  1.0,  //
                            -0.1894, 0.4079,  -0.1027, 1.0,  //
                            -0.2969, 0.6114,  -0.1720, 1.0,  //
                            -0.5118, 1.0183,  -0.3107, 1.0,  //

                            0.9999,  1.0001,  -0.3462, 1.0,  //
                            0.0000,  0.0001,  0.4181,  1.0,  //
                            0.0001,  0.0001,  0.6260,  1.0,  //
                            0.0002,  0.0004,  1.0419,  1.0,  //
                        };
                    }
                    default:
                        DAWN_UNREACHABLE();
                }
            }
            default:
                break;
        }
        DAWN_UNREACHABLE();
    }

    void DoColorSpaceConversionTest() {
        constexpr uint32_t kWidth = 12;
        constexpr uint32_t kHeight = 1;

        TextureSpec srcTextureSpec;
        srcTextureSpec.textureSize = {kWidth, kHeight};

        TextureSpec dstTextureSpec;
        dstTextureSpec.textureSize = {kWidth, kHeight};
        dstTextureSpec.format = GetParam().mDstFormat;

        ColorSpace srcColorSpace = GetParam().mSrcColorSpace;
        ColorSpace dstColorSpace = GetParam().mDstColorSpace;

        ColorSpaceInfo srcColorSpaceInfo = GetColorSpaceInfo(srcColorSpace);
        ColorSpaceInfo dstColorSpaceInfo = GetColorSpaceInfo(dstColorSpace);

        std::array<float, 9> matrix = GetConversionMatrix(srcColorSpace, dstColorSpace);

        wgpu::CopyTextureForBrowserOptions options = {};
        options.needsColorSpaceConversion = srcColorSpace != dstColorSpace;
        options.srcAlphaMode = GetParam().mSrcAlphaMode;
        options.srcTransferFunctionParameters = srcColorSpaceInfo.gammaDecodingParams.data();
        options.conversionMatrix = matrix.data();
        options.dstTransferFunctionParameters = dstColorSpaceInfo.gammaEncodingParams.data();
        options.dstAlphaMode = GetParam().mDstAlphaMode;

        std::vector<utils::RGBA8> sourceTextureData = GetSourceData(options.srcAlphaMode);
        const wgpu::Extent3D& copySize = {kWidth, kHeight};

        const utils::TextureDataCopyLayout srcCopyLayout =
            utils::GetTextureDataCopyLayoutForTextureAtLevel(
                kTextureFormat,
                {srcTextureSpec.textureSize.width, srcTextureSpec.textureSize.height},
                srcTextureSpec.level);

        wgpu::TextureUsage srcUsage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
                                      wgpu::TextureUsage::TextureBinding;
        wgpu::Texture srcTexture = this->CreateAndInitTexture(
            srcTextureSpec, srcUsage, srcCopyLayout, sourceTextureData.data(),
            sourceTextureData.size() * sizeof(utils::RGBA8));

        // Create dst texture.
        wgpu::Texture dstTexture = this->CreateTexture(
            dstTextureSpec, wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::TextureBinding |
                                wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc);

        // Perform the texture to texture copy
        this->RunCopyExternalImageToTexture(srcTextureSpec, srcTexture, dstTextureSpec, dstTexture,
                                            copySize, options);

        std::vector<float> expectedData = GetExpectedData(
            srcColorSpace, dstColorSpace, options.srcAlphaMode, options.dstAlphaMode);

        // The value provided by Apple's ColorSync Utility.
        float tolerance = 0.001;
        if (dstTextureSpec.format == wgpu::TextureFormat::RGBA16Float) {
            EXPECT_TEXTURE_FLOAT16_EQ(expectedData.data(), dstTexture, {0, 0}, {kWidth, kHeight},
                                      dstTextureSpec.format, tolerance);
        } else {
            EXPECT_TEXTURE_EQ(expectedData.data(), dstTexture, {0, 0}, {kWidth, kHeight},
                              dstTextureSpec.format, tolerance);
        }
    }
};

// Verify CopyTextureForBrowserTests works with internal pipeline.
// The case do copy without any transform.
TEST_P(CopyTextureForBrowser_Basic, PassthroughCopy) {
    // TODO(crbug.com/40238674): Fails on Pixel 10 gles.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    DAWN_SUPPRESS_TEST_IF(IsOpenGL() && IsLinux());

    DoBasicCopyTest({10, 1});
}

TEST_P(CopyTextureForBrowser_Basic, VerifyCopyOnXDirection) {
    // TODO(crbug.com/40238674): Fails on Pixel 10 gles.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    DAWN_SUPPRESS_TEST_IF(IsOpenGL() && IsLinux());

    DoBasicCopyTest({1000, 1});
}

TEST_P(CopyTextureForBrowser_Basic, VerifyCopyOnYDirection) {
    // TODO(crbug.com/40238674): Fails on Pixel 10 gles.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    DAWN_SUPPRESS_TEST_IF(IsOpenGL() && IsLinux());

    DoBasicCopyTest({1, 1000});
}

TEST_P(CopyTextureForBrowser_Basic, VerifyCopyFromLargeTexture) {
    // TODO(crbug.com/40238674): Fails on Pixel 10 gles.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    DAWN_SUPPRESS_TEST_IF(IsOpenGL() && IsLinux());

    DoBasicCopyTest({899, 999});
}

TEST_P(CopyTextureForBrowser_Basic, VerifyFlipY) {
    // TODO(crbug.com/40238674): Fails on Pixel 10 gles.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    DAWN_SUPPRESS_TEST_IF(IsOpenGL() && IsLinux());

    wgpu::CopyTextureForBrowserOptions options = {};
    options.flipY = true;

    DoBasicCopyTest({901, 1001}, options);
}

TEST_P(CopyTextureForBrowser_Basic, VerifyFlipYInSlimTexture) {
    // TODO(crbug.com/40238674): Fails on Pixel 10 gles.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    DAWN_SUPPRESS_TEST_IF(IsOpenGL() && IsLinux());

    wgpu::CopyTextureForBrowserOptions options = {};
    options.flipY = true;

    DoBasicCopyTest({1, 1001}, options);
}

DAWN_INSTANTIATE_TEST(CopyTextureForBrowser_Basic,
                      D3D11Backend(),
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      VulkanBackend(),
                      WebGPUBackend());

// Verify |CopyTextureForBrowser| doing color conversion correctly when
// the source texture is RGBA8Unorm format.
TEST_P(CopyTextureForBrowser_Formats, ColorConversion) {
    // TODO(crbug.com/40238674): Fails on Pixel 10 gles.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    // BGRA8UnormSrgb is unsupported in Compatibility mode.
    DAWN_TEST_UNSUPPORTED_IF(IsCompatibilityMode() &&
                             GetParam().mDstFormat == wgpu::TextureFormat::BGRA8UnormSrgb);

    DAWN_SUPPRESS_TEST_IF(IsOpenGL() && IsLinux());

    // Skip OpenGL backend on linux because it fails on using *-srgb format as
    // dst texture format
    DAWN_SUPPRESS_TEST_IF(IsOpenGL() && IsLinux() && IsDstFormatSrgbFormats());

    DoColorConversionTest();
}

DAWN_INSTANTIATE_TEST_P(CopyTextureForBrowser_Formats,
                        {D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
                         VulkanBackend()},
                        std::vector<wgpu::TextureFormat>({wgpu::TextureFormat::RGBA8Unorm,
                                                          wgpu::TextureFormat::BGRA8Unorm,
                                                          wgpu::TextureFormat::RGBA16Float}),
                        std::vector<wgpu::TextureFormat>(
                            {wgpu::TextureFormat::R8Unorm,      wgpu::TextureFormat::R16Float,
                             wgpu::TextureFormat::R32Float,     wgpu::TextureFormat::RG8Unorm,
                             wgpu::TextureFormat::RG16Float,    wgpu::TextureFormat::RG32Float,
                             wgpu::TextureFormat::RGBA8Unorm,   wgpu::TextureFormat::RGBA8UnormSrgb,
                             wgpu::TextureFormat::BGRA8Unorm,   wgpu::TextureFormat::BGRA8UnormSrgb,
                             wgpu::TextureFormat::RGB10A2Unorm, wgpu::TextureFormat::RGBA16Float,
                             wgpu::TextureFormat::RGBA32Float,  wgpu::TextureFormat::R16Unorm,
                             wgpu::TextureFormat::RG16Unorm,    wgpu::TextureFormat::RGBA16Unorm,
                             wgpu::TextureFormat::R16Snorm,     wgpu::TextureFormat::RG16Snorm,
                             wgpu::TextureFormat::RGBA16Snorm,  wgpu::TextureFormat::R8Snorm,
                             wgpu::TextureFormat::RG8Snorm,     wgpu::TextureFormat::RGBA8Snorm,
                             wgpu::TextureFormat::RG11B10Ufloat}));

// Verify |CopyTextureForBrowser| doing subrect copy.
// Source texture is a full red texture and dst texture is a full
// green texture originally. After the subrect copy, affected part
// in dst texture should be red and other part should remain green.
TEST_P(CopyTextureForBrowser_SubRects, CopySubRect) {
    // TODO(crbug.com/40238674): Fails on Pixel 10 gles.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    DAWN_SUPPRESS_TEST_IF(IsOpenGL() && IsLinux());

    // Tests skip due to crbug.com/dawn/592.
    DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsBackendValidationEnabled());

    // Tests skip due to crbug.com/dawn/1104.
    DAWN_SUPPRESS_TEST_IF(IsWARP());

    DoCopySubRectTest();
}

DAWN_INSTANTIATE_TEST_P(CopyTextureForBrowser_SubRects,
                        {D3D11Backend(), D3D12Backend(), MetalBackend(), OpenGLBackend(),
                         OpenGLESBackend(), VulkanBackend()},
                        std::vector<wgpu::Origin3D>({{1, 1}, {1, 2}, {2, 1}}),
                        std::vector<wgpu::Origin3D>({{1, 1}, {1, 2}, {2, 1}}),
                        std::vector<wgpu::Extent3D>({{1, 1}, {2, 1}, {1, 2}, {2, 2}}),
                        std::vector<bool>({true, false}));

// Verify |CopyTextureForBrowser| doing alpha changes.
// Test srcAlphaMode and dstAlphaMode: Premultiplied, Unpremultiplied.
TEST_P(CopyTextureForBrowser_AlphaMode, alphaMode) {
    // TODO(crbug.com/40238674): Fails on Pixel 10 gles.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    DAWN_SUPPRESS_TEST_IF(IsOpenGL() && IsLinux());

    // Tests skip due to crbug.com/dawn/1104.
    DAWN_SUPPRESS_TEST_IF(IsWARP());

    DoAlphaModeTest();
}

DAWN_INSTANTIATE_TEST_P(
    CopyTextureForBrowser_AlphaMode,
    {D3D11Backend(), D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
     VulkanBackend()},
    std::vector<wgpu::AlphaMode>({wgpu::AlphaMode::Premultiplied, wgpu::AlphaMode::Unpremultiplied,
                                  wgpu::AlphaMode::Opaque}),
    std::vector<wgpu::AlphaMode>({wgpu::AlphaMode::Premultiplied, wgpu::AlphaMode::Unpremultiplied,
                                  wgpu::AlphaMode::Opaque}));

// Verify |CopyTextureForBrowser| doing color space conversion.
TEST_P(CopyTextureForBrowser_ColorSpace, colorSpaceConversion) {
    // TODO(crbug.com/40238674): Fails on Pixel 10 gles.
    DAWN_SUPPRESS_TEST_IF(IsImgTec());
    DAWN_SUPPRESS_TEST_IF(IsOpenGL() && IsLinux());

    // Tests skip due to crbug.com/dawn/1104.
    DAWN_SUPPRESS_TEST_IF(IsWARP());

    DoColorSpaceConversionTest();
}

DAWN_INSTANTIATE_TEST_P(CopyTextureForBrowser_ColorSpace,
                        {D3D11Backend(), D3D12Backend(), MetalBackend(), OpenGLBackend(),
                         OpenGLESBackend(), VulkanBackend()},
                        std::vector<wgpu::TextureFormat>({wgpu::TextureFormat::RGBA16Float,
                                                          wgpu::TextureFormat::RGBA32Float}),
                        std::vector<ColorSpace>({ColorSpace::SRGB, ColorSpace::DisplayP3}),
                        std::vector<ColorSpace>({ColorSpace::SRGB}),
                        std::vector<wgpu::AlphaMode>({wgpu::AlphaMode::Premultiplied,
                                                      wgpu::AlphaMode::Unpremultiplied}),
                        std::vector<wgpu::AlphaMode>({wgpu::AlphaMode::Premultiplied,
                                                      wgpu::AlphaMode::Unpremultiplied}));

}  // anonymous namespace
}  // namespace dawn
