Skip to content

Commit ac10b79

Browse files
chinmaygardednfield
authored andcommitted
Rendering of continuous strokes.
1 parent 41ed619 commit ac10b79

14 files changed

+164
-7
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@ TEST_F(AiksTest, CanRenderStrokes) {
8181
Paint paint;
8282
paint.color = Color::Red();
8383
paint.stroke_width = 20.0;
84+
paint.style = Paint::Style::kStroke;
85+
canvas.DrawPath(PathBuilder{}.AddLine({200, 100}, {800, 100}).CreatePath(),
86+
paint);
87+
// ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
88+
}
89+
90+
TEST_F(AiksTest, CanRenderCurvedStrokes) {
91+
Canvas canvas;
92+
Paint paint;
93+
paint.color = Color::Blue();
94+
paint.stroke_width = 25.0;
95+
paint.style = Paint::Style::kStroke;
8496
canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).CreatePath(), paint);
8597
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
8698
}

impeller/entity/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ impeller_shaders("entity_shaders") {
1212
"shaders/gradient_fill.vert",
1313
"shaders/solid_fill.frag",
1414
"shaders/solid_fill.vert",
15+
"shaders/solid_stroke.frag",
16+
"shaders/solid_stroke.vert",
1517
"shaders/texture_fill.frag",
1618
"shaders/texture_fill.vert",
1719
]

impeller/entity/content_renderer.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ ContentRenderer::ContentRenderer(std::shared_ptr<Context> context)
1515
gradient_fill_pipeline_ = std::make_unique<GradientFillPipeline>(*context_);
1616
solid_fill_pipeline_ = std::make_unique<SolidFillPipeline>(*context_);
1717
texture_pipeline_ = std::make_unique<TexturePipeline>(*context_);
18+
solid_stroke_pipeline_ = std::make_unique<SolidStrokePipeline>(*context_);
1819

1920
is_valid_ = true;
2021
}
@@ -52,4 +53,12 @@ std::shared_ptr<Pipeline> ContentRenderer::GetTexturePipeline() const {
5253
return texture_pipeline_->WaitAndGet();
5354
}
5455

56+
std::shared_ptr<Pipeline> ContentRenderer::GetSolidStrokePipeline() const {
57+
if (!IsValid()) {
58+
return nullptr;
59+
}
60+
61+
return solid_stroke_pipeline_->WaitAndGet();
62+
}
63+
5564
} // namespace impeller

impeller/entity/content_renderer.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include "flutter/impeller/entity/gradient_fill.vert.h"
1212
#include "flutter/impeller/entity/solid_fill.frag.h"
1313
#include "flutter/impeller/entity/solid_fill.vert.h"
14+
#include "flutter/impeller/entity/solid_stroke.frag.h"
15+
#include "flutter/impeller/entity/solid_stroke.vert.h"
1416
#include "flutter/impeller/entity/texture_fill.frag.h"
1517
#include "flutter/impeller/entity/texture_fill.vert.h"
1618
#include "impeller/renderer/pipeline.h"
@@ -23,6 +25,8 @@ using SolidFillPipeline =
2325
PipelineT<SolidFillVertexShader, SolidFillFragmentShader>;
2426
using TexturePipeline =
2527
PipelineT<TextureFillVertexShader, TextureFillFragmentShader>;
28+
using SolidStrokePipeline =
29+
PipelineT<SolidStrokeVertexShader, SolidStrokeFragmentShader>;
2630

2731
class ContentRenderer {
2832
public:
@@ -38,13 +42,16 @@ class ContentRenderer {
3842

3943
std::shared_ptr<Pipeline> GetTexturePipeline() const;
4044

45+
std::shared_ptr<Pipeline> GetSolidStrokePipeline() const;
46+
4147
std::shared_ptr<Context> GetContext() const;
4248

4349
private:
4450
std::shared_ptr<Context> context_;
4551
std::unique_ptr<GradientFillPipeline> gradient_fill_pipeline_;
4652
std::unique_ptr<SolidFillPipeline> solid_fill_pipeline_;
4753
std::unique_ptr<TexturePipeline> texture_pipeline_;
54+
std::unique_ptr<SolidStrokePipeline> solid_stroke_pipeline_;
4855
bool is_valid_ = false;
4956

5057
FML_DISALLOW_COPY_AND_ASSIGN(ContentRenderer);

impeller/entity/contents.cc

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "impeller/entity/content_renderer.h"
1111
#include "impeller/entity/entity.h"
1212
#include "impeller/geometry/path_builder.h"
13+
#include "impeller/geometry/vector.h"
1314
#include "impeller/renderer/render_pass.h"
1415
#include "impeller/renderer/sampler_library.h"
1516
#include "impeller/renderer/surface.h"
@@ -236,13 +237,11 @@ bool TextureContents::Render(const ContentRenderer& renderer,
236237
frame_info.mvp =
237238
Matrix::MakeOrthographic(surface.GetSize()) * entity.GetTransformation();
238239

239-
auto frame_info_view = host_buffer.EmplaceUniform(frame_info);
240-
241240
Command cmd;
242241
cmd.label = "TextureFill";
243242
cmd.pipeline = renderer.GetTexturePipeline();
244243
cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer));
245-
VS::BindFrameInfo(cmd, frame_info_view);
244+
VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
246245
FS::BindTextureSampler(
247246
cmd, texture_,
248247
renderer.GetContext()->GetSamplerLibrary()->GetSampler({}));
@@ -275,6 +274,45 @@ const Color& SolidStrokeContents::GetColor() const {
275274
return color_;
276275
}
277276

277+
static VertexBuffer CreateSolidStrokeVertices(const Path& path,
278+
HostBuffer& buffer) {
279+
using VS = SolidStrokeVertexShader;
280+
281+
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
282+
auto polyline = path.CreatePolyline();
283+
284+
for (size_t i = 0, polyline_size = polyline.size(); i < polyline_size; i++) {
285+
const auto is_last_point = i == polyline_size - 1;
286+
287+
const auto& p1 = polyline[i];
288+
const auto& p2 = is_last_point ? polyline[i - 1] : polyline[i + 1];
289+
290+
const auto diff = p2 - p1;
291+
292+
const Scalar direction = is_last_point ? -1.0 : 1.0;
293+
294+
const auto normal =
295+
Point{-diff.y * direction, diff.x * direction}.Normalize();
296+
297+
VS::PerVertexData vtx;
298+
vtx.vertex_position = p1;
299+
300+
if (i == 0) {
301+
vtx.vertex_normal = -normal;
302+
vtx_builder.AppendVertex(vtx);
303+
vtx.vertex_normal = normal;
304+
vtx_builder.AppendVertex(vtx);
305+
}
306+
307+
vtx.vertex_normal = normal;
308+
vtx_builder.AppendVertex(vtx);
309+
vtx.vertex_normal = -normal;
310+
vtx_builder.AppendVertex(vtx);
311+
}
312+
313+
return vtx_builder.CreateVertexBuffer(buffer);
314+
}
315+
278316
bool SolidStrokeContents::Render(const ContentRenderer& renderer,
279317
const Entity& entity,
280318
const Surface& surface,
@@ -283,7 +321,29 @@ bool SolidStrokeContents::Render(const ContentRenderer& renderer,
283321
return true;
284322
}
285323

286-
return false;
324+
using VS = SolidStrokeVertexShader;
325+
326+
VS::FrameInfo frame_info;
327+
frame_info.mvp =
328+
Matrix::MakeOrthographic(surface.GetSize()) * entity.GetTransformation();
329+
330+
VS::StrokeInfo stroke_info;
331+
stroke_info.color = color_;
332+
stroke_info.size = stroke_size_;
333+
334+
Command cmd;
335+
cmd.primitive_type = PrimitiveType::kTriangleStrip;
336+
cmd.label = "SolidStroke";
337+
cmd.pipeline = renderer.GetSolidStrokePipeline();
338+
cmd.BindVertices(
339+
CreateSolidStrokeVertices(entity.GetPath(), pass.GetTransientsBuffer()));
340+
VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info));
341+
VS::BindStrokeInfo(cmd,
342+
pass.GetTransientsBuffer().EmplaceUniform(stroke_info));
343+
344+
pass.AddCommand(std::move(cmd));
345+
346+
return true;
287347
}
288348

289349
void SolidStrokeContents::SetStrokeSize(Scalar size) {
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+
in vec4 stroke_color;
6+
7+
out vec4 frag_color;
8+
9+
void main() {
10+
frag_color = stroke_color;
11+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
uniform FrameInfo {
6+
mat4 mvp;
7+
} frame_info;
8+
9+
uniform StrokeInfo {
10+
vec4 color;
11+
float size;
12+
} stroke_info;
13+
14+
in vec2 vertex_position;
15+
in vec2 vertex_normal;
16+
17+
out vec4 stroke_color;
18+
19+
void main() {
20+
vec2 offset = vertex_normal * vec2(stroke_info.size * 0.5);
21+
gl_Position = frame_info.mvp * vec4(vertex_position + offset, 0.0, 1.0);
22+
stroke_color = stroke_info.color;
23+
}

impeller/geometry/path_builder.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,11 @@ PathBuilder& PathBuilder::AddOval(const Rect& container) {
298298
return *this;
299299
}
300300

301+
PathBuilder& PathBuilder::AddLine(const Point& p1, const Point& p2) {
302+
prototype_.AddLinearComponent(p1, p2);
303+
return *this;
304+
}
305+
301306
const Path& PathBuilder::GetCurrentPath() const {
302307
return prototype_;
303308
}

impeller/geometry/path_builder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class PathBuilder {
5454

5555
PathBuilder& AddOval(const Rect& rect);
5656

57+
PathBuilder& AddLine(const Point& p1, const Point& p2);
58+
5759
struct RoundingRadii {
5860
Scalar topLeft = 0.0;
5961
Scalar bottomLeft = 0.0;

impeller/geometry/point.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ struct TPoint {
8686
constexpr Type GetDistance(const TPoint& p) const {
8787
return sqrt(GetDistanceSquared(p));
8888
}
89+
90+
constexpr Type GetLengthSquared() const { return GetDistanceSquared({}); }
91+
92+
constexpr Type GetLength() const { return GetDistance({}); }
93+
94+
constexpr TPoint Normalize() const {
95+
const auto length = GetLength();
96+
if (length == 0) {
97+
return {};
98+
}
99+
return {x / length, y / length};
100+
}
89101
};
90102

91103
using Point = TPoint<Scalar>;

impeller/renderer/backend/metal/vertex_descriptor_mtl.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include <Metal/Metal.h>
66

7+
#include <set>
8+
79
#include "flutter/fml/macros.h"
810
#include "impeller/renderer/backend/metal/backend_cast.h"
911
#include "impeller/renderer/vertex_descriptor.h"
@@ -28,8 +30,15 @@ class VertexDescriptorMTL {
2830

2931
StageInput(size_t p_location, MTLVertexFormat p_format, size_t p_length)
3032
: location(p_location), format(p_format), length(p_length) {}
33+
34+
struct Compare {
35+
constexpr bool operator()(const StageInput& lhs,
36+
const StageInput& rhs) const {
37+
return lhs.location < rhs.location;
38+
}
39+
};
3140
};
32-
std::vector<StageInput> stage_inputs_;
41+
std::set<StageInput, StageInput::Compare> stage_inputs_;
3342

3443
FML_DISALLOW_COPY_AND_ASSIGN(VertexDescriptorMTL);
3544
};

impeller/renderer/backend/metal/vertex_descriptor_mtl.mm

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,9 @@ static MTLVertexFormat ReadStageInputFormat(const ShaderStageIOSlot& input) {
179179
FML_LOG(ERROR) << "Format for input " << input.name << " not supported.";
180180
return false;
181181
}
182-
stage_inputs_.emplace_back(StageInput{
183-
input.location, vertex_format, (input.bit_width * input.vec_size) / 8});
182+
183+
stage_inputs_.insert(StageInput{input.location, vertex_format,
184+
(input.bit_width * input.vec_size) / 8});
184185
}
185186

186187
return true;

impeller/renderer/shader_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ struct ShaderUniformSlot {
5050

5151
struct ShaderStageIOSlot {
5252
// Statically allocated const string containing advisory debug description.
53+
// This may be absent in release modes and the runtime may not use this string
54+
// for normal operation.
5355
const char* name;
5456
size_t location;
5557
size_t set;

impeller/renderer/vertex_buffer_builder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class VertexBufferBuilder {
3535

3636
bool HasVertices() const { return !vertices_.empty(); }
3737

38+
size_t GetVertexCount() const { return vertices_.size(); }
39+
3840
VertexBufferBuilder& AppendVertex(VertexType_ vertex) {
3941
vertices_.emplace_back(std::move(vertex));
4042
return *this;

0 commit comments

Comments
 (0)