// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flutter GPU API tests.
// The flutter_gpu package is located at //flutter/impeller/lib/gpu.

// ignore_for_file: avoid_relative_lib_imports

import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:test/test.dart';
import 'package:vector_math/vector_math.dart';

import '../../lib/gpu/lib/gpu.dart' as gpu;

import 'goldens.dart';
import 'impeller_enabled.dart';

ByteData float32(List<double> values) {
  return Float32List.fromList(values).buffer.asByteData();
}

ByteData unlitUBO(Matrix4 mvp, Vector4 color) {
  return float32(<double>[
    mvp[0], mvp[1], mvp[2], mvp[3], //
    mvp[4], mvp[5], mvp[6], mvp[7], //
    mvp[8], mvp[9], mvp[10], mvp[11], //
    mvp[12], mvp[13], mvp[14], mvp[15], //
    color.r, color.g, color.b, color.a,
  ]);
}

gpu.RenderPipeline createUnlitRenderPipeline() {
  final gpu.ShaderLibrary? library =
      gpu.ShaderLibrary.fromAsset('test.shaderbundle');
  assert(library != null);
  final gpu.Shader? vertex = library!['UnlitVertex'];
  assert(vertex != null);
  final gpu.Shader? fragment = library['UnlitFragment'];
  assert(fragment != null);
  return gpu.gpuContext.createRenderPipeline(vertex!, fragment!);
}

class RenderPassState {
  RenderPassState(this.renderTexture, this.commandBuffer, this.renderPass);

  final gpu.Texture renderTexture;
  final gpu.CommandBuffer commandBuffer;
  final gpu.RenderPass renderPass;
}

/// Create a simple RenderPass with simple color and depth-stencil attachments.
RenderPassState createSimpleRenderPass({Vector4? clearColor}) {
  final gpu.Texture? renderTexture =
      gpu.gpuContext.createTexture(gpu.StorageMode.devicePrivate, 100, 100);
  assert(renderTexture != null);

  final gpu.Texture? depthStencilTexture = gpu.gpuContext.createTexture(
      gpu.StorageMode.deviceTransient, 100, 100,
      format: gpu.gpuContext.defaultDepthStencilFormat);
  assert(depthStencilTexture != null);

  final gpu.CommandBuffer commandBuffer = gpu.gpuContext.createCommandBuffer();

  final gpu.RenderTarget renderTarget = gpu.RenderTarget.singleColor(
      gpu.ColorAttachment(texture: renderTexture!, clearValue: clearColor),
      depthStencilAttachment:
          gpu.DepthStencilAttachment(texture: depthStencilTexture!));

  final gpu.RenderPass renderPass =
      commandBuffer.createRenderPass(renderTarget);

  return RenderPassState(renderTexture, commandBuffer, renderPass);
}

RenderPassState createSimpleRenderPassWithMSAA() {
  // Create transient MSAA attachments, which will live entirely in tile memory
  // for most GPUs.

  final gpu.Texture? renderTexture = gpu.gpuContext.createTexture(
      gpu.StorageMode.deviceTransient, 100, 100,
      format: gpu.gpuContext.defaultColorFormat, sampleCount: 4);
  assert(renderTexture != null);

  final gpu.Texture? depthStencilTexture = gpu.gpuContext.createTexture(
      gpu.StorageMode.deviceTransient, 100, 100,
      format: gpu.gpuContext.defaultDepthStencilFormat, sampleCount: 4);
  assert(depthStencilTexture != null);

  // Create the single-sample resolve texture that live in DRAM and will be
  // drawn to the screen.

  final gpu.Texture? resolveTexture = gpu.gpuContext.createTexture(
      gpu.StorageMode.devicePrivate, 100, 100,
      format: gpu.gpuContext.defaultColorFormat);
  assert(resolveTexture != null);

  final gpu.CommandBuffer commandBuffer = gpu.gpuContext.createCommandBuffer();

  final gpu.RenderTarget renderTarget = gpu.RenderTarget.singleColor(
      gpu.ColorAttachment(
          texture: renderTexture!,
          resolveTexture: resolveTexture,
          storeAction: gpu.StoreAction.multisampleResolve),
      depthStencilAttachment:
          gpu.DepthStencilAttachment(texture: depthStencilTexture!));

  final gpu.RenderPass renderPass =
      commandBuffer.createRenderPass(renderTarget);

  return RenderPassState(resolveTexture!, commandBuffer, renderPass);
}

void drawTriangle(RenderPassState state, Vector4 color) {
  final gpu.RenderPipeline pipeline = createUnlitRenderPipeline();

  state.renderPass.bindPipeline(pipeline);

  final gpu.HostBuffer transients = gpu.gpuContext.createHostBuffer();
  final gpu.BufferView vertices = transients.emplace(float32(<double>[
    -0.5, 0.5, //
    0.0, -0.5, //
    0.5, 0.5, //
  ]));
  final gpu.BufferView vertInfoData =
      transients.emplace(unlitUBO(Matrix4.identity(), color));
  state.renderPass.bindVertexBuffer(vertices, 3);

  final gpu.UniformSlot vertInfo =
      pipeline.vertexShader.getUniformSlot('VertInfo');
  state.renderPass.bindUniform(vertInfo, vertInfoData);

  state.renderPass.draw();
}

void main() async {
  final ImageComparer comparer = await ImageComparer.create();

  test('gpu.context throws exception for incompatible embedders', () async {
    try {
      // ignore: unnecessary_statements
      gpu.gpuContext; // Force the context to instantiate.
      if (!impellerEnabled) {
        fail('Exception not thrown, but no Impeller context available.');
      }
    } catch (e) {
      if (impellerEnabled) {
        fail('Exception thrown even though Impeller is enabled.');
      }
      expect(
          e.toString(),
          contains(
              'Flutter GPU requires the Impeller rendering backend to be enabled.'));
    }
  });

  test('GpuContext.minimumUniformByteAlignment', () async {
    final int alignment = gpu.gpuContext.minimumUniformByteAlignment;
    expect(alignment, greaterThanOrEqualTo(16));
  }, skip: !impellerEnabled);

  test('HostBuffer.emplace', () async {
    final gpu.HostBuffer hostBuffer = gpu.gpuContext.createHostBuffer();

    final gpu.BufferView view0 = hostBuffer
        .emplace(Int8List.fromList(<int>[0, 1, 2, 3]).buffer.asByteData());
    expect(view0.offsetInBytes, 0);
    expect(view0.lengthInBytes, 4);

    final gpu.BufferView view1 = hostBuffer
        .emplace(Int8List.fromList(<int>[0, 1, 2, 3]).buffer.asByteData());
    expect(view1.offsetInBytes,
        equals(gpu.gpuContext.minimumUniformByteAlignment));
    expect(view1.lengthInBytes, 4);
  }, skip: !impellerEnabled);

  test('HostBuffer.reset', () async {
    final gpu.HostBuffer hostBuffer = gpu.gpuContext.createHostBuffer();

    final gpu.BufferView view0 = hostBuffer
        .emplace(Int8List.fromList(<int>[0, 1, 2, 3]).buffer.asByteData());
    expect(view0.offsetInBytes, 0);
    expect(view0.lengthInBytes, 4);

    hostBuffer.reset();

    final gpu.BufferView view1 = hostBuffer
        .emplace(Int8List.fromList(<int>[0, 1, 2, 3]).buffer.asByteData());
    expect(view1.offsetInBytes, 0);
    expect(view1.lengthInBytes, 4);
  }, skip: !impellerEnabled);

  test('HostBuffer reuses DeviceBuffers after N frames', () async {
    final gpu.HostBuffer hostBuffer = gpu.gpuContext.createHostBuffer();

    final gpu.BufferView view0 = hostBuffer
        .emplace(Int8List.fromList(<int>[0, 1, 2, 3]).buffer.asByteData());

    for (int i = 0; i < hostBuffer.frameCount; i++) {
      hostBuffer.reset();
    }
    final gpu.BufferView view1 = hostBuffer
        .emplace(Int8List.fromList(<int>[0, 1, 2, 3]).buffer.asByteData());

    expect(view0.buffer, equals(view1.buffer));
  }, skip: !impellerEnabled);

  test('GpuContext.createDeviceBuffer', () async {
    final gpu.DeviceBuffer? deviceBuffer =
        gpu.gpuContext.createDeviceBuffer(gpu.StorageMode.hostVisible, 4);
    assert(deviceBuffer != null);

    expect(deviceBuffer!.sizeInBytes, 4);
  }, skip: !impellerEnabled);

  test('DeviceBuffer.overwrite', () async {
    final gpu.DeviceBuffer? deviceBuffer =
        gpu.gpuContext.createDeviceBuffer(gpu.StorageMode.hostVisible, 4);
    assert(deviceBuffer != null);

    final bool success = deviceBuffer!
        .overwrite(Int8List.fromList(<int>[0, 1, 2, 3]).buffer.asByteData());
    deviceBuffer.flush();
    expect(success, true);
  }, skip: !impellerEnabled);

  test('DeviceBuffer.overwrite fails when out of bounds', () async {
    final gpu.DeviceBuffer? deviceBuffer =
        gpu.gpuContext.createDeviceBuffer(gpu.StorageMode.hostVisible, 4);
    assert(deviceBuffer != null);

    final bool success = deviceBuffer!.overwrite(
        Int8List.fromList(<int>[0, 1, 2, 3]).buffer.asByteData(),
        destinationOffsetInBytes: 1);
    deviceBuffer.flush();
    expect(success, false);
  }, skip: !impellerEnabled);

  test('DeviceBuffer.overwrite throws for negative destination offset',
      () async {
    final gpu.DeviceBuffer? deviceBuffer =
        gpu.gpuContext.createDeviceBuffer(gpu.StorageMode.hostVisible, 4);
    assert(deviceBuffer != null);

    try {
      deviceBuffer!.overwrite(
          Int8List.fromList(<int>[0, 1, 2, 3]).buffer.asByteData(),
          destinationOffsetInBytes: -1);
      deviceBuffer.flush();
      fail('Exception not thrown for negative destination offset.');
    } catch (e) {
      expect(
          e.toString(), contains('destinationOffsetInBytes must be positive'));
    }
  }, skip: !impellerEnabled);

  test('GpuContext.createTexture', () async {
    final gpu.Texture? texture =
        gpu.gpuContext.createTexture(gpu.StorageMode.hostVisible, 100, 100);
    assert(texture != null);

    // Check the defaults.
    expect(
        texture!.coordinateSystem, gpu.TextureCoordinateSystem.renderToTexture);
    expect(texture.width, 100);
    expect(texture.height, 100);
    expect(texture.storageMode, gpu.StorageMode.hostVisible);
    expect(texture.sampleCount, 1);
    expect(texture.format, gpu.PixelFormat.r8g8b8a8UNormInt);
    expect(texture.enableRenderTargetUsage, true);
    expect(texture.enableShaderReadUsage, true);
    expect(!texture.enableShaderWriteUsage, true);
    expect(texture.bytesPerTexel, 4);
    expect(texture.GetBaseMipLevelSizeInBytes(), 40000);
  }, skip: !impellerEnabled);

  test('Texture.overwrite', () async {
    final gpu.Texture? texture =
        gpu.gpuContext.createTexture(gpu.StorageMode.hostVisible, 2, 2);
    assert(texture != null);

    const ui.Color red = ui.Color.fromARGB(0xFF, 0xFF, 0, 0);
    const ui.Color green = ui.Color.fromARGB(0xFF, 0, 0xFF, 0);
    final bool success = texture!.overwrite(Int32List.fromList(
            <int>[red.value, green.value, green.value, red.value])
        .buffer
        .asByteData());

    expect(success, true);
  }, skip: !impellerEnabled);

  test('Texture.overwrite throws for wrong buffer size', () async {
    final gpu.Texture? texture =
        gpu.gpuContext.createTexture(gpu.StorageMode.hostVisible, 100, 100);
    assert(texture != null);

    const ui.Color red = ui.Color.fromARGB(0xFF, 0xFF, 0, 0);
    try {
      texture!.overwrite(
          Int32List.fromList(<int>[red.value, red.value, red.value, red.value])
              .buffer
              .asByteData());
      fail('Exception not thrown for wrong buffer size.');
    } catch (e) {
      expect(
          e.toString(),
          contains(
              'The length of sourceBytes (bytes: 16) must exactly match the size of the base mip level (bytes: 40000)'));
    }
  }, skip: !impellerEnabled);

  test('Texture.asImage returns a valid ui.Image handle', () async {
    final gpu.Texture? texture =
        gpu.gpuContext.createTexture(gpu.StorageMode.hostVisible, 100, 100);
    assert(texture != null);

    final ui.Image image = texture!.asImage();
    expect(image.width, 100);
    expect(image.height, 100);
  }, skip: !impellerEnabled);

  test('Texture.asImage throws when not shader readable', () async {
    final gpu.Texture? texture = gpu.gpuContext.createTexture(
        gpu.StorageMode.hostVisible, 100, 100,
        enableShaderReadUsage: false);
    assert(texture != null);

    try {
      texture!.asImage();
      fail('Exception not thrown when not shader readable.');
    } catch (e) {
      expect(
          e.toString(),
          contains(
              'Only shader readable Flutter GPU textures can be used as UI Images'));
    }
  }, skip: !impellerEnabled);

  test('RenderPass.setStencilReference doesnt throw for valid values',
      () async {
    final state = createSimpleRenderPass();

    state.renderPass.setStencilReference(0);
    state.renderPass.setStencilReference(2 << 30);
  }, skip: !impellerEnabled);

  test('RenderPass.setStencilReference throws for invalid values', () async {
    final state = createSimpleRenderPass();

    try {
      state.renderPass.setStencilReference(-1);
      fail('Exception not thrown for out of bounds stencil reference.');
    } catch (e) {
      expect(e.toString(),
          contains('The stencil reference value must be in the range'));
    }

    try {
      state.renderPass.setStencilReference(2 << 31);
      fail('Exception not thrown for out of bounds stencil reference.');
    } catch (e) {
      expect(e.toString(),
          contains('The stencil reference value must be in the range'));
    }
  }, skip: !impellerEnabled);

  test('RenderPass.setStencilConfig doesnt throw for valid values', () async {
    final state = createSimpleRenderPass();

    state.renderPass.setStencilConfig(gpu.StencilConfig());
    state.renderPass.setStencilConfig(
        gpu.StencilConfig(
            compareFunction: gpu.CompareFunction.notEqual,
            depthFailureOperation: gpu.StencilOperation.decrementWrap,
            depthStencilPassOperation: gpu.StencilOperation.incrementWrap,
            stencilFailureOperation: gpu.StencilOperation.invert,
            readMask: 0,
            writeMask: 0),
        targetFace: gpu.StencilFace.back);
  }, skip: !impellerEnabled);

  test('RenderPass.setStencilConfig throws for invalid masks', () async {
    final state = createSimpleRenderPass();

    try {
      state.renderPass.setStencilConfig(gpu.StencilConfig(readMask: -1));
      fail('Exception not thrown for invalid stencil read mask.');
    } catch (e) {
      expect(
          e.toString(), contains('The stencil read mask must be in the range'));
    }
    try {
      state.renderPass
          .setStencilConfig(gpu.StencilConfig(readMask: 0xFFFFFFFF + 1));
      fail('Exception not thrown for invalid stencil read mask.');
    } catch (e) {
      expect(
          e.toString(), contains('The stencil read mask must be in the range'));
    }

    try {
      state.renderPass.setStencilConfig(gpu.StencilConfig(writeMask: -1));
      fail('Exception not thrown for invalid stencil write mask.');
    } catch (e) {
      expect(e.toString(),
          contains('The stencil write mask must be in the range'));
    }
    try {
      state.renderPass
          .setStencilConfig(gpu.StencilConfig(writeMask: 0xFFFFFFFF + 1));
      fail('Exception not thrown for invalid stencil write mask.');
    } catch (e) {
      expect(e.toString(),
          contains('The stencil write mask must be in the range'));
    }
  }, skip: !impellerEnabled);

  test('RenderPass.bindTexture throws for deviceTransient Textures', () async {
    final state = createSimpleRenderPass();

    final gpu.RenderPipeline pipeline = createUnlitRenderPipeline();
    // Although this is a non-texture uniform slot, it'll work fine for the
    // purposes of testing this error.
    final gpu.UniformSlot vertInfo =
        pipeline.vertexShader.getUniformSlot('VertInfo');

    final gpu.Texture texture = gpu.gpuContext
        .createTexture(gpu.StorageMode.deviceTransient, 100, 100)!;

    try {
      state.renderPass.bindTexture(vertInfo, texture);
      fail('Exception not thrown when binding a transient texture.');
    } catch (e) {
      expect(
          e.toString(),
          contains(
              'Textures with StorageMode.deviceTransient cannot be bound to a RenderPass'));
    }
  }, skip: !impellerEnabled);

  // Performs no draw calls. Just clears the render target to a solid green color.
  test('Can render clear color', () async {
    final state = createSimpleRenderPass(clearColor: Colors.lime);

    state.commandBuffer.submit();

    final ui.Image image = state.renderTexture.asImage();
    await comparer.addGoldenImage(image, 'flutter_gpu_test_clear_color.png');
  }, skip: !impellerEnabled);

  // Regression test for https://github.com/flutter/flutter/issues/157324
  test('Can bind uniforms in range', () async {
    final state = createSimpleRenderPass();

    final gpu.RenderPipeline pipeline = createUnlitRenderPipeline();
    final gpu.UniformSlot vertInfo =
        pipeline.vertexShader.getUniformSlot('VertInfo');

    final ByteData vertInfoData = float32(<double>[
      1, 0, 0, 0, // mvp
      0, 1, 0, 0, // mvp
      0, 0, 1, 0, // mvp
      0, 0, 0, 1, // mvp
      0, 1, 0, 1, // color
    ]);
    final uniformBuffer =
        gpu.gpuContext.createDeviceBufferWithCopy(vertInfoData)!;
    final gooduniformBufferView = gpu.BufferView(
      uniformBuffer,
      offsetInBytes: 0,
      lengthInBytes: uniformBuffer.sizeInBytes,
    );
    state.renderPass.bindUniform(vertInfo, gooduniformBufferView);

    final badUniformBufferView = gpu.BufferView(
      uniformBuffer,
      offsetInBytes: 0,
      lengthInBytes: uniformBuffer.sizeInBytes + 1,
    );
    try {
      state.renderPass.bindUniform(vertInfo, badUniformBufferView);
      fail('Exception not thrown for bad buffer view range.');
    } catch (e) {
      expect(e.toString(), contains('Failed to bind uniform'));
    }
  }, skip: !impellerEnabled);

  // Renders a green triangle pointing downwards.
  test('Can render triangle', () async {
    final state = createSimpleRenderPass();
    drawTriangle(state, Colors.lime);
    state.commandBuffer.submit();

    final ui.Image image = state.renderTexture.asImage();
    await comparer.addGoldenImage(image, 'flutter_gpu_test_triangle.png');
  }, skip: !impellerEnabled);

  // Renders a green triangle pointing downwards using polygon mode line.
  test('Can render triangle with polygon mode line.', () async {
    final state = createSimpleRenderPass();

    final gpu.RenderPipeline pipeline = createUnlitRenderPipeline();
    state.renderPass.bindPipeline(pipeline);

    // Configure blending with defaults (just to test the bindings).
    state.renderPass.setColorBlendEnable(true);
    state.renderPass.setColorBlendEquation(gpu.ColorBlendEquation());

    // Set polygon mode.
    state.renderPass.setPolygonMode(gpu.PolygonMode.line);

    final gpu.HostBuffer transients = gpu.gpuContext.createHostBuffer();
    final gpu.BufferView vertices = transients.emplace(float32(<double>[
      -0.5, 0.5, //
      0.0, -0.5, //
      0.5, 0.5, //
    ]));
    final gpu.BufferView vertInfoData = transients.emplace(float32(<double>[
      1, 0, 0, 0, // mvp
      0, 1, 0, 0, // mvp
      0, 0, 1, 0, // mvp
      0, 0, 0, 1, // mvp
      0, 1, 0, 1, // color
    ]));
    state.renderPass.bindVertexBuffer(vertices, 3);

    final gpu.UniformSlot vertInfo =
        pipeline.vertexShader.getUniformSlot('VertInfo');
    state.renderPass.bindUniform(vertInfo, vertInfoData);
    state.renderPass.draw();

    state.commandBuffer.submit();

    final ui.Image image = state.renderTexture.asImage();
    await comparer.addGoldenImage(
        image, 'flutter_gpu_test_triangle_polygon_mode.png');
  }, skip: !impellerEnabled);

  // Renders a green triangle pointing downwards, with 4xMSAA.
  test('Can render triangle with MSAA', () async {
    final state = createSimpleRenderPassWithMSAA();
    drawTriangle(state, Colors.lime);
    state.commandBuffer.submit();

    final ui.Image image = state.renderTexture.asImage();
    await comparer.addGoldenImage(image, 'flutter_gpu_test_triangle_msaa.png');
  }, skip: !(impellerEnabled && gpu.gpuContext.doesSupportOffscreenMSAA));

  test(
      'Rendering with MSAA throws exception when offscreen MSAA is not supported',
      () async {
    try {
      final state = createSimpleRenderPassWithMSAA();
      drawTriangle(state, Colors.lime);
      state.commandBuffer.submit();
      fail('Exception not thrown when offscreen MSAA is not supported.');
    } catch (e) {
      expect(
          e.toString(),
          contains(
              'The backend does not support multisample anti-aliasing for offscreen color and stencil attachments'));
    }
  }, skip: !(impellerEnabled && !gpu.gpuContext.doesSupportOffscreenMSAA));

  // Renders a hollow green triangle pointing downwards.
  test('Can render hollowed out triangle using stencil ops', () async {
    final state = createSimpleRenderPass();

    final gpu.RenderPipeline pipeline = createUnlitRenderPipeline();
    state.renderPass.bindPipeline(pipeline);

    // Configure blending with defaults (just to test the bindings).
    state.renderPass.setColorBlendEnable(true);
    state.renderPass.setColorBlendEquation(gpu.ColorBlendEquation());

    final gpu.HostBuffer transients = gpu.gpuContext.createHostBuffer();
    final gpu.BufferView vertices = transients.emplace(float32(<double>[
      -0.5, 0.5, //
      0.0, -0.5, //
      0.5, 0.5, //
    ]));
    final gpu.BufferView innerClipVertInfo =
        transients.emplace(float32(<double>[
      0.5, 0, 0, 0, // mvp
      0, 0.5, 0, 0, // mvp
      0, 0, 0.5, 0, // mvp
      0, 0, 0, 1, // mvp
      0, 1, 0, 1, // color
    ]));
    final gpu.BufferView outerGreenVertInfo =
        transients.emplace(float32(<double>[
      1, 0, 0, 0, // mvp
      0, 1, 0, 0, // mvp
      0, 0, 1, 0, // mvp
      0, 0, 0, 1, // mvp
      0, 1, 0, 1, // color
    ]));
    state.renderPass.bindVertexBuffer(vertices, 3);

    final gpu.UniformSlot vertInfo =
        pipeline.vertexShader.getUniformSlot('VertInfo');

    // First, punch out a scaled down triangle in the stencil buffer.
    // Since the stencil buffer is initialized to 0, we set the stencil ref to 1
    // and the compare to `equial`, which will result in the stencil test
    // failing. But on failure, we increment the stencil in order to punch out
    // the triangle.

    state.renderPass.bindUniform(vertInfo, innerClipVertInfo);
    state.renderPass.setStencilReference(1);
    state.renderPass.setStencilConfig(gpu.StencilConfig(
        compareFunction: gpu.CompareFunction.equal,
        stencilFailureOperation: gpu.StencilOperation.incrementClamp));
    state.renderPass.draw();

    // Next, render the outer triangle with the stencil ref set to zero, so that
    // the stencil test passes everywhere except where the inner triangle was
    // punched out.

    state.renderPass.setStencilReference(0);
    // Set the stencil config to turn off the increment. For this golden test
    // we technically don't need to do this, but we do it here just to exercise
    // the API.
    state.renderPass.setStencilConfig(
        gpu.StencilConfig(compareFunction: gpu.CompareFunction.equal));
    state.renderPass.bindUniform(vertInfo, outerGreenVertInfo);
    state.renderPass.draw();

    state.commandBuffer.submit();

    final ui.Image image = state.renderTexture.asImage();
    await comparer.addGoldenImage(
        image, 'flutter_gpu_test_triangle_stencil.png');
  }, skip: !impellerEnabled);

  test('Drawing respects cull mode', () async {
    final state = createSimpleRenderPass();

    final gpu.RenderPipeline pipeline = createUnlitRenderPipeline();
    state.renderPass.bindPipeline(pipeline);

    state.renderPass.setColorBlendEnable(true);
    state.renderPass.setColorBlendEquation(gpu.ColorBlendEquation());

    final gpu.HostBuffer transients = gpu.gpuContext.createHostBuffer();
    // Counter-clockwise triangle.
    final List<double> triangle = [
      -0.5, 0.5, //
      0.0, -0.5, //
      0.5, 0.5, //
    ];
    final gpu.BufferView vertices = transients.emplace(float32(triangle));

    void drawTriangle(Vector4 color) {
      final gpu.BufferView vertInfoUboFront =
          transients.emplace(unlitUBO(Matrix4.identity(), color));

      final gpu.UniformSlot vertInfo =
          pipeline.vertexShader.getUniformSlot('VertInfo');
      state.renderPass.bindVertexBuffer(vertices, 3);
      state.renderPass.bindUniform(vertInfo, vertInfoUboFront);
      state.renderPass.draw();
    }

    // Draw the green rectangle.
    // Defaults to clockwise winding order. So frontface culling should not
    // impact the green triangle.
    state.renderPass.setCullMode(gpu.CullMode.frontFace);
    drawTriangle(Colors.lime);

    // Backface cull a red triangle.
    state.renderPass.setCullMode(gpu.CullMode.backFace);
    drawTriangle(Colors.red);

    // Invert the winding mode and frontface cull a red rectangle.
    state.renderPass.setWindingOrder(gpu.WindingOrder.counterClockwise);
    state.renderPass.setCullMode(gpu.CullMode.frontFace);
    drawTriangle(Colors.red);

    state.commandBuffer.submit();

    final ui.Image image = state.renderTexture.asImage();
    await comparer.addGoldenImage(image, 'flutter_gpu_test_cull_mode.png');
  }, skip: !impellerEnabled);

  // Renders a hexagon using line strip primitive type.
  test('Can render hollow hexagon using line strip primitive type', () async {
    final state = createSimpleRenderPass();

    final gpu.RenderPipeline pipeline = createUnlitRenderPipeline();
    state.renderPass.bindPipeline(pipeline);

    // Configure blending with defaults (just to test the bindings).
    state.renderPass.setColorBlendEnable(true);
    state.renderPass.setColorBlendEquation(gpu.ColorBlendEquation());

    // Set primitive type
    state.renderPass.setPrimitiveType(gpu.PrimitiveType.lineStrip);

    final gpu.HostBuffer transients = gpu.gpuContext.createHostBuffer();
    final gpu.BufferView vertices = transients.emplace(float32(<double>[
      1.0,
      0.0,
      0.5,
      0.8,
      -0.5,
      0.8,
      -1.0,
      0.0,
      -0.5,
      -0.8,
      0.5,
      -0.8,
      1.0,
      0.0
    ]));
    final gpu.BufferView vertInfoData = transients.emplace(float32(<double>[
      1, 0, 0, 0, // mvp
      0, 1, 0, 0, // mvp
      0, 0, 1, 0, // mvp
      0, 0, 0, 1, // mvp
      0, 1, 0, 1, // color
    ]));
    state.renderPass.bindVertexBuffer(vertices, 7);

    final gpu.UniformSlot vertInfo =
        pipeline.vertexShader.getUniformSlot('VertInfo');
    state.renderPass.bindUniform(vertInfo, vertInfoData);
    state.renderPass.draw();

    state.commandBuffer.submit();

    final ui.Image image = state.renderTexture.asImage();
    await comparer.addGoldenImage(
        image, 'flutter_gpu_test_hexgon_line_strip.png');
  }, skip: !impellerEnabled);
}
