Skip to content

Commit

Permalink
Setup join/cap proc (flutter#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdero authored and dnfield committed Apr 27, 2022
1 parent c11f408 commit a781e2f
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 39 deletions.
94 changes: 59 additions & 35 deletions impeller/entity/contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,11 @@ const IRect& TextureContents::GetSourceRect() const {
******* SolidStrokeContents
******************************************************************************/

SolidStrokeContents::SolidStrokeContents() = default;
SolidStrokeContents::SolidStrokeContents() {
SetStrokeCap(Cap::kButt);
// TODO(99089): Change this to kMiter once implemented.
SetStrokeJoin(Join::kBevel);
}

SolidStrokeContents::~SolidStrokeContents() = default;

Expand All @@ -294,32 +298,11 @@ const Color& SolidStrokeContents::GetColor() const {
return color_;
}

static void CreateCap(
VertexBufferBuilder<SolidStrokeVertexShader::PerVertexData>& vtx_builder,
const Point& position,
const Point& normal) {}

static void CreateJoin(
VertexBufferBuilder<SolidStrokeVertexShader::PerVertexData>& vtx_builder,
const Point& position,
const Point& start_normal,
const Point& end_normal) {
SolidStrokeVertexShader::PerVertexData vtx;
vtx.vertex_position = position;
vtx.pen_down = 1.0;
vtx.vertex_normal = {};
vtx_builder.AppendVertex(vtx);

// A simple bevel join to start with.
Scalar dir = start_normal.Cross(end_normal) > 0 ? -1 : 1;
vtx.vertex_normal = start_normal * dir;
vtx_builder.AppendVertex(vtx);
vtx.vertex_normal = end_normal * dir;
vtx_builder.AppendVertex(vtx);
}

static VertexBuffer CreateSolidStrokeVertices(const Path& path,
HostBuffer& buffer) {
static VertexBuffer CreateSolidStrokeVertices(
const Path& path,
HostBuffer& buffer,
const SolidStrokeContents::CapProc& cap_proc,
const SolidStrokeContents::JoinProc& join_proc) {
using VS = SolidStrokeVertexShader;

VertexBufferBuilder<VS::PerVertexData> vtx_builder;
Expand Down Expand Up @@ -372,7 +355,7 @@ static VertexBuffer CreateSolidStrokeVertices(const Path& path,

// Generate start cap.
if (!polyline.contours[contour_i].is_closed) {
CreateCap(vtx_builder, polyline.points[contour_start_point_i], -normal);
cap_proc(vtx_builder, polyline.points[contour_start_point_i], -normal);
}

// Generate contour geometry.
Expand All @@ -396,18 +379,18 @@ static VertexBuffer CreateSolidStrokeVertices(const Path& path,
compute_normal(point_i + 1);

// Generate join from the current line to the next line.
CreateJoin(vtx_builder, polyline.points[point_i], previous_normal,
normal);
join_proc(vtx_builder, polyline.points[point_i], previous_normal,
normal);
}
}
}

// Generate end cap or join.
if (!polyline.contours[contour_i].is_closed) {
CreateCap(vtx_builder, polyline.points[contour_end_point_i - 1], normal);
cap_proc(vtx_builder, polyline.points[contour_end_point_i - 1], normal);
} else {
CreateJoin(vtx_builder, polyline.points[contour_start_point_i], normal,
contour_first_normal);
join_proc(vtx_builder, polyline.points[contour_start_point_i], normal,
contour_first_normal);
}
}

Expand Down Expand Up @@ -436,8 +419,8 @@ bool SolidStrokeContents::Render(const ContentContext& renderer,
cmd.label = "SolidStroke";
cmd.pipeline = renderer.GetSolidStrokePipeline(OptionsFromPass(pass));
cmd.stencil_reference = entity.GetStencilDepth();
cmd.BindVertices(
CreateSolidStrokeVertices(entity.GetPath(), pass.GetTransientsBuffer()));
cmd.BindVertices(CreateSolidStrokeVertices(
entity.GetPath(), pass.GetTransientsBuffer(), cap_proc_, join_proc_));
VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info));
VS::BindStrokeInfo(cmd,
pass.GetTransientsBuffer().EmplaceUniform(stroke_info));
Expand Down Expand Up @@ -465,6 +448,20 @@ Scalar SolidStrokeContents::GetStrokeMiter(Scalar miter) {

void SolidStrokeContents::SetStrokeCap(Cap cap) {
cap_ = cap;

using VS = SolidStrokeVertexShader;
switch (cap) {
case Cap::kButt:
cap_proc_ = [](VertexBufferBuilder<VS::PerVertexData>& vtx_builder,
const Point& position, const Point& normal) {};
break;
case Cap::kRound:
FML_DLOG(ERROR) << "Unimplemented.";
break;
case Cap::kSquare:
FML_DLOG(ERROR) << "Unimplemented.";
break;
}
}

SolidStrokeContents::Cap SolidStrokeContents::GetStrokeCap() {
Expand All @@ -473,6 +470,33 @@ SolidStrokeContents::Cap SolidStrokeContents::GetStrokeCap() {

void SolidStrokeContents::SetStrokeJoin(Join join) {
join_ = join;

using VS = SolidStrokeVertexShader;
switch (join) {
case Join::kBevel:
join_proc_ = [](VertexBufferBuilder<VS::PerVertexData>& vtx_builder,
const Point& position, const Point& start_normal,
const Point& end_normal) {
SolidStrokeVertexShader::PerVertexData vtx;
vtx.vertex_position = position;
vtx.pen_down = 1.0;
vtx.vertex_normal = {};
vtx_builder.AppendVertex(vtx);

Scalar dir = start_normal.Cross(end_normal) > 0 ? -1 : 1;
vtx.vertex_normal = start_normal * dir;
vtx_builder.AppendVertex(vtx);
vtx.vertex_normal = end_normal * dir;
vtx_builder.AppendVertex(vtx);
};
break;
case Join::kMiter:
FML_DLOG(ERROR) << "Unimplemented.";
break;
case Join::kRound:
FML_DLOG(ERROR) << "Unimplemented.";
break;
}
}

SolidStrokeContents::Join SolidStrokeContents::GetStrokeJoin() {
Expand Down
22 changes: 18 additions & 4 deletions impeller/entity/contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

#pragma once

#include <functional>
#include <memory>
#include <vector>

#include "flutter/fml/macros.h"
#include "impeller/entity/solid_stroke.vert.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/point.h"
#include "impeller/geometry/rect.h"
Expand Down Expand Up @@ -119,16 +121,24 @@ class SolidStrokeContents final : public Contents {
kButt,
kRound,
kSquare,
kLast,
};

enum class Join {
kMiter,
kRound,
kBevel,
kLast,
};

using CapProc = std::function<void(
VertexBufferBuilder<SolidStrokeVertexShader::PerVertexData>& vtx_builder,
const Point& position,
const Point& normal)>;
using JoinProc = std::function<void(
VertexBufferBuilder<SolidStrokeVertexShader::PerVertexData>& vtx_builder,
const Point& position,
const Point& start_normal,
const Point& end_normal)>;

SolidStrokeContents();

~SolidStrokeContents() override;
Expand Down Expand Up @@ -162,8 +172,12 @@ class SolidStrokeContents final : public Contents {
Color color_;
Scalar stroke_size_ = 0.0;
Scalar miter_ = 0.0;
Cap cap_ = Cap::kButt;
Join join_ = Join::kMiter;

Cap cap_;
CapProc cap_proc_;

Join join_;
JoinProc join_proc_;

FML_DISALLOW_COPY_AND_ASSIGN(SolidStrokeContents);
};
Expand Down
9 changes: 9 additions & 0 deletions impeller/entity/entity_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "entity/contents.h"
#include "flutter/testing/testing.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/entity_playground.h"
Expand Down Expand Up @@ -328,5 +329,13 @@ TEST_F(EntityTest, CubicCurveAndOverlapTest) {
ASSERT_TRUE(OpenPlaygroundHere(entity));
}

TEST_F(EntityTest, SolidStrokeContentsSetStrokeDefaults) {
SolidStrokeContents stroke;
ASSERT_EQ(stroke.GetStrokeCap(), SolidStrokeContents::Cap::kButt);
ASSERT_EQ(stroke.GetStrokeJoin(), SolidStrokeContents::Join::kBevel);
// TODO(99089): Test that SetStroke[Cap|Join] works once there are multiple
// caps and joins.
}

} // namespace testing
} // namespace impeller

0 comments on commit a781e2f

Please sign in to comment.