Reverts flutter/flutter#166591 Golden diffs were not discovered the first time this was submitted. Re-submitting to double check the goldens.
This commit is contained in:
parent
a56ff4890d
commit
790d1b1d9a
@ -5,8 +5,8 @@
|
|||||||
#include "flutter/display_list/geometry/dl_path.h"
|
#include "flutter/display_list/geometry/dl_path.h"
|
||||||
|
|
||||||
#include "flutter/display_list/geometry/dl_geometry_types.h"
|
#include "flutter/display_list/geometry/dl_geometry_types.h"
|
||||||
|
#include "flutter/impeller/geometry/path.h"
|
||||||
#include "flutter/impeller/geometry/path_builder.h"
|
#include "flutter/impeller/geometry/path_builder.h"
|
||||||
#include "impeller/geometry/path.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
inline constexpr flutter::DlPathFillType ToDlFillType(SkPathFillType sk_type) {
|
inline constexpr flutter::DlPathFillType ToDlFillType(SkPathFillType sk_type) {
|
||||||
@ -452,9 +452,10 @@ class ImpellerPathReceiver final : public DlPathReceiver {
|
|||||||
void QuadTo(const DlPoint& cp, const DlPoint& p2) override {
|
void QuadTo(const DlPoint& cp, const DlPoint& p2) override {
|
||||||
builder_.QuadraticCurveTo(cp, p2);
|
builder_.QuadraticCurveTo(cp, p2);
|
||||||
}
|
}
|
||||||
// For legacy compatibility we do not override ConicTo to let the dispatcher
|
bool ConicTo(const DlPoint& cp, const DlPoint& p2, DlScalar weight) override {
|
||||||
// convert conics to quads until we update Impeller for full support of
|
builder_.ConicCurveTo(cp, p2, weight);
|
||||||
// rational quadratics
|
return true;
|
||||||
|
}
|
||||||
void CubicTo(const DlPoint& cp1,
|
void CubicTo(const DlPoint& cp1,
|
||||||
const DlPoint& cp2,
|
const DlPoint& cp2,
|
||||||
const DlPoint& p2) override {
|
const DlPoint& p2) override {
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
#include "flutter/display_list/geometry/dl_path.h"
|
#include "flutter/display_list/geometry/dl_path.h"
|
||||||
|
|
||||||
#include "gmock/gmock.h"
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "flutter/display_list/testing/dl_test_mock_path_receiver.h"
|
||||||
#include "flutter/third_party/skia/include/core/SkRRect.h"
|
#include "flutter/third_party/skia/include/core/SkRRect.h"
|
||||||
|
|
||||||
namespace flutter {
|
namespace flutter {
|
||||||
@ -595,31 +595,6 @@ TEST(DisplayListPath, IsLineFromImpellerPath) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class DlPathReceiverMock : public DlPathReceiver {
|
|
||||||
public:
|
|
||||||
MOCK_METHOD(void,
|
|
||||||
RecommendSizes,
|
|
||||||
(size_t verb_count, size_t point_count),
|
|
||||||
(override));
|
|
||||||
MOCK_METHOD(void, RecommendBounds, (const DlRect& bounds), (override));
|
|
||||||
MOCK_METHOD(void,
|
|
||||||
SetPathInfo,
|
|
||||||
(DlPathFillType fill_type, bool is_convex),
|
|
||||||
(override));
|
|
||||||
MOCK_METHOD(void, MoveTo, (const DlPoint& p2), (override));
|
|
||||||
MOCK_METHOD(void, LineTo, (const DlPoint& p2), (override));
|
|
||||||
MOCK_METHOD(void, QuadTo, (const DlPoint& cp, const DlPoint& p2), (override));
|
|
||||||
MOCK_METHOD(bool,
|
|
||||||
ConicTo,
|
|
||||||
(const DlPoint& cp, const DlPoint& p2, DlScalar weight),
|
|
||||||
(override));
|
|
||||||
MOCK_METHOD(void,
|
|
||||||
CubicTo,
|
|
||||||
(const DlPoint& cp1, const DlPoint& cp2, const DlPoint& p2),
|
|
||||||
(override));
|
|
||||||
MOCK_METHOD(void, Close, (), (override));
|
|
||||||
};
|
|
||||||
|
|
||||||
using ::testing::AtMost;
|
using ::testing::AtMost;
|
||||||
using ::testing::Return;
|
using ::testing::Return;
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -925,6 +900,104 @@ TEST(DisplayListPath, DispatchImpellerPathConvexSpecified) {
|
|||||||
path.Dispatch(mock_receiver);
|
path.Dispatch(mock_receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(DisplayListPath, DispatchSkiaPathConicToQuads) {
|
||||||
|
// If we execute conicTo with a weight of exactly 1.0, SkPath will turn
|
||||||
|
// it into a quadTo, so we avoid that by using 0.999
|
||||||
|
SkScalar weights[4] = {
|
||||||
|
0.02f,
|
||||||
|
0.5f,
|
||||||
|
SK_ScalarSqrt2 * 0.5f,
|
||||||
|
1.0f - kEhCloseEnough,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (SkScalar weight : weights) {
|
||||||
|
SkPath sk_path;
|
||||||
|
sk_path.moveTo(10, 10);
|
||||||
|
sk_path.conicTo(20, 10, 20, 20, weight);
|
||||||
|
|
||||||
|
std::array<DlPoint, 5> i_points;
|
||||||
|
impeller::ConicPathComponent i_conic(DlPoint(10, 10), DlPoint(20, 10),
|
||||||
|
DlPoint(20, 20), weight);
|
||||||
|
i_conic.SubdivideToQuadraticPoints(i_points);
|
||||||
|
|
||||||
|
::testing::StrictMock<DlPathReceiverMock> mock_receiver;
|
||||||
|
|
||||||
|
// Recommendations must happen before any of the path segments is dispatched
|
||||||
|
::testing::ExpectationSet all_recommendations;
|
||||||
|
all_recommendations += //
|
||||||
|
EXPECT_CALL(mock_receiver, RecommendSizes(2u, 3u)) //
|
||||||
|
.Times(AtMost(1));
|
||||||
|
all_recommendations +=
|
||||||
|
EXPECT_CALL(mock_receiver,
|
||||||
|
RecommendBounds(DlRect::MakeLTRB(10, 10, 20, 20)))
|
||||||
|
.Times(AtMost(1));
|
||||||
|
EXPECT_CALL(mock_receiver, SetPathInfo(DlPathFillType::kNonZero, true));
|
||||||
|
|
||||||
|
{
|
||||||
|
::testing::InSequence sequence;
|
||||||
|
|
||||||
|
EXPECT_CALL(mock_receiver, MoveTo(DlPoint(10, 10)))
|
||||||
|
.After(all_recommendations);
|
||||||
|
EXPECT_CALL(mock_receiver,
|
||||||
|
ConicTo(DlPoint(20, 10), DlPoint(20, 20), weight))
|
||||||
|
.WillOnce(Return(false));
|
||||||
|
EXPECT_CALL(mock_receiver, QuadTo(i_points[1], i_points[2]));
|
||||||
|
EXPECT_CALL(mock_receiver, QuadTo(i_points[3], i_points[4]));
|
||||||
|
}
|
||||||
|
|
||||||
|
DlPath(sk_path).Dispatch(mock_receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DisplayListPath, DispatchImpellerPathConicToQuads) {
|
||||||
|
// If we execute conicTo with a weight of exactly 1.0, SkPath will turn
|
||||||
|
// it into a quadTo, so we avoid that by using 0.999
|
||||||
|
DlScalar weights[4] = {
|
||||||
|
0.02f,
|
||||||
|
0.5f,
|
||||||
|
SK_ScalarSqrt2 * 0.5f,
|
||||||
|
1.0f - kEhCloseEnough,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (DlScalar weight : weights) {
|
||||||
|
DlPathBuilder path_builder;
|
||||||
|
path_builder.MoveTo(DlPoint(10, 10));
|
||||||
|
path_builder.ConicCurveTo(DlPoint(20, 10), DlPoint(20, 20), weight);
|
||||||
|
|
||||||
|
std::array<DlPoint, 5> i_points;
|
||||||
|
impeller::ConicPathComponent i_conic(DlPoint(10, 10), DlPoint(20, 10),
|
||||||
|
DlPoint(20, 20), weight);
|
||||||
|
i_conic.SubdivideToQuadraticPoints(i_points);
|
||||||
|
|
||||||
|
::testing::StrictMock<DlPathReceiverMock> mock_receiver;
|
||||||
|
|
||||||
|
// Recommendations must happen before any of the path segments is dispatched
|
||||||
|
::testing::ExpectationSet all_recommendations;
|
||||||
|
all_recommendations += //
|
||||||
|
EXPECT_CALL(mock_receiver, RecommendSizes(2u, 6u)) //
|
||||||
|
.Times(AtMost(1));
|
||||||
|
all_recommendations +=
|
||||||
|
EXPECT_CALL(mock_receiver,
|
||||||
|
RecommendBounds(DlRect::MakeLTRB(10, 10, 20, 20)))
|
||||||
|
.Times(AtMost(1));
|
||||||
|
EXPECT_CALL(mock_receiver, SetPathInfo(DlPathFillType::kNonZero, false));
|
||||||
|
|
||||||
|
{
|
||||||
|
::testing::InSequence sequence;
|
||||||
|
|
||||||
|
EXPECT_CALL(mock_receiver, MoveTo(DlPoint(10, 10)))
|
||||||
|
.After(all_recommendations);
|
||||||
|
EXPECT_CALL(mock_receiver,
|
||||||
|
ConicTo(DlPoint(20, 10), DlPoint(20, 20), weight))
|
||||||
|
.WillOnce(Return(false));
|
||||||
|
EXPECT_CALL(mock_receiver, QuadTo(i_points[1], i_points[2]));
|
||||||
|
EXPECT_CALL(mock_receiver, QuadTo(i_points[3], i_points[4]));
|
||||||
|
}
|
||||||
|
|
||||||
|
DlPath(path_builder).Dispatch(mock_receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// Tests that verify we don't try to use inverse path modes as they aren't
|
// Tests that verify we don't try to use inverse path modes as they aren't
|
||||||
// supported by either Flutter public APIs or Impeller
|
// supported by either Flutter public APIs or Impeller
|
||||||
|
@ -12,10 +12,11 @@
|
|||||||
#include "flutter/display_list/effects/dl_image_filters.h"
|
#include "flutter/display_list/effects/dl_image_filters.h"
|
||||||
#include "flutter/display_list/skia/dl_sk_conversions.h"
|
#include "flutter/display_list/skia/dl_sk_conversions.h"
|
||||||
#include "flutter/impeller/geometry/path_component.h"
|
#include "flutter/impeller/geometry/path_component.h"
|
||||||
|
#include "flutter/third_party/skia/include/core/SkColorSpace.h"
|
||||||
|
#include "flutter/third_party/skia/include/core/SkSamplingOptions.h"
|
||||||
|
#include "flutter/third_party/skia/include/core/SkTileMode.h"
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "third_party/skia/include/core/SkColorSpace.h"
|
|
||||||
#include "third_party/skia/include/core/SkSamplingOptions.h"
|
|
||||||
#include "third_party/skia/include/core/SkTileMode.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
namespace flutter {
|
||||||
namespace testing {
|
namespace testing {
|
||||||
@ -402,9 +403,7 @@ TEST(DisplayListSkConversions, ConicToQuads) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This tests the new conic subdivision code in the Impeller conic path
|
TEST(DisplayListSkConversions, ConicPathToImpeller) {
|
||||||
// component object vs the code we used to rely on inside Skia
|
|
||||||
TEST(DisplayListSkConversions, ConicPathToQuads) {
|
|
||||||
// If we execute conicTo with a weight of exactly 1.0, SkPath will turn
|
// If we execute conicTo with a weight of exactly 1.0, SkPath will turn
|
||||||
// it into a quadTo, so we avoid that by using 0.999
|
// it into a quadTo, so we avoid that by using 0.999
|
||||||
SkScalar weights[4] = {
|
SkScalar weights[4] = {
|
||||||
@ -426,35 +425,16 @@ TEST(DisplayListSkConversions, ConicPathToQuads) {
|
|||||||
ASSERT_EQ(it.type(), impeller::Path::ComponentType::kContour);
|
ASSERT_EQ(it.type(), impeller::Path::ComponentType::kContour);
|
||||||
++it;
|
++it;
|
||||||
|
|
||||||
ASSERT_EQ(it.type(), impeller::Path::ComponentType::kQuadratic);
|
ASSERT_EQ(it.type(), impeller::Path::ComponentType::kConic);
|
||||||
auto quad1 = it.quadratic();
|
auto conic = it.conic();
|
||||||
ASSERT_NE(quad1, nullptr);
|
ASSERT_NE(conic, nullptr);
|
||||||
++it;
|
++it;
|
||||||
|
|
||||||
ASSERT_EQ(it.type(), impeller::Path::ComponentType::kQuadratic);
|
EXPECT_EQ(conic->p1, DlPoint(10, 10)) << "weight: " << weight;
|
||||||
auto quad2 = it.quadratic();
|
EXPECT_EQ(conic->cp, DlPoint(20, 10)) << "weight: " << weight;
|
||||||
ASSERT_NE(quad2, nullptr);
|
EXPECT_EQ(conic->p2, DlPoint(20, 20)) << "weight: " << weight;
|
||||||
++it;
|
EXPECT_EQ(conic->weight.x, weight) << "weight: " << weight;
|
||||||
|
EXPECT_EQ(conic->weight.y, weight) << "weight: " << weight;
|
||||||
SkPoint sk_points[5];
|
|
||||||
int ncurves = SkPath::ConvertConicToQuads(
|
|
||||||
SkPoint::Make(10, 10), SkPoint::Make(20, 10), SkPoint::Make(20, 20),
|
|
||||||
weight, sk_points, 1);
|
|
||||||
ASSERT_EQ(ncurves, 2);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(sk_points[0].fX, quad1->p1.x) << "weight: " << weight;
|
|
||||||
EXPECT_FLOAT_EQ(sk_points[0].fY, quad1->p1.y) << "weight: " << weight;
|
|
||||||
EXPECT_FLOAT_EQ(sk_points[1].fX, quad1->cp.x) << "weight: " << weight;
|
|
||||||
EXPECT_FLOAT_EQ(sk_points[1].fY, quad1->cp.y) << "weight: " << weight;
|
|
||||||
EXPECT_FLOAT_EQ(sk_points[2].fX, quad1->p2.x) << "weight: " << weight;
|
|
||||||
EXPECT_FLOAT_EQ(sk_points[2].fY, quad1->p2.y) << "weight: " << weight;
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(sk_points[2].fX, quad2->p1.x) << "weight: " << weight;
|
|
||||||
EXPECT_FLOAT_EQ(sk_points[2].fY, quad2->p1.y) << "weight: " << weight;
|
|
||||||
EXPECT_FLOAT_EQ(sk_points[3].fX, quad2->cp.x) << "weight: " << weight;
|
|
||||||
EXPECT_FLOAT_EQ(sk_points[3].fY, quad2->cp.y) << "weight: " << weight;
|
|
||||||
EXPECT_FLOAT_EQ(sk_points[4].fX, quad2->p2.x) << "weight: " << weight;
|
|
||||||
EXPECT_FLOAT_EQ(sk_points[4].fY, quad2->p2.y) << "weight: " << weight;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ source_set("display_list_testing") {
|
|||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
"dl_test_equality.h",
|
"dl_test_equality.h",
|
||||||
|
"dl_test_mock_path_receiver.h",
|
||||||
"dl_test_snippets.cc",
|
"dl_test_snippets.cc",
|
||||||
"dl_test_snippets.h",
|
"dl_test_snippets.h",
|
||||||
]
|
]
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef FLUTTER_DISPLAY_LIST_TESTING_DL_TEST_MOCK_PATH_RECEIVER_H_
|
||||||
|
#define FLUTTER_DISPLAY_LIST_TESTING_DL_TEST_MOCK_PATH_RECEIVER_H_
|
||||||
|
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
|
#include "flutter/display_list/geometry/dl_path.h"
|
||||||
|
|
||||||
|
namespace flutter {
|
||||||
|
namespace testing {
|
||||||
|
class DlPathReceiverMock : public DlPathReceiver {
|
||||||
|
public:
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
RecommendSizes,
|
||||||
|
(size_t verb_count, size_t point_count),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(void, RecommendBounds, (const DlRect& bounds), (override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
SetPathInfo,
|
||||||
|
(DlPathFillType fill_type, bool is_convex),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(void, MoveTo, (const DlPoint& p2), (override));
|
||||||
|
MOCK_METHOD(void, LineTo, (const DlPoint& p2), (override));
|
||||||
|
MOCK_METHOD(void, QuadTo, (const DlPoint& cp, const DlPoint& p2), (override));
|
||||||
|
MOCK_METHOD(bool,
|
||||||
|
ConicTo,
|
||||||
|
(const DlPoint& cp, const DlPoint& p2, DlScalar weight),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
CubicTo,
|
||||||
|
(const DlPoint& cp1, const DlPoint& cp2, const DlPoint& p2),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(void, Close, (), (override));
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
} // namespace flutter
|
||||||
|
|
||||||
|
#endif // FLUTTER_DISPLAY_LIST_TESTING_DL_TEST_MOCK_PATH_RECEIVER_H_
|
@ -344,7 +344,9 @@ void ConicPathComponent::AppendPolylinePoints(
|
|||||||
Scalar scale_factor,
|
Scalar scale_factor,
|
||||||
std::vector<Point>& points) const {
|
std::vector<Point>& points) const {
|
||||||
ToLinearPathComponents(scale_factor, [&points](const Point& point) {
|
ToLinearPathComponents(scale_factor, [&points](const Point& point) {
|
||||||
points.emplace_back(point);
|
if (point != points.back()) {
|
||||||
|
points.emplace_back(point);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ using DlImageSampling = flutter::DlImageSampling;
|
|||||||
using SaveLayerOptions = flutter::SaveLayerOptions;
|
using SaveLayerOptions = flutter::SaveLayerOptions;
|
||||||
using DisplayListOpType = flutter::DisplayListOpType;
|
using DisplayListOpType = flutter::DisplayListOpType;
|
||||||
using DisplayListOpCategory = flutter::DisplayListOpCategory;
|
using DisplayListOpCategory = flutter::DisplayListOpCategory;
|
||||||
|
using DlPathFillType = flutter::DlPathFillType;
|
||||||
using DlPath = flutter::DlPath;
|
using DlPath = flutter::DlPath;
|
||||||
|
|
||||||
using DisplayListStreamDispatcher = flutter::testing::DisplayListStreamDispatcher;
|
using DisplayListStreamDispatcher = flutter::testing::DisplayListStreamDispatcher;
|
||||||
@ -137,6 +138,14 @@ extern std::ostream& operator<<(
|
|||||||
return os << "DisplayListOpCategory::???";
|
return os << "DisplayListOpCategory::???";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern std::ostream& operator<<(
|
||||||
|
std::ostream& os, const flutter::DlPathFillType& type) {
|
||||||
|
switch (type) {
|
||||||
|
DLT_OSTREAM_CASE(DlPathFillType, Odd);
|
||||||
|
DLT_OSTREAM_CASE(DlPathFillType, NonZero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#undef DLT_OSTREAM_CASE
|
#undef DLT_OSTREAM_CASE
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const SaveLayerOptions& options) {
|
std::ostream& operator<<(std::ostream& os, const SaveLayerOptions& options) {
|
||||||
@ -167,6 +176,12 @@ extern std::ostream& operator<<(std::ostream& os, const DlPath& path) {
|
|||||||
<< ")";
|
<< ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern std::ostream& operator<<(std::ostream& os, const flutter::testing::DlVerbosePath& path) {
|
||||||
|
DisplayListStreamDispatcher dispatcher(os, 0);
|
||||||
|
dispatcher.out(path);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const flutter::DlClipOp& op) {
|
std::ostream& operator<<(std::ostream& os, const flutter::DlClipOp& op) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case flutter::DlClipOp::kDifference: return os << "DlClipOp::kDifference";
|
case flutter::DlClipOp::kDifference: return os << "DlClipOp::kDifference";
|
||||||
@ -625,6 +640,75 @@ void DisplayListStreamDispatcher::out(const DlImageFilter* filter) {
|
|||||||
outdent(1);
|
outdent(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DisplayListStreamDispatcher::DlPathStreamer::~DlPathStreamer() {
|
||||||
|
if (done_with_info_) {
|
||||||
|
dispatcher_.outdent(2);
|
||||||
|
dispatcher_.startl() << "}" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void DisplayListStreamDispatcher::DlPathStreamer::RecommendSizes(
|
||||||
|
size_t verb_count, size_t point_count) {
|
||||||
|
FML_DCHECK(!done_with_info_);
|
||||||
|
dispatcher_.startl() << "sizes: "
|
||||||
|
<< verb_count << " verbs, " << point_count << " points" << std::endl;
|
||||||
|
};
|
||||||
|
void DisplayListStreamDispatcher::DlPathStreamer::RecommendBounds(
|
||||||
|
const DlRect& bounds) {
|
||||||
|
FML_DCHECK(!done_with_info_);
|
||||||
|
dispatcher_.startl() << "bounds: " << bounds << std::endl;
|
||||||
|
};
|
||||||
|
void DisplayListStreamDispatcher::DlPathStreamer::SetPathInfo(
|
||||||
|
DlPathFillType fill_type, bool is_convex) {
|
||||||
|
FML_DCHECK(!done_with_info_);
|
||||||
|
dispatcher_.startl() << "info: "
|
||||||
|
<< fill_type << ", convex: " << is_convex << std::endl;
|
||||||
|
}
|
||||||
|
void DisplayListStreamDispatcher::DlPathStreamer::MoveTo(const DlPoint& p2) {
|
||||||
|
if (!done_with_info_) {
|
||||||
|
done_with_info_ = true;
|
||||||
|
dispatcher_.startl() << "{" << std::endl;
|
||||||
|
dispatcher_.indent(2);
|
||||||
|
}
|
||||||
|
dispatcher_.startl() << "MoveTo(" << p2 << ")," << std::endl;
|
||||||
|
}
|
||||||
|
void DisplayListStreamDispatcher::DlPathStreamer::LineTo(const DlPoint& p2) {
|
||||||
|
FML_DCHECK(done_with_info_);
|
||||||
|
dispatcher_.startl() << "LineTo(" << p2 << ")," << std::endl;
|
||||||
|
}
|
||||||
|
void DisplayListStreamDispatcher::DlPathStreamer::QuadTo(const DlPoint& cp,
|
||||||
|
const DlPoint& p2) {
|
||||||
|
FML_DCHECK(done_with_info_);
|
||||||
|
dispatcher_.startl() << "QuadTo(" << cp << ", " << p2 << ")," << std::endl;
|
||||||
|
}
|
||||||
|
bool DisplayListStreamDispatcher::DlPathStreamer::ConicTo(const DlPoint& cp,
|
||||||
|
const DlPoint& p2,
|
||||||
|
DlScalar weight) {
|
||||||
|
FML_DCHECK(done_with_info_);
|
||||||
|
dispatcher_.startl() << "ConicTo(" << cp << ", " << p2 << ", " << weight
|
||||||
|
<< ")," << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void DisplayListStreamDispatcher::DlPathStreamer::CubicTo(const DlPoint& cp1,
|
||||||
|
const DlPoint& cp2,
|
||||||
|
const DlPoint& p2) {
|
||||||
|
FML_DCHECK(done_with_info_);
|
||||||
|
dispatcher_.startl() << "CubicTo(" << cp1 << ", " << cp2 << ", " << p2 << ", "
|
||||||
|
<< p2 << ")," << std::endl;
|
||||||
|
}
|
||||||
|
void DisplayListStreamDispatcher::DlPathStreamer::Close() {
|
||||||
|
FML_DCHECK(done_with_info_);
|
||||||
|
dispatcher_.startl() << "Close()," << std::endl;
|
||||||
|
}
|
||||||
|
void DisplayListStreamDispatcher::out(const DlVerbosePath& path) {
|
||||||
|
os_ << "DlPath(" << std::endl;
|
||||||
|
indent(2);
|
||||||
|
{
|
||||||
|
DlPathStreamer streamer(*this);
|
||||||
|
path.path.Dispatch(streamer);
|
||||||
|
}
|
||||||
|
outdent(2);
|
||||||
|
os_ << ")";
|
||||||
|
}
|
||||||
void DisplayListStreamDispatcher::setImageFilter(const DlImageFilter* filter) {
|
void DisplayListStreamDispatcher::setImageFilter(const DlImageFilter* filter) {
|
||||||
startl() << "setImageFilter(";
|
startl() << "setImageFilter(";
|
||||||
indent(15);
|
indent(15);
|
||||||
|
@ -35,6 +35,12 @@ namespace flutter::testing {
|
|||||||
const sk_sp<const DisplayList>& b) {
|
const sk_sp<const DisplayList>& b) {
|
||||||
return DisplayListsNE_Verbose(a.get(), b.get());
|
return DisplayListsNE_Verbose(a.get(), b.get());
|
||||||
}
|
}
|
||||||
|
class DlVerbosePath {
|
||||||
|
public:
|
||||||
|
explicit DlVerbosePath(const DlPath& path) : path(path) {}
|
||||||
|
|
||||||
|
const DlPath& path;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace flutter::testing
|
} // namespace flutter::testing
|
||||||
|
|
||||||
@ -76,6 +82,10 @@ extern std::ostream& operator<<(std::ostream& os,
|
|||||||
extern std::ostream& operator<<(std::ostream& os,
|
extern std::ostream& operator<<(std::ostream& os,
|
||||||
const flutter::DisplayListOpCategory& category);
|
const flutter::DisplayListOpCategory& category);
|
||||||
extern std::ostream& operator<<(std::ostream& os, const flutter::DlPath& path);
|
extern std::ostream& operator<<(std::ostream& os, const flutter::DlPath& path);
|
||||||
|
extern std::ostream& operator<<(std::ostream& os,
|
||||||
|
const flutter::testing::DlVerbosePath& path);
|
||||||
|
extern std::ostream& operator<<(std::ostream& os,
|
||||||
|
const flutter::DlPathFillType& type);
|
||||||
extern std::ostream& operator<<(std::ostream& os,
|
extern std::ostream& operator<<(std::ostream& os,
|
||||||
const flutter::DlImageFilter& type);
|
const flutter::DlImageFilter& type);
|
||||||
extern std::ostream& operator<<(std::ostream& os,
|
extern std::ostream& operator<<(std::ostream& os,
|
||||||
@ -204,6 +214,7 @@ class DisplayListStreamDispatcher final : public DlOpReceiver {
|
|||||||
void out(const DlColorFilter* filter);
|
void out(const DlColorFilter* filter);
|
||||||
void out(const DlImageFilter& filter);
|
void out(const DlImageFilter& filter);
|
||||||
void out(const DlImageFilter* filter);
|
void out(const DlImageFilter* filter);
|
||||||
|
void out(const DlVerbosePath& path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::ostream& os_;
|
std::ostream& os_;
|
||||||
@ -219,6 +230,29 @@ class DisplayListStreamDispatcher final : public DlOpReceiver {
|
|||||||
std::ostream& out_array(std::string name, int count, const T array[]);
|
std::ostream& out_array(std::string name, int count, const T array[]);
|
||||||
|
|
||||||
std::ostream& startl();
|
std::ostream& startl();
|
||||||
|
|
||||||
|
class DlPathStreamer : public DlPathReceiver {
|
||||||
|
public:
|
||||||
|
~DlPathStreamer();
|
||||||
|
|
||||||
|
explicit DlPathStreamer(DisplayListStreamDispatcher& dispatcher)
|
||||||
|
: dispatcher_(dispatcher) {}
|
||||||
|
|
||||||
|
void RecommendSizes(size_t verb_count, size_t point_count);
|
||||||
|
void RecommendBounds(const DlRect& bounds);
|
||||||
|
void SetPathInfo(DlPathFillType fill_type, bool is_convex);
|
||||||
|
void MoveTo(const DlPoint& p2);
|
||||||
|
void LineTo(const DlPoint& p2);
|
||||||
|
void QuadTo(const DlPoint& cp, const DlPoint& p2);
|
||||||
|
bool ConicTo(const DlPoint& cp, const DlPoint& p2, DlScalar weight);
|
||||||
|
void CubicTo(const DlPoint& cp1, const DlPoint& cp2, const DlPoint& p2);
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
private:
|
||||||
|
DisplayListStreamDispatcher& dispatcher_;
|
||||||
|
bool done_with_info_ = false;
|
||||||
|
};
|
||||||
|
friend class DlPathStreamer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DisplayListGeneralReceiver : public DlOpReceiver {
|
class DisplayListGeneralReceiver : public DlOpReceiver {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user