Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
VelloRenderer.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
9
10#include "include/core/SkPath.h"
13#include "src/core/SkGeometry.h"
14#include "src/core/SkPathPriv.h"
26
27#include <algorithm>
28
29namespace skgpu::graphite {
30namespace {
31
32BufferView new_scratch_slice(ScratchBuffer& scratch) {
33 size_t size = scratch.size(); // Use the whole buffer.
34 BindBufferInfo info = scratch.suballocate(size);
35 return {info, info ? size : 0};
36}
37
38BufferView new_indirect_slice(DrawBufferManager* mgr, size_t size) {
39 BindBufferInfo info = mgr->getIndirectStorage(size, ClearBuffer::kYes);
40 return {info, info ? size : 0};
41}
42
43::rust::Slice<uint8_t> to_slice(void* ptr, size_t size) {
44 return {static_cast<uint8_t*>(ptr), size};
45}
46
47vello_cpp::Affine to_vello_affine(const SkMatrix& m) {
48 // Vello currently doesn't support perspective scaling and the encoding only accepts a 2x3
49 // affine transform matrix.
50 return {{m.get(0), m.get(3), m.get(1), m.get(4), m.get(2), m.get(5)}};
51}
52
53vello_cpp::Point to_vello_point(const SkPoint& p) { return {p.x(), p.y()}; }
54
55vello_cpp::Color to_vello_color(const SkColor4f& color) {
56 SkColor c = color.toSkColor();
57 return {
58 static_cast<uint8_t>(SkColorGetR(c)),
59 static_cast<uint8_t>(SkColorGetG(c)),
60 static_cast<uint8_t>(SkColorGetB(c)),
61 static_cast<uint8_t>(SkColorGetA(c)),
62 };
63}
64
65WorkgroupSize to_wg_size(const vello_cpp::WorkgroupSize& src) {
66 return WorkgroupSize(src.x, src.y, src.z);
67}
68
69vello_cpp::Fill to_fill_type(SkPathFillType fillType) {
70 // Vello does not provide an encoding for inverse fill types. When Skia uses vello to render
71 // a coverage mask for an inverse fill, it encodes a regular fill and inverts the coverage value
72 // after sampling the mask.
73 switch (fillType) {
76 return vello_cpp::Fill::NonZero;
79 return vello_cpp::Fill::EvenOdd;
80 }
81 return vello_cpp::Fill::NonZero;
82}
83
84vello_cpp::CapStyle to_cap_style(SkPaint::Cap cap) {
85 switch (cap) {
87 return vello_cpp::CapStyle::Butt;
89 return vello_cpp::CapStyle::Round;
91 return vello_cpp::CapStyle::Square;
92 }
94}
95
96vello_cpp::JoinStyle to_join_style(SkPaint::Join join) {
97 switch (join) {
99 return vello_cpp::JoinStyle::Miter;
101 return vello_cpp::JoinStyle::Bevel;
103 return vello_cpp::JoinStyle::Round;
104 }
106}
107
108vello_cpp::Stroke to_stroke(const SkStrokeRec& style) {
109 return vello_cpp::Stroke{
110 /*width=*/style.getWidth(),
111 /*miter_limit=*/style.getMiter(),
112 /*cap*/ to_cap_style(style.getCap()),
113 /*join*/ to_join_style(style.getJoin()),
114 };
115}
116
117class PathIter : public vello_cpp::PathIterator {
118public:
119 PathIter(const SkPath& path, const Transform& t)
120 : fIterate(path), fIter(fIterate.begin()), fTransform(t) {}
121
122 bool next_element(vello_cpp::PathElement* outElem) override {
123 if (fConicQuadIdx < fConicConverter.countQuads()) {
124 SkASSERT(fConicQuads != nullptr);
125 outElem->verb = vello_cpp::PathVerb::QuadTo;
126 int pointIdx = fConicQuadIdx * 2;
127 outElem->points[0] = to_vello_point(fConicQuads[pointIdx]);
128 outElem->points[1] = to_vello_point(fConicQuads[pointIdx + 1]);
129 outElem->points[2] = to_vello_point(fConicQuads[pointIdx + 2]);
130 fConicQuadIdx++;
131 return true;
132 }
133
134 if (fIter == fIterate.end()) {
135 return false;
136 }
137
138 SkASSERT(outElem);
139 auto [verb, points, weights] = *fIter;
140 fIter++;
141
142 switch (verb) {
144 outElem->verb = vello_cpp::PathVerb::MoveTo;
145 outElem->points[0] = to_vello_point(points[0]);
146 break;
148 outElem->verb = vello_cpp::PathVerb::LineTo;
149 outElem->points[0] = to_vello_point(points[0]);
150 outElem->points[1] = to_vello_point(points[1]);
151 break;
153 // The vello encoding API doesn't handle conic sections. Approximate it with
154 // quadratic Béziers.
155 SkASSERT(fConicQuadIdx >= fConicConverter.countQuads()); // No other conic->quad
156 // conversions should be
157 // in progress
158 fConicQuads = fConicConverter.computeQuads(
159 points, *weights, 0.25 / fTransform.maxScaleFactor());
160 outElem->verb = vello_cpp::PathVerb::QuadTo;
161 outElem->points[0] = to_vello_point(fConicQuads[0]);
162 outElem->points[1] = to_vello_point(fConicQuads[1]);
163 outElem->points[2] = to_vello_point(fConicQuads[2]);
164
165 // The next call to `next_element` will yield the next quad in the list (at index 1)
166 // if `fConicConverter` contains more than 1 quad.
167 fConicQuadIdx = 1;
168 break;
170 outElem->verb = vello_cpp::PathVerb::QuadTo;
171 outElem->points[0] = to_vello_point(points[0]);
172 outElem->points[1] = to_vello_point(points[1]);
173 outElem->points[2] = to_vello_point(points[2]);
174 break;
176 outElem->verb = vello_cpp::PathVerb::CurveTo;
177 outElem->points[0] = to_vello_point(points[0]);
178 outElem->points[1] = to_vello_point(points[1]);
179 outElem->points[2] = to_vello_point(points[2]);
180 outElem->points[3] = to_vello_point(points[3]);
181 break;
183 outElem->verb = vello_cpp::PathVerb::Close;
184 break;
185 }
186
187 return true;
188 }
189
190private:
191 SkPathPriv::Iterate fIterate;
193
194 // Variables used to track conic to quadratic spline conversion. `fTransform` is used to
195 // determine the subpixel error tolerance in device coordinate space.
196 const Transform& fTransform;
197 SkAutoConicToQuads fConicConverter;
198 const SkPoint* fConicQuads = nullptr;
199 int fConicQuadIdx = 0;
200};
201
202} // namespace
203
204VelloScene::VelloScene() : fEncoding(vello_cpp::new_encoding()) {}
205
207 fEncoding->reset();
208}
209
211 const SkColor4f& fillColor,
212 const SkPathFillType fillType,
213 const Transform& t) {
214 PathIter iter(shape, t);
215 fEncoding->fill(to_fill_type(fillType),
216 to_vello_affine(t),
217 {vello_cpp::BrushKind::Solid, {to_vello_color(fillColor)}},
218 iter);
219}
220
222 const SkColor4f& fillColor,
223 const SkStrokeRec& style,
224 const Transform& t) {
225 // TODO: Obtain dashing pattern here and let Vello handle dashing on the CPU while
226 // encoding the path?
227 PathIter iter(shape, t);
228 vello_cpp::Brush brush{vello_cpp::BrushKind::Solid, {to_vello_color(fillColor)}};
229 fEncoding->stroke(to_stroke(style), to_vello_affine(t), brush, iter);
230}
231
232void VelloScene::pushClipLayer(const SkPath& shape, const Transform& t) {
233 PathIter iter(shape, t);
234 fEncoding->begin_clip(to_vello_affine(t), iter);
235 SkDEBUGCODE(fLayers++;)
236}
237
239 SkASSERT(fLayers > 0);
240 fEncoding->end_clip();
241 SkDEBUGCODE(fLayers--;)
242}
243
246 fFineArea = std::make_unique<VelloFineAreaAlpha8Step>();
247 fFineMsaa16 = std::make_unique<VelloFineMsaa16Alpha8Step>();
248 fFineMsaa8 = std::make_unique<VelloFineMsaa8Alpha8Step>();
249 } else {
250 fFineArea = std::make_unique<VelloFineAreaStep>();
251 fFineMsaa16 = std::make_unique<VelloFineMsaa16Step>();
252 fFineMsaa8 = std::make_unique<VelloFineMsaa8Step>();
253 }
254}
255
257
258std::unique_ptr<DispatchGroup> VelloRenderer::renderScene(const RenderParams& params,
259 const VelloScene& scene,
261 Recorder* recorder) const {
262 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
264
265 if (scene.fEncoding->is_empty()) {
266 return nullptr;
267 }
268
269 if (params.fWidth == 0 || params.fHeight == 0) {
270 return nullptr;
271 }
272
273 // TODO: validate that the pixel format matches the pipeline layout.
274 // Clamp the draw region to the target texture dimensions.
275 const SkISize dims = target->dimensions();
276 if (dims.isEmpty() || dims.fWidth < 0 || dims.fHeight < 0) {
277 SKGPU_LOG_W("VelloRenderer: cannot render to an empty target");
278 return nullptr;
279 }
280
281 SkASSERT(scene.fLayers == 0); // Begin/end clips must be matched.
282 auto config = scene.fEncoding->prepare_render(
283 std::min(params.fWidth, static_cast<uint32_t>(dims.fWidth)),
284 std::min(params.fHeight, static_cast<uint32_t>(dims.fHeight)),
285 to_vello_color(params.fBaseColor));
286 auto dispatchInfo = config->workgroup_counts();
287 auto bufferSizes = config->buffer_sizes();
288
289 DispatchGroup::Builder builder(recorder);
290
291 // In total there are 25 resources that are used across the full pipeline stages. The sizes of
292 // these resources depend on the encoded scene. We allocate all of them and assign them
293 // directly to the builder here instead of delegating the logic to the ComputeSteps.
294 DrawBufferManager* bufMgr = recorder->priv().drawBufferManager();
295
296 size_t uboSize = config->config_uniform_buffer_size();
297 auto [uboPtr, configBuf] = bufMgr->getUniformPointer(uboSize);
298 if (!uboPtr || !config->write_config_uniform_buffer(to_slice(uboPtr, uboSize))) {
299 return nullptr;
300 }
301
302 size_t sceneSize = config->scene_buffer_size();
303 auto [scenePtr, sceneBuf] = bufMgr->getStoragePointer(sceneSize);
304 if (!scenePtr || !config->write_scene_buffer(to_slice(scenePtr, sceneSize))) {
305 return nullptr;
306 }
307
308 // TODO(b/285189802): The default sizes for the bump buffers (~97MB) exceed Graphite's resource
309 // budget if multiple passes are necessary per frame (250MB, see ResouceCache.h). We apply a
310 // crude size reduction here which seems to be enough for a 4k x 4k atlas render for the GMs
311 // that we have tested. The numbers below are able to render GM_longpathdash with CPU-side
312 // stroke expansion.
313 //
314 // We need to come up with a better approach to accurately predict the sizes for these buffers
315 // based on the scene encoding and our resource budget. It should be possible to build a
316 // conservative estimate using the total number of path verbs, some heuristic based on the verb
317 // and the path's transform, and the total number of tiles.
318 //
319 // The following numbers amount to ~48MB
320 const size_t lines_size = bufferSizes.lines;
321 const size_t bin_data_size = bufferSizes.bin_data;
322 const size_t tiles_size = bufferSizes.tiles;
323 const size_t segments_size = bufferSizes.segments;
324 const size_t seg_counts_size = bufferSizes.seg_counts;
325 const size_t ptcl_size = bufferSizes.ptcl;
326
327 // See the comments in VelloComputeSteps.h for an explanation of the logic here.
328
329 builder.assignSharedBuffer({configBuf, uboSize}, kVelloSlot_ConfigUniform);
330 builder.assignSharedBuffer({sceneBuf, sceneSize}, kVelloSlot_Scene);
331
332 // Buffers get cleared ahead of the entire DispatchGroup. Allocate the bump buffer early to
333 // avoid a potentially recycled (and prematurely cleared) scratch buffer.
334 ScratchBuffer bump = bufMgr->getScratchStorage(bufferSizes.bump_alloc);
335 builder.assignSharedBuffer(new_scratch_slice(bump), kVelloSlot_BumpAlloc, ClearBuffer::kYes);
336
337 // path_reduce
338 ScratchBuffer tagmonoids = bufMgr->getScratchStorage(bufferSizes.path_monoids);
339 {
340 // This can be immediately returned after input processing.
341 ScratchBuffer pathtagReduceOutput = bufMgr->getScratchStorage(bufferSizes.path_reduced);
342 builder.assignSharedBuffer(new_scratch_slice(pathtagReduceOutput),
344 builder.assignSharedBuffer(new_scratch_slice(tagmonoids), kVelloSlot_TagMonoid);
345 builder.appendStep(&fPathtagReduce, to_wg_size(dispatchInfo.path_reduce));
346
347 // If the input is too large to be fully processed by a single workgroup then a second
348 // reduce step and two scan steps are necessary. Otherwise one reduce+scan pair is
349 // sufficient.
350 //
351 // In either case, the result is `tagmonoids`.
352 if (dispatchInfo.use_large_path_scan) {
353 ScratchBuffer reduced2 = bufMgr->getScratchStorage(bufferSizes.path_reduced2);
354 ScratchBuffer reducedScan = bufMgr->getScratchStorage(bufferSizes.path_reduced_scan);
355
356 builder.assignSharedBuffer(new_scratch_slice(reduced2),
358 builder.assignSharedBuffer(new_scratch_slice(reducedScan),
360
361 builder.appendStep(&fPathtagReduce2, to_wg_size(dispatchInfo.path_reduce2));
362 builder.appendStep(&fPathtagScan1, to_wg_size(dispatchInfo.path_scan1));
363 builder.appendStep(&fPathtagScanLarge, to_wg_size(dispatchInfo.path_scan));
364 } else {
365 builder.appendStep(&fPathtagScanSmall, to_wg_size(dispatchInfo.path_scan));
366 }
367 }
368
369 // bbox_clear
370 ScratchBuffer pathBboxes = bufMgr->getScratchStorage(bufferSizes.path_bboxes);
371 builder.assignSharedBuffer(new_scratch_slice(pathBboxes), kVelloSlot_PathBBoxes);
372 builder.appendStep(&fBboxClear, to_wg_size(dispatchInfo.bbox_clear));
373
374 // flatten
375 ScratchBuffer lines = bufMgr->getScratchStorage(lines_size);
376 builder.assignSharedBuffer(new_scratch_slice(lines), kVelloSlot_Lines);
377 builder.appendStep(&fFlatten, to_wg_size(dispatchInfo.flatten));
378
379 tagmonoids.returnToPool();
380
381 // draw_reduce
382 ScratchBuffer drawReduced = bufMgr->getScratchStorage(bufferSizes.draw_reduced);
383 builder.assignSharedBuffer(new_scratch_slice(drawReduced), kVelloSlot_DrawReduceOutput);
384 builder.appendStep(&fDrawReduce, to_wg_size(dispatchInfo.draw_reduce));
385
386 // draw_leaf
387 ScratchBuffer drawMonoids = bufMgr->getScratchStorage(bufferSizes.draw_monoids);
388 ScratchBuffer binData = bufMgr->getScratchStorage(bin_data_size);
389 // A clip input buffer must still get bound even if the encoding doesn't contain any clips
390 ScratchBuffer clipInput = bufMgr->getScratchStorage(bufferSizes.clip_inps);
391 builder.assignSharedBuffer(new_scratch_slice(drawMonoids), kVelloSlot_DrawMonoid);
392 builder.assignSharedBuffer(new_scratch_slice(binData), kVelloSlot_InfoBinData);
393 builder.assignSharedBuffer(new_scratch_slice(clipInput), kVelloSlot_ClipInput);
394 builder.appendStep(&fDrawLeaf, to_wg_size(dispatchInfo.draw_leaf));
395
396 drawReduced.returnToPool();
397
398 // clip_reduce, clip_leaf
399 // The clip bbox buffer is always an input to the binning stage, even when the encoding doesn't
400 // contain any clips
401 ScratchBuffer clipBboxes = bufMgr->getScratchStorage(bufferSizes.clip_bboxes);
402 builder.assignSharedBuffer(new_scratch_slice(clipBboxes), kVelloSlot_ClipBBoxes);
403 WorkgroupSize clipReduceWgCount = to_wg_size(dispatchInfo.clip_reduce);
404 WorkgroupSize clipLeafWgCount = to_wg_size(dispatchInfo.clip_leaf);
405 bool doClipReduce = clipReduceWgCount.scalarSize() > 0u;
406 bool doClipLeaf = clipLeafWgCount.scalarSize() > 0u;
407 if (doClipReduce || doClipLeaf) {
408 ScratchBuffer clipBic = bufMgr->getScratchStorage(bufferSizes.clip_bics);
409 ScratchBuffer clipEls = bufMgr->getScratchStorage(bufferSizes.clip_els);
410 builder.assignSharedBuffer(new_scratch_slice(clipBic), kVelloSlot_ClipBicyclic);
411 builder.assignSharedBuffer(new_scratch_slice(clipEls), kVelloSlot_ClipElement);
412 if (doClipReduce) {
413 builder.appendStep(&fClipReduce, clipReduceWgCount);
414 }
415 if (doClipLeaf) {
416 builder.appendStep(&fClipLeaf, clipLeafWgCount);
417 }
418 }
419
420 clipInput.returnToPool();
421
422 // binning
423 ScratchBuffer drawBboxes = bufMgr->getScratchStorage(bufferSizes.draw_bboxes);
424 ScratchBuffer binHeaders = bufMgr->getScratchStorage(bufferSizes.bin_headers);
425 builder.assignSharedBuffer(new_scratch_slice(drawBboxes), kVelloSlot_DrawBBoxes);
426 builder.assignSharedBuffer(new_scratch_slice(binHeaders), kVelloSlot_BinHeader);
427 builder.appendStep(&fBinning, to_wg_size(dispatchInfo.binning));
428
429 pathBboxes.returnToPool();
430 clipBboxes.returnToPool();
431
432 // tile_alloc
433 ScratchBuffer paths = bufMgr->getScratchStorage(bufferSizes.paths);
434 ScratchBuffer tiles = bufMgr->getScratchStorage(tiles_size);
435 builder.assignSharedBuffer(new_scratch_slice(paths), kVelloSlot_Path);
436 builder.assignSharedBuffer(new_scratch_slice(tiles), kVelloSlot_Tile);
437 builder.appendStep(&fTileAlloc, to_wg_size(dispatchInfo.tile_alloc));
438
439 drawBboxes.returnToPool();
440
441 // path_count_setup
442 auto indirectCountBuffer = new_indirect_slice(bufMgr, bufferSizes.indirect_count);
443 builder.assignSharedBuffer(indirectCountBuffer, kVelloSlot_IndirectCount);
444 builder.appendStep(&fPathCountSetup, to_wg_size(dispatchInfo.path_count_setup));
445
446 // Rasterization stage scratch buffers.
447 ScratchBuffer seg_counts = bufMgr->getScratchStorage(seg_counts_size);
448 ScratchBuffer segments = bufMgr->getScratchStorage(segments_size);
449 ScratchBuffer ptcl = bufMgr->getScratchStorage(ptcl_size);
450
451 // path_count
452 builder.assignSharedBuffer(new_scratch_slice(seg_counts), kVelloSlot_SegmentCounts);
453 builder.appendStepIndirect(&fPathCount, indirectCountBuffer);
454
455 // backdrop
456 builder.appendStep(&fBackdrop, to_wg_size(dispatchInfo.backdrop));
457
458 // coarse
459 builder.assignSharedBuffer(new_scratch_slice(ptcl), kVelloSlot_PTCL);
460 builder.appendStep(&fCoarse, to_wg_size(dispatchInfo.coarse));
461
462 // path_tiling_setup
463 builder.appendStep(&fPathTilingSetup, to_wg_size(dispatchInfo.path_tiling_setup));
464
465 // path_tiling
466 builder.assignSharedBuffer(new_scratch_slice(segments), kVelloSlot_Segments);
467 builder.appendStepIndirect(&fPathTiling, indirectCountBuffer);
468
469 // fine
470 builder.assignSharedTexture(std::move(target), kVelloSlot_OutputImage);
471 const ComputeStep* fineVariant = nullptr;
472 switch (params.fAaConfig) {
474 fineVariant = fFineArea.get();
475 break;
477 fineVariant = fFineMsaa16.get();
478 break;
480 fineVariant = fFineMsaa8.get();
481 break;
482 }
483 SkASSERT(fineVariant != nullptr);
484 builder.appendStep(fineVariant, to_wg_size(dispatchInfo.fine));
485
486 return builder.finalize();
487}
488
489} // namespace skgpu::graphite
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
static const int points[]
SkColor4f color
std::unique_ptr< SkLatticeIter > fIter
#define SKGPU_LOG_W(fmt,...)
Definition Log.h:40
#define SkUNREACHABLE
Definition SkAssert.h:135
#define SkASSERT(cond)
Definition SkAssert.h:116
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition SkColorType.h:21
#define SkColorGetR(color)
Definition SkColor.h:65
#define SkColorGetG(color)
Definition SkColor.h:69
uint32_t SkColor
Definition SkColor.h:37
#define SkColorGetA(color)
Definition SkColor.h:61
#define SkColorGetB(color)
Definition SkColor.h:73
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
SkPathFillType
Definition SkPathTypes.h:11
@ kClose
SkPath::RawIter returns 0 points.
@ kCubic
SkPath::RawIter returns 4 points.
@ kConic
SkPath::RawIter returns 3 points + 1 weight.
@ kQuad
SkPath::RawIter returns 3 points.
@ kMove
SkPath::RawIter returns 1 point.
@ kLine
SkPath::RawIter returns 2 points.
#define TRACE_FUNC
const SkPoint * computeQuads(const SkConic &conic, SkScalar tol)
Definition SkGeometry.h:524
int countQuads() const
Definition SkGeometry.h:539
@ kRound_Cap
adds circle
Definition SkPaint.h:335
@ kButt_Cap
no stroke extension
Definition SkPaint.h:334
@ kSquare_Cap
adds square
Definition SkPaint.h:336
@ kRound_Join
adds circle
Definition SkPaint.h:360
@ kMiter_Join
extends to miter limit
Definition SkPaint.h:359
@ kBevel_Join
connects outside edges
Definition SkPaint.h:361
SkPath::RangeIter RangeIter
Definition SkPathPriv.h:164
SkScalar getWidth() const
Definition SkStrokeRec.h:42
SkPaint::Join getJoin() const
Definition SkStrokeRec.h:45
SkPaint::Cap getCap() const
Definition SkStrokeRec.h:44
SkScalar getMiter() const
Definition SkStrokeRec.h:43
ScratchBuffer getScratchStorage(size_t requiredBytes)
std::pair< void *, BindBufferInfo > getUniformPointer(size_t requiredBytes)
std::pair< void *, BindBufferInfo > getStoragePointer(size_t requiredBytes)
DrawBufferManager * drawBufferManager()
std::unique_ptr< DispatchGroup > renderScene(const RenderParams &, const VelloScene &, sk_sp< TextureProxy > target, Recorder *) const
void pushClipLayer(const SkPath &shape, const Transform &transform)
void solidStroke(const SkPath &, const SkColor4f &, const SkStrokeRec &, const Transform &transform)
void solidFill(const SkPath &, const SkColor4f &, const SkPathFillType, const Transform &transform)
static const char * begin(const StringSlice &s)
Definition editor.cpp:252
const EmbeddedViewParams * params
uint32_t * target
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
Definition switches.h:57
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
constexpr int kVelloSlot_DrawBBoxes
constexpr int kVelloSlot_Lines
SkColorType ComputeShaderCoverageMaskTargetFormat(const Caps *caps)
constexpr int kVelloSlot_LargePathtagScanFirstPassOutput
constexpr int kVelloSlot_BinHeader
constexpr int kVelloSlot_SegmentCounts
constexpr int kVelloSlot_ClipBicyclic
constexpr int kVelloSlot_Scene
constexpr int kVelloSlot_ConfigUniform
constexpr int kVelloSlot_ClipInput
constexpr int kVelloSlot_IndirectCount
constexpr int kVelloSlot_DrawReduceOutput
constexpr int kVelloSlot_LargePathtagReduceSecondPassOutput
constexpr int kVelloSlot_TagMonoid
constexpr int kVelloSlot_Segments
constexpr int kVelloSlot_InfoBinData
constexpr int kVelloSlot_ClipElement
constexpr int kVelloSlot_PathBBoxes
constexpr int kVelloSlot_Path
constexpr int kVelloSlot_OutputImage
constexpr int kVelloSlot_Tile
constexpr int kVelloSlot_PathtagReduceOutput
constexpr int kVelloSlot_PTCL
constexpr int kVelloSlot_ClipBBoxes
constexpr int kVelloSlot_DrawMonoid
constexpr int kVelloSlot_BumpAlloc
skgpu::graphite::Transform Transform
constexpr struct @268 tiles[]
bool isEmpty() const
Definition SkSize.h:31
int32_t fHeight
Definition SkSize.h:18
int32_t fWidth
Definition SkSize.h:17
SkPath::RangeIter end()
Definition SkPathPriv.h:187
#define TRACE_EVENT0(category_group, name)