Flutter Engine
The Flutter Engine
BigImageTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023 Google LLC
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
21#include "include/core/SkRect.h"
25#include "include/core/SkSize.h"
34#include "tests/Test.h"
35#include "tests/TestUtils.h"
36#include "tools/ToolUtils.h"
37
38#if defined(SK_GANESH)
46struct GrContextOptions;
47#endif
48
49#if defined(SK_GRAPHITE)
56#include "tools/GpuToolUtils.h"
57#else
58namespace skgpu { namespace graphite { class Recorder; } }
59#endif
60
61#include <atomic>
62#include <functional>
63#include <initializer_list>
64#include <string.h>
65#include <utility>
66
67#if defined(SK_GANESH) && defined(GR_TEST_UTILS)
68extern int gOverrideMaxTextureSizeGanesh;
69extern std::atomic<int> gNumTilesDrawnGanesh;
70#endif
71
72#if defined(SK_GRAPHITE) && defined(GRAPHITE_TEST_UTILS)
73extern int gOverrideMaxTextureSizeGraphite;
74extern std::atomic<int> gNumTilesDrawnGraphite;
75#endif
76
77namespace {
78
79// Draw a white border around the edge (to test strict constraints) and
80// a Hilbert curve inside of that (so the effects of (mis) sampling are evident).
81 void draw(SkCanvas* canvas, int imgSize, int whiteBandWidth,
82 int desiredLineWidth, int desiredDepth) {
83 const int kPad = desiredLineWidth;
84
85 canvas->clear(SK_ColorWHITE);
86
87 SkPaint innerRect;
88 innerRect.setColor(SK_ColorDKGRAY);
89 canvas->drawRect(SkRect::MakeIWH(imgSize, imgSize).makeInset(whiteBandWidth, whiteBandWidth),
90 innerRect);
91
92 int desiredDrawSize = imgSize - 2 * kPad - 2 * whiteBandWidth;
93 ToolUtils::HilbertGenerator gen(desiredDrawSize, desiredLineWidth, desiredDepth);
94
95 canvas->translate(kPad + whiteBandWidth, imgSize - kPad - whiteBandWidth);
96 gen.draw(canvas);
97}
98
99
100sk_sp<SkImage> make_big_bitmap_image(int imgSize, int whiteBandWidth,
101 int desiredLineWidth, int desiredDepth) {
102 SkBitmap bm;
103
104 bm.allocN32Pixels(imgSize, imgSize, /* isOpaque= */ true);
105 SkCanvas canvas(bm);
106
107 draw(&canvas, imgSize, whiteBandWidth, desiredLineWidth, desiredDepth);
108
109 bm.setImmutable();
110 return bm.asImage();
111}
112
113sk_sp<SkImage> make_big_picture_image(int imgSize, int whiteBandWidth,
114 int desiredLineWidth, int desiredDepth) {
116
117 {
118 SkPictureRecorder recorder;
119 SkCanvas* canvas = recorder.beginRecording(SkRect::MakeIWH(imgSize, imgSize));
120 draw(canvas, imgSize, whiteBandWidth, desiredLineWidth, desiredDepth);
121 pic = recorder.finishRecordingAsPicture();
122 }
123
124 return SkImages::DeferredFromPicture(std::move(pic),
125 { imgSize, imgSize },
126 /* matrix= */ nullptr,
127 /* paint= */ nullptr,
130}
131
132
133const char* get_sampling_str(const SkSamplingOptions& sampling) {
134 if (sampling.isAniso()) {
135 return "Aniso";
136 } else if (sampling.useCubic) {
137 return "Cubic";
138 } else if (sampling.mipmap != SkMipmapMode::kNone) {
139 return "Mipmap";
140 } else if (sampling.filter == SkFilterMode::kLinear) {
141 return "Linear";
142 } else {
143 return "NN";
144 }
145}
146
147SkString create_label(GrDirectContext* dContext,
148 const char* generator,
150 int scale,
151 int rot,
153 int numTiles) {
154 SkString label;
155 label.appendf("%s-%s-%s-%d-%d-%s-%d",
156 dContext ? "ganesh" : "graphite",
157 generator,
158 get_sampling_str(sampling),
159 scale,
160 rot,
161 constraint == SkCanvas::kFast_SrcRectConstraint ? "fast" : "strict",
162 numTiles);
163 return label;
164 }
165
166void potentially_write_to_png(const char* directory,
167 const SkString& label,
168 const SkBitmap& bm) {
169 constexpr bool kWriteOutImages = false;
170
171 if constexpr(kWriteOutImages) {
172 SkString filename;
173 filename.appendf("//%s//%s.png", directory, label.c_str());
174
175 SkFILEWStream file(filename.c_str());
176 SkAssertResult(file.isValid());
177
179 }
180}
181
183 const SkBitmap& expected,
184 const SkBitmap& actual,
185 const SkString& label,
186 int rot) {
187 static const float kTols[4] = { 0.008f, 0.008f, 0.008f, 0.008f }; // ~ 2/255
188 static const float kRotTols[4] = { 0.024f, 0.024f, 0.024f, 0.024f }; // ~ 6/255
189
190 auto error = std::function<ComparePixmapsErrorReporter>(
191 [&](int x, int y, const float diffs[4]) {
192 SkASSERT(x >= 0 && y >= 0);
193 ERRORF(reporter, "%s: mismatch at %d, %d (%f, %f, %f %f)",
194 label.c_str(), x, y, diffs[0], diffs[1], diffs[2], diffs[3]);
195 });
196
197 return ComparePixels(expected.pixmap(), actual.pixmap(), rot ? kRotTols : kTols, error);
198}
199
200// Return a clip rect that will result in the number of desired tiles being used. The trick
201// is that the clip rect also has to work when rotated.
202SkRect clip_rect(SkRect dstRect, int numDesiredTiles) {
203 dstRect.outset(5, 5);
204
205 switch (numDesiredTiles) {
206 case 0:
207 return { dstRect.fLeft-64, dstRect.fTop-64, dstRect.fLeft-63, dstRect.fTop-63 };
208 case 4: {
209 // Upper left 4x4
210 float outset = 0.125f * dstRect.width() * SK_ScalarRoot2Over2;
211 SkPoint center = dstRect.center();
212 return { center.fX - outset, center.fY - outset,
213 center.fX + outset, center.fY + outset };
214 }
215 case 9: {
216 // Upper left 3x3
217 float outset = 0.25f * dstRect.width() * SK_ScalarRoot2Over2;
218 SkPoint center = dstRect.center();
219 center.offset(-dstRect.width()/8.0f, -dstRect.height()/8.0f);
220 return { center.fX - outset, center.fY - outset,
221 center.fX + outset, center.fY + outset };
222 }
223 }
224
225 return dstRect; // all 16 tiles
226}
227
228bool difficult_case(const SkSamplingOptions& sampling,
229 int scale,
230 int rot,
231 SkCanvas::SrcRectConstraint constraint) {
232 if (sampling.useCubic) {
233 return false; // cubic never causes any issues
234 }
235
236 if (constraint == SkCanvas::kStrict_SrcRectConstraint &&
238 // linear-filtered strict big image drawing is currently broken (b/286239467). The issue
239 // is that the strict constraint is propagated to the child tiles which breaks the
240 // interpolation expected in the middle of the large image.
241 // Note that strict mipmapping is auto-downgraded to strict linear sampling.
242 return true;
243 }
244
246 // Mipmapping is broken for anything other that 1-to-1 draws (b/286256104). The issue
247 // is that the mipmaps are created for each tile individually so the higher levels differ
248 // from what would be generated with the entire image. Mipmapped draws are off by ~20/255
249 // at 4x and ~64/255 at 8x)
250 return scale > 1;
251 }
252
254 // Perhaps unsurprisingly, NN only passes on un-rotated 1-to-1 draws (off by ~187/255 at
255 // different scales).
256 return scale > 1 || rot > 0;
257 }
258
259 return false;
260}
261
262// compare tiled and untiled draws - varying the parameters (e.g., sampling, rotation, fast vs.
263// strict, etc).
264void tiling_comparison_test(GrDirectContext* dContext,
267 // We're using the knowledge that the internal tile size is 1024. By creating kImageSize
268 // sized images we know we'll get a 4x4 tiling regardless of the sampling.
269 static const int kImageSize = 4096 - 4 * 2 * kBicubicFilterTexelPad;
270 static const int kOverrideMaxTextureSize = 1024;
271
272#if defined(SK_GANESH)
273 if (dContext && dContext->maxTextureSize() < kImageSize) {
274 // For the expected images we need to be able to draw w/o tiling
275 return;
276 }
277#endif
278
279#if defined(SK_GRAPHITE)
280 if (recorder) {
281 const skgpu::graphite::Caps* caps = recorder->priv().caps();
282 if (caps->maxTextureSize() < kImageSize) {
283 return;
284 }
285 }
286#endif
287
288 static const int kWhiteBandWidth = 4;
289 const SkRect srcRect = SkRect::MakeIWH(kImageSize, kImageSize).makeInset(kWhiteBandWidth,
290 kWhiteBandWidth);
291
292 using GeneratorT = sk_sp<SkImage>(*)(int imgSize, int whiteBandWidth,
293 int desiredLineWidth, int desiredDepth);
294
295 static const struct {
296 GeneratorT fGen;
297 const char* fTag;
298 } kGenerators[] = { { make_big_bitmap_image, "BM" },
299 { make_big_picture_image, "Picture" } };
300
301 static const SkSamplingOptions kSamplingOptions[] = {
304 // Note that Mipmapping gets auto-disabled with a strict-constraint
307 };
308
309 int numClippedTiles = 9;
310 for (auto gen : kGenerators) {
311 if (recorder && !strcmp(gen.fTag, "Picture")) {
312 // In the picture-image case, the non-tiled code path draws the picture directly into a
313 // gpu-backed surface while the tiled code path the picture is draws the picture into
314 // a raster-backed surface. For Ganesh this works out, since both Ganesh and Raster
315 // support non-AA rect draws. For Graphite the results are very different (since
316 // Graphite always anti-aliases. Forcing all the rect draws to be AA doesn't work out
317 // since AA introduces too much variance between both of the gpu backends and Raster -
318 // which would obscure any errors introduced by tiling.
319 continue;
320 }
321
322 sk_sp<SkImage> img = (*gen.fGen)(kImageSize,
323 kWhiteBandWidth,
324 /* desiredLineWidth= */ 16,
325 /* desiredDepth= */ 7);
326 numClippedTiles = (numClippedTiles == 9) ? 4 : 9; // alternate to reduce the combinatorics
327
328 for (int scale : { 1, 4, 8 }) {
329 for (int rot : { 0, 45 }) {
330 for (int numDesiredTiles : { numClippedTiles, 16 }) {
331 SkRect destRect = SkRect::MakeWH(srcRect.width()/scale,
332 srcRect.height()/scale);
333
334 SkMatrix m = SkMatrix::RotateDeg(rot, destRect.center());
335 SkIRect rotatedRect = m.mapRect(destRect).roundOut();
336 rotatedRect.outset(2, 2); // outset to capture the constraint's effect
337
338 SkRect clipRect = clip_rect(destRect, numDesiredTiles);
339
340 auto destII = SkImageInfo::Make(rotatedRect.width(),
341 rotatedRect.height(),
344
345 SkBitmap expected, actual;
346 expected.allocPixels(destII);
347 actual.allocPixels(destII);
348
350
351#if defined(SK_GANESH)
352 if (dContext) {
355 destII);
356 }
357#endif
358
359#if defined(SK_GRAPHITE)
360 if (recorder) {
361 surface = SkSurfaces::RenderTarget(recorder, destII);
362 }
363#endif
364
365 for (auto sampling : kSamplingOptions) {
366 for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
368 if (difficult_case(sampling, scale, rot, constraint)) {
369 continue;
370 }
371
372 SkString label = create_label(dContext, gen.fTag, sampling, scale, rot,
373 constraint, numDesiredTiles);
374
375 SkCanvas* canvas = surface->getCanvas();
376
377 SkAutoCanvasRestore acr(canvas, /* doSave= */ true);
378
379 canvas->translate(-rotatedRect.fLeft, -rotatedRect.fTop);
381 // NN sampling doesn't deal well w/ the (0.5, 0.5) offset but the
382 // other sampling modes need it to exercise strict vs. fast
383 // constraint in non-rotated draws
384 canvas->translate(0.5f, 0.5f);
385 }
386 canvas->concat(m);
387
388 // First, draw w/o tiling
389#if defined(SK_GANESH) && defined(GR_TEST_UTILS)
390 gOverrideMaxTextureSizeGanesh = 0;
391#endif
392#if defined(SK_GRAPHITE) && defined(GRAPHITE_TEST_UTILS)
393 gOverrideMaxTextureSizeGraphite = 0;
394#endif
395 canvas->clear(SK_ColorBLACK);
396 canvas->save();
397 canvas->clipRect(clipRect);
398
399 SkTiledImageUtils::DrawImageRect(canvas, img, srcRect, destRect,
400 sampling, /* paint= */ nullptr,
401 constraint);
402 SkAssertResult(surface->readPixels(expected, 0, 0));
403#if defined(SK_GANESH) && defined(GR_TEST_UTILS)
404 int actualNumTiles =
405 gNumTilesDrawnGanesh.load(std::memory_order_acquire);
406 REPORTER_ASSERT(reporter, actualNumTiles == 0);
407#endif
408#if defined(SK_GRAPHITE) && defined(GRAPHITE_TEST_UTILS)
409 int actualNumTiles2 =
410 gNumTilesDrawnGraphite.load(std::memory_order_acquire);
411 REPORTER_ASSERT(reporter, actualNumTiles2 == 0);
412#endif
413 canvas->restore();
414
415 // Then, force 4x4 tiling
416#if defined(SK_GANESH) && defined(GR_TEST_UTILS)
417 gOverrideMaxTextureSizeGanesh = kOverrideMaxTextureSize;
418#endif
419#if defined(SK_GRAPHITE) && defined(GRAPHITE_TEST_UTILS)
420 gOverrideMaxTextureSizeGraphite = kOverrideMaxTextureSize;
421#endif
422
423 canvas->clear(SK_ColorBLACK);
424 canvas->save();
425 canvas->clipRect(clipRect);
426
427 SkTiledImageUtils::DrawImageRect(canvas, img, srcRect, destRect,
428 sampling, /* paint= */ nullptr,
429 constraint);
430 SkAssertResult(surface->readPixels(actual, 0, 0));
431#if defined(SK_GANESH) && defined(GR_TEST_UTILS)
432 if (canvas->recordingContext()) {
433 actualNumTiles =
434 gNumTilesDrawnGanesh.load(std::memory_order_acquire);
436 numDesiredTiles == actualNumTiles,
437 "mismatch expected: %d actual: %d\n",
438 numDesiredTiles,
439 actualNumTiles);
440 }
441#endif
442#if defined(SK_GRAPHITE) && defined(GRAPHITE_TEST_UTILS)
443 if (canvas->recorder()) {
444 actualNumTiles2 =
445 gNumTilesDrawnGraphite.load(std::memory_order_acquire);
447 numDesiredTiles == actualNumTiles2,
448 "mismatch expected: %d actual: %d\n",
449 numDesiredTiles,
450 actualNumTiles2);
451 }
452#endif
453
454 canvas->restore();
455
457 label, rot));
458
459 potentially_write_to_png("expected", label, expected);
460 potentially_write_to_png("actual", label, actual);
461 }
462 }
463 }
464 }
465 }
466 }
467 // Reset tiling behavior
468#if defined(SK_GANESH) && defined(GR_TEST_UTILS)
469 gOverrideMaxTextureSizeGanesh = 0;
470#endif
471#if defined(SK_GRAPHITE) && defined(GRAPHITE_TEST_UTILS)
472 gOverrideMaxTextureSizeGraphite = 0;
473#endif
474}
475
476// In this test we draw the same bitmap-backed image twice and check that we only upload it once.
477// Everything is set up for the bitmap-backed image to be split into 16 1024x1024 tiles.
478void tiled_image_caching_test(GrDirectContext* dContext,
481 static const int kImageSize = 4096;
482 static const int kOverrideMaxTextureSize = 1024;
483 static const SkISize kExpectedTileSize { kOverrideMaxTextureSize, kOverrideMaxTextureSize };
484
485 sk_sp<SkImage> img = make_big_bitmap_image(kImageSize,
486 /* whiteBandWidth= */ 0,
487 /* desiredLineWidth= */ 16,
488 /* desiredDepth= */ 7);
489
493
495 readback.allocPixels(destII);
496
498
499#if defined(SK_GANESH)
500 if (dContext) {
502 }
503#endif
504
505#if defined(SK_GRAPHITE)
506 if (recorder) {
507 surface = SkSurfaces::RenderTarget(recorder, destII);
508 }
509#endif
510
511 if (!surface) {
512 return;
513 }
514
515 SkCanvas* canvas = surface->getCanvas();
516
517#if defined(SK_GANESH) && defined(GR_TEST_UTILS)
518 gOverrideMaxTextureSizeGanesh = kOverrideMaxTextureSize;
519#endif
520#if defined(SK_GRAPHITE) && defined(GRAPHITE_TEST_UTILS)
521 gOverrideMaxTextureSizeGraphite = kOverrideMaxTextureSize;
522#endif
523 for (int i = 0; i < 2; ++i) {
524 canvas->clear(SK_ColorBLACK);
525
527 /* x= */ 0, /* y= */ 0,
529 /* paint= */ nullptr,
531 SkAssertResult(surface->readPixels(readback, 0, 0));
532 }
533
534 int numFound = 0;
535
536#if defined(SK_GANESH)
537 if (dContext) {
539
540 cache->visitSurfaces([&](const GrSurface* surf, bool /* purgeable */) {
541 const GrTexture* tex = surf->asTexture();
542 if (tex && tex->dimensions() == kExpectedTileSize) {
543 ++numFound;
544 }
545 });
546 }
547#endif
548
549#if defined(SK_GRAPHITE)
550 if (recorder) {
551 skgpu::graphite::ResourceCache* cache = recorder->priv().resourceCache();
552
553 cache->visitTextures([&](const skgpu::graphite::Texture* tex, bool /* purgeable */) {
554 if (tex->dimensions() == kExpectedTileSize) {
555 ++numFound;
556 }
557 });
558 }
559#endif
560
561 REPORTER_ASSERT(reporter, numFound == 16, "Expected: 16 Actual: %d", numFound);
562
563 // reset to default behavior
564#if defined(SK_GANESH) && defined(GR_TEST_UTILS)
565 gOverrideMaxTextureSizeGanesh = 0;
566#endif
567#if defined(SK_GRAPHITE) && defined(GRAPHITE_TEST_UTILS)
568 gOverrideMaxTextureSizeGraphite = 0;
569#endif
570}
571
572} // anonymous namespace
573
574#if defined(SK_GANESH)
575
576// TODO(b/306005622): fix in SkQP and move to CtsEnforcement::kNextRelease
578 reporter,
579 ctxInfo,
581 auto dContext = ctxInfo.directContext();
582
583 tiling_comparison_test(dContext, /* recorder= */ nullptr, reporter);
584}
585
586// TODO(b/306005622): fix in SkQP and move to CtsEnforcement::kNextRelease
587DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(TiledDrawCacheTest_Ganesh,
588 reporter,
589 ctxInfo,
591 auto dContext = ctxInfo.directContext();
592
593 tiled_image_caching_test(dContext, /* recorder= */ nullptr, reporter);
594}
595
596#endif // SK_GANESH
597
598#if defined(SK_GRAPHITE)
599
600// TODO(b/306005622): fix in SkQP and move to CtsEnforcement::kNextRelease
601DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(BigImageTest_Graphite,
602 reporter,
603 context,
605 std::unique_ptr<skgpu::graphite::Recorder> recorder =
606 context->makeRecorder(ToolUtils::CreateTestingRecorderOptions());
607
608 tiling_comparison_test(/* dContext= */ nullptr, recorder.get(), reporter);
609}
610
611DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(TiledDrawCacheTest_Graphite,
612 reporter,
613 context,
615 std::unique_ptr<skgpu::graphite::Recorder> recorder =
616 context->makeRecorder(ToolUtils::CreateTestingRecorderOptions());
617
618 tiled_image_caching_test(/* dContext= */ nullptr, recorder.get(), reporter);
619}
620
621#endif // SK_GRAPHITE
static void readback(const SkBitmap &src, int *result, int resultCount)
Definition: BlurTest.cpp:264
static const int outset
Definition: BlurTest.cpp:58
reporter
Definition: FontMgrTest.cpp:39
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
bool check_pixels(skiatest::Reporter *reporter, GrDirectContext *dContext, const GrBackendTexture &tex, const SkImageInfo &info, SkColor expectedColor)
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
constexpr SkColor SK_ColorDKGRAY
Definition: SkColor.h:108
static constexpr int kBicubicFilterTexelPad
#define SK_ScalarRoot2Over2
Definition: SkScalar.h:23
bool ComparePixels(const GrCPixmap &a, const GrCPixmap &b, const float tolRGBA[4], std::function< ComparePixmapsErrorReporter > &error)
Definition: TestUtils.cpp:142
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
#define DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(name, reporter, graphite_context, ctsEnforcement)
Definition: Test.h:377
#define ERRORF(r,...)
Definition: Test.h:293
#define DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(name, reporter, context_info, ctsEnforcement)
Definition: Test.h:434
static SkScalar center(float pos0, float pos1)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Definition: aaclip.cpp:27
constexpr int kPad
GrResourceCache * getResourceCache()
SK_API int maxTextureSize() const
GrDirectContextPriv priv()
SkISize dimensions() const
Definition: GrSurface.h:27
virtual GrTexture * asTexture()
Definition: GrSurface.h:59
void allocPixels(const SkImageInfo &info, size_t rowBytes)
Definition: SkBitmap.cpp:258
sk_sp< SkImage > asImage() const
Definition: SkBitmap.cpp:645
void setImmutable()
Definition: SkBitmap.cpp:400
const SkPixmap & pixmap() const
Definition: SkBitmap.h:133
void allocN32Pixels(int width, int height, bool isOpaque=false)
Definition: SkBitmap.cpp:232
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
SrcRectConstraint
Definition: SkCanvas.h:1541
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
Definition: SkCanvas.h:1542
@ kFast_SrcRectConstraint
sample outside bounds; faster
Definition: SkCanvas.h:1543
void clear(SkColor color)
Definition: SkCanvas.h:1199
int save()
Definition: SkCanvas.cpp:447
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
static sk_sp< SkColorSpace > MakeSRGB()
static SkMatrix RotateDeg(SkScalar deg)
Definition: SkMatrix.h:104
void setColor(SkColor color)
Definition: SkPaint.cpp:119
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
const char * c_str() const
Definition: SkString.h:133
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
Definition: SkString.cpp:550
int maxTextureSize() const
Definition: Caps.h:141
const Caps * caps() const
Definition: RecorderPriv.h:31
SkISize dimensions() const
Definition: Texture.h:31
VkSurfaceKHR surface
Definition: main.cc:49
const uint8_t uint32_t uint32_t GError ** error
static const int kImageSize
Definition: flippity.cpp:44
double y
double x
SK_API sk_sp< SkImage > DeferredFromPicture(sk_sp< SkPicture > picture, const SkISize &dimensions, const SkMatrix *matrix, const SkPaint *paint, BitDepth bitDepth, sk_sp< SkColorSpace > colorSpace, SkSurfaceProps props)
@ kU8
uses 8-bit unsigned int per color component
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
clipRect(r.rect, r.opAA.op(), r.opAA.aa())) template<> void Draw
SkSamplingOptions sampling
Definition: SkRecords.h:337
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
void DrawImage(SkCanvas *canvas, const SkImage *image, SkScalar x, SkScalar y, const SkSamplingOptions &sampling={}, const SkPaint *paint=nullptr, SkCanvas::SrcRectConstraint constraint=SkCanvas::kFast_SrcRectConstraint)
SK_API void DrawImageRect(SkCanvas *canvas, const SkImage *image, const SkRect &src, const SkRect &dst, const SkSamplingOptions &sampling={}, const SkPaint *paint=nullptr, SkCanvas::SrcRectConstraint constraint=SkCanvas::kFast_SrcRectConstraint)
def gen()
Definition: dom.py:77
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia Filters out all Skia trace event categories except those that are specified in this comma separated list dump skp on shader Automatically dump the skp that triggers new shader compilations This is useful for writing custom ShaderWarmUp to reduce jank By this is not enabled to reduce the overhead purge persistent cache
Definition: switches.h:191
Definition: gen.py:1
Definition: GpuTools.h:21
SkSamplingOptions(SkFilterMode::kLinear))
const Scalar scale
static constexpr SkCubicResampler CatmullRom()
Definition: SkRect.h:32
constexpr int32_t height() const
Definition: SkRect.h:165
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34
constexpr int32_t width() const
Definition: SkRect.h:158
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33
void outset(int32_t dx, int32_t dy)
Definition: SkRect.h:428
Definition: SkSize.h:16
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkScalar fLeft
smaller x-axis bounds
Definition: extension.cpp:14
static SkRect MakeIWH(int w, int h)
Definition: SkRect.h:623
void outset(float dx, float dy)
Definition: SkRect.h:1077
SkRect makeInset(float dx, float dy) const
Definition: SkRect.h:987
constexpr float height() const
Definition: SkRect.h:769
constexpr float width() const
Definition: SkRect.h:762
constexpr SkPoint center() const
Definition: SkRect.h:792
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609
SkScalar fTop
smaller y-axis bounds
Definition: extension.cpp:15
const SkFilterMode filter
const SkMipmapMode mipmap