Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 6415efd

Browse files
[Impeller] fix drawVertices dest fast path to apply alpha. (#47695)
Part of flutter/flutter#118914 When drawing vertices with a destination blend mode, we need to make sure to forward any alpha component. I introduced some test helpers to allow verification of recorded cmds without goldens.
1 parent 461d815 commit 6415efd

File tree

6 files changed

+142
-4
lines changed

6 files changed

+142
-4
lines changed

ci/licenses_golden/excluded_files

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@
136136
../../../flutter/impeller/docs
137137
../../../flutter/impeller/entity/contents/checkerboard_contents_unittests.cc
138138
../../../flutter/impeller/entity/contents/filters/inputs/filter_input_unittests.cc
139+
../../../flutter/impeller/entity/contents/test
140+
../../../flutter/impeller/entity/contents/vertices_contents_unittests.cc
139141
../../../flutter/impeller/entity/entity_unittests.cc
140142
../../../flutter/impeller/entity/geometry/geometry_unittests.cc
141143
../../../flutter/impeller/entity/render_target_cache_unittests.cc

impeller/entity/BUILD.gn

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,12 +264,24 @@ impeller_component("entity") {
264264
deps = [ "//flutter/fml" ]
265265
}
266266

267+
impeller_component("entity_test_helpers") {
268+
testonly = true
269+
270+
sources = [
271+
"contents/test/contents_test_helpers.cc",
272+
"contents/test/contents_test_helpers.h",
273+
]
274+
275+
deps = [ ":entity" ]
276+
}
277+
267278
impeller_component("entity_unittests") {
268279
testonly = true
269280

270281
sources = [
271282
"contents/checkerboard_contents_unittests.cc",
272283
"contents/filters/inputs/filter_input_unittests.cc",
284+
"contents/vertices_contents_unittests.cc",
273285
"entity_playground.cc",
274286
"entity_playground.h",
275287
"entity_unittests.cc",
@@ -278,6 +290,7 @@ impeller_component("entity_unittests") {
278290

279291
deps = [
280292
":entity",
293+
":entity_test_helpers",
281294
"../geometry:geometry_asserts",
282295
"../playground:playground_test",
283296
"//flutter/impeller/typographer/backends/skia:typographer_skia_backend",
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "impeller/entity/contents/test/contents_test_helpers.h"
6+
7+
namespace impeller {
8+
9+
//
10+
11+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#pragma once
6+
7+
#include "impeller/renderer/command.h"
8+
9+
namespace impeller {
10+
11+
/// @brief Retrieve the [VertInfo] struct data from the provided [command].
12+
template <typename T>
13+
typename T::VertInfo* GetVertInfo(const Command& command) {
14+
auto resource = command.vertex_bindings.buffers.find(0u);
15+
if (resource == command.vertex_bindings.buffers.end()) {
16+
return nullptr;
17+
}
18+
19+
auto data = (resource->second.view.resource.contents +
20+
resource->second.view.resource.range.offset);
21+
return reinterpret_cast<typename T::VertInfo*>(data);
22+
}
23+
24+
/// @brief Retrieve the [FragInfo] struct data from the provided [command].
25+
template <typename T>
26+
typename T::FragInfo* GetFragInfo(const Command& command) {
27+
auto resource = command.fragment_bindings.buffers.find(0u);
28+
if (resource == command.fragment_bindings.buffers.end()) {
29+
return nullptr;
30+
}
31+
32+
auto data = (resource->second.view.resource.contents +
33+
resource->second.view.resource.range.offset);
34+
return reinterpret_cast<typename T::FragInfo*>(data);
35+
}
36+
37+
} // namespace impeller

impeller/entity/contents/vertices_contents.cc

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,8 @@
44

55
#include "vertices_contents.h"
66

7-
#include "impeller/core/formats.h"
8-
#include "impeller/core/vertex_buffer.h"
97
#include "impeller/entity/contents/content_context.h"
108
#include "impeller/entity/contents/filters/color_filter_contents.h"
11-
#include "impeller/entity/contents/filters/filter_contents.h"
12-
#include "impeller/entity/contents/texture_contents.h"
139
#include "impeller/entity/position_color.vert.h"
1410
#include "impeller/entity/vertices.frag.h"
1511
#include "impeller/geometry/color.h"
@@ -73,6 +69,7 @@ bool VerticesContents::Render(const ContentContext& renderer,
7369

7470
std::shared_ptr<Contents> contents;
7571
if (blend_mode_ == BlendMode::kDestination) {
72+
dst_contents->SetAlpha(alpha_);
7673
contents = dst_contents;
7774
} else {
7875
auto color_filter_contents = ColorFilterContents::MakeBlend(
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include <memory>
6+
#include <optional>
7+
8+
#include "gtest/gtest.h"
9+
10+
#include "impeller/entity/contents/contents.h"
11+
#include "impeller/entity/contents/solid_color_contents.h"
12+
#include "impeller/entity/contents/test/contents_test_helpers.h"
13+
#include "impeller/entity/contents/vertices_contents.h"
14+
#include "impeller/entity/entity.h"
15+
#include "impeller/entity/entity_playground.h"
16+
#include "impeller/entity/vertices.frag.h"
17+
#include "impeller/geometry/path_builder.h"
18+
#include "impeller/renderer/render_target.h"
19+
20+
namespace impeller {
21+
namespace testing {
22+
23+
using EntityTest = EntityPlayground;
24+
INSTANTIATE_PLAYGROUND_SUITE(EntityTest);
25+
26+
std::shared_ptr<VerticesGeometry> CreateColorVertices(
27+
const std::vector<Point>& vertices,
28+
const std::vector<Color>& colors) {
29+
auto bounds = Rect::MakePointBounds(vertices.begin(), vertices.end());
30+
std::vector<uint16_t> indices = {};
31+
for (auto i = 0u; i < vertices.size(); i++) {
32+
indices.emplace_back(i);
33+
}
34+
std::vector<Point> texture_coordinates = {};
35+
36+
return std::make_shared<VerticesGeometry>(
37+
vertices, indices, texture_coordinates, colors,
38+
bounds.value_or(Rect::MakeLTRB(0, 0, 0, 0)),
39+
VerticesGeometry::VertexMode::kTriangles);
40+
}
41+
42+
// Verifies that the destination blend fast path still sets an alpha value.
43+
TEST_P(EntityTest, RendersDstPerColorWithAlpha) {
44+
using FS = GeometryColorPipeline::FragmentShader;
45+
46+
auto contents = std::make_shared<VerticesContents>();
47+
auto vertices = CreateColorVertices(
48+
{{0, 0}, {100, 0}, {0, 100}, {100, 0}, {0, 100}, {100, 100}},
49+
{Color::Red(), Color::Red(), Color::Red(), Color::Red(), Color::Red(),
50+
Color::Red()});
51+
auto src_contents = SolidColorContents::Make(
52+
PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath(),
53+
Color::Red());
54+
55+
contents->SetGeometry(vertices);
56+
contents->SetAlpha(0.5);
57+
contents->SetBlendMode(BlendMode::kDestination);
58+
contents->SetSourceContents(std::move(src_contents));
59+
60+
auto content_context = GetContentContext();
61+
auto buffer = content_context->GetContext()->CreateCommandBuffer();
62+
auto render_target = RenderTarget::CreateOffscreenMSAA(
63+
*content_context->GetContext(),
64+
*GetContentContext()->GetRenderTargetCache(), {100, 100});
65+
auto render_pass = buffer->CreateRenderPass(render_target);
66+
Entity entity;
67+
68+
ASSERT_TRUE(render_pass->GetCommands().empty());
69+
ASSERT_TRUE(contents->Render(*content_context, entity, *render_pass));
70+
71+
const auto& cmd = render_pass->GetCommands()[0];
72+
auto* frag_uniforms = GetFragInfo<FS>(cmd);
73+
74+
ASSERT_EQ(frag_uniforms->alpha, 0.5);
75+
}
76+
77+
} // namespace testing
78+
} // namespace impeller

0 commit comments

Comments
 (0)