[Impeller] Switch to uniform arrays for gradient data on non-SSBO hardware (flutter/engine#56441)
Currently the most generalized form of the Impeller gradient shaders uses an SSBO to store the gradient information, but SSBO data is not supported on older platforms. To make the capability more general we introduce variants of the gradient shaders that uses uniform arrays which are more widely supported.
This commit is contained in:
parent
ac0b5ca828
commit
2fb2e3e70a
@ -43078,15 +43078,19 @@ 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/conical_gradient_uniform_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
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_uniform_fill.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/radial_gradient_fill.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/radial_gradient_ssbo_fill.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/radial_gradient_uniform_fill.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/sweep_gradient_fill.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/sweep_gradient_ssbo_fill.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/sweep_gradient_uniform_fill.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/rrect_blur.frag + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/rrect_blur.vert + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/impeller/entity/shaders/runtime_effect.vert + ../../../flutter/LICENSE
|
||||
@ -45940,15 +45944,19 @@ 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/conical_gradient_uniform_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
|
||||
FILE: ../../../flutter/impeller/entity/shaders/gradients/linear_gradient_uniform_fill.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/gradients/radial_gradient_fill.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/gradients/radial_gradient_ssbo_fill.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/gradients/radial_gradient_uniform_fill.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/gradients/sweep_gradient_fill.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/gradients/sweep_gradient_ssbo_fill.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/gradients/sweep_gradient_uniform_fill.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/rrect_blur.frag
|
||||
FILE: ../../../flutter/impeller/entity/shaders/rrect_blur.vert
|
||||
FILE: ../../../flutter/impeller/entity/shaders/runtime_effect.vert
|
||||
|
@ -216,6 +216,123 @@ TEST_P(AiksTest, CanRenderLinearGradientWithOverlappingStopsClamp) {
|
||||
CanRenderLinearGradientWithOverlappingStops(this, DlTileMode::kClamp);
|
||||
}
|
||||
|
||||
namespace {
|
||||
void CanRenderGradientWithIncompleteStops(AiksTest* aiks_test,
|
||||
DlColorSourceType type) {
|
||||
const DlTileMode tile_modes[4] = {
|
||||
DlTileMode::kClamp,
|
||||
DlTileMode::kRepeat,
|
||||
DlTileMode::kMirror,
|
||||
DlTileMode::kDecal,
|
||||
};
|
||||
const DlScalar test_size = 250;
|
||||
const DlScalar test_border = 25;
|
||||
const DlScalar gradient_size = 50;
|
||||
const DlScalar quadrant_size = test_size + test_border * 2;
|
||||
|
||||
DisplayListBuilder builder;
|
||||
builder.DrawRect(DlRect::MakeWH(quadrant_size * 2, quadrant_size * 2),
|
||||
DlPaint().setColor(DlColor::kDarkGrey()));
|
||||
|
||||
for (int quadrant = 0; quadrant < 4; quadrant++) {
|
||||
builder.Save();
|
||||
builder.Translate((quadrant & 1) * quadrant_size + test_border,
|
||||
(quadrant >> 1) * quadrant_size + test_border);
|
||||
|
||||
if (type == DlColorSourceType::kLinearGradient) {
|
||||
// Alignment lines for the gradient edges/repeats/mirrors/etc.
|
||||
// (rendered under the gradient so as not to obscure it)
|
||||
DlPoint center = DlPoint(test_size, test_size) * 0.5;
|
||||
DlScalar ten_percent = gradient_size * 0.1;
|
||||
for (int i = gradient_size / 2; i <= test_size / 2; i += gradient_size) {
|
||||
auto draw_at = [=](DlCanvas& canvas, DlScalar offset, DlColor color) {
|
||||
DlPaint line_paint;
|
||||
line_paint.setColor(color);
|
||||
// strokewidth of 2 straddles the dividing line
|
||||
line_paint.setStrokeWidth(2.0f);
|
||||
line_paint.setDrawStyle(DlDrawStyle::kStroke);
|
||||
|
||||
DlPoint along(offset, offset);
|
||||
DlScalar across_distance = test_size / 2 + 10 - offset;
|
||||
DlPoint across(across_distance, -across_distance);
|
||||
|
||||
canvas.DrawLine(center - along - across, //
|
||||
center - along + across, //
|
||||
line_paint);
|
||||
canvas.DrawLine(center + along - across, //
|
||||
center + along + across, //
|
||||
line_paint);
|
||||
};
|
||||
// White line is at the edge of the gradient
|
||||
// Grey lines are where the 0.1 and 0.9 color stops land
|
||||
draw_at(builder, i - ten_percent, DlColor::kMidGrey());
|
||||
draw_at(builder, i, DlColor::kWhite());
|
||||
draw_at(builder, i + ten_percent, DlColor::kMidGrey());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<DlColor> colors = {
|
||||
DlColor::kGreen(),
|
||||
DlColor::kPurple(),
|
||||
DlColor::kOrange(),
|
||||
DlColor::kBlue(),
|
||||
};
|
||||
std::vector<Scalar> stops = {0.1, 0.3, 0.7, 0.9};
|
||||
|
||||
DlPaint paint;
|
||||
switch (type) {
|
||||
case DlColorSourceType::kLinearGradient:
|
||||
paint.setColorSource(DlColorSource::MakeLinear(
|
||||
{test_size / 2 - gradient_size / 2,
|
||||
test_size / 2 - gradient_size / 2},
|
||||
{test_size / 2 + gradient_size / 2,
|
||||
test_size / 2 + gradient_size / 2},
|
||||
stops.size(), colors.data(), stops.data(), tile_modes[quadrant]));
|
||||
break;
|
||||
case DlColorSourceType::kRadialGradient:
|
||||
paint.setColorSource(DlColorSource::MakeRadial(
|
||||
{test_size / 2, test_size / 2}, gradient_size, //
|
||||
stops.size(), colors.data(), stops.data(), tile_modes[quadrant]));
|
||||
break;
|
||||
case DlColorSourceType::kConicalGradient:
|
||||
paint.setColorSource(DlColorSource::MakeConical(
|
||||
{test_size / 2, test_size / 2}, 0,
|
||||
{test_size / 2 + 20, test_size / 2 - 10}, gradient_size,
|
||||
stops.size(), colors.data(), stops.data(), tile_modes[quadrant]));
|
||||
break;
|
||||
case DlColorSourceType::kSweepGradient:
|
||||
paint.setColorSource(DlColorSource::MakeSweep(
|
||||
{test_size / 2, test_size / 2}, 0, 45, //
|
||||
stops.size(), colors.data(), stops.data(), tile_modes[quadrant]));
|
||||
break;
|
||||
default:
|
||||
FML_UNREACHABLE();
|
||||
}
|
||||
|
||||
builder.DrawRect(SkRect::MakeXYWH(0, 0, test_size, test_size), paint);
|
||||
builder.Restore();
|
||||
}
|
||||
|
||||
ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST_P(AiksTest, CanRenderLinearGradientWithIncompleteStops) {
|
||||
CanRenderGradientWithIncompleteStops(this,
|
||||
DlColorSourceType::kLinearGradient);
|
||||
}
|
||||
TEST_P(AiksTest, CanRenderRadialGradientWithIncompleteStops) {
|
||||
CanRenderGradientWithIncompleteStops(this,
|
||||
DlColorSourceType::kRadialGradient);
|
||||
}
|
||||
TEST_P(AiksTest, CanRenderConicalGradientWithIncompleteStops) {
|
||||
CanRenderGradientWithIncompleteStops(this,
|
||||
DlColorSourceType::kConicalGradient);
|
||||
}
|
||||
TEST_P(AiksTest, CanRenderSweepGradientWithIncompleteStops) {
|
||||
CanRenderGradientWithIncompleteStops(this, DlColorSourceType::kSweepGradient);
|
||||
}
|
||||
|
||||
namespace {
|
||||
void CanRenderLinearGradientManyColors(AiksTest* aiks_test,
|
||||
DlTileMode tile_mode) {
|
||||
|
@ -18,18 +18,22 @@ impeller_shaders("entity_shaders") {
|
||||
"shaders/blending/advanced_blend.frag",
|
||||
"shaders/clip.frag",
|
||||
"shaders/clip.vert",
|
||||
"shaders/gradients/conical_gradient_fill.frag",
|
||||
"shaders/glyph_atlas.frag",
|
||||
"shaders/glyph_atlas.vert",
|
||||
"shaders/gradients/gradient_fill.vert",
|
||||
"shaders/gradients/conical_gradient_fill.frag",
|
||||
"shaders/gradients/conical_gradient_uniform_fill.frag",
|
||||
"shaders/gradients/linear_gradient_fill.frag",
|
||||
"shaders/gradients/linear_gradient_uniform_fill.frag",
|
||||
"shaders/gradients/radial_gradient_fill.frag",
|
||||
"shaders/gradients/radial_gradient_uniform_fill.frag",
|
||||
"shaders/gradients/sweep_gradient_fill.frag",
|
||||
"shaders/gradients/sweep_gradient_uniform_fill.frag",
|
||||
"shaders/rrect_blur.vert",
|
||||
"shaders/rrect_blur.frag",
|
||||
"shaders/runtime_effect.vert",
|
||||
"shaders/solid_fill.frag",
|
||||
"shaders/solid_fill.vert",
|
||||
"shaders/gradients/sweep_gradient_fill.frag",
|
||||
"shaders/texture_fill.frag",
|
||||
"shaders/texture_fill.vert",
|
||||
"shaders/texture_uv_fill.vert",
|
||||
|
@ -49,12 +49,24 @@ void ConicalGradientContents::SetFocus(std::optional<Point> focus,
|
||||
focus_radius_ = radius;
|
||||
}
|
||||
|
||||
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define UNIFORM_FRAG_INFO(t) \
|
||||
t##GradientUniformFillPipeline::FragmentShader::FragInfo
|
||||
#define UNIFORM_COLOR_SIZE ARRAY_LEN(UNIFORM_FRAG_INFO(Conical)::colors)
|
||||
#define UNIFORM_STOP_SIZE ARRAY_LEN(UNIFORM_FRAG_INFO(Conical)::stop_pairs)
|
||||
static_assert(UNIFORM_COLOR_SIZE == kMaxUniformGradientStops);
|
||||
static_assert(UNIFORM_STOP_SIZE == kMaxUniformGradientStops / 2);
|
||||
|
||||
bool ConicalGradientContents::Render(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
if (renderer.GetDeviceCapabilities().SupportsSSBO()) {
|
||||
return RenderSSBO(renderer, entity, pass);
|
||||
}
|
||||
if (colors_.size() <= kMaxUniformGradientStops &&
|
||||
stops_.size() <= kMaxUniformGradientStops) {
|
||||
return RenderUniform(renderer, entity, pass);
|
||||
}
|
||||
return RenderTexture(renderer, entity, pass);
|
||||
}
|
||||
|
||||
@ -107,6 +119,49 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer,
|
||||
});
|
||||
}
|
||||
|
||||
bool ConicalGradientContents::RenderUniform(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
using VS = ConicalGradientUniformFillPipeline::VertexShader;
|
||||
using FS = ConicalGradientUniformFillPipeline::FragmentShader;
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.matrix = GetInverseEffectTransform();
|
||||
|
||||
PipelineBuilderCallback pipeline_callback =
|
||||
[&renderer](ContentContextOptions options) {
|
||||
return renderer.GetConicalGradientUniformFillPipeline(options);
|
||||
};
|
||||
return ColorSourceContents::DrawGeometry<VS>(
|
||||
renderer, entity, pass, pipeline_callback, frame_info,
|
||||
[this, &renderer, &entity](RenderPass& pass) {
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.center = center_;
|
||||
if (focus_) {
|
||||
frag_info.focus = focus_.value();
|
||||
frag_info.focus_radius = focus_radius_;
|
||||
} else {
|
||||
frag_info.focus = center_;
|
||||
frag_info.focus_radius = 0.0;
|
||||
}
|
||||
frag_info.radius = radius_;
|
||||
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
|
||||
frag_info.alpha =
|
||||
GetOpacityFactor() *
|
||||
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
|
||||
frag_info.colors_length = PopulateUniformGradientColors(
|
||||
colors_, stops_, frag_info.colors, frag_info.stop_pairs);
|
||||
frag_info.decal_border_color = decal_border_color_;
|
||||
|
||||
pass.SetCommandLabel("ConicalGradientUniformFill");
|
||||
|
||||
FS::BindFragInfo(
|
||||
pass, renderer.GetTransientsBuffer().EmplaceUniform(frag_info));
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool ConicalGradientContents::RenderTexture(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
|
@ -51,6 +51,11 @@ class ConicalGradientContents final : public ColorSourceContents {
|
||||
bool RenderSSBO(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const;
|
||||
|
||||
bool RenderUniform(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const;
|
||||
|
||||
Point center_;
|
||||
Scalar radius_ = 0.0f;
|
||||
std::vector<Color> colors_;
|
||||
|
@ -308,6 +308,12 @@ ContentContext::ContentContext(
|
||||
conical_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
|
||||
sweep_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
|
||||
} else {
|
||||
linear_gradient_uniform_fill_pipelines_.CreateDefault(*context_, options);
|
||||
radial_gradient_uniform_fill_pipelines_.CreateDefault(*context_, options);
|
||||
conical_gradient_uniform_fill_pipelines_.CreateDefault(*context_,
|
||||
options);
|
||||
sweep_gradient_uniform_fill_pipelines_.CreateDefault(*context_, options);
|
||||
|
||||
linear_gradient_fill_pipelines_.CreateDefault(*context_, options);
|
||||
radial_gradient_fill_pipelines_.CreateDefault(*context_, options);
|
||||
conical_gradient_fill_pipelines_.CreateDefault(*context_, options);
|
||||
|
@ -56,6 +56,11 @@
|
||||
#include "impeller/entity/tiled_texture_fill.frag.h"
|
||||
#include "impeller/entity/yuv_to_rgb_filter.frag.h"
|
||||
|
||||
#include "impeller/entity/conical_gradient_uniform_fill.frag.h"
|
||||
#include "impeller/entity/linear_gradient_uniform_fill.frag.h"
|
||||
#include "impeller/entity/radial_gradient_uniform_fill.frag.h"
|
||||
#include "impeller/entity/sweep_gradient_uniform_fill.frag.h"
|
||||
|
||||
#include "impeller/entity/conical_gradient_ssbo_fill.frag.h"
|
||||
#include "impeller/entity/linear_gradient_ssbo_fill.frag.h"
|
||||
#include "impeller/entity/radial_gradient_ssbo_fill.frag.h"
|
||||
@ -92,6 +97,18 @@ using ConicalGradientFillPipeline =
|
||||
using SweepGradientFillPipeline =
|
||||
RenderPipelineHandle<GradientFillVertexShader,
|
||||
SweepGradientFillFragmentShader>;
|
||||
using LinearGradientUniformFillPipeline =
|
||||
RenderPipelineHandle<GradientFillVertexShader,
|
||||
LinearGradientUniformFillFragmentShader>;
|
||||
using ConicalGradientUniformFillPipeline =
|
||||
RenderPipelineHandle<GradientFillVertexShader,
|
||||
ConicalGradientUniformFillFragmentShader>;
|
||||
using RadialGradientUniformFillPipeline =
|
||||
RenderPipelineHandle<GradientFillVertexShader,
|
||||
RadialGradientUniformFillFragmentShader>;
|
||||
using SweepGradientUniformFillPipeline =
|
||||
RenderPipelineHandle<GradientFillVertexShader,
|
||||
SweepGradientUniformFillFragmentShader>;
|
||||
using LinearGradientSSBOFillPipeline =
|
||||
RenderPipelineHandle<GradientFillVertexShader,
|
||||
LinearGradientSsboFillFragmentShader>;
|
||||
@ -370,6 +387,26 @@ class ContentContext {
|
||||
return GetPipeline(linear_gradient_fill_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetLinearGradientUniformFillPipeline(ContentContextOptions opts) const {
|
||||
return GetPipeline(linear_gradient_uniform_fill_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetRadialGradientUniformFillPipeline(ContentContextOptions opts) const {
|
||||
return GetPipeline(radial_gradient_uniform_fill_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetConicalGradientUniformFillPipeline(ContentContextOptions opts) const {
|
||||
return GetPipeline(conical_gradient_uniform_fill_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetSweepGradientUniformFillPipeline(ContentContextOptions opts) const {
|
||||
return GetPipeline(sweep_gradient_uniform_fill_pipelines_, opts);
|
||||
}
|
||||
|
||||
std::shared_ptr<Pipeline<PipelineDescriptor>>
|
||||
GetLinearGradientSSBOFillPipeline(ContentContextOptions opts) const {
|
||||
FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
|
||||
@ -867,6 +904,14 @@ class ContentContext {
|
||||
mutable Variants<ConicalGradientFillPipeline>
|
||||
conical_gradient_fill_pipelines_;
|
||||
mutable Variants<SweepGradientFillPipeline> sweep_gradient_fill_pipelines_;
|
||||
mutable Variants<LinearGradientUniformFillPipeline>
|
||||
linear_gradient_uniform_fill_pipelines_;
|
||||
mutable Variants<RadialGradientUniformFillPipeline>
|
||||
radial_gradient_uniform_fill_pipelines_;
|
||||
mutable Variants<ConicalGradientUniformFillPipeline>
|
||||
conical_gradient_uniform_fill_pipelines_;
|
||||
mutable Variants<SweepGradientUniformFillPipeline>
|
||||
sweep_gradient_uniform_fill_pipelines_;
|
||||
mutable Variants<LinearGradientSSBOFillPipeline>
|
||||
linear_gradient_ssbo_fill_pipelines_;
|
||||
mutable Variants<RadialGradientSSBOFillPipeline>
|
||||
|
@ -67,4 +67,31 @@ std::vector<StopData> CreateGradientColors(const std::vector<Color>& colors,
|
||||
return result;
|
||||
}
|
||||
|
||||
int PopulateUniformGradientColors(
|
||||
const std::vector<Color>& colors,
|
||||
const std::vector<Scalar>& stops,
|
||||
Vector4 frag_info_colors[kMaxUniformGradientStops],
|
||||
Vector4 frag_info_stop_pairs[kMaxUniformGradientStops / 2]) {
|
||||
FML_DCHECK(stops.size() == colors.size());
|
||||
|
||||
Scalar last_stop = 0;
|
||||
int index = 0;
|
||||
for (auto i = 0u; i < stops.size() && i < kMaxUniformGradientStops; i++) {
|
||||
Scalar cur_stop = stops[i];
|
||||
Scalar delta = cur_stop - last_stop;
|
||||
Scalar inverse_delta = delta == 0.0f ? 0.0 : 1.0 / delta;
|
||||
frag_info_colors[index] = colors[i];
|
||||
if ((i & 1) == 0) {
|
||||
frag_info_stop_pairs[index / 2].x = cur_stop;
|
||||
frag_info_stop_pairs[index / 2].y = inverse_delta;
|
||||
} else {
|
||||
frag_info_stop_pairs[index / 2].z = cur_stop;
|
||||
frag_info_stop_pairs[index / 2].w = inverse_delta;
|
||||
}
|
||||
last_stop = cur_stop;
|
||||
index++;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
@ -44,6 +44,28 @@ static_assert(sizeof(StopData) == 32);
|
||||
std::vector<StopData> CreateGradientColors(const std::vector<Color>& colors,
|
||||
const std::vector<Scalar>& stops);
|
||||
|
||||
static constexpr uint32_t kMaxUniformGradientStops = 256u;
|
||||
|
||||
/**
|
||||
* @brief Populate 2 arrays with the colors and stop data for a gradient
|
||||
*
|
||||
* The color data is simply converted to a vec4 format, but the stop data
|
||||
* is both turned into pairs of {t, inverse_delta} information and also
|
||||
* stops are themselves paired up into a vec4 format for efficient packing
|
||||
* in the uniform data.
|
||||
*
|
||||
* @param colors colors from gradient
|
||||
* @param stops stops from gradient
|
||||
* @param frag_info_colors colors for fragment shader in vec4 format
|
||||
* @param frag_info_stop_pairs pairs of stop data for shader in vec4 format
|
||||
* @return count of colors stored
|
||||
*/
|
||||
int PopulateUniformGradientColors(
|
||||
const std::vector<Color>& colors,
|
||||
const std::vector<Scalar>& stops,
|
||||
Vector4 frag_info_colors[kMaxUniformGradientStops],
|
||||
Vector4 frag_info_stop_pairs[kMaxUniformGradientStops / 2]);
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
#endif // FLUTTER_IMPELLER_ENTITY_CONTENTS_GRADIENT_GENERATOR_H_
|
||||
|
@ -186,6 +186,14 @@ bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer,
|
||||
/*force_stencil=*/force_stencil, geom_callback);
|
||||
}
|
||||
|
||||
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define UNIFORM_FRAG_INFO(t) \
|
||||
t##GradientUniformFillPipeline::FragmentShader::FragInfo
|
||||
#define UNIFORM_COLOR_SIZE ARRAY_LEN(UNIFORM_FRAG_INFO(Linear)::colors)
|
||||
#define UNIFORM_STOP_SIZE ARRAY_LEN(UNIFORM_FRAG_INFO(Linear)::stop_pairs)
|
||||
static_assert(UNIFORM_COLOR_SIZE == kMaxUniformGradientStops);
|
||||
static_assert(UNIFORM_STOP_SIZE == kMaxUniformGradientStops / 2);
|
||||
|
||||
bool LinearGradientContents::Render(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
@ -198,6 +206,10 @@ bool LinearGradientContents::Render(const ContentContext& renderer,
|
||||
if (renderer.GetDeviceCapabilities().SupportsSSBO()) {
|
||||
return RenderSSBO(renderer, entity, pass);
|
||||
}
|
||||
if (colors_.size() <= kMaxUniformGradientStops &&
|
||||
stops_.size() <= kMaxUniformGradientStops) {
|
||||
return RenderUniform(renderer, entity, pass);
|
||||
}
|
||||
return RenderTexture(renderer, entity, pass);
|
||||
}
|
||||
|
||||
@ -310,6 +322,44 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer,
|
||||
});
|
||||
}
|
||||
|
||||
bool LinearGradientContents::RenderUniform(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
using VS = LinearGradientUniformFillPipeline::VertexShader;
|
||||
using FS = LinearGradientUniformFillPipeline::FragmentShader;
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.matrix = GetInverseEffectTransform();
|
||||
|
||||
PipelineBuilderCallback pipeline_callback =
|
||||
[&renderer](ContentContextOptions options) {
|
||||
return renderer.GetLinearGradientUniformFillPipeline(options);
|
||||
};
|
||||
return ColorSourceContents::DrawGeometry<VS>(
|
||||
renderer, entity, pass, pipeline_callback, frame_info,
|
||||
[this, &renderer, &entity](RenderPass& pass) {
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.start_point = start_point_;
|
||||
frag_info.start_to_end = end_point_ - start_point_;
|
||||
frag_info.alpha =
|
||||
GetOpacityFactor() *
|
||||
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
|
||||
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
|
||||
frag_info.colors_length = PopulateUniformGradientColors(
|
||||
colors_, stops_, frag_info.colors, frag_info.stop_pairs);
|
||||
frag_info.inverse_dot_start_to_end =
|
||||
CalculateInverseDotStartToEnd(start_point_, end_point_);
|
||||
frag_info.decal_border_color = decal_border_color_;
|
||||
|
||||
pass.SetCommandLabel("LinearGradientUniformFill");
|
||||
|
||||
FS::BindFragInfo(
|
||||
pass, renderer.GetTransientsBuffer().EmplaceUniform(frag_info));
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool LinearGradientContents::ApplyColorFilter(
|
||||
const ColorFilterProc& color_filter_proc) {
|
||||
for (Color& color : colors_) {
|
||||
|
@ -53,6 +53,10 @@ class LinearGradientContents final : public ColorSourceContents {
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const;
|
||||
|
||||
bool RenderUniform(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const;
|
||||
|
||||
bool FastLinearGradient(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const;
|
||||
|
@ -55,12 +55,24 @@ bool RadialGradientContents::IsOpaque(const Matrix& transform) const {
|
||||
return !AppliesAlphaForStrokeCoverage(transform);
|
||||
}
|
||||
|
||||
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define UNIFORM_FRAG_INFO(t) \
|
||||
t##GradientUniformFillPipeline::FragmentShader::FragInfo
|
||||
#define UNIFORM_COLOR_SIZE ARRAY_LEN(UNIFORM_FRAG_INFO(Radial)::colors)
|
||||
#define UNIFORM_STOP_SIZE ARRAY_LEN(UNIFORM_FRAG_INFO(Radial)::stop_pairs)
|
||||
static_assert(UNIFORM_COLOR_SIZE == kMaxUniformGradientStops);
|
||||
static_assert(UNIFORM_STOP_SIZE == kMaxUniformGradientStops / 2);
|
||||
|
||||
bool RadialGradientContents::Render(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
if (renderer.GetDeviceCapabilities().SupportsSSBO()) {
|
||||
return RenderSSBO(renderer, entity, pass);
|
||||
}
|
||||
if (colors_.size() <= kMaxUniformGradientStops &&
|
||||
stops_.size() <= kMaxUniformGradientStops) {
|
||||
return RenderUniform(renderer, entity, pass);
|
||||
}
|
||||
return RenderTexture(renderer, entity, pass);
|
||||
}
|
||||
|
||||
@ -106,6 +118,42 @@ bool RadialGradientContents::RenderSSBO(const ContentContext& renderer,
|
||||
});
|
||||
}
|
||||
|
||||
bool RadialGradientContents::RenderUniform(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
using VS = RadialGradientUniformFillPipeline::VertexShader;
|
||||
using FS = RadialGradientUniformFillPipeline::FragmentShader;
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.matrix = GetInverseEffectTransform();
|
||||
|
||||
PipelineBuilderCallback pipeline_callback =
|
||||
[&renderer](ContentContextOptions options) {
|
||||
return renderer.GetRadialGradientUniformFillPipeline(options);
|
||||
};
|
||||
return ColorSourceContents::DrawGeometry<VS>(
|
||||
renderer, entity, pass, pipeline_callback, frame_info,
|
||||
[this, &renderer, &entity](RenderPass& pass) {
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.center = center_;
|
||||
frag_info.radius = radius_;
|
||||
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
|
||||
frag_info.alpha =
|
||||
GetOpacityFactor() *
|
||||
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
|
||||
frag_info.colors_length = PopulateUniformGradientColors(
|
||||
colors_, stops_, frag_info.colors, frag_info.stop_pairs);
|
||||
frag_info.decal_border_color = decal_border_color_;
|
||||
|
||||
pass.SetCommandLabel("RadialGradientUniformFill");
|
||||
|
||||
FS::BindFragInfo(
|
||||
pass, renderer.GetTransientsBuffer().EmplaceUniform(frag_info));
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool RadialGradientContents::RenderTexture(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
|
@ -52,6 +52,11 @@ class RadialGradientContents final : public ColorSourceContents {
|
||||
bool RenderSSBO(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const;
|
||||
|
||||
bool RenderUniform(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const;
|
||||
|
||||
Point center_;
|
||||
Scalar radius_;
|
||||
std::vector<Color> colors_;
|
||||
|
@ -61,12 +61,24 @@ bool SweepGradientContents::IsOpaque(const Matrix& transform) const {
|
||||
return !AppliesAlphaForStrokeCoverage(transform);
|
||||
}
|
||||
|
||||
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define UNIFORM_FRAG_INFO(t) \
|
||||
t##GradientUniformFillPipeline::FragmentShader::FragInfo
|
||||
#define UNIFORM_COLOR_SIZE ARRAY_LEN(UNIFORM_FRAG_INFO(Sweep)::colors)
|
||||
#define UNIFORM_STOP_SIZE ARRAY_LEN(UNIFORM_FRAG_INFO(Sweep)::stop_pairs)
|
||||
static_assert(UNIFORM_COLOR_SIZE == kMaxUniformGradientStops);
|
||||
static_assert(UNIFORM_STOP_SIZE == kMaxUniformGradientStops / 2);
|
||||
|
||||
bool SweepGradientContents::Render(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
if (renderer.GetDeviceCapabilities().SupportsSSBO()) {
|
||||
return RenderSSBO(renderer, entity, pass);
|
||||
}
|
||||
if (colors_.size() <= kMaxUniformGradientStops &&
|
||||
stops_.size() <= kMaxUniformGradientStops) {
|
||||
return RenderUniform(renderer, entity, pass);
|
||||
}
|
||||
return RenderTexture(renderer, entity, pass);
|
||||
}
|
||||
|
||||
@ -116,6 +128,46 @@ bool SweepGradientContents::RenderSSBO(const ContentContext& renderer,
|
||||
});
|
||||
}
|
||||
|
||||
bool SweepGradientContents::RenderUniform(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
using VS = SweepGradientUniformFillPipeline::VertexShader;
|
||||
using FS = SweepGradientUniformFillPipeline::FragmentShader;
|
||||
|
||||
VS::FrameInfo frame_info;
|
||||
frame_info.matrix = GetInverseEffectTransform();
|
||||
VS::BindFrameInfo(pass,
|
||||
renderer.GetTransientsBuffer().EmplaceUniform(frame_info));
|
||||
|
||||
PipelineBuilderCallback pipeline_callback =
|
||||
[&renderer](ContentContextOptions options) {
|
||||
return renderer.GetSweepGradientUniformFillPipeline(options);
|
||||
};
|
||||
return ColorSourceContents::DrawGeometry<VS>(
|
||||
renderer, entity, pass, pipeline_callback, frame_info,
|
||||
[this, &renderer, &entity](RenderPass& pass) {
|
||||
FS::FragInfo frag_info;
|
||||
frag_info.center = center_;
|
||||
frag_info.bias = bias_;
|
||||
frag_info.scale = scale_;
|
||||
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
|
||||
frag_info.alpha =
|
||||
GetOpacityFactor() *
|
||||
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
|
||||
frag_info.colors_length = PopulateUniformGradientColors(
|
||||
colors_, stops_, frag_info.colors, frag_info.stop_pairs);
|
||||
|
||||
frag_info.decal_border_color = decal_border_color_;
|
||||
|
||||
pass.SetCommandLabel("SweepGradientUniformFill");
|
||||
|
||||
FS::BindFragInfo(
|
||||
pass, renderer.GetTransientsBuffer().EmplaceUniform(frag_info));
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool SweepGradientContents::RenderTexture(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const {
|
||||
|
@ -54,6 +54,10 @@ class SweepGradientContents final : public ColorSourceContents {
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const;
|
||||
|
||||
bool RenderUniform(const ContentContext& renderer,
|
||||
const Entity& entity,
|
||||
RenderPass& pass) const;
|
||||
|
||||
Point center_;
|
||||
Scalar bias_;
|
||||
Scalar scale_;
|
||||
|
@ -0,0 +1,68 @@
|
||||
// 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 <impeller/color.glsl>
|
||||
#include <impeller/dithering.glsl>
|
||||
#include <impeller/gradient.glsl>
|
||||
#include <impeller/texture.glsl>
|
||||
#include <impeller/types.glsl>
|
||||
|
||||
uniform FragInfo {
|
||||
highp vec2 center;
|
||||
vec2 focus;
|
||||
float focus_radius;
|
||||
float radius;
|
||||
float tile_mode;
|
||||
float alpha;
|
||||
float colors_length;
|
||||
vec4 decal_border_color;
|
||||
vec4 colors[256];
|
||||
vec4 stop_pairs[128];
|
||||
}
|
||||
frag_info;
|
||||
|
||||
highp in vec2 v_position;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
vec2 res = IPComputeConicalT(frag_info.focus, frag_info.focus_radius,
|
||||
frag_info.center, frag_info.radius, v_position);
|
||||
|
||||
float t = res.x;
|
||||
vec4 result_color = vec4(0);
|
||||
if (res.y < 0.0 ||
|
||||
((t < 0.0 || t > 1.0) && frag_info.tile_mode == kTileModeDecal)) {
|
||||
result_color = frag_info.decal_border_color;
|
||||
} else {
|
||||
t = IPFloatTile(t, frag_info.tile_mode);
|
||||
|
||||
vec2 prev_stop = frag_info.stop_pairs[0].xy;
|
||||
bool even = false;
|
||||
for (int i = 1; i < frag_info.colors_length; i++) {
|
||||
// stop_pairs[i/2].xy = values for stop i
|
||||
// stop_pairs[i/2].zw = values for stop i+1
|
||||
vec2 cur_stop = even ? frag_info.stop_pairs[i / 2].xy
|
||||
: frag_info.stop_pairs[i / 2].zw;
|
||||
even = !even;
|
||||
// stop.x == t value
|
||||
// stop.y == inverse_delta to next stop
|
||||
if (t >= prev_stop.x && t <= cur_stop.x) {
|
||||
if (cur_stop.y > 1000.0) {
|
||||
result_color = frag_info.colors[i];
|
||||
} else {
|
||||
float ratio = (t - prev_stop.x) * cur_stop.y;
|
||||
result_color =
|
||||
mix(frag_info.colors[i - 1], frag_info.colors[i], ratio);
|
||||
}
|
||||
break;
|
||||
}
|
||||
prev_stop = cur_stop;
|
||||
}
|
||||
}
|
||||
|
||||
frag_color = IPPremultiply(result_color) * frag_info.alpha;
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
// 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 <impeller/color.glsl>
|
||||
#include <impeller/dithering.glsl>
|
||||
#include <impeller/gradient.glsl>
|
||||
#include <impeller/texture.glsl>
|
||||
#include <impeller/types.glsl>
|
||||
|
||||
uniform FragInfo {
|
||||
highp vec2 start_point;
|
||||
highp vec2 start_to_end;
|
||||
float alpha;
|
||||
float tile_mode;
|
||||
float colors_length;
|
||||
float inverse_dot_start_to_end;
|
||||
vec4 decal_border_color;
|
||||
vec4 colors[256];
|
||||
vec4 stop_pairs[128];
|
||||
}
|
||||
frag_info;
|
||||
|
||||
highp in vec2 v_position;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
highp vec2 start_to_position = v_position - frag_info.start_point;
|
||||
highp float t = dot(start_to_position, frag_info.start_to_end) *
|
||||
frag_info.inverse_dot_start_to_end;
|
||||
|
||||
if ((t < 0.0 || t > 1.0) && frag_info.tile_mode == kTileModeDecal) {
|
||||
frag_color = frag_info.decal_border_color;
|
||||
} else {
|
||||
t = IPFloatTile(t, frag_info.tile_mode);
|
||||
|
||||
vec2 prev_stop = frag_info.stop_pairs[0].xy;
|
||||
bool even = false;
|
||||
for (int i = 1; i < frag_info.colors_length; i++) {
|
||||
// stop_pairs[i/2].xy = values for stop i
|
||||
// stop_pairs[i/2].zw = values for stop i+1
|
||||
vec2 cur_stop = even ? frag_info.stop_pairs[i / 2].xy
|
||||
: frag_info.stop_pairs[i / 2].zw;
|
||||
even = !even;
|
||||
// stop.x == t value
|
||||
// stop.y == inverse_delta to next stop
|
||||
if (t >= prev_stop.x && t <= cur_stop.x) {
|
||||
if (cur_stop.y > 1000.0) {
|
||||
frag_color = frag_info.colors[i];
|
||||
} else {
|
||||
float ratio = (t - prev_stop.x) * cur_stop.y;
|
||||
frag_color = mix(frag_info.colors[i - 1], frag_info.colors[i], ratio);
|
||||
}
|
||||
break;
|
||||
}
|
||||
prev_stop = cur_stop;
|
||||
}
|
||||
}
|
||||
|
||||
frag_color = IPPremultiply(frag_color) * frag_info.alpha;
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
// 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 <impeller/color.glsl>
|
||||
#include <impeller/dithering.glsl>
|
||||
#include <impeller/gradient.glsl>
|
||||
#include <impeller/texture.glsl>
|
||||
#include <impeller/types.glsl>
|
||||
|
||||
uniform FragInfo {
|
||||
highp vec2 center;
|
||||
float radius;
|
||||
float tile_mode;
|
||||
float alpha;
|
||||
float colors_length;
|
||||
vec4 decal_border_color;
|
||||
vec4 colors[256];
|
||||
vec4 stop_pairs[128];
|
||||
}
|
||||
frag_info;
|
||||
|
||||
highp in vec2 v_position;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
float len = length(v_position - frag_info.center);
|
||||
float t = len / frag_info.radius;
|
||||
|
||||
vec4 result_color = vec4(0);
|
||||
if ((t < 0.0 || t > 1.0) && frag_info.tile_mode == kTileModeDecal) {
|
||||
result_color = frag_info.decal_border_color;
|
||||
} else {
|
||||
t = IPFloatTile(t, frag_info.tile_mode);
|
||||
|
||||
vec2 prev_stop = frag_info.stop_pairs[0].xy;
|
||||
bool even = false;
|
||||
for (int i = 1; i < frag_info.colors_length; i++) {
|
||||
// stop_pairs[i/2].xy = values for stop i
|
||||
// stop_pairs[i/2].zw = values for stop i+1
|
||||
vec2 cur_stop = even ? frag_info.stop_pairs[i / 2].xy
|
||||
: frag_info.stop_pairs[i / 2].zw;
|
||||
even = !even;
|
||||
// stop.x == t value
|
||||
// stop.y == inverse_delta to next stop
|
||||
if (t >= prev_stop.x && t <= cur_stop.x) {
|
||||
if (cur_stop.y > 1000.0) {
|
||||
result_color = frag_info.colors[i];
|
||||
} else {
|
||||
float ratio = (t - prev_stop.x) * cur_stop.y;
|
||||
result_color =
|
||||
mix(frag_info.colors[i - 1], frag_info.colors[i], ratio);
|
||||
}
|
||||
break;
|
||||
}
|
||||
prev_stop = cur_stop;
|
||||
}
|
||||
}
|
||||
|
||||
frag_color = IPPremultiply(result_color) * frag_info.alpha;
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
// 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 <impeller/color.glsl>
|
||||
#include <impeller/constants.glsl>
|
||||
#include <impeller/dithering.glsl>
|
||||
#include <impeller/gradient.glsl>
|
||||
#include <impeller/texture.glsl>
|
||||
#include <impeller/types.glsl>
|
||||
|
||||
uniform FragInfo {
|
||||
highp vec2 center;
|
||||
float bias;
|
||||
float scale;
|
||||
float tile_mode;
|
||||
float alpha;
|
||||
float colors_length;
|
||||
vec4 decal_border_color;
|
||||
vec4 colors[256];
|
||||
vec4 stop_pairs[128];
|
||||
}
|
||||
frag_info;
|
||||
|
||||
highp in vec2 v_position;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
vec2 coord = v_position - frag_info.center;
|
||||
float angle = atan(-coord.y, -coord.x);
|
||||
float t = (angle * k1Over2Pi + 0.5 + frag_info.bias) * frag_info.scale;
|
||||
|
||||
vec4 result_color = vec4(0);
|
||||
if ((t < 0.0 || t > 1.0) && frag_info.tile_mode == kTileModeDecal) {
|
||||
result_color = frag_info.decal_border_color;
|
||||
} else {
|
||||
t = IPFloatTile(t, frag_info.tile_mode);
|
||||
|
||||
vec2 prev_stop = frag_info.stop_pairs[0].xy;
|
||||
bool even = false;
|
||||
for (int i = 1; i < frag_info.colors_length; i++) {
|
||||
// stop_pairs[i/2].xy = values for stop i
|
||||
// stop_pairs[i/2].zw = values for stop i+1
|
||||
vec2 cur_stop = even ? frag_info.stop_pairs[i / 2].xy
|
||||
: frag_info.stop_pairs[i / 2].zw;
|
||||
even = !even;
|
||||
// stop.x == t value
|
||||
// stop.y == inverse_delta to next stop
|
||||
if (t >= prev_stop.x && t <= cur_stop.x) {
|
||||
if (cur_stop.y > 1000.0) {
|
||||
result_color = frag_info.colors[i];
|
||||
} else {
|
||||
float ratio = (t - prev_stop.x) * cur_stop.y;
|
||||
result_color =
|
||||
mix(frag_info.colors[i - 1], frag_info.colors[i], ratio);
|
||||
}
|
||||
break;
|
||||
}
|
||||
prev_stop = cur_stop;
|
||||
}
|
||||
}
|
||||
|
||||
frag_color = IPPremultiply(result_color) * frag_info.alpha;
|
||||
}
|
@ -613,6 +613,76 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/conical_gradient_uniform_fill.frag.vkspv": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
"filename": "flutter/impeller/entity/conical_gradient_uniform_fill.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": 70,
|
||||
"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": [
|
||||
"varying"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.1875,
|
||||
0.0625,
|
||||
0.1875,
|
||||
0.0,
|
||||
0.0,
|
||||
0.25,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
1.5499999523162842,
|
||||
0.800000011920929,
|
||||
1.5499999523162842,
|
||||
0.5,
|
||||
4.0,
|
||||
0.25,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 36,
|
||||
"work_registers_used": 18
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/fast_gradient.frag.vkspv": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
@ -1951,6 +2021,121 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/gles/conical_gradient_uniform_fill.frag.gles": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
"filename": "flutter/impeller/entity/gles/conical_gradient_uniform_fill.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": 62,
|
||||
"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": [
|
||||
"varying"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.1875,
|
||||
0.0625,
|
||||
0.1875,
|
||||
0.0,
|
||||
0.0,
|
||||
0.25,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
1.40625,
|
||||
0.84375,
|
||||
1.40625,
|
||||
0.4375,
|
||||
4.0,
|
||||
0.25,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 38,
|
||||
"work_registers_used": 21
|
||||
}
|
||||
}
|
||||
},
|
||||
"Mali-T880": {
|
||||
"core": "Mali-T880",
|
||||
"filename": "flutter/impeller/entity/gles/conical_gradient_uniform_fill.frag.gles",
|
||||
"has_uniform_computation": true,
|
||||
"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"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
1.649999976158142,
|
||||
1.0,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"arithmetic"
|
||||
],
|
||||
"total_cycles": [
|
||||
20.66666603088379,
|
||||
4.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 6,
|
||||
"work_registers_used": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/gles/fast_gradient.frag.gles": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
@ -3210,6 +3395,121 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/gles/linear_gradient_uniform_fill.frag.gles": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
"filename": "flutter/impeller/entity/gles/linear_gradient_uniform_fill.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": 13,
|
||||
"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": [
|
||||
"varying"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.203125,
|
||||
0.203125,
|
||||
0.171875,
|
||||
0.0625,
|
||||
0.0,
|
||||
0.25,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.8125,
|
||||
0.46875,
|
||||
0.8125,
|
||||
0.1875,
|
||||
4.0,
|
||||
0.25,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 12,
|
||||
"work_registers_used": 21
|
||||
}
|
||||
}
|
||||
},
|
||||
"Mali-T880": {
|
||||
"core": "Mali-T880",
|
||||
"filename": "flutter/impeller/entity/gles/linear_gradient_uniform_fill.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"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
2.640000104904175,
|
||||
1.0,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"arithmetic"
|
||||
],
|
||||
"total_cycles": [
|
||||
10.0,
|
||||
4.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 3,
|
||||
"work_registers_used": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/gles/linear_to_srgb_filter.frag.gles": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
@ -3837,6 +4137,121 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/gles/radial_gradient_uniform_fill.frag.gles": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
"filename": "flutter/impeller/entity/gles/radial_gradient_uniform_fill.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": 67,
|
||||
"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": [
|
||||
"varying"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.1875,
|
||||
0.171875,
|
||||
0.1875,
|
||||
0.0625,
|
||||
0.0,
|
||||
0.25,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.762499988079071,
|
||||
0.359375,
|
||||
0.762499988079071,
|
||||
0.1875,
|
||||
4.0,
|
||||
0.25,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 10,
|
||||
"work_registers_used": 21
|
||||
}
|
||||
}
|
||||
},
|
||||
"Mali-T880": {
|
||||
"core": "Mali-T880",
|
||||
"filename": "flutter/impeller/entity/gles/radial_gradient_uniform_fill.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"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
2.640000104904175,
|
||||
1.0,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"arithmetic"
|
||||
],
|
||||
"total_cycles": [
|
||||
9.666666984558105,
|
||||
4.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 2,
|
||||
"work_registers_used": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/gles/rrect_blur.frag.gles": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
@ -4730,6 +5145,122 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/gles/sweep_gradient_uniform_fill.frag.gles": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
"filename": "flutter/impeller/entity/gles/sweep_gradient_uniform_fill.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_fma"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.375,
|
||||
0.375,
|
||||
0.25,
|
||||
0.3125,
|
||||
0.0,
|
||||
0.25,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.925000011920929,
|
||||
0.625,
|
||||
0.925000011920929,
|
||||
0.4375,
|
||||
4.0,
|
||||
0.25,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 20,
|
||||
"work_registers_used": 25
|
||||
}
|
||||
}
|
||||
},
|
||||
"Mali-T880": {
|
||||
"core": "Mali-T880",
|
||||
"filename": "flutter/impeller/entity/gles/sweep_gradient_uniform_fill.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"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
2.9700000286102295,
|
||||
1.0,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"arithmetic"
|
||||
],
|
||||
"total_cycles": [
|
||||
10.333333015441895,
|
||||
5.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 3,
|
||||
"work_registers_used": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/gles/texture_downsample.frag.gles": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
@ -6443,6 +6974,76 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/linear_gradient_uniform_fill.frag.vkspv": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
"filename": "flutter/impeller/entity/linear_gradient_uniform_fill.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": 35,
|
||||
"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": [
|
||||
"varying"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.15625,
|
||||
0.15625,
|
||||
0.15625,
|
||||
0.0625,
|
||||
0.0,
|
||||
0.25,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.84375,
|
||||
0.359375,
|
||||
0.84375,
|
||||
0.25,
|
||||
4.0,
|
||||
0.25,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 14,
|
||||
"work_registers_used": 18
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/linear_to_srgb_filter.frag.vkspv": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
@ -6913,6 +7514,76 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/radial_gradient_uniform_fill.frag.vkspv": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
"filename": "flutter/impeller/entity/radial_gradient_uniform_fill.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": 58,
|
||||
"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": [
|
||||
"varying"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.171875,
|
||||
0.171875,
|
||||
0.171875,
|
||||
0.0625,
|
||||
0.0,
|
||||
0.25,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.84375,
|
||||
0.359375,
|
||||
0.84375,
|
||||
0.25,
|
||||
4.0,
|
||||
0.25,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 12,
|
||||
"work_registers_used": 18
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/rrect_blur.frag.vkspv": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
@ -7561,6 +8232,77 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/sweep_gradient_uniform_fill.frag.vkspv": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
"filename": "flutter/impeller/entity/sweep_gradient_uniform_fill.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": 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_fma"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.390625,
|
||||
0.390625,
|
||||
0.25,
|
||||
0.3125,
|
||||
0.0,
|
||||
0.25,
|
||||
0.0
|
||||
],
|
||||
"total_bound_pipelines": [
|
||||
"load_store"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.875,
|
||||
0.637499988079071,
|
||||
0.875,
|
||||
0.5,
|
||||
4.0,
|
||||
0.25,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"stack_spill_bytes": 0,
|
||||
"thread_occupancy": 100,
|
||||
"uniform_registers_used": 20,
|
||||
"work_registers_used": 23
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"flutter/impeller/entity/texture_downsample.frag.vkspv": {
|
||||
"Mali-G78": {
|
||||
"core": "Mali-G78",
|
||||
|
@ -289,6 +289,9 @@ impeller_Play_AiksTest_CanRenderColoredRect_Vulkan.png
|
||||
impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringEnabled_Metal.png
|
||||
impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringEnabled_OpenGLES.png
|
||||
impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringEnabled_Vulkan.png
|
||||
impeller_Play_AiksTest_CanRenderConicalGradientWithIncompleteStops_Metal.png
|
||||
impeller_Play_AiksTest_CanRenderConicalGradientWithIncompleteStops_OpenGLES.png
|
||||
impeller_Play_AiksTest_CanRenderConicalGradientWithIncompleteStops_Vulkan.png
|
||||
impeller_Play_AiksTest_CanRenderConicalGradient_Metal.png
|
||||
impeller_Play_AiksTest_CanRenderConicalGradient_OpenGLES.png
|
||||
impeller_Play_AiksTest_CanRenderConicalGradient_Vulkan.png
|
||||
@ -382,6 +385,9 @@ impeller_Play_AiksTest_CanRenderLinearGradientWayManyColorsClamp_Vulkan.png
|
||||
impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringEnabled_Metal.png
|
||||
impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringEnabled_OpenGLES.png
|
||||
impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringEnabled_Vulkan.png
|
||||
impeller_Play_AiksTest_CanRenderLinearGradientWithIncompleteStops_Metal.png
|
||||
impeller_Play_AiksTest_CanRenderLinearGradientWithIncompleteStops_OpenGLES.png
|
||||
impeller_Play_AiksTest_CanRenderLinearGradientWithIncompleteStops_Vulkan.png
|
||||
impeller_Play_AiksTest_CanRenderLinearGradientWithOverlappingStopsClamp_Metal.png
|
||||
impeller_Play_AiksTest_CanRenderLinearGradientWithOverlappingStopsClamp_OpenGLES.png
|
||||
impeller_Play_AiksTest_CanRenderLinearGradientWithOverlappingStopsClamp_Vulkan.png
|
||||
@ -412,6 +418,9 @@ impeller_Play_AiksTest_CanRenderRadialGradientManyColors_Vulkan.png
|
||||
impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringEnabled_Metal.png
|
||||
impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringEnabled_OpenGLES.png
|
||||
impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringEnabled_Vulkan.png
|
||||
impeller_Play_AiksTest_CanRenderRadialGradientWithIncompleteStops_Metal.png
|
||||
impeller_Play_AiksTest_CanRenderRadialGradientWithIncompleteStops_OpenGLES.png
|
||||
impeller_Play_AiksTest_CanRenderRadialGradientWithIncompleteStops_Vulkan.png
|
||||
impeller_Play_AiksTest_CanRenderRadialGradient_Metal.png
|
||||
impeller_Play_AiksTest_CanRenderRadialGradient_OpenGLES.png
|
||||
impeller_Play_AiksTest_CanRenderRadialGradient_Vulkan.png
|
||||
@ -463,6 +472,9 @@ impeller_Play_AiksTest_CanRenderSweepGradientRepeat_Vulkan.png
|
||||
impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringEnabled_Metal.png
|
||||
impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringEnabled_OpenGLES.png
|
||||
impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringEnabled_Vulkan.png
|
||||
impeller_Play_AiksTest_CanRenderSweepGradientWithIncompleteStops_Metal.png
|
||||
impeller_Play_AiksTest_CanRenderSweepGradientWithIncompleteStops_OpenGLES.png
|
||||
impeller_Play_AiksTest_CanRenderSweepGradientWithIncompleteStops_Vulkan.png
|
||||
impeller_Play_AiksTest_CanRenderTextFrameWithFractionScaling_Metal.png
|
||||
impeller_Play_AiksTest_CanRenderTextFrameWithFractionScaling_OpenGLES.png
|
||||
impeller_Play_AiksTest_CanRenderTextFrameWithFractionScaling_Vulkan.png
|
||||
|
Loading…
x
Reference in New Issue
Block a user