mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] EntityPass should cover the whole screen for some blend modes (flutter/engine#35157)
This commit is contained in:
parent
6c71f6341b
commit
84a598832f
@ -252,6 +252,31 @@ TEST_P(AiksTest, CanRenderRadialGradient) {
|
||||
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
|
||||
}
|
||||
|
||||
TEST_P(AiksTest, BlendModeShouldCoverWholeScreen) {
|
||||
Canvas canvas;
|
||||
Paint paint;
|
||||
|
||||
paint.color = Color::Red();
|
||||
canvas.DrawPaint(paint);
|
||||
|
||||
paint.blend_mode = Entity::BlendMode::kSourceOver;
|
||||
canvas.SaveLayer(paint);
|
||||
|
||||
paint.color = Color::White();
|
||||
canvas.DrawRect({100, 100, 400, 400}, paint);
|
||||
|
||||
paint.blend_mode = Entity::BlendMode::kSource;
|
||||
canvas.SaveLayer(paint);
|
||||
|
||||
paint.color = Color::Blue();
|
||||
canvas.DrawRect({200, 200, 200, 200}, paint);
|
||||
|
||||
canvas.Restore();
|
||||
canvas.Restore();
|
||||
|
||||
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
|
||||
}
|
||||
|
||||
TEST_P(AiksTest, CanRenderGroupOpacity) {
|
||||
Canvas canvas;
|
||||
|
||||
|
||||
@ -42,6 +42,9 @@ std::optional<Rect> Entity::GetCoverage() const {
|
||||
}
|
||||
|
||||
bool Entity::ShouldRender(const ISize& target_size) const {
|
||||
if (BlendModeShouldCoverWholeScreen(blend_mode_)) {
|
||||
return true;
|
||||
}
|
||||
return contents_->ShouldRender(*this, target_size);
|
||||
}
|
||||
|
||||
@ -73,6 +76,23 @@ Entity::BlendMode Entity::GetBlendMode() const {
|
||||
return blend_mode_;
|
||||
}
|
||||
|
||||
bool Entity::BlendModeShouldCoverWholeScreen(BlendMode blend_mode) {
|
||||
switch (blend_mode) {
|
||||
case BlendMode::kClear:
|
||||
case BlendMode::kSource:
|
||||
case BlendMode::kSourceIn:
|
||||
case BlendMode::kDestinationIn:
|
||||
case BlendMode::kSourceOut:
|
||||
case BlendMode::kDestinationOut:
|
||||
case BlendMode::kDestinationATop:
|
||||
case BlendMode::kXor:
|
||||
case BlendMode::kModulate:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Entity::Render(const ContentContext& renderer,
|
||||
RenderPass& parent_pass) const {
|
||||
if (!contents_) {
|
||||
|
||||
@ -121,6 +121,8 @@ class Entity {
|
||||
|
||||
bool Render(const ContentContext& renderer, RenderPass& parent_pass) const;
|
||||
|
||||
static bool BlendModeShouldCoverWholeScreen(BlendMode blend_mode);
|
||||
|
||||
private:
|
||||
Matrix transformation_;
|
||||
std::shared_ptr<Contents> contents_;
|
||||
|
||||
@ -252,7 +252,10 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
|
||||
|
||||
auto subpass_coverage =
|
||||
GetSubpassCoverage(*subpass, Rect::MakeSize(root_pass_size));
|
||||
|
||||
if (subpass->cover_whole_screen) {
|
||||
subpass_coverage = Rect(
|
||||
position, Size(pass_context.GetRenderTarget().GetRenderTargetSize()));
|
||||
}
|
||||
if (backdrop_contents) {
|
||||
auto backdrop_coverage = backdrop_contents->GetCoverage(Entity{});
|
||||
if (backdrop_coverage.has_value()) {
|
||||
@ -501,6 +504,7 @@ void EntityPass::SetStencilDepth(size_t stencil_depth) {
|
||||
|
||||
void EntityPass::SetBlendMode(Entity::BlendMode blend_mode) {
|
||||
blend_mode_ = blend_mode;
|
||||
cover_whole_screen = Entity::BlendModeShouldCoverWholeScreen(blend_mode);
|
||||
}
|
||||
|
||||
void EntityPass::SetBackdropFilter(std::optional<BackdropFilterProc> proc) {
|
||||
|
||||
@ -114,7 +114,7 @@ class EntityPass {
|
||||
Matrix xformation_;
|
||||
size_t stencil_depth_ = 0u;
|
||||
Entity::BlendMode blend_mode_ = Entity::BlendMode::kSourceOver;
|
||||
|
||||
bool cover_whole_screen = false;
|
||||
/// This flag is set to `true` whenever an entity is added to the pass that
|
||||
/// requires reading the pass texture during rendering. This can happen in the
|
||||
/// following scenarios:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user