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

#include <AtlasPathRenderer.h>

Inheritance diagram for skgpu::ganesh::AtlasPathRenderer:
skgpu::ganesh::PathRenderer GrOnFlushCallbackObject SkRefCnt SkRefCntBase

Public Member Functions

const char * name () const override
 
GrFPResult makeAtlasClipEffect (const skgpu::ganesh::SurfaceDrawContext *, const GrOp *opBeingClipped, std::unique_ptr< GrFragmentProcessor > inputFP, const SkIRect &drawBounds, const SkMatrix &, const SkPath &)
 
- Public Member Functions inherited from skgpu::ganesh::PathRenderer
 PathRenderer ()=default
 
StencilSupport getStencilSupport (const GrStyledShape &shape) const
 
CanDrawPath canDrawPath (const CanDrawPathArgs &args) const
 
bool drawPath (const DrawPathArgs &args)
 
void stencilPath (const StencilPathArgs &args)
 
- Public Member Functions inherited from SkRefCntBase
 SkRefCntBase ()
 
virtual ~SkRefCntBase ()
 
bool unique () const
 
void ref () const
 
void unref () const
 
- Public Member Functions inherited from GrOnFlushCallbackObject
virtual ~GrOnFlushCallbackObject ()
 
virtual void postFlush (skgpu::AtlasToken startTokenForNextFlush)
 
virtual bool retainOnFreeGpuResources ()
 

Static Public Member Functions

static bool IsSupported (GrRecordingContext *)
 
static sk_sp< AtlasPathRendererMake (GrRecordingContext *rContext)
 

Private Member Functions

StencilSupport onGetStencilSupport (const GrStyledShape &) const override
 
CanDrawPath onCanDrawPath (const CanDrawPathArgs &) const override
 
bool onDrawPath (const DrawPathArgs &) override
 
bool preFlush (GrOnFlushResourceProvider *) override
 

Additional Inherited Members

- Public Types inherited from skgpu::ganesh::PathRenderer
enum  StencilSupport { kNoSupport_StencilSupport , kStencilOnly_StencilSupport , kNoRestriction_StencilSupport }
 
enum class  CanDrawPath { kNo , kAsBackup , kYes }
 
- Static Protected Member Functions inherited from skgpu::ganesh::PathRenderer
static void GetPathDevBounds (const SkPath &path, SkISize devSize, const SkMatrix &matrix, SkRect *bounds)
 

Detailed Description

Definition at line 27 of file AtlasPathRenderer.h.

Member Function Documentation

◆ IsSupported()

bool skgpu::ganesh::AtlasPathRenderer::IsSupported ( GrRecordingContext rContext)
static

Definition at line 107 of file AtlasPathRenderer.cpp.

107 {
108#ifdef SK_BUILD_FOR_IOS
109 // b/195095846: There is a bug with the atlas path renderer on OpenGL iOS. Disable until we can
110 // investigate.
111 if (rContext->backend() == GrBackendApi::kOpenGL) {
112 return false;
113 }
114#endif
115#ifdef SK_BUILD_FOR_WIN
116 // http://skbug.com/13519 There is a bug with the atlas path renderer on Direct3D, running on
117 // Radeon hardware and possibly others. Disable until we can investigate.
118 if (rContext->backend() == GrBackendApi::kDirect3D) {
119 return false;
120 }
121#endif
122 const GrCaps& caps = *rContext->priv().caps();
123 auto atlasFormat = caps.getDefaultBackendFormat(kAtlasAlpha8Type, GrRenderable::kYes);
124 return rContext->asDirectContext() && // The atlas doesn't support DDL yet.
125 caps.internalMultisampleCount(atlasFormat) > 1 &&
126 // GrAtlasRenderTask currently requires tessellation. In the future it could use the
127 // default path renderer when tessellation isn't available.
129}
const GrCaps * caps() const
GrBackendFormat getDefaultBackendFormat(GrColorType, GrRenderable) const
Definition GrCaps.cpp:400
int internalMultisampleCount(const GrBackendFormat &format) const
Definition GrCaps.h:271
virtual GrDirectContext * asDirectContext()
SK_API GrBackendApi backend() const
GrRecordingContextPriv priv()
static constexpr auto kAtlasAlpha8Type

◆ Make()

sk_sp< AtlasPathRenderer > skgpu::ganesh::AtlasPathRenderer::Make ( GrRecordingContext rContext)
static

Definition at line 131 of file AtlasPathRenderer.cpp.

131 {
132 return IsSupported(rContext)
133 ? sk_sp<AtlasPathRenderer>(new AtlasPathRenderer(rContext->asDirectContext()))
134 : nullptr;
135}
static bool IsSupported(GrRecordingContext *)

◆ makeAtlasClipEffect()

GrFPResult skgpu::ganesh::AtlasPathRenderer::makeAtlasClipEffect ( const skgpu::ganesh::SurfaceDrawContext sdc,
const GrOp opBeingClipped,
std::unique_ptr< GrFragmentProcessor inputFP,
const SkIRect drawBounds,
const SkMatrix viewMatrix,
const SkPath path 
)

Definition at line 332 of file AtlasPathRenderer.cpp.

337 {
338 if (viewMatrix.hasPerspective()) {
339 return GrFPFailure(std::move(inputFP));
340 }
341
342 const SkRect pathDevBounds = viewMatrix.mapRect(path.getBounds());
343 if (!is_visible(pathDevBounds, drawBounds)) {
344 // The path is empty or outside the drawBounds. No mask is needed. We explicitly allow the
345 // returned successful "fp" to be null in case this bypassed atlas clip effect was the first
346 // clip to be processed by the clip stack (at which point inputFP is null).
347 return path.isInverseFillType() ? GrFPNullableSuccess(std::move(inputFP))
348 : GrFPFailure(std::move(inputFP));
349 }
350
351 auto fallbackAAType = (sdc->numSamples() > 1 || sdc->canUseDynamicMSAA()) ? GrAAType::kMSAA
353 if (!this->pathFitsInAtlas(pathDevBounds, fallbackAAType)) {
354 // The path is too big.
355 return GrFPFailure(std::move(inputFP));
356 }
357
358 SkIRect devIBounds;
359 SkIPoint16 locationInAtlas;
360 bool transposedInAtlas;
361 // Called if the atlas runs out of room, to determine if it's safe to create a new one. (Draws
362 // can never access more than one atlas.)
363 auto drawRefsAtlasCallback = [opBeingClipped, &inputFP](const GrSurfaceProxy* atlasProxy) {
364 return refs_atlas(opBeingClipped, atlasProxy) ||
365 refs_atlas(inputFP.get(), atlasProxy);
366 };
367 // addPathToAtlas() ignores inverseness of the fill. See GrAtlasRenderTask::getAtlasUberPath().
368 if (!this->addPathToAtlas(sdc->recordingContext(), viewMatrix, path, pathDevBounds, &devIBounds,
369 &locationInAtlas, &transposedInAtlas, drawRefsAtlasCallback)) {
370 // The atlas ran out of room and we were unable to start a new one.
371 return GrFPFailure(std::move(inputFP));
372 }
373
374 SkMatrix atlasMatrix;
375 auto [atlasX, atlasY] = locationInAtlas;
376 if (!transposedInAtlas) {
377 atlasMatrix = SkMatrix::Translate(atlasX - devIBounds.left(), atlasY - devIBounds.top());
378 } else {
379 atlasMatrix.setAll(0, 1, atlasX - devIBounds.top(),
380 1, 0, atlasY - devIBounds.left(),
381 0, 0, 1);
382 }
384 if (path.isInverseFillType()) {
386 }
387 if (!devIBounds.contains(drawBounds)) {
389 // At this point in time we expect callers to tighten the scissor for "kIntersect" clips, as
390 // opposed to us having to check the path bounds. Feel free to remove this assert if that
391 // ever changes.
392 SkASSERT(path.isInverseFillType());
393 }
394 GrSurfaceProxyView atlasView = fAtlasRenderTasks.back()->readView(*sdc->caps());
395 return GrFPSuccess(std::make_unique<GrModulateAtlasCoverageEffect>(flags, std::move(inputFP),
396 std::move(atlasView),
397 atlasMatrix, devIBounds));
398}
static GrFPResult GrFPNullableSuccess(std::unique_ptr< GrFragmentProcessor > fp)
static GrFPResult GrFPSuccess(std::unique_ptr< GrFragmentProcessor > fp)
static GrFPResult GrFPFailure(std::unique_ptr< GrFragmentProcessor > fp)
GrAAType
#define SkASSERT(cond)
Definition SkAssert.h:116
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition SkMatrix.h:91
SkMatrix & setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar persp0, SkScalar persp1, SkScalar persp2)
Definition SkMatrix.h:562
bool hasPerspective() const
Definition SkMatrix.h:312
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
const GrCaps * caps() const
GrRecordingContext * recordingContext() const
FlutterSemanticsFlag flags
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
Definition ref_ptr.h:256
constexpr int32_t top() const
Definition SkRect.h:120
constexpr int32_t left() const
Definition SkRect.h:113
bool contains(int32_t x, int32_t y) const
Definition SkRect.h:463

◆ name()

const char * skgpu::ganesh::AtlasPathRenderer::name ( ) const
inlineoverridevirtual

Implements skgpu::ganesh::PathRenderer.

Definition at line 34 of file AtlasPathRenderer.h.

34{ return "GrAtlasPathRenderer"; }

◆ onCanDrawPath()

PathRenderer::CanDrawPath skgpu::ganesh::AtlasPathRenderer::onCanDrawPath ( const CanDrawPathArgs args) const
overrideprivatevirtual

Subclass implementation of canDrawPath()

Implements skgpu::ganesh::PathRenderer.

Definition at line 262 of file AtlasPathRenderer.cpp.

262 {
263#ifdef SK_DEBUG
264 if (!fAtlasRenderTasks.empty()) {
265 // args.fPaint should NEVER reference our current atlas. If it does, it means somebody
266 // intercepted a clip FP meant for a different op and will cause rendering artifacts.
267 const GrSurfaceProxy* atlasProxy = fAtlasRenderTasks.back()->atlasProxy();
268 SkASSERT(!refs_atlas(args.fPaint->getColorFragmentProcessor(), atlasProxy));
269 SkASSERT(!refs_atlas(args.fPaint->getCoverageFragmentProcessor(), atlasProxy));
270 }
271 SkASSERT(!args.fHasUserStencilSettings); // See onGetStencilSupport().
272#endif
273 bool canDrawPath = args.fShape->style().isSimpleFill() &&
274#ifdef SK_DISABLE_ATLAS_PATH_RENDERER_WITH_COVERAGE_AA
275 // The MSAA requirement is a temporary limitation in order to preserve
276 // functionality for refactoring. TODO: Allow kCoverage AA types.
277 args.fAAType == GrAAType::kMSAA &&
278#else
279 args.fAAType != GrAAType::kNone &&
280#endif
281 // Non-DMSAA convex paths should be handled by the convex tessellator.
282 // (With DMSAA we continue to use the atlas for these paths in order to avoid
283 // triggering MSAA.)
284 (args.fProxy->numSamples() == 1 || !args.fShape->knownToBeConvex()) &&
285 !args.fShape->style().hasPathEffect() &&
286 !args.fViewMatrix->hasPerspective() &&
287 this->pathFitsInAtlas(args.fViewMatrix->mapRect(args.fShape->bounds()),
288 args.fAAType);
290}
CanDrawPath canDrawPath(const CanDrawPathArgs &args) const
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args

◆ onDrawPath()

bool skgpu::ganesh::AtlasPathRenderer::onDrawPath ( const DrawPathArgs args)
overrideprivatevirtual

Subclass implementation of drawPath()

Implements skgpu::ganesh::PathRenderer.

Definition at line 292 of file AtlasPathRenderer.cpp.

292 {
293 SkPath path;
294 args.fShape->asPath(&path);
295
296 const SkRect pathDevBounds = args.fViewMatrix->mapRect(args.fShape->bounds());
297 SkASSERT(this->pathFitsInAtlas(pathDevBounds, args.fAAType));
298
299 if (!is_visible(pathDevBounds, args.fClip->getConservativeBounds())) {
300 // The path is empty or outside the clip. No mask is needed.
301 if (path.isInverseFillType()) {
302 args.fSurfaceDrawContext->drawPaint(args.fClip, std::move(args.fPaint),
303 *args.fViewMatrix);
304 }
305 return true;
306 }
307
308 SkIRect devIBounds;
309 SkIPoint16 locationInAtlas;
310 bool transposedInAtlas;
311 SkAssertResult(this->addPathToAtlas(args.fContext, *args.fViewMatrix, path, pathDevBounds,
312 &devIBounds, &locationInAtlas, &transposedInAtlas,
313 nullptr/*DrawRefsAtlasCallback -- see onCanDrawPath()*/));
314
315 const SkIRect& fillBounds = args.fShape->inverseFilled()
316 ? (args.fClip
317 ? args.fClip->getConservativeBounds()
318 : args.fSurfaceDrawContext->asSurfaceProxy()->backingStoreBoundsIRect())
319 : devIBounds;
320 const GrCaps& caps = *args.fSurfaceDrawContext->caps();
321 auto op = GrOp::Make<DrawAtlasPathOp>(args.fContext,
322 args.fSurfaceDrawContext->arenaAlloc(),
323 fillBounds, *args.fViewMatrix,
324 std::move(args.fPaint), locationInAtlas,
325 devIBounds, transposedInAtlas,
326 fAtlasRenderTasks.back()->readView(caps),
327 args.fShape->inverseFilled());
328 args.fSurfaceDrawContext->addDrawOp(args.fClip, std::move(op));
329 return true;
330}
#define SkAssertResult(cond)
Definition SkAssert.h:123

◆ onGetStencilSupport()

StencilSupport skgpu::ganesh::AtlasPathRenderer::onGetStencilSupport ( const GrStyledShape ) const
inlineoverrideprivatevirtual

Subclass overrides if it has any limitations of stenciling support.

Reimplemented from skgpu::ganesh::PathRenderer.

Definition at line 56 of file AtlasPathRenderer.h.

◆ preFlush()

bool skgpu::ganesh::AtlasPathRenderer::preFlush ( GrOnFlushResourceProvider onFlushRP)
overrideprivatevirtual

Implements GrOnFlushCallbackObject.

Definition at line 400 of file AtlasPathRenderer.cpp.

400 {
401 if (fAtlasRenderTasks.empty()) {
402 SkASSERT(fAtlasPathCache.count() == 0);
403 return true;
404 }
405
406 // Verify the atlases can all share the same texture.
407 SkDEBUGCODE(validate_atlas_dependencies(fAtlasRenderTasks);)
408
409 bool successful;
410
411#if defined(GR_TEST_UTILS)
412 if (onFlushRP->failFlushTimeCallbacks()) {
413 successful = false;
414 } else
415#endif
416 {
417 // TODO: it seems like this path renderer's backing-texture reuse could be greatly
418 // improved. Please see skbug.com/13298.
419
420 // Instantiate the first atlas.
421 successful = fAtlasRenderTasks[0]->instantiate(onFlushRP);
422
423 // Instantiate the remaining atlases.
424 GrTexture* firstAtlas = fAtlasRenderTasks[0]->atlasProxy()->peekTexture();
425 SkASSERT(firstAtlas);
426 for (int i = 1; successful && i < fAtlasRenderTasks.size(); ++i) {
427 auto atlasTask = fAtlasRenderTasks[i].get();
428 if (atlasTask->atlasProxy()->backingStoreDimensions() == firstAtlas->dimensions()) {
429 successful &= atlasTask->instantiate(onFlushRP, sk_ref_sp(firstAtlas));
430 } else {
431 // The atlases are expected to all be full size except possibly the final one.
432 SkASSERT(i == fAtlasRenderTasks.size() - 1);
433 SkASSERT(atlasTask->atlasProxy()->backingStoreDimensions().area() <
434 firstAtlas->dimensions().area());
435 // TODO: Recycle the larger atlas texture anyway?
436 successful &= atlasTask->instantiate(onFlushRP);
437 }
438 }
439 }
440
441 // Reset all atlas data.
442 fAtlasRenderTasks.clear();
443 fAtlasPathCache.reset();
444 return successful;
445}
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
SkISize dimensions() const
Definition GrSurface.h:27
constexpr int64_t area() const
Definition SkSize.h:39

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