From e9e2ef4f64ad6b97cb1ab22e9b7a31c59518aa5e Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 20 May 2024 09:31:18 -0700 Subject: [PATCH 01/13] [Impeller] use varying interpolation for linear gradients. --- impeller/entity/BUILD.gn | 2 + impeller/entity/contents/content_context.cc | 1 + impeller/entity/contents/content_context.h | 10 +++ .../contents/linear_gradient_contents.cc | 90 +++++++++++++++++++ .../contents/linear_gradient_contents.h | 4 + .../entity/shaders/gradients/gradient.frag | 23 +++++ .../entity/shaders/gradients/gradient.vert | 21 +++++ 7 files changed, 151 insertions(+) create mode 100644 impeller/entity/shaders/gradients/gradient.frag create mode 100644 impeller/entity/shaders/gradients/gradient.vert diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index c529d46684393..bb8dc08f2fb17 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -48,6 +48,8 @@ impeller_shaders("entity_shaders") { "shaders/filters/linear_to_srgb_filter.frag", "shaders/filters/morphology_filter.frag", "shaders/blending/vertices_uber.frag", + "shaders/gradients/gradient.vert", + "shaders/gradients/gradient.frag", ] } diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index fe3338fdaa791..f55f3afb645a3 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -293,6 +293,7 @@ ContentContext::ContentContext( { solid_fill_pipelines_.CreateDefault(*context_, options); texture_pipelines_.CreateDefault(*context_, options); + gradient_pipelines_.CreateDefault(*context_, options); if (context_->GetCapabilities()->SupportsSSBO()) { linear_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options); diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 1888845a222f8..cadd31d582918 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -34,6 +34,8 @@ #include "impeller/entity/gaussian.frag.h" #include "impeller/entity/glyph_atlas.frag.h" #include "impeller/entity/glyph_atlas.vert.h" +#include "impeller/entity/gradient.frag.h" +#include "impeller/entity/gradient.vert.h" #include "impeller/entity/gradient_fill.vert.h" #include "impeller/entity/linear_gradient_fill.frag.h" #include "impeller/entity/linear_to_srgb_filter.frag.h" @@ -79,6 +81,8 @@ namespace impeller { +using GradientPipeline = + RenderPipelineHandle; using LinearGradientFillPipeline = RenderPipelineHandle; @@ -379,6 +383,11 @@ class ContentContext { std::shared_ptr GetTessellator() const; + std::shared_ptr> GetGradientPipeline( + ContentContextOptions opts) const { + return GetPipeline(gradient_pipelines_, opts); + } + std::shared_ptr> GetLinearGradientFillPipeline( ContentContextOptions opts) const { return GetPipeline(linear_gradient_fill_pipelines_, opts); @@ -859,6 +868,7 @@ class ContentContext { // map. mutable Variants solid_fill_pipelines_; + mutable Variants gradient_pipelines_; mutable Variants linear_gradient_fill_pipelines_; mutable Variants radial_gradient_fill_pipelines_; mutable Variants diff --git a/impeller/entity/contents/linear_gradient_contents.cc b/impeller/entity/contents/linear_gradient_contents.cc index 99f2c79055f15..e4c627b6ed57d 100644 --- a/impeller/entity/contents/linear_gradient_contents.cc +++ b/impeller/entity/contents/linear_gradient_contents.cc @@ -9,6 +9,7 @@ #include "impeller/entity/contents/gradient_generator.h" #include "impeller/entity/entity.h" #include "impeller/renderer/render_pass.h" +#include "impeller/renderer/vertex_buffer_builder.h" namespace impeller { @@ -53,9 +54,98 @@ bool LinearGradientContents::IsOpaque() const { return true; } +// A much faster (in terms of ALU) linear gradient that uses vertex +// interpolation to perform all color computation. Requires that the geometry of +// the gradient is divided. +bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const { + using VS = GradientPipeline::VertexShader; + using FS = GradientPipeline::FragmentShader; + + auto options = OptionsFromPassAndEntity(pass, entity); + Geometry& geometry = *GetGeometry(); + + // We already know this is an axis aligned rectangle, so the coverage will + // be approximately the same as the geometry. For non AARs, we can force + // stencil then cover (not done here). We give an identity transform to + // avoid double transforming the gradient. + std::optional maybe_rect = geometry.GetCoverage(Matrix()); + if (!maybe_rect.has_value()) { + return false; + } + Rect rect = maybe_rect.value(); + + VertexBufferBuilder vtx_builder; + bool horizontal_axis = start_point_.x == end_point_.x; + + // Step 1. Compute the locations of each breakpoint along the primary axis. + if (stops_.size() == 2) { + // If there are exactly two stops then we have a nearly trivial gradient. + // Augment each vertex and submit. This is wrong if the gradient goes end -> + // start, we could fix that via some normalization. + vtx_builder.AddVertices( + {{rect.GetLeftTop(), colors_[0]}, + {rect.GetRightTop(), horizontal_axis ? colors_[0] : colors_[1]}, + {rect.GetLeftBottom(), horizontal_axis ? colors_[1] : colors_[0]}, + {rect.GetRightBottom(), colors_[1]}}); + options.primitive_type = PrimitiveType::kTriangleStrip; + } else { + // Otherwise, we need to compute a point along the primary axis. + std::vector points(stops_.size()); + for (auto i = 0u; i < stops_.size(); i++) { + Scalar t = stops_[i]; + points[i] = (1.0 - t) * start_point_ + t * end_point_; + } + // Now create a rectangle that joins each segment. That will be two + // triangles between each pair of points. For now just assume vertical but + // we'll fix this later. + options.primitive_type = PrimitiveType::kTriangle; + vtx_builder.Reserve(6 * (stops_.size() - 1)); + for (auto i = 1u; i < points.size(); i++) { + Rect section = + Rect::MakeXYWH(rect.GetX(), points[i - 1].y, rect.GetWidth(), + abs(points[i].y - points[i - 1].y)); + vtx_builder.AddVertices({ + {section.GetLeftTop(), colors_[i - 1]}, + {section.GetRightTop(), colors_[i - 1]}, + {section.GetLeftBottom(), colors_[i]}, + {section.GetRightTop(), colors_[i - 1]}, + {section.GetLeftBottom(), colors_[i]}, + {section.GetRightBottom(), colors_[i]}, + }); + } + } + + auto& host_buffer = renderer.GetTransientsBuffer(); + + pass.SetLabel("LinearGradient"); + pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer)); + pass.SetPipeline(renderer.GetGradientPipeline(options)); + pass.SetStencilReference(0); + + // Take the pre-populated vertex shader uniform struct and set managed + // values. + VS::FrameInfo frame_info; + frame_info.mvp = entity.GetShaderTransform(pass); + + VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info)); + + FS::FragInfo frag_info; + frag_info.alpha = GetOpacityFactor(); + + FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info)); + + return pass.Draw().ok(); +} + bool LinearGradientContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { + if (GetGeometry()->IsAxisAlignedRect() && + (start_point_.x == end_point_.x || start_point_.y == end_point_.y)) { + return FastLinearGradient(renderer, entity, pass); + } if (renderer.GetDeviceCapabilities().SupportsSSBO()) { return RenderSSBO(renderer, entity, pass); } diff --git a/impeller/entity/contents/linear_gradient_contents.h b/impeller/entity/contents/linear_gradient_contents.h index 1dd644977c67d..c1b94c6db4bc0 100644 --- a/impeller/entity/contents/linear_gradient_contents.h +++ b/impeller/entity/contents/linear_gradient_contents.h @@ -53,6 +53,10 @@ class LinearGradientContents final : public ColorSourceContents { const Entity& entity, RenderPass& pass) const; + bool FastLinearGradient(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const; + Point start_point_; Point end_point_; std::vector colors_; diff --git a/impeller/entity/shaders/gradients/gradient.frag b/impeller/entity/shaders/gradients/gradient.frag new file mode 100644 index 0000000000000..6a03610ab53e2 --- /dev/null +++ b/impeller/entity/shaders/gradients/gradient.frag @@ -0,0 +1,23 @@ +// 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. + +precision mediump float; + +#include +#include +#include + +uniform FragInfo { + float alpha; +} +frag_info; + +in vec4 v_color; + +out vec4 frag_color; + +void main() { + frag_color = IPPremultiply(v_color) * frag_info.alpha; + frag_color = IPOrderedDither8x8(frag_color, gl_FragCoord.xy); +} diff --git a/impeller/entity/shaders/gradients/gradient.vert b/impeller/entity/shaders/gradients/gradient.vert new file mode 100644 index 0000000000000..9a6cdfeac1d87 --- /dev/null +++ b/impeller/entity/shaders/gradients/gradient.vert @@ -0,0 +1,21 @@ +// 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. + +#include +#include + +uniform FrameInfo { + mat4 mvp; +} +frame_info; + +in vec2 position; +in vec4 color; + +out vec4 v_color; + +void main() { + gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0); + v_color = color; +} From af7c7ee511fde991091f0d3c761753cb7059f7c1 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Sun, 2 Jun 2024 10:36:48 -0700 Subject: [PATCH 02/13] ++ --- impeller/aiks/aiks_gradient_unittests.cc | 48 ++++++++++++++++++ .../contents/linear_gradient_contents.cc | 49 ++++++++++++------- .../entity/shaders/gradients/gradient.frag | 3 ++ 3 files changed, 83 insertions(+), 17 deletions(-) diff --git a/impeller/aiks/aiks_gradient_unittests.cc b/impeller/aiks/aiks_gradient_unittests.cc index 7938fb60f9f3c..268de96011e50 100644 --- a/impeller/aiks/aiks_gradient_unittests.cc +++ b/impeller/aiks/aiks_gradient_unittests.cc @@ -734,5 +734,53 @@ TEST_P(AiksTest, GradientStrokesRenderCorrectly) { ASSERT_TRUE(OpenPlaygroundHere(callback)); } +// Draws two gradients that should look identical (except that one is an RRECT). +TEST_P(AiksTest, FastGradientTestHorizontal) { + Canvas canvas; + Paint paint; + canvas.Translate({100.0f, 0, 0}); + + std::vector colors = {Color::Red(), Color::Blue(), Color::Green()}; + std::vector stops = {0.0, 0.1, 1.0}; + + paint.color_source = ColorSource::MakeLinearGradient( + {0, 0}, {600, 0}, std::move(colors), std::move(stops), + Entity::TileMode::kClamp, {}); + + paint.color = Color(1.0, 1.0, 1.0, 1.0); + canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint); + + { + canvas.Translate({800, 0, 0}); + canvas.DrawRRect(Rect::MakeXYWH(0, 0, 600, 600), Size(4, 4), paint); + } + + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + +// Draws two gradients that should look identical (except that one is an RRECT). +TEST_P(AiksTest, FastGradientTestVertical) { + Canvas canvas; + Paint paint; + canvas.Translate({100.0f, 0, 0}); + + std::vector colors = {Color::Red(), Color::Blue(), Color::Green()}; + std::vector stops = {0.0, 0.1, 1.0}; + + paint.color_source = ColorSource::MakeLinearGradient( + {0, 0}, {0, 600}, std::move(colors), std::move(stops), + Entity::TileMode::kClamp, {}); + + paint.color = Color(1.0, 1.0, 1.0, 1.0); + canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint); + + { + canvas.Translate({800, 0, 0}); + canvas.DrawRRect(Rect::MakeXYWH(0, 0, 600, 600), Size(4, 4), paint); + } + + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + } // namespace testing } // namespace impeller diff --git a/impeller/entity/contents/linear_gradient_contents.cc b/impeller/entity/contents/linear_gradient_contents.cc index 697c87416d4e6..da8a565c5261d 100644 --- a/impeller/entity/contents/linear_gradient_contents.cc +++ b/impeller/entity/contents/linear_gradient_contents.cc @@ -56,7 +56,10 @@ bool LinearGradientContents::IsOpaque() const { // A much faster (in terms of ALU) linear gradient that uses vertex // interpolation to perform all color computation. Requires that the geometry of -// the gradient is divided. +// the gradient is divided into regions based on the stop values. +// Currently restricted to rect geometry where the start and end points are +// perfectly horizontal/vertical, but could easily be expanded to StC cases +// provided that the start/end are on our outside the coverage rect. bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { @@ -64,6 +67,7 @@ bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, using FS = GradientPipeline::FragmentShader; auto options = OptionsFromPassAndEntity(pass, entity); + options.primitive_type = PrimitiveType::kTriangle; Geometry& geometry = *GetGeometry(); // We already know this is an axis aligned rectangle, so the coverage will @@ -77,7 +81,7 @@ bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, Rect rect = maybe_rect.value(); VertexBufferBuilder vtx_builder; - bool horizontal_axis = start_point_.x == end_point_.x; + bool horizontal_axis = start_point_.y == end_point_.y; // Step 1. Compute the locations of each breakpoint along the primary axis. if (stops_.size() == 2) { @@ -86,10 +90,11 @@ bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, // start, we could fix that via some normalization. vtx_builder.AddVertices( {{rect.GetLeftTop(), colors_[0]}, - {rect.GetRightTop(), horizontal_axis ? colors_[0] : colors_[1]}, - {rect.GetLeftBottom(), horizontal_axis ? colors_[1] : colors_[0]}, + {rect.GetRightTop(), horizontal_axis ? colors_[1] : colors_[0]}, + {rect.GetLeftBottom(), horizontal_axis ? colors_[0] : colors_[1]}, + {rect.GetRightTop(), horizontal_axis ? colors_[1] : colors_[0]}, + {rect.GetLeftBottom(), horizontal_axis ? colors_[0] : colors_[1]}, {rect.GetRightBottom(), colors_[1]}}); - options.primitive_type = PrimitiveType::kTriangleStrip; } else { // Otherwise, we need to compute a point along the primary axis. std::vector points(stops_.size()); @@ -98,21 +103,29 @@ bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, points[i] = (1.0 - t) * start_point_ + t * end_point_; } // Now create a rectangle that joins each segment. That will be two - // triangles between each pair of points. For now just assume vertical but - // we'll fix this later. - options.primitive_type = PrimitiveType::kTriangle; + // triangles between each pair of points. vtx_builder.Reserve(6 * (stops_.size() - 1)); for (auto i = 1u; i < points.size(); i++) { Rect section = - Rect::MakeXYWH(rect.GetX(), points[i - 1].y, rect.GetWidth(), - abs(points[i].y - points[i - 1].y)); + horizontal_axis + ? Rect::MakeXYWH(points[i - 1].x, rect.GetY(), + abs(points[i].x - points[i - 1].x), + rect.GetHeight()) + + : Rect::MakeXYWH(rect.GetX(), points[i - 1].y, rect.GetWidth(), + abs(points[i].y - points[i - 1].y)); vtx_builder.AddVertices({ {section.GetLeftTop(), colors_[i - 1]}, - {section.GetRightTop(), colors_[i - 1]}, - {section.GetLeftBottom(), colors_[i]}, - {section.GetRightTop(), colors_[i - 1]}, - {section.GetLeftBottom(), colors_[i]}, - {section.GetRightBottom(), colors_[i]}, + {section.GetRightTop(), + horizontal_axis ? colors_[i] : colors_[i - 1]}, + {section.GetLeftBottom(), + horizontal_axis ? colors_[i - 1] : colors_[i]}, + {section.GetRightTop(), + horizontal_axis ? colors_[i] : colors_[i - 1]}, + {section.GetLeftBottom(), + horizontal_axis ? colors_[i - 1] : colors_[i]}, + {section.GetRightBottom(), + horizontal_axis ? colors_[i] : colors_[i - 1]}, }); } } @@ -132,7 +145,8 @@ bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info)); FS::FragInfo frag_info; - frag_info.alpha = GetOpacityFactor(); + frag_info.alpha = + GetOpacityFactor() * GetGeometry()->ComputeAlphaCoverage(entity); FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info)); @@ -143,7 +157,8 @@ bool LinearGradientContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { if (GetGeometry()->IsAxisAlignedRect() && - (start_point_.x == end_point_.x || start_point_.y == end_point_.y)) { + (start_point_.x == end_point_.x || start_point_.y == end_point_.y) && + GetInverseEffectTransform().IsIdentity()) { return FastLinearGradient(renderer, entity, pass); } if (renderer.GetDeviceCapabilities().SupportsSSBO()) { diff --git a/impeller/entity/shaders/gradients/gradient.frag b/impeller/entity/shaders/gradients/gradient.frag index 6a03610ab53e2..b52f9aa3b2b55 100644 --- a/impeller/entity/shaders/gradients/gradient.frag +++ b/impeller/entity/shaders/gradients/gradient.frag @@ -19,5 +19,8 @@ out vec4 frag_color; void main() { frag_color = IPPremultiply(v_color) * frag_info.alpha; + // mod operator is not supported in GLES 2.0 +#ifndef IMPELLER_TARGET_OPENGLES frag_color = IPOrderedDither8x8(frag_color, gl_FragCoord.xy); +#endif // IMPELLER_TARGET_OPENGLES } From b5f764a6c6a4a6d59f7df890e5391a8df227b57c Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Sun, 2 Jun 2024 13:18:38 -0700 Subject: [PATCH 03/13] ++ --- impeller/tools/malioc.json | 459 +++++++++++++++++++++++++++++++++++++ 1 file changed, 459 insertions(+) diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index f156b6c8fefc9..54376a1f40167 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -2476,6 +2476,280 @@ } } }, + "flutter/impeller/entity/gles/gradient.frag.gles": { + "Mali-G78": { + "core": "Mali-G78", + "filename": "flutter/impeller/entity/gles/gradient.frag.gles", + "has_side_effects": false, + "has_uniform_computation": false, + "modifies_coverage": false, + "reads_color_buffer": false, + "type": "Fragment", + "uses_late_zs_test": false, + "uses_late_zs_update": false, + "variants": { + "Main": { + "fp16_arithmetic": 100, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "varying" + ], + "longest_path_cycles": [ + 0.0625, + 0.0625, + 0.046875, + 0.0, + 0.0, + 0.25, + 0.0 + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "varying", + "texture" + ], + "shortest_path_bound_pipelines": [ + "varying" + ], + "shortest_path_cycles": [ + 0.0625, + 0.0625, + 0.015625, + 0.0, + 0.0, + 0.25, + 0.0 + ], + "total_bound_pipelines": [ + "varying" + ], + "total_cycles": [ + 0.0625, + 0.0625, + 0.046875, + 0.0, + 0.0, + 0.25, + 0.0 + ] + }, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 2, + "work_registers_used": 19 + } + } + }, + "Mali-T880": { + "core": "Mali-T880", + "filename": "flutter/impeller/entity/gles/gradient.frag.gles", + "has_uniform_computation": false, + "type": "Fragment", + "variants": { + "Main": { + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "arithmetic", + "load_store" + ], + "longest_path_cycles": [ + 1.0, + 1.0, + 0.0 + ], + "pipelines": [ + "arithmetic", + "load_store", + "texture" + ], + "shortest_path_bound_pipelines": [ + "arithmetic", + "load_store" + ], + "shortest_path_cycles": [ + 1.0, + 1.0, + 0.0 + ], + "total_bound_pipelines": [ + "load_store" + ], + "total_cycles": [ + 0.6666666865348816, + 1.0, + 0.0 + ] + }, + "thread_occupancy": 100, + "uniform_registers_used": 1, + "work_registers_used": 2 + } + } + } + }, + "flutter/impeller/entity/gles/gradient.vert.gles": { + "Mali-G78": { + "core": "Mali-G78", + "filename": "flutter/impeller/entity/gles/gradient.vert.gles", + "has_uniform_computation": false, + "type": "Vertex", + "variants": { + "Position": { + "fp16_arithmetic": 0, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "load_store" + ], + "longest_path_cycles": [ + 0.140625, + 0.140625, + 0.0, + 0.0, + 2.0, + 0.0 + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "texture" + ], + "shortest_path_bound_pipelines": [ + "load_store" + ], + "shortest_path_cycles": [ + 0.140625, + 0.140625, + 0.0, + 0.0, + 2.0, + 0.0 + ], + "total_bound_pipelines": [ + "load_store" + ], + "total_cycles": [ + 0.140625, + 0.140625, + 0.0, + 0.0, + 2.0, + 0.0 + ] + }, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 20, + "work_registers_used": 32 + }, + "Varying": { + "fp16_arithmetic": null, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "load_store" + ], + "longest_path_cycles": [ + 0.0, + 0.0, + 0.0, + 0.0, + 3.0, + 0.0 + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "texture" + ], + "shortest_path_bound_pipelines": [ + "load_store" + ], + "shortest_path_cycles": [ + 0.0, + 0.0, + 0.0, + 0.0, + 3.0, + 0.0 + ], + "total_bound_pipelines": [ + "load_store" + ], + "total_cycles": [ + 0.0, + 0.0, + 0.0, + 0.0, + 3.0, + 0.0 + ] + }, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 8, + "work_registers_used": 9 + } + } + }, + "Mali-T880": { + "core": "Mali-T880", + "filename": "flutter/impeller/entity/gles/gradient.vert.gles", + "has_uniform_computation": false, + "type": "Vertex", + "variants": { + "Main": { + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "load_store" + ], + "longest_path_cycles": [ + 2.640000104904175, + 5.0, + 0.0 + ], + "pipelines": [ + "arithmetic", + "load_store", + "texture" + ], + "shortest_path_bound_pipelines": [ + "load_store" + ], + "shortest_path_cycles": [ + 2.640000104904175, + 5.0, + 0.0 + ], + "total_bound_pipelines": [ + "load_store" + ], + "total_cycles": [ + 2.6666667461395264, + 5.0, + 0.0 + ] + }, + "thread_occupancy": 100, + "uniform_registers_used": 5, + "work_registers_used": 2 + } + } + } + }, "flutter/impeller/entity/gles/gradient_fill.vert.gles": { "Mali-G78": { "core": "Mali-G78", @@ -5538,6 +5812,191 @@ } } }, + "flutter/impeller/entity/gradient.frag.vkspv": { + "Mali-G78": { + "core": "Mali-G78", + "filename": "flutter/impeller/entity/gradient.frag.vkspv", + "has_side_effects": false, + "has_uniform_computation": true, + "modifies_coverage": false, + "reads_color_buffer": false, + "type": "Fragment", + "uses_late_zs_test": false, + "uses_late_zs_update": false, + "variants": { + "Main": { + "fp16_arithmetic": 85, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "arith_total", + "arith_sfu" + ], + "longest_path_cycles": [ + 0.5, + 0.109375, + 0.125, + 0.5, + 0.0, + 0.25, + 0.0 + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "varying", + "texture" + ], + "shortest_path_bound_pipelines": [ + "arith_total", + "arith_sfu" + ], + "shortest_path_cycles": [ + 0.5, + 0.109375, + 0.125, + 0.5, + 0.0, + 0.25, + 0.0 + ], + "total_bound_pipelines": [ + "arith_total", + "arith_sfu" + ], + "total_cycles": [ + 0.5, + 0.109375, + 0.125, + 0.5, + 0.0, + 0.25, + 0.0 + ] + }, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 10, + "work_registers_used": 11 + } + } + } + }, + "flutter/impeller/entity/gradient.vert.vkspv": { + "Mali-G78": { + "core": "Mali-G78", + "filename": "flutter/impeller/entity/gradient.vert.vkspv", + "has_uniform_computation": true, + "type": "Vertex", + "variants": { + "Position": { + "fp16_arithmetic": 0, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "load_store" + ], + "longest_path_cycles": [ + 0.125, + 0.125, + 0.0, + 0.0, + 2.0, + 0.0 + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "texture" + ], + "shortest_path_bound_pipelines": [ + "load_store" + ], + "shortest_path_cycles": [ + 0.125, + 0.125, + 0.0, + 0.0, + 2.0, + 0.0 + ], + "total_bound_pipelines": [ + "load_store" + ], + "total_cycles": [ + 0.125, + 0.125, + 0.0, + 0.0, + 2.0, + 0.0 + ] + }, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 28, + "work_registers_used": 32 + }, + "Varying": { + "fp16_arithmetic": null, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "load_store" + ], + "longest_path_cycles": [ + 0.0, + 0.0, + 0.0, + 0.0, + 3.0, + 0.0 + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "texture" + ], + "shortest_path_bound_pipelines": [ + "load_store" + ], + "shortest_path_cycles": [ + 0.0, + 0.0, + 0.0, + 0.0, + 3.0, + 0.0 + ], + "total_bound_pipelines": [ + "load_store" + ], + "total_cycles": [ + 0.0, + 0.0, + 0.0, + 0.0, + 3.0, + 0.0 + ] + }, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 20, + "work_registers_used": 9 + } + } + } + }, "flutter/impeller/entity/gradient_fill.vert.vkspv": { "Mali-G78": { "core": "Mali-G78", From 9b35a37b314972e79ef6c6355558b3c0a806bda8 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Sun, 2 Jun 2024 16:49:06 -0700 Subject: [PATCH 04/13] ++ --- ci/licenses_golden/licenses_flutter | 4 ++++ .../backend/metal/pipeline_library_mtl.mm | 15 ++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 9883325e84309..52547c76de109 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -42528,6 +42528,8 @@ ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag + ../../../flu ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_ssbo_fill.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/gradient.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/gradient.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/gradient_fill.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_fill.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_ssbo_fill.frag + ../../../flutter/LICENSE @@ -45391,6 +45393,8 @@ FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill.frag FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_ssbo_fill.frag +FILE: ../../../flutter/impeller/entity/shaders/gradients/gradient.frag +FILE: ../../../flutter/impeller/entity/shaders/gradients/gradient.vert FILE: ../../../flutter/impeller/entity/shaders/gradients/gradient_fill.vert FILE: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_fill.frag FILE: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_ssbo_fill.frag diff --git a/impeller/renderer/backend/metal/pipeline_library_mtl.mm b/impeller/renderer/backend/metal/pipeline_library_mtl.mm index 059862cbdc926..b0b6406b6b0d9 100644 --- a/impeller/renderer/backend/metal/pipeline_library_mtl.mm +++ b/impeller/renderer/backend/metal/pipeline_library_mtl.mm @@ -67,11 +67,16 @@ static void GetMTLRenderPipelineDescriptor(const PipelineDescriptor& desc, FML_CHECK(!created_specialized_function); created_specialized_function = true; ShaderFunctionMTL::Cast(*entry.second) - .GetMTLFunctionSpecialized( - constants, [callback, descriptor](id function) { - descriptor.fragmentFunction = function; - callback(descriptor); - }); + .GetMTLFunctionSpecialized(constants, [callback, + &descriptor](id + function) { + descriptor.fragmentFunction = function; + if (!descriptor.vertexFunction) { + FML_LOG(ERROR) + << "Warning: Creating Descriptor with missing Vertex Main"; + } + callback(descriptor); + }); } } } From 765e00ff72c4c49186b33b374b1f568f522e2e56 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Sun, 2 Jun 2024 17:10:42 -0700 Subject: [PATCH 05/13] test deleting --- impeller/aiks/aiks_gradient_unittests.cc | 48 ------------------- .../backend/metal/pipeline_library_mtl.mm | 15 ++---- 2 files changed, 5 insertions(+), 58 deletions(-) diff --git a/impeller/aiks/aiks_gradient_unittests.cc b/impeller/aiks/aiks_gradient_unittests.cc index 268de96011e50..7938fb60f9f3c 100644 --- a/impeller/aiks/aiks_gradient_unittests.cc +++ b/impeller/aiks/aiks_gradient_unittests.cc @@ -734,53 +734,5 @@ TEST_P(AiksTest, GradientStrokesRenderCorrectly) { ASSERT_TRUE(OpenPlaygroundHere(callback)); } -// Draws two gradients that should look identical (except that one is an RRECT). -TEST_P(AiksTest, FastGradientTestHorizontal) { - Canvas canvas; - Paint paint; - canvas.Translate({100.0f, 0, 0}); - - std::vector colors = {Color::Red(), Color::Blue(), Color::Green()}; - std::vector stops = {0.0, 0.1, 1.0}; - - paint.color_source = ColorSource::MakeLinearGradient( - {0, 0}, {600, 0}, std::move(colors), std::move(stops), - Entity::TileMode::kClamp, {}); - - paint.color = Color(1.0, 1.0, 1.0, 1.0); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint); - - { - canvas.Translate({800, 0, 0}); - canvas.DrawRRect(Rect::MakeXYWH(0, 0, 600, 600), Size(4, 4), paint); - } - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -// Draws two gradients that should look identical (except that one is an RRECT). -TEST_P(AiksTest, FastGradientTestVertical) { - Canvas canvas; - Paint paint; - canvas.Translate({100.0f, 0, 0}); - - std::vector colors = {Color::Red(), Color::Blue(), Color::Green()}; - std::vector stops = {0.0, 0.1, 1.0}; - - paint.color_source = ColorSource::MakeLinearGradient( - {0, 0}, {0, 600}, std::move(colors), std::move(stops), - Entity::TileMode::kClamp, {}); - - paint.color = Color(1.0, 1.0, 1.0, 1.0); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint); - - { - canvas.Translate({800, 0, 0}); - canvas.DrawRRect(Rect::MakeXYWH(0, 0, 600, 600), Size(4, 4), paint); - } - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - } // namespace testing } // namespace impeller diff --git a/impeller/renderer/backend/metal/pipeline_library_mtl.mm b/impeller/renderer/backend/metal/pipeline_library_mtl.mm index b0b6406b6b0d9..059862cbdc926 100644 --- a/impeller/renderer/backend/metal/pipeline_library_mtl.mm +++ b/impeller/renderer/backend/metal/pipeline_library_mtl.mm @@ -67,16 +67,11 @@ static void GetMTLRenderPipelineDescriptor(const PipelineDescriptor& desc, FML_CHECK(!created_specialized_function); created_specialized_function = true; ShaderFunctionMTL::Cast(*entry.second) - .GetMTLFunctionSpecialized(constants, [callback, - &descriptor](id - function) { - descriptor.fragmentFunction = function; - if (!descriptor.vertexFunction) { - FML_LOG(ERROR) - << "Warning: Creating Descriptor with missing Vertex Main"; - } - callback(descriptor); - }); + .GetMTLFunctionSpecialized( + constants, [callback, descriptor](id function) { + descriptor.fragmentFunction = function; + callback(descriptor); + }); } } } From 1aed825cf0c242525005c398a0988a35a33c903d Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Sun, 2 Jun 2024 20:59:17 -0700 Subject: [PATCH 06/13] lets try spinning thats a neat trick. --- impeller/entity/BUILD.gn | 4 ++-- impeller/entity/contents/content_context.h | 6 +++--- .../shaders/gradients/{gradient.frag => fast_gradient.frag} | 0 .../shaders/gradients/{gradient.vert => fast_gradient.vert} | 0 4 files changed, 5 insertions(+), 5 deletions(-) rename impeller/entity/shaders/gradients/{gradient.frag => fast_gradient.frag} (100%) rename impeller/entity/shaders/gradients/{gradient.vert => fast_gradient.vert} (100%) diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index c19cf125400e4..d4363be8d7804 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -48,8 +48,8 @@ impeller_shaders("entity_shaders") { "shaders/filters/linear_to_srgb_filter.frag", "shaders/filters/morphology_filter.frag", "shaders/blending/vertices_uber.frag", - "shaders/gradients/gradient.vert", - "shaders/gradients/gradient.frag", + "shaders/gradients/fast_gradient.vert", + "shaders/gradients/fast_gradient.frag", ] } diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 15d5c25898c23..7486b1575f41d 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -28,13 +28,13 @@ #include "impeller/entity/clip.vert.h" #include "impeller/entity/color_matrix_color_filter.frag.h" #include "impeller/entity/conical_gradient_fill.frag.h" +#include "impeller/entity/fast_gradient.frag.h" +#include "impeller/entity/fast_gradient.vert.h" #include "impeller/entity/filter_position.vert.h" #include "impeller/entity/filter_position_uv.vert.h" #include "impeller/entity/gaussian.frag.h" #include "impeller/entity/glyph_atlas.frag.h" #include "impeller/entity/glyph_atlas.vert.h" -#include "impeller/entity/gradient.frag.h" -#include "impeller/entity/gradient.vert.h" #include "impeller/entity/gradient_fill.vert.h" #include "impeller/entity/linear_gradient_fill.frag.h" #include "impeller/entity/linear_to_srgb_filter.frag.h" @@ -79,7 +79,7 @@ namespace impeller { using GradientPipeline = - RenderPipelineHandle; + RenderPipelineHandle; using LinearGradientFillPipeline = RenderPipelineHandle; diff --git a/impeller/entity/shaders/gradients/gradient.frag b/impeller/entity/shaders/gradients/fast_gradient.frag similarity index 100% rename from impeller/entity/shaders/gradients/gradient.frag rename to impeller/entity/shaders/gradients/fast_gradient.frag diff --git a/impeller/entity/shaders/gradients/gradient.vert b/impeller/entity/shaders/gradients/fast_gradient.vert similarity index 100% rename from impeller/entity/shaders/gradients/gradient.vert rename to impeller/entity/shaders/gradients/fast_gradient.vert From 76239198d2166df8e508c878b95f8b299649bd97 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 3 Jun 2024 09:53:48 -0700 Subject: [PATCH 07/13] adjust goldens. --- ci/licenses_golden/licenses_flutter | 8 +-- impeller/aiks/aiks_gradient_unittests.cc | 84 ++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 52547c76de109..4756dee1734ca 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -42526,10 +42526,10 @@ ORIGIN: ../../../flutter/impeller/entity/shaders/filters/srgb_to_linear_filter.f ORIGIN: ../../../flutter/impeller/entity/shaders/filters/yuv_to_rgb_filter.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_ssbo_fill.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/gradient.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/gradient.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/gradient_fill.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_fill.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_ssbo_fill.frag + ../../../flutter/LICENSE @@ -45391,10 +45391,10 @@ FILE: ../../../flutter/impeller/entity/shaders/filters/srgb_to_linear_filter.fra FILE: ../../../flutter/impeller/entity/shaders/filters/yuv_to_rgb_filter.frag FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert +FILE: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.frag +FILE: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.vert FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill.frag FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_ssbo_fill.frag -FILE: ../../../flutter/impeller/entity/shaders/gradients/gradient.frag -FILE: ../../../flutter/impeller/entity/shaders/gradients/gradient.vert FILE: ../../../flutter/impeller/entity/shaders/gradients/gradient_fill.vert FILE: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_fill.frag FILE: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_ssbo_fill.frag diff --git a/impeller/aiks/aiks_gradient_unittests.cc b/impeller/aiks/aiks_gradient_unittests.cc index 7938fb60f9f3c..96779c08c1850 100644 --- a/impeller/aiks/aiks_gradient_unittests.cc +++ b/impeller/aiks/aiks_gradient_unittests.cc @@ -734,5 +734,89 @@ TEST_P(AiksTest, GradientStrokesRenderCorrectly) { ASSERT_TRUE(OpenPlaygroundHere(callback)); } +// Draws two gradients that should look identical (except that one is an RRECT). +TEST_P(AiksTest, FastGradientTestHorizontal) { + Canvas canvas; + Paint paint; + canvas.Translate({100.0f, 0, 0}); + + std::vector colors = {Color::Red(), Color::Blue(), Color::Green()}; + std::vector stops = {0.0, 0.1, 1.0}; + + paint.color_source = ColorSource::MakeLinearGradient( + {0, 0}, {600, 0}, std::move(colors), std::move(stops), + Entity::TileMode::kClamp, {}); + + paint.color = Color(1.0, 1.0, 1.0, 1.0); + canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint); + canvas.Translate({800, 0, 0}); + canvas.DrawRRect(Rect::MakeXYWH(0, 0, 600, 600), Size(4, 4), paint); + + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + +// Draws two gradients that should look identical (except that one is an RRECT). +TEST_P(AiksTest, FastGradientTestVertical) { + Canvas canvas; + Paint paint; + canvas.Translate({100.0f, 0, 0}); + + std::vector colors = {Color::Red(), Color::Blue(), Color::Green()}; + std::vector stops = {0.0, 0.1, 1.0}; + + paint.color_source = ColorSource::MakeLinearGradient( + {0, 0}, {0, 600}, std::move(colors), std::move(stops), + Entity::TileMode::kClamp, {}); + + paint.color = Color(1.0, 1.0, 1.0, 1.0); + canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint); + canvas.Translate({800, 0, 0}); + canvas.DrawRRect(Rect::MakeXYWH(0, 0, 600, 600), Size(4, 4), paint); + + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + +// Draws two gradients that should look identical (except that one is an RRECT). +TEST_P(AiksTest, FastGradientTestHorizontalReversed) { + Canvas canvas; + Paint paint; + canvas.Translate({100.0f, 0, 0}); + + std::vector colors = {Color::Red(), Color::Blue(), Color::Green()}; + std::vector stops = {0.0, 0.1, 1.0}; + + paint.color_source = ColorSource::MakeLinearGradient( + {600, 0}, {0, 0}, std::move(colors), std::move(stops), + Entity::TileMode::kClamp, {}); + + paint.color = Color(1.0, 1.0, 1.0, 1.0); + canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint); + canvas.Translate({800, 0, 0}); + canvas.DrawRRect(Rect::MakeXYWH(0, 0, 600, 600), Size(4, 4), paint); + + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + +// Draws two gradients that should look identical (except that one is an RRECT). +TEST_P(AiksTest, FastGradientTestVerticalReversed) { + Canvas canvas; + Paint paint; + canvas.Translate({100.0f, 0, 0}); + + std::vector colors = {Color::Red(), Color::Blue(), Color::Green()}; + std::vector stops = {0.0, 0.1, 1.0}; + + paint.color_source = ColorSource::MakeLinearGradient( + {0, 600}, {0, 0}, std::move(colors), std::move(stops), + Entity::TileMode::kClamp, {}); + + paint.color = Color(1.0, 1.0, 1.0, 1.0); + canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint); + canvas.Translate({800, 0, 0}); + canvas.DrawRRect(Rect::MakeXYWH(0, 0, 600, 600), Size(4, 4), paint); + + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + } // namespace testing } // namespace impeller From 61ed98a7b44b838af7a15729f6bfbc922edc8edf Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 3 Jun 2024 10:00:21 -0700 Subject: [PATCH 08/13] simplify. --- .../contents/linear_gradient_contents.cc | 73 +++++++------------ 1 file changed, 28 insertions(+), 45 deletions(-) diff --git a/impeller/entity/contents/linear_gradient_contents.cc b/impeller/entity/contents/linear_gradient_contents.cc index da8a565c5261d..8773815bc228b 100644 --- a/impeller/entity/contents/linear_gradient_contents.cc +++ b/impeller/entity/contents/linear_gradient_contents.cc @@ -84,52 +84,35 @@ bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, bool horizontal_axis = start_point_.y == end_point_.y; // Step 1. Compute the locations of each breakpoint along the primary axis. - if (stops_.size() == 2) { - // If there are exactly two stops then we have a nearly trivial gradient. - // Augment each vertex and submit. This is wrong if the gradient goes end -> - // start, we could fix that via some normalization. - vtx_builder.AddVertices( - {{rect.GetLeftTop(), colors_[0]}, - {rect.GetRightTop(), horizontal_axis ? colors_[1] : colors_[0]}, - {rect.GetLeftBottom(), horizontal_axis ? colors_[0] : colors_[1]}, - {rect.GetRightTop(), horizontal_axis ? colors_[1] : colors_[0]}, - {rect.GetLeftBottom(), horizontal_axis ? colors_[0] : colors_[1]}, - {rect.GetRightBottom(), colors_[1]}}); - } else { - // Otherwise, we need to compute a point along the primary axis. - std::vector points(stops_.size()); - for (auto i = 0u; i < stops_.size(); i++) { - Scalar t = stops_[i]; - points[i] = (1.0 - t) * start_point_ + t * end_point_; - } - // Now create a rectangle that joins each segment. That will be two - // triangles between each pair of points. - vtx_builder.Reserve(6 * (stops_.size() - 1)); - for (auto i = 1u; i < points.size(); i++) { - Rect section = - horizontal_axis - ? Rect::MakeXYWH(points[i - 1].x, rect.GetY(), - abs(points[i].x - points[i - 1].x), - rect.GetHeight()) - - : Rect::MakeXYWH(rect.GetX(), points[i - 1].y, rect.GetWidth(), - abs(points[i].y - points[i - 1].y)); - vtx_builder.AddVertices({ - {section.GetLeftTop(), colors_[i - 1]}, - {section.GetRightTop(), - horizontal_axis ? colors_[i] : colors_[i - 1]}, - {section.GetLeftBottom(), - horizontal_axis ? colors_[i - 1] : colors_[i]}, - {section.GetRightTop(), - horizontal_axis ? colors_[i] : colors_[i - 1]}, - {section.GetLeftBottom(), - horizontal_axis ? colors_[i - 1] : colors_[i]}, - {section.GetRightBottom(), - horizontal_axis ? colors_[i] : colors_[i - 1]}, - }); - } + std::vector points(stops_.size()); + for (auto i = 0u; i < stops_.size(); i++) { + Scalar t = stops_[i]; + points[i] = (1.0 - t) * start_point_ + t * end_point_; + } + // Now create a rectangle that joins each segment. That will be two + // triangles between each pair of points. + vtx_builder.Reserve(6 * (stops_.size() - 1)); + for (auto i = 1u; i < points.size(); i++) { + Rect section = + horizontal_axis + ? Rect::MakeXYWH(points[i - 1].x, rect.GetY(), + abs(points[i].x - points[i - 1].x), + rect.GetHeight()) + + : Rect::MakeXYWH(rect.GetX(), points[i - 1].y, rect.GetWidth(), + abs(points[i].y - points[i - 1].y)); + vtx_builder.AddVertices({ + {section.GetLeftTop(), colors_[i - 1]}, + {section.GetRightTop(), horizontal_axis ? colors_[i] : colors_[i - 1]}, + {section.GetLeftBottom(), + horizontal_axis ? colors_[i - 1] : colors_[i]}, + {section.GetRightTop(), horizontal_axis ? colors_[i] : colors_[i - 1]}, + {section.GetLeftBottom(), + horizontal_axis ? colors_[i - 1] : colors_[i]}, + {section.GetRightBottom(), + horizontal_axis ? colors_[i] : colors_[i - 1]}, + }); } - auto& host_buffer = renderer.GetTransientsBuffer(); pass.SetLabel("LinearGradient"); From a14f6664cc65b35c046aef1f88f50c4b32d377b0 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 3 Jun 2024 11:35:48 -0700 Subject: [PATCH 09/13] ++ --- ci/licenses_golden/licenses_flutter | 8 +- impeller/tools/malioc.json | 976 +++++++++++------------ testing/impeller_golden_tests_output.txt | 12 + 3 files changed, 504 insertions(+), 492 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 4756dee1734ca..9adebc0edfd92 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -42526,10 +42526,10 @@ ORIGIN: ../../../flutter/impeller/entity/shaders/filters/srgb_to_linear_filter.f ORIGIN: ../../../flutter/impeller/entity/shaders/filters/yuv_to_rgb_filter.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_ssbo_fill.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/gradient_fill.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_fill.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_ssbo_fill.frag + ../../../flutter/LICENSE @@ -45391,10 +45391,10 @@ FILE: ../../../flutter/impeller/entity/shaders/filters/srgb_to_linear_filter.fra FILE: ../../../flutter/impeller/entity/shaders/filters/yuv_to_rgb_filter.frag FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert -FILE: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.frag -FILE: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.vert FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill.frag FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_ssbo_fill.frag +FILE: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.frag +FILE: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.vert FILE: ../../../flutter/impeller/entity/shaders/gradients/gradient_fill.vert FILE: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_fill.frag FILE: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_ssbo_fill.frag diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index 54376a1f40167..7d0be585bf7b4 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -613,6 +613,191 @@ } } }, + "flutter/impeller/entity/fast_gradient.frag.vkspv": { + "Mali-G78": { + "core": "Mali-G78", + "filename": "flutter/impeller/entity/fast_gradient.frag.vkspv", + "has_side_effects": false, + "has_uniform_computation": true, + "modifies_coverage": false, + "reads_color_buffer": false, + "type": "Fragment", + "uses_late_zs_test": false, + "uses_late_zs_update": false, + "variants": { + "Main": { + "fp16_arithmetic": 85, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "arith_total", + "arith_sfu" + ], + "longest_path_cycles": [ + 0.5, + 0.109375, + 0.125, + 0.5, + 0.0, + 0.25, + 0.0 + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "varying", + "texture" + ], + "shortest_path_bound_pipelines": [ + "arith_total", + "arith_sfu" + ], + "shortest_path_cycles": [ + 0.5, + 0.109375, + 0.125, + 0.5, + 0.0, + 0.25, + 0.0 + ], + "total_bound_pipelines": [ + "arith_total", + "arith_sfu" + ], + "total_cycles": [ + 0.5, + 0.109375, + 0.125, + 0.5, + 0.0, + 0.25, + 0.0 + ] + }, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 10, + "work_registers_used": 11 + } + } + } + }, + "flutter/impeller/entity/fast_gradient.vert.vkspv": { + "Mali-G78": { + "core": "Mali-G78", + "filename": "flutter/impeller/entity/fast_gradient.vert.vkspv", + "has_uniform_computation": true, + "type": "Vertex", + "variants": { + "Position": { + "fp16_arithmetic": 0, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "load_store" + ], + "longest_path_cycles": [ + 0.125, + 0.125, + 0.0, + 0.0, + 2.0, + 0.0 + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "texture" + ], + "shortest_path_bound_pipelines": [ + "load_store" + ], + "shortest_path_cycles": [ + 0.125, + 0.125, + 0.0, + 0.0, + 2.0, + 0.0 + ], + "total_bound_pipelines": [ + "load_store" + ], + "total_cycles": [ + 0.125, + 0.125, + 0.0, + 0.0, + 2.0, + 0.0 + ] + }, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 28, + "work_registers_used": 32 + }, + "Varying": { + "fp16_arithmetic": null, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + "load_store" + ], + "longest_path_cycles": [ + 0.0, + 0.0, + 0.0, + 0.0, + 3.0, + 0.0 + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "texture" + ], + "shortest_path_bound_pipelines": [ + "load_store" + ], + "shortest_path_cycles": [ + 0.0, + 0.0, + 0.0, + 0.0, + 3.0, + 0.0 + ], + "total_bound_pipelines": [ + "load_store" + ], + "total_cycles": [ + 0.0, + 0.0, + 0.0, + 0.0, + 3.0, + 0.0 + ] + }, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 20, + "work_registers_used": 9 + } + } + } + }, "flutter/impeller/entity/filter_position.vert.vkspv": { "Mali-G78": { "core": "Mali-G78", @@ -1766,26 +1951,32 @@ } } }, - "flutter/impeller/entity/gles/filter_position.vert.gles": { + "flutter/impeller/entity/gles/fast_gradient.frag.gles": { "Mali-G78": { "core": "Mali-G78", - "filename": "flutter/impeller/entity/gles/filter_position.vert.gles", - "has_uniform_computation": true, - "type": "Vertex", + "filename": "flutter/impeller/entity/gles/fast_gradient.frag.gles", + "has_side_effects": false, + "has_uniform_computation": false, + "modifies_coverage": false, + "reads_color_buffer": false, + "type": "Fragment", + "uses_late_zs_test": false, + "uses_late_zs_update": false, "variants": { - "Position": { - "fp16_arithmetic": 0, + "Main": { + "fp16_arithmetic": 100, "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - "load_store" + "varying" ], "longest_path_cycles": [ - 0.140625, - 0.140625, + 0.0625, + 0.0625, + 0.046875, 0.0, 0.0, - 2.0, + 0.25, 0.0 ], "pipelines": [ @@ -1794,140 +1985,94 @@ "arith_cvt", "arith_sfu", "load_store", + "varying", "texture" ], "shortest_path_bound_pipelines": [ - "load_store" + "varying" ], "shortest_path_cycles": [ - 0.140625, - 0.140625, + 0.0625, + 0.0625, + 0.015625, 0.0, 0.0, - 2.0, + 0.25, 0.0 ], "total_bound_pipelines": [ - "load_store" + "varying" ], "total_cycles": [ - 0.140625, - 0.140625, + 0.0625, + 0.0625, + 0.046875, 0.0, 0.0, - 2.0, + 0.25, 0.0 ] }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 22, - "work_registers_used": 32 - }, - "Varying": { - "fp16_arithmetic": 0, + "uniform_registers_used": 2, + "work_registers_used": 19 + } + } + }, + "Mali-T880": { + "core": "Mali-T880", + "filename": "flutter/impeller/entity/gles/fast_gradient.frag.gles", + "has_uniform_computation": false, + "type": "Fragment", + "variants": { + "Main": { "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ + "arithmetic", "load_store" ], "longest_path_cycles": [ - 0.015625, - 0.015625, - 0.015625, - 0.0, - 3.0, + 1.0, + 1.0, 0.0 ], "pipelines": [ - "arith_total", - "arith_fma", - "arith_cvt", - "arith_sfu", + "arithmetic", "load_store", "texture" ], "shortest_path_bound_pipelines": [ + "arithmetic", "load_store" ], "shortest_path_cycles": [ - 0.015625, - 0.015625, - 0.015625, - 0.0, - 3.0, - 0.0 - ], - "total_bound_pipelines": [ - "load_store" - ], - "total_cycles": [ - 0.015625, - 0.015625, - 0.015625, - 0.0, - 3.0, - 0.0 - ] - }, - "stack_spill_bytes": 0, - "thread_occupancy": 100, - "uniform_registers_used": 10, - "work_registers_used": 8 - } - } - }, - "Mali-T880": { - "core": "Mali-T880", - "filename": "flutter/impeller/entity/gles/filter_position.vert.gles", - "has_uniform_computation": false, - "type": "Vertex", - "variants": { - "Main": { - "has_stack_spilling": false, - "performance": { - "longest_path_bound_pipelines": [ - "load_store" - ], - "longest_path_cycles": [ - 2.9700000286102295, - 4.0, - 0.0 - ], - "pipelines": [ - "arithmetic", - "load_store", - "texture" - ], - "shortest_path_bound_pipelines": [ - "load_store" - ], - "shortest_path_cycles": [ - 2.9700000286102295, - 4.0, + 1.0, + 1.0, 0.0 ], "total_bound_pipelines": [ "load_store" ], "total_cycles": [ - 3.0, - 4.0, + 0.6666666865348816, + 1.0, 0.0 ] }, "thread_occupancy": 100, - "uniform_registers_used": 6, + "uniform_registers_used": 1, "work_registers_used": 2 } } } }, - "flutter/impeller/entity/gles/filter_position_uv.vert.gles": { + "flutter/impeller/entity/gles/fast_gradient.vert.gles": { "Mali-G78": { "core": "Mali-G78", - "filename": "flutter/impeller/entity/gles/filter_position_uv.vert.gles", - "has_uniform_computation": true, + "filename": "flutter/impeller/entity/gles/fast_gradient.vert.gles", + "has_uniform_computation": false, "type": "Vertex", "variants": { "Position": { @@ -1978,20 +2123,20 @@ }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 22, + "uniform_registers_used": 20, "work_registers_used": 32 }, "Varying": { - "fp16_arithmetic": 0, + "fp16_arithmetic": null, "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ "load_store" ], "longest_path_cycles": [ - 0.015625, - 0.015625, - 0.015625, + 0.0, + 0.0, + 0.0, 0.0, 3.0, 0.0 @@ -2008,9 +2153,9 @@ "load_store" ], "shortest_path_cycles": [ - 0.015625, - 0.015625, - 0.015625, + 0.0, + 0.0, + 0.0, 0.0, 3.0, 0.0 @@ -2019,9 +2164,9 @@ "load_store" ], "total_cycles": [ - 0.015625, - 0.015625, - 0.015625, + 0.0, + 0.0, + 0.0, 0.0, 3.0, 0.0 @@ -2029,14 +2174,14 @@ }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 10, - "work_registers_used": 8 + "uniform_registers_used": 8, + "work_registers_used": 9 } } }, "Mali-T880": { "core": "Mali-T880", - "filename": "flutter/impeller/entity/gles/filter_position_uv.vert.gles", + "filename": "flutter/impeller/entity/gles/fast_gradient.vert.gles", "has_uniform_computation": false, "type": "Vertex", "variants": { @@ -2047,7 +2192,7 @@ "load_store" ], "longest_path_cycles": [ - 2.9700000286102295, + 2.640000104904175, 5.0, 0.0 ], @@ -2060,7 +2205,7 @@ "load_store" ], "shortest_path_cycles": [ - 2.9700000286102295, + 2.640000104904175, 5.0, 0.0 ], @@ -2068,45 +2213,39 @@ "load_store" ], "total_cycles": [ - 3.0, + 2.6666667461395264, 5.0, 0.0 ] }, "thread_occupancy": 100, - "uniform_registers_used": 6, + "uniform_registers_used": 5, "work_registers_used": 2 } } } }, - "flutter/impeller/entity/gles/gaussian.frag.gles": { + "flutter/impeller/entity/gles/filter_position.vert.gles": { "Mali-G78": { "core": "Mali-G78", - "filename": "flutter/impeller/entity/gles/gaussian.frag.gles", - "has_side_effects": false, + "filename": "flutter/impeller/entity/gles/filter_position.vert.gles", "has_uniform_computation": true, - "modifies_coverage": false, - "reads_color_buffer": false, - "type": "Fragment", - "uses_late_zs_test": false, - "uses_late_zs_update": false, + "type": "Vertex", "variants": { - "Main": { + "Position": { "fp16_arithmetic": 0, "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - null + "load_store" ], "longest_path_cycles": [ - null, - null, - null, - null, - null, - null, - null + 0.140625, + 0.140625, + 0.0, + 0.0, + 2.0, + 0.0 ], "pipelines": [ "arith_total", @@ -2114,117 +2253,50 @@ "arith_cvt", "arith_sfu", "load_store", - "varying", "texture" ], "shortest_path_bound_pipelines": [ - "arith_total", - "arith_cvt" + "load_store" ], "shortest_path_cycles": [ - 0.109375, - 0.0, - 0.109375, - 0.0, + 0.140625, + 0.140625, 0.0, 0.0, + 2.0, 0.0 ], "total_bound_pipelines": [ "load_store" ], "total_cycles": [ - 0.3125, - 0.09375, - 0.3125, + 0.140625, + 0.140625, + 0.0, 0.0, 2.0, - 0.25, - 0.25 + 0.0 ] }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 4, - "work_registers_used": 19 - } - } - }, - "Mali-T880": { - "core": "Mali-T880", - "filename": "flutter/impeller/entity/gles/gaussian.frag.gles", - "has_uniform_computation": false, - "type": "Fragment", - "variants": { - "Main": { + "uniform_registers_used": 22, + "work_registers_used": 32 + }, + "Varying": { + "fp16_arithmetic": 0, "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - null - ], - "longest_path_cycles": [ - null, - null, - null - ], - "pipelines": [ - "arithmetic", - "load_store", - "texture" - ], - "shortest_path_bound_pipelines": [ - "arithmetic", - "load_store" - ], - "shortest_path_cycles": [ - 1.0, - 1.0, - 0.0 - ], - "total_bound_pipelines": [ "load_store" ], - "total_cycles": [ - 1.6666666269302368, - 2.0, - 1.0 - ] - }, - "thread_occupancy": 100, - "uniform_registers_used": 1, - "work_registers_used": 3 - } - } - } - }, - "flutter/impeller/entity/gles/glyph_atlas.frag.gles": { - "Mali-G78": { - "core": "Mali-G78", - "filename": "flutter/impeller/entity/gles/glyph_atlas.frag.gles", - "has_side_effects": false, - "has_uniform_computation": true, - "modifies_coverage": false, - "reads_color_buffer": false, - "type": "Fragment", - "uses_late_zs_test": false, - "uses_late_zs_update": false, - "variants": { - "Main": { - "fp16_arithmetic": 100, - "has_stack_spilling": false, - "performance": { - "longest_path_bound_pipelines": [ - "varying", - "texture" - ], "longest_path_cycles": [ - 0.109375, - 0.03125, - 0.109375, - 0.0, + 0.015625, + 0.015625, + 0.015625, 0.0, - 0.25, - 0.25 + 3.0, + 0.0 ], "pipelines": [ "arith_total", @@ -2232,61 +2304,54 @@ "arith_cvt", "arith_sfu", "load_store", - "varying", "texture" ], "shortest_path_bound_pipelines": [ - "varying", - "texture" + "load_store" ], "shortest_path_cycles": [ - 0.0625, - 0.03125, - 0.0625, - 0.0, + 0.015625, + 0.015625, + 0.015625, 0.0, - 0.25, - 0.25 + 3.0, + 0.0 ], "total_bound_pipelines": [ - "varying", - "texture" + "load_store" ], "total_cycles": [ - 0.125, - 0.0625, - 0.125, - 0.0, + 0.015625, + 0.015625, + 0.015625, 0.0, - 0.25, - 0.25 + 3.0, + 0.0 ] }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 6, - "work_registers_used": 19 + "uniform_registers_used": 10, + "work_registers_used": 8 } } }, "Mali-T880": { "core": "Mali-T880", - "filename": "flutter/impeller/entity/gles/glyph_atlas.frag.gles", + "filename": "flutter/impeller/entity/gles/filter_position.vert.gles", "has_uniform_computation": false, - "type": "Fragment", + "type": "Vertex", "variants": { "Main": { "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - "arithmetic", - "load_store", - "texture" + "load_store" ], "longest_path_cycles": [ - 1.0, - 1.0, - 1.0 + 2.9700000286102295, + 4.0, + 0.0 ], "pipelines": [ "arithmetic", @@ -2294,36 +2359,34 @@ "texture" ], "shortest_path_bound_pipelines": [ - "arithmetic", - "load_store", - "texture" + "load_store" ], "shortest_path_cycles": [ - 1.0, - 1.0, - 1.0 + 2.9700000286102295, + 4.0, + 0.0 ], "total_bound_pipelines": [ - "arithmetic" + "load_store" ], "total_cycles": [ - 2.6666667461395264, - 1.0, - 1.0 + 3.0, + 4.0, + 0.0 ] }, "thread_occupancy": 100, - "uniform_registers_used": 1, + "uniform_registers_used": 6, "work_registers_used": 2 } } } }, - "flutter/impeller/entity/gles/glyph_atlas.vert.gles": { + "flutter/impeller/entity/gles/filter_position_uv.vert.gles": { "Mali-G78": { "core": "Mali-G78", - "filename": "flutter/impeller/entity/gles/glyph_atlas.vert.gles", - "has_uniform_computation": false, + "filename": "flutter/impeller/entity/gles/filter_position_uv.vert.gles", + "has_uniform_computation": true, "type": "Vertex", "variants": { "Position": { @@ -2374,20 +2437,20 @@ }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 20, + "uniform_registers_used": 22, "work_registers_used": 32 }, "Varying": { - "fp16_arithmetic": null, + "fp16_arithmetic": 0, "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ "load_store" ], "longest_path_cycles": [ - 0.0, - 0.0, - 0.0, + 0.015625, + 0.015625, + 0.015625, 0.0, 3.0, 0.0 @@ -2404,9 +2467,9 @@ "load_store" ], "shortest_path_cycles": [ - 0.0, - 0.0, - 0.0, + 0.015625, + 0.015625, + 0.015625, 0.0, 3.0, 0.0 @@ -2415,9 +2478,9 @@ "load_store" ], "total_cycles": [ - 0.0, - 0.0, - 0.0, + 0.015625, + 0.015625, + 0.015625, 0.0, 3.0, 0.0 @@ -2425,14 +2488,14 @@ }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 8, - "work_registers_used": 7 + "uniform_registers_used": 10, + "work_registers_used": 8 } } }, "Mali-T880": { "core": "Mali-T880", - "filename": "flutter/impeller/entity/gles/glyph_atlas.vert.gles", + "filename": "flutter/impeller/entity/gles/filter_position_uv.vert.gles", "has_uniform_computation": false, "type": "Vertex", "variants": { @@ -2443,7 +2506,7 @@ "load_store" ], "longest_path_cycles": [ - 2.640000104904175, + 2.9700000286102295, 5.0, 0.0 ], @@ -2456,32 +2519,149 @@ "load_store" ], "shortest_path_cycles": [ - 2.640000104904175, - 5.0, + 2.9700000286102295, + 5.0, + 0.0 + ], + "total_bound_pipelines": [ + "load_store" + ], + "total_cycles": [ + 3.0, + 5.0, + 0.0 + ] + }, + "thread_occupancy": 100, + "uniform_registers_used": 6, + "work_registers_used": 2 + } + } + } + }, + "flutter/impeller/entity/gles/gaussian.frag.gles": { + "Mali-G78": { + "core": "Mali-G78", + "filename": "flutter/impeller/entity/gles/gaussian.frag.gles", + "has_side_effects": false, + "has_uniform_computation": true, + "modifies_coverage": false, + "reads_color_buffer": false, + "type": "Fragment", + "uses_late_zs_test": false, + "uses_late_zs_update": false, + "variants": { + "Main": { + "fp16_arithmetic": 0, + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + null + ], + "longest_path_cycles": [ + null, + null, + null, + null, + null, + null, + null + ], + "pipelines": [ + "arith_total", + "arith_fma", + "arith_cvt", + "arith_sfu", + "load_store", + "varying", + "texture" + ], + "shortest_path_bound_pipelines": [ + "arith_total", + "arith_cvt" + ], + "shortest_path_cycles": [ + 0.109375, + 0.0, + 0.109375, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "total_bound_pipelines": [ + "load_store" + ], + "total_cycles": [ + 0.3125, + 0.09375, + 0.3125, + 0.0, + 2.0, + 0.25, + 0.25 + ] + }, + "stack_spill_bytes": 0, + "thread_occupancy": 100, + "uniform_registers_used": 4, + "work_registers_used": 19 + } + } + }, + "Mali-T880": { + "core": "Mali-T880", + "filename": "flutter/impeller/entity/gles/gaussian.frag.gles", + "has_uniform_computation": false, + "type": "Fragment", + "variants": { + "Main": { + "has_stack_spilling": false, + "performance": { + "longest_path_bound_pipelines": [ + null + ], + "longest_path_cycles": [ + null, + null, + null + ], + "pipelines": [ + "arithmetic", + "load_store", + "texture" + ], + "shortest_path_bound_pipelines": [ + "arithmetic", + "load_store" + ], + "shortest_path_cycles": [ + 1.0, + 1.0, 0.0 ], "total_bound_pipelines": [ "load_store" ], "total_cycles": [ - 2.6666667461395264, - 5.0, - 0.0 + 1.6666666269302368, + 2.0, + 1.0 ] }, "thread_occupancy": 100, - "uniform_registers_used": 5, - "work_registers_used": 2 + "uniform_registers_used": 1, + "work_registers_used": 3 } } } }, - "flutter/impeller/entity/gles/gradient.frag.gles": { + "flutter/impeller/entity/gles/glyph_atlas.frag.gles": { "Mali-G78": { "core": "Mali-G78", - "filename": "flutter/impeller/entity/gles/gradient.frag.gles", + "filename": "flutter/impeller/entity/gles/glyph_atlas.frag.gles", "has_side_effects": false, - "has_uniform_computation": false, + "has_uniform_computation": true, "modifies_coverage": false, "reads_color_buffer": false, "type": "Fragment", @@ -2493,16 +2673,17 @@ "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - "varying" + "varying", + "texture" ], "longest_path_cycles": [ - 0.0625, - 0.0625, - 0.046875, + 0.109375, + 0.03125, + 0.109375, 0.0, 0.0, 0.25, - 0.0 + 0.25 ], "pipelines": [ "arith_total", @@ -2514,40 +2695,42 @@ "texture" ], "shortest_path_bound_pipelines": [ - "varying" + "varying", + "texture" ], "shortest_path_cycles": [ 0.0625, + 0.03125, 0.0625, - 0.015625, 0.0, 0.0, 0.25, - 0.0 + 0.25 ], "total_bound_pipelines": [ - "varying" + "varying", + "texture" ], "total_cycles": [ + 0.125, 0.0625, - 0.0625, - 0.046875, + 0.125, 0.0, 0.0, 0.25, - 0.0 + 0.25 ] }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 2, + "uniform_registers_used": 6, "work_registers_used": 19 } } }, "Mali-T880": { "core": "Mali-T880", - "filename": "flutter/impeller/entity/gles/gradient.frag.gles", + "filename": "flutter/impeller/entity/gles/glyph_atlas.frag.gles", "has_uniform_computation": false, "type": "Fragment", "variants": { @@ -2556,12 +2739,13 @@ "performance": { "longest_path_bound_pipelines": [ "arithmetic", - "load_store" + "load_store", + "texture" ], "longest_path_cycles": [ 1.0, 1.0, - 0.0 + 1.0 ], "pipelines": [ "arithmetic", @@ -2570,20 +2754,21 @@ ], "shortest_path_bound_pipelines": [ "arithmetic", - "load_store" + "load_store", + "texture" ], "shortest_path_cycles": [ 1.0, 1.0, - 0.0 + 1.0 ], "total_bound_pipelines": [ - "load_store" + "arithmetic" ], "total_cycles": [ - 0.6666666865348816, + 2.6666667461395264, 1.0, - 0.0 + 1.0 ] }, "thread_occupancy": 100, @@ -2593,10 +2778,10 @@ } } }, - "flutter/impeller/entity/gles/gradient.vert.gles": { + "flutter/impeller/entity/gles/glyph_atlas.vert.gles": { "Mali-G78": { "core": "Mali-G78", - "filename": "flutter/impeller/entity/gles/gradient.vert.gles", + "filename": "flutter/impeller/entity/gles/glyph_atlas.vert.gles", "has_uniform_computation": false, "type": "Vertex", "variants": { @@ -2700,13 +2885,13 @@ "stack_spill_bytes": 0, "thread_occupancy": 100, "uniform_registers_used": 8, - "work_registers_used": 9 + "work_registers_used": 7 } } }, "Mali-T880": { "core": "Mali-T880", - "filename": "flutter/impeller/entity/gles/gradient.vert.gles", + "filename": "flutter/impeller/entity/gles/glyph_atlas.vert.gles", "has_uniform_computation": false, "type": "Vertex", "variants": { @@ -5812,191 +5997,6 @@ } } }, - "flutter/impeller/entity/gradient.frag.vkspv": { - "Mali-G78": { - "core": "Mali-G78", - "filename": "flutter/impeller/entity/gradient.frag.vkspv", - "has_side_effects": false, - "has_uniform_computation": true, - "modifies_coverage": false, - "reads_color_buffer": false, - "type": "Fragment", - "uses_late_zs_test": false, - "uses_late_zs_update": false, - "variants": { - "Main": { - "fp16_arithmetic": 85, - "has_stack_spilling": false, - "performance": { - "longest_path_bound_pipelines": [ - "arith_total", - "arith_sfu" - ], - "longest_path_cycles": [ - 0.5, - 0.109375, - 0.125, - 0.5, - 0.0, - 0.25, - 0.0 - ], - "pipelines": [ - "arith_total", - "arith_fma", - "arith_cvt", - "arith_sfu", - "load_store", - "varying", - "texture" - ], - "shortest_path_bound_pipelines": [ - "arith_total", - "arith_sfu" - ], - "shortest_path_cycles": [ - 0.5, - 0.109375, - 0.125, - 0.5, - 0.0, - 0.25, - 0.0 - ], - "total_bound_pipelines": [ - "arith_total", - "arith_sfu" - ], - "total_cycles": [ - 0.5, - 0.109375, - 0.125, - 0.5, - 0.0, - 0.25, - 0.0 - ] - }, - "stack_spill_bytes": 0, - "thread_occupancy": 100, - "uniform_registers_used": 10, - "work_registers_used": 11 - } - } - } - }, - "flutter/impeller/entity/gradient.vert.vkspv": { - "Mali-G78": { - "core": "Mali-G78", - "filename": "flutter/impeller/entity/gradient.vert.vkspv", - "has_uniform_computation": true, - "type": "Vertex", - "variants": { - "Position": { - "fp16_arithmetic": 0, - "has_stack_spilling": false, - "performance": { - "longest_path_bound_pipelines": [ - "load_store" - ], - "longest_path_cycles": [ - 0.125, - 0.125, - 0.0, - 0.0, - 2.0, - 0.0 - ], - "pipelines": [ - "arith_total", - "arith_fma", - "arith_cvt", - "arith_sfu", - "load_store", - "texture" - ], - "shortest_path_bound_pipelines": [ - "load_store" - ], - "shortest_path_cycles": [ - 0.125, - 0.125, - 0.0, - 0.0, - 2.0, - 0.0 - ], - "total_bound_pipelines": [ - "load_store" - ], - "total_cycles": [ - 0.125, - 0.125, - 0.0, - 0.0, - 2.0, - 0.0 - ] - }, - "stack_spill_bytes": 0, - "thread_occupancy": 100, - "uniform_registers_used": 28, - "work_registers_used": 32 - }, - "Varying": { - "fp16_arithmetic": null, - "has_stack_spilling": false, - "performance": { - "longest_path_bound_pipelines": [ - "load_store" - ], - "longest_path_cycles": [ - 0.0, - 0.0, - 0.0, - 0.0, - 3.0, - 0.0 - ], - "pipelines": [ - "arith_total", - "arith_fma", - "arith_cvt", - "arith_sfu", - "load_store", - "texture" - ], - "shortest_path_bound_pipelines": [ - "load_store" - ], - "shortest_path_cycles": [ - 0.0, - 0.0, - 0.0, - 0.0, - 3.0, - 0.0 - ], - "total_bound_pipelines": [ - "load_store" - ], - "total_cycles": [ - 0.0, - 0.0, - 0.0, - 0.0, - 3.0, - 0.0 - ] - }, - "stack_spill_bytes": 0, - "thread_occupancy": 100, - "uniform_registers_used": 20, - "work_registers_used": 9 - } - } - } - }, "flutter/impeller/entity/gradient_fill.vert.vkspv": { "Mali-G78": { "core": "Mali-G78", diff --git a/testing/impeller_golden_tests_output.txt b/testing/impeller_golden_tests_output.txt index fb2b34e52ff03..4ac24c63c96e9 100644 --- a/testing/impeller_golden_tests_output.txt +++ b/testing/impeller_golden_tests_output.txt @@ -563,6 +563,18 @@ impeller_Play_AiksTest_EmptySaveLayerIgnoresPaint_Vulkan.png impeller_Play_AiksTest_EmptySaveLayerRendersWithClear_Metal.png impeller_Play_AiksTest_EmptySaveLayerRendersWithClear_OpenGLES.png impeller_Play_AiksTest_EmptySaveLayerRendersWithClear_Vulkan.png +impeller_Play_AiksTest_FastGradientTestHorizontalReversed_Metal.png +impeller_Play_AiksTest_FastGradientTestHorizontalReversed_OpenGLES.png +impeller_Play_AiksTest_FastGradientTestHorizontalReversed_Vulkan.png +impeller_Play_AiksTest_FastGradientTestHorizontal_Metal.png +impeller_Play_AiksTest_FastGradientTestHorizontal_OpenGLES.png +impeller_Play_AiksTest_FastGradientTestHorizontal_Vulkan.png +impeller_Play_AiksTest_FastGradientTestVerticalReversed_Metal.png +impeller_Play_AiksTest_FastGradientTestVerticalReversed_OpenGLES.png +impeller_Play_AiksTest_FastGradientTestVerticalReversed_Vulkan.png +impeller_Play_AiksTest_FastGradientTestVertical_Metal.png +impeller_Play_AiksTest_FastGradientTestVertical_OpenGLES.png +impeller_Play_AiksTest_FastGradientTestVertical_Vulkan.png impeller_Play_AiksTest_FilledCirclesRenderCorrectly_Metal.png impeller_Play_AiksTest_FilledCirclesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_FilledCirclesRenderCorrectly_Vulkan.png From 4cfd1cfd002f201a417abdb1480ffca5682783da Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 3 Jun 2024 13:01:44 -0700 Subject: [PATCH 10/13] fix hoz gradients and reversed. --- .../contents/linear_gradient_contents.cc | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/impeller/entity/contents/linear_gradient_contents.cc b/impeller/entity/contents/linear_gradient_contents.cc index 8773815bc228b..77b79bd02b2f7 100644 --- a/impeller/entity/contents/linear_gradient_contents.cc +++ b/impeller/entity/contents/linear_gradient_contents.cc @@ -79,28 +79,23 @@ bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, return false; } Rect rect = maybe_rect.value(); - - VertexBufferBuilder vtx_builder; bool horizontal_axis = start_point_.y == end_point_.y; - // Step 1. Compute the locations of each breakpoint along the primary axis. - std::vector points(stops_.size()); - for (auto i = 0u; i < stops_.size(); i++) { - Scalar t = stops_[i]; - points[i] = (1.0 - t) * start_point_ + t * end_point_; - } - // Now create a rectangle that joins each segment. That will be two - // triangles between each pair of points. + // Compute the locations of each breakpoint along the primary axis, then + // create a rectangle that joins each segment. That will be two triangles + // between each pair of points. + VertexBufferBuilder vtx_builder; vtx_builder.Reserve(6 * (stops_.size() - 1)); - for (auto i = 1u; i < points.size(); i++) { - Rect section = - horizontal_axis - ? Rect::MakeXYWH(points[i - 1].x, rect.GetY(), - abs(points[i].x - points[i - 1].x), - rect.GetHeight()) - - : Rect::MakeXYWH(rect.GetX(), points[i - 1].y, rect.GetWidth(), - abs(points[i].y - points[i - 1].y)); + Point prev = start_point_; + for (auto i = 1u; i < stops_.size(); i++) { + Scalar t = stops_[i]; + Point current = (1.0 - t) * start_point_ + t * end_point_; + Rect section = horizontal_axis + ? Rect::MakeXYWH(prev.x, rect.GetY(), current.x - prev.x, + rect.GetHeight()) + + : Rect::MakeXYWH(rect.GetX(), prev.y, rect.GetWidth(), + current.y - prev.y); vtx_builder.AddVertices({ {section.GetLeftTop(), colors_[i - 1]}, {section.GetRightTop(), horizontal_axis ? colors_[i] : colors_[i - 1]}, @@ -109,9 +104,9 @@ bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, {section.GetRightTop(), horizontal_axis ? colors_[i] : colors_[i - 1]}, {section.GetLeftBottom(), horizontal_axis ? colors_[i - 1] : colors_[i]}, - {section.GetRightBottom(), - horizontal_axis ? colors_[i] : colors_[i - 1]}, + {section.GetRightBottom(), colors_[i]}, }); + prev = current; } auto& host_buffer = renderer.GetTransientsBuffer(); From 59ba1c402b6bb3b8b99c483403cc24d7f3798298 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 3 Jun 2024 13:03:19 -0700 Subject: [PATCH 11/13] ++ --- impeller/aiks/aiks_gradient_unittests.cc | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/impeller/aiks/aiks_gradient_unittests.cc b/impeller/aiks/aiks_gradient_unittests.cc index 96779c08c1850..8fa05e75db075 100644 --- a/impeller/aiks/aiks_gradient_unittests.cc +++ b/impeller/aiks/aiks_gradient_unittests.cc @@ -744,13 +744,13 @@ TEST_P(AiksTest, FastGradientTestHorizontal) { std::vector stops = {0.0, 0.1, 1.0}; paint.color_source = ColorSource::MakeLinearGradient( - {0, 0}, {600, 0}, std::move(colors), std::move(stops), + {0, 0}, {300, 0}, std::move(colors), std::move(stops), Entity::TileMode::kClamp, {}); paint.color = Color(1.0, 1.0, 1.0, 1.0); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint); - canvas.Translate({800, 0, 0}); - canvas.DrawRRect(Rect::MakeXYWH(0, 0, 600, 600), Size(4, 4), paint); + canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300), paint); + canvas.Translate({400, 0, 0}); + canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), Size(4, 4), paint); ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } @@ -765,13 +765,13 @@ TEST_P(AiksTest, FastGradientTestVertical) { std::vector stops = {0.0, 0.1, 1.0}; paint.color_source = ColorSource::MakeLinearGradient( - {0, 0}, {0, 600}, std::move(colors), std::move(stops), + {0, 0}, {0, 300}, std::move(colors), std::move(stops), Entity::TileMode::kClamp, {}); paint.color = Color(1.0, 1.0, 1.0, 1.0); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint); - canvas.Translate({800, 0, 0}); - canvas.DrawRRect(Rect::MakeXYWH(0, 0, 600, 600), Size(4, 4), paint); + canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300), paint); + canvas.Translate({400, 0, 0}); + canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), Size(4, 4), paint); ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } @@ -786,13 +786,13 @@ TEST_P(AiksTest, FastGradientTestHorizontalReversed) { std::vector stops = {0.0, 0.1, 1.0}; paint.color_source = ColorSource::MakeLinearGradient( - {600, 0}, {0, 0}, std::move(colors), std::move(stops), + {300, 0}, {0, 0}, std::move(colors), std::move(stops), Entity::TileMode::kClamp, {}); paint.color = Color(1.0, 1.0, 1.0, 1.0); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint); - canvas.Translate({800, 0, 0}); - canvas.DrawRRect(Rect::MakeXYWH(0, 0, 600, 600), Size(4, 4), paint); + canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300), paint); + canvas.Translate({400, 0, 0}); + canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), Size(4, 4), paint); ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } @@ -807,13 +807,13 @@ TEST_P(AiksTest, FastGradientTestVerticalReversed) { std::vector stops = {0.0, 0.1, 1.0}; paint.color_source = ColorSource::MakeLinearGradient( - {0, 600}, {0, 0}, std::move(colors), std::move(stops), + {0, 300}, {0, 0}, std::move(colors), std::move(stops), Entity::TileMode::kClamp, {}); paint.color = Color(1.0, 1.0, 1.0, 1.0); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint); - canvas.Translate({800, 0, 0}); - canvas.DrawRRect(Rect::MakeXYWH(0, 0, 600, 600), Size(4, 4), paint); + canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300), paint); + canvas.Translate({400, 0, 0}); + canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), Size(4, 4), paint); ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } From f33c417074b2919c38fdec70a25f50f3e50b4873 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 3 Jun 2024 16:26:38 -0700 Subject: [PATCH 12/13] chinmay review. --- impeller/entity/contents/content_context.h | 8 ++++---- .../contents/linear_gradient_contents.cc | 19 +++++++++++-------- .../shaders/gradients/fast_gradient.vert | 2 ++ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 7486b1575f41d..083412ecebeb8 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -78,7 +78,7 @@ namespace impeller { -using GradientPipeline = +using FastGradientPipeline = RenderPipelineHandle; using LinearGradientFillPipeline = RenderPipelineHandle GetTessellator() const; - std::shared_ptr> GetGradientPipeline( + std::shared_ptr> GetFastGradientPipeline( ContentContextOptions opts) const { - return GetPipeline(gradient_pipelines_, opts); + return GetPipeline(fast_gradient_pipelines_, opts); } std::shared_ptr> GetLinearGradientFillPipeline( @@ -865,7 +865,7 @@ class ContentContext { // map. mutable Variants solid_fill_pipelines_; - mutable Variants gradient_pipelines_; + mutable Variants fast_gradient_pipelines_; mutable Variants linear_gradient_fill_pipelines_; mutable Variants radial_gradient_fill_pipelines_; mutable Variants diff --git a/impeller/entity/contents/linear_gradient_contents.cc b/impeller/entity/contents/linear_gradient_contents.cc index 77b79bd02b2f7..1389da6fe0043 100644 --- a/impeller/entity/contents/linear_gradient_contents.cc +++ b/impeller/entity/contents/linear_gradient_contents.cc @@ -59,21 +59,21 @@ bool LinearGradientContents::IsOpaque() const { // the gradient is divided into regions based on the stop values. // Currently restricted to rect geometry where the start and end points are // perfectly horizontal/vertical, but could easily be expanded to StC cases -// provided that the start/end are on our outside the coverage rect. +// provided that the start/end are on or outside of the coverage rect. bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - using VS = GradientPipeline::VertexShader; - using FS = GradientPipeline::FragmentShader; + using VS = FastGradientPipeline::VertexShader; + using FS = FastGradientPipeline::FragmentShader; auto options = OptionsFromPassAndEntity(pass, entity); options.primitive_type = PrimitiveType::kTriangle; Geometry& geometry = *GetGeometry(); // We already know this is an axis aligned rectangle, so the coverage will - // be approximately the same as the geometry. For non AARs, we can force - // stencil then cover (not done here). We give an identity transform to - // avoid double transforming the gradient. + // be approximately the same as the geometry. For non axis-algined rectangles, + // we can force stencil then cover (not done here). We give an identity + // transform to avoid double transforming the gradient. std::optional maybe_rect = geometry.GetCoverage(Matrix()); if (!maybe_rect.has_value()) { return false; @@ -82,7 +82,7 @@ bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, bool horizontal_axis = start_point_.y == end_point_.y; // Compute the locations of each breakpoint along the primary axis, then - // create a rectangle that joins each segment. That will be two triangles + // create a rectangle that joins each segment. There will be two triangles // between each pair of points. VertexBufferBuilder vtx_builder; vtx_builder.Reserve(6 * (stops_.size() - 1)); @@ -112,7 +112,7 @@ bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, pass.SetLabel("LinearGradient"); pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer)); - pass.SetPipeline(renderer.GetGradientPipeline(options)); + pass.SetPipeline(renderer.GetFastGradientPipeline(options)); pass.SetStencilReference(0); // Take the pre-populated vertex shader uniform struct and set managed @@ -134,6 +134,9 @@ bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, bool LinearGradientContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { + // TODO(148651): The fast path is overly restrictive, following the design in + // https://github.com/flutter/flutter/issues/148651 support for more cases can + // be gradually added. if (GetGeometry()->IsAxisAlignedRect() && (start_point_.x == end_point_.x || start_point_.y == end_point_.y) && GetInverseEffectTransform().IsIdentity()) { diff --git a/impeller/entity/shaders/gradients/fast_gradient.vert b/impeller/entity/shaders/gradients/fast_gradient.vert index 9a6cdfeac1d87..993f05ccc48fb 100644 --- a/impeller/entity/shaders/gradients/fast_gradient.vert +++ b/impeller/entity/shaders/gradients/fast_gradient.vert @@ -13,6 +13,8 @@ frame_info; in vec2 position; in vec4 color; +// The geometry of the fast gradient draws is designed so that the +// varying unit will perform the correct color interpolation. out vec4 v_color; void main() { From 6c92f8e68c92f936054fcdf3ef14ac0fdd40beba Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Mon, 3 Jun 2024 16:30:00 -0700 Subject: [PATCH 13/13] ++ --- impeller/entity/contents/content_context.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index f55f3afb645a3..dc8985bb5acc5 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -293,7 +293,7 @@ ContentContext::ContentContext( { solid_fill_pipelines_.CreateDefault(*context_, options); texture_pipelines_.CreateDefault(*context_, options); - gradient_pipelines_.CreateDefault(*context_, options); + fast_gradient_pipelines_.CreateDefault(*context_, options); if (context_->GetCapabilities()->SupportsSSBO()) { linear_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);