Skip to content

Commit 6883215

Browse files
bderodnfield
authored andcommitted
Add blend mode setting to Entity, Aiks paint, and the dispatcher (flutter#89)
1 parent 6e77886 commit 6883215

15 files changed

+139
-8
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,5 +398,24 @@ TEST_F(AiksTest, CanDrawPaint) {
398398
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
399399
}
400400

401+
TEST_F(AiksTest, PaintBlendModeIsRespected) {
402+
Paint paint;
403+
Canvas canvas;
404+
// Default is kSourceOver.
405+
paint.color = Color(1, 0, 0, 0.5);
406+
canvas.DrawCircle(Point(150, 200), 100, paint);
407+
paint.color = Color(0, 1, 0, 0.5);
408+
canvas.DrawCircle(Point(250, 200), 100, paint);
409+
410+
paint.blend_mode = Entity::BlendMode::kPlus;
411+
paint.color = Color::Red();
412+
canvas.DrawCircle(Point(450, 250), 100, paint);
413+
paint.color = Color::Green();
414+
canvas.DrawCircle(Point(550, 250), 100, paint);
415+
paint.color = Color::Blue();
416+
canvas.DrawCircle(Point(500, 150), 100, paint);
417+
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
418+
}
419+
401420
} // namespace testing
402421
} // namespace impeller

impeller/aiks/canvas.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ void Canvas::DrawPath(Path path, Paint paint) {
109109
entity.SetTransformation(GetCurrentTransformation());
110110
entity.SetPath(std::move(path));
111111
entity.SetStencilDepth(GetStencilDepth());
112+
entity.SetBlendMode(paint.blend_mode);
112113
entity.SetContents(paint.CreateContentsForEntity());
113114

114115
GetCurrentPass().AddEntity(std::move(entity));
@@ -118,6 +119,7 @@ void Canvas::DrawPaint(Paint paint) {
118119
Entity entity;
119120
entity.SetTransformation(GetCurrentTransformation());
120121
entity.SetStencilDepth(GetStencilDepth());
122+
entity.SetBlendMode(paint.blend_mode);
121123
entity.SetContents(
122124
std::make_shared<ClearContents>(paint.CreateContentsForEntity()));
123125

@@ -227,6 +229,7 @@ void Canvas::DrawImageRect(std::shared_ptr<Image> image,
227229

228230
Entity entity;
229231
entity.SetPath(PathBuilder{}.AddRect(dest).TakePath());
232+
entity.SetBlendMode(paint.blend_mode);
230233
entity.SetContents(contents);
231234
entity.SetTransformation(GetCurrentTransformation());
232235

@@ -284,6 +287,7 @@ void Canvas::DrawTextFrame(TextFrame text_frame,
284287
Matrix::MakeTranslation(position));
285288
entity.SetPath({});
286289
entity.SetStencilDepth(GetStencilDepth());
290+
entity.SetBlendMode(paint.blend_mode);
287291
entity.SetContents(std::move(text_contents));
288292

289293
GetCurrentPass().AddEntity(std::move(entity));

impeller/aiks/paint.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "flutter/fml/macros.h"
1010
#include "impeller/entity/contents/contents.h"
11+
#include "impeller/entity/entity.h"
1112
#include "impeller/geometry/color.h"
1213

1314
namespace impeller {
@@ -21,6 +22,7 @@ struct Paint {
2122
Color color = Color::Black();
2223
Scalar stroke_width = 0.0;
2324
Style style = Style::kFill;
25+
Entity::BlendMode blend_mode = Entity::BlendMode::kSourceOver;
2426
std::shared_ptr<Contents> contents;
2527

2628
std::shared_ptr<Contents> CreateContentsForEntity() const;

impeller/display_list/display_list_dispatcher.cc

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "flutter/fml/trace_event.h"
88
#include "impeller/entity/contents/linear_gradient_contents.h"
9+
#include "impeller/entity/entity.h"
910
#include "impeller/geometry/path_builder.h"
1011
#include "impeller/typographer/backends/skia/text_frame_skia.h"
1112
#include "third_party/skia/include/core/SkColor.h"
@@ -158,7 +159,69 @@ void DisplayListDispatcher::setInvertColors(bool invert) {
158159

159160
// |flutter::Dispatcher|
160161
void DisplayListDispatcher::setBlendMode(SkBlendMode mode) {
161-
UNIMPLEMENTED;
162+
switch (mode) {
163+
case SkBlendMode::kClear:
164+
paint_.blend_mode = Entity::BlendMode::kClear;
165+
break;
166+
case SkBlendMode::kSrc:
167+
paint_.blend_mode = Entity::BlendMode::kSource;
168+
break;
169+
case SkBlendMode::kDst:
170+
paint_.blend_mode = Entity::BlendMode::kDestination;
171+
break;
172+
case SkBlendMode::kSrcOver:
173+
paint_.blend_mode = Entity::BlendMode::kSourceOver;
174+
break;
175+
case SkBlendMode::kDstOver:
176+
paint_.blend_mode = Entity::BlendMode::kDestinationOver;
177+
break;
178+
case SkBlendMode::kSrcIn:
179+
paint_.blend_mode = Entity::BlendMode::kSourceIn;
180+
break;
181+
case SkBlendMode::kDstIn:
182+
paint_.blend_mode = Entity::BlendMode::kDestinationIn;
183+
break;
184+
case SkBlendMode::kSrcOut:
185+
paint_.blend_mode = Entity::BlendMode::kSourceOut;
186+
break;
187+
case SkBlendMode::kDstOut:
188+
paint_.blend_mode = Entity::BlendMode::kDestinationOut;
189+
break;
190+
case SkBlendMode::kSrcATop:
191+
paint_.blend_mode = Entity::BlendMode::kSourceATop;
192+
break;
193+
case SkBlendMode::kDstATop:
194+
paint_.blend_mode = Entity::BlendMode::kDestinationATop;
195+
break;
196+
case SkBlendMode::kXor:
197+
paint_.blend_mode = Entity::BlendMode::kXor;
198+
break;
199+
case SkBlendMode::kPlus:
200+
paint_.blend_mode = Entity::BlendMode::kPlus;
201+
break;
202+
case SkBlendMode::kModulate:
203+
paint_.blend_mode = Entity::BlendMode::kModulate;
204+
break;
205+
case SkBlendMode::kScreen:
206+
case SkBlendMode::kOverlay:
207+
case SkBlendMode::kDarken:
208+
case SkBlendMode::kLighten:
209+
case SkBlendMode::kColorDodge:
210+
case SkBlendMode::kColorBurn:
211+
case SkBlendMode::kHardLight:
212+
case SkBlendMode::kSoftLight:
213+
case SkBlendMode::kDifference:
214+
case SkBlendMode::kExclusion:
215+
case SkBlendMode::kMultiply:
216+
case SkBlendMode::kHue:
217+
case SkBlendMode::kSaturation:
218+
case SkBlendMode::kColor:
219+
case SkBlendMode::kLuminosity:
220+
// Non-pipeline-friendly blend modes are not supported by setBlendMode
221+
// yet.
222+
UNIMPLEMENTED;
223+
break;
224+
}
162225
}
163226

164227
// |flutter::Dispatcher|

impeller/entity/contents/clip_contents.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ bool ClipContents::Render(const ContentContext& renderer,
2727

2828
Command cmd;
2929
cmd.label = "Clip";
30-
cmd.pipeline = renderer.GetClipPipeline(OptionsFromPass(pass));
30+
cmd.pipeline =
31+
renderer.GetClipPipeline(OptionsFromPassAndEntity(pass, entity));
3132
cmd.stencil_reference = entity.GetStencilDepth();
3233
cmd.BindVertices(SolidColorContents::CreateSolidFillVertices(
3334
entity.GetPath(), pass.GetTransientsBuffer()));
@@ -59,7 +60,8 @@ bool ClipRestoreContents::Render(const ContentContext& renderer,
5960

6061
Command cmd;
6162
cmd.label = "Clip Restore";
62-
cmd.pipeline = renderer.GetClipRestorePipeline(OptionsFromPass(pass));
63+
cmd.pipeline =
64+
renderer.GetClipRestorePipeline(OptionsFromPassAndEntity(pass, entity));
6365
cmd.stencil_reference = entity.GetStencilDepth();
6466

6567
// Create a rect that covers the whole render target.

impeller/entity/contents/contents.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ ContentContextOptions OptionsFromPass(const RenderPass& pass) {
1515
return opts;
1616
}
1717

18+
ContentContextOptions OptionsFromPassAndEntity(const RenderPass& pass,
19+
const Entity& entity) {
20+
ContentContextOptions opts;
21+
opts.sample_count = pass.GetRenderTarget().GetSampleCount();
22+
opts.blend_mode = entity.GetBlendMode();
23+
return opts;
24+
}
25+
1826
Contents::Contents() = default;
1927

2028
Contents::~Contents() = default;

impeller/entity/contents/contents.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ class RenderPass;
2020

2121
ContentContextOptions OptionsFromPass(const RenderPass& pass);
2222

23+
ContentContextOptions OptionsFromPassAndEntity(const RenderPass& pass,
24+
const Entity& entity);
25+
2326
class Contents {
2427
public:
2528
Contents();

impeller/entity/contents/linear_gradient_contents.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ bool LinearGradientContents::Render(const ContentContext& renderer,
6666

6767
Command cmd;
6868
cmd.label = "LinearGradientFill";
69-
cmd.pipeline = renderer.GetGradientFillPipeline(OptionsFromPass(pass));
69+
cmd.pipeline =
70+
renderer.GetGradientFillPipeline(OptionsFromPassAndEntity(pass, entity));
7071
cmd.stencil_reference = entity.GetStencilDepth();
7172
cmd.BindVertices(
7273
vertices_builder.CreateVertexBuffer(pass.GetTransientsBuffer()));

impeller/entity/contents/solid_color_contents.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ bool SolidColorContents::Render(const ContentContext& renderer,
5454

5555
Command cmd;
5656
cmd.label = "SolidFill";
57-
cmd.pipeline = renderer.GetSolidFillPipeline(OptionsFromPass(pass));
57+
cmd.pipeline =
58+
renderer.GetSolidFillPipeline(OptionsFromPassAndEntity(pass, entity));
5859
cmd.stencil_reference = entity.GetStencilDepth();
5960
cmd.BindVertices(
6061
CreateSolidFillVertices(entity.GetPath(), pass.GetTransientsBuffer()));

impeller/entity/contents/solid_stroke_contents.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ bool SolidStrokeContents::Render(const ContentContext& renderer,
149149
Command cmd;
150150
cmd.primitive_type = PrimitiveType::kTriangleStrip;
151151
cmd.label = "SolidStroke";
152-
cmd.pipeline = renderer.GetSolidStrokePipeline(OptionsFromPass(pass));
152+
cmd.pipeline =
153+
renderer.GetSolidStrokePipeline(OptionsFromPassAndEntity(pass, entity));
153154
cmd.stencil_reference = entity.GetStencilDepth();
154155
cmd.BindVertices(CreateSolidStrokeVertices(
155156
entity.GetPath(), pass.GetTransientsBuffer(), cap_proc_, join_proc_,

0 commit comments

Comments
 (0)