Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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 SkRect &oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, 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 44 of file SkDevice.cpp.

45 : fInfo(info)
46 , fSurfaceProps(surfaceProps) {
47 fDeviceToGlobal.setIdentity();
48 fGlobalToDevice.setIdentity();
49}
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 388 of file SkDevice.cpp.

388 {
389 SkPixmap tempStorage;
390 if (nullptr == pmap) {
391 pmap = &tempStorage;
392 }
393 return this->onAccessPixels(pmap);
394}
virtual bool onAccessPixels(SkPixmap *)
Definition SkDevice.h:534

◆ 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 514 of file SkDevice.h.

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

◆ 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) {
254 sh = as_SB(sh)->makeInvertAlpha();
255 }
256 this->onClipShader(std::move(sh));
257 }
SkShaderBase * as_SB(SkShader *shader)
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

◆ convertGlyphRunListToSlug()

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

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

Definition at line 488 of file SkDevice.cpp.

489 {
490 return nullptr;
491}

◆ 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

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

Definition at line 325 of file SkDevice.cpp.

326 {
328}
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 400 of file SkDevice.h.

400{}

◆ drawArc()

void SkDevice::drawArc ( const SkRect oval,
SkScalar  startAngle,
SkScalar  sweepAngle,
bool  useCenter,
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 133 of file SkDevice.cpp.

134 {
135 SkPath path;
136 bool isFillNoPathEffect = SkPaint::kFill_Style == paint.getStyle() && !paint.getPathEffect();
137 SkPathPriv::CreateDrawArcPath(&path, oval, startAngle, sweepAngle, useCenter,
138 isFillNoPathEffect);
139 this->drawPath(path, paint);
140}
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 SkRect &oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, bool isFillNoPathEffect)
Definition SkPath.cpp:3290
const Paint & paint
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 370 of file SkDevice.h.

376 { 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 204 of file SkDevice.cpp.

209 {
210 const int triCount = quadCount << 1;
211 const int vertexCount = triCount * 3;
213 if (colors) {
215 }
217
218 SkPoint* vPos = builder.positions();
219 SkPoint* vTex = builder.texCoords();
220 SkColor* vCol = builder.colors();
221 for (int i = 0; i < quadCount; ++i) {
222 SkPoint tmp[4];
223 xform[i].toQuad(tex[i].width(), tex[i].height(), tmp);
224 vPos = quad_to_tris(vPos, tmp);
225
226 tex[i].toQuad(tmp);
227 vTex = quad_to_tris(vTex, tmp);
228
229 if (colors) {
230 SkOpts::memset32(vCol, colors[i], 6);
231 vCol += 6;
232 }
233 }
234 this->drawVertices(builder.detach().get(), std::move(blender), paint);
235}
uint32_t SkColor
Definition SkColor.h:37
static SkPoint * quad_to_tris(SkPoint tris[6], const SkPoint quad[4])
Definition SkDevice.cpp:192
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)
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 470 of file SkDevice.h.

470 {
471 return false;
472 }

◆ 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 307 of file SkDevice.cpp.

308 {
309 // This shouldn't be reached; SkCanvas will only call this if
310 // useDrawCoverageMaskForMaskFilters() is overridden to return true.
311 SK_ABORT("Must override if useDrawCoverageMaskForMaskFilters() is true");
312}
#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 330 of file SkDevice.cpp.

332 {
333 sk_sp<SkSpecialImage> deviceImage = device->snapSpecial();
334 if (deviceImage) {
335#if defined(SK_DONT_PAD_LAYER_IMAGES) || defined(SK_RESOLVE_FILTERS_BEFORE_RESTORE)
336 this->drawSpecial(deviceImage.get(), device->getRelativeTransform(*this), sampling, paint);
337#else
338 // SkCanvas only calls drawDevice() when there are no filters (so the transform is pixel
339 // aligned). As such it can be drawn without clamping.
340 SkMatrix relativeTransform = device->getRelativeTransform(*this);
341 const bool strict = sampling != SkFilterMode::kNearest ||
342 !relativeTransform.isTranslate() ||
343 !SkScalarIsInt(relativeTransform.getTranslateX()) ||
344 !SkScalarIsInt(relativeTransform.getTranslateY());
345 this->drawSpecial(deviceImage.get(), relativeTransform, sampling, paint,
347 : SkCanvas::kFast_SrcRectConstraint);
348#endif
349 }
350}
static bool SkScalarIsInt(SkScalar x)
Definition SkScalar.h:80
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
Definition SkCanvas.h:1542
virtual void drawSpecial(SkSpecialImage *, const SkMatrix &localToDevice, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint constraint=SkCanvas::kStrict_SrcRectConstraint)
Definition SkDevice.cpp:305
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 299 of file SkDevice.cpp.

299 {
300 drawable->draw(canvas, matrix);
301}
void draw(SkCanvas *, const SkMatrix *=nullptr)

◆ drawDRRect()

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

Reimplemented in skgpu::ganesh::Device.

Definition at line 142 of file SkDevice.cpp.

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

◆ 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 254 of file SkDevice.cpp.

257 {
258 SkASSERT(paint.getStyle() == SkPaint::kFill_Style);
259 SkASSERT(!paint.getPathEffect());
260
261 SkPaint entryPaint = paint;
262 const SkM44 baseLocalToDevice = this->localToDevice44();
263 int clipIndex = 0;
264 for (int i = 0; i < count; ++i) {
265 // TODO: Handle per-edge AA. Right now this mirrors the SkiaRenderer component of Chrome
266 // which turns off antialiasing unless all four edges should be antialiased. This avoids
267 // seaming in tiled composited layers.
268 entryPaint.setAntiAlias(images[i].fAAFlags == SkCanvas::kAll_QuadAAFlags);
269 entryPaint.setAlphaf(paint.getAlphaf() * images[i].fAlpha);
270
271 SkASSERT(images[i].fMatrixIndex < 0 || preViewMatrices);
272 if (images[i].fMatrixIndex >= 0) {
273 this->setLocalToDevice(baseLocalToDevice *
274 SkM44(preViewMatrices[images[i].fMatrixIndex]));
275 }
276
277 SkASSERT(!images[i].fHasClip || dstClips);
278 if (images[i].fHasClip) {
279 // Since drawImageRect requires a srcRect, the dst clip is implemented as a true clip
280 this->pushClipStack();
282 clipPath.addPoly(dstClips + clipIndex, 4, true);
283 this->clipPath(clipPath, SkClipOp::kIntersect, entryPaint.isAntiAlias());
284 clipIndex += 4;
285 }
286 this->drawImageRect(images[i].fImage.get(), &images[i].fSrcRect, images[i].fDstRect,
287 sampling, entryPaint, constraint);
288 if (images[i].fHasClip) {
289 this->popClipStack();
290 }
291 if (images[i].fMatrixIndex >= 0) {
292 this->setLocalToDevice(baseLocalToDevice);
293 }
294 }
295}
int count
#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
SkPath & addPoly(const SkPoint pts[], int count, bool close)
Definition SkPath.cpp:880

◆ 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 237 of file SkDevice.cpp.

238 {
240 paint.setColor4f(color);
241 paint.setBlendMode(mode);
242 paint.setAntiAlias(aa == SkCanvas::kAll_QuadAAFlags);
243
244 if (clip) {
245 // Draw the clip directly as a quad since it's a filled color with no local coords
247 clipPath.addPoly(clip, 4, true);
248 this->drawPath(clipPath, paint);
249 } else {
250 this->drawRect(r, paint);
251 }
252}
SkColor4f color
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
virtual void drawRect(const SkRect &r, const SkPaint &paint)=0

◆ 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 352 of file SkDevice.cpp.

357 {
358 SkASSERT(!paint.getImageFilter() && !paint.getMaskFilter());
359
360 skif::LayerSpace<SkIRect> targetOutput = mapping.deviceToLayer(
362
365 }
366
368 skif::Context ctx{this->createImageFilteringBackend(src ? src->props() : this->surfaceProps(),
369 colorType),
370 mapping,
371 targetOutput,
372 skif::FilterResult(sk_ref_sp(src)),
373 this->imageInfo().colorSpace(),
374 &stats};
375
378 stats.reportStats();
379 if (result) {
380 SkMatrix deviceMatrixWithOffset = mapping.layerToDevice();
381 deviceMatrixWithOffset.preTranslate(offset.fX, offset.fY);
382 this->drawSpecial(result.get(), deviceMatrixWithOffset, sampling, paint);
383 }
384}
@ 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:325
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
dict stats
Definition malisc.py:20
Point offset

◆ drawGlyphRunList()

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

Definition at line 431 of file SkDevice.cpp.

433 {
434 if (!this->localToDevice().isFinite()) {
435 return;
436 }
437
438 if (!glyphRunList.hasRSXForm()) {
439 this->onDrawGlyphRunList(canvas, glyphRunList, paint);
440 } else {
441 this->simplifyGlyphRunRSXFormAndRedraw(canvas, glyphRunList, paint);
442 }
443}
static bool isFinite(const SkRect &r)
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 164 of file SkDevice.cpp.

165 {
166 SkLatticeIter iter(lattice, dst);
167
168 SkRect srcR, dstR;
169 SkColor c;
170 bool isFixedColor = false;
172
173 while (iter.next(&srcR, &dstR, &isFixedColor, &c)) {
174 // TODO: support this fast-path for GPU images
175 if (isFixedColor || (srcR.width() <= 1.0f && srcR.height() <= 1.0f &&
176 image->readPixels(nullptr, info, &c, 4, srcR.fLeft, srcR.fTop))) {
177 // Fast draw with drawRect, if this is a patch containing a single color
178 // or if this is a patch containing a single pixel.
179 if (0 != c || !paint.isSrcOver()) {
180 SkPaint paintCopy(paint);
181 int alpha = SkAlphaMul(SkColorGetA(c), SkAlpha255To256(paint.getAlpha()));
182 paintCopy.setColor(SkColorSetA(c, alpha));
183 this->drawRect(dstR, paintCopy);
184 }
185 } else {
186 this->drawImageRect(image, &srcR, dstR, SkSamplingOptions(filter), paint,
188 }
189 }
190}
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< SkImage > image
Definition examples.cpp:29
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 153 of file SkDevice.cpp.

155 {
157 auto vertices = SkPatchUtils::MakeVertices(cubics, colors, texCoords, lod.width(), lod.height(),
158 this->imageInfo().colorSpace());
159 if (vertices) {
160 this->drawVertices(vertices.get(), std::move(blender), paint);
161 }
162}
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)
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 112 of file SkDevice.cpp.

112 {
113 const SkMatrix& localToDevice = this->localToDevice();
114 bool isNonTranslate = localToDevice.getType() & ~(SkMatrix::kTranslate_Mask);
115 bool complexPaint = paint.getStyle() != SkPaint::kFill_Style || paint.getMaskFilter() ||
116 paint.getPathEffect();
117 bool antiAlias = paint.isAntiAlias() && (!is_int(localToDevice.getTranslateX()) ||
119 if (isNonTranslate || complexPaint || antiAlias) {
120 SkPath path;
121 region.getBoundaryPath(&path);
122 path.setIsVolatile(true);
123 return this->drawPath(path, paint, true);
124 }
125
126 SkRegion::Iterator it(region);
127 while (!it.done()) {
128 this->drawRect(SkRect::Make(it.rect()), paint);
129 it.next();
130 }
131}
static bool is_int(float x)
Definition SkDevice.cpp:108
@ 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) {
640 sk_sp<SkVertices> vertices = SkShadowTessellator::MakeAmbient(path, viewMatrix,
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) {
731 sk_sp<SkVertices> vertices = SkShadowTessellator::MakeSpot(path, viewMatrix,
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
@ kConcaveBlurOnly_ShadowFlag
@ kTransparentOccluder_ShadowFlag
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)
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)
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
Definition SkMatrix.cpp:770
static const SkMatrix & I()
bool hasPerspective() const
Definition SkMatrix.h:312
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
@ 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)
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
void draw_shadow(SkCanvas *canvas, const SkPath &path, SkScalar height, SkColor color, SkPoint3 lightPos, SkScalar lightR, bool isAmbient, uint32_t flags)
const Scalar scale
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)

◆ drawSlug()

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

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

Definition at line 493 of file SkDevice.cpp.

493 {
494 SK_ABORT("Slug drawing not supported.");
495}

◆ 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 305 of file SkDevice.cpp.

306 {}

◆ 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

◆ 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 90 of file SkDevice.cpp.

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

◆ 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 102 of file SkDevice.cpp.

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

◆ 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

◆ 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

◆ 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 81 of file SkDevice.cpp.

81 {
82 // pixelAligned is set to the identity + integer translation of the device-to-global matrix.
83 // If they are equal then the device is by definition pixel aligned.
84 SkM44 pixelAligned = SkM44();
85 pixelAligned.setRC(0, 3, SkScalarFloorToScalar(fDeviceToGlobal.rc(0, 3)));
86 pixelAligned.setRC(1, 3, SkScalarFloorToScalar(fDeviceToGlobal.rc(1, 3)));
87 return pixelAligned == fDeviceToGlobal;
88}
#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, skgpu::graphite::Device, and SkPDFDevice.

Definition at line 314 of file SkDevice.cpp.

314{ return nullptr; }

◆ makeSpecial() [2/2]

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

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

Definition at line 315 of file SkDevice.cpp.

315{ 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 499 of file SkDevice.cpp.

499 {
500 return nullptr;
501}

◆ onAccessPixels()

virtual bool SkDevice::onAccessPixels ( SkPixmap )
inlineprivatevirtual

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

Definition at line 534 of file SkDevice.h.

534{ 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

◆ onPeekPixels()

virtual bool SkDevice::onPeekPixels ( SkPixmap )
inlineprivatevirtual

Reimplemented in SkBitmapDevice.

Definition at line 536 of file SkDevice.h.

536{ return false; }

◆ onReadPixels()

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

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

Definition at line 529 of file SkDevice.h.

529{ return false; }

◆ onWritePixels()

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

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

Definition at line 532 of file SkDevice.h.

532{ 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 396 of file SkDevice.cpp.

396 {
397 SkPixmap tempStorage;
398 if (nullptr == pmap) {
399 pmap = &tempStorage;
400 }
401 return this->onPeekPixels(pmap);
402}
virtual bool onPeekPixels(SkPixmap *)
Definition SkDevice.h:536

◆ 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:529
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 503 of file SkDevice.cpp.

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

◆ setDeviceCoordinateSystem()

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

Definition at line 51 of file SkDevice.cpp.

55 {
56 fDeviceToGlobal = deviceToGlobal;
57 fDeviceToGlobal.normalizePerspective();
58 fGlobalToDevice = globalToDevice;
59 fGlobalToDevice.normalizePerspective();
60
61 fLocalToDevice = localToDevice;
62 fLocalToDevice.normalizePerspective();
63 if (bufferOriginX | bufferOriginY) {
64 fDeviceToGlobal.preTranslate(bufferOriginX, bufferOriginY);
65 fGlobalToDevice.postTranslate(-bufferOriginX, -bufferOriginY);
66 fLocalToDevice.postTranslate(-bufferOriginX, -bufferOriginY);
67 }
68 fLocalToDevice33 = fLocalToDevice.asM33();
69 fLocalToDeviceDirty = true;
70}
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 72 of file SkDevice.cpp.

72 {
73 fLocalToDevice = ctm;
74 fLocalToDevice.normalizePerspective();
75 // Map from the global CTM state to this device's coordinate system.
76 fLocalToDevice.postConcat(fGlobalToDevice);
77 fLocalToDevice33 = fLocalToDevice.asM33();
78 fLocalToDeviceDirty = true;
79}
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 509 of file SkDevice.h.

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

◆ shouldDrawAsTiledImageRect()

virtual bool SkDevice::shouldDrawAsTiledImageRect ( ) const
inlinevirtual

Reimplemented in skgpu::ganesh::Device.

Definition at line 369 of file SkDevice.h.

369{ return false; }

◆ size()

SkISize SkDevice::size ( ) const
inline

Definition at line 126 of file SkDevice.h.

126{ return this->imageInfo().dimensions(); }
SkISize dimensions() const

◆ snapSpecial() [1/2]

sk_sp< SkSpecialImage > SkDevice::snapSpecial ( )

Definition at line 321 of file SkDevice.cpp.

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

◆ 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 316 of file SkDevice.cpp.

316{ return nullptr; }

◆ snapSpecialScaled()

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

Reimplemented in skgpu::ganesh::Device.

Definition at line 317 of file SkDevice.cpp.

318 {
319 return nullptr;
320}

◆ 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:503

◆ 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

◆ 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:532

Friends And Related Symbol Documentation

◆ DeviceTestingAccess

friend class DeviceTestingAccess
friend

Definition at line 522 of file SkDevice.h.

◆ SkCanvas

friend class SkCanvas
friend

Definition at line 521 of file SkDevice.h.


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