diff --git a/engine/src/flutter/lib/gpu/formats.h b/engine/src/flutter/lib/gpu/formats.h index cd9ac85820..4c52fd57c7 100644 --- a/engine/src/flutter/lib/gpu/formats.h +++ b/engine/src/flutter/lib/gpu/formats.h @@ -541,6 +541,25 @@ constexpr impeller::WindingOrder ToImpellerWindingOrder(int value) { return ToImpellerWindingOrder(static_cast(value)); } +enum class FlutterGPUPolygonMode { + kFill, + kLine, +}; + +constexpr impeller::PolygonMode ToImpellerPolygonMode( + FlutterGPUPolygonMode value) { + switch (value) { + case FlutterGPUPolygonMode::kFill: + return impeller::PolygonMode::kFill; + case FlutterGPUPolygonMode::kLine: + return impeller::PolygonMode::kLine; + } +} + +constexpr impeller::PolygonMode ToImpellerPolygonMode(int value) { + return ToImpellerPolygonMode(static_cast(value)); +} + } // namespace gpu } // namespace flutter diff --git a/engine/src/flutter/lib/gpu/lib/src/formats.dart b/engine/src/flutter/lib/gpu/lib/src/formats.dart index ec6e703d90..a7a5f51b88 100644 --- a/engine/src/flutter/lib/gpu/lib/src/formats.dart +++ b/engine/src/flutter/lib/gpu/lib/src/formats.dart @@ -146,6 +146,11 @@ enum WindingOrder { counterClockwise, } +enum PolygonMode { + fill, + line +} + enum CompareFunction { /// Comparison test never passes. never, diff --git a/engine/src/flutter/lib/gpu/lib/src/render_pass.dart b/engine/src/flutter/lib/gpu/lib/src/render_pass.dart index 3be710fc6a..95d7b5f317 100644 --- a/engine/src/flutter/lib/gpu/lib/src/render_pass.dart +++ b/engine/src/flutter/lib/gpu/lib/src/render_pass.dart @@ -262,10 +262,13 @@ base class RenderPass extends NativeFieldWrapperClass1 { _setCullMode(cullMode.index); } + void setPolygonMode(PolygonMode polygonMode) { + _setPolygonMode(polygonMode.index); + } void setPrimitiveType(PrimitiveType primitiveType) { _setPrimitiveType(primitiveType.index); -} + } void setWindingOrder(WindingOrder windingOrder) { _setWindingOrder(windingOrder.index); @@ -433,6 +436,9 @@ base class RenderPass extends NativeFieldWrapperClass1 { symbol: 'InternalFlutterGpu_RenderPass_SetWindingOrder') external void _setWindingOrder(int windingOrder); + @Native, Int)>( + symbol: 'InternalFlutterGpu_RenderPass_SetPolygonMode') + external void _setPolygonMode(int polygonMode); @Native)>( symbol: 'InternalFlutterGpu_RenderPass_Draw') diff --git a/engine/src/flutter/lib/gpu/render_pass.cc b/engine/src/flutter/lib/gpu/render_pass.cc index f5ce4246eb..46d0085def 100644 --- a/engine/src/flutter/lib/gpu/render_pass.cc +++ b/engine/src/flutter/lib/gpu/render_pass.cc @@ -617,6 +617,15 @@ void InternalFlutterGpu_RenderPass_SetWindingOrder( flutter::gpu::ToImpellerWindingOrder(winding_order)); } +void InternalFlutterGpu_RenderPass_SetPolygonMode( + flutter::gpu::RenderPass* wrapper, + int polygon_mode) { + impeller::PipelineDescriptor& pipeline_descriptor = + wrapper->GetPipelineDescriptor(); + pipeline_descriptor.SetPolygonMode( + flutter::gpu::ToImpellerPolygonMode(polygon_mode)); +} + bool InternalFlutterGpu_RenderPass_Draw(flutter::gpu::RenderPass* wrapper) { return wrapper->Draw(); } diff --git a/engine/src/flutter/lib/gpu/render_pass.h b/engine/src/flutter/lib/gpu/render_pass.h index 49708bde60..cf572641fb 100644 --- a/engine/src/flutter/lib/gpu/render_pass.h +++ b/engine/src/flutter/lib/gpu/render_pass.h @@ -261,6 +261,11 @@ extern void InternalFlutterGpu_RenderPass_SetWindingOrder( flutter::gpu::RenderPass* wrapper, int winding_order); +FLUTTER_GPU_EXPORT +extern void InternalFlutterGpu_RenderPass_SetPolygonMode( + flutter::gpu::RenderPass* wrapper, + int polygon_mode); + FLUTTER_GPU_EXPORT extern bool InternalFlutterGpu_RenderPass_Draw( flutter::gpu::RenderPass* wrapper); diff --git a/engine/src/flutter/testing/dart/gpu_test.dart b/engine/src/flutter/testing/dart/gpu_test.dart index fecde35857..a26bab37b9 100644 --- a/engine/src/flutter/testing/dart/gpu_test.dart +++ b/engine/src/flutter/testing/dart/gpu_test.dart @@ -371,6 +371,46 @@ void main() async { 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([ + -0.5, 0.5, // + 0.0, -0.5, // + 0.5, 0.5, // + ])); + final gpu.BufferView vertInfoData = transients.emplace(float32([ + 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 hollow green triangle pointing downwards. test('Can render hollowed out triangle using stencil ops', () async { final state = createSimpleRenderPass();