Flutter Engine
The Flutter Engine
Classes | Public Types | Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes | List of all members
skgpu::graphite::PathAtlas Class Referenceabstract

#include <PathAtlas.h>

Inheritance diagram for skgpu::graphite::PathAtlas:
skgpu::graphite::ComputePathAtlas skgpu::graphite::RasterPathAtlas

Classes

class  DrawAtlasMgr
 

Public Types

using MaskAndOrigin = std::pair< CoverageMaskShape, SkIPoint >
 

Public Member Functions

 PathAtlas (Recorder *recorder, uint32_t requestedWidth, uint32_t requestedHeight)
 
virtual ~PathAtlas ()
 
std::pair< const Renderer *, std::optional< MaskAndOrigin > > addShape (const Rect &transformedShapeBounds, const Shape &shape, const Transform &localToDevice, const SkStrokeRec &style)
 
virtual bool isSuitableForAtlasing (const Rect &transformedShapeBounds, const Rect &clipBounds) const
 
uint32_t width () const
 
uint32_t height () const
 

Static Public Attributes

static constexpr int kEntryPadding = 1
 

Protected Member Functions

virtual const TextureProxyonAddShape (const Shape &, const Transform &transform, const SkStrokeRec &, skvx::half2 maskSize, skvx::half2 *outPos)=0
 

Protected Attributes

RecorderfRecorder
 
uint32_t fWidth = 0
 
uint32_t fHeight = 0
 

Detailed Description

PathAtlas manages one or more atlas textures that store coverage masks for path rendering.

The contents of a PathAtlas are intended to be transient: atlas regions are considered valid only for the scope of the render passes that sample them. Unlike DrawAtlas, PathAtlas does not necessarily support partial eviction and reuse of subregions. In most subclasses, once an atlas texture is filled up all of its sub-allocations must be invalidated before it can be reused.

PathAtlas does not prescribe how atlas contents get uploaded to the GPU. The specific task mechanism is defined by subclasses.

Definition at line 41 of file PathAtlas.h.

Member Typedef Documentation

◆ MaskAndOrigin

Definition at line 50 of file PathAtlas.h.

Constructor & Destructor Documentation

◆ PathAtlas()

skgpu::graphite::PathAtlas::PathAtlas ( Recorder recorder,
uint32_t  requestedWidth,
uint32_t  requestedHeight 
)

The PathAtlas will use textures of the requested size or the system's maximum texture size, whichever is smaller.

Definition at line 26 of file PathAtlas.cpp.

27 : fRecorder(recorder) {
28 const Caps* caps = recorder->priv().caps();
29 int maxTextureSize = std::max(caps->maxPathAtlasTextureSize(), kMinAtlasTextureSize);
30 maxTextureSize = std::min(maxTextureSize, caps->maxTextureSize());
31
32 fWidth = SkPrevPow2(std::min<uint32_t>(requestedWidth, maxTextureSize));
33 fHeight = SkPrevPow2(std::min<uint32_t>(requestedHeight, maxTextureSize));
34}
static int SkPrevPow2(int value)
Definition: SkMathPriv.h:287
const Caps * caps() const
Definition: RecorderPriv.h:31
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48

◆ ~PathAtlas()

skgpu::graphite::PathAtlas::~PathAtlas ( )
virtualdefault

Member Function Documentation

◆ addShape()

std::pair< const Renderer *, std::optional< PathAtlas::MaskAndOrigin > > skgpu::graphite::PathAtlas::addShape ( const Rect transformedShapeBounds,
const Shape shape,
const Transform localToDevice,
const SkStrokeRec style 
)

Searches the atlas for a slot that can fit a coverage mask for a clipped shape with the given bounds in device coordinates and submits the mask to be drawn into the found atlas region. For atlases that cache coverage masks, will first search the cache before adding.

Returns an empty result if a the shape cannot fit in the atlas. Otherwise, returns the CoverageMaskShape (including the texture proxy) for sampling the eventually-rendered coverage mask and the device-space origin the mask should be drawn at (e.g. its recorded draw should be an integer translation matrix), and the Renderer that should be used to draw that shape. The Renderer should have single-channel coverage, require AA bounds outsetting, and have a single renderStep.

The bounds of the atlas entry is laid out with a 1 pixel outset from the given dimensions. The returned shape's UV origin accounts for the padding, and its mask size does not include the padding. This allows the mask to be sampled safely with linear filtering without worrying about HW filtering accessing pixels from other entries.

shape will be drawn after applying the linear components (scale, rotation, skew) of the provided localToDevice transform. This is done by translating the shape by the inverse of the rounded out transformedShapeBounds offset. For an unclipped shape this amounts to translating it back to its origin while preserving any sub-pixel translation. For a clipped shape, this ensures that the visible portions of the mask are centered in the atlas slot while invisible portions that would lie outside the atlas slot get clipped out.

addShape() schedules the shape to be drawn but when and how the rendering happens is specified by the subclass implementation.

The stroke-and-fill style is drawn as a single combined coverage mask containing the stroke and the fill.

Definition at line 38 of file PathAtlas.cpp.

42 {
43 // It is possible for the transformed shape bounds to be fully clipped out while the draw still
44 // produces coverage due to an inverse fill. In this case, don't render any mask;
45 // CoverageMaskShapeRenderStep will automatically handle the simple fill. We'll handle this
46 // by adding an empty mask.
47 // TODO: We could have addShape() handle this fully except we need a valid TextureProxy still.
48 const bool emptyMask = transformedShapeBounds.isEmptyNegativeOrNaN();
49
50 // Round out the shape bounds to preserve any fractional offset so that it is present in the
51 // translation that we use when deriving the atlas-space transform later.
52 Rect maskBounds = transformedShapeBounds.makeRoundOut();
53
54 CoverageMaskShape::MaskInfo maskInfo;
55 // This size does *not* include any padding that the atlas may place around the mask. This size
56 // represents the area the shape can actually modify.
57 maskInfo.fMaskSize = emptyMask ? skvx::half2(0) : skvx::cast<uint16_t>(maskBounds.size());
58 Transform atlasTransform = localToDevice.postTranslate(-maskBounds.left(), -maskBounds.top());
59 const TextureProxy* atlasProxy = this->onAddShape(shape,
60 atlasTransform,
61 style,
62 maskInfo.fMaskSize,
63 &maskInfo.fTextureOrigin);
64 if (!atlasProxy) {
65 return std::make_pair(nullptr, std::nullopt);
66 }
67
68 std::optional<PathAtlas::MaskAndOrigin> atlasMask =
69 std::make_pair(CoverageMaskShape(shape, atlasProxy, localToDevice.inverse(), maskInfo),
70 SkIPoint{(int) maskBounds.left(), (int) maskBounds.top()});
71 return std::make_pair(fRecorder->priv().rendererProvider()->coverageMask(), atlasMask);
72}
SI D cast(const S &v)
virtual const TextureProxy * onAddShape(const Shape &, const Transform &transform, const SkStrokeRec &, skvx::half2 maskSize, skvx::half2 *outPos)=0
const RendererProvider * rendererProvider() const
Definition: RecorderPriv.h:48
const Renderer * coverageMask() const
Transform postTranslate(float x, float y) const
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
TRect< Scalar > Rect
Definition: rect.h:769
skgpu::graphite::Transform Transform
Definition: SkVx.h:73
Vec< 2, uint16_t > half2
Definition: SkVx.h:1175

◆ height()

uint32_t skgpu::graphite::PathAtlas::height ( ) const
inline

Definition at line 109 of file PathAtlas.h.

109{ return fHeight; }

◆ isSuitableForAtlasing()

virtual bool skgpu::graphite::PathAtlas::isSuitableForAtlasing ( const Rect transformedShapeBounds,
const Rect clipBounds 
) const
inlinevirtual

Returns true if a path coverage mask with the given device-space bounds is sufficiently small to benefit from atlasing without causing too many atlas renders.

transformedShapeBounds represents the device-space bounds of the coverage mask shape unrestricted by clip and viewport bounds.

clipBounds represents the conservative bounding box of the union of the clip stack that should apply to the shape.

Reimplemented in skgpu::graphite::ComputePathAtlas.

Definition at line 103 of file PathAtlas.h.

104 {
105 return true;
106 }

◆ onAddShape()

virtual const TextureProxy * skgpu::graphite::PathAtlas::onAddShape ( const Shape ,
const Transform transform,
const SkStrokeRec ,
skvx::half2  maskSize,
skvx::half2 outPos 
)
protectedpure virtual

◆ width()

uint32_t skgpu::graphite::PathAtlas::width ( ) const
inline

Definition at line 108 of file PathAtlas.h.

108{ return fWidth; }

Member Data Documentation

◆ fHeight

uint32_t skgpu::graphite::PathAtlas::fHeight = 0
protected

Definition at line 180 of file PathAtlas.h.

◆ fRecorder

Recorder* skgpu::graphite::PathAtlas::fRecorder
protected

Definition at line 177 of file PathAtlas.h.

◆ fWidth

uint32_t skgpu::graphite::PathAtlas::fWidth = 0
protected

Definition at line 179 of file PathAtlas.h.

◆ kEntryPadding

constexpr int skgpu::graphite::PathAtlas::kEntryPadding = 1
staticconstexpr

Definition at line 55 of file PathAtlas.h.


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