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 "flutter/display_list/dl_blend_mode.h"
7 #include "flutter/display_list/dl_color.h"
8 #include "third_party/skia/modules/skparagraph/include/Paragraph.h"
9 
10 namespace impeller {
11 namespace skia_conversions {
12 
13 static inline bool SkScalarsNearlyEqual(SkScalar a,
14  SkScalar b,
15  SkScalar c,
16  SkScalar d) {
17  return SkScalarNearlyEqual(a, b, kEhCloseEnough) &&
18  SkScalarNearlyEqual(a, c, kEhCloseEnough) &&
19  SkScalarNearlyEqual(a, d, kEhCloseEnough);
20 }
21 
22 bool IsNearlySimpleRRect(const SkRRect& rr) {
23  auto [xa, ya] = rr.radii(SkRRect::kUpperLeft_Corner);
24  auto [xb, yb] = rr.radii(SkRRect::kLowerLeft_Corner);
25  auto [xc, yc] = rr.radii(SkRRect::kUpperRight_Corner);
26  auto [xd, yd] = rr.radii(SkRRect::kLowerRight_Corner);
27  return SkScalarsNearlyEqual(xa, xb, xc, xd) &&
28  SkScalarsNearlyEqual(ya, yb, yc, yd);
29 }
30 
31 Rect ToRect(const SkRect& rect) {
32  return Rect::MakeLTRB(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
33 }
34 
35 std::optional<Rect> ToRect(const SkRect* rect) {
36  if (rect == nullptr) {
37  return std::nullopt;
38  }
39  return Rect::MakeLTRB(rect->fLeft, rect->fTop, rect->fRight, rect->fBottom);
40 }
41 
42 std::optional<const Rect> ToRect(const flutter::DlRect* rect) {
43  if (rect == nullptr) {
44  return std::nullopt;
45  }
46  return *rect;
47 }
48 
49 std::vector<Rect> ToRects(const SkRect tex[], int count) {
50  auto result = std::vector<Rect>();
51  for (int i = 0; i < count; i++) {
52  result.push_back(ToRect(tex[i]));
53  }
54  return result;
55 }
56 
57 std::vector<Rect> ToRects(const flutter::DlRect tex[], int count) {
58  auto result = std::vector<Rect>();
59  for (int i = 0; i < count; i++) {
60  result.push_back(tex[i]);
61  }
62  return result;
63 }
64 
65 std::vector<Point> ToPoints(const SkPoint points[], int count) {
66  std::vector<Point> result(count);
67  for (auto i = 0; i < count; i++) {
68  result[i] = ToPoint(points[i]);
69  }
70  return result;
71 }
72 
73 std::vector<Point> ToPoints(const flutter::DlPoint points[], int count) {
74  std::vector<Point> result(count);
75  for (auto i = 0; i < count; i++) {
76  result[i] = points[i];
77  }
78  return result;
79 }
80 
81 Point ToPoint(const SkPoint& point) {
82  return Point::MakeXY(point.fX, point.fY);
83 }
84 
85 Size ToSize(const SkPoint& point) {
86  return Size(point.fX, point.fY);
87 }
88 
89 Color ToColor(const flutter::DlColor& color) {
90  FML_DCHECK(color.getColorSpace() == flutter::DlColorSpace::kExtendedSRGB ||
91  color.getColorSpace() == flutter::DlColorSpace::kSRGB);
92  return {
93  static_cast<Scalar>(color.getRedF()), //
94  static_cast<Scalar>(color.getGreenF()), //
95  static_cast<Scalar>(color.getBlueF()), //
96  static_cast<Scalar>(color.getAlphaF()) //
97  };
98 }
99 
100 std::optional<impeller::PixelFormat> ToPixelFormat(SkColorType type) {
101  switch (type) {
102  case kRGBA_8888_SkColorType:
104  case kBGRA_8888_SkColorType:
106  case kRGBA_F16_SkColorType:
108  case kBGR_101010x_XR_SkColorType:
110  default:
111  return std::nullopt;
112  }
113  return std::nullopt;
114 }
115 
116 void ConvertStops(const flutter::DlGradientColorSourceBase* gradient,
117  std::vector<Color>& colors,
118  std::vector<float>& stops) {
119  FML_DCHECK(gradient->stop_count() >= 2)
120  << "stop_count:" << gradient->stop_count();
121 
122  auto* dl_colors = gradient->colors();
123  auto* dl_stops = gradient->stops();
124  if (dl_stops[0] != 0.0) {
125  colors.emplace_back(skia_conversions::ToColor(dl_colors[0]));
126  stops.emplace_back(0);
127  }
128  for (auto i = 0; i < gradient->stop_count(); i++) {
129  colors.emplace_back(skia_conversions::ToColor(dl_colors[i]));
130  stops.emplace_back(std::clamp(dl_stops[i], 0.0f, 1.0f));
131  }
132  if (dl_stops[gradient->stop_count() - 1] != 1.0) {
133  colors.emplace_back(colors.back());
134  stops.emplace_back(1.0);
135  }
136  for (auto i = 1; i < gradient->stop_count(); i++) {
137  stops[i] = std::clamp(stops[i], stops[i - 1], stops[i]);
138  }
139 }
140 
142  const flutter::DlImageSampling options) {
144  switch (options) {
145  case flutter::DlImageSampling::kNearestNeighbor:
148  desc.label = "Nearest Sampler";
149  break;
150  case flutter::DlImageSampling::kLinear:
153  desc.label = "Linear Sampler";
154  break;
155  case flutter::DlImageSampling::kCubic:
156  case flutter::DlImageSampling::kMipmapLinear:
159  desc.label = "Mipmap Linear Sampler";
160  break;
161  }
162  return desc;
163 }
164 
165 Matrix ToMatrix(const SkMatrix& m) {
166  return Matrix{
167  // clang-format off
168  m[0], m[3], 0, m[6],
169  m[1], m[4], 0, m[7],
170  0, 0, 1, 0,
171  m[2], m[5], 0, m[8],
172  // clang-format on
173  };
174 }
175 
176 BlendMode ToBlendMode(flutter::DlBlendMode mode) {
177  switch (mode) {
178  case flutter::DlBlendMode::kClear:
179  return BlendMode::kClear;
180  case flutter::DlBlendMode::kSrc:
181  return BlendMode::kSource;
182  case flutter::DlBlendMode::kDst:
184  case flutter::DlBlendMode::kSrcOver:
185  return BlendMode::kSourceOver;
186  case flutter::DlBlendMode::kDstOver:
188  case flutter::DlBlendMode::kSrcIn:
189  return BlendMode::kSourceIn;
190  case flutter::DlBlendMode::kDstIn:
192  case flutter::DlBlendMode::kSrcOut:
193  return BlendMode::kSourceOut;
194  case flutter::DlBlendMode::kDstOut:
196  case flutter::DlBlendMode::kSrcATop:
197  return BlendMode::kSourceATop;
198  case flutter::DlBlendMode::kDstATop:
200  case flutter::DlBlendMode::kXor:
201  return BlendMode::kXor;
202  case flutter::DlBlendMode::kPlus:
203  return BlendMode::kPlus;
204  case flutter::DlBlendMode::kModulate:
205  return BlendMode::kModulate;
206  case flutter::DlBlendMode::kScreen:
207  return BlendMode::kScreen;
208  case flutter::DlBlendMode::kOverlay:
209  return BlendMode::kOverlay;
210  case flutter::DlBlendMode::kDarken:
211  return BlendMode::kDarken;
212  case flutter::DlBlendMode::kLighten:
213  return BlendMode::kLighten;
214  case flutter::DlBlendMode::kColorDodge:
215  return BlendMode::kColorDodge;
216  case flutter::DlBlendMode::kColorBurn:
217  return BlendMode::kColorBurn;
218  case flutter::DlBlendMode::kHardLight:
219  return BlendMode::kHardLight;
220  case flutter::DlBlendMode::kSoftLight:
221  return BlendMode::kSoftLight;
222  case flutter::DlBlendMode::kDifference:
223  return BlendMode::kDifference;
224  case flutter::DlBlendMode::kExclusion:
225  return BlendMode::kExclusion;
226  case flutter::DlBlendMode::kMultiply:
227  return BlendMode::kMultiply;
228  case flutter::DlBlendMode::kHue:
229  return BlendMode::kHue;
230  case flutter::DlBlendMode::kSaturation:
231  return BlendMode::kSaturation;
232  case flutter::DlBlendMode::kColor:
233  return BlendMode::kColor;
234  case flutter::DlBlendMode::kLuminosity:
235  return BlendMode::kLuminosity;
236  }
237  FML_UNREACHABLE();
238 }
239 
240 } // namespace skia_conversions
241 } // namespace impeller
GLenum type
Matrix ToMatrix(const SkMatrix &m)
BlendMode ToBlendMode(flutter::DlBlendMode mode)
std::optional< impeller::PixelFormat > ToPixelFormat(SkColorType type)
static bool SkScalarsNearlyEqual(SkScalar a, SkScalar b, SkScalar c, SkScalar d)
std::vector< Point > ToPoints(const SkPoint points[], int count)
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...
Point ToPoint(const SkPoint &point)
Size ToSize(const SkPoint &point)
std::vector< Rect > ToRects(const SkRect tex[], int count)
impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlImageSampling options)
bool IsNearlySimpleRRect(const SkRRect &rr)
Like SkRRect.isSimple, but allows the corners to differ by kEhCloseEnough.
Rect ToRect(const SkRect &rect)
Color ToColor(const flutter::DlColor &color)
flutter::DlRect DlRect
Definition: dl_dispatcher.h:25
float Scalar
Definition: scalar.h:18
constexpr float kEhCloseEnough
Definition: constants.h:56
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:24
@ kLinear
Sample from the two nearest mip levels and linearly interpolate.
@ kBase
The texture is sampled as if it only had a single mipmap level.
BlendMode
Definition: color.h:58
TSize< Scalar > Size
Definition: size.h:171
@ kNearest
Select nearest to the sample point. Most widely supported.
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
static constexpr TPoint< Type > MakeXY(Type x, Type y)
Definition: point.h:46
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129