| Flutter Impeller |

Functions
impeller::skia_conversions Namespace Reference

## Functions
bool | IsNearlySimpleRRect (const SkRRect &rr)
| Like SkRRect.isSimple, but allows the corners to differ by kEhCloseEnough. More...
Rect | ToRect (const SkRect &rect)
std::optional< Rect > | ToRect (const SkRect *rect)
std::vector< Rect > | ToRects (const SkRect tex[], int count)
std::vector< Point > | ToPoints (const SkPoint points[], int count)
PathBuilder::RoundingRadii | ToRoundingRadii (const SkRRect &rrect)
Path | ToPath (const SkPath &path, Point shift)
Path | ToPath (const SkRRect &rrect)
Point | ToPoint (const SkPoint &point)
Size | ToSize (const SkPoint &point)
Color | ToColor (const flutter::DlColor &color)
std::vector< Matrix > | ToRSXForms (const SkRSXform xform[], int count)
Path | PathDataFromTextBlob (const sk_sp< SkTextBlob > &blob, Point shift)
std::optional< impeller::PixelFormat > | ToPixelFormat (SkColorType type)
void | ConvertStops (const flutter::DlGradientColorSourceBase *gradient, std::vector< Color > &colors, std::vector< float > &stops)
| Convert display list colors + stops into impeller colors and stops, taking care to ensure that the stops monotonically increase from 0.0 to 1.0. More...

## Function Documentation

## ◆ ConvertStops()

void impeller::skia_conversions::ConvertStops | ( | const flutter::DlGradientColorSourceBase * | gradient,
|  | std::vector< Color > & | colors,
|  | std::vector< float > & | stops
| ) |  |

Convert display list colors + stops into impeller colors and stops, taking care to ensure that the stops monotonically increase from 0.0 to 1.0.

The general process is:

- Ensure that the first gradient stop value is 0.0. If not, insert a new stop with a value of 0.0 and use the first gradient color as this new stops color.
- Ensure the last gradient stop value is 1.0. If not, insert a new stop with a value of 1.0 and use the last gradient color as this stops color.
- Clamp all gradient values between the values of 0.0 and 1.0.
- For all stop values, ensure that the values are monotonically increasing by clamping each value to a minimum of the previous stop value and itself. For example, with stop values of 0.0, 0.5, 0.4, 1.0, we would clamp such that the values were 0.0, 0.5, 0.5, 1.0.

Definition at line 212 of file skia_conversions.cc.

214 {
215 FML_DCHECK(gradient->stop_count() >= 2);
216
217 auto* dl_colors = gradient->colors();
218 auto* dl_stops = gradient->stops();
219 if (dl_stops[0] != 0.0) {
220 colors.emplace_back(skia_conversions::ToColor(dl_colors[0]));
221 stops.emplace_back(0);
222 }
223 for (auto i = 0; i < gradient->stop_count(); i++) {
224 colors.emplace_back(skia_conversions::ToColor(dl_colors[i]));
225 stops.emplace_back(std::clamp(dl_stops[i], 0.0f, 1.0f));
226 }
227 if (dl_stops[gradient->stop_count() - 1] != 1.0) {
228 colors.emplace_back(colors.back());
229 stops.emplace_back(1.0);
230 }
231 for (auto i = 1; i < gradient->stop_count(); i++) {
232 stops[i] = std::clamp(stops[i], stops[i - 1], stops[i]);
233 }
234 }

References ToColor().

Referenced by impeller::DlDispatcherBase::setColorSource(), and impeller::testing::TEST().

## ◆ IsNearlySimpleRRect()

bool impeller::skia_conversions::IsNearlySimpleRRect | ( | const SkRRect & | rr | ) |

Like SkRRect.isSimple, but allows the corners to differ by kEhCloseEnough.

An RRect is simple if all corner radii are approximately equal.

Definition at line 12 of file skia_conversions.cc.

12 {
13 auto [a, b] = rr.radii(SkRRect::kUpperLeft_Corner);
14 auto [c, d] = rr.radii(SkRRect::kLowerLeft_Corner);
15 auto [e, f] = rr.radii(SkRRect::kUpperRight_Corner);
16 auto [g, h] = rr.radii(SkRRect::kLowerRight_Corner);
17 return SkScalarNearlyEqual(a, b, kEhCloseEnough) &&
18 SkScalarNearlyEqual(a, c, kEhCloseEnough) &&
19 SkScalarNearlyEqual(a, d, kEhCloseEnough) &&
20 SkScalarNearlyEqual(a, e, kEhCloseEnough) &&
21 SkScalarNearlyEqual(a, f, kEhCloseEnough) &&
22 SkScalarNearlyEqual(a, g, kEhCloseEnough) &&
23 SkScalarNearlyEqual(a, h, kEhCloseEnough);
24 }

References impeller::saturated::b, and impeller::kEhCloseEnough.

Referenced by impeller::DlDispatcherBase::drawRRect(), and impeller::testing::TEST().

## ◆ PathDataFromTextBlob()

Path impeller::skia_conversions::PathDataFromTextBlob | ( | const sk_sp< SkTextBlob > & | blob,
|  | Point | shift
| ) |  |

Definition at line 188 of file skia_conversions.cc.

188 {
189 if (!blob) {
190 return {};
191 }
192
193 return ToPath(skia::textlayout::Paragraph::GetPath(blob.get()), shift);
194 }

References ToPath().

## ◆ ToColor()

Color impeller::skia_conversions::ToColor | ( | const flutter::DlColor & | color | ) |

Definition at line 162 of file skia_conversions.cc.

162 {
163 return {
164 static_cast<Scalar>(color.getRedF()), //
165 static_cast<Scalar>(color.getGreenF()), //
166 static_cast<Scalar>(color.getBlueF()), //
167 static_cast<Scalar>(color.getAlphaF()) //
168 };
169 }

References color.

Referenced by ConvertStops(), impeller::DlDispatcherBase::drawColor(), impeller::DlDispatcherBase::drawShadow(), impeller::MakeVertices(), impeller::testing::TEST(), impeller::ToColorFilter(), and impeller::ToColors().

## ◆ ToPath() [1/2]

Path impeller::skia_conversions::ToPath | ( | const SkPath & | path,
|  | Point | shift
| ) |  |

Definition at line 63 of file skia_conversions.cc.

63 {
64 auto iterator = SkPath::Iter(path, false);
65
66 struct PathData {
67 union {
68 SkPoint points[4];
69 };
70 };
71
72 PathBuilder builder;
73 PathData data;
74 // Reserve a path size with some arbitrarily additional padding.
75 builder.Reserve(path.countPoints() + 8, path.countVerbs() + 8);
76 auto verb = SkPath::Verb::kDone_Verb;
77 do {
78 verb = iterator.next(data.points);
79 switch (verb) {
80 case SkPath::kMove_Verb:
81 builder.MoveTo(ToPoint(data.points[0]));
82 break;
83 case SkPath::kLine_Verb:
84 builder.LineTo(ToPoint(data.points[1]));
85 break;
86 case SkPath::kQuad_Verb:
87 builder.QuadraticCurveTo(ToPoint(data.points[1]),
88 ToPoint(data.points[2]));
89 break;
90 case SkPath::kConic_Verb: {
91 constexpr auto kPow2 = 1; // Only works for sweeps up to 90 degrees.
92 constexpr auto kQuadCount = 1 + (2 * (1 << kPow2));
93 SkPoint points[kQuadCount];
94 const auto curve_count =
95 SkPath::ConvertConicToQuads(data.points[0], //
96 data.points[1], //
97 data.points[2], //
98 iterator.conicWeight(), //
99 points, //
100 kPow2 //
101 );
102
103 for (int curve_index = 0, point_index = 0; //
104 curve_index < curve_count; //
105 curve_index++, point_index += 2 //
106 ) {
107 builder.QuadraticCurveTo(ToPoint(points[point_index + 1]),
108 ToPoint(points[point_index + 2]));
109 }
110 } break;
111 case SkPath::kCubic_Verb:
112 builder.CubicCurveTo(ToPoint(data.points[1]), ToPoint(data.points[2]),
113 ToPoint(data.points[3]));
114 break;
115 case SkPath::kClose_Verb:
116 builder.Close();
117 break;
118 case SkPath::kDone_Verb:
119 break;
120 }
121 } while (verb != SkPath::Verb::kDone_Verb);
122
123 FillType fill_type;
124 switch (path.getFillType()) {
125 case SkPathFillType::kWinding:
126 fill_type = FillType::kNonZero;
127 break;
128 case SkPathFillType::kEvenOdd:
129 fill_type = FillType::kOdd;
130 break;
131 case SkPathFillType::kInverseWinding:
132 case SkPathFillType::kInverseEvenOdd:
133 // Flutter doesn't expose these path fill types. These are only visible
134 // via the receiver interface. We should never get here.
135 fill_type = FillType::kNonZero;
136 break;
137 }
138 builder.SetConvexity(path.isConvex() ? Convexity::kConvex
139 : Convexity::kUnknown);
140 builder.Shift(shift);
141 auto sk_bounds = path.getBounds().makeOutset(shift.x, shift.y);
142 builder.SetBounds(ToRect(sk_bounds));
143 return builder.TakePath(fill_type);
144 }

References impeller::PathBuilder::Close(), impeller::PathBuilder::CubicCurveTo(), data, impeller::kConvex, impeller::kNonZero, impeller::kOdd, impeller::kUnknown, impeller::PathBuilder::LineTo(), impeller::PathBuilder::MoveTo(), impeller::PathBuilder::QuadraticCurveTo(), impeller::PathBuilder::Reserve(), impeller::PathBuilder::SetBounds(), impeller::PathBuilder::SetConvexity(), impeller::PathBuilder::Shift(), impeller::PathBuilder::TakePath(), ToPoint(), ToRect(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by impeller::DlDispatcherBase::clipRRect(), impeller::DlDispatcherBase::drawDRRect(), impeller::DlDispatcherBase::drawRRect(), and PathDataFromTextBlob().

## ◆ ToPath() [2/2]

Path impeller::skia_conversions::ToPath | ( | const SkRRect & | rrect | ) |

Definition at line 146 of file skia_conversions.cc.

146 {
147 return PathBuilder{}
148 .AddRoundedRect(ToRect(rrect.getBounds()), ToRoundingRadii(rrect))
149 .SetConvexity(Convexity::kConvex)
150 .SetBounds(ToRect(rrect.getBounds()))
151 .TakePath();
152 }

References impeller::PathBuilder::AddRoundedRect(), impeller::kConvex, impeller::PathBuilder::SetBounds(), impeller::PathBuilder::SetConvexity(), impeller::PathBuilder::TakePath(), ToRect(), and ToRoundingRadii().

## ◆ ToPixelFormat()

std::optional< impeller::PixelFormat > impeller::skia_conversions::ToPixelFormat | ( | SkColorType | type | ) |

Definition at line 196 of file skia_conversions.cc.

196 {
197 switch (type) {
198 case kRGBA_8888_SkColorType:
199 return impeller::PixelFormat::kR8G8B8A8UNormInt;
200 case kBGRA_8888_SkColorType:
201 return impeller::PixelFormat::kB8G8R8A8UNormInt;
202 case kRGBA_F16_SkColorType:
203 return impeller::PixelFormat::kR16G16B16A16Float;
204 case kBGR_101010x_XR_SkColorType:
205 return impeller::PixelFormat::kB10G10R10XR;
206 default:
207 return std::nullopt;
208 }
209 return std::nullopt;
210 }

References impeller::kB10G10R10XR, impeller::kB8G8R8A8UNormInt, impeller::kR16G16B16A16Float, impeller::kR8G8B8A8UNormInt, and type.

## ◆ ToPoint()

Point impeller::skia_conversions::ToPoint | ( | const SkPoint & | point | ) |

Definition at line 154 of file skia_conversions.cc.

154 {
155 return Point::MakeXY(point.fX, point.fY);
156 }

References impeller::TPoint< Scalar >::MakeXY().

Referenced by impeller::DlDispatcherBase::drawCircle(), impeller::DlDispatcherBase::drawLine(), impeller::DlDispatcherBase::drawPoints(), impeller::MakeVertices(), impeller::DlDispatcherBase::setColorSource(), impeller::testing::TEST(), ToPath(), ToPoints(), and ToRoundingRadii().

## ◆ ToPoints()

std::vector< Point > impeller::skia_conversions::ToPoints | ( | const SkPoint | points[],
|  | int | count
| ) |  |

Definition at line 45 of file skia_conversions.cc.

45 {
46 std::vector<Point> result(count);
47 for (auto i = 0; i < count; i++) {
48 result[i] = ToPoint(points[i]);
49 }
50 return result;
51 }

References ToPoint().

Referenced by impeller::DlDispatcherBase::drawPoints().

## ◆ ToRect() [1/2]

Rect impeller::skia_conversions::ToRect | ( | const SkRect & | rect | ) |

Definition at line 26 of file skia_conversions.cc.

26 {
27 return Rect::MakeLTRB(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
28 }

References impeller::TRect< Scalar >::MakeLTRB().

Referenced by impeller::DlDispatcherBase::clipPath(), impeller::DlDispatcherBase::clipRect(), impeller::DlDispatcherBase::clipRRect(), impeller::DlDispatcherBase::drawArc(), impeller::DlDispatcherBase::drawAtlas(), impeller::DlDispatcherBase::drawDisplayList(), impeller::DlDispatcherBase::drawImageNine(), impeller::DlDispatcherBase::drawImageRect(), impeller::DlDispatcherBase::drawOval(), impeller::DlDispatcherBase::drawRect(), impeller::DlDispatcherBase::drawRRect(), impeller::DlDispatcherBase::saveLayer(), ToPath(), and ToRects().

## ◆ ToRect() [2/2]

std::optional< Rect > impeller::skia_conversions::ToRect | ( | const SkRect * | rect | ) |

Definition at line 30 of file skia_conversions.cc.

30 {
31 if (rect == nullptr) {
32 return std::nullopt;
33 }
34 return Rect::MakeLTRB(rect->fLeft, rect->fTop, rect->fRight, rect->fBottom);
35 }

References impeller::TRect< Scalar >::MakeLTRB().

## ◆ ToRects()

std::vector< Rect > impeller::skia_conversions::ToRects | ( | const SkRect | tex[],
|  | int | count
| ) |  |

Definition at line 37 of file skia_conversions.cc.

37 {
38 auto result = std::vector<Rect>();
39 for (int i = 0; i < count; i++) {
40 result.push_back(ToRect(tex[i]));
41 }
42 return result;
43 }

References ToRect().

Referenced by impeller::DlDispatcherBase::drawAtlas().

## ◆ ToRoundingRadii()

PathBuilder::RoundingRadii impeller::skia_conversions::ToRoundingRadii | ( | const SkRRect & | rrect | ) |

Definition at line 53 of file skia_conversions.cc.

53 {
54 using Corner = SkRRect::Corner;
55 PathBuilder::RoundingRadii radii;
56 radii.bottom_left = ToPoint(rrect.radii(Corner::kLowerLeft_Corner));
57 radii.bottom_right = ToPoint(rrect.radii(Corner::kLowerRight_Corner));
58 radii.top_left = ToPoint(rrect.radii(Corner::kUpperLeft_Corner));
59 radii.top_right = ToPoint(rrect.radii(Corner::kUpperRight_Corner));
60 return radii;
61 }

References impeller::PathBuilder::RoundingRadii::bottom_left, impeller::PathBuilder::RoundingRadii::bottom_right, impeller::PathBuilder::RoundingRadii::top_left, impeller::PathBuilder::RoundingRadii::top_right, and ToPoint().

Referenced by ToPath().

## ◆ ToRSXForms()

std::vector< Matrix > impeller::skia_conversions::ToRSXForms | ( | const SkRSXform | xform[],
|  | int | count
| ) |  |

Definition at line 171 of file skia_conversions.cc.

171 {
172 auto result = std::vector<Matrix>();
173 for (int i = 0; i < count; i++) {
174 auto form = xform[i];
175 // clang-format off
176 auto matrix = Matrix{
177 form.fSCos, form.fSSin, 0, 0,
178 -form.fSSin, form.fSCos, 0, 0,
179 0, 0, 1, 0,
180 form.fTx, form.fTy, 0, 1
181 };
182 // clang-format on
183 result.push_back(matrix);
184 }
185 return result;
186 }

Referenced by impeller::DlDispatcherBase::drawAtlas().

## ◆ ToSize()

Size impeller::skia_conversions::ToSize | ( | const SkPoint & | point | ) |

Definition at line 158 of file skia_conversions.cc.

158 {
159 return Size(point.fX, point.fY);
160 }

Referenced by impeller::DlDispatcherBase::clipPath(), impeller::DlDispatcherBase::clipRRect(), impeller::DlDispatcherBase::drawRRect(), and impeller::testing::TEST().

impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::kEhCloseEnough
constexpr float kEhCloseEnough
Definition: constants.h:56
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::skia_conversions::ToColor
Color ToColor(const flutter::DlColor &color)
Definition: skia_conversions.cc:162
impeller::Size
TSize< Scalar > Size
Definition: size.h:137
impeller::skia_conversions::ToRoundingRadii
PathBuilder::RoundingRadii ToRoundingRadii(const SkRRect &rrect)
Definition: skia_conversions.cc:53
impeller::PixelFormat::kB10G10R10XR
@ kB10G10R10XR
type
GLenum type
Definition: blit_command_gles.cc:126
impeller::FillType
FillType
Definition: path.h:30
impeller::PixelFormat::kR16G16B16A16Float
@ kR16G16B16A16Float
impeller::skia_conversions::ToPoint
Point ToPoint(const SkPoint &point)
Definition: skia_conversions.cc:154
impeller::skia_conversions::ToRect
std::optional< Rect > ToRect(const SkRect *rect)
Definition: skia_conversions.cc:30
impeller::saturated::b
SI b
Definition: saturated_math.h:87
color
DlColor color
Definition: dl_golden_blur_unittests.cc:23
impeller::skia_conversions::ToPath
Path ToPath(const SkRRect &rrect)
Definition: skia_conversions.cc:146
impeller::PixelFormat::kB8G8R8A8UNormInt
@ kB8G8R8A8UNormInt