Flutter Impeller
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< RectToRect (const SkRect *rect)
 
std::vector< RectToRects (const SkRect tex[], int count)
 
std::vector< PointToPoints (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< MatrixToRSXForms (const SkRSXform xform[], int count)
 
Path PathDataFromTextBlob (const sk_sp< SkTextBlob > &blob, Point shift)
 
std::optional< impeller::PixelFormatToPixelFormat (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:
200  case kBGRA_8888_SkColorType:
202  case kRGBA_F16_SkColorType:
204  case kBGR_101010x_XR_SkColorType:
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)

◆ 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]

◆ 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)
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