Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
317 changes: 154 additions & 163 deletions impeller/display_list/canvas.cc

Large diffs are not rendered by default.

33 changes: 13 additions & 20 deletions impeller/display_list/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,23 +197,6 @@ class Canvas {
SamplerDescriptor sampler = {},
SourceRectConstraint src_rect_constraint = SourceRectConstraint::kFast);

void ClipPath(
const Path& path,
Entity::ClipOperation clip_op = Entity::ClipOperation::kIntersect);

void ClipRect(
const Rect& rect,
Entity::ClipOperation clip_op = Entity::ClipOperation::kIntersect);

void ClipOval(
const Rect& bounds,
Entity::ClipOperation clip_op = Entity::ClipOperation::kIntersect);

void ClipRRect(
const Rect& rect,
const Size& corner_radii,
Entity::ClipOperation clip_op = Entity::ClipOperation::kIntersect);

void DrawTextFrame(const std::shared_ptr<TextFrame>& text_frame,
Point position,
const Paint& paint);
Expand All @@ -225,6 +208,9 @@ class Canvas {
void DrawAtlas(const std::shared_ptr<AtlasContents>& atlas_contents,
const Paint& paint);

void ClipGeometry(std::unique_ptr<Geometry> geometry,
Entity::ClipOperation clip_op);

void EndReplay();

uint64_t GetOpDepth() const { return current_depth_; }
Expand All @@ -247,6 +233,11 @@ class Canvas {
std::vector<LazyRenderingConfig> render_passes_;
std::vector<SaveLayerState> save_layer_state_;

// All geometry objects created for regular draws can be stack allocated,
// but clip geometries must be cached for record/replay for backdrop filters
// and so must be kept alive longer.
std::vector<std::unique_ptr<Geometry>> clip_geometry_;

uint64_t current_depth_ = 0u;

Point GetGlobalPassPosition() const;
Expand All @@ -271,13 +262,15 @@ class Canvas {

void Reset();

void AddRenderEntityWithFiltersToCurrentPass(Entity& entity,
const Geometry* geometry,
const Paint& paint,
bool reuse_depth = false);

void AddRenderEntityToCurrentPass(Entity& entity, bool reuse_depth = false);

void AddClipEntityToCurrentPass(Entity& entity);

void ClipGeometry(const std::shared_ptr<Geometry>& geometry,
Entity::ClipOperation clip_op);

void RestoreClip();

bool AttemptDrawBlurredRRect(const Rect& rect,
Expand Down
37 changes: 23 additions & 14 deletions impeller/display_list/dl_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "impeller/entity/contents/filters/filter_contents.h"
#include "impeller/entity/contents/filters/inputs/filter_input.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/geometry/geometry.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/path.h"
#include "impeller/geometry/path_builder.h"
Expand Down Expand Up @@ -430,7 +431,7 @@ void DlDispatcherBase::clipRect(const DlRect& rect,
bool is_aa) {
AUTO_DEPTH_WATCHER(0u);

GetCanvas().ClipRect(rect, ToClipOperation(clip_op));
GetCanvas().ClipGeometry(Geometry::MakeRect(rect), ToClipOperation(clip_op));
}

// |flutter::DlOpReceiver|
Expand All @@ -439,7 +440,8 @@ void DlDispatcherBase::clipOval(const DlRect& bounds,
bool is_aa) {
AUTO_DEPTH_WATCHER(0u);

GetCanvas().ClipOval(bounds, ToClipOperation(clip_op));
GetCanvas().ClipGeometry(Geometry::MakeOval(bounds),
ToClipOperation(clip_op));
}

// |flutter::DlOpReceiver|
Expand All @@ -450,15 +452,20 @@ void DlDispatcherBase::clipRRect(const SkRRect& rrect,

auto clip_op = ToClipOperation(sk_op);
if (rrect.isRect()) {
GetCanvas().ClipRect(skia_conversions::ToRect(rrect.rect()), clip_op);
GetCanvas().ClipGeometry(
Geometry::MakeRect(skia_conversions::ToRect(rrect.rect())), clip_op);
} else if (rrect.isOval()) {
GetCanvas().ClipOval(skia_conversions::ToRect(rrect.rect()), clip_op);
GetCanvas().ClipGeometry(
Geometry::MakeOval(skia_conversions::ToRect(rrect.rect())), clip_op);
} else if (rrect.isSimple()) {
GetCanvas().ClipRRect(skia_conversions::ToRect(rrect.rect()),
skia_conversions::ToSize(rrect.getSimpleRadii()),
clip_op);
GetCanvas().ClipGeometry(
Geometry::MakeRoundRect(
skia_conversions::ToRect(rrect.rect()),
skia_conversions::ToSize(rrect.getSimpleRadii())),
clip_op);
} else {
GetCanvas().ClipPath(skia_conversions::ToPath(rrect), clip_op);
GetCanvas().ClipGeometry(
Geometry::MakeFillPath(skia_conversions::ToPath(rrect)), clip_op);
}
}

Expand All @@ -470,17 +477,19 @@ void DlDispatcherBase::clipPath(const DlPath& path, ClipOp sk_op, bool is_aa) {

DlRect rect;
if (path.IsRect(&rect)) {
GetCanvas().ClipRect(rect, clip_op);
GetCanvas().ClipGeometry(Geometry::MakeRect(rect), clip_op);
} else if (path.IsOval(&rect)) {
GetCanvas().ClipOval(rect, clip_op);
GetCanvas().ClipGeometry(Geometry::MakeOval(rect), clip_op);
} else {
SkRRect rrect;
if (path.IsSkRRect(&rrect) && rrect.isSimple()) {
GetCanvas().ClipRRect(skia_conversions::ToRect(rrect.rect()),
skia_conversions::ToSize(rrect.getSimpleRadii()),
clip_op);
GetCanvas().ClipGeometry(
Geometry::MakeRoundRect(
skia_conversions::ToRect(rrect.rect()),
skia_conversions::ToSize(rrect.getSimpleRadii())),
clip_op);
} else {
GetCanvas().ClipPath(path.GetPath(), clip_op);
GetCanvas().ClipGeometry(Geometry::MakeFillPath(path.GetPath()), clip_op);
}
}
}
Expand Down
16 changes: 10 additions & 6 deletions impeller/display_list/paint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "impeller/entity/contents/sweep_gradient_contents.h"
#include "impeller/entity/contents/tiled_texture_contents.h"
#include "impeller/entity/geometry/geometry.h"
#include "impeller/entity/geometry/rect_geometry.h"

namespace impeller {

Expand Down Expand Up @@ -340,19 +341,21 @@ std::shared_ptr<Contents> Paint::WithColorFilter(
}

std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
std::shared_ptr<TextureContents> texture_contents) const {
std::shared_ptr<TextureContents> texture_contents,
RectGeometry* rect_geom) const {
Scalar expand_amount = GaussianBlurFilterContents::CalculateBlurRadius(
GaussianBlurFilterContents::ScaleSigma(sigma.sigma));
texture_contents->SetSourceRect(
texture_contents->GetSourceRect().Expand(expand_amount, expand_amount));
auto mask = std::make_shared<SolidColorContents>();
mask->SetColor(Color::White());
std::optional<Rect> coverage = texture_contents->GetCoverage({});
std::shared_ptr<Geometry> geometry;
Geometry* geometry = nullptr;
if (coverage) {
texture_contents->SetDestinationRect(
coverage.value().Expand(expand_amount, expand_amount));
geometry = Geometry::MakeRect(coverage.value());
*rect_geom = RectGeometry(coverage.value());
geometry = rect_geom;
}
mask->SetGeometry(geometry);
auto descriptor = texture_contents->GetSamplerDescriptor();
Expand All @@ -370,7 +373,8 @@ std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
std::shared_ptr<ColorSourceContents> color_source_contents,
const flutter::DlColorFilter* color_filter,
bool invert_colors) const {
bool invert_colors,
RectGeometry* rect_geom) const {
// If it's a solid color then we can just get away with doing one Gaussian
// blur. The color filter will always be applied on the CPU.
if (color_source_contents->IsSolidColor()) {
Expand Down Expand Up @@ -399,8 +403,8 @@ std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
if (!expanded_local_bounds.has_value()) {
expanded_local_bounds = Rect();
}
color_source_contents->SetGeometry(
Geometry::MakeRect(*expanded_local_bounds));
*rect_geom = RectGeometry(expanded_local_bounds.value());
color_source_contents->SetGeometry(rect_geom);
std::shared_ptr<Contents> color_contents = color_source_contents;

/// 4. Apply the user set color filter on the GPU, if applicable.
Expand Down
6 changes: 4 additions & 2 deletions impeller/display_list/paint.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ struct Paint {
std::shared_ptr<FilterContents> CreateMaskBlur(
std::shared_ptr<ColorSourceContents> color_source_contents,
const flutter::DlColorFilter* color_filter,
bool invert_colors) const;
bool invert_colors,
RectGeometry* rect_geom) const;

std::shared_ptr<FilterContents> CreateMaskBlur(
std::shared_ptr<TextureContents> texture_contents) const;
std::shared_ptr<TextureContents> texture_contents,
RectGeometry* rect_geom) const;

std::shared_ptr<FilterContents> CreateMaskBlur(
const FilterInput::Ref& input,
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/clip_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ ClipContents::ClipContents() = default;

ClipContents::~ClipContents() = default;

void ClipContents::SetGeometry(const std::shared_ptr<Geometry>& geometry) {
void ClipContents::SetGeometry(const Geometry* geometry) {
geometry_ = geometry;
}

Expand Down
8 changes: 2 additions & 6 deletions impeller/entity/contents/clip_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
#ifndef FLUTTER_IMPELLER_ENTITY_CONTENTS_CLIP_CONTENTS_H_
#define FLUTTER_IMPELLER_ENTITY_CONTENTS_CLIP_CONTENTS_H_

#include <functional>
#include <memory>
#include <vector>

#include "impeller/entity/contents/contents.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/geometry/geometry.h"
Expand All @@ -21,7 +17,7 @@ class ClipContents final : public Contents {

~ClipContents();

void SetGeometry(const std::shared_ptr<Geometry>& geometry);
void SetGeometry(const Geometry* geometry);

void SetClipOperation(Entity::ClipOperation clip_op);

Expand All @@ -42,7 +38,7 @@ class ClipContents final : public Contents {
void SetInheritedOpacity(Scalar opacity) override;

private:
std::shared_ptr<Geometry> geometry_;
const Geometry* geometry_ = nullptr;
Entity::ClipOperation clip_op_ = Entity::ClipOperation::kIntersect;

ClipContents(const ClipContents&) = delete;
Expand Down
3 changes: 2 additions & 1 deletion impeller/entity/contents/clip_contents_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ TEST_P(EntityTest, ClipContentsOptimizesFullScreenIntersectClips) {

auto contents = std::make_shared<ClipContents>();
contents->SetClipOperation(Entity::ClipOperation::kIntersect);
contents->SetGeometry(Geometry::MakeCover());
auto geom = Geometry::MakeCover();
contents->SetGeometry(geom.get());

Entity entity;
entity.SetContents(std::move(contents));
Expand Down
6 changes: 3 additions & 3 deletions impeller/entity/contents/color_source_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ ColorSourceContents::ColorSourceContents() = default;

ColorSourceContents::~ColorSourceContents() = default;

void ColorSourceContents::SetGeometry(std::shared_ptr<Geometry> geometry) {
geometry_ = std::move(geometry);
void ColorSourceContents::SetGeometry(const Geometry* geometry) {
geometry_ = geometry;
}

const std::shared_ptr<Geometry>& ColorSourceContents::GetGeometry() const {
const Geometry* ColorSourceContents::GetGeometry() const {
return geometry_;
}

Expand Down
29 changes: 19 additions & 10 deletions impeller/entity/contents/color_source_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ class ColorSourceContents : public Contents {
//----------------------------------------------------------------------------
/// @brief Set the geometry that this contents will use to render.
///
void SetGeometry(std::shared_ptr<Geometry> geometry);
void SetGeometry(const Geometry* geometry);

//----------------------------------------------------------------------------
/// @brief Get the geometry that this contents will use to render.
///
const std::shared_ptr<Geometry>& GetGeometry() const;
const Geometry* GetGeometry() const;

//----------------------------------------------------------------------------
/// @brief Set the effect transform for this color source.
Expand Down Expand Up @@ -110,14 +110,14 @@ class ColorSourceContents : public Contents {
std::function<GeometryResult(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass,
const Geometry& geom)>;
const Geometry* geom)>;

static GeometryResult DefaultCreateGeometryCallback(
const ContentContext& renderer,
const Entity& entity,
RenderPass& pass,
const Geometry& geom) {
return geom.GetPositionBuffer(renderer, entity, pass);
const Geometry* geom) {
return geom->GetPositionBuffer(renderer, entity, pass);
}

/// @brief Whether the entity should be treated as non-opaque due to stroke
Expand All @@ -137,7 +137,8 @@ class ColorSourceContents : public Contents {
auto options = OptionsFromPassAndEntity(pass, entity);

GeometryResult::Mode geometry_mode = GetGeometry()->GetResultMode();
Geometry& geometry = *GetGeometry();
bool do_cover_draw = false;
Rect cover_area = {};

bool is_stencil_then_cover =
geometry_mode == GeometryResult::Mode::kNonZero ||
Expand Down Expand Up @@ -200,11 +201,19 @@ class ColorSourceContents : public Contents {
if (!maybe_cover_area.has_value()) {
return true;
}
geometry = RectGeometry(maybe_cover_area.value());
do_cover_draw = true;
cover_area = maybe_cover_area.value();
}

GeometryResult geometry_result;
if (do_cover_draw) {
RectGeometry geom(cover_area);
geometry_result = create_geom_callback(renderer, entity, pass, &geom);
} else {
geometry_result =
create_geom_callback(renderer, entity, pass, GetGeometry());
}

GeometryResult geometry_result =
create_geom_callback(renderer, entity, pass, geometry);
if (geometry_result.vertex_buffer.vertex_count == 0u) {
return true;
}
Expand Down Expand Up @@ -260,7 +269,7 @@ class ColorSourceContents : public Contents {
}

private:
std::shared_ptr<Geometry> geometry_;
const Geometry* geometry_ = nullptr;
Matrix inverse_matrix_;
Scalar opacity_ = 1.0;
Scalar inherited_opacity_ = 1.0;
Expand Down
5 changes: 3 additions & 2 deletions impeller/entity/contents/filters/blend_filter_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "impeller/entity/contents/filters/inputs/filter_input.h"
#include "impeller/entity/contents/solid_color_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/geometry/rect_geometry.h"
#include "impeller/entity/texture_fill.frag.h"
#include "impeller/entity/texture_fill.vert.h"
#include "impeller/geometry/color.h"
Expand Down Expand Up @@ -626,8 +627,8 @@ static std::optional<Entity> PipelineBlend(

if (foreground_color.has_value()) {
auto contents = std::make_shared<SolidColorContents>();
contents->SetGeometry(
Geometry::MakeRect(Rect::MakeSize(pass.GetRenderTargetSize())));
RectGeometry geom(Rect::MakeSize(pass.GetRenderTargetSize()));
contents->SetGeometry(&geom);
contents->SetColor(foreground_color.value());

Entity foreground_entity;
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/filters/filter_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ std::shared_ptr<FilterContents> FilterContents::MakeGaussianBlur(
Sigma sigma_y,
Entity::TileMode tile_mode,
FilterContents::BlurStyle mask_blur_style,
const std::shared_ptr<Geometry>& mask_geometry) {
const Geometry* mask_geometry) {
auto blur = std::make_shared<GaussianBlurFilterContents>(
sigma_x.sigma, sigma_y.sigma, tile_mode, mask_blur_style, mask_geometry);
blur->SetInputs({input});
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/filters/filter_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class FilterContents : public Contents {
Sigma sigma_y,
Entity::TileMode tile_mode = Entity::TileMode::kDecal,
BlurStyle mask_blur_style = BlurStyle::kNormal,
const std::shared_ptr<Geometry>& mask_geometry = nullptr);
const Geometry* mask_geometry = nullptr);

static std::shared_ptr<FilterContents> MakeBorderMaskBlur(
FilterInput::Ref input,
Expand Down
Loading