[Impeller] Support 'matrix' parameter for color sources (flutter/engine#35400)

This commit is contained in:
ColdPaleLight 2022-08-17 11:40:22 +08:00 committed by GitHub
parent 3afe0778d0
commit 970e092ee7
27 changed files with 342 additions and 263 deletions

View File

@ -500,6 +500,7 @@ FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/branching.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/color.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/constants.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/texture.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/transform.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/types.glsl
FILE: ../../../flutter/impeller/compiler/source_options.cc
FILE: ../../../flutter/impeller/compiler/source_options.h
@ -556,6 +557,8 @@ FILE: ../../../flutter/impeller/entity/contents/atlas_contents.cc
FILE: ../../../flutter/impeller/entity/contents/atlas_contents.h
FILE: ../../../flutter/impeller/entity/contents/clip_contents.cc
FILE: ../../../flutter/impeller/entity/contents/clip_contents.h
FILE: ../../../flutter/impeller/entity/contents/color_source_contents.cc
FILE: ../../../flutter/impeller/entity/contents/color_source_contents.h
FILE: ../../../flutter/impeller/entity/contents/content_context.cc
FILE: ../../../flutter/impeller/entity/contents/content_context.h
FILE: ../../../flutter/impeller/entity/contents/contents.cc
@ -581,8 +584,6 @@ FILE: ../../../flutter/impeller/entity/contents/filters/inputs/texture_filter_in
FILE: ../../../flutter/impeller/entity/contents/filters/inputs/texture_filter_input.h
FILE: ../../../flutter/impeller/entity/contents/linear_gradient_contents.cc
FILE: ../../../flutter/impeller/entity/contents/linear_gradient_contents.h
FILE: ../../../flutter/impeller/entity/contents/path_contents.cc
FILE: ../../../flutter/impeller/entity/contents/path_contents.h
FILE: ../../../flutter/impeller/entity/contents/radial_gradient_contents.cc
FILE: ../../../flutter/impeller/entity/contents/radial_gradient_contents.h
FILE: ../../../flutter/impeller/entity/contents/rrect_shadow_contents.cc
@ -641,10 +642,9 @@ FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur.frag
FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur.vert
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert
FILE: ../../../flutter/impeller/entity/shaders/gradient_fill.frag
FILE: ../../../flutter/impeller/entity/shaders/gradient_fill.vert
FILE: ../../../flutter/impeller/entity/shaders/linear_gradient_fill.frag
FILE: ../../../flutter/impeller/entity/shaders/radial_gradient_fill.frag
FILE: ../../../flutter/impeller/entity/shaders/radial_gradient_fill.vert
FILE: ../../../flutter/impeller/entity/shaders/rrect_blur.frag
FILE: ../../../flutter/impeller/entity/shaders/rrect_blur.vert
FILE: ../../../flutter/impeller/entity/shaders/solid_fill.frag
@ -652,7 +652,6 @@ FILE: ../../../flutter/impeller/entity/shaders/solid_fill.vert
FILE: ../../../flutter/impeller/entity/shaders/solid_stroke.frag
FILE: ../../../flutter/impeller/entity/shaders/solid_stroke.vert
FILE: ../../../flutter/impeller/entity/shaders/sweep_gradient_fill.frag
FILE: ../../../flutter/impeller/entity/shaders/sweep_gradient_fill.vert
FILE: ../../../flutter/impeller/entity/shaders/texture_fill.frag
FILE: ../../../flutter/impeller/entity/shaders/texture_fill.vert
FILE: ../../../flutter/impeller/entity/shaders/tiled_texture_fill.frag

View File

@ -13,6 +13,7 @@
#include "impeller/entity/contents/tiled_texture_contents.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/geometry_unittests.h"
#include "impeller/geometry/matrix.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/playground/widgets.h"
#include "impeller/renderer/command_buffer.h"
@ -125,7 +126,21 @@ TEST_P(AiksTest, CanRenderTiledTexture) {
ImGui::Combo("Min Mag filter", &selected_min_mag_filter,
min_mag_filter_names,
sizeof(min_mag_filter_names) / sizeof(char*));
static Matrix matrix = {
1, 0, 0, 0, //
0, 1, 0, 0, //
0, 0, 1, 0, //
0, 0, 0, 1 //
};
std::string label = "##1";
label.c_str();
for (int i = 0; i < 4; i++) {
ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float, &(matrix.vec[i]),
4, NULL, NULL, "%.2f", 0);
label[2]++;
}
ImGui::End();
Canvas canvas;
Paint paint;
canvas.Translate({100.0, 100.0, 0});
@ -140,6 +155,7 @@ TEST_P(AiksTest, CanRenderTiledTexture) {
contents->SetTexture(texture);
contents->SetTileModes(x_tile_mode, y_tile_mode);
contents->SetSamplerDescriptor(descriptor);
contents->SetMatrix(matrix);
return contents;
};
canvas.DrawRect({0, 0, 600, 600}, paint);
@ -282,86 +298,162 @@ TEST_P(AiksTest, CanSaveLayerStandalone) {
}
TEST_P(AiksTest, CanRenderLinearGradient) {
Canvas canvas;
Paint paint;
std::vector<Vector3> offsets = {
{0, 0, 0}, {0, 300, 0}, {300, 0, 0}, {300, 300, 0}};
std::vector<Entity::TileMode> tile_modes = {
Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
Entity::TileMode::kMirror, Entity::TileMode::kDecal};
for (int i = 0; i < 4; i++) {
canvas.Save();
canvas.Translate(offsets[i]);
Entity::TileMode tile_mode = tile_modes[i];
bool first_frame = true;
auto callback = [&](AiksContext& renderer, RenderTarget& render_target) {
if (first_frame) {
first_frame = false;
ImGui::SetNextWindowSize({480, 100});
ImGui::SetNextWindowPos({100, 550});
}
const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
const Entity::TileMode tile_modes[] = {
Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
Entity::TileMode::kMirror, Entity::TileMode::kDecal};
static int selected_tile_mode = 0;
ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
sizeof(tile_mode_names) / sizeof(char*));
static Matrix matrix = {
1, 0, 0, 0, //
0, 1, 0, 0, //
0, 0, 1, 0, //
0, 0, 0, 1 //
};
std::string label = "##1";
label.c_str();
for (int i = 0; i < 4; i++) {
ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float, &(matrix.vec[i]),
4, NULL, NULL, "%.2f", 0);
label[2]++;
}
ImGui::End();
Canvas canvas;
Paint paint;
canvas.Translate({100.0, 100.0, 0});
auto tile_mode = tile_modes[selected_tile_mode];
paint.color_source = [tile_mode]() {
auto contents = std::make_shared<LinearGradientContents>();
contents->SetEndPoints({0, 0}, {100, 100});
contents->SetEndPoints({0, 0}, {200, 200});
std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
Color{0.1294, 0.5882, 0.9529, 1.0}};
contents->SetColors(std::move(colors));
contents->SetTileMode(tile_mode);
contents->SetMatrix(matrix);
return contents;
};
canvas.DrawRect({0, 0, 200, 200}, paint);
canvas.Restore();
}
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
canvas.DrawRect({0, 0, 600, 600}, paint);
return renderer.Render(canvas.EndRecordingAsPicture(), render_target);
};
ASSERT_TRUE(OpenPlaygroundHere(callback));
}
TEST_P(AiksTest, CanRenderRadialGradient) {
Canvas canvas;
Paint paint;
std::vector<Vector3> offsets = {
{0, 0, 0}, {0, 300, 0}, {300, 0, 0}, {300, 300, 0}};
std::vector<Entity::TileMode> tile_modes = {
Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
Entity::TileMode::kMirror, Entity::TileMode::kDecal};
for (int i = 0; i < 4; i++) {
canvas.Save();
canvas.Translate(offsets[i]);
Entity::TileMode tile_mode = tile_modes[i];
bool first_frame = true;
auto callback = [&](AiksContext& renderer, RenderTarget& render_target) {
if (first_frame) {
first_frame = false;
ImGui::SetNextWindowSize({480, 100});
ImGui::SetNextWindowPos({100, 550});
}
const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
const Entity::TileMode tile_modes[] = {
Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
Entity::TileMode::kMirror, Entity::TileMode::kDecal};
static int selected_tile_mode = 0;
ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
sizeof(tile_mode_names) / sizeof(char*));
static Matrix matrix = {
1, 0, 0, 0, //
0, 1, 0, 0, //
0, 0, 1, 0, //
0, 0, 0, 1 //
};
std::string label = "##1";
label.c_str();
for (int i = 0; i < 4; i++) {
ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float, &(matrix.vec[i]),
4, NULL, NULL, "%.2f", 0);
label[2]++;
}
ImGui::End();
Canvas canvas;
Paint paint;
canvas.Translate({100.0, 100.0, 0});
auto tile_mode = tile_modes[selected_tile_mode];
paint.color_source = [tile_mode]() {
auto contents = std::make_shared<RadialGradientContents>();
contents->SetCenterAndRadius({50, 50}, 50);
contents->SetCenterAndRadius({100, 100}, 100);
std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
Color{0.1294, 0.5882, 0.9529, 1.0}};
contents->SetColors(std::move(colors));
contents->SetTileMode(tile_mode);
contents->SetMatrix(matrix);
return contents;
};
canvas.DrawRect({0, 0, 200, 200}, paint);
canvas.Restore();
}
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
canvas.DrawRect({0, 0, 600, 600}, paint);
return renderer.Render(canvas.EndRecordingAsPicture(), render_target);
};
ASSERT_TRUE(OpenPlaygroundHere(callback));
}
TEST_P(AiksTest, CanRenderSweepGradient) {
Canvas canvas;
Paint paint;
std::vector<Vector3> offsets = {
{0, 0, 0}, {0, 300, 0}, {300, 0, 0}, {300, 300, 0}};
std::vector<Entity::TileMode> tile_modes = {
Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
Entity::TileMode::kMirror, Entity::TileMode::kDecal};
for (int i = 0; i < 4; i++) {
canvas.Save();
canvas.Translate(offsets[i]);
Entity::TileMode tile_mode = tile_modes[i];
bool first_frame = true;
auto callback = [&](AiksContext& renderer, RenderTarget& render_target) {
if (first_frame) {
first_frame = false;
ImGui::SetNextWindowSize({480, 100});
ImGui::SetNextWindowPos({100, 550});
}
const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
const Entity::TileMode tile_modes[] = {
Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
Entity::TileMode::kMirror, Entity::TileMode::kDecal};
static int selected_tile_mode = 0;
ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
sizeof(tile_mode_names) / sizeof(char*));
static Matrix matrix = {
1, 0, 0, 0, //
0, 1, 0, 0, //
0, 0, 1, 0, //
0, 0, 0, 1 //
};
std::string label = "##1";
label.c_str();
for (int i = 0; i < 4; i++) {
ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float, &(matrix.vec[i]),
4, NULL, NULL, "%.2f", 0);
label[2]++;
}
ImGui::End();
Canvas canvas;
Paint paint;
canvas.Translate({100.0, 100.0, 0});
auto tile_mode = tile_modes[selected_tile_mode];
paint.color_source = [tile_mode]() {
auto contents = std::make_shared<SweepGradientContents>();
contents->SetCenterAndAngles({50, 50}, Degrees(45), Degrees(135));
contents->SetCenterAndAngles({100, 100}, Degrees(45), Degrees(135));
std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
Color{0.1294, 0.5882, 0.9529, 1.0}};
contents->SetColors(std::move(colors));
contents->SetTileMode(tile_mode);
contents->SetMatrix(matrix);
return contents;
};
canvas.DrawRect({0, 0, 200, 200}, paint);
canvas.Restore();
}
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
canvas.DrawRect({0, 0, 600, 600}, paint);
return renderer.Render(canvas.EndRecordingAsPicture(), render_target);
};
ASSERT_TRUE(OpenPlaygroundHere(callback));
}
TEST_P(AiksTest, CanRenderDifferentShapesWithSameColorSource) {

View File

@ -25,7 +25,7 @@ struct Paint {
using MaskFilterProc =
std::function<std::shared_ptr<FilterContents>(FilterInput::Ref,
bool is_solid_color)>;
using ColorSourceProc = std::function<std::shared_ptr<PathContents>()>;
using ColorSourceProc = std::function<std::shared_ptr<ColorSourceContents>()>;
enum class Style {
kFill,

View File

@ -0,0 +1,14 @@
// 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.
#ifndef TRANSFORM_GLSL_
#define TRANSFORM_GLSL_
/// Returns the Cartesian coordinates of `position` in `transform` space.
vec2 IPVec2TransformPosition(mat4 matrix, vec2 point) {
vec4 transformed = matrix * vec4(point, 0, 1);
return transformed.xy / transformed.w;
}
#endif

View File

@ -161,6 +161,17 @@ static impeller::SamplerDescriptor ToSamplerDescriptor(
return desc;
}
static Matrix ToMatrix(const SkMatrix& m) {
return Matrix{
// clang-format off
m[0], m[3], 0, m[6],
m[1], m[4], 0, m[7],
0, 0, 1, 0,
m[2], m[5], 0, m[8],
// clang-format on
};
}
// |flutter::Dispatcher|
void DisplayListDispatcher::setAntiAlias(bool aa) {
// Nothing to do because AA is implicit.
@ -305,12 +316,14 @@ void DisplayListDispatcher::setColorSource(
colors.emplace_back(ToColor(linear->colors()[i]));
}
auto tile_mode = ToTileMode(linear->tile_mode());
auto matrix = ToMatrix(linear->matrix());
paint_.color_source = [start_point, end_point, colors = std::move(colors),
tile_mode]() {
tile_mode, matrix]() {
auto contents = std::make_shared<LinearGradientContents>();
contents->SetEndPoints(start_point, end_point);
contents->SetColors(std::move(colors));
contents->SetTileMode(tile_mode);
contents->SetMatrix(matrix);
return contents;
};
return;
@ -326,12 +339,14 @@ void DisplayListDispatcher::setColorSource(
colors.emplace_back(ToColor(radialGradient->colors()[i]));
}
auto tile_mode = ToTileMode(radialGradient->tile_mode());
auto matrix = ToMatrix(radialGradient->matrix());
paint_.color_source = [center, radius, colors = std::move(colors),
tile_mode]() {
tile_mode, matrix]() {
auto contents = std::make_shared<RadialGradientContents>();
contents->SetCenterAndRadius(center, radius),
contents->SetColors(std::move(colors));
contents->SetCenterAndRadius(center, radius);
contents->SetColors(std::move(colors));
contents->SetTileMode(tile_mode);
contents->SetMatrix(matrix);
return contents;
};
return;
@ -349,12 +364,14 @@ void DisplayListDispatcher::setColorSource(
colors.emplace_back(ToColor(sweepGradient->colors()[i]));
}
auto tile_mode = ToTileMode(sweepGradient->tile_mode());
auto matrix = ToMatrix(sweepGradient->matrix());
paint_.color_source = [center, start_angle, end_angle,
colors = std::move(colors), tile_mode]() {
colors = std::move(colors), tile_mode, matrix]() {
auto contents = std::make_shared<SweepGradientContents>();
contents->SetCenterAndAngles(center, start_angle, end_angle);
contents->SetColors(std::move(colors));
contents->SetTileMode(tile_mode);
contents->SetMatrix(matrix);
return contents;
};
return;
@ -367,12 +384,14 @@ void DisplayListDispatcher::setColorSource(
auto x_tile_mode = ToTileMode(image_color_source->horizontal_tile_mode());
auto y_tile_mode = ToTileMode(image_color_source->vertical_tile_mode());
auto desc = ToSamplerDescriptor(image_color_source->sampling());
paint_.color_source = [texture, x_tile_mode, y_tile_mode, desc]() {
auto matrix = ToMatrix(image_color_source->matrix());
paint_.color_source = [texture, x_tile_mode, y_tile_mode, desc,
matrix]() {
auto contents = std::make_shared<TiledTextureContents>();
contents->SetTexture(texture);
contents->SetTileModes(x_tile_mode, y_tile_mode);
contents->SetSamplerDescriptor(desc);
// TODO(109384) Support 'matrix' parameter for all color sources.
contents->SetMatrix(matrix);
return contents;
};
return;

View File

@ -36,10 +36,9 @@ impeller_shaders("entity_shaders") {
"shaders/gaussian_blur.vert",
"shaders/glyph_atlas.frag",
"shaders/glyph_atlas.vert",
"shaders/gradient_fill.frag",
"shaders/gradient_fill.vert",
"shaders/linear_gradient_fill.frag",
"shaders/radial_gradient_fill.frag",
"shaders/radial_gradient_fill.vert",
"shaders/rrect_blur.vert",
"shaders/rrect_blur.frag",
"shaders/solid_fill.frag",
@ -47,7 +46,6 @@ impeller_shaders("entity_shaders") {
"shaders/solid_stroke.frag",
"shaders/solid_stroke.vert",
"shaders/sweep_gradient_fill.frag",
"shaders/sweep_gradient_fill.vert",
"shaders/texture_fill.frag",
"shaders/texture_fill.vert",
"shaders/tiled_texture_fill.frag",
@ -63,6 +61,8 @@ impeller_component("entity") {
"contents/atlas_contents.h",
"contents/clip_contents.cc",
"contents/clip_contents.h",
"contents/color_source_contents.cc",
"contents/color_source_contents.h",
"contents/content_context.cc",
"contents/content_context.h",
"contents/contents.cc",
@ -87,8 +87,6 @@ impeller_component("entity") {
"contents/filters/inputs/texture_filter_input.h",
"contents/linear_gradient_contents.cc",
"contents/linear_gradient_contents.h",
"contents/path_contents.cc",
"contents/path_contents.h",
"contents/radial_gradient_contents.cc",
"contents/radial_gradient_contents.h",
"contents/rrect_shadow_contents.cc",

View File

@ -0,0 +1,37 @@
// 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 "color_source_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/geometry/matrix.h"
namespace impeller {
ColorSourceContents::ColorSourceContents() = default;
ColorSourceContents::~ColorSourceContents() = default;
void ColorSourceContents::SetPath(Path path) {
path_ = path;
}
const Path& ColorSourceContents::GetPath() const {
return path_;
}
void ColorSourceContents::SetMatrix(Matrix matrix) {
inverse_matrix_ = matrix.Invert();
}
const Matrix& ColorSourceContents::GetInverseMatrix() const {
return inverse_matrix_;
}
std::optional<Rect> ColorSourceContents::GetCoverage(
const Entity& entity) const {
return path_.GetTransformedBoundingBox(entity.GetTransformation());
};
} // namespace impeller

View File

@ -0,0 +1,39 @@
// 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.
#pragma once
#include "flutter/fml/macros.h"
#include "impeller/entity/contents/contents.h"
#include "impeller/geometry/matrix.h"
#include "impeller/geometry/path.h"
namespace impeller {
class ColorSourceContents : public Contents {
public:
ColorSourceContents();
~ColorSourceContents() override;
void SetPath(Path path);
void SetMatrix(Matrix matrix);
// |Contents|
std::optional<Rect> GetCoverage(const Entity& entity) const override;
protected:
const Path& GetPath() const;
const Matrix& GetInverseMatrix() const;
private:
Path path_;
Matrix inverse_matrix_;
FML_DISALLOW_COPY_AND_ASSIGN(ColorSourceContents);
};
} // namespace impeller

View File

@ -149,10 +149,10 @@ ContentContext::ContentContext(std::shared_ptr<Context> context)
return;
}
gradient_fill_pipelines_[{}] =
CreateDefaultPipeline<GradientFillPipeline>(*context_);
solid_fill_pipelines_[{}] =
CreateDefaultPipeline<SolidFillPipeline>(*context_);
linear_gradient_fill_pipelines_[{}] =
CreateDefaultPipeline<LinearGradientFillPipeline>(*context_);
radial_gradient_fill_pipelines_[{}] =
CreateDefaultPipeline<RadialGradientFillPipeline>(*context_);
sweep_gradient_fill_pipelines_[{}] =

View File

@ -40,10 +40,9 @@
#include "impeller/entity/gaussian_blur.vert.h"
#include "impeller/entity/glyph_atlas.frag.h"
#include "impeller/entity/glyph_atlas.vert.h"
#include "impeller/entity/gradient_fill.frag.h"
#include "impeller/entity/gradient_fill.vert.h"
#include "impeller/entity/linear_gradient_fill.frag.h"
#include "impeller/entity/radial_gradient_fill.frag.h"
#include "impeller/entity/radial_gradient_fill.vert.h"
#include "impeller/entity/rrect_blur.frag.h"
#include "impeller/entity/rrect_blur.vert.h"
#include "impeller/entity/solid_fill.frag.h"
@ -51,7 +50,6 @@
#include "impeller/entity/solid_stroke.frag.h"
#include "impeller/entity/solid_stroke.vert.h"
#include "impeller/entity/sweep_gradient_fill.frag.h"
#include "impeller/entity/sweep_gradient_fill.vert.h"
#include "impeller/entity/texture_fill.frag.h"
#include "impeller/entity/texture_fill.vert.h"
#include "impeller/entity/tiled_texture_fill.frag.h"
@ -62,14 +60,14 @@
namespace impeller {
using GradientFillPipeline =
PipelineT<GradientFillVertexShader, GradientFillFragmentShader>;
using LinearGradientFillPipeline =
PipelineT<GradientFillVertexShader, LinearGradientFillFragmentShader>;
using SolidFillPipeline =
PipelineT<SolidFillVertexShader, SolidFillFragmentShader>;
using RadialGradientFillPipeline =
PipelineT<RadialGradientFillVertexShader, RadialGradientFillFragmentShader>;
PipelineT<GradientFillVertexShader, RadialGradientFillFragmentShader>;
using SweepGradientFillPipeline =
PipelineT<SweepGradientFillVertexShader, SweepGradientFillFragmentShader>;
PipelineT<GradientFillVertexShader, SweepGradientFillFragmentShader>;
using BlendPipeline = PipelineT<BlendVertexShader, BlendFragmentShader>;
using RRectBlurPipeline =
PipelineT<RrectBlurVertexShader, RrectBlurFragmentShader>;
@ -160,9 +158,9 @@ class ContentContext {
bool IsValid() const;
std::shared_ptr<Pipeline> GetGradientFillPipeline(
std::shared_ptr<Pipeline> GetLinearGradientFillPipeline(
ContentContextOptions opts) const {
return GetPipeline(gradient_fill_pipelines_, opts);
return GetPipeline(linear_gradient_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline> GetRadialGradientFillPipeline(
@ -335,8 +333,8 @@ class ContentContext {
// These are mutable because while the prototypes are created eagerly, any
// variants requested from that are lazily created and cached in the variants
// map.
mutable Variants<GradientFillPipeline> gradient_fill_pipelines_;
mutable Variants<SolidFillPipeline> solid_fill_pipelines_;
mutable Variants<LinearGradientFillPipeline> linear_gradient_fill_pipelines_;
mutable Variants<RadialGradientFillPipeline> radial_gradient_fill_pipelines_;
mutable Variants<SweepGradientFillPipeline> sweep_gradient_fill_pipelines_;
mutable Variants<RRectBlurPipeline> rrect_blur_pipelines_;

View File

@ -16,10 +16,6 @@ LinearGradientContents::LinearGradientContents() = default;
LinearGradientContents::~LinearGradientContents() = default;
void LinearGradientContents::SetPath(Path path) {
path_ = std::move(path);
}
void LinearGradientContents::SetEndPoints(Point start_point, Point end_point) {
start_point_ = start_point;
end_point_ = end_point;
@ -43,26 +39,21 @@ const std::vector<Color>& LinearGradientContents::GetColors() const {
return colors_;
}
std::optional<Rect> LinearGradientContents::GetCoverage(
const Entity& entity) const {
return path_.GetTransformedBoundingBox(entity.GetTransformation());
};
bool LinearGradientContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
using VS = GradientFillPipeline::VertexShader;
using FS = GradientFillPipeline::FragmentShader;
using VS = LinearGradientFillPipeline::VertexShader;
using FS = LinearGradientFillPipeline::FragmentShader;
auto vertices_builder = VertexBufferBuilder<VS::PerVertexData>();
{
auto result =
Tessellator{}.Tessellate(path_.GetFillType(), path_.CreatePolyline(),
[&vertices_builder](Point point) {
VS::PerVertexData vtx;
vtx.vertices = point;
vertices_builder.AppendVertex(vtx);
});
auto result = Tessellator{}.Tessellate(GetPath().GetFillType(),
GetPath().CreatePolyline(),
[&vertices_builder](Point point) {
VS::PerVertexData vtx;
vtx.position = point;
vertices_builder.AppendVertex(vtx);
});
if (result == Tessellator::Result::kInputError) {
return true;
@ -75,6 +66,7 @@ bool LinearGradientContents::Render(const ContentContext& renderer,
VS::FrameInfo frame_info;
frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
entity.GetTransformation();
frame_info.matrix = GetInverseMatrix();
FS::GradientInfo gradient_info;
gradient_info.start_point = start_point_;
@ -85,8 +77,8 @@ bool LinearGradientContents::Render(const ContentContext& renderer,
Command cmd;
cmd.label = "LinearGradientFill";
cmd.pipeline =
renderer.GetGradientFillPipeline(OptionsFromPassAndEntity(pass, entity));
cmd.pipeline = renderer.GetLinearGradientFillPipeline(
OptionsFromPassAndEntity(pass, entity));
cmd.stencil_reference = entity.GetStencilDepth();
cmd.BindVertices(
vertices_builder.CreateVertexBuffer(pass.GetTransientsBuffer()));

View File

@ -9,7 +9,7 @@
#include <vector>
#include "flutter/fml/macros.h"
#include "impeller/entity/contents/path_contents.h"
#include "impeller/entity/contents/color_source_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/path.h"
@ -17,17 +17,12 @@
namespace impeller {
class LinearGradientContents final : public PathContents {
class LinearGradientContents final : public ColorSourceContents {
public:
LinearGradientContents();
~LinearGradientContents() override;
void SetPath(Path path) override;
// |Contents|
std::optional<Rect> GetCoverage(const Entity& entity) const override;
// |Contents|
bool Render(const ContentContext& renderer,
const Entity& entity,
@ -42,7 +37,6 @@ class LinearGradientContents final : public PathContents {
const std::vector<Color>& GetColors() const;
private:
Path path_;
Point start_point_;
Point end_point_;
std::vector<Color> colors_;

View File

@ -1,13 +0,0 @@
// 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 "path_contents.h"
namespace impeller {
PathContents::PathContents() = default;
PathContents::~PathContents() = default;
} // namespace impeller

View File

@ -1,24 +0,0 @@
// 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.
#pragma once
#include "flutter/fml/macros.h"
#include "impeller/entity/contents/contents.h"
#include "impeller/geometry/path.h"
namespace impeller {
class PathContents : public Contents {
public:
PathContents();
~PathContents() override;
virtual void SetPath(Path path) = 0;
FML_DISALLOW_COPY_AND_ASSIGN(PathContents);
};
} // namespace impeller

View File

@ -16,10 +16,6 @@ RadialGradientContents::RadialGradientContents() = default;
RadialGradientContents::~RadialGradientContents() = default;
void RadialGradientContents::SetPath(Path path) {
path_ = std::move(path);
}
void RadialGradientContents::SetCenterAndRadius(Point center, Scalar radius) {
center_ = center;
radius_ = radius;
@ -43,11 +39,6 @@ const std::vector<Color>& RadialGradientContents::GetColors() const {
return colors_;
}
std::optional<Rect> RadialGradientContents::GetCoverage(
const Entity& entity) const {
return path_.GetTransformedBoundingBox(entity.GetTransformation());
};
bool RadialGradientContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
@ -56,13 +47,13 @@ bool RadialGradientContents::Render(const ContentContext& renderer,
auto vertices_builder = VertexBufferBuilder<VS::PerVertexData>();
{
auto result =
Tessellator{}.Tessellate(path_.GetFillType(), path_.CreatePolyline(),
[&vertices_builder](Point point) {
VS::PerVertexData vtx;
vtx.vertices = point;
vertices_builder.AppendVertex(vtx);
});
auto result = Tessellator{}.Tessellate(GetPath().GetFillType(),
GetPath().CreatePolyline(),
[&vertices_builder](Point point) {
VS::PerVertexData vtx;
vtx.position = point;
vertices_builder.AppendVertex(vtx);
});
if (result == Tessellator::Result::kInputError) {
return true;
@ -75,6 +66,7 @@ bool RadialGradientContents::Render(const ContentContext& renderer,
VS::FrameInfo frame_info;
frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
entity.GetTransformation();
frame_info.matrix = GetInverseMatrix();
FS::GradientInfo gradient_info;
gradient_info.center = center_;

View File

@ -9,7 +9,7 @@
#include <vector>
#include "flutter/fml/macros.h"
#include "impeller/entity/contents/path_contents.h"
#include "impeller/entity/contents/color_source_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/path.h"
@ -17,17 +17,12 @@
namespace impeller {
class RadialGradientContents final : public PathContents {
class RadialGradientContents final : public ColorSourceContents {
public:
RadialGradientContents();
~RadialGradientContents() override;
void SetPath(Path path) override;
// |Contents|
std::optional<Rect> GetCoverage(const Entity& entity) const override;
// |Contents|
bool Render(const ContentContext& renderer,
const Entity& entity,
@ -42,7 +37,6 @@ class RadialGradientContents final : public PathContents {
const std::vector<Color>& GetColors() const;
private:
Path path_;
Point center_;
Scalar radius_;
std::vector<Color> colors_;

View File

@ -16,10 +16,6 @@ SweepGradientContents::SweepGradientContents() = default;
SweepGradientContents::~SweepGradientContents() = default;
void SweepGradientContents::SetPath(Path path) {
path_ = std::move(path);
}
void SweepGradientContents::SetCenterAndAngles(Point center,
Degrees start_angle,
Degrees end_angle) {
@ -49,11 +45,6 @@ const std::vector<Color>& SweepGradientContents::GetColors() const {
return colors_;
}
std::optional<Rect> SweepGradientContents::GetCoverage(
const Entity& entity) const {
return path_.GetTransformedBoundingBox(entity.GetTransformation());
};
bool SweepGradientContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
@ -62,13 +53,13 @@ bool SweepGradientContents::Render(const ContentContext& renderer,
auto vertices_builder = VertexBufferBuilder<VS::PerVertexData>();
{
auto result =
Tessellator{}.Tessellate(path_.GetFillType(), path_.CreatePolyline(),
[&vertices_builder](Point point) {
VS::PerVertexData vtx;
vtx.vertices = point;
vertices_builder.AppendVertex(vtx);
});
auto result = Tessellator{}.Tessellate(GetPath().GetFillType(),
GetPath().CreatePolyline(),
[&vertices_builder](Point point) {
VS::PerVertexData vtx;
vtx.position = point;
vertices_builder.AppendVertex(vtx);
});
if (result == Tessellator::Result::kInputError) {
return true;
@ -81,6 +72,7 @@ bool SweepGradientContents::Render(const ContentContext& renderer,
VS::FrameInfo frame_info;
frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
entity.GetTransformation();
frame_info.matrix = GetInverseMatrix();
FS::GradientInfo gradient_info;
gradient_info.center = center_;

View File

@ -9,7 +9,7 @@
#include <vector>
#include "flutter/fml/macros.h"
#include "impeller/entity/contents/path_contents.h"
#include "impeller/entity/contents/color_source_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/path.h"
@ -18,17 +18,12 @@
namespace impeller {
class SweepGradientContents final : public PathContents {
class SweepGradientContents final : public ColorSourceContents {
public:
SweepGradientContents();
~SweepGradientContents() override;
void SetPath(Path path) override;
// |Contents|
std::optional<Rect> GetCoverage(const Entity& entity) const override;
// |Contents|
bool Render(const ContentContext& renderer,
const Entity& entity,
@ -43,7 +38,6 @@ class SweepGradientContents final : public PathContents {
const std::vector<Color>& GetColors() const;
private:
Path path_;
Point center_;
Scalar bias_;
Scalar scale_;

View File

@ -17,10 +17,6 @@ TiledTextureContents::TiledTextureContents() = default;
TiledTextureContents::~TiledTextureContents() = default;
void TiledTextureContents::SetPath(Path path) {
path_ = std::move(path);
}
void TiledTextureContents::SetTexture(std::shared_ptr<Texture> texture) {
texture_ = std::move(texture);
}
@ -35,11 +31,6 @@ void TiledTextureContents::SetSamplerDescriptor(SamplerDescriptor desc) {
sampler_descriptor_ = std::move(desc);
}
std::optional<Rect> TiledTextureContents::GetCoverage(
const Entity& entity) const {
return path_.GetTransformedBoundingBox(entity.GetTransformation());
};
bool TiledTextureContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
@ -50,7 +41,7 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
using VS = TiledTextureFillVertexShader;
using FS = TiledTextureFillFragmentShader;
const auto coverage_rect = path_.GetBoundingBox();
const auto coverage_rect = GetPath().GetBoundingBox();
if (!coverage_rect.has_value()) {
return true;
@ -67,14 +58,13 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
{
const auto tess_result =
Tessellator{}.Tessellate(path_.GetFillType(), path_.CreatePolyline(),
[&vertex_builder, &texture_size](Point vtx) {
VS::PerVertexData data;
data.position = vtx;
data.texture_coords = vtx / texture_size;
vertex_builder.AppendVertex(data);
});
const auto tess_result = Tessellator{}.Tessellate(
GetPath().GetFillType(), GetPath().CreatePolyline(),
[&vertex_builder](Point vtx) {
VS::PerVertexData data;
data.position = vtx;
vertex_builder.AppendVertex(data);
});
if (tess_result == Tessellator::Result::kInputError) {
return true;
@ -93,6 +83,9 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
VS::VertInfo vert_info;
vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
entity.GetTransformation();
vert_info.matrix = GetInverseMatrix();
vert_info.texture_size = Vector2{static_cast<Scalar>(texture_size.width),
static_cast<Scalar>(texture_size.height)};
FS::FragInfo frag_info;
frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();

View File

@ -9,24 +9,19 @@
#include <vector>
#include "flutter/fml/macros.h"
#include "impeller/entity/contents/path_contents.h"
#include "impeller/entity/contents/color_source_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/geometry/path.h"
#include "impeller/renderer/sampler_descriptor.h"
namespace impeller {
class TiledTextureContents final : public PathContents {
class TiledTextureContents final : public ColorSourceContents {
public:
TiledTextureContents();
~TiledTextureContents() override;
void SetPath(Path path) override;
// |Contents|
std::optional<Rect> GetCoverage(const Entity& entity) const override;
// |Contents|
bool Render(const ContentContext& renderer,
const Entity& entity,
@ -39,7 +34,6 @@ class TiledTextureContents final : public PathContents {
void SetSamplerDescriptor(SamplerDescriptor desc);
private:
Path path_;
std::shared_ptr<Texture> texture_;
SamplerDescriptor sampler_descriptor_ = {};
Entity::TileMode x_tile_mode_;

View File

@ -2,15 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <impeller/transform.glsl>
uniform FrameInfo {
mat4 mvp;
mat4 matrix;
} frame_info;
in vec2 vertices;
in vec2 position;
out vec2 interpolated_vertices;
out vec2 v_position;
void main() {
gl_Position = frame_info.mvp * vec4(vertices, 0.0, 1.0);
interpolated_vertices = vertices;
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
v_position = IPVec2TransformPosition(frame_info.matrix, position);
}

View File

@ -12,14 +12,14 @@ uniform GradientInfo {
float tile_mode;
} gradient_info;
in vec2 interpolated_vertices;
in vec2 v_position;
out vec4 frag_color;
void main() {
float len = length(gradient_info.end_point - gradient_info.start_point);
float dot = dot(
interpolated_vertices - gradient_info.start_point,
v_position - gradient_info.start_point,
gradient_info.end_point - gradient_info.start_point
);
float t = dot / (len * len);

View File

@ -12,12 +12,12 @@ uniform GradientInfo {
float tile_mode;
} gradient_info;
in vec2 interpolated_vertices;
in vec2 v_position;
out vec4 frag_color;
void main() {
float len = length(interpolated_vertices - gradient_info.center);
float len = length(v_position - gradient_info.center);
float t = len / gradient_info.radius;
if ((t < 0.0 || t > 1.0) && gradient_info.tile_mode == kTileModeDecal) {
frag_color = vec4(0);

View File

@ -1,16 +0,0 @@
// 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.
uniform FrameInfo {
mat4 mvp;
} frame_info;
in vec2 vertices;
out vec2 interpolated_vertices;
void main() {
gl_Position = frame_info.mvp * vec4(vertices, 0.0, 1.0);
interpolated_vertices = vertices;
}

View File

@ -14,12 +14,12 @@ uniform GradientInfo {
float tile_mode;
} gradient_info;
in vec2 interpolated_vertices;
in vec2 v_position;
out vec4 frag_color;
void main() {
vec2 coord = interpolated_vertices - gradient_info.center;
vec2 coord = v_position - gradient_info.center;
float angle = atan(-coord.y, -coord.x);
float t = (angle * k1Over2Pi + 0.5 + gradient_info.bias) * gradient_info.scale;

View File

@ -1,16 +0,0 @@
// 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.
uniform FrameInfo {
mat4 mvp;
} frame_info;
in vec2 vertices;
out vec2 interpolated_vertices;
void main() {
gl_Position = frame_info.mvp * vec4(vertices, 0.0, 1.0);
interpolated_vertices = vertices;
}

View File

@ -2,17 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <impeller/transform.glsl>
uniform VertInfo {
mat4 mvp;
mat4 matrix;
vec2 texture_size;
}
vert_info;
in vec2 position;
in vec2 texture_coords;
out vec2 v_texture_coords;
void main() {
gl_Position = vert_info.mvp * vec4(position, 0.0, 1.0);
v_texture_coords = texture_coords;
vec2 transformed = IPVec2TransformPosition(vert_info.matrix, position);
v_texture_coords = transformed / vert_info.texture_size;
}