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

[Impeller] Fix incorrect rendering path when duplicated point exists. #40115

Merged
merged 9 commits into from
Mar 14, 2023

Conversation

luckysmg
Copy link
Contributor

@luckysmg luckysmg commented Mar 7, 2023

Playground test case in this patch

Code
TEST_P(DisplayListTest, StrokedPathsDrawCorrectly) {
  auto callback = [&]() {
    flutter::DisplayListBuilder builder;
    builder.setColor(SK_ColorRED);
    builder.setStyle(flutter::DlDrawStyle::kStroke);

    static float stroke_width = 10.0f;
    static int selected_stroke_type = 0;
    static int selected_join_type = 0;
    const char* stroke_types[] = {"Butte", "Round", "Square"};
    const char* join_type[] = {"kMiter", "Round", "kBevel"};

    ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
    ImGui::Combo("Cap", &selected_stroke_type, stroke_types,
                 sizeof(stroke_types) / sizeof(char*));
    ImGui::Combo("Join", &selected_join_type, join_type,
                 sizeof(join_type) / sizeof(char*));
    ImGui::SliderFloat("Stroke Width", &stroke_width, 10.0f, 50.0f);
    ImGui::End();

    flutter::DlStrokeCap cap;
    flutter::DlStrokeJoin join;
    switch (selected_stroke_type) {
      case 0:
        cap = flutter::DlStrokeCap::kButt;
        break;
      case 1:
        cap = flutter::DlStrokeCap::kRound;
        break;
      case 2:
        cap = flutter::DlStrokeCap::kSquare;
        break;
      default:
        cap = flutter::DlStrokeCap::kButt;
        break;
    }
    switch (selected_join_type) {
      case 0:
        join = flutter::DlStrokeJoin::kMiter;
        break;
      case 1:
        join = flutter::DlStrokeJoin::kRound;
        break;
      case 2:
        join = flutter::DlStrokeJoin::kBevel;
        break;
      default:
        join = flutter::DlStrokeJoin::kMiter;
        break;
    }
    builder.setStrokeCap(cap);
    builder.setStrokeJoin(join);
    builder.setStrokeWidth(stroke_width);

    // Make rendering better to watch.
    builder.scale(1.5f, 1.5f);

    // Rectangle
    builder.translate(100, 100);
    builder.drawRect(SkRect::MakeSize({100, 100}));

    // Rounded rectangle
    builder.translate(150, 0);
    builder.drawRRect(SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10));

    // Double rounded rectangle
    builder.translate(150, 0);
    builder.drawDRRect(
        SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10),
        SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 10, 80, 30), 10, 10));

    // Contour with duplicate join points
    {
      builder.translate(150, 0);
      SkPath path;
      path.moveTo(0, 0);
      path.lineTo(0, 0);
      path.lineTo({100, 0});
      path.lineTo({100, 0});
      path.lineTo({100, 100});
      builder.drawPath(path);
    }

    // Contour with duplicate start and end points

    // Line.
    builder.translate(200, 0);
    {
      builder.save();

      SkPath line_path;
      line_path.moveTo(0, 0);
      line_path.moveTo(0, 0);
      line_path.lineTo({0, 0});
      line_path.lineTo({0, 0});
      line_path.lineTo({50, 50});
      line_path.lineTo({50, 50});
      line_path.lineTo({100, 0});
      line_path.lineTo({100, 0});
      builder.drawPath(line_path);

      builder.translate(0, 100);
      builder.drawPath(line_path);

      builder.translate(0, 100);
      SkPath line_path2;
      line_path2.moveTo(0, 0);
      line_path2.lineTo(0, 0);
      line_path2.lineTo(0, 0);
      builder.drawPath(line_path2);

      builder.restore();
    }

    // Cubic.
    builder.translate(150, 0);
    {
      builder.save();

      SkPath cubic_path;
      cubic_path.moveTo({0, 0});
      cubic_path.cubicTo(0, 0, 140.0, 100.0, 140, 20);
      builder.drawPath(cubic_path);

      builder.translate(0, 100);
      SkPath cubic_path2;
      cubic_path2.moveTo({0, 0});
      cubic_path2.cubicTo(0, 0, 0, 0, 150, 150);
      builder.drawPath(cubic_path2);

      builder.translate(0, 100);
      SkPath cubic_path3;
      cubic_path3.moveTo({0, 0});
      cubic_path3.cubicTo(0, 0, 0, 0, 0, 0);
      builder.drawPath(cubic_path3);

      builder.restore();
    }

    // Quad.
    builder.translate(200, 0);
    {
      builder.save();

      SkPath quad_path;
      quad_path.moveTo(0, 0);
      quad_path.moveTo(0, 0);
      quad_path.quadTo({100, 40}, {50, 80});
      builder.drawPath(quad_path);

      builder.translate(0, 150);
      SkPath quad_path2;
      quad_path2.moveTo(0, 0);
      quad_path2.moveTo(0, 0);
      quad_path2.quadTo({0, 0}, {100, 100});
      builder.drawPath(quad_path2);

      builder.translate(0, 100);
      SkPath quad_path3;
      quad_path3.moveTo(0, 0);
      quad_path3.quadTo({0, 0}, {0, 0});
      builder.drawPath(quad_path3);

      builder.restore();
    }
    return builder.Build();
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

Before:

Before.mp4

After:

After.mp4

Test Recheck CanDrawCapsAndJoins

Test case in flutter/flutter#119964

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides].
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See [testing the engine] for instructions on writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the [CLA].
  • All existing and new tests are passing.

@luckysmg luckysmg changed the title [WIP][Impeller] Fix incorrect rendering when duplicated path component exists. [WIP][Impeller] Fix incorrect rendering path when duplicated point exists. Mar 8, 2023
@luckysmg luckysmg changed the title [WIP][Impeller] Fix incorrect rendering path when duplicated point exists. [WIP][Impeller] Fix incorrect rendering path when duplicated points exists. Mar 8, 2023
@luckysmg luckysmg changed the title [WIP][Impeller] Fix incorrect rendering path when duplicated points exists. [Impeller] Fix incorrect rendering path when duplicated points exists. Mar 9, 2023
@luckysmg luckysmg changed the title [Impeller] Fix incorrect rendering path when duplicated points exists. [Impeller] Fix incorrect rendering path when duplicated point exists. Mar 9, 2023
@luckysmg luckysmg marked this pull request as ready for review March 9, 2023 09:15
@chinmaygarde
Copy link
Member

cc @dnfield @bdero

Copy link
Member

@chinmaygarde chinmaygarde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes sense but @dnfield might have more comments. I'll defer to his review is he is able.

@@ -245,7 +245,7 @@ Path::Polyline Path::CreatePolyline(Scalar scale) const {

auto get_path_component =
[this](size_t component_i) -> std::optional<const PathComponent*> {
if (component_i >= components_.size()) {
if (component_i < 0 || component_i >= components_.size()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

component_i is unsigned. Is this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad. Should all be size_t instead of int. Done ^_^

@luckysmg luckysmg requested a review from dnfield March 13, 2023 05:37
Copy link
Contributor

@dnfield dnfield left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM.

It does make me wonder if we should just silently elide duplicate components.

@dnfield dnfield added the autosubmit Merge PR when tree becomes green via auto submit App label Mar 14, 2023
@auto-submit auto-submit bot merged commit 0fca429 into flutter:main Mar 14, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 14, 2023
@luckysmg luckysmg deleted the path_fix branch March 14, 2023 02:05
auto-submit bot pushed a commit to flutter/flutter that referenced this pull request Mar 14, 2023
…nt exists. (flutter/engine#40115) (#122569)

Roll Flutter Engine from cbc8ae897cd1 to 0fca429de53f (1 revision)
sourcegraph-bot pushed a commit to sgtest/megarepo that referenced this pull request Mar 14, 2023
…cated point exists. (flutter/engine#40115) (#122569)

Commit: 713842fb5ba4cb1b9c2ce2fb1e4770f0f4498e13
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 14, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 14, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 10, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 10, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
autosubmit Merge PR when tree becomes green via auto submit App e: impeller
Projects
No open projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants