Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Impeller] separate algorithm for computing render target size. #54604

Merged
merged 38 commits into from
Aug 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
9d59af1
[Impeller] separate algorithm for computing render target size.
jonahwilliams Aug 18, 2024
a935594
++
jonahwilliams Aug 18, 2024
7aa3a48
Update save_layer_utils_unittests.cc
jonahwilliams Aug 18, 2024
54cea5a
nolint.
jonahwilliams Aug 19, 2024
e6e56d8
oh boy here we go.
jonahwilliams Aug 19, 2024
98a5d68
cleanups.
jonahwilliams Aug 19, 2024
81ccaa0
remove print.
jonahwilliams Aug 19, 2024
55a6a50
Update save_layer_utils_unittests.cc
jonahwilliams Aug 19, 2024
3591395
dont overwrite save layer bounds.
jonahwilliams Aug 19, 2024
a8f0e2c
Merge branch 'render_target_sizing' of github.com:jonahwilliams/engin…
jonahwilliams Aug 19, 2024
1c55cf5
++
jonahwilliams Aug 20, 2024
a6f5f21
Update dl_dispatcher.cc
jonahwilliams Aug 20, 2024
a646c1b
++
jonahwilliams Aug 20, 2024
8daf291
Merge branch 'main' of github.com:flutter/engine into render_target_s…
jonahwilliams Aug 20, 2024
199a846
++
jonahwilliams Aug 20, 2024
b2eb6b9
++
jonahwilliams Aug 20, 2024
d347783
++
jonahwilliams Aug 20, 2024
24442e0
flood clip.
jonahwilliams Aug 21, 2024
78b7f60
add flood clip.
jonahwilliams Aug 21, 2024
2a4ac2d
++
jonahwilliams Aug 21, 2024
3eff88b
++
jonahwilliams Aug 21, 2024
04b5be5
Update entity_pass.cc
jonahwilliams Aug 21, 2024
086abb8
Update entity_pass.h
jonahwilliams Aug 21, 2024
4a5f30b
++
jonahwilliams Aug 21, 2024
fa3afcc
Merge branch 'render_target_sizing' of github.com:jonahwilliams/engin…
jonahwilliams Aug 21, 2024
4e7a707
partial review feedback.
jonahwilliams Aug 23, 2024
e0105d7
more adjustments.
jonahwilliams Aug 23, 2024
e8f34ac
oops
jonahwilliams Aug 23, 2024
8a3d1ef
Merge branch 'main' into render_target_sizing
jonahwilliams Aug 27, 2024
24ef59a
Merge branch 'main' into render_target_sizing
jonahwilliams Aug 28, 2024
0cae7a8
flar review.
jonahwilliams Aug 29, 2024
ae57e62
Merge branch 'main' of github.com:flutter/engine into render_target_s…
jonahwilliams Aug 29, 2024
bc2276e
no bds from caller.
jonahwilliams Aug 30, 2024
b3ab833
update comment.
jonahwilliams Aug 30, 2024
334e5e9
++
jonahwilliams Aug 30, 2024
82a6621
++
jonahwilliams Aug 30, 2024
5011b3c
++
jonahwilliams Aug 30, 2024
008b6f9
++
jonahwilliams Aug 30, 2024
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
1 change: 1 addition & 0 deletions ci/licenses_golden/excluded_files
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@
../../../flutter/impeller/entity/entity_unittests.cc
../../../flutter/impeller/entity/geometry/geometry_unittests.cc
../../../flutter/impeller/entity/render_target_cache_unittests.cc
../../../flutter/impeller/entity/save_layer_utils_unittests.cc
../../../flutter/impeller/fixtures
../../../flutter/impeller/geometry/README.md
../../../flutter/impeller/geometry/geometry_unittests.cc
Expand Down
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -42871,6 +42871,8 @@ ORIGIN: ../../../flutter/impeller/entity/inline_pass_context.cc + ../../../flutt
ORIGIN: ../../../flutter/impeller/entity/inline_pass_context.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/render_target_cache.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/render_target_cache.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/save_layer_utils.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/save_layer_utils.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.vert + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/blending/blend_select.glsl + ../../../flutter/LICENSE
Expand Down Expand Up @@ -45759,6 +45761,8 @@ FILE: ../../../flutter/impeller/entity/inline_pass_context.cc
FILE: ../../../flutter/impeller/entity/inline_pass_context.h
FILE: ../../../flutter/impeller/entity/render_target_cache.cc
FILE: ../../../flutter/impeller/entity/render_target_cache.h
FILE: ../../../flutter/impeller/entity/save_layer_utils.cc
FILE: ../../../flutter/impeller/entity/save_layer_utils.h
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.frag
FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.vert
FILE: ../../../flutter/impeller/entity/shaders/blending/blend_select.glsl
Expand Down
9 changes: 5 additions & 4 deletions impeller/aiks/aiks_blend_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,13 @@ TEST_P(AiksTest, ColorWheel) {

draw_color_wheel(canvas);
auto color_wheel_picture = canvas.EndRecordingAsPicture();
auto snapshot = color_wheel_picture.Snapshot(renderer);
if (!snapshot.has_value() || !snapshot->texture) {
auto image = color_wheel_picture.ToImage(
renderer, ISize{GetWindowSize().width, GetWindowSize().height});
if (!image) {
return std::nullopt;
}
color_wheel_image = snapshot->texture;
color_wheel_transform = snapshot->transform;
color_wheel_image = image;
color_wheel_transform = Matrix();
}

Canvas canvas;
Expand Down
5 changes: 2 additions & 3 deletions impeller/aiks/canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -814,8 +814,7 @@ void Canvas::SaveLayer(const Paint& paint,
const std::shared_ptr<ImageFilter>& backdrop_filter,
ContentBoundsPromise bounds_promise,
uint32_t total_content_depth,
bool can_distribute_opacity,
bool bounds_from_caller) {
bool can_distribute_opacity) {
if (can_distribute_opacity && !backdrop_filter &&
Paint::CanApplyOpacityPeephole(paint) &&
bounds_promise != ContentBoundsPromise::kMayClipContents) {
Expand All @@ -837,7 +836,7 @@ void Canvas::SaveLayer(const Paint& paint,

auto& new_layer_pass = GetCurrentPass();
if (bounds) {
new_layer_pass.SetBoundsLimit(bounds, bounds_promise);
new_layer_pass.SetBoundsLimit(bounds);
}

// When applying a save layer, absorb any pending distributed opacity.
Expand Down
3 changes: 1 addition & 2 deletions impeller/aiks/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ class Canvas {
const std::shared_ptr<ImageFilter>& backdrop_filter = nullptr,
ContentBoundsPromise bounds_promise = ContentBoundsPromise::kUnknown,
uint32_t total_content_depth = kMaxDepth,
bool can_distribute_opacity = false,
bool bounds_from_caller = false);
bool can_distribute_opacity = false);

virtual bool Restore();

Expand Down
57 changes: 26 additions & 31 deletions impeller/aiks/experimental_canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
#include "impeller/core/allocator.h"
#include "impeller/core/formats.h"
#include "impeller/entity/contents/clip_contents.h"
#include "impeller/entity/contents/filters/filter_contents.h"
#include "impeller/entity/contents/framebuffer_blend_contents.h"
#include "impeller/entity/contents/text_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/entity_pass_clip_stack.h"
#include "impeller/entity/save_layer_utils.h"
#include "impeller/geometry/color.h"
#include "impeller/renderer/render_target.h"

Expand Down Expand Up @@ -314,15 +316,9 @@ void ExperimentalCanvas::SaveLayer(
const std::shared_ptr<ImageFilter>& backdrop_filter,
ContentBoundsPromise bounds_promise,
uint32_t total_content_depth,
bool can_distribute_opacity,
bool bounds_from_caller) {
bool can_distribute_opacity) {
TRACE_EVENT0("flutter", "Canvas::saveLayer");

if (bounds.has_value() && bounds->IsEmpty()) {
Save(total_content_depth);
return;
}

if (!clip_coverage_stack_.HasCoverage()) {
// The current clip is empty. This means the pass texture won't be
// visible, so skip it.
Expand All @@ -346,13 +342,6 @@ void ExperimentalCanvas::SaveLayer(
->GetSize()))
.Intersection(current_clip_coverage);

if (!maybe_coverage_limit.has_value()) {
Save(total_content_depth);
return;
}
maybe_coverage_limit = maybe_coverage_limit->Intersection(
Rect::MakeSize(render_target_.GetRenderTargetSize()));

if (!maybe_coverage_limit.has_value() || maybe_coverage_limit->IsEmpty()) {
Save(total_content_depth);
return;
Expand All @@ -367,12 +356,33 @@ void ExperimentalCanvas::SaveLayer(
return;
}

std::shared_ptr<FilterContents> filter_contents;
if (paint.image_filter) {
filter_contents = paint.image_filter->GetFilterContents();
}

std::optional<Rect> maybe_subpass_coverage = ComputeSaveLayerCoverage(
bounds.value_or(Rect::MakeMaximum()),
transform_stack_.back().transform, //
coverage_limit, //
filter_contents, //
/*flood_output_coverage=*/
Entity::IsBlendModeDestructive(paint.blend_mode), //
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also examine the paint.color_filter?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't know that bit currently, but we will eventually: flutter/flutter#154035

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(once we delete impeller::ColorFilter)

/*flood_input_coverage=*/!!backdrop_filter //
);

if (!maybe_subpass_coverage.has_value() ||
maybe_subpass_coverage->IsEmpty()) {
Save(total_content_depth);
return;
}
auto subpass_coverage = maybe_subpass_coverage.value();

// Backdrop filter state, ignored if there is no BDF.
std::shared_ptr<FilterContents> backdrop_filter_contents;
Point local_position = {0, 0};
if (backdrop_filter) {
local_position =
current_clip_coverage.GetOrigin() - GetGlobalPassPosition();
local_position = subpass_coverage.GetOrigin() - GetGlobalPassPosition();
EntityPass::BackdropFilterProc backdrop_filter_proc =
[backdrop_filter = backdrop_filter->Clone()](
const FilterInput::Ref& input, const Matrix& effect_transform,
Expand Down Expand Up @@ -409,21 +419,6 @@ void ExperimentalCanvas::SaveLayer(
paint_copy.color.alpha *= transform_stack_.back().distributed_opacity;
transform_stack_.back().distributed_opacity = 1.0;

// Backdrop Filter must expand bounds to at least the clip stack, otherwise
// the coverage of the parent render pass.
Rect subpass_coverage;
if (backdrop_filter_contents ||
Entity::IsBlendModeDestructive(paint.blend_mode) || !bounds.has_value()) {
subpass_coverage = coverage_limit;
// TODO(jonahwilliams): if we have tight bounds we should be able to reduce
// this size here. if (bounds.has_value() && bounds_from_caller) {
// subpass_coverage =
// coverage_limit.Intersection(bounds.value()).value_or(bounds.value());
// }
} else {
subpass_coverage = bounds->TransformBounds(GetCurrentTransform());
}

render_passes_.push_back(LazyRenderingConfig(
renderer_, //
CreateRenderTarget(renderer_, //
Expand Down
3 changes: 1 addition & 2 deletions impeller/aiks/experimental_canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ class ExperimentalCanvas : public Canvas {
const std::shared_ptr<ImageFilter>& backdrop_filter,
ContentBoundsPromise bounds_promise,
uint32_t total_content_depth,
bool can_distribute_opacity,
bool bounds_from_caller) override;
bool can_distribute_opacity) override;

bool Restore() override;

Expand Down
16 changes: 0 additions & 16 deletions impeller/aiks/picture.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,10 @@
#include <optional>

#include "impeller/base/validation.h"
#include "impeller/entity/entity.h"
#include "impeller/renderer/render_target.h"
#include "impeller/renderer/snapshot.h"

namespace impeller {

std::optional<Snapshot> Picture::Snapshot(AiksContext& context) {
auto coverage = pass->GetElementsCoverage(std::nullopt);
if (!coverage.has_value() || coverage->IsEmpty()) {
return std::nullopt;
}

const auto translate = Matrix::MakeTranslation(-coverage->GetOrigin());
auto texture =
RenderToTexture(context, ISize(coverage->GetSize()), translate);
return impeller::Snapshot{
.texture = std::move(texture),
.transform = Matrix::MakeTranslation(coverage->GetOrigin())};
}

std::shared_ptr<Texture> Picture::ToImage(AiksContext& context,
ISize size) const {
if (size.IsEmpty()) {
Expand Down
2 changes: 0 additions & 2 deletions impeller/aiks/picture.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ namespace impeller {
struct Picture {
std::unique_ptr<EntityPass> pass;

std::optional<Snapshot> Snapshot(AiksContext& context);

std::shared_ptr<Texture> ToImage(AiksContext& context, ISize size) const;

private:
Expand Down
20 changes: 8 additions & 12 deletions impeller/display_list/dl_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -723,22 +723,18 @@ void DlDispatcherBase::saveLayer(const SkRect& bounds,
? ContentBoundsPromise::kMayClipContents
: ContentBoundsPromise::kContainsContents;
std::optional<Rect> impeller_bounds;
// If the content is unbounded but has developer specified bounds, we take
// the original bounds so that we clip the content as expected.
if (!options.content_is_unbounded() || options.bounds_from_caller()) {
impeller_bounds = skia_conversions::ToRect(bounds);
}

// Empty bounds on a save layer that contains a BDF or destructive blend
// should be treated as unbounded. All other empty bounds can be skipped.
if (impeller_bounds.has_value() && impeller_bounds->IsEmpty() &&
(backdrop != nullptr ||
Entity::IsBlendModeDestructive(paint.blend_mode))) {
impeller_bounds = std::nullopt;
}

GetCanvas().SaveLayer(paint, impeller_bounds, ToImageFilter(backdrop),
promise, total_content_depth,
options.can_distribute_opacity(),
options.bounds_from_caller());
GetCanvas().SaveLayer(
paint, impeller_bounds, ToImageFilter(backdrop), promise,
total_content_depth,
// Unbounded content can still have user specified bounds that require a
// saveLayer to be created to perform the clip.
options.can_distribute_opacity() && !options.content_is_unbounded());
}

// |flutter::DlOpReceiver|
Expand Down
3 changes: 3 additions & 0 deletions impeller/entity/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ impeller_component("entity") {
"inline_pass_context.h",
"render_target_cache.cc",
"render_target_cache.h",
"save_layer_utils.cc",
"save_layer_utils.h",
]

public_deps = [
Expand Down Expand Up @@ -260,6 +262,7 @@ impeller_component("entity_unittests") {
"entity_unittests.cc",
"geometry/geometry_unittests.cc",
"render_target_cache_unittests.cc",
"save_layer_utils_unittests.cc",
]

deps = [
Expand Down
Loading