diff --git a/impeller/core/allocator.cc b/impeller/core/allocator.cc index 2d056a38b2a76..be380b671ec27 100644 --- a/impeller/core/allocator.cc +++ b/impeller/core/allocator.cc @@ -49,9 +49,8 @@ std::shared_ptr Allocator::CreateTexture( const TextureDescriptor& desc) { const auto max_size = GetMaxTextureSizeSupported(); if (desc.size.width > max_size.width || desc.size.height > max_size.height) { - VALIDATION_LOG - << "Requested texture size exceeds maximum supported size of " - << desc.size; + VALIDATION_LOG << "Requested texture size " << desc.size + << " exceeds maximum supported size of " << max_size; return nullptr; } diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index 041477710c0ee..2c3961ca4e27e 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -168,8 +168,15 @@ static std::optional AdvancedBlend( return true; }; - auto out_texture = renderer.MakeSubpass("Advanced Blend Filter", - ISize(coverage.size), callback); + auto subpass_size = ISize(coverage.size); + if (entity.GetContents()) { + auto coverage_hint = entity.GetContents()->GetCoverageHint(); + if (coverage_hint.has_value()) { + subpass_size = subpass_size.Min(ISize(coverage_hint->size)); + } + } + auto out_texture = + renderer.MakeSubpass("Advanced Blend Filter", subpass_size, callback); if (!out_texture) { return std::nullopt; } @@ -531,7 +538,8 @@ static std::optional PipelineBlend( VS::FrameInfo frame_info; frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * - Matrix::MakeTranslation(-coverage.origin) * + Matrix::MakeTranslation( + -input->GetCoverage().value_or(coverage).origin) * input->transform; frame_info.texture_sampler_y_coord_scale = input->texture->GetYCoordScale(); @@ -587,8 +595,16 @@ static std::optional PipelineBlend( return true; }; - auto out_texture = renderer.MakeSubpass("Pipeline Blend Filter", - ISize(coverage.size), callback); + auto subpass_size = ISize(coverage.size); + if (entity.GetContents()) { + auto coverage_hint = entity.GetContents()->GetCoverageHint(); + if (coverage_hint.has_value()) { + subpass_size = subpass_size.Min(ISize(coverage_hint->size)); + } + } + auto out_texture = + renderer.MakeSubpass("Pipeline Blend Filter", subpass_size, callback); + if (!out_texture) { return std::nullopt; } diff --git a/impeller/entity/contents/filters/inputs/contents_filter_input.cc b/impeller/entity/contents/filters/inputs/contents_filter_input.cc index d50788e67f183..e990bfc3d2749 100644 --- a/impeller/entity/contents/filters/inputs/contents_filter_input.cc +++ b/impeller/entity/contents/filters/inputs/contents_filter_input.cc @@ -26,6 +26,9 @@ std::optional ContentsFilterInput::GetSnapshot( const ContentContext& renderer, const Entity& entity, std::optional coverage_limit) const { + if (!coverage_limit.has_value() && entity.GetContents()) { + coverage_limit = entity.GetContents()->GetCoverageHint(); + } if (!snapshot_.has_value()) { snapshot_ = contents_->RenderToSnapshot( renderer, // renderer diff --git a/impeller/entity/contents/filters/inputs/filter_input.h b/impeller/entity/contents/filters/inputs/filter_input.h index 7eb228851f531..37d4209555ced 100644 --- a/impeller/entity/contents/filters/inputs/filter_input.h +++ b/impeller/entity/contents/filters/inputs/filter_input.h @@ -10,12 +10,12 @@ #include #include "impeller/entity/contents/contents.h" +#include "impeller/entity/entity.h" #include "impeller/geometry/rect.h" namespace impeller { class ContentContext; -class Entity; class FilterContents; /// `FilterInput` is a lazy/single eval `Snapshot` which may be shared across diff --git a/impeller/entity/contents/tiled_texture_contents.cc b/impeller/entity/contents/tiled_texture_contents.cc index e302cb5eb5db7..d2d9ee02f3d8d 100644 --- a/impeller/entity/contents/tiled_texture_contents.cc +++ b/impeller/entity/contents/tiled_texture_contents.cc @@ -198,4 +198,29 @@ bool TiledTextureContents::Render(const ContentContext& renderer, return true; } +std::optional TiledTextureContents::RenderToSnapshot( + const ContentContext& renderer, + const Entity& entity, + std::optional coverage_limit, + const std::optional& sampler_descriptor, + bool msaa_enabled, + const std::string& label) const { + if (GetInverseMatrix().IsIdentity()) { + return Snapshot{ + .texture = texture_, + .transform = entity.GetTransformation(), + .sampler_descriptor = sampler_descriptor.value_or(sampler_descriptor_), + .opacity = GetOpacity(), + }; + } + + return Contents::RenderToSnapshot( + renderer, // renderer + entity, // entity + std::nullopt, // coverage_limit + sampler_descriptor.value_or(sampler_descriptor_), // sampler_descriptor + true, // msaa_enabled + label); // label +} + } // namespace impeller diff --git a/impeller/entity/contents/tiled_texture_contents.h b/impeller/entity/contents/tiled_texture_contents.h index 929c0c9e6f5ce..589f5e2b08b2b 100644 --- a/impeller/entity/contents/tiled_texture_contents.h +++ b/impeller/entity/contents/tiled_texture_contents.h @@ -53,6 +53,15 @@ class TiledTextureContents final : public ColorSourceContents { /// much smaller size that its original texture size. void SetColorFilter(std::optional color_filter); + // |Contents| + std::optional RenderToSnapshot( + const ContentContext& renderer, + const Entity& entity, + std::optional coverage_limit = std::nullopt, + const std::optional& sampler_descriptor = std::nullopt, + bool msaa_enabled = true, + const std::string& label = "Tiled Texture Snapshot") const override; + private: std::optional> CreateFilterTexture( const ContentContext& renderer) const; diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index b01716c00f260..75c6b2ea3b6f1 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -57,8 +57,10 @@ bool VerticesContents::Render(const ContentContext& renderer, return true; } std::shared_ptr src_contents = src_contents_; + src_contents->SetCoverageHint(GetCoverageHint()); if (geometry_->HasTextureCoordinates()) { auto contents = std::make_shared(*this); + contents->SetCoverageHint(GetCoverageHint()); if (!geometry_->HasVertexColors()) { contents->SetAlpha(alpha_); return contents->Render(renderer, entity, pass); @@ -67,6 +69,7 @@ bool VerticesContents::Render(const ContentContext& renderer, } auto dst_contents = std::make_shared(*this); + dst_contents->SetCoverageHint(GetCoverageHint()); std::shared_ptr contents; if (blend_mode_ == BlendMode::kDestination) { @@ -76,9 +79,11 @@ bool VerticesContents::Render(const ContentContext& renderer, blend_mode_, {FilterInput::Make(dst_contents, false), FilterInput::Make(src_contents, false)}); color_filter_contents->SetAlpha(alpha_); + color_filter_contents->SetCoverageHint(GetCoverageHint()); contents = color_filter_contents; } + FML_DCHECK(contents->GetCoverageHint() == GetCoverageHint()); return contents->Render(renderer, entity, pass); } @@ -108,11 +113,11 @@ bool VerticesUVContents::Render(const ContentContext& renderer, auto src_contents = parent_.GetSourceContents(); auto snapshot = - src_contents->RenderToSnapshot(renderer, // renderer - entity, // entity - std::nullopt, // coverage_limit - std::nullopt, // sampler_descriptor - true, // msaa_enabled + src_contents->RenderToSnapshot(renderer, // renderer + entity, // entity + GetCoverageHint(), // coverage_limit + std::nullopt, // sampler_descriptor + true, // msaa_enabled "VerticesUVContents Snapshot"); // label if (!snapshot.has_value()) { return false; diff --git a/impeller/entity/entity.cc b/impeller/entity/entity.cc index dc08164deb735..ec1e39be8ecfd 100644 --- a/impeller/entity/entity.cc +++ b/impeller/entity/entity.cc @@ -154,6 +154,11 @@ bool Entity::Render(const ContentContext& renderer, return true; } + if (!contents_->GetCoverageHint().has_value()) { + contents_->SetCoverageHint( + Rect::MakeSize(parent_pass.GetRenderTargetSize())); + } + return contents_->Render(renderer, *this, parent_pass); } diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index bbe4ce286828a..65ceaf2ccb693 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -2415,6 +2415,26 @@ TEST_P(EntityTest, PointFieldGeometryDivisions) { ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(20000.0, true), 140u); } +TEST_P(EntityTest, ColorFilterContentsWithLargeGeometry) { + Entity entity; + entity.SetTransformation(Matrix::MakeScale(GetContentScale())); + auto src_contents = std::make_shared(); + src_contents->SetGeometry( + Geometry::MakeRect(Rect::MakeLTRB(-300, -500, 30000, 50000))); + src_contents->SetColor(Color::Red()); + + auto dst_contents = std::make_shared(); + dst_contents->SetGeometry( + Geometry::MakeRect(Rect::MakeLTRB(300, 500, 20000, 30000))); + dst_contents->SetColor(Color::Blue()); + + auto contents = ColorFilterContents::MakeBlend( + BlendMode::kSourceOver, {FilterInput::Make(dst_contents, false), + FilterInput::Make(src_contents, false)}); + entity.SetContents(std::move(contents)); + ASSERT_TRUE(OpenPlaygroundHere(entity)); +} + } // namespace testing } // namespace impeller