Flutter Impeller
skia_conversions.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 #include "display_list/dl_color.h"
7 #include "third_party/skia/modules/skparagraph/include/Paragraph.h"
8 
9 namespace impeller {
10 namespace skia_conversions {
11 
12 static inline bool SkScalarsNearlyEqual(SkScalar a,
13  SkScalar b,
14  SkScalar c,
15  SkScalar d) {
16  return SkScalarNearlyEqual(a, b, kEhCloseEnough) &&
17  SkScalarNearlyEqual(a, c, kEhCloseEnough) &&
18  SkScalarNearlyEqual(a, d, kEhCloseEnough);
19 }
20 
21 bool IsNearlySimpleRRect(const SkRRect& rr) {
22  auto [xa, ya] = rr.radii(SkRRect::kUpperLeft_Corner);
23  auto [xb, yb] = rr.radii(SkRRect::kLowerLeft_Corner);
24  auto [xc, yc] = rr.radii(SkRRect::kUpperRight_Corner);
25  auto [xd, yd] = rr.radii(SkRRect::kLowerRight_Corner);
26  return SkScalarsNearlyEqual(xa, xb, xc, xd) &&
27  SkScalarsNearlyEqual(ya, yb, yc, yd);
28 }
29 
30 Rect ToRect(const SkRect& rect) {
31  return Rect::MakeLTRB(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
32 }
33 
34 std::optional<Rect> ToRect(const SkRect* rect) {
35  if (rect == nullptr) {
36  return std::nullopt;
37  }
38  return Rect::MakeLTRB(rect->fLeft, rect->fTop, rect->fRight, rect->fBottom);
39 }
40 
41 std::optional<const Rect> ToRect(const flutter::DlRect* rect) {
42  if (rect == nullptr) {
43  return std::nullopt;
44  }
45  return *rect;
46 }
47 
48 std::vector<Rect> ToRects(const SkRect tex[], int count) {
49  auto result = std::vector<Rect>();
50  for (int i = 0; i < count; i++) {
51  result.push_back(ToRect(tex[i]));
52  }
53  return result;
54 }
55 
56 std::vector<Rect> ToRects(const flutter::DlRect tex[], int count) {
57  auto result = std::vector<Rect>();
58  for (int i = 0; i < count; i++) {
59  result.push_back(tex[i]);
60  }
61  return result;
62 }
63 
64 std::vector<Point> ToPoints(const SkPoint points[], int count) {
65  std::vector<Point> result(count);
66  for (auto i = 0; i < count; i++) {
67  result[i] = ToPoint(points[i]);
68  }
69  return result;
70 }
71 
72 std::vector<Point> ToPoints(const flutter::DlPoint points[], int count) {
73  std::vector<Point> result(count);
74  for (auto i = 0; i < count; i++) {
75  result[i] = points[i];
76  }
77  return result;
78 }
79 
81  using Corner = SkRRect::Corner;
83  radii.bottom_left = ToPoint(rrect.radii(Corner::kLowerLeft_Corner));
84  radii.bottom_right = ToPoint(rrect.radii(Corner::kLowerRight_Corner));
85  radii.top_left = ToPoint(rrect.radii(Corner::kUpperLeft_Corner));
86  radii.top_right = ToPoint(rrect.radii(Corner::kUpperRight_Corner));
87  return radii;
88 }
89 
90 Path ToPath(const SkRRect& rrect) {
91  return PathBuilder{}
92  .AddRoundedRect(ToRect(rrect.getBounds()), ToRoundingRadii(rrect))
94  .SetBounds(ToRect(rrect.getBounds()))
95  .TakePath();
96 }
97 
98 Point ToPoint(const SkPoint& point) {
99  return Point::MakeXY(point.fX, point.fY);
100 }
101 
102 Size ToSize(const SkPoint& point) {
103  return Size(point.fX, point.fY);
104 }
105 
106 Color ToColor(const flutter::DlColor& color) {
107  FML_DCHECK(color.getColorSpace() == flutter::DlColorSpace::kExtendedSRGB ||
108  color.getColorSpace() == flutter::DlColorSpace::kSRGB);
109  return {
110  static_cast<Scalar>(color.getRedF()), //
111  static_cast<Scalar>(color.getGreenF()), //
112  static_cast<Scalar>(color.getBlueF()), //
113  static_cast<Scalar>(color.getAlphaF()) //
114  };
115 }
116 
117 Matrix ToRSXForm(const SkRSXform& form) {
118  // clang-format off
119  return Matrix{
120  form.fSCos, form.fSSin, 0, 0,
121  -form.fSSin, form.fSCos, 0, 0,
122  0, 0, 1, 0,
123  form.fTx, form.fTy, 0, 1
124  };
125  // clang-format on
126 }
127 
128 std::optional<impeller::PixelFormat> ToPixelFormat(SkColorType type) {
129  switch (type) {
130  case kRGBA_8888_SkColorType:
132  case kBGRA_8888_SkColorType:
134  case kRGBA_F16_SkColorType:
136  case kBGR_101010x_XR_SkColorType:
138  default:
139  return std::nullopt;
140  }
141  return std::nullopt;
142 }
143 
144 void ConvertStops(const flutter::DlGradientColorSourceBase* gradient,
145  std::vector<Color>& colors,
146  std::vector<float>& stops) {
147  FML_DCHECK(gradient->stop_count() >= 2)
148  << "stop_count:" << gradient->stop_count();
149 
150  auto* dl_colors = gradient->colors();
151  auto* dl_stops = gradient->stops();
152  if (dl_stops[0] != 0.0) {
153  colors.emplace_back(skia_conversions::ToColor(dl_colors[0]));
154  stops.emplace_back(0);
155  }
156  for (auto i = 0; i < gradient->stop_count(); i++) {
157  colors.emplace_back(skia_conversions::ToColor(dl_colors[i]));
158  stops.emplace_back(std::clamp(dl_stops[i], 0.0f, 1.0f));
159  }
160  if (dl_stops[gradient->stop_count() - 1] != 1.0) {
161  colors.emplace_back(colors.back());
162  stops.emplace_back(1.0);
163  }
164  for (auto i = 1; i < gradient->stop_count(); i++) {
165  stops[i] = std::clamp(stops[i], stops[i - 1], stops[i]);
166  }
167 }
168 
170  const flutter::DlImageSampling options) {
172  switch (options) {
173  case flutter::DlImageSampling::kNearestNeighbor:
176  desc.label = "Nearest Sampler";
177  break;
178  case flutter::DlImageSampling::kLinear:
181  desc.label = "Linear Sampler";
182  break;
183  case flutter::DlImageSampling::kCubic:
184  case flutter::DlImageSampling::kMipmapLinear:
187  desc.label = "Mipmap Linear Sampler";
188  break;
189  }
190  return desc;
191 }
192 
193 Matrix ToMatrix(const SkMatrix& m) {
194  return Matrix{
195  // clang-format off
196  m[0], m[3], 0, m[6],
197  m[1], m[4], 0, m[7],
198  0, 0, 1, 0,
199  m[2], m[5], 0, m[8],
200  // clang-format on
201  };
202 }
203 
204 BlendMode ToBlendMode(flutter::DlBlendMode mode) {
205  switch (mode) {
206  case flutter::DlBlendMode::kClear:
207  return BlendMode::kClear;
208  case flutter::DlBlendMode::kSrc:
209  return BlendMode::kSource;
210  case flutter::DlBlendMode::kDst:
212  case flutter::DlBlendMode::kSrcOver:
213  return BlendMode::kSourceOver;
214  case flutter::DlBlendMode::kDstOver:
216  case flutter::DlBlendMode::kSrcIn:
217  return BlendMode::kSourceIn;
218  case flutter::DlBlendMode::kDstIn:
220  case flutter::DlBlendMode::kSrcOut:
221  return BlendMode::kSourceOut;
222  case flutter::DlBlendMode::kDstOut:
224  case flutter::DlBlendMode::kSrcATop:
225  return BlendMode::kSourceATop;
226  case flutter::DlBlendMode::kDstATop:
228  case flutter::DlBlendMode::kXor:
229  return BlendMode::kXor;
230  case flutter::DlBlendMode::kPlus:
231  return BlendMode::kPlus;
232  case flutter::DlBlendMode::kModulate:
233  return BlendMode::kModulate;
234  case flutter::DlBlendMode::kScreen:
235  return BlendMode::kScreen;
236  case flutter::DlBlendMode::kOverlay:
237  return BlendMode::kOverlay;
238  case flutter::DlBlendMode::kDarken:
239  return BlendMode::kDarken;
240  case flutter::DlBlendMode::kLighten:
241  return BlendMode::kLighten;
242  case flutter::DlBlendMode::kColorDodge:
243  return BlendMode::kColorDodge;
244  case flutter::DlBlendMode::kColorBurn:
245  return BlendMode::kColorBurn;
246  case flutter::DlBlendMode::kHardLight:
247  return BlendMode::kHardLight;
248  case flutter::DlBlendMode::kSoftLight:
249  return BlendMode::kSoftLight;
250  case flutter::DlBlendMode::kDifference:
251  return BlendMode::kDifference;
252  case flutter::DlBlendMode::kExclusion:
253  return BlendMode::kExclusion;
254  case flutter::DlBlendMode::kMultiply:
255  return BlendMode::kMultiply;
256  case flutter::DlBlendMode::kHue:
257  return BlendMode::kHue;
258  case flutter::DlBlendMode::kSaturation:
259  return BlendMode::kSaturation;
260  case flutter::DlBlendMode::kColor:
261  return BlendMode::kColor;
262  case flutter::DlBlendMode::kLuminosity:
263  return BlendMode::kLuminosity;
264  }
265  FML_UNREACHABLE();
266 }
267 
268 } // namespace skia_conversions
269 } // namespace impeller
impeller::BlendMode::kDestinationATop
@ kDestinationATop
impeller::skia_conversions::ToPoints
std::vector< Point > ToPoints(const SkPoint points[], int count)
Definition: skia_conversions.cc:64
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::skia_conversions::IsNearlySimpleRRect
bool IsNearlySimpleRRect(const SkRRect &rr)
Like SkRRect.isSimple, but allows the corners to differ by kEhCloseEnough.
Definition: skia_conversions.cc:21
impeller::skia_conversions::ToPixelFormat
std::optional< impeller::PixelFormat > ToPixelFormat(SkColorType type)
Definition: skia_conversions.cc:128
impeller::skia_conversions::ConvertStops
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 st...
Definition: skia_conversions.cc:144
impeller::skia_conversions::ToSize
Size ToSize(const SkPoint &point)
Definition: skia_conversions.cc:102
impeller::BlendMode
BlendMode
Definition: color.h:58
impeller::Color
Definition: color.h:123
impeller::PathBuilder::SetBounds
PathBuilder & SetBounds(Rect bounds)
Set the bounding box that will be used by Path.GetBoundingBox in place of performing the computation.
Definition: path_builder.cc:494
impeller::skia_conversions::ToSamplerDescriptor
impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlImageSampling options)
Definition: skia_conversions.cc:169
impeller::kEhCloseEnough
constexpr float kEhCloseEnough
Definition: constants.h:56
impeller::BlendMode::kLuminosity
@ kLuminosity
impeller::BlendMode::kSource
@ kSource
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::BlendMode::kColorDodge
@ kColorDodge
impeller::BlendMode::kDestination
@ kDestination
impeller::BlendMode::kDarken
@ kDarken
impeller::PathBuilder
Definition: path_builder.h:14
impeller::BlendMode::kColor
@ kColor
impeller::skia_conversions::ToMatrix
Matrix ToMatrix(const SkMatrix &m)
Definition: skia_conversions.cc:193
impeller::skia_conversions::ToRects
std::vector< Rect > ToRects(const SkRect tex[], int count)
Definition: skia_conversions.cc:48
impeller::BlendMode::kDestinationOver
@ kDestinationOver
impeller::BlendMode::kPlus
@ kPlus
impeller::skia_conversions::ToColor
Color ToColor(const flutter::DlColor &color)
Definition: skia_conversions.cc:106
impeller::BlendMode::kOverlay
@ kOverlay
impeller::PathBuilder::AddRoundedRect
PathBuilder & AddRoundedRect(Rect rect, RoundingRadii radii)
Definition: path_builder.cc:153
impeller::Size
TSize< Scalar > Size
Definition: size.h:137
impeller::PathBuilder::SetConvexity
PathBuilder & SetConvexity(Convexity value)
Definition: path_builder.cc:88
impeller::skia_conversions::ToBlendMode
BlendMode ToBlendMode(flutter::DlBlendMode mode)
Definition: skia_conversions.cc:204
impeller::BlendMode::kModulate
@ kModulate
impeller::PathBuilder::RoundingRadii::bottom_right
Point bottom_right
Definition: path_builder.h:109
impeller::BlendMode::kSourceOut
@ kSourceOut
impeller::skia_conversions::ToRSXForm
Matrix ToRSXForm(const SkRSXform &form)
Definition: skia_conversions.cc:117
impeller::BlendMode::kSaturation
@ kSaturation
impeller::BlendMode::kDifference
@ kDifference
impeller::MinMagFilter::kNearest
@ kNearest
Select nearest to the sample point. Most widely supported.
impeller::SamplerDescriptor::mag_filter
MinMagFilter mag_filter
Definition: sampler_descriptor.h:17
impeller::skia_conversions::ToRect
Rect ToRect(const SkRect &rect)
Definition: skia_conversions.cc:30
impeller::SamplerDescriptor
Definition: sampler_descriptor.h:15
impeller::PathBuilder::RoundingRadii
Definition: path_builder.h:105
impeller::skia_conversions::SkScalarsNearlyEqual
static bool SkScalarsNearlyEqual(SkScalar a, SkScalar b, SkScalar c, SkScalar d)
Definition: skia_conversions.cc:12
impeller::BlendMode::kLighten
@ kLighten
impeller::TSize< Scalar >
impeller::skia_conversions::ToRoundingRadii
PathBuilder::RoundingRadii ToRoundingRadii(const SkRRect &rrect)
Definition: skia_conversions.cc:80
impeller::SamplerDescriptor::min_filter
MinMagFilter min_filter
Definition: sampler_descriptor.h:16
impeller::BlendMode::kSoftLight
@ kSoftLight
impeller::BlendMode::kColorBurn
@ kColorBurn
skia_conversions.h
impeller::BlendMode::kHardLight
@ kHardLight
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:52
impeller::BlendMode::kClear
@ kClear
impeller::MinMagFilter::kLinear
@ kLinear
impeller::DlRect
flutter::DlRect DlRect
Definition: dl_dispatcher.h:23
impeller::PixelFormat::kB10G10R10XR
@ kB10G10R10XR
type
GLenum type
Definition: blit_command_gles.cc:127
impeller::PathBuilder::RoundingRadii::top_left
Point top_left
Definition: path_builder.h:106
impeller::PixelFormat::kR16G16B16A16Float
@ kR16G16B16A16Float
impeller::PathBuilder::TakePath
Path TakePath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:24
impeller::skia_conversions::ToPoint
Point ToPoint(const SkPoint &point)
Definition: skia_conversions.cc:98
impeller::SamplerDescriptor::mip_filter
MipFilter mip_filter
Definition: sampler_descriptor.h:18
impeller::BlendMode::kDestinationIn
@ kDestinationIn
impeller::BlendMode::kExclusion
@ kExclusion
impeller::BlendMode::kDestinationOut
@ kDestinationOut
impeller::MipFilter::kBase
@ kBase
The texture is sampled as if it only had a single mipmap level.
impeller::PathBuilder::RoundingRadii::top_right
Point top_right
Definition: path_builder.h:108
impeller::DlPoint
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:22
impeller::TPoint
Definition: point.h:27
impeller::saturated::b
SI b
Definition: saturated_math.h:87
impeller::PathBuilder::RoundingRadii::bottom_left
Point bottom_left
Definition: path_builder.h:107
impeller::MipFilter::kLinear
@ kLinear
Sample from the two nearest mip levels and linearly interpolate.
impeller::BlendMode::kSourceIn
@ kSourceIn
impeller::BlendMode::kScreen
@ kScreen
impeller::SamplerDescriptor::label
std::string label
Definition: sampler_descriptor.h:24
color
DlColor color
Definition: dl_golden_blur_unittests.cc:24
impeller::skia_conversions::ToPath
Path ToPath(const SkRRect &rrect)
Definition: skia_conversions.cc:90
impeller::BlendMode::kHue
@ kHue
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
impeller::BlendMode::kXor
@ kXor
impeller::Convexity::kConvex
@ kConvex
impeller::PixelFormat::kB8G8R8A8UNormInt
@ kB8G8R8A8UNormInt
impeller
Definition: allocation.cc:12
impeller::BlendMode::kSourceATop
@ kSourceATop
impeller::BlendMode::kMultiply
@ kMultiply
impeller::TRect< Scalar >
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::BlendMode::kSourceOver
@ kSourceOver
impeller::TPoint< Scalar >::MakeXY
static constexpr TPoint< Type > MakeXY(Type x, Type y)
Definition: point.h:46