75#include <unordered_map>
83#if defined(GRAPHITE_TEST_UTILS)
84int gOverrideMaxTextureSizeGraphite = 0;
89std::atomic<int> gNumTilesDrawnGraphite{0};
94#define ASSERT_SINGLE_OWNER SkASSERT(fRecorder); SKGPU_ASSERT_SINGLE_OWNER(fRecorder->singleOwner())
103bool blender_depends_on_dst(
const SkBlender* blender,
bool srcIsTransparent) {
105 if (!bm.has_value()) {
114 return srcIsTransparent;
125 const bool srcIsTransparent = !
color.isOpaque() || (shader && !shader->
isOpaque()) ||
128 if (primitiveBlender && blender_depends_on_dst(primitiveBlender, srcIsTransparent)) {
132 return blender_depends_on_dst(finalBlender, srcIsTransparent);
135bool paint_depends_on_dst(
const PaintParams& paintParams) {
136 return paint_depends_on_dst(paintParams.color(),
137 paintParams.shader(),
138 paintParams.colorFilter(),
139 paintParams.finalBlender(),
140 paintParams.primitiveBlender());
146 return paint_depends_on_dst(
paint.getColor4f(),
148 paint.getColorFilter(),
154std::optional<SkColor4f> extract_paint_color(
const SkPaint&
paint,
157 if (
paint.getShader()) {
165 return filter->filterColor4f(dstPaintColor, dstCS, dstCS);
167 return dstPaintColor;
171 return r.makeRoundOut().asSkIRect();
205 auto& trees = fTrees[drawOrder];
207 for (
auto&& tree : trees) {
208 if (tree->add(
rect)) {
211 stencil = stencil.
next();
217 trees.push_back(newTree);
231 IntersectionTree* makeTree() {
232 return fTreeStore.make<IntersectionTree>();
240 std::unordered_map<CompressedPaintersOrder, std::vector<IntersectionTree*>,
Hash> fTrees;
251 std::string_view label,
252 bool registerWithRecorder) {
268 backingDimensions, textureInfo, std::move(label), budgeted),
273 registerWithRecorder);
282 bool registerWithRecorder) {
301 if (registerWithRecorder) {
326 :
SkDevice(dc->imageInfo(), dc->surfaceProps())
327 , fRecorder(recorder)
332 , fDisjointStencilSet(
std::make_unique<IntersectionTreeSet>())
333 , fCachedLocalToDevice(
SkM44())
335 , fSDFTControl(recorder->
priv().caps()->getSDFTControl(
336 fDC->surfaceProps().isUseDeviceIndependentFonts())) {
338 if (fRecorder->priv().caps()->defaultMSAASamplesCount() > 1) {
339 if (fRecorder->priv().caps()->msaaRenderToSingleSampledSupport()) {
340 fMSAASupported =
true;
343 fRecorder->priv().caps()->getDefaultMSAATextureInfo(fDC->target()->textureInfo(),
345 fMSAASupported = msaaTexInfo.
isValid();
356 SkASSERT(!fRecorder || fScopedRecordingID != 0);
358 if (fScopedRecordingID != 0 && fRecorder) {
359 SkASSERT(fScopedRecordingID == fRecorder->priv().nextRecordingID());
366void Device::setImmutable() {
373 this->flushPendingWorkToRecorder();
374 fRecorder->deregisterDevice(
this);
377 this->abandonRecorder();
382 if (this->checkLocalToDeviceDirty()) {
383 fCachedLocalToDevice =
Transform{this->localToDevice44()};
385 return fCachedLocalToDevice;
389 return {this->surfaceProps(), this->scalerContextFlags(), &fSDFTControl};
399 LoadOp initialLoadOp =
info.fInfo.isOpaque() ? LoadOp::kDiscard : LoadOp::kClear;
401 std::string label = this->
target()->label();
403 label =
"ChildDevice";
405 label +=
"_ChildDevice";
408 return Make(fRecorder,
427 this->flushPendingWorkToRecorder();
429 const SkColorInfo& colorInfo = this->imageInfo().colorInfo();
434 Swizzle readSwizzle = fRecorder->priv().caps()->getReadSwizzle(
435 colorInfo.
colorType(), this->target()->textureInfo());
438 std::string label = this->
target()->label();
440 label =
"CopyDeviceTexture";
442 label +=
"_DeviceCopy";
445 return Image::Copy(fRecorder, srcView, colorInfo, subset, budgeted, mipmapped, backingFit,
449bool Device::onReadPixels(
const SkPixmap& pm,
int srcX,
int srcY) {
450#if defined(GRAPHITE_TEST_UTILS)
454 if (
Context* context = fRecorder->
priv().context()) {
458 std::unique_ptr<Recording> recording = fRecorder->snap();
462 InsertRecordingInfo
info;
463 info.fRecording = recording.get();
464 if (!context->insertRecording(
info)) {
467 return context->priv().readPixels(pm, fDC->target(), this->imageInfo(), srcX, srcY);
474bool Device::onWritePixels(
const SkPixmap&
src,
int x,
int y) {
479 const TextureProxy*
target = fDC->target();
495 if (!fRecorder->priv().caps()->supportsWritePixels(
target->textureInfo())) {
523 std::vector<MipLevel> levels;
524 levels.push_back({
addr,
src.rowBytes()});
528 this->internalFlush();
532 return fDC->recordUpload(fRecorder, fDC->refTarget(),
src.info().colorInfo(),
533 this->imageInfo().colorInfo(), levels, dstRect,
nullptr);
539bool Device::isClipAntiAliased()
const {
546 SkASSERT(
rect.fShape.isRect() &&
rect.fLocalToDevice.type() == Transform::Type::kIdentity);
547 return rect.fShape.rect() !=
rect.fShape.rect().makeRoundOut();
554 return rect_to_pixelbounds(fClip.conservativeBounds());
565 if (
e.fShape.isRect() &&
e.fLocalToDevice.type() == Transform::Type::kIdentity) {
566 tmp.
setRect(rect_to_pixelbounds(
e.fShape.rect()));
568 SkPath tmpPath =
e.fShape.asPath();
570 tmp.
setPath(tmpPath, deviceBounds);
580 fClip.clipShape(this->localToDeviceTransform(),
Shape{
rect}, op);
587 fClip.clipShape(this->localToDeviceTransform(),
Shape{
rrect}, op);
595 fClip.clipShape(this->localToDeviceTransform(),
Shape{
path}, op);
599 fClip.clipShader(std::move(shader));
606 Transform globalToDevice{this->globalToDevice()};
609 fClip.clipShape(globalToDevice,
Shape{}, op);
610 }
else if (globalRgn.
isRect()) {
618 fClip.clipShape(globalToDevice,
Shape{
path}, op);
644 if (this->isClipWideOpen() && !fDC->target()->isFullyLazy()) {
645 if (!paint_depends_on_dst(
paint)) {
646 if (std::optional<SkColor4f>
color = extract_paint_color(
paint, fDC->colorInfo())) {
658 const Transform& localToDevice = this->localToDeviceTransform();
659 if (!localToDevice.
valid()) {
667 this->drawGeometry(localToDevice,
671 DrawFlags::kIgnorePathEffect);
675 this->drawGeometry(this->localToDeviceTransform(),
Geometry(
Shape(r)),
682 this->drawGeometry(this->localToDeviceTransform(),
686 DrawFlags::kIgnorePathEffect,
708 size_t cacheSize = recorder->priv().getResourceCacheLimit();
709 size_t maxTextureSize = recorder->priv().caps()->maxTextureSize();
711#if defined(GRAPHITE_TEST_UTILS)
712 if (gOverrideMaxTextureSizeGraphite) {
713 maxTextureSize = gOverrideMaxTextureSizeGraphite;
715 gNumTilesDrawnGraphite.store(0, std::memory_order_relaxed);
718 [[maybe_unused]]
auto [wasTiled, numTiles] =
729#if defined(GRAPHITE_TEST_UTILS)
730 gNumTilesDrawnGraphite.store(numTiles, std::memory_order_relaxed);
736 if (
paint.getPathEffect()) {
750 this->drawGeometry(this->localToDeviceTransform(),
Geometry(
Shape(rr)),
757 if (!
paint.getPathEffect() && !
path.isInverseFillType()) {
759 this->drawGeometry(this->localToDeviceTransform(),
766 this->drawGeometry(this->localToDeviceTransform(),
773 this->drawGeometry(this->localToDeviceTransform(),
794 paint.getStrokeJoin(),
795 paint.getStrokeMiter());
803 for (
size_t i = 0;
i <
count;
i += inc) {
804 this->drawGeometry(this->localToDeviceTransform(),
821 this->drawGeometry(this->localToDeviceTransform(),
825 DrawFlags::kIgnorePathEffect);
835 int dstClipIndex = 0;
842 auto [ imageToDraw, newSampling ] =
845 SKGPU_LOG_W(
"Device::drawImageRect: Creation of Graphite-backed image failed");
854 imageToDraw.get(), newSampling,
set[
i].fSrcRect,
set[
i].fDstRect,
870 if (
set[
i].fMatrixIndex < 0) {
871 this->drawGeometry(this->localToDeviceTransform(),
875 DrawFlags::kIgnorePathEffect);
878 this->drawGeometry(this->localToDeviceTransform().concat(xtraTransform),
882 DrawFlags::kIgnorePathEffect);
885 dstClipIndex += 4 *
set[
i].fHasClip;
897 this->drawEdgeAAImageSet(&single, 1,
nullptr,
nullptr,
sampling,
paint, constraint);
906 this->drawAtlasSubRun(subRun, drawOrigin,
paint, subRunStorage, rendererData);
910void Device::onDrawGlyphRunList(
SkCanvas* canvas,
914 fRecorder->priv().textBlobCache()->drawGlyphRunList(canvas,
915 this->localToDevice(),
918 this->strikeDeviceInfo(),
919 this->atlasDelegate());
935 return glyphs->regenerateAtlasForGraphite(
begin, end, maskFormat, padding, fRecorder);
937 for (
int subRunCursor = 0; subRunCursor < subRunEnd;) {
945 if (glyphsRegenerated) {
947 this->localToDeviceTransform(), drawOrigin);
955 bool useGammaCorrectDistanceTable =
956 this->imageInfo().colorSpace() &&
957 this->imageInfo().colorSpace()->gammaIsLinear();
958 this->drawGeometry(localToDevice,
959 Geometry(SubRunData(subRun,
962 this->localToDeviceTransform().inverse(),
966 useGammaCorrectDistanceTable,
967 this->surfaceProps().pixelGeometry(),
972 DrawFlags::kIgnorePathEffect);
974 subRunCursor += glyphsRegenerated;
976 if (subRunCursor < subRunEnd) {
982 fRecorder->priv().flushTrackedDevices();
987void Device::drawGeometry(
const Transform& localToDevice,
988 const Geometry& geometry,
993 bool skipColorXform) {
996 if (!localToDevice.valid()) {
998 SKGPU_LOG_W(
"Skipping draw with non-invertible/non-finite transform.");
1004 if (!(
flags & DrawFlags::kIgnorePathEffect) &&
paint.getPathEffect()) {
1014 float maxScaleFactor = localToDevice.maxScaleFactor();
1015 if (localToDevice.type() == Transform::Type::kPerspective) {
1016 auto bounds = geometry.bounds();
1017 float tl =
std::get<1>(localToDevice.scaleFactors({bounds.left(), bounds.top()}));
1018 float tr =
std::get<1>(localToDevice.scaleFactors({bounds.right(), bounds.top()}));
1019 float br =
std::get<1>(localToDevice.scaleFactors({bounds.right(), bounds.bot()}));
1020 float bl =
std::get<1>(localToDevice.scaleFactors({bounds.left(), bounds.bot()}));
1025 if (
paint.getPathEffect()->filterPath(&
dst, geometry.shape().asPath(), &newStyle,
1026 nullptr, localToDevice)) {
1027 dst.setIsVolatile(
true);
1029 this->drawGeometry(localToDevice, Geometry(
Shape(
dst)),
paint, newStyle,
1030 flags | DrawFlags::kIgnorePathEffect, std::move(primitiveBlender),
1034 SKGPU_LOG_W(
"Path effect failed to apply, drawing original path.");
1035 this->drawGeometry(localToDevice, geometry,
paint, style,
1036 flags | DrawFlags::kIgnorePathEffect, std::move(primitiveBlender),
1045 if (geometry.isShape() && localToDevice.type() == Transform::Type::kPerspective &&
1046 !is_simple_shape(geometry.shape(), style.
getStyle())) {
1047 SkPath devicePath = geometry.shape().asPath();
1048 devicePath.
transform(localToDevice.matrix().asM33());
1050 this->drawGeometry(Transform::Identity(), Geometry(
Shape(devicePath)),
paint, style,
flags,
1051 std::move(primitiveBlender), skipColorXform);
1071 this->chooseRenderer(localToDevice, geometry, style,
false);
1073 SKGPU_LOG_W(
"Skipping draw with no supported renderer or PathAtlas.");
1079 const bool outsetBoundsForAA =
renderer ?
renderer->outsetBoundsForAA() :
true;
1080 ClipStack::ElementList clipElements;
1082 fClip.visitClipStackForDraw(localToDevice, geometry, style, outsetBoundsForAA,
1084 if (
clip.isClippedOut()) {
1092 const std::optional<SkBlendMode> blendMode = blender ? blender->
asBlendMode()
1095 : Coverage::kSingleChannel;
1101 const int numNewRenderSteps =
1104 ? fRecorder->priv().rendererProvider()->tessellatedStrokes()->numRenderSteps()
1110 const bool needsFlush = this->needsFlushBeforeDraw(numNewRenderSteps, dstReadReq);
1112 if (pathAtlas !=
nullptr) {
1115 fRecorder->priv().flushTrackedDevices();
1117 this->flushPendingWorkToRecorder();
1123 std::optional<PathAtlas::MaskAndOrigin> atlasMask;
1124 if (pathAtlas !=
nullptr) {
1125 std::tie(
renderer, atlasMask) = pathAtlas->addShape(
clip.transformedShapeBounds(),
1133 if (!atlasMask && !needsFlush) {
1136 fRecorder->priv().flushTrackedDevices();
1139 std::tie(
renderer, atlasMask) = pathAtlas->addShape(
clip.transformedShapeBounds(),
1159 DrawOrder order(fCurrentDepth.next());
1161 clip, clipElements, fColorDepthBoundsManager.get(), order.depth());
1163#if defined(SK_DEBUG)
1171 auto dss =
step->depthStencilSettings();
1172 SkASSERT((!
step->performsShading() || dss.fDepthTestEnabled) &&
1173 (!dss.fDepthTestEnabled ||
1174 dss.fDepthCompareOp == CompareOp::kGreater ||
1175 dss.fDepthCompareOp == CompareOp::kGEqual));
1180 order.dependsOnPaintersOrder(clipOrder);
1185 if (!
renderer->emitsPrimitiveColor()) {
1186 primitiveBlender =
nullptr;
1187 }
else if (!
SkToBool(primitiveBlender)) {
1194 PaintParams shading{
paint,
1195 std::move(primitiveBlender),
1199 const bool dependsOnDst = rendererCoverage !=
Coverage::kNone || paint_depends_on_dst(shading);
1202 fColorDepthBoundsManager->getMostRecentDraw(
clip.drawBounds());
1203 order.dependsOnPaintersOrder(prevDraw);
1209 if (
renderer->depthStencilFlags() & DepthStencilFlags::kStencil) {
1212 order.dependsOnStencil(setIndex);
1217 shading.notifyImagesInUse(fRecorder, fDC.get());
1222 if (pathAtlas !=
nullptr) {
1225 auto [mask, origin] = *atlasMask;
1226 fDC->recordDraw(
renderer, Transform::Translate(origin.fX, origin.fY), Geometry(mask),
1227 clip, order, &shading,
nullptr);
1236 ? fRecorder->priv().rendererProvider()->tessellatedStrokes()
1238 localToDevice, geometry,
clip, order, &shading, &
stroke);
1242 fDC->recordDraw(
renderer, localToDevice, geometry,
clip, order, &shading,
nullptr);
1254 fColorDepthBoundsManager->recordDraw(
clip.drawBounds(), order.paintOrder());
1255 fCurrentDepth = order.depth();
1263void Device::drawClipShape(
const Transform& localToDevice,
1269 Geometry geometry{shape};
1270 auto [
renderer, pathAtlas] = this->chooseRenderer(localToDevice,
1275 SKGPU_LOG_W(
"Skipping clip with no supported path renderer.");
1277 }
else if (
renderer->depthStencilFlags() & DepthStencilFlags::kStencil) {
1280 order.dependsOnStencil(setIndex);
1285 SkASSERT(fDC->pendingRenderSteps() +
renderer->numRenderSteps() < DrawList::kMaxRenderSteps);
1294 if (localToDevice.type() == Transform::Type::kPerspective) {
1295 SkPath devicePath = geometry.shape().asPath();
1296 devicePath.
transform(localToDevice.matrix().asM33());
1297 fDC->recordDraw(
renderer, Transform::Identity(), Geometry(
Shape(devicePath)),
clip, order,
1300 fDC->recordDraw(
renderer, localToDevice, geometry,
clip, order,
nullptr,
nullptr);
1304 if (order.depth() > fCurrentDepth) {
1305 fCurrentDepth = order.depth();
1311std::pair<const Renderer*, PathAtlas*> Device::chooseRenderer(
const Transform& localToDevice,
1312 const Geometry& geometry,
1314 bool requireMSAA)
const {
1315 const RendererProvider* renderers = fRecorder->priv().rendererProvider();
1319 if (geometry.isSubRun()) {
1322 if (!rendererData.
isSDF) {
1323 return {renderers->bitmapText(rendererData.
isLCD),
nullptr};
1327 bool useLCD = rendererData.
isLCD &&
1329 return {renderers->sdfText(useLCD),
nullptr};
1330 }
else if (geometry.isVertices()) {
1332 return {renderers->vertices(
info.mode(),
info.hasColors(),
info.hasTexCoords()),
nullptr};
1333 }
else if (geometry.isCoverageMaskShape()) {
1337 return {renderers->coverageMask(),
nullptr};
1338 }
else if (geometry.isEdgeAAQuad()) {
1341 return {renderers->perEdgeAAQuad(),
nullptr};
1342 }
else if (geometry.isAnalyticBlur()) {
1343 return {renderers->analyticBlur(),
nullptr};
1344 }
else if (!geometry.isShape()) {
1346 return {
nullptr,
nullptr};
1349 const Shape& shape = geometry.shape();
1351 if (!requireMSAA && is_simple_shape(shape,
type)) {
1352 return {renderers->analyticRRect(),
nullptr};
1364#if defined(GRAPHITE_TEST_UTILS)
1370 PathAtlas* pathAtlas =
nullptr;
1371 AtlasProvider* atlasProvider = fRecorder->priv().atlasProvider();
1376 std::optional<Rect> drawBounds;
1377 if (atlasProvider->isAvailable(AtlasProvider::PathAtlasFlags::kCompute) &&
1378 use_compute_atlas_when_available(strategy)) {
1379 PathAtlas*
atlas = fDC->getComputePathAtlas(fRecorder);
1387 drawBounds = localToDevice.mapRect(shape.bounds());
1388 if (
atlas->isSuitableForAtlasing(*drawBounds, fClip.conservativeBounds())) {
1397 (strategy == PathRendererStrategy::kRasterAA ||
1401 pathAtlas = atlasProvider->getRasterPathAtlas();
1404 if (!requireMSAA && pathAtlas) {
1407 return {
nullptr, pathAtlas};
1427 return {renderers->tessellatedStrokes(),
nullptr};
1432 if (shape.convex() && !shape.inverted()) {
1435 return {renderers->convexTessellatedWedges(),
nullptr};
1437 if (!drawBounds.has_value()) {
1438 drawBounds = localToDevice.mapRect(shape.bounds());
1440 drawBounds->intersect(fClip.conservativeBounds());
1441 const bool preferWedges =
1445 drawBounds->isEmptyNegativeOrNaN() ||
1449 (shape.isPath() && shape.path().countVerbs() < 50) ||
1450 drawBounds->area() <= (256 * 256);
1453 return {renderers->stencilTessellatedWedges(shape.fillType()),
nullptr};
1455 return {renderers->stencilTessellatedCurvesAndTris(shape.fillType()),
nullptr};
1465void Device::flushPendingWorkToRecorder() {
1471 SkASSERT(fScopedRecordingID == 0 || fScopedRecordingID == fRecorder->priv().nextRecordingID());
1492 this->internalFlush();
1493 sk_sp<Task> drawTask = fDC->snapDrawTask(fRecorder);
1494 if (this->isScratchDevice()) {
1497 fLastTask = drawTask;
1508 fLastTask =
nullptr;
1512 fRecorder->priv().add(std::move(drawTask));
1518 if (!
GenerateMipmaps(fRecorder, fDC->refTarget(), fDC->colorInfo())) {
1519 SKGPU_LOG_W(
"Device::flushPendingWorkToRecorder: Failed to generate mipmaps");
1524 fIsFlushing =
false;
1527void Device::internalFlush() {
1532 fRecorder->priv().atlasProvider()->recordUploads(fDC.get());
1536 fClip.recordDeferredClipDraws();
1539 fDC->flush(fRecorder);
1541 fColorDepthBoundsManager->reset();
1542 fDisjointStencilSet->reset();
1543 fCurrentDepth = DrawOrder::kClearDepth;
1546 fRecorder->priv().atlasProvider()->postFlush();
1549bool Device::needsFlushBeforeDraw(
int numNewRenderSteps,
DstReadRequirement dstReadReq)
const {
1551 numNewRenderSteps += fClip.maxDeferredClipDraws() * Renderer::kMaxRenderSteps;
1553 (DrawList::kMaxRenderSteps - fDC->pendingRenderSteps()) < numNewRenderSteps ||
1555 dstReadReq == DstReadRequirement::kTextureCopy;
1566 if (!img || !
as_IB(img)->isGraphiteBacked()) {
1567 SKGPU_LOG_W(
"Couldn't get Graphite-backed special image as image");
1579 if (
dst.isEmpty()) {
1587 DrawFlags::kIgnorePathEffect);
1596 {SkTo<uint16_t>(mask->
width()),
1597 SkTo<uint16_t>(mask->
height())}};
1600 if (!maskProxyView) {
1601 SKGPU_LOG_W(
"Couldn't get Graphite-backed special image as texture proxy view");
1624 fRecorder->priv().textureDataCache()->insert(tdb);
1629 maskProxyView.proxy(),
1633 this->localToDeviceTransform().inverse(),
1640 DrawFlags::kIgnorePathEffect);
1656 if (forceCopy || !this->readSurfaceView() || this->readSurfaceView().proxy()->isFullyLazy()) {
1657 deviceImage = this->makeImageCopy(
1665 this->flushPendingWorkToRecorder();
1667 deviceImage = Image::WrapDevice(
sk_ref_sp(
this));
1668 finalSubset = subset;
1678 fRecorder, finalSubset, std::move(deviceImage), this->surfaceProps());
1690bool Device::isScratchDevice()
const {
1700 return !fDC->target()->isInstantiated() && !fDC->target()->isLazy();
1708 this->strikeDeviceInfo(),
1714 slugImpl->
subRuns()->draw(canvas, slugImpl->origin(),
paint, slugImpl, this->atlasDelegate());
1720 this->drawGeometry(this->localToDeviceTransform(),
1728 this->recorder(), this->localToDeviceTransform(), deviceSigma,
rrect);
1729 if (!analyticBlur) {
1733 this->drawGeometry(this->localToDeviceTransform(),
Geometry(*analyticBlur),
paint, style);
static int step(int x, SkScalar min, SkScalar max)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
static const int points[]
#define SKGPU_LOG_E(fmt,...)
#define SKGPU_LOG_W(fmt,...)
static float next(float f)
@ kUnknown_SkAlphaType
uninitialized
@ kSrcOver
r = s + (1-sa)*d
SkBlenderBase * as_BB(SkBlender *blend)
@ kUnknown_SkColorType
uninitialized
constexpr SkColor SK_ColorWHITE
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static bool ok(int result)
SkRect SkModifyPaintAndDstForDrawImageRect(const SkImage *image, const SkSamplingOptions &, SkRect src, SkRect dst, bool strictSrcSubset, SkPaint *paint)
static SkImage_Base * as_IB(SkImage *image)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
sk_sp< T > sk_ref_sp(T *obj)
@ kUnknown_SkPixelGeometry
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
static constexpr bool SkToBool(const T &x)
#define TRACE_EVENT_SCOPE_NAME_THREAD
virtual std::optional< SkBlendMode > asBlendMode() const
static sk_sp< SkBlender > Mode(SkBlendMode mode)
virtual skgpu::graphite::Recorder * recorder() const
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
@ kFast_SrcRectConstraint
sample outside bounds; faster
@ kLines_PointMode
draw each pair of points as a line segment
@ kPoints_PointMode
draw each point separately
bool isAlphaUnchanged() const
SkColorSpace * colorSpace() const
SkColorType colorType() const
void(ReadPixelsContext, std::unique_ptr< const AsyncReadResult >) ReadPixelsCallback
static SkColor ComputeLuminanceColor(const SkPaint &)
@ kButt_Cap
no stroke extension
void setColor(SkColor color)
@ kStroke_Style
set to stroke geometry
@ kFill_Style
set to fill geometry
void setColor4f(const SkColor4f &color, SkColorSpace *colorSpace=nullptr)
void setShader(sk_sp< SkShader > shader)
void setBlendMode(SkBlendMode mode)
SkPath & setIsVolatile(bool isVolatile)
static SkPath Oval(const SkRect &, SkPathDirection=SkPathDirection::kCW)
void transform(const SkMatrix &matrix, SkPath *dst, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
static bool AllCornersCircular(const SkRRect &rr, SkScalar tolerance=SK_ScalarNearlyZero)
const SkRect & rect() const
static SkRRect MakeOval(const SkRect &oval)
bool getBoundaryPath(SkPath *path) const
const SkIRect & getBounds() const
bool op(const SkIRect &rect, Op op)
bool setRect(const SkIRect &rect)
bool setPath(const SkPath &path, const SkRegion &clip)
virtual bool isOpaque() const
virtual sk_sp< SkImage > asImage() const =0
const SkIRect & subset() const
static SkStrikeCache * GlobalStrikeCache()
SkScalar getWidth() const
SkPaint::Join getJoin() const
SkPaint::Cap getCap() const
void setResScale(SkScalar rs)
SkScalar getMiter() const
SkSurfaceProps cloneWithPixelGeometry(SkPixelGeometry newPixelGeometry) const
static std::tuple< bool, size_t > DrawAsTiledImageRect(SkCanvas *, const SkImage *, const SkRect &srcRect, const SkRect &dstRect, SkCanvas::QuadAAFlags, const SkSamplingOptions &, const SkPaint *, SkCanvas::SrcRectConstraint, size_t cacheSize, size_t maxTextureSize)
virtual TextureInfo getDefaultSampledTextureInfo(SkColorType, Mipmapped mipmapped, Protected, Renderable) const =0
DisjointStencilIndex add(CompressedPaintersOrder drawOrder, Rect rect)
IntersectionTreeSet()=default
static sk_sp< Device > Make(Recorder *recorder, sk_sp< TextureProxy >, SkISize deviceSize, const SkColorInfo &, const SkSurfaceProps &, LoadOp initialLoadOp, bool registerWithRecorder=true)
Recorder * recorder() const override
static sk_sp< DrawContext > Make(const Caps *caps, sk_sp< TextureProxy > target, SkISize deviceSize, const SkColorInfo &, const SkSurfaceProps &)
static constexpr DisjointStencilIndex kUnassigned
MonotonicValue next() const
static SkColor4f Color4fPrepForDst(SkColor4f srgb, const SkColorInfo &dstColorInfo)
Protected isProtected() const
const Caps * caps() const
ResourceProvider * resourceProvider()
void add(sk_sp< TextureProxy > proxy, const SamplerDesc &samplerDesc)
static sk_sp< TextureProxy > Make(const Caps *, ResourceProvider *, SkISize dimensions, const TextureInfo &, std::string_view label, skgpu::Budgeted)
virtual skgpu::MaskFormat maskFormat() const =0
virtual const VertexFiller & vertexFiller() const =0
virtual std::tuple< bool, int > regenerateAtlas(int begin, int end, RegenerateAtlasDelegate) const =0
virtual int glyphCount() const =0
const gpu::SubRunContainerOwner & subRuns() const
static sk_sp< SlugImpl > Make(const SkMatrix &viewMatrix, const sktext::GlyphRunList &glyphRunList, const SkPaint &paint, SkStrikeDeviceInfo strikeDeviceInfo, sktext::StrikeForGPUCacheInterface *strikeCache)
std::tuple< skgpu::graphite::Rect, skgpu::graphite::Transform > boundsAndDeviceMatrix(const skgpu::graphite::Transform &localToDevice, SkPoint drawOrigin) const
static const char * begin(const StringSlice &s)
@ kRaster
Suitable for thread which raster data.
FlutterSemanticsFlag flags
FlPixelBufferTexturePrivate * priv
SkImage::ReadPixelsContext ReadPixelsContext
SkImage::ReadPixelsCallback ReadPixelsCallback
#define ASSERT_SINGLE_OWNER
static float max(float r, float g, float b)
static void drawPath(SkPath &path, SkCanvas *canvas, SkColor color, const SkRect &clip, SkPaint::Cap cap, SkPaint::Join join, SkPaint::Style style, SkPathFillType fill, SkScalar strokeWidth)
constexpr SkColor4f kTransparent
SK_API sk_sp< SkImage > RasterFromPixmap(const SkPixmap &pixmap, RasterReleaseProc rasterReleaseProc, ReleaseContext releaseContext)
SK_API sk_sp< SkImage > TextureFromImage(GrDirectContext *, const SkImage *, skgpu::Mipmapped=skgpu::Mipmapped::kNo, skgpu::Budgeted=skgpu::Budgeted::kYes)
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
clipRRect(r.rrect, r.opAA.op(), r.opAA.aa())) DRAW(ClipRect
sk_sp< const SkImage > atlas
drawSlug(r.slug.get(), r.paint)) DRAW(DrawAtlas
Optional< SkRect > bounds
clipRect(r.rect, r.opAA.op(), r.opAA.aa())) template<> void Draw
PODArray< SkPoint > dstClips
sk_sp< const SkImage > image
ClipOpAndAA opAA SkRegion region
clipPath(r.path, r.opAA.op(), r.opAA.aa())) DRAW(ClipRRect
sk_sp< SkBlender > blender SkRect rect
PODArray< SkMatrix > preViewMatrices
SkSamplingOptions sampling
sk_sp< SkSpecialImage > MakeGraphite(skgpu::graphite::Recorder *recorder, const SkIRect &subset, sk_sp< SkImage > image, const SkSurfaceProps &props)
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)
static uint32_t Hash(uint32_t key)
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
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 mode
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 set
const myers::Point & get< 1 >(const myers::Segment &s)
std::tuple< GrSurfaceProxyView, GrColorType > AsView(GrRecordingContext *rContext, const SkImage *img, skgpu::Mipmapped mipmapped, GrImageTexGenPolicy policy)
bool GenerateMipmaps(Recorder *recorder, sk_sp< TextureProxy > texture, const SkColorInfo &colorInfo)
MonotonicValue< DisjointStencilIndexSequence > DisjointStencilIndex
DstReadRequirement GetDstReadRequirement(const Caps *caps, std::optional< SkBlendMode > blendMode, Coverage coverage)
static constexpr int kMaxBruteForceN
std::pair< sk_sp< SkImage >, SkSamplingOptions > GetGraphiteBacked(Recorder *recorder, const SkImage *imageIn, SkSamplingOptions sampling)
static constexpr int kMaxGridSize
MonotonicValue< CompressedPaintersOrderSequence > CompressedPaintersOrder
static constexpr int kGridCellSize
constexpr bool BlurIsEffectivelyIdentity(float sigma)
SkISize GetApproxSize(SkISize size)
@ kARGB
4-bytes per pixel, color format
sk_sp< Backend > MakeGraphiteBackend(skgpu::graphite::Recorder *recorder, const SkSurfaceProps &surfaceProps, SkColorType colorType)
std::function< void(const sktext::gpu::AtlasSubRun *subRun, SkPoint drawOrigin, const SkPaint &paint, sk_sp< SkRefCnt > subRunStorage, sktext::gpu::RendererData)> AtlasDrawDelegate
skgpu::graphite::Transform Transform
bool intersect(const SkIRect &r)
constexpr SkISize size() const
int32_t fTop
smaller y-axis bounds
static constexpr SkIRect MakeSize(const SkISize &size)
int32_t fLeft
smaller x-axis bounds
static constexpr SkIRect MakePtSize(SkIPoint pt, SkISize size)
const SkColorInfo & colorInfo() const
SkISize dimensions() const
SkColorType colorType() const
static SkRect Make(const SkISize &size)
static SkRect MakeIWH(int w, int h)
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
#define TRACE_EVENT0(category_group, name)
#define TRACE_EVENT_INSTANT0(category_group, name)
static constexpr SkIRect kDeviceRect