Flutter Engine
The Flutter Engine
Classes | Public Member Functions | Protected Member Functions | Private Member Functions | Friends | List of all members
SkDevice Class Referenceabstract

#include <SkDevice.h>

Inheritance diagram for SkDevice:
SkRefCnt SkRefCntBase SkBitmapDevice SkClipStackDevice SkNoPixelsDevice skgpu::ganesh::Device skgpu::graphite::Device SkPDFDevice SkSVGDevice GlyphTrackingDevice

Classes

struct  CreateInfo
 

Public Member Functions

 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
 
virtual SkStrikeDeviceInfo strikeDeviceInfo () 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
 
virtual SkIRect devClipBounds () const =0
 
virtual void pushClipStack ()=0
 
virtual void popClipStack ()=0
 
virtual void clipRect (const SkRect &rect, SkClipOp op, bool aa)=0
 
virtual void clipRRect (const SkRRect &rrect, SkClipOp op, bool aa)=0
 
virtual void clipPath (const SkPath &path, SkClipOp op, bool aa)=0
 
virtual void clipRegion (const SkRegion &region, SkClipOp op)=0
 
void clipShader (sk_sp< SkShader > sh, SkClipOp op)
 
virtual void replaceClip (const SkIRect &rect)=0
 
virtual bool isClipAntiAliased () const =0
 
virtual bool isClipEmpty () const =0
 
virtual bool isClipRect () const =0
 
virtual bool isClipWideOpen () const =0
 
virtual void android_utils_clipAsRgn (SkRegion *) const =0
 
virtual bool android_utils_clipWithStencil ()
 
virtual bool useDrawCoverageMaskForMaskFilters () const
 
virtual bool isNoPixelsDevice () const
 
virtual void * getRasterHandle () const
 
virtual GrRecordingContextrecordingContext () const
 
virtual skgpu::graphite::Recorderrecorder () const
 
virtual skgpu::ganesh::DeviceasGaneshDevice ()
 
virtual skgpu::graphite::DeviceasGraphiteDevice ()
 
virtual void setImmutable ()
 
virtual sk_sp< SkSurfacemakeSurface (const SkImageInfo &, const SkSurfaceProps &)
 
virtual sk_sp< SkDevicecreateDevice (const CreateInfo &, const SkPaint *)
 
void drawGlyphRunList (SkCanvas *, const sktext::GlyphRunList &glyphRunList, const SkPaint &paint)
 
virtual sk_sp< sktext::gpu::SlugconvertGlyphRunListToSlug (const sktext::GlyphRunList &glyphRunList, const SkPaint &paint)
 
virtual void drawSlug (SkCanvas *, const sktext::gpu::Slug *slug, const SkPaint &paint)
 
virtual void drawPaint (const SkPaint &paint)=0
 
virtual void drawPoints (SkCanvas::PointMode mode, size_t count, const SkPoint[], const SkPaint &paint)=0
 
virtual void drawRect (const SkRect &r, const SkPaint &paint)=0
 
virtual void drawRegion (const SkRegion &r, const SkPaint &paint)
 
virtual void drawOval (const SkRect &oval, const SkPaint &paint)=0
 
virtual void drawArc (const SkArc &arc, const SkPaint &paint)
 
virtual void drawRRect (const SkRRect &rr, const SkPaint &paint)=0
 
virtual void drawDRRect (const SkRRect &outer, const SkRRect &inner, const SkPaint &)
 
virtual void drawPath (const SkPath &path, const SkPaint &paint, bool pathIsMutable=false)=0
 
virtual void drawImageRect (const SkImage *, const SkRect *src, const SkRect &dst, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint)=0
 
virtual bool shouldDrawAsTiledImageRect () const
 
virtual bool drawAsTiledImageRect (SkCanvas *, const SkImage *, const SkRect *src, const SkRect &dst, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint)
 
virtual void drawImageLattice (const SkImage *, const SkCanvas::Lattice &, const SkRect &dst, SkFilterMode, const SkPaint &)
 
virtual void drawVertices (const SkVertices *, sk_sp< SkBlender >, const SkPaint &, bool skipColorXform=false)=0
 
virtual void drawMesh (const SkMesh &mesh, sk_sp< SkBlender >, const SkPaint &)=0
 
virtual void drawShadow (const SkPath &, const SkDrawShadowRec &)
 
virtual void drawPatch (const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], sk_sp< SkBlender >, const SkPaint &paint)
 
virtual void drawAtlas (const SkRSXform[], const SkRect[], const SkColor[], int count, sk_sp< SkBlender >, const SkPaint &)
 
virtual void drawAnnotation (const SkRect &, const char[], SkData *)
 
virtual void drawEdgeAAQuad (const SkRect &rect, const SkPoint clip[4], SkCanvas::QuadAAFlags aaFlags, const SkColor4f &color, SkBlendMode mode)
 
virtual void drawEdgeAAImageSet (const SkCanvas::ImageSetEntry[], int count, const SkPoint dstClips[], const SkMatrix preViewMatrices[], const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint)
 
virtual void drawDrawable (SkCanvas *, SkDrawable *, const SkMatrix *)
 
virtual sk_sp< SkSpecialImagesnapSpecial (const SkIRect &subset, bool forceCopy=false)
 
virtual sk_sp< SkSpecialImagesnapSpecialScaled (const SkIRect &subset, const SkISize &dstDims)
 
sk_sp< SkSpecialImagesnapSpecial ()
 
virtual void drawDevice (SkDevice *, const SkSamplingOptions &, const SkPaint &)
 
virtual void drawSpecial (SkSpecialImage *, const SkMatrix &localToDevice, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint constraint=SkCanvas::kStrict_SrcRectConstraint)
 
virtual void drawCoverageMask (const SkSpecialImage *, const SkMatrix &maskToDevice, const SkSamplingOptions &, const SkPaint &)
 
virtual bool drawBlurredRRect (const SkRRect &, const SkPaint &, float deviceSigma)
 
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
 

Protected Member Functions

virtual sk_sp< SkSpecialImagemakeSpecial (const SkBitmap &)
 
virtual sk_sp< SkSpecialImagemakeSpecial (const SkImage *)
 
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 ()
 

Private Member Functions

virtual sk_sp< skif::BackendcreateImageFilteringBackend (const SkSurfaceProps &surfaceProps, SkColorType colorType) const
 
virtual bool onReadPixels (const SkPixmap &, int x, int y)
 
virtual bool onWritePixels (const SkPixmap &, int x, int y)
 
virtual bool onAccessPixels (SkPixmap *)
 
virtual bool onPeekPixels (SkPixmap *)
 
virtual void onClipShader (sk_sp< SkShader >)=0
 
virtual void onDrawGlyphRunList (SkCanvas *, const sktext::GlyphRunList &, const SkPaint &paint)=0
 

Friends

class SkCanvas
 
class DeviceTestingAccess
 

Detailed Description

SkDevice is the internal API and implementation that SkCanvas will use to perform rendering and implement the saveLayer abstraction. A device wraps some pixel allocation (for non-document based devices) or wraps some other container that stores rendering operations. The drawing operations perform equivalently to their corresponding functions in SkCanvas except that the canvas is responsible for all SkImageFilters. An image filter is applied by automatically creating a layer, drawing the filter-less paint into the layer, and then evaluating the filter on the layer's image.

Each layer in an SkCanvas stack is represented by an SkDevice instance that was created by the parent SkDevice (up to the canvas's base device). In most cases these devices will be pixel aligned with one another but may differ in size based on the known extent of the active clip. In complex image filtering scenarios, they may not be axis aligned, although the effective pixel size should remain approximately equal across all devices in a canvas.

While SkCanvas manages a single stack of layers and canvas transforms, SkDevice does not have a stack of transforms. Instead, it has a single active transform that is modified as needed by SkCanvas. However, SkDevices are the means by which SkCanvas manages the clip stack because each layer's clip stack starts anew (although the layer's results are then clipped by its parent's stack when it is restored).

Definition at line 107 of file SkDevice.h.

Constructor & Destructor Documentation

◆ SkDevice()

SkDevice::SkDevice ( const SkImageInfo info,
const SkSurfaceProps surfaceProps 
)

Definition at line 45 of file SkDevice.cpp.

46 : fInfo(info)
47 , fSurfaceProps(surfaceProps) {
48 fDeviceToGlobal.setIdentity();
49 fGlobalToDevice.setIdentity();
50}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
const SkSurfaceProps & surfaceProps() const
Definition: SkDevice.h:131
SkM44 & setIdentity()
Definition: SkM44.h:293

Member Function Documentation

◆ accessPixels()

bool SkDevice::accessPixels ( SkPixmap pmap)

Try to get write-access to the pixels behind the device. If successful, this returns true and fills-out the pixmap parameter. On success it also bumps the genID of the underlying bitmap.

On failure, returns false and ignores the pixmap parameter.

Definition at line 383 of file SkDevice.cpp.

383 {
384 SkPixmap tempStorage;
385 if (nullptr == pmap) {
386 pmap = &tempStorage;
387 }
388 return this->onAccessPixels(pmap);
389}
virtual bool onAccessPixels(SkPixmap *)
Definition: SkDevice.h:533

◆ android_utils_clipAsRgn()

virtual void SkDevice::android_utils_clipAsRgn ( SkRegion ) const
pure virtual

◆ android_utils_clipWithStencil()

virtual bool SkDevice::android_utils_clipWithStencil ( )
inlinevirtual

Reimplemented in skgpu::ganesh::Device.

Definition at line 267 of file SkDevice.h.

267{ return false; }

◆ asGaneshDevice()

virtual skgpu::ganesh::Device * SkDevice::asGaneshDevice ( )
inlinevirtual

Reimplemented in skgpu::ganesh::Device.

Definition at line 287 of file SkDevice.h.

287{ return nullptr; }

◆ asGraphiteDevice()

virtual skgpu::graphite::Device * SkDevice::asGraphiteDevice ( )
inlinevirtual

Reimplemented in skgpu::graphite::Device.

Definition at line 288 of file SkDevice.h.

288{ return nullptr; }

◆ bounds()

SkIRect SkDevice::bounds ( ) const
inline

Definition at line 125 of file SkDevice.h.

125{ return SkIRect::MakeWH(this->width(), this->height()); }
int height() const
Definition: SkDevice.h:120
int width() const
Definition: SkDevice.h:119
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition: SkRect.h:56

◆ checkLocalToDeviceDirty()

bool SkDevice::checkLocalToDeviceDirty ( )
inlineprotected

Definition at line 513 of file SkDevice.h.

513 {
514 bool wasDirty = fLocalToDeviceDirty;
515 fLocalToDeviceDirty = false;
516 return wasDirty;
517 }

◆ clipPath()

virtual void SkDevice::clipPath ( const SkPath path,
SkClipOp  op,
bool  aa 
)
pure virtual

◆ clipRect()

virtual void SkDevice::clipRect ( const SkRect rect,
SkClipOp  op,
bool  aa 
)
pure virtual

◆ clipRegion()

virtual void SkDevice::clipRegion ( const SkRegion region,
SkClipOp  op 
)
pure virtual

◆ clipRRect()

virtual void SkDevice::clipRRect ( const SkRRect rrect,
SkClipOp  op,
bool  aa 
)
pure virtual

◆ clipShader()

void SkDevice::clipShader ( sk_sp< SkShader sh,
SkClipOp  op 
)
inline

Definition at line 251 of file SkDevice.h.

251 {
252 sh = as_SB(sh)->makeWithCTM(this->localToDevice());
253 if (op == SkClipOp::kDifference) {
255 }
256 this->onClipShader(std::move(sh));
257 }
SkShaderBase * as_SB(SkShader *shader)
Definition: SkShaderBase.h:412
const SkMatrix & localToDevice() const
Definition: SkDevice.h:179
virtual void onClipShader(sk_sp< SkShader >)=0
sk_sp< SkShader > makeInvertAlpha() const
sk_sp< SkShader > makeWithCTM(const SkMatrix &) const
sh
Definition: run_sh.py:10

◆ convertGlyphRunListToSlug()

sk_sp< sktext::gpu::Slug > SkDevice::convertGlyphRunListToSlug ( const sktext::GlyphRunList glyphRunList,
const SkPaint paint 
)
virtual

Reimplemented in skgpu::ganesh::Device, and GlyphTrackingDevice.

Definition at line 483 of file SkDevice.cpp.

484 {
485 return nullptr;
486}

◆ createDevice()

virtual sk_sp< SkDevice > SkDevice::createDevice ( const CreateInfo ,
const SkPaint  
)
inlinevirtual

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 in SkBitmapDevice, skgpu::ganesh::Device, skgpu::graphite::Device, SkPDFDevice, and GlyphTrackingDevice.

Definition at line 322 of file SkDevice.h.

322{ return nullptr; }

◆ createImageFilteringBackend()

sk_sp< skif::Backend > SkDevice::createImageFilteringBackend ( const SkSurfaceProps surfaceProps,
SkColorType  colorType 
) const
privatevirtual

Definition at line 324 of file SkDevice.cpp.

325 {
327}
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
sk_sp< Backend > MakeRasterBackend(const SkSurfaceProps &surfaceProps, SkColorType colorType)

◆ devClipBounds()

virtual SkIRect SkDevice::devClipBounds ( ) const
pure virtual

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).

Implemented in SkBitmapDevice, SkClipStackDevice, SkNoPixelsDevice, skgpu::ganesh::Device, and skgpu::graphite::Device.

◆ deviceToGlobal()

const SkM44 & SkDevice::deviceToGlobal ( ) const
inline

Return the device's coordinate space transform: this maps from the device's coordinate space into the global canvas' space (or root device space). This includes the translation necessary to account for the device's origin.

Definition at line 186 of file SkDevice.h.

186{ return fDeviceToGlobal; }

◆ drawAnnotation()

virtual void SkDevice::drawAnnotation ( const SkRect ,
const char  [],
SkData  
)
inlinevirtual

Reimplemented in SkPDFDevice, and SkSVGDevice.

Definition at line 399 of file SkDevice.h.

399{}

◆ drawArc()

void SkDevice::drawArc ( const SkArc arc,
const SkPaint paint 
)
virtual

By the time this is called we know that abs(sweepAngle) is in the range [0, 360).

Reimplemented in skgpu::ganesh::Device.

Definition at line 134 of file SkDevice.cpp.

134 {
135 SkPath path;
136 bool isFillNoPathEffect = SkPaint::kFill_Style == paint.getStyle() && !paint.getPathEffect();
137 SkPathPriv::CreateDrawArcPath(&path, arc, isFillNoPathEffect);
138 this->drawPath(path, paint);
139}
virtual void drawPath(const SkPath &path, const SkPaint &paint, bool pathIsMutable=false)=0
@ kFill_Style
set to fill geometry
Definition: SkPaint.h:193
static void CreateDrawArcPath(SkPath *path, const SkArc &arc, bool isFillNoPathEffect)
Definition: SkPath.cpp:3356
Definition: SkPath.h:59
const Paint & paint
Definition: color_source.cc:38
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

◆ drawAsTiledImageRect()

virtual bool SkDevice::drawAsTiledImageRect ( SkCanvas ,
const SkImage ,
const SkRect src,
const SkRect dst,
const SkSamplingOptions ,
const SkPaint ,
SkCanvas::SrcRectConstraint   
)
inlinevirtual

Reimplemented in skgpu::ganesh::Device, and skgpu::graphite::Device.

Definition at line 369 of file SkDevice.h.

375 { return false; }

◆ drawAtlas()

void SkDevice::drawAtlas ( const SkRSXform  xform[],
const SkRect  tex[],
const SkColor  colors[],
int  count,
sk_sp< SkBlender blender,
const SkPaint paint 
)
virtual

Reimplemented in SkBitmapDevice, skgpu::ganesh::Device, and skgpu::graphite::Device.

Definition at line 203 of file SkDevice.cpp.

208 {
209 const int triCount = quadCount << 1;
210 const int vertexCount = triCount * 3;
212 if (colors) {
214 }
216
217 SkPoint* vPos = builder.positions();
218 SkPoint* vTex = builder.texCoords();
219 SkColor* vCol = builder.colors();
220 for (int i = 0; i < quadCount; ++i) {
221 SkPoint tmp[4];
222 xform[i].toQuad(tex[i].width(), tex[i].height(), tmp);
223 vPos = quad_to_tris(vPos, tmp);
224
225 tex[i].toQuad(tmp);
226 vTex = quad_to_tris(vTex, tmp);
227
228 if (colors) {
229 SkOpts::memset32(vCol, colors[i], 6);
230 vCol += 6;
231 }
232 }
233 this->drawVertices(builder.detach().get(), std::move(blender), paint);
234}
uint32_t SkColor
Definition: SkColor.h:37
static SkPoint * quad_to_tris(SkPoint tris[6], const SkPoint quad[4])
Definition: SkDevice.cpp:191
virtual void drawVertices(const SkVertices *, sk_sp< SkBlender >, const SkPaint &, bool skipColorXform=false)=0
@ kHasTexCoords_BuilderFlag
Definition: SkVertices.h:63
@ kHasColors_BuilderFlag
Definition: SkVertices.h:64
@ kTriangles_VertexMode
Definition: SkVertices.h:31
FlutterSemanticsFlag flags
void(* memset32)(uint32_t[], uint32_t, int)
PODArray< SkColor > colors
Definition: SkRecords.h:276
void toQuad(SkScalar width, SkScalar height, SkPoint quad[4]) const
Definition: SkRSXform.cpp:9
void toQuad(SkPoint quad[4]) const
Definition: SkRect.cpp:50

◆ drawBlurredRRect()

virtual bool SkDevice::drawBlurredRRect ( const SkRRect ,
const SkPaint ,
float  deviceSigma 
)
inlinevirtual

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

Reimplemented in skgpu::graphite::Device.

Definition at line 469 of file SkDevice.h.

469 {
470 return false;
471 }

◆ drawCoverageMask()

void SkDevice::drawCoverageMask ( const SkSpecialImage ,
const SkMatrix maskToDevice,
const SkSamplingOptions ,
const SkPaint  
)
virtual

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 in skgpu::graphite::Device.

Definition at line 306 of file SkDevice.cpp.

307 {
308 // This shouldn't be reached; SkCanvas will only call this if
309 // useDrawCoverageMaskForMaskFilters() is overridden to return true.
310 SK_ABORT("Must override if useDrawCoverageMaskForMaskFilters() is true");
311}
#define SK_ABORT(message,...)
Definition: SkAssert.h:70

◆ drawDevice()

void SkDevice::drawDevice ( SkDevice device,
const SkSamplingOptions sampling,
const SkPaint paint 
)
virtual

The SkDevice passed will be an SkDevice which was returned by a call to onCreateDevice on this device with kNeverTile_TileExpectation.

The default implementation calls snapSpecial() and drawSpecial() with the relative transform from the input device to this device. The provided SkPaint cannot have a mask filter or image filter, and any shader is ignored.

Reimplemented in SkNoPixelsDevice, skgpu::ganesh::Device, and SkPDFDevice.

Definition at line 329 of file SkDevice.cpp.

331 {
332 sk_sp<SkSpecialImage> deviceImage = device->snapSpecial();
333 if (deviceImage) {
334 // SkCanvas only calls drawDevice() when there are no filters (so the transform is pixel
335 // aligned). As such it can be drawn without clamping.
336 SkMatrix relativeTransform = device->getRelativeTransform(*this);
337 const bool strict = sampling != SkFilterMode::kNearest ||
338 !relativeTransform.isTranslate() ||
339 !SkScalarIsInt(relativeTransform.getTranslateX()) ||
340 !SkScalarIsInt(relativeTransform.getTranslateY());
341 this->drawSpecial(deviceImage.get(), relativeTransform, sampling, paint,
344 }
345}
static bool SkScalarIsInt(SkScalar x)
Definition: SkScalar.h:80
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
Definition: SkCanvas.h:1542
@ kFast_SrcRectConstraint
sample outside bounds; faster
Definition: SkCanvas.h:1543
virtual void drawSpecial(SkSpecialImage *, const SkMatrix &localToDevice, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint constraint=SkCanvas::kStrict_SrcRectConstraint)
Definition: SkDevice.cpp:304
SkScalar getTranslateY() const
Definition: SkMatrix.h:452
bool isTranslate() const
Definition: SkMatrix.h:248
SkScalar getTranslateX() const
Definition: SkMatrix.h:445
T * get() const
Definition: SkRefCnt.h:303
VkDevice device
Definition: main.cc:53
SkSamplingOptions sampling
Definition: SkRecords.h:337

◆ drawDrawable()

void SkDevice::drawDrawable ( SkCanvas canvas,
SkDrawable drawable,
const SkMatrix matrix 
)
virtual

Reimplemented in skgpu::ganesh::Device, and skgpu::graphite::Device.

Definition at line 298 of file SkDevice.cpp.

298 {
299 drawable->draw(canvas, matrix);
300}
void draw(SkCanvas *, const SkMatrix *=nullptr)
Definition: SkDrawable.cpp:43
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258

◆ drawDRRect()

void SkDevice::drawDRRect ( const SkRRect outer,
const SkRRect inner,
const SkPaint paint 
)
virtual

Reimplemented in skgpu::ganesh::Device.

Definition at line 141 of file SkDevice.cpp.

142 {
143 SkPath path;
144 path.addRRect(outer);
145 path.addRRect(inner);
146 path.setFillType(SkPathFillType::kEvenOdd);
147 path.setIsVolatile(true);
148
149 this->drawPath(path, paint, true);
150}

◆ drawEdgeAAImageSet()

void SkDevice::drawEdgeAAImageSet ( const SkCanvas::ImageSetEntry  images[],
int  count,
const SkPoint  dstClips[],
const SkMatrix  preViewMatrices[],
const SkSamplingOptions sampling,
const SkPaint paint,
SkCanvas::SrcRectConstraint  constraint 
)
virtual

Reimplemented in skgpu::ganesh::Device, and skgpu::graphite::Device.

Definition at line 253 of file SkDevice.cpp.

256 {
257 SkASSERT(paint.getStyle() == SkPaint::kFill_Style);
258 SkASSERT(!paint.getPathEffect());
259
260 SkPaint entryPaint = paint;
261 const SkM44 baseLocalToDevice = this->localToDevice44();
262 int clipIndex = 0;
263 for (int i = 0; i < count; ++i) {
264 // TODO: Handle per-edge AA. Right now this mirrors the SkiaRenderer component of Chrome
265 // which turns off antialiasing unless all four edges should be antialiased. This avoids
266 // seaming in tiled composited layers.
267 entryPaint.setAntiAlias(images[i].fAAFlags == SkCanvas::kAll_QuadAAFlags);
268 entryPaint.setAlphaf(paint.getAlphaf() * images[i].fAlpha);
269
270 SkASSERT(images[i].fMatrixIndex < 0 || preViewMatrices);
271 if (images[i].fMatrixIndex >= 0) {
272 this->setLocalToDevice(baseLocalToDevice *
273 SkM44(preViewMatrices[images[i].fMatrixIndex]));
274 }
275
276 SkASSERT(!images[i].fHasClip || dstClips);
277 if (images[i].fHasClip) {
278 // Since drawImageRect requires a srcRect, the dst clip is implemented as a true clip
279 this->pushClipStack();
281 clipPath.addPoly(dstClips + clipIndex, 4, true);
282 this->clipPath(clipPath, SkClipOp::kIntersect, entryPaint.isAntiAlias());
283 clipIndex += 4;
284 }
285 this->drawImageRect(images[i].fImage.get(), &images[i].fSrcRect, images[i].fDstRect,
286 sampling, entryPaint, constraint);
287 if (images[i].fHasClip) {
288 this->popClipStack();
289 }
290 if (images[i].fMatrixIndex >= 0) {
291 this->setLocalToDevice(baseLocalToDevice);
292 }
293 }
294}
int count
Definition: FontMgrTest.cpp:50
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kAll_QuadAAFlags
Definition: SkCanvas.h:1665
virtual void clipPath(const SkPath &path, SkClipOp op, bool aa)=0
void setLocalToDevice(const SkM44 &localToDevice)
Definition: SkDevice.h:211
virtual void popClipStack()=0
virtual void pushClipStack()=0
virtual void drawImageRect(const SkImage *, const SkRect *src, const SkRect &dst, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint)=0
const SkM44 & localToDevice44() const
Definition: SkDevice.h:178
Definition: SkM44.h:150
void setAntiAlias(bool aa)
Definition: SkPaint.h:170
bool isAntiAlias() const
Definition: SkPaint.h:162
void setAlphaf(float a)
Definition: SkPaint.cpp:130
std::array< MockImage, 3 > images
Definition: mock_vulkan.cc:41
PODArray< SkPoint > dstClips
Definition: SkRecords.h:364
PODArray< SkMatrix > preViewMatrices
Definition: SkRecords.h:365

◆ drawEdgeAAQuad()

void SkDevice::drawEdgeAAQuad ( const SkRect rect,
const SkPoint  clip[4],
SkCanvas::QuadAAFlags  aaFlags,
const SkColor4f color,
SkBlendMode  mode 
)
virtual

Reimplemented in skgpu::ganesh::Device, and skgpu::graphite::Device.

Definition at line 236 of file SkDevice.cpp.

237 {
239 paint.setColor4f(color);
240 paint.setBlendMode(mode);
241 paint.setAntiAlias(aa == SkCanvas::kAll_QuadAAFlags);
242
243 if (clip) {
244 // Draw the clip directly as a quad since it's a filled color with no local coords
246 clipPath.addPoly(clip, 4, true);
247 this->drawPath(clipPath, paint);
248 } else {
249 this->drawRect(r, paint);
250 }
251}
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
virtual void drawRect(const SkRect &r, const SkPaint &paint)=0
DlColor color
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
Definition: switches.h:228

◆ drawFilteredImage()

void SkDevice::drawFilteredImage ( const skif::Mapping mapping,
SkSpecialImage src,
SkColorType  ct,
const SkImageFilter filter,
const SkSamplingOptions sampling,
const SkPaint paint 
)

Evaluate 'filter' and draw the final output into this device using 'paint'. The 'mapping' defines the parameter-to-layer space transform used to evaluate the image filter on 'src', and the layer-to-device space transform that is used to draw the result into this device. Since 'mapping' fully specifies the transform, this draw function ignores the current local-to-device matrix (i.e. just like drawSpecial and drawDevice).

The final paint must not have an image filter or mask filter set on it; a shader is ignored. The provided color type will be used for any intermediate surfaces that need to be created as part of filter evaluation. It does not have to be src's color type or this Device's type.

Definition at line 347 of file SkDevice.cpp.

352 {
353 SkASSERT(!paint.getImageFilter() && !paint.getMaskFilter());
354
355 skif::LayerSpace<SkIRect> targetOutput = mapping.deviceToLayer(
357
360 }
361
363 skif::Context ctx{this->createImageFilteringBackend(src ? src->props() : this->surfaceProps(),
364 colorType),
365 mapping,
366 targetOutput,
368 this->imageInfo().colorSpace(),
369 &stats};
370
373 stats.reportStats();
374 if (result) {
375 SkMatrix deviceMatrixWithOffset = mapping.layerToDevice();
376 deviceMatrixWithOffset.preTranslate(offset.fX, offset.fY);
377 this->drawSpecial(result.get(), deviceMatrixWithOffset, sampling, paint);
378 }
379}
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
@ kUnknown_SkColorType
uninitialized
Definition: SkColorType.h:20
static SkImageFilter_Base * as_IFB(SkImageFilter *filter)
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
const SkImageInfo & imageInfo() const
Definition: SkDevice.h:117
virtual sk_sp< skif::Backend > createImageFilteringBackend(const SkSurfaceProps &surfaceProps, SkColorType colorType) const
Definition: SkDevice.cpp:324
virtual SkIRect devClipBounds() const =0
skif::FilterResult filterImage(const skif::Context &context) const
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:263
sk_sp< SkSpecialImage > imageAndOffset(const Context &ctx, SkIPoint *offset) const
const SkMatrix & deviceToLayer() const
const SkMatrix & layerToDevice() const
GAsyncResult * result
dictionary stats
Definition: malisc.py:20
SeparatedVector2 offset
SkColorSpace * colorSpace() const

◆ drawGlyphRunList()

void SkDevice::drawGlyphRunList ( SkCanvas canvas,
const sktext::GlyphRunList glyphRunList,
const SkPaint paint 
)

Definition at line 426 of file SkDevice.cpp.

428 {
429 if (!this->localToDevice().isFinite()) {
430 return;
431 }
432
433 if (!glyphRunList.hasRSXForm()) {
434 this->onDrawGlyphRunList(canvas, glyphRunList, paint);
435 } else {
436 this->simplifyGlyphRunRSXFormAndRedraw(canvas, glyphRunList, paint);
437 }
438}
static bool isFinite(const SkRect &r)
Definition: MathBench.cpp:230
virtual void onDrawGlyphRunList(SkCanvas *, const sktext::GlyphRunList &, const SkPaint &paint)=0
bool hasRSXForm() const
Definition: GlyphRun.h:105

◆ drawImageLattice()

void SkDevice::drawImageLattice ( const SkImage image,
const SkCanvas::Lattice lattice,
const SkRect dst,
SkFilterMode  filter,
const SkPaint paint 
)
virtual

Reimplemented in skgpu::ganesh::Device, and skgpu::graphite::Device.

Definition at line 163 of file SkDevice.cpp.

164 {
165 SkLatticeIter iter(lattice, dst);
166
167 SkRect srcR, dstR;
168 SkColor c;
169 bool isFixedColor = false;
171
172 while (iter.next(&srcR, &dstR, &isFixedColor, &c)) {
173 // TODO: support this fast-path for GPU images
174 if (isFixedColor || (srcR.width() <= 1.0f && srcR.height() <= 1.0f &&
175 image->readPixels(nullptr, info, &c, 4, srcR.fLeft, srcR.fTop))) {
176 // Fast draw with drawRect, if this is a patch containing a single color
177 // or if this is a patch containing a single pixel.
178 if (0 != c || !paint.isSrcOver()) {
179 SkPaint paintCopy(paint);
180 int alpha = SkAlphaMul(SkColorGetA(c), SkAlpha255To256(paint.getAlpha()));
181 paintCopy.setColor(SkColorSetA(c, alpha));
182 this->drawRect(dstR, paintCopy);
183 }
184 } else {
185 this->drawImageRect(image, &srcR, dstR, SkSamplingOptions(filter), paint,
187 }
188 }
189}
kUnpremul_SkAlphaType
#define SkAlphaMul(value, alpha256)
Definition: SkColorPriv.h:34
static unsigned SkAlpha255To256(U8CPU alpha)
Definition: SkColorPriv.h:24
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
static constexpr SkColor SkColorSetA(SkColor c, U8CPU a)
Definition: SkColor.h:82
#define SkColorGetA(color)
Definition: SkColor.h:61
bool readPixels(GrDirectContext *context, const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY, CachingHint cachingHint=kAllow_CachingHint) const
Definition: SkImage.cpp:42
sk_sp< const SkImage > image
Definition: SkRecords.h:269
dst
Definition: cp.py:12
SkSamplingOptions(SkFilterMode::kLinear))
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkScalar fLeft
smaller x-axis bounds
Definition: extension.cpp:14
constexpr float height() const
Definition: SkRect.h:769
constexpr float width() const
Definition: SkRect.h:762
SkScalar fTop
smaller y-axis bounds
Definition: extension.cpp:15

◆ drawImageRect()

virtual void SkDevice::drawImageRect ( const SkImage ,
const SkRect src,
const SkRect dst,
const SkSamplingOptions ,
const SkPaint ,
SkCanvas::SrcRectConstraint   
)
pure virtual

◆ drawMesh()

virtual void SkDevice::drawMesh ( const SkMesh mesh,
sk_sp< SkBlender ,
const SkPaint  
)
pure virtual

◆ drawOval()

virtual void SkDevice::drawOval ( const SkRect oval,
const SkPaint paint 
)
pure virtual

◆ drawPaint()

virtual void SkDevice::drawPaint ( const SkPaint paint)
pure virtual

◆ drawPatch()

void SkDevice::drawPatch ( const SkPoint  cubics[12],
const SkColor  colors[4],
const SkPoint  texCoords[4],
sk_sp< SkBlender blender,
const SkPaint paint 
)
virtual

Definition at line 152 of file SkDevice.cpp.

154 {
156 auto vertices = SkPatchUtils::MakeVertices(cubics, colors, texCoords, lod.width(), lod.height(),
157 this->imageInfo().colorSpace());
158 if (vertices) {
159 this->drawVertices(vertices.get(), std::move(blender), paint);
160 }
161}
static sk_sp< SkVertices > MakeVertices(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], int lodX, int lodY, SkColorSpace *colorSpace=nullptr)
static SkISize GetLevelOfDetail(const SkPoint cubics[12], const SkMatrix *matrix)
Definition: SkSize.h:16
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37

◆ drawPath()

virtual void SkDevice::drawPath ( const SkPath path,
const SkPaint paint,
bool  pathIsMutable = false 
)
pure virtual

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.

Implemented in SkBitmapDevice, SkNoPixelsDevice, SkPDFDevice, skgpu::ganesh::Device, skgpu::graphite::Device, and SkSVGDevice.

◆ drawPoints()

virtual void SkDevice::drawPoints ( SkCanvas::PointMode  mode,
size_t  count,
const  SkPoint[],
const SkPaint paint 
)
pure virtual

◆ drawRect()

virtual void SkDevice::drawRect ( const SkRect r,
const SkPaint paint 
)
pure virtual

◆ drawRegion()

void SkDevice::drawRegion ( const SkRegion r,
const SkPaint paint 
)
virtual

Reimplemented in skgpu::ganesh::Device.

Definition at line 113 of file SkDevice.cpp.

113 {
114 const SkMatrix& localToDevice = this->localToDevice();
115 bool isNonTranslate = localToDevice.getType() & ~(SkMatrix::kTranslate_Mask);
116 bool complexPaint = paint.getStyle() != SkPaint::kFill_Style || paint.getMaskFilter() ||
117 paint.getPathEffect();
118 bool antiAlias = paint.isAntiAlias() && (!is_int(localToDevice.getTranslateX()) ||
120 if (isNonTranslate || complexPaint || antiAlias) {
121 SkPath path;
123 path.setIsVolatile(true);
124 return this->drawPath(path, paint, true);
125 }
126
128 while (!it.done()) {
129 this->drawRect(SkRect::Make(it.rect()), paint);
130 it.next();
131 }
132}
static bool is_int(float x)
Definition: SkDevice.cpp:109
@ kTranslate_Mask
translation SkMatrix
Definition: SkMatrix.h:193
TypeMask getType() const
Definition: SkMatrix.h:207
bool getBoundaryPath(SkPath *path) const
ClipOpAndAA opAA SkRegion region
Definition: SkRecords.h:238
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669

◆ drawRRect()

virtual void SkDevice::drawRRect ( const SkRRect rr,
const SkPaint paint 
)
pure virtual

◆ drawShadow()

void SkDevice::drawShadow ( const SkPath path,
const SkDrawShadowRec rec 
)
virtual

Reimplemented in skgpu::ganesh::Device, and skgpu::graphite::Device.

Definition at line 593 of file SkShadowUtils.cpp.

593 {
594 if (!validate_rec(rec)) {
595 return;
596 }
597
598 SkMatrix viewMatrix = this->localToDevice();
600
601#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
602 auto drawVertsProc = [this](const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint,
603 SkScalar tx, SkScalar ty, bool hasPerspective) {
604 if (vertices->priv().vertexCount()) {
605 // For perspective shadows we've already computed the shadow in world space,
606 // and we can't translate it without changing it. Otherwise we concat the
607 // change in translation from the cached version.
609 this,
610 hasPerspective ? SkMatrix::I()
611 : this->localToDevice() * SkMatrix::Translate(tx, ty));
612 // The vertex colors for a tesselated shadow polygon are always either opaque black
613 // or transparent and their real contribution to the final blended color is via
614 // their alpha. We can skip expensive per-vertex color conversion for this.
615 this->drawVertices(vertices, SkBlender::Mode(mode), paint, /*skipColorXform=*/true);
616 }
617 };
618
619 ShadowedPath shadowedPath(&path, &viewMatrix);
620
621 bool tiltZPlane = tilted(rec.fZPlaneParams);
624 !path.isConvex();
625 bool uncached = tiltZPlane || path.isVolatile();
626#endif
628
629 SkPoint3 zPlaneParams = rec.fZPlaneParams;
630 SkPoint3 devLightPos = rec.fLightPos;
631 if (!directional) {
632 viewMatrix.mapPoints((SkPoint*)&devLightPos.fX, 1);
633 }
634 float lightRadius = rec.fLightRadius;
635
636 if (SkColorGetA(rec.fAmbientColor) > 0) {
637 bool success = false;
638#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
639 if (uncached && !useBlur) {
641 zPlaneParams,
642 transparent);
643 if (vertices) {
645 // Run the vertex color through a GaussianColorFilter and then modulate the
646 // grayscale result of that against our 'color' param.
647 paint.setColorFilter(
651 // The vertex colors for a tesselated shadow polygon are always either opaque black
652 // or transparent and their real contribution to the final blended color is via
653 // their alpha. We can skip expensive per-vertex color conversion for this.
654 this->drawVertices(vertices.get(),
656 paint,
657 /*skipColorXform=*/true);
658 success = true;
659 }
660 }
661
662 if (!success && !useBlur) {
663 AmbientVerticesFactory factory;
664 factory.fOccluderHeight = zPlaneParams.fZ;
665 factory.fTransparent = transparent;
666 if (viewMatrix.hasPerspective()) {
667 factory.fOffset.set(0, 0);
668 } else {
669 factory.fOffset.fX = viewMatrix.getTranslateX();
670 factory.fOffset.fY = viewMatrix.getTranslateY();
671 }
672
673 success = draw_shadow(factory, drawVertsProc, shadowedPath, rec.fAmbientColor);
674 }
675#endif // !defined(SK_ENABLE_OPTIMIZE_SIZE)
676
677 // All else has failed, draw with blur
678 if (!success) {
679 // Pretransform the path to avoid transforming the stroke, below.
680 SkPath devSpacePath;
681 path.transform(viewMatrix, &devSpacePath);
682 devSpacePath.setIsVolatile(true);
683
684 // The tesselator outsets by AmbientBlurRadius (or 'r') to get the outer ring of
685 // the tesselation, and sets the alpha on the path to 1/AmbientRecipAlpha (or 'a').
686 //
687 // We want to emulate this with a blur. The full blur width (2*blurRadius or 'f')
688 // can be calculated by interpolating:
689 //
690 // original edge outer edge
691 // | |<---------- r ------>|
692 // |<------|--- f -------------->|
693 // | | |
694 // alpha = 1 alpha = a alpha = 0
695 //
696 // Taking ratios, f/1 = r/a, so f = r/a and blurRadius = f/2.
697 //
698 // We now need to outset the path to place the new edge in the center of the
699 // blur region:
700 //
701 // original new
702 // | |<------|--- r ------>|
703 // |<------|--- f -|------------>|
704 // | |<- o ->|<--- f/2 --->|
705 //
706 // r = o + f/2, so o = r - f/2
707 //
708 // We outset by using the stroker, so the strokeWidth is o/2.
709 //
710 SkScalar devSpaceOutset = SkDrawShadowMetrics::AmbientBlurRadius(zPlaneParams.fZ);
711 SkScalar oneOverA = SkDrawShadowMetrics::AmbientRecipAlpha(zPlaneParams.fZ);
712 SkScalar blurRadius = 0.5f*devSpaceOutset*oneOverA;
713 SkScalar strokeWidth = 0.5f*(devSpaceOutset - blurRadius);
714
715 // Now draw with blur
717 paint.setColor(rec.fAmbientColor);
718 paint.setStrokeWidth(strokeWidth);
720 SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(blurRadius);
721 bool respectCTM = false;
722 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, sigma, respectCTM));
723 this->drawPath(devSpacePath, paint);
724 }
725 }
726
727 if (SkColorGetA(rec.fSpotColor) > 0) {
728 bool success = false;
729#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
730 if (uncached && !useBlur) {
732 zPlaneParams,
733 devLightPos, lightRadius,
734 transparent,
735 directional);
736 if (vertices) {
738 // Run the vertex color through a GaussianColorFilter and then modulate the
739 // grayscale result of that against our 'color' param.
740 paint.setColorFilter(
744 // The vertex colors for a tesselated shadow polygon are always either opaque black
745 // or transparent and their real contribution to the final blended color is via
746 // their alpha. We can skip expensive per-vertex color conversion for this.
747 this->drawVertices(vertices.get(),
749 paint,
750 /*skipColorXform=*/true);
751 success = true;
752 }
753 }
754
755 if (!success && !useBlur) {
756 SpotVerticesFactory factory;
757 factory.fOccluderHeight = zPlaneParams.fZ;
758 factory.fDevLightPos = devLightPos;
759 factory.fLightRadius = lightRadius;
760
761 SkPoint center = SkPoint::Make(path.getBounds().centerX(), path.getBounds().centerY());
762 factory.fLocalCenter = center;
763 viewMatrix.mapPoints(&center, 1);
764 SkScalar radius, scale;
766 SkDrawShadowMetrics::GetDirectionalParams(zPlaneParams.fZ, devLightPos.fX,
767 devLightPos.fY, devLightPos.fZ,
768 lightRadius, &radius, &scale,
769 &factory.fOffset);
770 } else {
771 SkDrawShadowMetrics::GetSpotParams(zPlaneParams.fZ, devLightPos.fX - center.fX,
772 devLightPos.fY - center.fY, devLightPos.fZ,
773 lightRadius, &radius, &scale, &factory.fOffset);
774 }
775
776 SkRect devBounds;
777 viewMatrix.mapRect(&devBounds, path.getBounds());
778 if (transparent ||
779 SkTAbs(factory.fOffset.fX) > 0.5f*devBounds.width() ||
780 SkTAbs(factory.fOffset.fY) > 0.5f*devBounds.height()) {
781 // if the translation of the shadow is big enough we're going to end up
782 // filling the entire umbra, we can treat these as all the same
783 if (directional) {
784 factory.fOccluderType =
785 SpotVerticesFactory::OccluderType::kDirectionalTransparent;
786 } else {
787 factory.fOccluderType = SpotVerticesFactory::OccluderType::kPointTransparent;
788 }
789 } else if (directional) {
790 factory.fOccluderType = SpotVerticesFactory::OccluderType::kDirectional;
791 } else if (factory.fOffset.length()*scale + scale < radius) {
792 // if we don't translate more than the blur distance, can assume umbra is covered
793 factory.fOccluderType = SpotVerticesFactory::OccluderType::kPointOpaqueNoUmbra;
794 } else if (path.isConvex()) {
795 factory.fOccluderType = SpotVerticesFactory::OccluderType::kPointOpaquePartialUmbra;
796 } else {
797 factory.fOccluderType = SpotVerticesFactory::OccluderType::kPointTransparent;
798 }
799 // need to add this after we classify the shadow
800 factory.fOffset.fX += viewMatrix.getTranslateX();
801 factory.fOffset.fY += viewMatrix.getTranslateY();
802
804#ifdef DEBUG_SHADOW_CHECKS
805 switch (factory.fOccluderType) {
806 case SpotVerticesFactory::OccluderType::kPointTransparent:
807 color = 0xFFD2B48C; // tan for transparent
808 break;
809 case SpotVerticesFactory::OccluderType::kPointOpaquePartialUmbra:
810 color = 0xFFFFA500; // orange for opaque
811 break;
812 case SpotVerticesFactory::OccluderType::kPointOpaqueNoUmbra:
813 color = 0xFFE5E500; // corn yellow for covered
814 break;
815 case SpotVerticesFactory::OccluderType::kDirectional:
816 case SpotVerticesFactory::OccluderType::kDirectionalTransparent:
817 color = 0xFF550000; // dark red for directional
818 break;
819 }
820#endif
821 success = draw_shadow(factory, drawVertsProc, shadowedPath, color);
822 }
823#endif // !defined(SK_ENABLE_OPTIMIZE_SIZE)
824
825 // All else has failed, draw with blur
826 if (!success) {
827 SkMatrix shadowMatrix;
828 SkScalar radius;
829 if (!SkDrawShadowMetrics::GetSpotShadowTransform(devLightPos, lightRadius,
830 viewMatrix, zPlaneParams,
831 path.getBounds(), directional,
832 &shadowMatrix, &radius)) {
833 return;
834 }
835 SkAutoDeviceTransformRestore adr2(this, shadowMatrix);
836
838 paint.setColor(rec.fSpotColor);
840 bool respectCTM = false;
841 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, sigma, respectCTM));
842 this->drawPath(path, paint);
843 }
844 }
845}
static const int strokeWidth
Definition: BlurTest.cpp:60
SkBlendMode
Definition: SkBlendMode.h:38
@ kModulate
r = s*d
@ kNormal_SkBlurStyle
fuzzy inside and outside
Definition: SkBlurTypes.h:12
static bool tilted(const SkPoint3 &zPlaneParams)
static bool validate_rec(const SkDrawShadowRec &rec)
@ kDirectionalLight_ShadowFlag
Definition: SkShadowUtils.h:31
@ kConcaveBlurOnly_ShadowFlag
Definition: SkShadowUtils.h:33
@ kTransparentOccluder_ShadowFlag
Definition: SkShadowUtils.h:27
static T SkTAbs(T value)
Definition: SkTemplates.h:43
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
static SkScalar center(float pos0, float pos1)
static sk_sp< SkBlender > Mode(SkBlendMode mode)
static SkScalar SK_SPI ConvertRadiusToSigma(SkScalar radius)
Definition: SkBlurMask.cpp:39
static sk_sp< SkColorFilter > MakeGaussian()
sk_sp< SkColorFilter > makeComposed(sk_sp< SkColorFilter > inner) const
static sk_sp< SkColorFilter > Blend(const SkColor4f &c, sk_sp< SkColorSpace >, SkBlendMode mode)
static sk_sp< SkMaskFilter > MakeBlur(SkBlurStyle style, SkScalar sigma, bool respectCTM=true)
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.h:91
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
Definition: SkMatrix.cpp:770
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
bool hasPerspective() const
Definition: SkMatrix.h:312
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
Definition: SkMatrix.cpp:1141
@ kStrokeAndFill_Style
sets to stroke and fill geometry
Definition: SkPaint.h:195
SkPath & setIsVolatile(bool isVolatile)
Definition: SkPath.h:370
int vertexCount() const
SkVerticesPriv priv()
float SkScalar
Definition: extension.cpp:12
bool GetSpotShadowTransform(const SkPoint3 &lightPos, SkScalar lightRadius, const SkMatrix &ctm, const SkPoint3 &zPlaneParams, const SkRect &pathBounds, bool directional, SkMatrix *shadowTransform, SkScalar *radius)
SkScalar AmbientRecipAlpha(SkScalar height)
void GetDirectionalParams(SkScalar occluderZ, SkScalar lightX, SkScalar lightY, SkScalar lightZ, SkScalar lightRadius, SkScalar *blurRadius, SkScalar *scale, SkVector *translate)
SkScalar AmbientBlurRadius(SkScalar height)
void GetSpotParams(SkScalar occluderZ, SkScalar lightX, SkScalar lightY, SkScalar lightZ, SkScalar lightRadius, SkScalar *blurRadius, SkScalar *scale, SkVector *translate)
sk_sp< SkVertices > MakeAmbient(const SkPath &path, const SkMatrix &ctm, const SkPoint3 &zPlane, bool transparent)
sk_sp< SkVertices > MakeSpot(const SkPath &path, const SkMatrix &ctm, const SkPoint3 &zPlane, const SkPoint3 &lightPos, SkScalar lightRadius, bool transparent, bool directional)
void draw_shadow(SkCanvas *canvas, const SkPath &path, SkScalar height, SkColor color, SkPoint3 lightPos, SkScalar lightR, bool isAmbient, uint32_t flags)
Definition: shadowutils.cpp:28
const Scalar scale
SkPoint3 fZPlaneParams
SkScalar fX
Definition: SkPoint3.h:16
SkScalar fZ
Definition: SkPoint3.h:16
SkScalar fY
Definition: SkPoint3.h:16
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173

◆ drawSlug()

void SkDevice::drawSlug ( SkCanvas ,
const sktext::gpu::Slug slug,
const SkPaint paint 
)
virtual

Reimplemented in SkNoPixelsDevice, and skgpu::ganesh::Device.

Definition at line 488 of file SkDevice.cpp.

488 {
489 SK_ABORT("Slug drawing not supported.");
490}

◆ drawSpecial()

void SkDevice::drawSpecial ( SkSpecialImage ,
const SkMatrix localToDevice,
const SkSamplingOptions ,
const SkPaint ,
SkCanvas::SrcRectConstraint  constraint = SkCanvas::kStrict_SrcRectConstraint 
)
virtual

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 in SkBitmapDevice, SkPDFDevice, skgpu::ganesh::Device, and skgpu::graphite::Device.

Definition at line 304 of file SkDevice.cpp.

305 {}

◆ drawVertices()

virtual void SkDevice::drawVertices ( const SkVertices ,
sk_sp< SkBlender ,
const SkPaint ,
bool  skipColorXform = false 
)
pure virtual

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

Implemented in SkBitmapDevice, SkNoPixelsDevice, skgpu::ganesh::Device, skgpu::graphite::Device, SkPDFDevice, and SkSVGDevice.

◆ getGlobalBounds() [1/2]

SkIRect SkDevice::getGlobalBounds ( ) const
inline

Definition at line 230 of file SkDevice.h.

230 {
232 this->getGlobalBounds(&bounds);
233 return bounds;
234 }
SkIRect bounds() const
Definition: SkDevice.h:125
SkIRect getGlobalBounds() const
Definition: SkDevice.h:230
Definition: SkRect.h:32

◆ getGlobalBounds() [2/2]

void SkDevice::getGlobalBounds ( SkIRect bounds) const
inline

Return the bounds of the device in the coordinate space of the root canvas. The root device will have its top-left at 0,0, but other devices such as those associated with saveLayer may have a non-zero origin.

Definition at line 225 of file SkDevice.h.

225 {
227 *bounds = SkMatrixPriv::MapRect(fDeviceToGlobal, SkRect::Make(this->bounds())).roundOut();
228 }
static SkRect MapRect(const SkM44 &m, const SkRect &r)
Definition: SkM44.cpp:216
void roundOut(SkIRect *dst) const
Definition: SkRect.h:1241

◆ getOrigin()

SkIPoint SkDevice::getOrigin ( ) const

DEPRECATED: This asserts that 'getDeviceToGlobal' is a translation matrix with integer components. In the future some SkDevices will have more complex device-to-global transforms, so getDeviceToGlobal() or getRelativeTransform() should be used instead.

Definition at line 91 of file SkDevice.cpp.

91 {
92 // getOrigin() is deprecated, the old origin has been moved into the fDeviceToGlobal matrix.
93 // This extracts the origin from the matrix, but asserts that a more complicated coordinate
94 // space hasn't been set of the device. This function can be removed once existing use cases
95 // have been updated to use the device-to-global matrix instead or have themselves been removed
96 // (e.g. Android's device-space clip regions are going away, and are not compatible with the
97 // generalized device coordinate system).
99 return SkIPoint::Make(SkScalarFloorToInt(fDeviceToGlobal.rc(0, 3)),
100 SkScalarFloorToInt(fDeviceToGlobal.rc(1, 3)));
101}
#define SkScalarFloorToInt(x)
Definition: SkScalar.h:35
bool isPixelAlignedToGlobal() const
Definition: SkDevice.cpp:82
SkScalar rc(int r, int c) const
Definition: SkM44.h:261
static constexpr SkIPoint Make(int32_t x, int32_t y)
Definition: SkPoint_impl.h:38

◆ getRasterHandle()

virtual void * SkDevice::getRasterHandle ( ) const
inlinevirtual

Reimplemented in SkBitmapDevice.

Definition at line 282 of file SkDevice.h.

282{ return nullptr; }

◆ getRelativeTransform()

SkMatrix SkDevice::getRelativeTransform ( const SkDevice dstDevice) const

Get the transformation from this device's coordinate system to the provided device space. This transform can be used to draw this device into the provided device, such that once that device is drawn to the root device, the net effect will be that this device's contents have been transformed by the global CTM.

Definition at line 103 of file SkDevice.cpp.

103 {
104 // To get the transform from this space to the other device's, transform from our space to
105 // global and then from global to the other device.
106 return (dstDevice.fGlobalToDevice * fDeviceToGlobal).asM33();
107}

◆ globalToDevice()

const SkM44 & SkDevice::globalToDevice ( ) const
inline

Return the inverse of getDeviceToGlobal(), mapping from the global canvas' space (or root device space) into this device's coordinate space.

Definition at line 191 of file SkDevice.h.

191{ return fGlobalToDevice; }

◆ height()

int SkDevice::height ( ) const
inline

Definition at line 120 of file SkDevice.h.

120{ return this->imageInfo().height(); }
int height() const
Definition: SkImageInfo.h:371

◆ imageInfo()

const SkImageInfo & SkDevice::imageInfo ( ) const
inline

Return ImageInfo for this device. If the canvas is not backed by pixels (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.

Definition at line 117 of file SkDevice.h.

117{ return fInfo; }

◆ isClipAntiAliased()

virtual bool SkDevice::isClipAntiAliased ( ) const
pure virtual

◆ isClipEmpty()

virtual bool SkDevice::isClipEmpty ( ) const
pure virtual

◆ isClipRect()

virtual bool SkDevice::isClipRect ( ) const
pure virtual

◆ isClipWideOpen()

virtual bool SkDevice::isClipWideOpen ( ) const
pure virtual

◆ isNoPixelsDevice()

virtual bool SkDevice::isNoPixelsDevice ( ) const
inlinevirtual

Reimplemented in SkNoPixelsDevice.

Definition at line 280 of file SkDevice.h.

280{ return false; }

◆ isOpaque()

bool SkDevice::isOpaque ( ) const
inline

Definition at line 122 of file SkDevice.h.

122{ return this->imageInfo().isOpaque(); }
bool isOpaque() const
Definition: SkImageInfo.h:415

◆ isPixelAlignedToGlobal()

bool SkDevice::isPixelAlignedToGlobal ( ) const

Returns true when this device's pixel grid is axis aligned with the global coordinate space, and any relative translation between the two spaces is in integer pixel units.

Definition at line 82 of file SkDevice.cpp.

82 {
83 // pixelAligned is set to the identity + integer translation of the device-to-global matrix.
84 // If they are equal then the device is by definition pixel aligned.
85 SkM44 pixelAligned = SkM44();
86 pixelAligned.setRC(0, 3, SkScalarFloorToScalar(fDeviceToGlobal.rc(0, 3)));
87 pixelAligned.setRC(1, 3, SkScalarFloorToScalar(fDeviceToGlobal.rc(1, 3)));
88 return pixelAligned == fDeviceToGlobal;
89}
#define SkScalarFloorToScalar(x)
Definition: SkScalar.h:30
void setRC(int r, int c, SkScalar value)
Definition: SkM44.h:266

◆ localToDevice()

const SkMatrix & SkDevice::localToDevice ( ) const
inline

Definition at line 179 of file SkDevice.h.

179{ return fLocalToDevice33; }

◆ localToDevice44()

const SkM44 & SkDevice::localToDevice44 ( ) const
inline

Returns the transformation that maps from the local space to the device's coordinate space.

Definition at line 178 of file SkDevice.h.

178{ return fLocalToDevice; }

◆ makeSpecial() [1/2]

sk_sp< SkSpecialImage > SkDevice::makeSpecial ( const SkBitmap )
protectedvirtual

Reimplemented in SkBitmapDevice, skgpu::ganesh::Device, and SkPDFDevice.

Definition at line 313 of file SkDevice.cpp.

313{ return nullptr; }

◆ makeSpecial() [2/2]

sk_sp< SkSpecialImage > SkDevice::makeSpecial ( const SkImage )
protectedvirtual

Reimplemented in SkBitmapDevice, skgpu::ganesh::Device, and SkPDFDevice.

Definition at line 314 of file SkDevice.cpp.

314{ return nullptr; }

◆ makeSurface()

sk_sp< SkSurface > SkDevice::makeSurface ( const SkImageInfo ,
const SkSurfaceProps  
)
virtual

Reimplemented in SkBitmapDevice, skgpu::ganesh::Device, skgpu::graphite::Device, and SkPDFDevice.

Definition at line 494 of file SkDevice.cpp.

494 {
495 return nullptr;
496}

◆ onAccessPixels()

virtual bool SkDevice::onAccessPixels ( SkPixmap )
inlineprivatevirtual

Definition at line 533 of file SkDevice.h.

533{ return false; }

◆ onClipShader()

virtual void SkDevice::onClipShader ( sk_sp< SkShader )
privatepure virtual

◆ onDrawGlyphRunList()

virtual void SkDevice::onDrawGlyphRunList ( SkCanvas ,
const sktext::GlyphRunList ,
const SkPaint paint 
)
privatepure virtual

Implemented in SkNoPixelsDevice, and GlyphTrackingDevice.

◆ onPeekPixels()

virtual bool SkDevice::onPeekPixels ( SkPixmap )
inlineprivatevirtual

Definition at line 535 of file SkDevice.h.

535{ return false; }

◆ onReadPixels()

virtual bool SkDevice::onReadPixels ( const SkPixmap ,
int  x,
int  y 
)
inlineprivatevirtual

Definition at line 528 of file SkDevice.h.

528{ return false; }

◆ onWritePixels()

virtual bool SkDevice::onWritePixels ( const SkPixmap ,
int  x,
int  y 
)
inlineprivatevirtual

Definition at line 531 of file SkDevice.h.

531{ return false; }

◆ peekPixels()

bool SkDevice::peekPixels ( SkPixmap pmap)

Try to get read-only-access to the pixels behind the device. If successful, this returns true and fills-out the pixmap parameter.

On failure, returns false and ignores the pixmap parameter.

Definition at line 391 of file SkDevice.cpp.

391 {
392 SkPixmap tempStorage;
393 if (nullptr == pmap) {
394 pmap = &tempStorage;
395 }
396 return this->onPeekPixels(pmap);
397}
virtual bool onPeekPixels(SkPixmap *)
Definition: SkDevice.h:535

◆ popClipStack()

virtual void SkDevice::popClipStack ( )
pure virtual

◆ pushClipStack()

virtual void SkDevice::pushClipStack ( )
pure virtual

◆ readPixels()

bool SkDevice::readPixels ( const SkPixmap dst,
int  x,
int  y 
)
inline

Read pixels from this Device at the specified x,y offset into dst. The caller is responsible for "pre-clipping" the dst

Definition at line 153 of file SkDevice.h.

153{ return this->onReadPixels(dst, x, y); }
virtual bool onReadPixels(const SkPixmap &, int x, int y)
Definition: SkDevice.h:528
double y
double x

◆ recorder()

virtual skgpu::graphite::Recorder * SkDevice::recorder ( ) const
inlinevirtual

Reimplemented in skgpu::graphite::Device.

Definition at line 285 of file SkDevice.h.

285{ return nullptr; }

◆ recordingContext()

virtual GrRecordingContext * SkDevice::recordingContext ( ) const
inlinevirtual

Reimplemented in skgpu::ganesh::Device.

Definition at line 284 of file SkDevice.h.

284{ return nullptr; }

◆ replaceClip()

virtual void SkDevice::replaceClip ( const SkIRect rect)
pure virtual

◆ scalerContextFlags()

SkScalerContextFlags SkDevice::scalerContextFlags ( ) const

Definition at line 498 of file SkDevice.cpp.

498 {
499 // If we're doing linear blending, then we can disable the gamma hacks.
500 // Otherwise, leave them on. In either case, we still want the contrast boost:
501 // TODO: Can we be even smarter about mask gamma based on the dest transfer function?
502 const SkColorSpace* const cs = fInfo.colorSpace();
503 if (cs && cs->gammaIsLinear()) {
505 } else {
507 }
508}
bool gammaIsLinear() const

◆ setDeviceCoordinateSystem()

void SkDevice::setDeviceCoordinateSystem ( const SkM44 deviceToGlobal,
const SkM44 globalToDevice,
const SkM44 localToDevice,
int  bufferOriginX,
int  bufferOriginY 
)
protected

Definition at line 52 of file SkDevice.cpp.

56 {
57 fDeviceToGlobal = deviceToGlobal;
58 fDeviceToGlobal.normalizePerspective();
59 fGlobalToDevice = globalToDevice;
60 fGlobalToDevice.normalizePerspective();
61
62 fLocalToDevice = localToDevice;
63 fLocalToDevice.normalizePerspective();
64 if (bufferOriginX | bufferOriginY) {
65 fDeviceToGlobal.preTranslate(bufferOriginX, bufferOriginY);
66 fGlobalToDevice.postTranslate(-bufferOriginX, -bufferOriginY);
67 fLocalToDevice.postTranslate(-bufferOriginX, -bufferOriginY);
68 }
69 fLocalToDevice33 = fLocalToDevice.asM33();
70 fLocalToDeviceDirty = true;
71}
const SkM44 & globalToDevice() const
Definition: SkDevice.h:191
const SkM44 & deviceToGlobal() const
Definition: SkDevice.h:186
SkM44 & postTranslate(SkScalar x, SkScalar y, SkScalar z=0)
Definition: SkM44.cpp:100
void normalizePerspective()
Definition: SkM44.cpp:226
SkMatrix asM33() const
Definition: SkM44.h:409
SkM44 & preTranslate(SkScalar x, SkScalar y, SkScalar z=0)
Definition: SkM44.cpp:89

◆ setGlobalCTM()

void SkDevice::setGlobalCTM ( const SkM44 ctm)

Definition at line 73 of file SkDevice.cpp.

73 {
74 fLocalToDevice = ctm;
75 fLocalToDevice.normalizePerspective();
76 // Map from the global CTM state to this device's coordinate system.
77 fLocalToDevice.postConcat(fGlobalToDevice);
78 fLocalToDevice33 = fLocalToDevice.asM33();
79 fLocalToDeviceDirty = true;
80}
SkM44 & postConcat(const SkM44 &m)
Definition: SkM44.h:355

◆ setImmutable()

virtual void SkDevice::setImmutable ( )
inlinevirtual

Reimplemented in SkBitmapDevice, and skgpu::graphite::Device.

Definition at line 293 of file SkDevice.h.

293{}

◆ setLocalToDevice()

void SkDevice::setLocalToDevice ( const SkM44 localToDevice)
inline

Definition at line 211 of file SkDevice.h.

211 {
212 fLocalToDevice = localToDevice;
213 fLocalToDevice33 = fLocalToDevice.asM33();
214 fLocalToDeviceDirty = true;
215 }

◆ setOrigin()

void SkDevice::setOrigin ( const SkM44 globalCTM,
int  x,
int  y 
)
inlineprotected

Definition at line 508 of file SkDevice.h.

508 {
509 this->setDeviceCoordinateSystem(SkM44(), SkM44(), globalCTM, x, y);
510 }
void setDeviceCoordinateSystem(const SkM44 &deviceToGlobal, const SkM44 &globalToDevice, const SkM44 &localToDevice, int bufferOriginX, int bufferOriginY)
Definition: SkDevice.cpp:52

◆ shouldDrawAsTiledImageRect()

virtual bool SkDevice::shouldDrawAsTiledImageRect ( ) const
inlinevirtual

Reimplemented in skgpu::ganesh::Device.

Definition at line 368 of file SkDevice.h.

368{ return false; }

◆ size()

SkISize SkDevice::size ( ) const
inline

Definition at line 126 of file SkDevice.h.

126{ return this->imageInfo().dimensions(); }
SkISize dimensions() const
Definition: SkImageInfo.h:421

◆ snapSpecial() [1/2]

sk_sp< SkSpecialImage > SkDevice::snapSpecial ( )

Definition at line 320 of file SkDevice.cpp.

320 {
321 return this->snapSpecial(SkIRect::MakeWH(this->width(), this->height()));
322}
sk_sp< SkSpecialImage > snapSpecial()
Definition: SkDevice.cpp:320

◆ snapSpecial() [2/2]

sk_sp< SkSpecialImage > SkDevice::snapSpecial ( const SkIRect subset,
bool  forceCopy = false 
)
virtual

Reimplemented in SkBitmapDevice, skgpu::ganesh::Device, and skgpu::graphite::Device.

Definition at line 315 of file SkDevice.cpp.

315{ return nullptr; }

◆ snapSpecialScaled()

sk_sp< SkSpecialImage > SkDevice::snapSpecialScaled ( const SkIRect subset,
const SkISize dstDims 
)
virtual

Reimplemented in skgpu::ganesh::Device.

Definition at line 316 of file SkDevice.cpp.

317 {
318 return nullptr;
319}

◆ strikeDeviceInfo()

virtual SkStrikeDeviceInfo SkDevice::strikeDeviceInfo ( ) const
inlinevirtual

Reimplemented in skgpu::ganesh::Device, skgpu::graphite::Device, and GlyphTrackingDevice.

Definition at line 137 of file SkDevice.h.

137 {
138 return {fSurfaceProps, this->scalerContextFlags(), nullptr};
139 }
SkScalerContextFlags scalerContextFlags() const
Definition: SkDevice.cpp:498

◆ surfaceProps()

const SkSurfaceProps & SkDevice::surfaceProps ( ) const
inline

Return SurfaceProps for this device.

Definition at line 131 of file SkDevice.h.

131 {
132 return fSurfaceProps;
133 }

◆ useDrawCoverageMaskForMaskFilters()

virtual bool SkDevice::useDrawCoverageMaskForMaskFilters ( ) const
inlinevirtual

Reimplemented in skgpu::graphite::Device.

Definition at line 276 of file SkDevice.h.

276{ return false; }

◆ width()

int SkDevice::width ( ) const
inline

Definition at line 119 of file SkDevice.h.

119{ return this->imageInfo().width(); }
int width() const
Definition: SkImageInfo.h:365

◆ writePixels()

bool SkDevice::writePixels ( const SkPixmap src,
int  x,
int  y 
)
inline

Write the pixels in 'src' into this Device at the specified x,y offset. The caller is responsible for "pre-clipping" the src.

Definition at line 147 of file SkDevice.h.

147{ return this->onWritePixels(src, x, y); }
virtual bool onWritePixels(const SkPixmap &, int x, int y)
Definition: SkDevice.h:531

Friends And Related Function Documentation

◆ DeviceTestingAccess

friend class DeviceTestingAccess
friend

Definition at line 521 of file SkDevice.h.

◆ SkCanvas

friend class SkCanvas
friend

Definition at line 520 of file SkDevice.h.


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