Flutter Engine
The Flutter Engine
imagemakewithfilter.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "gm/gm.h"
9
14#include "include/core/SkFont.h"
21#include "include/core/SkRect.h"
25#include "include/core/SkSize.h"
30#include "tools/DecodeUtils.h"
31#include "tools/GpuToolUtils.h"
32#include "tools/Resources.h"
33#include "tools/ToolUtils.h"
35
36#if defined(SK_GANESH)
39#endif
40
41#if defined(SK_GRAPHITE)
43#endif
44
45#include <utility>
46
47///////////////////////////////////////////////////////////////////////////////
48
49static void show_bounds(SkCanvas* canvas, const SkIRect* clip, const SkIRect* inSubset,
50 const SkIRect* outSubset) {
51 const SkIRect* rects[] { clip, inSubset, outSubset };
53
56
57 for (size_t i = 0; i < std::size(rects); ++i) {
58 // Skip null bounds rects, since not all methods have subsets
59 if (rects[i]) {
60 paint.setColor(colors[i]);
61 canvas->drawRect(SkRect::Make(*(rects[i])), paint);
62 }
63 }
64}
65
66// Factories for creating image filters, either with or without a cropRect
67// (this could go away if there was a SkImageFilter::makeWithCropRect() function, but that seems
68// less generally useful).
69typedef sk_sp<SkImageFilter> (*FilterFactory)(sk_sp<SkImage> auxImage, const SkIRect* cropRect);
70
72 // The color filter uses kSrcIn so that it respects the transparency introduced by clamping;
73 // using kSrc would just turn the entire out rect to green regardless.
75 return SkImageFilters::ColorFilter(std::move(cf), nullptr, cropRect);
76}
77
79 return SkImageFilters::Blur(2.0f, 2.0f, nullptr, cropRect);
80}
81
83 return SkImageFilters::DropShadow(10.0f, 5.0f, 3.0f, 3.0f, SK_ColorBLUE, nullptr, cropRect);
84}
85
86static sk_sp<SkImageFilter> offset_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
87 return SkImageFilters::Offset(10.f, 5.f, nullptr, cropRect);
88}
89
90static sk_sp<SkImageFilter> dilate_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
91 return SkImageFilters::Dilate(10.f, 5.f, nullptr, cropRect);
92}
93
94static sk_sp<SkImageFilter> erode_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
95 return SkImageFilters::Erode(10.f, 5.f, nullptr, cropRect);
96}
97
99 sk_sp<SkImageFilter> displacement = SkImageFilters::Image(std::move(auxImage),
102 std::move(displacement), nullptr, cropRect);
103}
104
106 sk_sp<SkImageFilter> background = SkImageFilters::Image(std::move(auxImage),
108 return SkImageFilters::Arithmetic(0.0f, .6f, 1.f, 0.f, false, std::move(background),
109 nullptr, cropRect);
110}
111
112static sk_sp<SkImageFilter> blend_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
113 sk_sp<SkImageFilter> background = SkImageFilters::Image(std::move(auxImage),
116 SkBlendMode::kModulate, std::move(background), nullptr, cropRect);
117}
118
120 SkISize kernelSize = SkISize::Make(3, 3);
121 SkIPoint kernelOffset = SkIPoint::Make(1, 1);
122 // A Laplacian edge detector, ee https://en.wikipedia.org/wiki/Kernel_(image_processing)
123 SkScalar kernel[9] = {-1.f, -1.f, -1.f,
124 -1.f, 8.f, -1.f,
125 -1.f, -1.f, -1.f};
126 return SkImageFilters::MatrixConvolution(kernelSize, kernel, 1.f, 0.f, kernelOffset,
127 SkTileMode::kClamp, false, nullptr, cropRect);
128}
129
132 matrix.setRotate(45.f, 50.f, 50.f);
133
134 // This doesn't support a cropRect
136}
137
139 // Must convert the RGB values of the source to alpha, since that is what the lighting filters
140 // use to estimate their normals. This color matrix changes the color to white and the alpha
141 // to be equal to the approx. luminance of the original color.
142 static const float kMatrix[20] = {
143 0.f, 0.f, 0.f, 0.f, 1.f,
144 0.f, 0.f, 0.f, 0.f, 1.f,
145 0.f, 0.f, 0.f, 0.f, 1.f,
146 0.2126f, 0.7152f, 0.0722f, 0.f, 0.f
147 };
149 SkColorFilters::Matrix(kMatrix), nullptr);
150
151 // Combine both specular and diffuse into a single DAG since they use separate internal filter
152 // implementations.
153 SkScalar sinAzimuth = SkScalarSin(SkDegreesToRadians(225.f)),
154 cosAzimuth = SkScalarCos(SkDegreesToRadians(225.f));
155
156 SkPoint3 spotTarget = SkPoint3::Make(SkIntToScalar(40), SkIntToScalar(40), 0);
157 SkPoint3 diffLocation = SkPoint3::Make(spotTarget.fX + 50 * cosAzimuth,
158 spotTarget.fY + 50 * sinAzimuth,
159 SkIntToScalar(10));
160 SkPoint3 specLocation = SkPoint3::Make(spotTarget.fX - 50 * sinAzimuth,
161 spotTarget.fY + 50 * cosAzimuth,
162 SkIntToScalar(10));
164 diffLocation, SK_ColorWHITE, /* scale */ 1.f, /* kd */ 2.f, srcToAlpha, cropRect);
166 specLocation, SK_ColorRED, /* scale */ 1.f, /* ks */ 1.f, /* shine */ 8.f,
167 srcToAlpha, cropRect);
168 return SkImageFilters::Merge(std::move(diffuse), std::move(specular), cropRect);
169}
170
171static sk_sp<SkImageFilter> tile_factory(sk_sp<SkImage> auxImage, const SkIRect* cropRect) {
172 // Tile the subset over a large region
173 return SkImageFilters::Tile(SkRect::MakeLTRB(25, 25, 75, 75), SkRect::MakeWH(100, 100),
174 nullptr);
175}
176
177namespace {
178 enum class Strategy {
179 // Uses MakeWithFilter, passing in subset and clip directly
180 kMakeWithFilter,
181 // Uses saveLayer after clipRect() to filter on the restore (i.e. reference image)
182 kSaveLayer
183 };
184} // namespace
185
186// In this GM, we're going to feed the inner portion of a 100x100 mandrill (i.e., strip off a
187// 25-wide border) through the MakeWithFilter factory. We'll then draw the appropriate subset of the
188// result to the screen at the given offset. Some filters rely on a secondary image, which will be a
189// 100x100 checkerboard. The original image is drawn in the background so that alignment is clear
190// when drawing the result at its reported offset.
192public:
193 ImageMakeWithFilterGM (Strategy strategy, bool filterWithCropRect = false)
194 : fStrategy(strategy)
195 , fFilterWithCropRect(filterWithCropRect)
196 , fMainImage(nullptr)
197 , fAuxImage(nullptr) {}
198
199protected:
200 SkString getName() const override {
201 SkString name = SkString("imagemakewithfilter");
202
203 if (fFilterWithCropRect) {
204 name.append("_crop");
205 }
206 if (fStrategy == Strategy::kSaveLayer) {
207 name.append("_ref");
208 }
209 return name;
210 }
211
212 SkISize getISize() override { return SkISize::Make(1840, 860); }
213
214 void onOnceBeforeDraw() override {
216 auto surface = SkSurfaces::Raster(info, nullptr);
217
218 sk_sp<SkImage> colorImage = ToolUtils::GetResourceAsImage("images/mandrill_128.png");
219 // Resize to 100x100
220 surface->getCanvas()->drawImageRect(
221 colorImage, SkRect::MakeWH(colorImage->width(), colorImage->height()),
222 SkRect::MakeWH(info.width(), info.height()), SkSamplingOptions(), nullptr,
224 fMainImage = surface->makeImageSnapshot();
225
227 fAuxImage = surface->makeImageSnapshot();
228 }
229
230 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
231 FilterFactory filters[] = {
245 };
246 const char* filterNames[] = {
247 "Color",
248 "Blur",
249 "Drop Shadow",
250 "Offset",
251 "Dilate",
252 "Erode",
253 "Displacement",
254 "Arithmetic",
255 "Blend",
256 "Convolution",
257 "Matrix Xform",
258 "Lighting",
259 "Tile"
260 };
261 static_assert(std::size(filters) == std::size(filterNames), "filter name length");
262
263 SkIRect clipBounds[] {
264 { -20, -20, 100, 100 },
265 { 0, 0, 75, 75 },
266 { 20, 20, 100, 100 },
267 { -20, -20, 50, 50 },
268 { 20, 20, 50, 50 },
269 { 30, 30, 75, 75 }
270 };
271
272 auto rContext = canvas->recordingContext();
273 // In a DDL context, we can't use the GPU code paths and we will drop the work – skip.
274 auto dContext = GrAsDirectContext(rContext);
275 if (rContext) {
276 if (!dContext) {
277 *errorMsg = "Requires a direct context.";
278 return DrawResult::kSkip;
279 }
280 if (dContext->abandoned()) {
281 *errorMsg = "Direct context abandoned.";
282 return DrawResult::kSkip;
283 }
284 }
285
286 // These need to be GPU-backed when on the GPU to ensure that the image filters use the GPU
287 // code paths (otherwise they may choose to do CPU filtering then upload)
288 sk_sp<SkImage> mainImage = ToolUtils::MakeTextureImage(canvas, fMainImage);
289 sk_sp<SkImage> auxImage = ToolUtils::MakeTextureImage(canvas, fAuxImage);
290 if (!mainImage || !auxImage) {
291 return DrawResult::kFail;
292 }
293 SkASSERT(mainImage && (mainImage->isTextureBacked() || !dContext));
294 SkASSERT(auxImage && (auxImage->isTextureBacked() || !dContext));
295
297 SkScalar DX = mainImage->width() + MARGIN;
298 SkScalar DY = auxImage->height() + MARGIN;
299
300 // Header hinting at what the filters do
301 SkPaint textPaint;
302 textPaint.setAntiAlias(true);
304 font.setSize(12);
305 for (size_t i = 0; i < std::size(filterNames); ++i) {
306 canvas->drawString(filterNames[i], DX * i + MARGIN, 15, font, textPaint);
307 }
308
309 canvas->translate(MARGIN, MARGIN);
310
311 for (auto clipBound : clipBounds) {
312 canvas->save();
313 for (size_t i = 0; i < std::size(filters); ++i) {
314 SkIRect subset = SkIRect::MakeXYWH(25, 25, 50, 50);
315 SkIRect outSubset;
316
317 // Draw the original image faintly so that it aids in checking alignment of the
318 // filtered result.
319 SkPaint alpha;
320 alpha.setAlphaf(0.3f);
321 canvas->drawImage(mainImage, 0, 0, SkSamplingOptions(), &alpha);
322
323 this->drawImageWithFilter(canvas, mainImage, auxImage, filters[i], clipBound,
324 subset, &outSubset);
325
326 // Draw outlines to highlight what was subset, what was cropped, and what was output
327 // (no output subset is displayed for kSaveLayer since that information isn't avail)
328 SkIRect* outSubsetBounds = nullptr;
329 if (fStrategy != Strategy::kSaveLayer) {
330 outSubsetBounds = &outSubset;
331 }
332 show_bounds(canvas, &clipBound, &subset, outSubsetBounds);
333
334 canvas->translate(DX, 0);
335 }
336 canvas->restore();
337 canvas->translate(0, DY);
338 }
339 return DrawResult::kOk;
340 }
341
342private:
343 Strategy fStrategy;
344 bool fFilterWithCropRect;
345 sk_sp<SkImage> fMainImage;
346 sk_sp<SkImage> fAuxImage;
347
348 void drawImageWithFilter(SkCanvas* canvas, sk_sp<SkImage> mainImage, sk_sp<SkImage> auxImage,
349 FilterFactory filterFactory, const SkIRect& clip,
350 const SkIRect& subset, SkIRect* dstRect) {
351 // When creating the filter with a crop rect equal to the clip, we should expect to see no
352 // difference from a filter without a crop rect. However, if the CTM isn't managed properly
353 // by MakeWithFilter, then the final result will be the incorrect intersection of the clip
354 // and the transformed crop rect.
355 sk_sp<SkImageFilter> filter = filterFactory(auxImage,
356 fFilterWithCropRect ? &clip : nullptr);
357
358 if (fStrategy == Strategy::kSaveLayer) {
359 SkAutoCanvasRestore acr(canvas, true);
360
361 // Clip before the saveLayer with the filter
362 canvas->clipRect(SkRect::Make(clip));
363
364 // Put the image filter on the layer
366 paint.setImageFilter(filter);
367 canvas->saveLayer(nullptr, &paint);
368
369 // Draw the original subset of the image
370 SkRect r = SkRect::Make(subset);
371 canvas->drawImageRect(mainImage, r, r, SkSamplingOptions(),
373
374 *dstRect = subset;
375 } else {
377 SkIRect outSubset;
379
380#if defined(SK_GANESH)
381 if (auto rContext = canvas->recordingContext()) {
382 result = SkImages::MakeWithFilter(rContext, mainImage, filter.get(),
383 subset, clip, &outSubset, &offset);
384 } else
385#endif
386#if defined(SK_GRAPHITE)
387 if (auto recorder = canvas->recorder()){
388 result = SkImages::MakeWithFilter(recorder, mainImage, filter.get(),
389 subset, clip, &outSubset, &offset);
390 } else
391#endif
392 {
393 result = SkImages::MakeWithFilter(mainImage, filter.get(),
394 subset, clip, &outSubset, &offset);
395 }
396
397 if (!result) {
398 return;
399 }
400
401 SkASSERT(mainImage->isTextureBacked() == result->isTextureBacked());
402
403 *dstRect = SkIRect::MakeXYWH(offset.x(), offset.y(),
404 outSubset.width(), outSubset.height());
405 canvas->drawImageRect(result, SkRect::Make(outSubset), SkRect::Make(*dstRect),
406 SkSamplingOptions(), nullptr,
408 }
409 }
410
411 using INHERITED = GM;
412};
413// The different strategies should all look the same, with the exception of filters that affect
414// transparent black (i.e. the lighting filter). In the save layer case, the filter affects the
415// transparent pixels outside of the drawn subset, whereas the MakeWithFilter is restricted. This
416// works as intended.
417DEF_GM( return new ImageMakeWithFilterGM(Strategy::kMakeWithFilter); )
418DEF_GM( return new ImageMakeWithFilterGM(Strategy::kSaveLayer); )
419// Test with crop rects on the image filters; should look identical to above if working correctly
420DEF_GM( return new ImageMakeWithFilterGM(Strategy::kMakeWithFilter, true); )
421DEF_GM( return new ImageMakeWithFilterGM(Strategy::kSaveLayer, true); )
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
static GrDirectContext * GrAsDirectContext(GrContext_Base *base)
kUnpremul_SkAlphaType
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kModulate
r = s*d
@ kSrcIn
r = s * da
constexpr SkColor SK_ColorYELLOW
Definition: SkColor.h:139
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
#define SkDegreesToRadians(degrees)
Definition: SkScalar.h:77
#define SkScalarSin(radians)
Definition: SkScalar.h:45
#define SkIntToScalar(x)
Definition: SkScalar.h:57
#define SkScalarCos(radians)
Definition: SkScalar.h:46
void onOnceBeforeDraw() override
SkISize getISize() override
DrawResult onDraw(SkCanvas *canvas, SkString *errorMsg) override
SkString getName() const override
ImageMakeWithFilterGM(Strategy strategy, bool filterWithCropRect=false)
int saveLayer(const SkRect *bounds, const SkPaint *paint)
Definition: SkCanvas.cpp:496
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1361
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
virtual GrRecordingContext * recordingContext() const
Definition: SkCanvas.cpp:1637
virtual skgpu::graphite::Recorder * recorder() const
Definition: SkCanvas.cpp:1641
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
Definition: SkCanvas.h:1542
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
Definition: SkCanvas.cpp:2333
int save()
Definition: SkCanvas.cpp:447
void drawString(const char str[], SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
Definition: SkCanvas.h:1803
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
static sk_sp< SkColorFilter > Blend(const SkColor4f &c, sk_sp< SkColorSpace >, SkBlendMode mode)
static sk_sp< SkColorFilter > Matrix(const SkColorMatrix &)
Definition: SkFont.h:35
static sk_sp< SkImageFilter > PointLitDiffuse(const SkPoint3 &location, SkColor lightColor, SkScalar surfaceScale, SkScalar kd, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > MatrixConvolution(const SkISize &kernelSize, const SkScalar kernel[], SkScalar gain, SkScalar bias, const SkIPoint &kernelOffset, SkTileMode tileMode, bool convolveAlpha, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > ColorFilter(sk_sp< SkColorFilter > cf, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > DropShadow(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor color, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Erode(SkScalar radiusX, SkScalar radiusY, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Merge(sk_sp< SkImageFilter > *const filters, int count, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Arithmetic(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, bool enforcePMColor, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Blur(SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > DisplacementMap(SkColorChannel xChannelSelector, SkColorChannel yChannelSelector, SkScalar scale, sk_sp< SkImageFilter > displacement, sk_sp< SkImageFilter > color, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Image(sk_sp< SkImage > image, const SkRect &srcRect, const SkRect &dstRect, const SkSamplingOptions &sampling)
static sk_sp< SkImageFilter > MatrixTransform(const SkMatrix &matrix, const SkSamplingOptions &sampling, sk_sp< SkImageFilter > input)
static sk_sp< SkImageFilter > Blend(SkBlendMode mode, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground=nullptr, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Offset(SkScalar dx, SkScalar dy, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Dilate(SkScalar radiusX, SkScalar radiusY, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Tile(const SkRect &src, const SkRect &dst, sk_sp< SkImageFilter > input)
static sk_sp< SkImageFilter > PointLitSpecular(const SkPoint3 &location, SkColor lightColor, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
int width() const
Definition: SkImage.h:285
virtual bool isTextureBacked() const =0
int height() const
Definition: SkImage.h:291
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
void setAntiAlias(bool aa)
Definition: SkPaint.h:170
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
void setAlphaf(float a)
Definition: SkPaint.cpp:130
T * get() const
Definition: SkRefCnt.h:303
Definition: gm.h:110
GM(SkColor backgroundColor=SK_ColorWHITE)
Definition: gm.cpp:81
const Paint & paint
Definition: color_source.cc:38
#define MARGIN
VkSurfaceKHR surface
Definition: main.cc:49
float SkScalar
Definition: extension.cpp:12
GAsyncResult * result
#define DEF_GM(CODE)
Definition: gm.h:40
static sk_sp< SkImageFilter > tile_factory(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
static void show_bounds(SkCanvas *canvas, const SkIRect *clip, const SkIRect *inSubset, const SkIRect *outSubset)
static sk_sp< SkImageFilter > drop_shadow_factory(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
static sk_sp< SkImageFilter > lighting_factory(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
static sk_sp< SkImageFilter > dilate_factory(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
static sk_sp< SkImageFilter > blur_filter_factory(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
static sk_sp< SkImageFilter > convolution_factory(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
static sk_sp< SkImageFilter > offset_factory(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
static sk_sp< SkImageFilter > blend_factory(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
static sk_sp< SkImageFilter > erode_factory(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
static sk_sp< SkImageFilter > color_filter_factory(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
static sk_sp< SkImageFilter > matrix_factory(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
sk_sp< SkImageFilter >(* FilterFactory)(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
static sk_sp< SkImageFilter > arithmetic_factory(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
static sk_sp< SkImageFilter > displacement_factory(sk_sp< SkImage > auxImage, const SkIRect *cropRect)
SK_API sk_sp< SkImage > MakeWithFilter(sk_sp< SkImage > src, const SkImageFilter *filter, const SkIRect &subset, const SkIRect &clipBounds, SkIRect *outSubset, SkIPoint *offset)
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
PODArray< SkColor > colors
Definition: SkRecords.h:276
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
void draw_checkerboard(SkCanvas *canvas, SkColor c1, SkColor c2, int size)
Definition: ToolUtils.cpp:174
SkFont DefaultPortableFont()
sk_sp< SkImage > MakeTextureImage(SkCanvas *canvas, sk_sp< SkImage > orig)
sk_sp< SkImage > GetResourceAsImage(const char *resource)
Definition: DecodeUtils.h:25
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
font
Font Metadata and Metrics.
SkSamplingOptions(SkFilterMode::kLinear))
DrawResult
Definition: gm.h:104
SeparatedVector2 offset
static constexpr SkIPoint Make(int32_t x, int32_t y)
Definition: SkPoint_impl.h:38
Definition: SkRect.h:32
constexpr int32_t height() const
Definition: SkRect.h:165
constexpr int32_t width() const
Definition: SkRect.h:158
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition: SkRect.h:104
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
static SkImageInfo MakeN32(int width, int height, SkAlphaType at)
SkScalar fX
Definition: SkPoint3.h:16
static SkPoint3 Make(SkScalar x, SkScalar y, SkScalar z)
Definition: SkPoint3.h:18
SkScalar fY
Definition: SkPoint3.h:16
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646