Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | Private Member Functions | Friends | List of all members
skgpu::graphite::Device Class Referencefinal

#include <Device.h>

Inheritance diagram for skgpu::graphite::Device:
SkDevice SkRefCnt SkRefCntBase

Classes

class  IntersectionTreeSet
 

Public Member Functions

 ~Device () override
 
DeviceasGraphiteDevice () override
 
Recorderrecorder () const override
 
void abandonRecorder ()
 
void flushPendingWorkToRecorder (Recorder *recorder=nullptr)
 
const TransformlocalToDeviceTransform ()
 
void setImmutable () override
 
SkStrikeDeviceInfo strikeDeviceInfo () const override
 
TextureProxytarget ()
 
TextureProxyView readSurfaceView () const
 
sk_sp< ImagemakeImageCopy (const SkIRect &subset, Budgeted, Mipmapped, SkBackingFit)
 
bool isScratchDevice () const
 
sk_sp< TasklastDrawTask () const
 
bool useDrawCoverageMaskForMaskFilters () const override
 
void pushClipStack () override
 
void popClipStack () override
 
bool isClipWideOpen () const override
 
bool isClipEmpty () const override
 
bool isClipRect () const override
 
bool isClipAntiAliased () const override
 
SkIRect devClipBounds () const override
 
void android_utils_clipAsRgn (SkRegion *) const override
 
void clipRect (const SkRect &rect, SkClipOp, bool aa) override
 
void clipRRect (const SkRRect &rrect, SkClipOp, bool aa) override
 
void clipPath (const SkPath &path, SkClipOp, bool aa) override
 
void clipRegion (const SkRegion &globalRgn, SkClipOp) override
 
void replaceClip (const SkIRect &rect) override
 
void drawPaint (const SkPaint &paint) override
 
void drawRect (const SkRect &r, const SkPaint &paint) override
 
void drawOval (const SkRect &oval, const SkPaint &paint) override
 
void drawRRect (const SkRRect &rr, const SkPaint &paint) override
 
void drawPoints (SkCanvas::PointMode mode, size_t count, const SkPoint[], const SkPaint &paint) override
 
void drawPath (const SkPath &path, const SkPaint &paint, bool pathIsMutable=false) override
 
void drawEdgeAAQuad (const SkRect &rect, const SkPoint clip[4], SkCanvas::QuadAAFlags aaFlags, const SkColor4f &color, SkBlendMode mode) override
 
void drawEdgeAAImageSet (const SkCanvas::ImageSetEntry[], int count, const SkPoint dstClips[], const SkMatrix preViewMatrices[], const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
 
void drawImageRect (const SkImage *, const SkRect *src, const SkRect &dst, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
 
void drawVertices (const SkVertices *, sk_sp< SkBlender >, const SkPaint &, bool) override
 
bool drawAsTiledImageRect (SkCanvas *, const SkImage *, const SkRect *src, const SkRect &dst, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
 
void drawImageLattice (const SkImage *, const SkCanvas::Lattice &, const SkRect &dst, SkFilterMode, const SkPaint &) override
 
void drawAtlas (const SkRSXform[], const SkRect[], const SkColor[], int count, sk_sp< SkBlender >, const SkPaint &) override
 
void drawDrawable (SkCanvas *, SkDrawable *, const SkMatrix *) override
 
void drawMesh (const SkMesh &, sk_sp< SkBlender >, const SkPaint &) override
 
void drawShadow (const SkPath &, const SkDrawShadowRec &) override
 
sk_sp< SkSurfacemakeSurface (const SkImageInfo &, const SkSurfaceProps &) override
 
sk_sp< SkDevicecreateDevice (const CreateInfo &, const SkPaint *) override
 
sk_sp< SkSpecialImagesnapSpecial (const SkIRect &subset, bool forceCopy=false) override
 
void drawSpecial (SkSpecialImage *, const SkMatrix &localToDevice, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
 
void drawCoverageMask (const SkSpecialImage *, const SkMatrix &localToDevice, const SkSamplingOptions &, const SkPaint &) override
 
bool drawBlurredRRect (const SkRRect &, const SkPaint &, float deviceSigma) override
 
- Public Member Functions inherited from SkDevice
 SkDevice (const SkImageInfo &, const SkSurfaceProps &)
 
const SkImageInfoimageInfo () const
 
int width () const
 
int height () const
 
bool isOpaque () const
 
SkIRect bounds () const
 
SkISize size () const
 
const SkSurfacePropssurfaceProps () const
 
SkScalerContextFlags scalerContextFlags () const
 
bool writePixels (const SkPixmap &src, int x, int y)
 
bool readPixels (const SkPixmap &dst, int x, int y)
 
bool accessPixels (SkPixmap *pmap)
 
bool peekPixels (SkPixmap *)
 
const SkM44localToDevice44 () const
 
const SkMatrixlocalToDevice () const
 
const SkM44deviceToGlobal () const
 
const SkM44globalToDevice () const
 
SkIPoint getOrigin () const
 
bool isPixelAlignedToGlobal () const
 
SkMatrix getRelativeTransform (const SkDevice &) const
 
void setLocalToDevice (const SkM44 &localToDevice)
 
void setGlobalCTM (const SkM44 &ctm)
 
void getGlobalBounds (SkIRect *bounds) const
 
SkIRect getGlobalBounds () const
 
void clipShader (sk_sp< SkShader > sh, SkClipOp op)
 
virtual bool android_utils_clipWithStencil ()
 
virtual bool isNoPixelsDevice () const
 
virtual void * getRasterHandle () const
 
virtual GrRecordingContextrecordingContext () const
 
virtual skgpu::ganesh::DeviceasGaneshDevice ()
 
void drawGlyphRunList (SkCanvas *, const sktext::GlyphRunList &glyphRunList, const SkPaint &paint)
 
virtual void drawRegion (const SkRegion &r, const SkPaint &paint)
 
virtual void drawArc (const SkRect &oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, const SkPaint &paint)
 
virtual void drawDRRect (const SkRRect &outer, const SkRRect &inner, const SkPaint &)
 
virtual bool shouldDrawAsTiledImageRect () const
 
virtual void drawPatch (const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], sk_sp< SkBlender >, const SkPaint &paint)
 
virtual void drawAnnotation (const SkRect &, const char[], SkData *)
 
virtual sk_sp< SkSpecialImagesnapSpecialScaled (const SkIRect &subset, const SkISize &dstDims)
 
sk_sp< SkSpecialImagesnapSpecial ()
 
virtual void drawDevice (SkDevice *, const SkSamplingOptions &, const SkPaint &)
 
void drawFilteredImage (const skif::Mapping &mapping, SkSpecialImage *src, SkColorType ct, const SkImageFilter *, const SkSamplingOptions &, const SkPaint &)
 
- Public Member Functions inherited from SkRefCntBase
 SkRefCntBase ()
 
virtual ~SkRefCntBase ()
 
bool unique () const
 
void ref () const
 
void unref () const
 

Static Public Member Functions

static sk_sp< DeviceMake (Recorder *recorder, sk_sp< TextureProxy >, SkISize deviceSize, const SkColorInfo &, const SkSurfaceProps &, LoadOp initialLoadOp, bool registerWithRecorder=true)
 
static sk_sp< DeviceMake (Recorder *, const SkImageInfo &, Budgeted, Mipmapped, SkBackingFit, const SkSurfaceProps &, LoadOp initialLoadOp, bool registerWithRecorder=true)
 

Private Member Functions

sk_sp< SkSpecialImagemakeSpecial (const SkBitmap &) override
 
sk_sp< SkSpecialImagemakeSpecial (const SkImage *) override
 
bool onReadPixels (const SkPixmap &, int x, int y) override
 
bool onWritePixels (const SkPixmap &, int x, int y) override
 
void onDrawGlyphRunList (SkCanvas *, const sktext::GlyphRunList &, const SkPaint &) override
 
void onClipShader (sk_sp< SkShader > shader) override
 
sk_sp< skif::BackendcreateImageFilteringBackend (const SkSurfaceProps &surfaceProps, SkColorType colorType) const override
 
sk_sp< sktext::gpu::SlugconvertGlyphRunListToSlug (const sktext::GlyphRunList &glyphRunList, const SkPaint &paint) override
 
void drawSlug (SkCanvas *, const sktext::gpu::Slug *slug, const SkPaint &paint) override
 

Friends

class ClipStack
 

Additional Inherited Members

- Protected Member Functions inherited from SkDevice
void setDeviceCoordinateSystem (const SkM44 &deviceToGlobal, const SkM44 &globalToDevice, const SkM44 &localToDevice, int bufferOriginX, int bufferOriginY)
 
void setOrigin (const SkM44 &globalCTM, int x, int y)
 
bool checkLocalToDeviceDirty ()
 

Detailed Description

Definition at line 45 of file Device.h.

Constructor & Destructor Documentation

◆ ~Device()

skgpu::graphite::Device::~Device ( )
override

Definition at line 343 of file Device.cpp.

343 {
344 // The Device should have been marked immutable before it's destroyed, or the Recorder was the
345 // last holder of a reference to it and de-registered the device as part of its cleanup.
346 // However, if the Device was not registered with the recorder (i.e. a scratch device) we don't
347 // require that its recorder be adandoned. Scratch devices must either have been marked
348 // immutable or be destroyed before the recorder has been snapped.
349 SkASSERT(!fRecorder || fScopedRecordingID != 0);
350#if defined(SK_DEBUG)
351 if (fScopedRecordingID != 0 && fRecorder) {
352 SkASSERT(fScopedRecordingID == fRecorder->priv().nextRecordingID());
353 }
354 // else it wasn't a scratch device, or it was a scratch device that was marked immutable so its
355 // lifetime was validated when setImmutable() was called.
356#endif
357}
#define SkASSERT(cond)
Definition SkAssert.h:116

Member Function Documentation

◆ abandonRecorder()

void skgpu::graphite::Device::abandonRecorder ( )
inline

Definition at line 74 of file Device.h.

74{ fRecorder = nullptr; }

◆ android_utils_clipAsRgn()

void skgpu::graphite::Device::android_utils_clipAsRgn ( SkRegion region) const
overridevirtual

Implements SkDevice.

Definition at line 539 of file Device.cpp.

539 {
540 SkIRect bounds = this->devClipBounds();
541 // Assume wide open and then perform intersect/difference operations reducing the region
542 region->setRect(bounds);
543 const SkRegion deviceBounds(bounds);
544 for (const ClipStack::Element& e : fClip) {
545 SkRegion tmp;
546 if (e.fShape.isRect() && e.fLocalToDevice.type() == Transform::Type::kIdentity) {
547 tmp.setRect(rect_to_pixelbounds(e.fShape.rect()));
548 } else {
549 SkPath tmpPath = e.fShape.asPath();
550 tmpPath.transform(e.fLocalToDevice);
551 tmp.setPath(tmpPath, deviceBounds);
552 }
553
554 region->op(tmp, (SkRegion::Op) e.fOp);
555 }
556}
SkIRect bounds() const
Definition SkDevice.h:125
void transform(const SkMatrix &matrix, SkPath *dst, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
Definition SkPath.cpp:1647
bool op(const SkIRect &rect, Op op)
Definition SkRegion.h:384
bool setRect(const SkIRect &rect)
Definition SkRegion.cpp:192
bool setPath(const SkPath &path, const SkRegion &clip)
SkIRect devClipBounds() const override
Definition Device.cpp:534
ClipOpAndAA opAA SkRegion region
Definition SkRecords.h:238

◆ asGraphiteDevice()

Device * skgpu::graphite::Device::asGraphiteDevice ( )
inlineoverridevirtual

Reimplemented from SkDevice.

Definition at line 69 of file Device.h.

69{ return this; }

◆ clipPath()

void skgpu::graphite::Device::clipPath ( const SkPath path,
SkClipOp  op,
bool  aa 
)
overridevirtual

Implements SkDevice.

Definition at line 571 of file Device.cpp.

571 {
573 // TODO: Ensure all path inspection is handled here or in SkCanvas, and that non-AA rects as
574 // paths are routed appropriately.
575 // TODO: Must also detect paths that are lines so the clip stack can be set to empty
576 fClip.clipShape(this->localToDeviceTransform(), Shape{path}, op);
577}
Shape
void clipShape(const Transform &localToDevice, const Shape &shape, SkClipOp op)
const Transform & localToDeviceTransform()
Definition Device.cpp:374
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

◆ clipRect()

void skgpu::graphite::Device::clipRect ( const SkRect rect,
SkClipOp  op,
bool  aa 
)
overridevirtual

Implements SkDevice.

Definition at line 558 of file Device.cpp.

558 {
560 // TODO: Snap rect edges to pixel bounds if non-AA and axis-aligned?
561 fClip.clipShape(this->localToDeviceTransform(), Shape{rect}, op);
562}
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350

◆ clipRegion()

void skgpu::graphite::Device::clipRegion ( const SkRegion globalRgn,
SkClipOp  op 
)
overridevirtual

Implements SkDevice.

Definition at line 584 of file Device.cpp.

584 {
586
588
589 if (globalRgn.isEmpty()) {
590 fClip.clipShape(globalToDevice, Shape{}, op);
591 } else if (globalRgn.isRect()) {
592 // TODO: Region clips are non-AA so this should match non-AA onClipRect(), but we use a
593 // different transform so can't just call that instead.
594 fClip.clipShape(globalToDevice, Shape{SkRect::Make(globalRgn.getBounds())}, op);
595 } else {
596 // TODO: Can we just iterate the region and do non-AA rects for each chunk?
597 SkPath path;
598 globalRgn.getBoundaryPath(&path);
599 fClip.clipShape(globalToDevice, Shape{path}, op);
600 }
601}
const SkM44 & globalToDevice() const
Definition SkDevice.h:191
bool getBoundaryPath(SkPath *path) const
bool isRect() const
Definition SkRegion.h:152
const SkIRect & getBounds() const
Definition SkRegion.h:165
bool isEmpty() const
Definition SkRegion.h:146
skgpu::graphite::Transform Transform
static SkRect Make(const SkISize &size)
Definition SkRect.h:669

◆ clipRRect()

void skgpu::graphite::Device::clipRRect ( const SkRRect rrect,
SkClipOp  op,
bool  aa 
)
overridevirtual

Implements SkDevice.

Definition at line 564 of file Device.cpp.

564 {
566 // TODO: Snap rrect edges to pixel bounds if non-AA and axis-aligned? Is that worth doing to
567 // seam with non-AA rects even if the curves themselves are AA'ed?
568 fClip.clipShape(this->localToDeviceTransform(), Shape{rrect}, op);
569}
SkRRect rrect
Definition SkRecords.h:232

◆ convertGlyphRunListToSlug()

sk_sp< sktext::gpu::Slug > skgpu::graphite::Device::convertGlyphRunListToSlug ( const sktext::GlyphRunList glyphRunList,
const SkPaint paint 
)
overrideprivatevirtual

Reimplemented from SkDevice.

Definition at line 1658 of file Device.cpp.

1659 {
1661 glyphRunList,
1662 paint,
1663 this->strikeDeviceInfo(),
1665}
const SkMatrix & localToDevice() const
Definition SkDevice.h:179
static SkStrikeCache * GlobalStrikeCache()
SkStrikeDeviceInfo strikeDeviceInfo() const override
Definition Device.cpp:381
static sk_sp< SlugImpl > Make(const SkMatrix &viewMatrix, const sktext::GlyphRunList &glyphRunList, const SkPaint &paint, SkStrikeDeviceInfo strikeDeviceInfo, sktext::StrikeForGPUCacheInterface *strikeCache)
Definition SlugImpl.cpp:74
const Paint & paint

◆ createDevice()

sk_sp< SkDevice > skgpu::graphite::Device::createDevice ( const CreateInfo ,
const SkPaint  
)
overridevirtual

Create a new device based on CreateInfo. If the paint is not null, then it represents a preview of how the new device will be composed with its creator device (this).

The subclass may be handed this device in drawDevice(), so it must always return a device that it knows how to draw, and that it knows how to identify if it is not of the same subclass (since drawDevice is passed a SkDevice*). If the subclass cannot fulfill that contract (e.g. PDF cannot support some settings on the paint) it should return NULL, and the caller may then decide to explicitly create a bitmapdevice, knowing that later it could not call drawDevice with it (but it could call drawSprite or drawBitmap).

Reimplemented from SkDevice.

Definition at line 385 of file Device.cpp.

385 {
386 // TODO: Inspect the paint and create info to determine if there's anything that has to be
387 // modified to support inline subpasses.
388 SkSurfaceProps props =
389 this->surfaceProps().cloneWithPixelGeometry(info.fPixelGeometry);
390
391 // Skia's convention is to only clear a device if it is non-opaque.
392 LoadOp initialLoadOp = info.fInfo.isOpaque() ? LoadOp::kDiscard : LoadOp::kClear;
393
394 return Make(fRecorder,
395 info.fInfo,
397 Mipmapped::kNo,
398#if defined(GRAPHITE_USE_APPROX_FIT_FOR_FILTERS)
400#else
402#endif
403 props,
404 initialLoadOp);
405}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
const SkSurfaceProps & surfaceProps() const
Definition SkDevice.h:131
SkSurfaceProps cloneWithPixelGeometry(SkPixelGeometry newPixelGeometry) const
static sk_sp< Device > Make(Recorder *recorder, sk_sp< TextureProxy >, SkISize deviceSize, const SkColorInfo &, const SkSurfaceProps &, LoadOp initialLoadOp, bool registerWithRecorder=true)
Definition Device.cpp:268

◆ createImageFilteringBackend()

sk_sp< skif::Backend > skgpu::graphite::Device::createImageFilteringBackend ( const SkSurfaceProps surfaceProps,
SkColorType  colorType 
) const
overrideprivatevirtual

Reimplemented from SkDevice.

Definition at line 1636 of file Device.cpp.

1637 {
1638 return skif::MakeGraphiteBackend(fRecorder, surfaceProps, colorType);
1639}
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)

◆ devClipBounds()

SkIRect skgpu::graphite::Device::devClipBounds ( ) const
overridevirtual

Returns the bounding box of the current clip, in this device's coordinate space. No pixels outside of these bounds will be touched by draws unless the clip is further modified (at which point this will return the updated bounds).

Implements SkDevice.

Definition at line 534 of file Device.cpp.

534 {
535 return rect_to_pixelbounds(fClip.conservativeBounds());
536}

◆ drawAsTiledImageRect()

bool skgpu::graphite::Device::drawAsTiledImageRect ( SkCanvas canvas,
const SkImage image,
const SkRect src,
const SkRect dst,
const SkSamplingOptions sampling,
const SkPaint paint,
SkCanvas::SrcRectConstraint  constraint 
)
overridevirtual

Reimplemented from SkDevice.

Definition at line 672 of file Device.cpp.

678 {
679 auto recorder = canvas->recorder();
680 if (!recorder) {
681 return false;
682 }
683 SkASSERT(src);
684
685 // For Graphite this is a pretty loose heuristic. The Recorder-local cache size (relative
686 // to the large image's size) is used as a proxy for how conservative we should be when
687 // allocating tiles. Since the tiles will actually be owned by the client (via an
688 // ImageProvider) they won't actually add any memory pressure directly to Graphite.
689 size_t cacheSize = recorder->priv().getResourceCacheLimit();
690 size_t maxTextureSize = recorder->priv().caps()->maxTextureSize();
691
692#if defined(GRAPHITE_TEST_UTILS)
693 if (gOverrideMaxTextureSizeGraphite) {
694 maxTextureSize = gOverrideMaxTextureSizeGraphite;
695 }
696 gNumTilesDrawnGraphite.store(0, std::memory_order_relaxed);
697#endif
698
699 [[maybe_unused]] auto [wasTiled, numTiles] =
701 image,
702 *src,
703 dst,
705 sampling,
706 &paint,
707 constraint,
708 cacheSize,
709 maxTextureSize);
710#if defined(GRAPHITE_TEST_UTILS)
711 gNumTilesDrawnGraphite.store(numTiles, std::memory_order_relaxed);
712#endif
713 return wasTiled;
714}
virtual skgpu::graphite::Recorder * recorder() const
@ kAll_QuadAAFlags
Definition SkCanvas.h:1665
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)
int maxTextureSize() const
Definition Caps.h:134
Recorder * recorder() const override
Definition Device.h:71
size_t getResourceCacheLimit() const
Definition Recorder.cpp:547
const Caps * caps() const
sk_sp< SkImage > image
Definition examples.cpp:29

◆ drawAtlas()

void skgpu::graphite::Device::drawAtlas ( const SkRSXform  [],
const SkRect  [],
const SkColor  [],
int  count,
sk_sp< SkBlender ,
const SkPaint  
)
inlineoverridevirtual

Reimplemented from SkDevice.

Definition at line 183 of file Device.h.

184 {}

◆ drawBlurredRRect()

bool skgpu::graphite::Device::drawBlurredRRect ( const SkRRect ,
const SkPaint ,
float  deviceSigma 
)
overridevirtual

Draw rrect with an optimized path for analytic blurs, if provided by the device.

Reimplemented from SkDevice.

Definition at line 1672 of file Device.cpp.

1672 {
1673 SkStrokeRec style(paint);
1674 if (skgpu::BlurIsEffectivelyIdentity(deviceSigma)) {
1675 this->drawGeometry(this->localToDeviceTransform(),
1676 Geometry(rrect.isRect() ? Shape(rrect.rect()) : Shape(rrect)),
1677 paint,
1678 style);
1679 return true;
1680 }
1681
1682 std::optional<AnalyticBlurMask> analyticBlur = AnalyticBlurMask::Make(
1683 this->recorder(), this->localToDeviceTransform(), deviceSigma, rrect);
1684 if (!analyticBlur) {
1685 return false;
1686 }
1687
1688 this->drawGeometry(this->localToDeviceTransform(), Geometry(*analyticBlur), paint, style);
1689 return true;
1690}
const SkRect & rect() const
Definition SkRRect.h:264
bool isRect() const
Definition SkRRect.h:84
static std::optional< AnalyticBlurMask > Make(Recorder *, const Transform &localToDevice, float deviceSigma, const SkRRect &srcRRect)
constexpr bool BlurIsEffectivelyIdentity(float sigma)
Definition BlurUtils.h:37

◆ drawCoverageMask()

void skgpu::graphite::Device::drawCoverageMask ( const SkSpecialImage ,
const SkMatrix maskToDevice,
const SkSamplingOptions ,
const SkPaint  
)
overridevirtual

Draw the special image's subset to this device, treating its alpha channel as coverage for the draw and ignoring any RGB channels that might be present. This will be drawn using the provided matrix transform instead of the device's current local to device matrix.

Coverage values beyond the image's subset are treated as 0 (i.e. kDecal tiling). Color values before coverage are determined as normal by the SkPaint, ignoring style, path effects, mask filters and image filters. The local coords of any SkShader on the paint should be relative to the SkDevice's current matrix (i.e. 'maskToDevice' determines how the coverage mask aligns with device-space, but otherwise shading proceeds like other draws).

Reimplemented from SkDevice.

Definition at line 1552 of file Device.cpp.

1555 {
1556 CoverageMaskShape::MaskInfo maskInfo{/*fTextureOrigin=*/{SkTo<uint16_t>(mask->subset().fLeft),
1557 SkTo<uint16_t>(mask->subset().fTop)},
1558 /*fMaskSize=*/{SkTo<uint16_t>(mask->width()),
1559 SkTo<uint16_t>(mask->height())}};
1560
1561 auto maskProxyView = AsView(mask->asImage());
1562 if (!maskProxyView) {
1563 SKGPU_LOG_W("Couldn't get Graphite-backed special image as texture proxy view");
1564 return;
1565 }
1566
1567 // 'mask' logically has 0 coverage outside of its pixels, which is equivalent to kDecal tiling.
1568 // However, since we draw geometry tightly fitting 'mask', we can use the better-supported
1569 // kClamp tiling and behave effectively the same way.
1571
1572 // Ensure this is kept alive; normally textures are kept alive by the PipelineDataGatherer for
1573 // image shaders, or by the PathAtlas. This is a unique circumstance.
1574 // TODO: Find a cleaner way to ensure 'maskProxyView' is transferred to the final Recording.
1575 TextureDataBlock tdb;
1576 // NOTE: CoverageMaskRenderStep controls the final sampling options; this texture data block
1577 // serves only to keep the mask alive so the sampling passed to add() doesn't matter.
1578 tdb.add(SkFilterMode::kLinear, kClamp, maskProxyView.refProxy());
1579 fRecorder->priv().textureDataCache()->insert(tdb);
1580
1581 // CoverageMaskShape() wraps a Shape when it's used as a PathAtlas, but in this case the
1582 // original shape has been long lost, so just use a Rect that bounds the image.
1583 CoverageMaskShape maskShape{Shape{Rect::WH((float)mask->width(), (float)mask->height())},
1584 maskProxyView.proxy(),
1585 // Use the active local-to-device transform for this since it
1586 // determines the local coords for evaluating the skpaint, whereas
1587 // the provided 'localToDevice' just places the coverage mask.
1589 maskInfo};
1590
1591 this->drawGeometry(Transform(SkM44(localToDevice)),
1592 Geometry(maskShape),
1593 paint,
1594 DefaultFillStyle(),
1595 DrawFlags::kIgnorePathEffect);
1596}
#define SKGPU_LOG_W(fmt,...)
Definition Log.h:40
SkTileMode
Definition SkTileMode.h:13
Definition SkM44.h:150
static AI Rect WH(float w, float h)
Definition Rect.h:46
const SkM44 & inverse() const
TextureProxyView AsView(const SkImage *image)

◆ drawDrawable()

void skgpu::graphite::Device::drawDrawable ( SkCanvas ,
SkDrawable ,
const SkMatrix  
)
inlineoverridevirtual

Reimplemented from SkDevice.

Definition at line 186 of file Device.h.

186{}

◆ drawEdgeAAImageSet()

void skgpu::graphite::Device::drawEdgeAAImageSet ( const SkCanvas::ImageSetEntry  set[],
int  count,
const SkPoint  dstClips[],
const SkMatrix  preViewMatrices[],
const SkSamplingOptions sampling,
const SkPaint paint,
SkCanvas::SrcRectConstraint  constraint 
)
overridevirtual

Reimplemented from SkDevice.

Definition at line 786 of file Device.cpp.

789 {
790 SkASSERT(count > 0);
791
792 SkPaint paintWithShader(paint);
793 int dstClipIndex = 0;
794 for (int i = 0; i < count; ++i) {
795 // If the entry is clipped by 'dstClips', that must be provided
796 SkASSERT(!set[i].fHasClip || dstClips);
797 // Similarly, if it has an extra transform, those must be provided
798 SkASSERT(set[i].fMatrixIndex < 0 || preViewMatrices);
799
800 auto [ imageToDraw, newSampling ] =
801 skgpu::graphite::GetGraphiteBacked(this->recorder(), set[i].fImage.get(), sampling);
802 if (!imageToDraw) {
803 SKGPU_LOG_W("Device::drawImageRect: Creation of Graphite-backed image failed");
804 return;
805 }
806
807 // TODO: Produce an image shading paint key and data directly without having to reconstruct
808 // the equivalent SkPaint for each entry. Reuse the key and data between entries if possible
809 paintWithShader.setShader(paint.refShader());
810 paintWithShader.setAlphaf(paint.getAlphaf() * set[i].fAlpha);
812 imageToDraw.get(), newSampling, set[i].fSrcRect, set[i].fDstRect,
814 &paintWithShader);
815 if (dst.isEmpty()) {
816 return;
817 }
818
819 auto flags =
820 SkEnumBitMask<EdgeAAQuad::Flags>(static_cast<EdgeAAQuad::Flags>(set[i].fAAFlags));
821 EdgeAAQuad quad = set[i].fHasClip ? EdgeAAQuad(dstClips + dstClipIndex, flags)
822 : EdgeAAQuad(dst, flags);
823
824 // TODO: Calling drawGeometry() for each entry re-evaluates the clip stack every time, which
825 // is consistent with Ganesh's behavior. It also matches the behavior if edge-AA images were
826 // submitted one at a time by SkiaRenderer (a nice client simplification). However, we
827 // should explore the performance trade off with doing one bulk evaluation for the whole set
828 if (set[i].fMatrixIndex < 0) {
829 this->drawGeometry(this->localToDeviceTransform(),
830 Geometry(quad),
831 paintWithShader,
832 DefaultFillStyle(),
833 DrawFlags::kIgnorePathEffect);
834 } else {
835 SkM44 xtraTransform(preViewMatrices[set[i].fMatrixIndex]);
836 this->drawGeometry(this->localToDeviceTransform().concat(xtraTransform),
837 Geometry(quad),
838 paintWithShader,
839 DefaultFillStyle(),
840 DrawFlags::kIgnorePathEffect);
841 }
842
843 dstClipIndex += 4 * set[i].fHasClip;
844 }
845}
int count
SkRect SkModifyPaintAndDstForDrawImageRect(const SkImage *image, const SkSamplingOptions &, SkRect src, SkRect dst, bool strictSrcSubset, SkPaint *paint)
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
Definition SkCanvas.h:1542
FlutterSemanticsFlag flags
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
Definition switches.h:76
dst
Definition cp.py:12
std::pair< sk_sp< SkImage >, SkSamplingOptions > GetGraphiteBacked(Recorder *recorder, const SkImage *imageIn, SkSamplingOptions sampling)

◆ drawEdgeAAQuad()

void skgpu::graphite::Device::drawEdgeAAQuad ( const SkRect rect,
const SkPoint  clip[4],
SkCanvas::QuadAAFlags  aaFlags,
const SkColor4f color,
SkBlendMode  mode 
)
overridevirtual

Reimplemented from SkDevice.

Definition at line 768 of file Device.cpp.

772 {
773 SkPaint solidColorPaint;
774 solidColorPaint.setColor4f(color, /*colorSpace=*/nullptr);
775 solidColorPaint.setBlendMode(mode);
776
777 auto flags = SkEnumBitMask<EdgeAAQuad::Flags>(static_cast<EdgeAAQuad::Flags>(aaFlags));
778 EdgeAAQuad quad = clip ? EdgeAAQuad(clip, flags) : EdgeAAQuad(rect, flags);
779 this->drawGeometry(this->localToDeviceTransform(),
780 Geometry(quad),
781 solidColorPaint,
782 DefaultFillStyle(),
783 DrawFlags::kIgnorePathEffect);
784}
SkColor4f color
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
void setColor4f(const SkColor4f &color, SkColorSpace *colorSpace=nullptr)
Definition SkPaint.h:253
void setBlendMode(SkBlendMode mode)
Definition SkPaint.cpp:151

◆ drawImageLattice()

void skgpu::graphite::Device::drawImageLattice ( const SkImage ,
const SkCanvas::Lattice ,
const SkRect dst,
SkFilterMode  ,
const SkPaint  
)
inlineoverridevirtual

Reimplemented from SkDevice.

Definition at line 181 of file Device.h.

182 {}

◆ drawImageRect()

void skgpu::graphite::Device::drawImageRect ( const SkImage image,
const SkRect src,
const SkRect dst,
const SkSamplingOptions sampling,
const SkPaint paint,
SkCanvas::SrcRectConstraint  constraint 
)
overridevirtual

Implements SkDevice.

Definition at line 847 of file Device.cpp.

849 {
852 dst,
853 /*alpha=*/1.f,
855 this->drawEdgeAAImageSet(&single, 1, nullptr, nullptr, sampling, paint, constraint);
856}
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
SkIRect bounds() const
Definition SkImage.h:303
void drawEdgeAAImageSet(const SkCanvas::ImageSetEntry[], int count, const SkPoint dstClips[], const SkMatrix preViewMatrices[], const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
Definition Device.cpp:786

◆ drawMesh()

void skgpu::graphite::Device::drawMesh ( const SkMesh ,
sk_sp< SkBlender ,
const SkPaint  
)
inlineoverridevirtual

Implements SkDevice.

Definition at line 187 of file Device.h.

187{}

◆ drawOval()

void skgpu::graphite::Device::drawOval ( const SkRect oval,
const SkPaint paint 
)
overridevirtual

Implements SkDevice.

Definition at line 716 of file Device.cpp.

716 {
717 if (paint.getPathEffect()) {
718 // Dashing requires that the oval path starts on the right side and travels clockwise. This
719 // is the default for the SkPath::Oval constructor, as used by SkBitmapDevice.
720 this->drawGeometry(this->localToDeviceTransform(), Geometry(Shape(SkPath::Oval(oval))),
722 } else {
723 // TODO: This has wasted effort from the SkCanvas level since it instead converts rrects
724 // that happen to be ovals into this, only for us to go right back to rrect.
725 this->drawGeometry(this->localToDeviceTransform(), Geometry(Shape(SkRRect::MakeOval(oval))),
727 }
728}
static SkPath Oval(const SkRect &, SkPathDirection=SkPathDirection::kCW)
Definition SkPath.cpp:3522
static SkRRect MakeOval(const SkRect &oval)
Definition SkRRect.h:162

◆ drawPaint()

void skgpu::graphite::Device::drawPaint ( const SkPaint paint)
overridevirtual

Implements SkDevice.

Definition at line 620 of file Device.cpp.

620 {
622 // We never want to do a fullscreen clear on a fully-lazy render target, because the device size
623 // may be smaller than the final surface we draw to, in which case we don't want to fill the
624 // entire final surface.
625 if (this->isClipWideOpen() && !fDC->target()->isFullyLazy()) {
626 if (!paint_depends_on_dst(paint)) {
627 if (std::optional<SkColor4f> color = extract_paint_color(paint, fDC->colorInfo())) {
628 // do fullscreen clear
629 fDC->clear(*color);
630 return;
631 } else {
632 // This paint does not depend on the destination and covers the entire surface, so
633 // discard everything previously recorded and proceed with the draw.
634 fDC->discard();
635 }
636 }
637 }
638
640 if (!localToDevice.valid()) {
641 // TBD: This matches legacy behavior for drawPaint() that requires local coords, although
642 // v1 handles arbitrary transforms when the paint is solid color because it just fills the
643 // device bounds directly. In the new world it might be nice to have non-invertible
644 // transforms formalized (i.e. no drawing ever, handled at SkCanvas level possibly?)
645 return;
646 }
647 Rect localCoveringBounds = localToDevice.inverseMapRect(fClip.conservativeBounds());
648 this->drawGeometry(localToDevice,
649 Geometry(Shape(localCoveringBounds)),
650 paint,
651 DefaultFillStyle(),
652 DrawFlags::kIgnorePathEffect);
653}
bool isClipWideOpen() const override
Definition Device.h:125
#define ASSERT_SINGLE_OWNER
Definition Device.cpp:120
TRect< Scalar > Rect
Definition rect.h:746

◆ drawPath()

void skgpu::graphite::Device::drawPath ( const SkPath path,
const SkPaint paint,
bool  pathIsMutable = false 
)
overridevirtual

If pathIsMutable, then the implementation is allowed to cast path to a non-const pointer and modify it in place (as an optimization). Canvas may do this to implement helpers such as drawOval, by placing a temp path on the stack to hold the representation of the oval.

Implements SkDevice.

Definition at line 735 of file Device.cpp.

735 {
736 // TODO: If we do try to inspect the path, it should happen here and possibly after computing
737 // the path effect. Alternatively, all that should be handled in SkCanvas.
738 this->drawGeometry(this->localToDeviceTransform(), Geometry(Shape(path)),
740}

◆ drawPoints()

void skgpu::graphite::Device::drawPoints ( SkCanvas::PointMode  mode,
size_t  count,
const SkPoint  [],
const SkPaint paint 
)
overridevirtual

Implements SkDevice.

◆ drawRect()

void skgpu::graphite::Device::drawRect ( const SkRect r,
const SkPaint paint 
)
overridevirtual

Implements SkDevice.

Definition at line 655 of file Device.cpp.

655 {
656 this->drawGeometry(this->localToDeviceTransform(), Geometry(Shape(r)),
658}

◆ drawRRect()

void skgpu::graphite::Device::drawRRect ( const SkRRect rr,
const SkPaint paint 
)
overridevirtual

Implements SkDevice.

Definition at line 730 of file Device.cpp.

730 {
731 this->drawGeometry(this->localToDeviceTransform(), Geometry(Shape(rr)),
733}

◆ drawShadow()

void skgpu::graphite::Device::drawShadow ( const SkPath ,
const SkDrawShadowRec  
)
inlineoverridevirtual

Reimplemented from SkDevice.

Definition at line 188 of file Device.h.

188{}

◆ drawSlug()

void skgpu::graphite::Device::drawSlug ( SkCanvas canvas,
const sktext::gpu::Slug slug,
const SkPaint paint 
)
overrideprivatevirtual

Reimplemented from SkDevice.

Definition at line 1667 of file Device.cpp.

1667 {
1668 auto slugImpl = static_cast<const sktext::gpu::SlugImpl*>(slug);
1669 slugImpl->subRuns()->draw(canvas, slugImpl->origin(), paint, slugImpl, this->atlasDelegate());
1670}
const gpu::SubRunContainerOwner & subRuns() const
Definition SlugImpl.h:57

◆ drawSpecial()

void skgpu::graphite::Device::drawSpecial ( SkSpecialImage ,
const SkMatrix localToDevice,
const SkSamplingOptions ,
const SkPaint ,
SkCanvas::SrcRectConstraint  constraint 
)
overridevirtual

Draw the special image's subset to this device, subject to the given matrix transform instead of the device's current local to device matrix.

If 'constraint' is kFast, the rendered geometry of the image still reflects the extent of the SkSpecialImage's subset, but it's assumed that the pixel data beyond the subset is valid (e.g. SkSpecialImage::makeSubset() was called to crop a larger image).

Reimplemented from SkDevice.

Definition at line 1520 of file Device.cpp.

1524 {
1525 SkASSERT(!paint.getMaskFilter() && !paint.getImageFilter());
1526
1527 sk_sp<SkImage> img = special->asImage();
1528 if (!img || !as_IB(img)->isGraphiteBacked()) {
1529 SKGPU_LOG_W("Couldn't get Graphite-backed special image as image");
1530 return;
1531 }
1532
1533 SkPaint paintWithShader(paint);
1535 img.get(),
1536 sampling,
1537 /*src=*/SkRect::Make(special->subset()),
1538 /*dst=*/SkRect::MakeIWH(special->width(), special->height()),
1539 /*strictSrcSubset=*/constraint == SkCanvas::kStrict_SrcRectConstraint,
1540 &paintWithShader);
1541 if (dst.isEmpty()) {
1542 return;
1543 }
1544
1545 this->drawGeometry(Transform(SkM44(localToDevice)),
1546 Geometry(Shape(dst)),
1547 paintWithShader,
1548 DefaultFillStyle(),
1549 DrawFlags::kIgnorePathEffect);
1550}
static SkImage_Base * as_IB(SkImage *image)
T * get() const
Definition SkRefCnt.h:303
static SkRect MakeIWH(int w, int h)
Definition SkRect.h:623

◆ drawVertices()

void skgpu::graphite::Device::drawVertices ( const SkVertices ,
sk_sp< SkBlender ,
const SkPaint ,
bool  skipColorXform 
)
overridevirtual

If skipColorXform is true, then the implementation should assume that the provided vertex colors are already in the destination color space.

Implements SkDevice.

Definition at line 660 of file Device.cpp.

661 {
662 // TODO - Add GPU handling of skipColorXform once Graphite has its color system more fleshed out.
663 this->drawGeometry(this->localToDeviceTransform(),
664 Geometry(sk_ref_sp(vertices)),
665 paint,
666 DefaultFillStyle(),
667 DrawFlags::kIgnorePathEffect,
668 std::move(blender),
669 skipColorXform);
670}

◆ flushPendingWorkToRecorder()

void skgpu::graphite::Device::flushPendingWorkToRecorder ( Recorder recorder = nullptr)

Definition at line 1410 of file Device.cpp.

1410 {
1411 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
1412
1413 // Confirm sentinels match the original values set from fRecorder
1414 SkDEBUGCODE(intptr_t expected = reinterpret_cast<intptr_t>(recorder ? recorder : fRecorder);)
1415 SkASSERT(fPreRecorderSentinel == expected - 1);
1416 SkASSERT(fPostRecorderSentinel == expected + 1);
1417
1418 SkASSERT(recorder == nullptr || recorder == fRecorder);
1419 if (recorder && recorder != fRecorder) {
1420 // TODO(b/333073673): This should not happen but if the Device were corrupted exit now
1421 // to avoid further access of Device's state.
1422 return;
1423 }
1424
1425 // If this is a scratch device being flushed, it should only be flushing into the expected
1426 // next recording from when the Device was first created.
1427 SkASSERT(fRecorder);
1428 // TODO(b/333073673):
1429 // The only time flushPendingWorkToRecorder() is called with a non-null Recorder is from
1430 // flushTrackedDevices(), so the scoped recording ID of the device should be 0 or it means a
1431 // non-tracked device got added to the recorder or something has stomped the heap.
1432 SkASSERT(!recorder || fScopedRecordingID == 0);
1433 SkASSERT(fScopedRecordingID == 0 || fScopedRecordingID == fRecorder->priv().nextRecordingID());
1434
1435 // TODO(b/330864257): flushPendingWorkToRecorder() can be recursively called if this Device
1436 // recorded a picture shader draw and during a flush (triggered by snap or automatically from
1437 // reaching limits), the picture shader will be rendered to a new device. If that picture drawn
1438 // to the temporary device fills up an atlas it can trigger the global
1439 // recorder->flushTrackedDevices(), which will then encounter this device that is already in
1440 // the midst of flushing. To avoid crashing we only actually flush the first time this is called
1441 // and set a bit to early-out on any recursive calls.
1442 // This is not an ideal solution since the temporary Device's flush-the-world may have reset
1443 // atlas entries that the current Device's flushed draws will reference. But at this stage it's
1444 // not possible to split the already recorded draws into a before-list and an after-list that
1445 // can reference the old and new contents of the atlas. While avoiding the crash, this may cause
1446 // incorrect accesses to a shared atlas. Once paint data is extracted at draw time, picture
1447 // shaders will be resolved outside of flushes and then this will be fixed automatically.
1448 if (fIsFlushing) {
1449 return;
1450 } else {
1451 fIsFlushing = true;
1452 }
1453
1454 this->internalFlush();
1455 sk_sp<Task> drawTask = fDC->snapDrawTask(fRecorder);
1456 if (this->isScratchDevice()) {
1457 // TODO(b/323887221): Once shared atlas resources are less brittle, scratch devices won't
1458 // flush to the recorder at all and will only store the snapped task here.
1459 fLastTask = drawTask;
1460 } else {
1461 // Non-scratch devices do not need to point back to the last snapped task since they are
1462 // always added to the root task list.
1463 // TODO: It is currently possible for scratch devices to be flushed and instantiated before
1464 // their work is finished, meaning they will produce additional tasks to be included in
1465 // a follow-up Recording: https://chat.google.com/room/AAAA2HlH94I/YU0XdFqX2Uw.
1466 // However, in this case they no longer appear scratch because the first Recording
1467 // instantiated the targets. When scratch devices are not actually registered with the
1468 // Recorder and are only included when they are drawn (e.g. restored), we should be able to
1469 // assert that `fLastTask` is null.
1470 fLastTask = nullptr;
1471 }
1472
1473 if (drawTask) {
1474 fRecorder->priv().add(std::move(drawTask));
1475
1476 // TODO(b/297344089): This always regenerates mipmaps on the draw target when it's drawn to.
1477 // This could be wasteful if we draw to a target multiple times before reading from it with
1478 // downscaling.
1479 if (fDC->target()->mipmapped() == Mipmapped::kYes) {
1480 if (!GenerateMipmaps(fRecorder, fDC->refTarget(), fDC->colorInfo())) {
1481 SKGPU_LOG_W("Device::flushPendingWorkToRecorder: Failed to generate mipmaps");
1482 }
1483 }
1484 }
1485
1486 fIsFlushing = false;
1487}
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
#define TRACE_FUNC
bool isScratchDevice() const
Definition Device.cpp:1645
bool GenerateMipmaps(Recorder *recorder, sk_sp< TextureProxy > texture, const SkColorInfo &colorInfo)
#define TRACE_EVENT0(category_group, name)

◆ isClipAntiAliased()

bool skgpu::graphite::Device::isClipAntiAliased ( ) const
overridevirtual

Implements SkDevice.

Definition at line 520 of file Device.cpp.

520 {
521 // All clips are AA'ed unless it's wide-open, empty, or a device-rect with integer coordinates
524 return false;
526 const ClipStack::Element rect = *fClip.begin();
527 SkASSERT(rect.fShape.isRect() && rect.fLocalToDevice.type() == Transform::Type::kIdentity);
528 return rect.fShape.rect() != rect.fShape.rect().makeRoundOut();
529 } else {
530 return true;
531 }
532}

◆ isClipEmpty()

bool skgpu::graphite::Device::isClipEmpty ( ) const
inlineoverridevirtual

Implements SkDevice.

Definition at line 128 of file Device.h.

128 {
129 return fClip.clipState() == ClipStack::ClipState::kEmpty;
130 }

◆ isClipRect()

bool skgpu::graphite::Device::isClipRect ( ) const
inlineoverridevirtual

Implements SkDevice.

Definition at line 131 of file Device.h.

131 {
134 }

◆ isClipWideOpen()

bool skgpu::graphite::Device::isClipWideOpen ( ) const
inlineoverridevirtual

Implements SkDevice.

Definition at line 125 of file Device.h.

125 {
127 }

◆ isScratchDevice()

bool skgpu::graphite::Device::isScratchDevice ( ) const

Definition at line 1645 of file Device.cpp.

1645 {
1646 // Scratch device status is inferred from whether or not the Device's target is instantiated.
1647 // By default devices start out un-instantiated unless they are wrapping an existing backend
1648 // texture (definitely not a scratch scenario), or Surface explicitly instantiates the target
1649 // before returning to the client (not a scratch scenario).
1650 //
1651 // Scratch device targets are instantiated during the prepareResources() phase of
1652 // Recorder::snap(). Truly scratch devices that have gone out of scope as intended will have
1653 // already been destroyed at this point. Scratch devices that become longer-lived (linked to
1654 // a client-owned object) automatically transition to non-scratch usage.
1655 return !fDC->target()->isInstantiated() && !fDC->target()->isLazy();
1656}

◆ lastDrawTask()

sk_sp< Task > skgpu::graphite::Device::lastDrawTask ( ) const

Definition at line 1405 of file Device.cpp.

1405 {
1406 SkASSERT(this->isScratchDevice());
1407 return fLastTask;
1408}

◆ localToDeviceTransform()

const Transform & skgpu::graphite::Device::localToDeviceTransform ( )

Definition at line 374 of file Device.cpp.

374 {
375 if (this->checkLocalToDeviceDirty()) {
376 fCachedLocalToDevice = Transform{this->localToDevice44()};
377 }
378 return fCachedLocalToDevice;
379}
bool checkLocalToDeviceDirty()
Definition SkDevice.h:514
const SkM44 & localToDevice44() const
Definition SkDevice.h:178

◆ Make() [1/2]

sk_sp< Device > skgpu::graphite::Device::Make ( Recorder recorder,
const SkImageInfo ii,
skgpu::Budgeted  budgeted,
Mipmapped  mipmapped,
SkBackingFit  backingFit,
const SkSurfaceProps props,
LoadOp  initialLoadOp,
bool  registerWithRecorder = true 
)
static

Definition at line 237 of file Device.cpp.

244 {
245 SkASSERT(!(mipmapped == Mipmapped::kYes && backingFit == SkBackingFit::kApprox));
246 if (!recorder) {
247 return nullptr;
248 }
249
250 const Caps* caps = recorder->priv().caps();
251 SkISize backingDimensions = backingFit == SkBackingFit::kApprox ? GetApproxSize(ii.dimensions())
252 : ii.dimensions();
253 auto textureInfo = caps->getDefaultSampledTextureInfo(ii.colorType(),
254 mipmapped,
256 Renderable::kYes);
257
258 return Make(recorder,
260 backingDimensions, textureInfo, budgeted),
261 ii.dimensions(),
262 ii.colorInfo(),
263 props,
264 initialLoadOp,
265 registerWithRecorder);
266}
Protected isProtected() const
ResourceProvider * resourceProvider()
static sk_sp< TextureProxy > Make(const Caps *, ResourceProvider *, SkISize dimensions, const TextureInfo &, skgpu::Budgeted)
SkISize GetApproxSize(SkISize size)
const SkColorInfo & colorInfo() const
SkISize dimensions() const
SkColorType colorType() const

◆ Make() [2/2]

sk_sp< Device > skgpu::graphite::Device::Make ( Recorder recorder,
sk_sp< TextureProxy target,
SkISize  deviceSize,
const SkColorInfo colorInfo,
const SkSurfaceProps props,
LoadOp  initialLoadOp,
bool  registerWithRecorder = true 
)
static

Definition at line 268 of file Device.cpp.

274 {
275 if (!recorder) {
276 return nullptr;
277 }
278
280 std::move(target),
281 deviceSize,
282 colorInfo,
283 props);
284 if (!dc) {
285 return nullptr;
286 } else if (initialLoadOp == LoadOp::kClear) {
287 dc->clear(SkColors::kTransparent);
288 } else if (initialLoadOp == LoadOp::kDiscard) {
289 dc->discard();
290 } // else kLoad is the default initial op for a DrawContext
291
292 sk_sp<Device> device{new Device(recorder, std::move(dc))};
293 if (registerWithRecorder) {
294 // We don't register the device with the recorder until after the constructor has returned.
295 recorder->registerDevice(device);
296 } else {
297 // Since it's not registered, it should go out of scope before nextRecordingID() changes
298 // from what is saved to fScopedRecordingID.
299 SkDEBUGCODE(device->fScopedRecordingID = recorder->priv().nextRecordingID();)
300 }
301 return device;
302}
TextureProxy * target()
Definition Device.cpp:1641
static sk_sp< DrawContext > Make(const Caps *caps, sk_sp< TextureProxy > target, SkISize deviceSize, const SkColorInfo &, const SkSurfaceProps &)
VkDevice device
Definition main.cc:53
constexpr SkColor4f kTransparent
Definition SkColor.h:434

◆ makeImageCopy()

sk_sp< Image > skgpu::graphite::Device::makeImageCopy ( const SkIRect subset,
Budgeted  budgeted,
Mipmapped  mipmapped,
SkBackingFit  backingFit 
)

Definition at line 411 of file Device.cpp.

414 {
417
418 const SkColorInfo& colorInfo = this->imageInfo().colorInfo();
419 TextureProxyView srcView = this->readSurfaceView();
420 if (!srcView) {
421 // readSurfaceView() returns an empty view when the target is not texturable. Create an
422 // equivalent view for the blitting operation.
423 Swizzle readSwizzle = fRecorder->priv().caps()->getReadSwizzle(
424 colorInfo.colorType(), this->target()->textureInfo());
425 srcView = {sk_ref_sp(this->target()), readSwizzle};
426 }
427 return Image::Copy(fRecorder, srcView, colorInfo, subset, budgeted, mipmapped, backingFit);
428}
SkColorType colorType() const
const SkImageInfo & imageInfo() const
Definition SkDevice.h:117
TextureProxyView readSurfaceView() const
Definition Device.cpp:1643
void flushPendingWorkToRecorder(Recorder *recorder=nullptr)
Definition Device.cpp:1410
static sk_sp< Image > Copy(Recorder *, const TextureProxyView &srcView, const SkColorInfo &, const SkIRect &subset, Budgeted, Mipmapped, SkBackingFit)

◆ makeSpecial() [1/2]

sk_sp< SkSpecialImage > skgpu::graphite::Device::makeSpecial ( const SkBitmap )
overrideprivatevirtual

Reimplemented from SkDevice.

Definition at line 1598 of file Device.cpp.

1598 {
1599 return nullptr;
1600}

◆ makeSpecial() [2/2]

sk_sp< SkSpecialImage > skgpu::graphite::Device::makeSpecial ( const SkImage )
overrideprivatevirtual

Reimplemented from SkDevice.

Definition at line 1602 of file Device.cpp.

1602 {
1603 return nullptr;
1604}

◆ makeSurface()

sk_sp< SkSurface > skgpu::graphite::Device::makeSurface ( const SkImageInfo ii,
const SkSurfaceProps props 
)
overridevirtual

Reimplemented from SkDevice.

Definition at line 407 of file Device.cpp.

407 {
408 return SkSurfaces::RenderTarget(fRecorder, ii, Mipmapped::kNo, &props);
409}
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)

◆ onClipShader()

void skgpu::graphite::Device::onClipShader ( sk_sp< SkShader shader)
overrideprivatevirtual

Implements SkDevice.

Definition at line 579 of file Device.cpp.

579 {
580 fClip.clipShader(std::move(shader));
581}
void clipShader(sk_sp< SkShader > shader)

◆ onDrawGlyphRunList()

void skgpu::graphite::Device::onDrawGlyphRunList ( SkCanvas canvas,
const sktext::GlyphRunList glyphRunList,
const SkPaint paint 
)
overrideprivatevirtual

Implements SkDevice.

Definition at line 868 of file Device.cpp.

870 {
872 fRecorder->priv().textBlobCache()->drawGlyphRunList(canvas,
873 this->localToDevice(),
874 glyphRunList,
875 paint,
876 this->strikeDeviceInfo(),
877 this->atlasDelegate());
878}

◆ onReadPixels()

bool skgpu::graphite::Device::onReadPixels ( const SkPixmap pm,
int  x,
int  y 
)
overrideprivatevirtual

Reimplemented from SkDevice.

Definition at line 430 of file Device.cpp.

430 {
431#if defined(GRAPHITE_TEST_UTILS)
432 // This testing-only function should only be called before the Device has detached from its
433 // Recorder, since it's accessed via the test-held Surface.
435 if (Context* context = fRecorder->priv().context()) {
436 // Add all previous commands generated to the command buffer.
437 // If the client snaps later they'll only get post-read commands in their Recording,
438 // but since they're doing a readPixels in the middle that shouldn't be unexpected.
439 std::unique_ptr<Recording> recording = fRecorder->snap();
440 if (!recording) {
441 return false;
442 }
443 InsertRecordingInfo info;
444 info.fRecording = recording.get();
445 if (!context->insertRecording(info)) {
446 return false;
447 }
448 return context->priv().readPixels(pm, fDC->target(), this->imageInfo(), srcX, srcY);
449 }
450#endif
451 // We have no access to a context to do a read pixels here.
452 return false;
453}

◆ onWritePixels()

bool skgpu::graphite::Device::onWritePixels ( const SkPixmap src,
int  x,
int  y 
)
overrideprivatevirtual

Reimplemented from SkDevice.

Definition at line 455 of file Device.cpp.

455 {
457 // TODO: we may need to share this in a more central place to handle uploads
458 // to backend textures
459
460 const TextureProxy* target = fDC->target();
461
462 // TODO: add mipmap support for createBackendTexture
463
464 if (src.colorType() == kUnknown_SkColorType) {
465 return false;
466 }
467
468 // If one alpha type is unknown and the other isn't, it's too underspecified.
469 if ((src.alphaType() == kUnknown_SkAlphaType) !=
470 (this->imageInfo().alphaType() == kUnknown_SkAlphaType)) {
471 return false;
472 }
473
474 // TODO: canvas2DFastPath?
475
476 if (!fRecorder->priv().caps()->supportsWritePixels(target->textureInfo())) {
477 auto image = SkImages::RasterFromPixmap(src, nullptr, nullptr);
479 if (!image) {
480 return false;
481 }
482
484 paint.setBlendMode(SkBlendMode::kSrc);
485 this->drawImageRect(image.get(),
486 /*src=*/nullptr,
487 SkRect::MakeXYWH(x, y, src.width(), src.height()),
489 paint,
491 return true;
492 }
493
494 // TODO: check for flips and either handle here or pass info to UploadTask
495
496 // Determine rect to copy
497 SkIRect dstRect = SkIRect::MakePtSize({x, y}, src.dimensions());
499 return false;
500 }
501
502 // Set up copy location
503 const void* addr = src.addr(dstRect.fLeft - x, dstRect.fTop - y);
504 std::vector<MipLevel> levels;
505 levels.push_back({addr, src.rowBytes()});
506
507 // The writePixels() still respects painter's order, so flush everything to tasks before this
508 // recording the upload for the pixel data.
509 this->internalFlush();
510 // The new upload will be executed before any new draws are recorded and also ensures that
511 // the next call to flushDeviceToRecorder() will produce a non-null DrawTask. If this Device's
512 // target is mipmapped, mipmap generation tasks will be added automatically at that point.
513 return fDC->recordUpload(fRecorder, fDC->refTarget(), src.info().colorInfo(),
514 this->imageInfo().colorInfo(), levels, dstRect, nullptr);
515}
@ kUnknown_SkAlphaType
uninitialized
Definition SkAlphaType.h:27
@ kUnknown_SkColorType
uninitialized
Definition SkColorType.h:20
@ kFast_SrcRectConstraint
sample outside bounds; faster
Definition SkCanvas.h:1543
int width() const
Definition SkPixmap.h:160
void drawImageRect(const SkImage *, const SkRect *src, const SkRect &dst, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
Definition Device.cpp:847
const TextureInfo & textureInfo() const
double y
double x
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)
bool intersect(const SkIRect &r)
Definition SkRect.h:513
int32_t fTop
smaller y-axis bounds
Definition SkRect.h:34
static constexpr SkIRect MakeSize(const SkISize &size)
Definition SkRect.h:66
int32_t fLeft
smaller x-axis bounds
Definition SkRect.h:33
static constexpr SkIRect MakePtSize(SkIPoint pt, SkISize size)
Definition SkRect.h:78
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659

◆ popClipStack()

void skgpu::graphite::Device::popClipStack ( )
inlineoverridevirtual

Implements SkDevice.

Definition at line 123 of file Device.h.

◆ pushClipStack()

void skgpu::graphite::Device::pushClipStack ( )
inlineoverridevirtual

Implements SkDevice.

Definition at line 122 of file Device.h.

◆ readSurfaceView()

TextureProxyView skgpu::graphite::Device::readSurfaceView ( ) const

Definition at line 1643 of file Device.cpp.

1643{ return fDC->readSurfaceView(); }

◆ recorder()

Recorder * skgpu::graphite::Device::recorder ( ) const
inlineoverridevirtual

Reimplemented from SkDevice.

Definition at line 71 of file Device.h.

71{ return fRecorder; }

◆ replaceClip()

void skgpu::graphite::Device::replaceClip ( const SkIRect rect)
overridevirtual

Implements SkDevice.

Definition at line 603 of file Device.cpp.

603 {
604 // ReplaceClip() is currently not intended to be supported in Graphite since it's only used
605 // for emulating legacy clip ops in Android Framework, and apps/devices that require that
606 // should not use Graphite. However, if it needs to be supported, we could probably implement
607 // it by:
608 // 1. Flush all pending clip element depth draws.
609 // 2. Draw a fullscreen rect to the depth attachment using a Z value greater than what's
610 // been used so far.
611 // 3. Make sure all future "unclipped" draws use this Z value instead of 0 so they aren't
612 // sorted before the depth reset.
613 // 4. Make sure all prior elements are inactive so they can't affect subsequent draws.
614 //
615 // For now, just ignore it.
616}

◆ setImmutable()

void skgpu::graphite::Device::setImmutable ( )
overridevirtual

Reimplemented from SkDevice.

Definition at line 359 of file Device.cpp.

359 {
360 if (fRecorder) {
361 // Push any pending work to the Recorder now. setImmutable() is only called by the
362 // destructor of a client-owned Surface, or explicitly in layer/filtering workflows. In
363 // both cases this is restricted to the Recorder's thread. This is in contrast to ~Device(),
364 // which might be called from another thread if it was linked to an Image used in multiple
365 // recorders.
367 fRecorder->deregisterDevice(this);
368 // Abandoning the recorder ensures that there are no further operations that can be recorded
369 // and is relied on by Image::notifyInUse() to detect when it can unlink from a Device.
370 this->abandonRecorder();
371 }
372}

◆ snapSpecial()

sk_sp< SkSpecialImage > skgpu::graphite::Device::snapSpecial ( const SkIRect subset,
bool  forceCopy = false 
)
overridevirtual

Reimplemented from SkDevice.

Definition at line 1606 of file Device.cpp.

1606 {
1607 // NOTE: snapSpecial() can be called even after the device has been marked immutable (null
1608 // recorder), but in those cases it should not be a copy and just returns the image view.
1609 sk_sp<Image> deviceImage;
1610 SkIRect finalSubset;
1611 if (forceCopy || !this->readSurfaceView() || this->readSurfaceView().proxy()->isFullyLazy()) {
1612 deviceImage = this->makeImageCopy(
1613 subset, Budgeted::kYes, Mipmapped::kNo, SkBackingFit::kApprox);
1614 finalSubset = SkIRect::MakeSize(subset.size());
1615 } else {
1616 // TODO(b/323886870): For now snapSpecial() force adds the pending work to the recorder's
1617 // root task list. Once shared atlas management is solved and DrawTasks can be nested in a
1618 // graph then this can go away in favor of auto-flushing through the image's linked device.
1619 if (fRecorder) {
1621 }
1622 deviceImage = Image::WrapDevice(sk_ref_sp(this));
1623 finalSubset = subset;
1624 }
1625
1626 if (!deviceImage) {
1627 return nullptr;
1628 }
1629
1630 // For non-copying "snapSpecial", the semantics are returning an image view of the surface data,
1631 // and relying on higher-level draw and restore logic for the contents to make sense.
1632 return SkSpecialImages::MakeGraphite(
1633 fRecorder, finalSubset, std::move(deviceImage), this->surfaceProps());
1634}
sk_sp< Image > makeImageCopy(const SkIRect &subset, Budgeted, Mipmapped, SkBackingFit)
Definition Device.cpp:411
static sk_sp< Image > WrapDevice(sk_sp< Device > device)
constexpr SkISize size() const
Definition SkRect.h:172

◆ strikeDeviceInfo()

SkStrikeDeviceInfo skgpu::graphite::Device::strikeDeviceInfo ( ) const
overridevirtual

Reimplemented from SkDevice.

Definition at line 381 of file Device.cpp.

381 {
382 return {this->surfaceProps(), this->scalerContextFlags(), &fSDFTControl};
383}
SkScalerContextFlags scalerContextFlags() const
Definition SkDevice.cpp:503

◆ target()

TextureProxy * skgpu::graphite::Device::target ( )

Definition at line 1641 of file Device.cpp.

1641{ return fDC->target(); }

◆ useDrawCoverageMaskForMaskFilters()

bool skgpu::graphite::Device::useDrawCoverageMaskForMaskFilters ( ) const
inlineoverridevirtual

Reimplemented from SkDevice.

Definition at line 118 of file Device.h.

118{ return true; }

Friends And Related Symbol Documentation

◆ ClipStack

friend class ClipStack
friend

Definition at line 336 of file Device.h.


The documentation for this class was generated from the following files: