mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] Use minimal coverage for stencil restores after overdraw prevention (flutter/engine#39358)
This commit is contained in:
parent
b139a05b64
commit
21710ccc6b
@ -136,6 +136,11 @@ ClipRestoreContents::ClipRestoreContents() = default;
|
||||
|
||||
ClipRestoreContents::~ClipRestoreContents() = default;
|
||||
|
||||
void ClipRestoreContents::SetRestoreCoverage(
|
||||
std::optional<Rect> restore_coverage) {
|
||||
restore_coverage_ = restore_coverage;
|
||||
}
|
||||
|
||||
std::optional<Rect> ClipRestoreContents::GetCoverage(
|
||||
const Entity& entity) const {
|
||||
return std::nullopt;
|
||||
@ -164,19 +169,20 @@ bool ClipRestoreContents::Render(const ContentContext& renderer,
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
options.stencil_compare = CompareFunction::kLess;
|
||||
options.stencil_operation = StencilOperation::kSetToReferenceValue;
|
||||
options.primitive_type = PrimitiveType::kTriangleStrip;
|
||||
cmd.pipeline = renderer.GetClipPipeline(options);
|
||||
cmd.stencil_reference = entity.GetStencilDepth();
|
||||
|
||||
// Create a rect that covers the whole render target.
|
||||
auto size = pass.GetRenderTargetSize();
|
||||
// Create a rect that covers either the given restore area, or the whole
|
||||
// render target texture.
|
||||
auto ltrb = restore_coverage_.value_or(Rect(Size(pass.GetRenderTargetSize())))
|
||||
.GetLTRB();
|
||||
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
|
||||
vtx_builder.AddVertices({
|
||||
{Point(0.0, 0.0)},
|
||||
{Point(size.width, 0.0)},
|
||||
{Point(size.width, size.height)},
|
||||
{Point(0.0, 0.0)},
|
||||
{Point(size.width, size.height)},
|
||||
{Point(0.0, size.height)},
|
||||
{Point(ltrb[0], ltrb[1])},
|
||||
{Point(ltrb[2], ltrb[1])},
|
||||
{Point(ltrb[0], ltrb[3])},
|
||||
{Point(ltrb[2], ltrb[3])},
|
||||
});
|
||||
cmd.BindVertices(vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
|
||||
|
||||
|
||||
@ -55,6 +55,12 @@ class ClipRestoreContents final : public Contents {
|
||||
|
||||
~ClipRestoreContents();
|
||||
|
||||
/// @brief The area on the pass texture where this clip restore will be
|
||||
/// applied. If unset, the entire pass texture will be restored.
|
||||
///
|
||||
/// @note This rectangle is not transformed by the entity's transformation.
|
||||
void SetRestoreCoverage(std::optional<Rect> coverage);
|
||||
|
||||
// |Contents|
|
||||
std::optional<Rect> GetCoverage(const Entity& entity) const override;
|
||||
|
||||
@ -73,6 +79,8 @@ class ClipRestoreContents final : public Contents {
|
||||
RenderPass& pass) const override;
|
||||
|
||||
private:
|
||||
std::optional<Rect> restore_coverage_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(ClipRestoreContents);
|
||||
};
|
||||
|
||||
|
||||
@ -111,7 +111,9 @@ bool LinearGradientContents::RenderTexture(const ContentContext& renderer,
|
||||
}
|
||||
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
return ClipRestoreContents().Render(renderer, entity, pass);
|
||||
auto restore = ClipRestoreContents();
|
||||
restore.SetRestoreCoverage(GetCoverage(entity));
|
||||
return restore.Render(renderer, entity, pass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -165,7 +167,9 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer,
|
||||
}
|
||||
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
return ClipRestoreContents().Render(renderer, entity, pass);
|
||||
auto restore = ClipRestoreContents();
|
||||
restore.SetRestoreCoverage(GetCoverage(entity));
|
||||
return restore.Render(renderer, entity, pass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -103,7 +103,9 @@ bool RadialGradientContents::RenderSSBO(const ContentContext& renderer,
|
||||
}
|
||||
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
return ClipRestoreContents().Render(renderer, entity, pass);
|
||||
auto restore = ClipRestoreContents();
|
||||
restore.SetRestoreCoverage(GetCoverage(entity));
|
||||
return restore.Render(renderer, entity, pass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -166,7 +168,9 @@ bool RadialGradientContents::RenderTexture(const ContentContext& renderer,
|
||||
}
|
||||
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
return ClipRestoreContents().Render(renderer, entity, pass);
|
||||
auto restore = ClipRestoreContents();
|
||||
restore.SetRestoreCoverage(GetCoverage(entity));
|
||||
return restore.Render(renderer, entity, pass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -238,7 +238,9 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
|
||||
pass.AddCommand(std::move(cmd));
|
||||
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
return ClipRestoreContents().Render(renderer, entity, pass);
|
||||
auto restore = ClipRestoreContents();
|
||||
restore.SetRestoreCoverage(GetCoverage(entity));
|
||||
return restore.Render(renderer, entity, pass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -83,7 +83,9 @@ bool SolidColorContents::Render(const ContentContext& renderer,
|
||||
}
|
||||
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
return ClipRestoreContents().Render(renderer, entity, pass);
|
||||
auto restore = ClipRestoreContents();
|
||||
restore.SetRestoreCoverage(GetCoverage(entity));
|
||||
return restore.Render(renderer, entity, pass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -109,7 +109,9 @@ bool SweepGradientContents::RenderSSBO(const ContentContext& renderer,
|
||||
}
|
||||
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
return ClipRestoreContents().Render(renderer, entity, pass);
|
||||
auto restore = ClipRestoreContents();
|
||||
restore.SetRestoreCoverage(GetCoverage(entity));
|
||||
return restore.Render(renderer, entity, pass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -173,7 +175,9 @@ bool SweepGradientContents::RenderTexture(const ContentContext& renderer,
|
||||
}
|
||||
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
return ClipRestoreContents().Render(renderer, entity, pass);
|
||||
auto restore = ClipRestoreContents();
|
||||
restore.SetRestoreCoverage(GetCoverage(entity));
|
||||
return restore.Render(renderer, entity, pass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -96,7 +96,9 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
|
||||
}
|
||||
|
||||
if (geometry_result.prevent_overdraw) {
|
||||
return ClipRestoreContents().Render(renderer, entity, pass);
|
||||
auto restore = ClipRestoreContents();
|
||||
restore.SetRestoreCoverage(GetCoverage(entity));
|
||||
return restore.Render(renderer, entity, pass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user