diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 9883325e84309..9adebc0edfd92 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/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,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/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/aiks/aiks_gradient_unittests.cc b/impeller/aiks/aiks_gradient_unittests.cc index 7938fb60f9f3c..8fa05e75db075 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}, {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, 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())); +} + +// 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, 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, 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())); +} + +// 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( + {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, 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())); +} + +// 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, 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, 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())); +} + } // namespace testing } // namespace impeller diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 5b1bbdb1770ae..d4363be8d7804 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/fast_gradient.vert", + "shaders/gradients/fast_gradient.frag", ] } diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index fe3338fdaa791..dc8985bb5acc5 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); + fast_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 aa173c3b04fc1..083412ecebeb8 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -28,6 +28,8 @@ #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" @@ -76,6 +78,8 @@ namespace impeller { +using FastGradientPipeline = + RenderPipelineHandle; using LinearGradientFillPipeline = RenderPipelineHandle; @@ -376,6 +380,11 @@ class ContentContext { std::shared_ptr GetTessellator() const; + std::shared_ptr> GetFastGradientPipeline( + ContentContextOptions opts) const { + return GetPipeline(fast_gradient_pipelines_, opts); + } + std::shared_ptr> GetLinearGradientFillPipeline( ContentContextOptions opts) const { return GetPipeline(linear_gradient_fill_pipelines_, opts); @@ -856,6 +865,7 @@ class ContentContext { // map. mutable Variants solid_fill_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 a61185654e9e2..1389da6fe0043 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,94 @@ 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 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 or outside of the coverage rect. +bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const { + 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 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; + } + Rect rect = maybe_rect.value(); + 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. There will be two triangles + // between each pair of points. + VertexBufferBuilder vtx_builder; + vtx_builder.Reserve(6 * (stops_.size() - 1)); + 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]}, + {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(), colors_[i]}, + }); + prev = current; + } + auto& host_buffer = renderer.GetTransientsBuffer(); + + pass.SetLabel("LinearGradient"); + pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer)); + pass.SetPipeline(renderer.GetFastGradientPipeline(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() * GetGeometry()->ComputeAlphaCoverage(entity); + + FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info)); + + return pass.Draw().ok(); +} + 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()) { + 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/fast_gradient.frag b/impeller/entity/shaders/gradients/fast_gradient.frag new file mode 100644 index 0000000000000..b52f9aa3b2b55 --- /dev/null +++ b/impeller/entity/shaders/gradients/fast_gradient.frag @@ -0,0 +1,26 @@ +// 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; + // 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 +} diff --git a/impeller/entity/shaders/gradients/fast_gradient.vert b/impeller/entity/shaders/gradients/fast_gradient.vert new file mode 100644 index 0000000000000..993f05ccc48fb --- /dev/null +++ b/impeller/entity/shaders/gradients/fast_gradient.vert @@ -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. + +#include +#include + +uniform FrameInfo { + mat4 mvp; +} +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() { + gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0); + v_color = color; +} diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index f156b6c8fefc9..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,6 +1951,280 @@ } } }, + "flutter/impeller/entity/gles/fast_gradient.frag.gles": { + "Mali-G78": { + "core": "Mali-G78", + "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": { + "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/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": [ + 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/fast_gradient.vert.gles": { + "Mali-G78": { + "core": "Mali-G78", + "filename": "flutter/impeller/entity/gles/fast_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/fast_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/filter_position.vert.gles": { "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