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

#include <SurfaceDrawContext.h>

Inheritance diagram for skgpu::ganesh::SurfaceDrawContext:
skgpu::ganesh::SurfaceFillContext skgpu::ganesh::SurfaceContext

Public Types

enum class  QuadOptimization { kDiscarded , kSubmitted , kClipApplied , kCropped }
 
using WillAddOpFn = void(GrOp *, uint32_t opsTaskID)
 
- Public Types inherited from skgpu::ganesh::SurfaceContext
using ReadPixelsCallback = SkImage::ReadPixelsCallback
 
using ReadPixelsContext = SkImage::ReadPixelsContext
 
using RescaleGamma = SkImage::RescaleGamma
 
using RescaleMode = SkImage::RescaleMode
 

Public Member Functions

 SurfaceDrawContext (GrRecordingContext *, GrSurfaceProxyView readView, GrSurfaceProxyView writeView, GrColorType, sk_sp< SkColorSpace >, const SkSurfaceProps &)
 
 ~SurfaceDrawContext () override
 
void drawPaint (const GrClip *, GrPaint &&, const SkMatrix &viewMatrix)
 
void drawRect (const GrClip *, GrPaint &&paint, GrAA, const SkMatrix &viewMatrix, const SkRect &, const GrStyle *style=nullptr)
 
void fillRectToRect (const GrClip *, GrPaint &&, GrAA, const SkMatrix &, const SkRect &rectToDraw, const SkRect &localRect)
 
void fillPixelsWithLocalMatrix (const GrClip *clip, GrPaint &&paint, const SkIRect &bounds, const SkMatrix &localMatrix)
 
void fillRectWithEdgeAA (const GrClip *clip, GrPaint &&paint, GrQuadAAFlags edgeAA, const SkMatrix &viewMatrix, const SkRect &rect, const SkRect *optionalLocalRect=nullptr)
 
void fillQuadWithEdgeAA (const GrClip *clip, GrPaint &&paint, GrQuadAAFlags edgeAA, const SkMatrix &viewMatrix, const SkPoint points[4], const SkPoint optionalLocalPoints[4])
 
void drawQuadSet (const GrClip *clip, GrPaint &&paint, const SkMatrix &viewMatrix, const GrQuadSetEntry[], int cnt)
 
void drawTexture (const GrClip *, GrSurfaceProxyView, SkAlphaType, GrSamplerState::Filter, GrSamplerState::MipmapMode, SkBlendMode, const SkPMColor4f &, const SkRect &srcRect, const SkRect &dstRect, GrQuadAAFlags, SkCanvas::SrcRectConstraint, const SkMatrix &, sk_sp< GrColorSpaceXform >)
 
void drawTextureQuad (const GrClip *clip, GrSurfaceProxyView view, GrColorType srcColorType, SkAlphaType srcAlphaType, GrSamplerState::Filter filter, GrSamplerState::MipmapMode mm, SkBlendMode mode, const SkPMColor4f &color, const SkPoint srcQuad[4], const SkPoint dstQuad[4], GrQuadAAFlags edgeAA, const SkRect *subset, const SkMatrix &viewMatrix, sk_sp< GrColorSpaceXform > texXform)
 
void drawTextureSet (const GrClip *, GrTextureSetEntry[], int cnt, int proxyRunCnt, GrSamplerState::Filter, GrSamplerState::MipmapMode, SkBlendMode mode, SkCanvas::SrcRectConstraint, const SkMatrix &viewMatrix, sk_sp< GrColorSpaceXform > texXform)
 
void drawRRect (const GrClip *, GrPaint &&, GrAA, const SkMatrix &viewMatrix, const SkRRect &rrect, const GrStyle &style)
 
bool drawFastShadow (const GrClip *, const SkMatrix &viewMatrix, const SkPath &path, const SkDrawShadowRec &rec)
 
void drawPath (const GrClip *, GrPaint &&, GrAA, const SkMatrix &viewMatrix, const SkPath &, const GrStyle &)
 
void drawShape (const GrClip *, GrPaint &&, GrAA, const SkMatrix &viewMatrix, GrStyledShape &&)
 
void drawVertices (const GrClip *, GrPaint &&paint, const SkMatrix &viewMatrix, sk_sp< SkVertices > vertices, GrPrimitiveType *overridePrimType=nullptr, bool skipColorXform=false)
 
void drawMesh (const GrClip *, GrPaint &&paint, const SkMatrix &viewMatrix, const SkMesh &mesh, skia_private::TArray< std::unique_ptr< GrFragmentProcessor > > children)
 
void drawAtlas (const GrClip *, GrPaint &&paint, const SkMatrix &viewMatrix, int spriteCount, const SkRSXform xform[], const SkRect texRect[], const SkColor colors[])
 
void drawRegion (const GrClip *, GrPaint &&paint, GrAA aa, const SkMatrix &viewMatrix, const SkRegion &region, const GrStyle &style, const GrUserStencilSettings *ss=nullptr)
 
void drawOval (const GrClip *, GrPaint &&paint, GrAA, const SkMatrix &viewMatrix, const SkRect &oval, const GrStyle &style)
 
void drawArc (const GrClip *, GrPaint &&paint, GrAA, const SkMatrix &viewMatrix, const SkRect &oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, const GrStyle &style)
 
void drawImageLattice (const GrClip *, GrPaint &&, const SkMatrix &viewMatrix, GrSurfaceProxyView, SkAlphaType alphaType, sk_sp< GrColorSpaceXform >, GrSamplerState::Filter, std::unique_ptr< SkLatticeIter >, const SkRect &dst)
 
void drawGlyphRunList (SkCanvas *, const GrClip *, const SkMatrix &viewMatrix, const sktext::GlyphRunList &glyphRunList, SkStrikeDeviceInfo strikeDeviceInfo, const SkPaint &paint)
 
void drawDrawable (std::unique_ptr< SkDrawable::GpuDrawHandler >, const SkRect &bounds)
 
void setLastClip (uint32_t clipStackGenID, const SkIRect &devClipBounds, int numClipAnalyticElements)
 
bool mustRenderClip (uint32_t clipStackGenID, const SkIRect &devClipBounds, int numClipAnalyticElements)
 
void clearStencilClip (const SkIRect &scissor, bool insideStencilMask)
 
void stencilRect (const GrClip *clip, const GrUserStencilSettings *ss, GrPaint &&paint, GrAA doStencilMSAA, const SkMatrix &viewMatrix, const SkRect &rect, const SkMatrix *localMatrix=nullptr)
 
bool stencilPath (const GrHardClip *, GrAA doStencilMSAA, const SkMatrix &viewMatrix, const SkPath &)
 
bool drawAndStencilPath (const GrHardClip *, const GrUserStencilSettings *, SkRegion::Op op, bool invert, GrAA doStencilMSAA, const SkMatrix &viewMatrix, const SkPath &)
 
skgpu::Budgeted isBudgeted () const
 
int maxWindowRectangles () const
 
GrSurfaceProxy::UniqueID uniqueID () const
 
void addDrawOp (const GrClip *, GrOp::Owner, const std::function< WillAddOpFn > &=std::function< WillAddOpFn >())
 
void addDrawOp (GrOp::Owner op)
 
bool refsWrappedObjects () const
 
bool waitOnSemaphores (int numSemaphores, const GrBackendSemaphore waitSemaphores[], bool deleteSemaphoresAfterWait)
 
int numSamples () const
 
const SkSurfacePropssurfaceProps () const
 
bool canUseDynamicMSAA () const
 
bool wrapsVkSecondaryCB () const
 
bool alwaysAntialias () const
 
GrAA chooseAA (const SkPaint &paint)
 
GrAAType chooseAAType (GrAA aa)
 
GrRenderTargetaccessRenderTarget ()
 
void drawStrokedLine (const GrClip *, GrPaint &&, GrAA, const SkMatrix &, const SkPoint[2], const SkStrokeRec &)
 
- Public Member Functions inherited from skgpu::ganesh::SurfaceFillContext
 SurfaceFillContext (GrRecordingContext *rContext, GrSurfaceProxyView readView, GrSurfaceProxyView writeView, const GrColorInfo &colorInfo)
 
SurfaceFillContextasFillContext () override
 
OpsTaskgetOpsTask ()
 
void discard ()
 
void resolveMSAA ()
 
template<SkAlphaType AlphaType>
void clear (const SkIRect &rect, const SkRGBA4f< AlphaType > &color)
 
template<SkAlphaType AlphaType>
void clear (const SkRGBA4f< AlphaType > &color)
 
template<SkAlphaType AlphaType>
void clearAtLeast (const SkIRect &scissor, const SkRGBA4f< AlphaType > &color)
 
void fillRectWithFP (const SkIRect &dstRect, std::unique_ptr< GrFragmentProcessor >)
 
void fillRectWithFP (const SkIRect &dstRect, const SkMatrix &localMatrix, std::unique_ptr< GrFragmentProcessor >)
 
void fillRectToRectWithFP (const SkRect &srcRect, const SkIRect &dstRect, std::unique_ptr< GrFragmentProcessor > fp)
 
void fillRectToRectWithFP (const SkIRect &srcRect, const SkIRect &dstRect, std::unique_ptr< GrFragmentProcessor > fp)
 
void fillWithFP (std::unique_ptr< GrFragmentProcessor > fp)
 
bool blitTexture (GrSurfaceProxyView, const SkIRect &srcRect, const SkIPoint &dstPoint)
 
sk_sp< GrRenderTaskrefRenderTask ()
 
int numSamples () const
 
bool wrapsVkSecondaryCB () const
 
SkArenaAllocarenaAlloc ()
 
sktext::gpu::SubRunAllocatorsubRunAlloc ()
 
const GrSurfaceProxyViewwriteSurfaceView () const
 
- Public Member Functions inherited from skgpu::ganesh::SurfaceContext
 SurfaceContext (GrRecordingContext *, GrSurfaceProxyView readView, const GrColorInfo &)
 
virtual ~SurfaceContext ()=default
 
GrRecordingContextrecordingContext () const
 
const GrColorInfocolorInfo () const
 
GrImageInfo imageInfo () const
 
GrSurfaceOrigin origin () const
 
skgpu::Swizzle readSwizzle () const
 
GrSurfaceProxyView readSurfaceView ()
 
SkISize dimensions () const
 
int width () const
 
int height () const
 
skgpu::Mipmapped mipmapped () const
 
const GrCapscaps () const
 
bool readPixels (GrDirectContext *dContext, GrPixmap dst, SkIPoint srcPt)
 
void asyncRescaleAndReadPixels (GrDirectContext *, const SkImageInfo &info, const SkIRect &srcRect, RescaleGamma rescaleGamma, RescaleMode, ReadPixelsCallback callback, ReadPixelsContext callbackContext)
 
void asyncRescaleAndReadPixelsYUV420 (GrDirectContext *, SkYUVColorSpace yuvColorSpace, bool readAlpha, sk_sp< SkColorSpace > dstColorSpace, const SkIRect &srcRect, SkISize dstSize, RescaleGamma rescaleGamma, RescaleMode, ReadPixelsCallback callback, ReadPixelsContext context)
 
bool writePixels (GrDirectContext *dContext, GrCPixmap src, SkIPoint dstPt)
 
bool writePixels (GrDirectContext *dContext, const GrCPixmap src[], int numLevels)
 
GrSurfaceProxyasSurfaceProxy ()
 
const GrSurfaceProxyasSurfaceProxy () const
 
sk_sp< GrSurfaceProxyasSurfaceProxyRef ()
 
GrTextureProxyasTextureProxy ()
 
const GrTextureProxyasTextureProxy () const
 
sk_sp< GrTextureProxyasTextureProxyRef ()
 
GrRenderTargetProxyasRenderTargetProxy ()
 
const GrRenderTargetProxyasRenderTargetProxy () const
 
sk_sp< GrRenderTargetProxyasRenderTargetProxyRef ()
 
std::unique_ptr< SurfaceFillContextrescale (const GrImageInfo &info, GrSurfaceOrigin, SkIRect srcRect, SkImage::RescaleGamma, SkImage::RescaleMode)
 
bool rescaleInto (SurfaceFillContext *dst, SkIRect dstRect, SkIRect srcRect, SkImage::RescaleGamma, SkImage::RescaleMode)
 

Static Public Member Functions

static std::unique_ptr< SurfaceDrawContextMake (GrRecordingContext *, GrColorType, sk_sp< GrSurfaceProxy >, sk_sp< SkColorSpace >, GrSurfaceOrigin, const SkSurfaceProps &)
 
static std::unique_ptr< SurfaceDrawContextMake (GrRecordingContext *, GrColorType, sk_sp< SkColorSpace >, SkBackingFit, SkISize dimensions, const SkSurfaceProps &, std::string_view label, int sampleCnt=1, skgpu::Mipmapped=skgpu::Mipmapped::kNo, skgpu::Protected=skgpu::Protected::kNo, GrSurfaceOrigin=kBottomLeft_GrSurfaceOrigin, skgpu::Budgeted=skgpu::Budgeted::kYes)
 
static std::unique_ptr< SurfaceDrawContextMake (GrRecordingContext *, sk_sp< SkColorSpace >, SkBackingFit, SkISize dimensions, const GrBackendFormat &, int sampleCnt, skgpu::Mipmapped, skgpu::Protected, skgpu::Swizzle readSwizzle, skgpu::Swizzle writeSwizzle, GrSurfaceOrigin, skgpu::Budgeted, const SkSurfaceProps &, std::string_view label)
 
static std::unique_ptr< SurfaceDrawContextMakeWithFallback (GrRecordingContext *, GrColorType, sk_sp< SkColorSpace >, SkBackingFit, SkISize dimensions, const SkSurfaceProps &, int sampleCnt, skgpu::Mipmapped, skgpu::Protected, GrSurfaceOrigin=kBottomLeft_GrSurfaceOrigin, skgpu::Budgeted=skgpu::Budgeted::kYes)
 
static std::unique_ptr< SurfaceDrawContextMakeFromBackendTexture (GrRecordingContext *, GrColorType, sk_sp< SkColorSpace >, const GrBackendTexture &, int sampleCnt, GrSurfaceOrigin, const SkSurfaceProps &, sk_sp< skgpu::RefCntedCallback > releaseHelper)
 

Private Member Functions

void willReplaceOpsTask (OpsTask *prevTask, OpsTask *nextTask) override
 
OpsTask::CanDiscardPreviousOps canDiscardPreviousOpsOnFullClear () const override
 

Additional Inherited Members

- Protected Member Functions inherited from skgpu::ganesh::SurfaceFillContext
OpsTaskreplaceOpsTask ()
 
void addOp (GrOp::Owner)
 
template<SkAlphaType AlphaType>
std::array< float, 4 > adjustColorAlphaType (SkRGBA4f< AlphaType > color) const
 
- Protected Member Functions inherited from skgpu::ganesh::SurfaceContext
GrDrawingManagerdrawingManager ()
 
const GrDrawingManagerdrawingManager () const
 
PixelTransferResult transferPixels (GrColorType colorType, const SkIRect &rect)
 
void asyncReadPixels (GrDirectContext *, const SkIRect &srcRect, SkColorType, ReadPixelsCallback, ReadPixelsContext)
 
- Static Protected Member Functions inherited from skgpu::ganesh::SurfaceFillContext
static void ClearToGrPaint (std::array< float, 4 > color, GrPaint *paint)
 
template<SkAlphaType AlphaType>
static std::array< float, 4 > ConvertColor (SkRGBA4f< AlphaType > color)
 
template<>
std::array< float, 4 > ConvertColor (SkPMColor4f color)
 
template<>
std::array< float, 4 > ConvertColor (SkColor4f color)
 
- Protected Attributes inherited from skgpu::ganesh::SurfaceFillContext
GrSurfaceProxyView fWriteView
 
- Protected Attributes inherited from skgpu::ganesh::SurfaceContext
SkDEBUGCODE(void validate() const ;) SkDEBUGCODE(skgpu GrRecordingContextfContext
 
GrSurfaceProxyView fReadView
 

Detailed Description

A helper object to orchestrate commands (draws, etc...) for GrSurfaces that are GrRenderTargets.

Definition at line 65 of file SurfaceDrawContext.h.

Member Typedef Documentation

◆ WillAddOpFn

using skgpu::ganesh::SurfaceDrawContext::WillAddOpFn = void(GrOp*, uint32_t opsTaskID)

Definition at line 570 of file SurfaceDrawContext.h.

Member Enumeration Documentation

◆ QuadOptimization

Enumerator
kDiscarded 
kSubmitted 
kClipApplied 
kCropped 

Definition at line 388 of file SurfaceDrawContext.cpp.

388 {
389 // The rect to draw doesn't intersect clip or render target, so no draw op should be added
391 // The rect to draw was converted to some other op and appended to the oplist, so no additional
392 // op is necessary. Currently this can convert it to a clear op or a rrect op. Only valid if
393 // a constColor is provided.
395 // The clip was folded into the device quad, with updated edge flags and local coords, and
396 // caller is responsible for adding an appropriate op.
398 // No change to clip, but quad updated to better fit clip/render target, and caller is
399 // responsible for adding an appropriate op.
401};

Constructor & Destructor Documentation

◆ SurfaceDrawContext()

skgpu::ganesh::SurfaceDrawContext::SurfaceDrawContext ( GrRecordingContext rContext,
GrSurfaceProxyView  readView,
GrSurfaceProxyView  writeView,
GrColorType  colorType,
sk_sp< SkColorSpace colorSpace,
const SkSurfaceProps surfaceProps 
)

Definition at line 294 of file SurfaceDrawContext.cpp.

300 : SurfaceFillContext(rContext,
301 std::move(readView),
302 std::move(writeView),
303 {colorType, kPremul_SkAlphaType, std::move(colorSpace)})
304 , fSurfaceProps(surfaceProps)
305 , fCanUseDynamicMSAA(
306 (fSurfaceProps.flags() & SkSurfaceProps::kDynamicMSAA_Flag) &&
307 rContext->priv().caps()->supportsDynamicMSAA(this->asRenderTargetProxy())) {
308 SkDEBUGCODE(this->validate();)
309}
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
const GrCaps * caps() const
bool supportsDynamicMSAA(const GrRenderTargetProxy *) const
Definition GrCaps.cpp:470
GrRecordingContextPriv priv()
uint32_t flags() const
const SkSurfaceProps & surfaceProps() const
SurfaceFillContext(GrRecordingContext *rContext, GrSurfaceProxyView readView, GrSurfaceProxyView writeView, const GrColorInfo &colorInfo)

◆ ~SurfaceDrawContext()

skgpu::ganesh::SurfaceDrawContext::~SurfaceDrawContext ( )
override

Definition at line 311 of file SurfaceDrawContext.cpp.

311 {
313}
#define ASSERT_SINGLE_OWNER
Definition Device.cpp:120

Member Function Documentation

◆ accessRenderTarget()

GrRenderTarget * skgpu::ganesh::SurfaceDrawContext::accessRenderTarget ( )
inline

Definition at line 616 of file SurfaceDrawContext.h.

616{ return this->asSurfaceProxy()->peekRenderTarget(); }
GrRenderTarget * peekRenderTarget() const
GrSurfaceProxy * asSurfaceProxy()

◆ addDrawOp() [1/2]

void skgpu::ganesh::SurfaceDrawContext::addDrawOp ( const GrClip clip,
GrOp::Owner  op,
const std::function< WillAddOpFn > &  willAddFn = std::function<WillAddOpFn>() 
)

Definition at line 1922 of file SurfaceDrawContext.cpp.

1924 {
1926 if (fContext->abandoned()) {
1927 return;
1928 }
1929 GrDrawOp* drawOp = (GrDrawOp*)op.get();
1930 SkDEBUGCODE(this->validate();)
1931 SkDEBUGCODE(drawOp->fAddDrawOpCalled = true;)
1932 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "addDrawOp", fContext);
1933
1934 // Setup clip
1935 SkRect bounds;
1936 op_bounds(&bounds, op.get());
1937 GrAppliedClip appliedClip(this->dimensions(), this->asSurfaceProxy()->backingStoreDimensions());
1938 const bool opUsesMSAA = drawOp->usesMSAA();
1939 bool skipDraw = false;
1940 if (clip) {
1941 // Have a complex clip, so defer to its early clip culling
1942 GrAAType aaType;
1943 if (opUsesMSAA) {
1944 aaType = GrAAType::kMSAA;
1945 } else {
1946 aaType = op->hasAABloat() ? GrAAType::kCoverage : GrAAType::kNone;
1947 }
1948 skipDraw = clip->apply(fContext, this, drawOp, aaType,
1949 &appliedClip, &bounds) == GrClip::Effect::kClippedOut;
1950 } else {
1951 // No clipping, so just clip the bounds against the logical render target dimensions
1952 skipDraw = !bounds.intersect(this->asSurfaceProxy()->getBoundsRect());
1953 }
1954
1955 if (skipDraw) {
1956 return;
1957 }
1958
1959 GrClampType clampType = GrColorTypeClampType(this->colorInfo().colorType());
1960 GrProcessorSet::Analysis analysis = drawOp->finalize(*this->caps(), &appliedClip, clampType);
1961
1962 const bool opUsesStencil = drawOp->usesStencil();
1963
1964 // Always trigger DMSAA when there is stencil. This ensures stencil contents get properly
1965 // preserved between render passes, if needed.
1966 const bool drawNeedsMSAA = opUsesMSAA || (fCanUseDynamicMSAA && opUsesStencil);
1967
1968 // Must be called before setDstProxyView so that it sees the final bounds of the op.
1969 op->setClippedBounds(bounds);
1970
1971 // Determine if the Op will trigger the use of a separate DMSAA attachment that requires manual
1972 // resolves.
1973 // TODO: Currently usesAttachmentIfDMSAA checks if this is a textureProxy or not. This check is
1974 // really only for GL which uses a normal texture sampling when using barriers. For Vulkan it
1975 // is possible to use the msaa buffer as an input attachment even if this is not a texture.
1976 // However, support for that is not fully implemented yet in Vulkan. Once it is, this check
1977 // should change to a virtual caps check that returns whether we need to break up an OpsTask
1978 // if it has barriers and we are about to promote to MSAA.
1979 bool usesAttachmentIfDMSAA =
1980 fCanUseDynamicMSAA &&
1981 (!this->caps()->msaaResolvesAutomatically() || !this->asTextureProxy());
1982 bool opRequiresDMSAAAttachment = usesAttachmentIfDMSAA && drawNeedsMSAA;
1983 bool opTriggersDMSAAAttachment =
1984 opRequiresDMSAAAttachment && !this->getOpsTask()->usesMSAASurface();
1985 if (opTriggersDMSAAAttachment) {
1986 // This will be the op that actually triggers use of a DMSAA attachment. Texture barriers
1987 // can't be moved to a DMSAA attachment, so if there already are any on the current opsTask
1988 // then we need to split.
1989 if (this->getOpsTask()->renderPassXferBarriers() & GrXferBarrierFlags::kTexture) {
1990 SkASSERT(!this->getOpsTask()->isColorNoOp());
1991 this->replaceOpsTask()->setCannotMergeBackward();
1992 }
1993 }
1994
1995 GrDstProxyView dstProxyView;
1996 if (analysis.requiresDstTexture()) {
1997 if (!this->setupDstProxyView(drawOp->bounds(), drawNeedsMSAA, &dstProxyView)) {
1998 return;
1999 }
2000#ifdef SK_DEBUG
2001 if (fCanUseDynamicMSAA && drawNeedsMSAA && !this->caps()->msaaResolvesAutomatically()) {
2002 // Since we aren't literally writing to the render target texture while using a DMSAA
2003 // attachment, we need to resolve that texture before sampling it. Ensure the current
2004 // opsTask got closed off in order to initiate an implicit resolve.
2005 SkASSERT(this->getOpsTask()->isEmpty());
2006 }
2007#endif
2008 }
2009
2010 auto opsTask = this->getOpsTask();
2011 if (willAddFn) {
2012 willAddFn(op.get(), opsTask->uniqueID());
2013 }
2014
2015 // Note if the op needs stencil. Stencil clipping already called setNeedsStencil for itself, if
2016 // needed.
2017 if (opUsesStencil) {
2018 this->setNeedsStencil();
2019 }
2020
2021#if GR_GPU_STATS && defined(GR_TEST_UTILS)
2022 if (fCanUseDynamicMSAA && drawNeedsMSAA) {
2023 if (!opsTask->usesMSAASurface()) {
2024 fContext->priv().dmsaaStats().fNumMultisampleRenderPasses++;
2025 }
2026 fContext->priv().dmsaaStats().fTriggerCounts[op->name()]++;
2027 }
2028#endif
2029
2030 opsTask->addDrawOp(this->drawingManager(), std::move(op), drawNeedsMSAA, analysis,
2031 std::move(appliedClip), dstProxyView,
2032 GrTextureResolveManager(this->drawingManager()), *this->caps());
2033
2034#ifdef SK_DEBUG
2035 if (fCanUseDynamicMSAA && drawNeedsMSAA) {
2036 SkASSERT(opsTask->usesMSAASurface());
2037 }
2038#endif
2039}
#define GR_CREATE_TRACE_MARKER_CONTEXT(classname, op, context)
Definition GrTracing.h:18
GrClampType
GrAAType
static constexpr GrClampType GrColorTypeClampType(GrColorType colorType)
#define SkASSERT(cond)
Definition SkAssert.h:116
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
bool msaaResolvesAutomatically() const
Definition GrCaps.h:100
virtual bool usesMSAA() const
Definition GrDrawOp.h:37
virtual GrProcessorSet::Analysis finalize(const GrCaps &, const GrAppliedClip *, GrClampType)=0
virtual bool usesStencil() const
Definition GrDrawOp.h:82
const SkRect & bounds() const
Definition GrOp.h:122
bool requiresDstTexture() const
bool abandoned() override
bool usesMSAASurface() const
Definition OpsTask.h:51
GrDrawingManager * drawingManager()
SkDEBUGCODE(void validate() const ;) SkDEBUGCODE(skgpu GrRecordingContext * fContext
const GrCaps * caps() const
const GrColorInfo & colorInfo() const
GrTextureProxy * asTextureProxy()
Optional< SkRect > bounds
Definition SkRecords.h:189

◆ addDrawOp() [2/2]

void skgpu::ganesh::SurfaceDrawContext::addDrawOp ( GrOp::Owner  op)
inline

Definition at line 580 of file SurfaceDrawContext.h.

580{ this->addDrawOp(nullptr, std::move(op)); }
void addDrawOp(const GrClip *, GrOp::Owner, const std::function< WillAddOpFn > &=std::function< WillAddOpFn >())

◆ alwaysAntialias()

bool skgpu::ganesh::SurfaceDrawContext::alwaysAntialias ( ) const
inline

Definition at line 596 of file SurfaceDrawContext.h.

596 {
597 return fSurfaceProps.flags() & SkSurfaceProps::kDynamicMSAA_Flag;
598 }

◆ canDiscardPreviousOpsOnFullClear()

OpsTask::CanDiscardPreviousOps skgpu::ganesh::SurfaceDrawContext::canDiscardPreviousOpsOnFullClear ( ) const
overrideprivatevirtual

Override to be called to participate in the decision to discard all previous ops if a fullscreen clear occurs.

Reimplemented from skgpu::ganesh::SurfaceFillContext.

Definition at line 803 of file SurfaceDrawContext.cpp.

803 {
804#if defined(GR_TEST_UTILS)
805 if (fPreserveOpsOnFullClear_TestingOnly) {
807 }
808#endif
809 // Regardless of how the clear is implemented (native clear or a fullscreen quad), all prior ops
810 // would normally be overwritten. The one exception is if the render target context is marked as
811 // needing a stencil buffer then there may be a prior op that writes to the stencil buffer.
812 // Although the clear will ignore the stencil buffer, following draw ops may not so we can't get
813 // rid of all the preceding ops. Beware! If we ever add any ops that have a side effect beyond
814 // modifying the stencil buffer we will need a more elaborate tracking system (skbug.com/7002).
815 return OpsTask::CanDiscardPreviousOps(!fNeedsStencil);
816}

◆ canUseDynamicMSAA()

bool skgpu::ganesh::SurfaceDrawContext::canUseDynamicMSAA ( ) const
inline

Definition at line 593 of file SurfaceDrawContext.h.

593{ return fCanUseDynamicMSAA; }

◆ chooseAA()

GrAA skgpu::ganesh::SurfaceDrawContext::chooseAA ( const SkPaint paint)
inline

Definition at line 600 of file SurfaceDrawContext.h.

600 {
601 return GrAA(paint.isAntiAlias() || this->alwaysAntialias());
602 }
GrAA
const Paint & paint

◆ chooseAAType()

GrAAType skgpu::ganesh::SurfaceDrawContext::chooseAAType ( GrAA  aa)
inline

Definition at line 604 of file SurfaceDrawContext.h.

604 {
605 if (this->numSamples() > 1 || fCanUseDynamicMSAA) {
606 // Always trigger DMSAA when it's available. The coverage ops that know how to handle
607 // both single and multisample targets without popping will do so without calling
608 // chooseAAType.
609 return GrAAType::kMSAA;
610 }
612 }

◆ clearStencilClip()

void skgpu::ganesh::SurfaceDrawContext::clearStencilClip ( const SkIRect scissor,
bool  insideStencilMask 
)
inline

Definition at line 517 of file SurfaceDrawContext.h.

517 {
518 this->internalStencilClear(&scissor, insideStencilMask);
519 }

◆ drawAndStencilPath()

bool skgpu::ganesh::SurfaceDrawContext::drawAndStencilPath ( const GrHardClip clip,
const GrUserStencilSettings ss,
SkRegion::Op  op,
bool  invert,
GrAA  doStencilMSAA,
const SkMatrix viewMatrix,
const SkPath path 
)

Draws a path, either AA or not, and touches the stencil buffer with the user stencil settings for each color sample written.

Definition at line 1589 of file SurfaceDrawContext.cpp.

1595 {
1598 SkDEBUGCODE(this->validate();)
1599 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawAndStencilPath", fContext);
1600
1601 if (path.isEmpty() && path.isInverseFillType()) {
1602 GrPaint paint;
1603 paint.setCoverageSetOpXPFactory(op, invert);
1604 this->stencilRect(clip, ss, std::move(paint), GrAA::kNo, SkMatrix::I(),
1605 SkRect::Make(this->dimensions()));
1606 return true;
1607 }
1608
1609 AutoCheckFlush acf(this->drawingManager());
1610
1611 // An Assumption here is that path renderer would use some form of tweaking
1612 // the src color (either the input alpha or in the frag shader) to implement
1613 // aa. If we have some future driver-mojo path AA that can do the right
1614 // thing WRT to the blend then we'll need some query on the PR.
1615 GrAAType aaType = this->chooseAAType(aa);
1616 bool hasUserStencilSettings = !ss->isUnused();
1617
1618 SkIRect clipConservativeBounds = get_clip_bounds(this, clip);
1619
1620 GrPaint paint;
1621 paint.setCoverageSetOpXPFactory(op, invert);
1622
1623 GrStyledShape shape(path, GrStyle::SimpleFill());
1624 PathRenderer::CanDrawPathArgs canDrawArgs;
1625 canDrawArgs.fCaps = this->caps();
1626 canDrawArgs.fProxy = this->asRenderTargetProxy();
1627 canDrawArgs.fViewMatrix = &viewMatrix;
1628 canDrawArgs.fShape = &shape;
1629 canDrawArgs.fPaint = &paint;
1630 canDrawArgs.fSurfaceProps = &fSurfaceProps;
1631 canDrawArgs.fClipConservativeBounds = &clipConservativeBounds;
1632 canDrawArgs.fAAType = aaType;
1633 canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
1634
1636
1637 // Don't allow the SW renderer
1638 auto pr = this->drawingManager()->getPathRenderer(canDrawArgs,
1639 false,
1640 DrawType::kStencilAndColor);
1641 if (!pr) {
1642 return false;
1643 }
1644
1645 PathRenderer::DrawPathArgs args{this->drawingManager()->getContext(),
1646 std::move(paint),
1647 ss,
1648 this,
1649 clip,
1650 &clipConservativeBounds,
1651 &viewMatrix,
1652 &shape,
1653 aaType,
1654 this->colorInfo().isLinearlyBlended()};
1655 pr->drawPath(args);
1656 return true;
1657}
#define RETURN_FALSE_IF_ABANDONED
bool isLinearlyBlended() const
GrRecordingContext * getContext()
PathRenderer * getPathRenderer(const PathRenderer::CanDrawPathArgs &, bool allowSW, PathRendererChain::DrawType, PathRenderer::StencilSupport *=nullptr)
static const GrStyle & SimpleFill()
Definition GrStyle.h:30
static const SkMatrix & I()
GrRenderTargetProxy * asRenderTargetProxy()
void stencilRect(const GrClip *clip, const GrUserStencilSettings *ss, GrPaint &&paint, GrAA doStencilMSAA, const SkMatrix &viewMatrix, const SkRect &rect, const SkMatrix *localMatrix=nullptr)
gboolean invert
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
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
static SkIRect get_clip_bounds(const SurfaceDrawContext *sdc, const GrClip *clip)
static SkRect Make(const SkISize &size)
Definition SkRect.h:669

◆ drawArc()

void skgpu::ganesh::SurfaceDrawContext::drawArc ( const GrClip clip,
GrPaint &&  paint,
GrAA  aa,
const SkMatrix viewMatrix,
const SkRect oval,
SkScalar  startAngle,
SkScalar  sweepAngle,
bool  useCenter,
const GrStyle style 
)

Draws a partial arc of an oval.

Parameters
paintdescribes how to color pixels.
GrGrAAControls whether the arc is antialiased.
viewMatrixtransformation matrix.
ovalthe bounding rect of the oval.
startAnglestarting angle in degrees.
sweepAngleangle to sweep in degrees. Must be in (-360, 360)
useCentertrue means that the implied path begins at the oval center, connects as a line to the point indicated by the start contains the arc indicated by the sweep angle. If false the line beginning at the center point is omitted.
stylestyle to apply to the oval.

Definition at line 1418 of file SurfaceDrawContext.cpp.

1426 {
1429 SkDEBUGCODE(this->validate();)
1430 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawArc", fContext);
1431
1432 AutoCheckFlush acf(this->drawingManager());
1433
1434#ifndef SK_ENABLE_OPTIMIZE_SIZE
1435 GrAAType aaType = this->chooseAAType(aa);
1436 if (aaType == GrAAType::kCoverage) {
1437 const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
1439 std::move(paint),
1440 viewMatrix,
1441 oval,
1442 startAngle,
1443 sweepAngle,
1444 useCenter,
1445 style,
1446 shaderCaps);
1447 if (op) {
1448 this->addDrawOp(clip, std::move(op));
1449 return;
1450 }
1451 assert_alive(paint);
1452 }
1453#endif
1454 this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix,
1455 GrStyledShape::MakeArc(oval, startAngle, sweepAngle, useCenter,
1456 style, DoSimplify::kNo));
1457}
#define RETURN_IF_ABANDONED
const GrShaderCaps * shaderCaps() const
Definition GrCaps.h:63
std::unique_ptr< GrOp > Owner
Definition GrOp.h:72
static GrOp::Owner MakeArcOp(GrRecordingContext *, GrPaint &&, const SkMatrix &, const SkRect &oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, const GrStyle &, const GrShaderCaps *)
static GrStyledShape MakeArc(const SkRect &oval, SkScalar startAngleDegrees, SkScalar sweepAngleDegrees, bool useCenter, const GrStyle &style, DoSimplify=DoSimplify::kYes)

◆ drawAtlas()

void skgpu::ganesh::SurfaceDrawContext::drawAtlas ( const GrClip clip,
GrPaint &&  paint,
const SkMatrix viewMatrix,
int  spriteCount,
const SkRSXform  xform[],
const SkRect  texRect[],
const SkColor  colors[] 
)

Draws textured sprites from an atlas with a paint. This currently does not support AA for the sprite rectangle edges.

Parameters
paintdescribes how to color pixels.
viewMatrixtransformation matrix
spriteCountnumber of sprites.
xformarray of compressed transformation data, required.
texRectarray of texture rectangles used to access the paint.
colorsoptional array of per-sprite colors, supercedes the paint's color field.

Definition at line 983 of file SurfaceDrawContext.cpp.

989 {
992 SkDEBUGCODE(this->validate();)
993 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawAtlas", fContext);
994
995 AutoCheckFlush acf(this->drawingManager());
996
997 GrAAType aaType = this->chooseAAType(GrAA::kNo);
998 GrOp::Owner op = DrawAtlasOp::Make(fContext, std::move(paint), viewMatrix,
999 aaType, spriteCount, xform, texRect, colors);
1000 this->addDrawOp(clip, std::move(op));
1001}
GrOp::Owner Make(GrRecordingContext *context, GrPaint &&paint, const SkMatrix &viewMatrix, GrAAType aaType, int spriteCount, const SkRSXform *xforms, const SkRect *rects, const SkColor *colors)

◆ drawDrawable()

void skgpu::ganesh::SurfaceDrawContext::drawDrawable ( std::unique_ptr< SkDrawable::GpuDrawHandler drawable,
const SkRect bounds 
)

Adds the necessary signal and wait semaphores and adds the passed in SkDrawable to the command stream.

Definition at line 1481 of file SurfaceDrawContext.cpp.

1482 {
1485 SkDEBUGCODE(this->validate();)
1486 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawDrawable", fContext);
1487 GrOp::Owner op(DrawableOp::Make(fContext, std::move(drawable), bounds));
1488 SkASSERT(op);
1489 this->addOp(std::move(op));
1490}
static DEFINE_OP_CLASS_ID GrOp::Owner Make(GrRecordingContext *, std::unique_ptr< SkDrawable::GpuDrawHandler > drawable, const SkRect &bounds)

◆ drawFastShadow()

bool skgpu::ganesh::SurfaceDrawContext::drawFastShadow ( const GrClip clip,
const SkMatrix viewMatrix,
const SkPath path,
const SkDrawShadowRec rec 
)

Use a fast method to render the ambient and spot shadows for a path. Will return false if not possible for the given path.

Parameters
viewMatrixtransformation matrix
paththe path to shadow
recparameters for shadow rendering

Definition at line 1104 of file SurfaceDrawContext.cpp.

1107 {
1109 if (fContext->abandoned()) {
1110 return true;
1111 }
1112 SkDEBUGCODE(this->validate();)
1113 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawFastShadow", fContext);
1114
1115 // check z plane
1116 bool tiltZPlane = SkToBool(!SkScalarNearlyZero(rec.fZPlaneParams.fX) ||
1118 bool skipAnalytic = SkToBool(rec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
1119 if (tiltZPlane || skipAnalytic || !viewMatrix.rectStaysRect() || !viewMatrix.isSimilarity()) {
1120 return false;
1121 }
1122
1123 SkRRect rrect;
1124 SkRect rect;
1125 // we can only handle rects, circles, and simple rrects with circular corners
1126 bool isRRect = path.isRRect(&rrect) && SkRRectPriv::IsNearlySimpleCircular(rrect) &&
1128 if (!isRRect &&
1129 path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height()) &&
1130 rect.width() > SK_ScalarNearlyZero) {
1131 rrect.setOval(rect);
1132 isRRect = true;
1133 }
1134 if (!isRRect && path.isRect(&rect)) {
1135 rrect.setRect(rect);
1136 isRRect = true;
1137 }
1138
1139 if (!isRRect) {
1140 return false;
1141 }
1142
1143 if (rrect.isEmpty()) {
1144 return true;
1145 }
1146
1147 AutoCheckFlush acf(this->drawingManager());
1148
1149 SkPoint3 devLightPos = rec.fLightPos;
1150 bool directional = SkToBool(rec.fFlags & kDirectionalLight_ShadowFlag);
1151 if (!directional) {
1152 // transform light
1153 viewMatrix.mapPoints((SkPoint*)&devLightPos.fX, 1);
1154 }
1155
1156 // 1/scale
1157 SkScalar devToSrcScale = viewMatrix.isScaleTranslate() ?
1159 sk_float_rsqrt(viewMatrix[SkMatrix::kMScaleX] * viewMatrix[SkMatrix::kMScaleX] +
1160 viewMatrix[SkMatrix::kMSkewX] * viewMatrix[SkMatrix::kMSkewX]);
1161
1162 SkScalar occluderHeight = rec.fZPlaneParams.fZ;
1164
1165 if (SkColorGetA(rec.fAmbientColor) > 0) {
1166 SkScalar devSpaceInsetWidth = SkDrawShadowMetrics::AmbientBlurRadius(occluderHeight);
1167 const SkScalar umbraRecipAlpha = SkDrawShadowMetrics::AmbientRecipAlpha(occluderHeight);
1168 const SkScalar devSpaceAmbientBlur = devSpaceInsetWidth * umbraRecipAlpha;
1169
1170 // Outset the shadow rrect to the border of the penumbra
1171 SkScalar ambientPathOutset = devSpaceInsetWidth * devToSrcScale;
1172 SkRRect ambientRRect;
1173 SkRect outsetRect = rrect.rect().makeOutset(ambientPathOutset, ambientPathOutset);
1174 // If the rrect was an oval then its outset will also be one.
1175 // We set it explicitly to avoid errors.
1176 if (rrect.isOval()) {
1177 ambientRRect = SkRRect::MakeOval(outsetRect);
1178 } else {
1179 SkScalar outsetRad = SkRRectPriv::GetSimpleRadii(rrect).fX + ambientPathOutset;
1180 ambientRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
1181 }
1182
1183 // The ShadowRRectOp still uses 8888 colors, so it might get clamped if the shadow color
1184 // does not fit in bytes after being transformed to the destination color space. This can
1185 // happen if the destination color space is smaller than sRGB, which is highly unlikely.
1187 if (transparent) {
1188 // set a large inset to force a fill
1189 devSpaceInsetWidth = ambientRRect.width();
1190 }
1191
1193 ambientColor,
1194 viewMatrix,
1195 ambientRRect,
1196 devSpaceAmbientBlur,
1197 devSpaceInsetWidth);
1198 if (op) {
1199 this->addDrawOp(clip, std::move(op));
1200 }
1201 }
1202
1203 if (SkColorGetA(rec.fSpotColor) > 0) {
1204 SkScalar devSpaceSpotBlur;
1205 SkScalar spotScale;
1206 SkVector spotOffset;
1207 if (directional) {
1208 SkDrawShadowMetrics::GetDirectionalParams(occluderHeight, devLightPos.fX,
1209 devLightPos.fY, devLightPos.fZ,
1210 rec.fLightRadius, &devSpaceSpotBlur,
1211 &spotScale, &spotOffset);
1212 } else {
1213 SkDrawShadowMetrics::GetSpotParams(occluderHeight, devLightPos.fX, devLightPos.fY,
1214 devLightPos.fZ, rec.fLightRadius,
1215 &devSpaceSpotBlur, &spotScale, &spotOffset);
1216 }
1217 // handle scale of radius due to CTM
1218 const SkScalar srcSpaceSpotBlur = devSpaceSpotBlur * devToSrcScale;
1219
1220 // Adjust translate for the effect of the scale.
1221 spotOffset.fX += spotScale*viewMatrix[SkMatrix::kMTransX];
1222 spotOffset.fY += spotScale*viewMatrix[SkMatrix::kMTransY];
1223 // This offset is in dev space, need to transform it into source space.
1224 SkMatrix ctmInverse;
1225 if (viewMatrix.invert(&ctmInverse)) {
1226 ctmInverse.mapPoints(&spotOffset, 1);
1227 } else {
1228 // Since the matrix is a similarity, this should never happen, but just in case...
1229 SkDebugf("Matrix is degenerate. Will not render spot shadow correctly!\n");
1230 SkASSERT(false);
1231 }
1232
1233 // Compute the transformed shadow rrect
1234 SkRRect spotShadowRRect;
1235 SkMatrix shadowTransform;
1236 shadowTransform.setScaleTranslate(spotScale, spotScale, spotOffset.fX, spotOffset.fY);
1237 rrect.transform(shadowTransform, &spotShadowRRect);
1238 SkScalar spotRadius = spotShadowRRect.getSimpleRadii().fX;
1239
1240 // Compute the insetWidth
1241 SkScalar blurOutset = srcSpaceSpotBlur;
1242 SkScalar insetWidth = blurOutset;
1243 if (transparent) {
1244 // If transparent, just do a fill
1245 insetWidth += spotShadowRRect.width();
1246 } else {
1247 // For shadows, instead of using a stroke we specify an inset from the penumbra
1248 // border. We want to extend this inset area so that it meets up with the caster
1249 // geometry. The inset geometry will by default already be inset by the blur width.
1250 //
1251 // We compare the min and max corners inset by the radius between the original
1252 // rrect and the shadow rrect. The distance between the two plus the difference
1253 // between the scaled radius and the original radius gives the distance from the
1254 // transformed shadow shape to the original shape in that corner. The max
1255 // of these gives the maximum distance we need to cover.
1256 //
1257 // Since we are outsetting by 1/2 the blur distance, we just add the maxOffset to
1258 // that to get the full insetWidth.
1259 SkScalar maxOffset;
1260 if (rrect.isRect()) {
1261 // Manhattan distance works better for rects
1262 maxOffset = std::max(std::max(SkTAbs(spotShadowRRect.rect().fLeft -
1263 rrect.rect().fLeft),
1264 SkTAbs(spotShadowRRect.rect().fTop -
1265 rrect.rect().fTop)),
1266 std::max(SkTAbs(spotShadowRRect.rect().fRight -
1267 rrect.rect().fRight),
1268 SkTAbs(spotShadowRRect.rect().fBottom -
1269 rrect.rect().fBottom)));
1270 } else {
1271 SkScalar dr = spotRadius - SkRRectPriv::GetSimpleRadii(rrect).fX;
1272 SkPoint upperLeftOffset = SkPoint::Make(spotShadowRRect.rect().fLeft -
1273 rrect.rect().fLeft + dr,
1274 spotShadowRRect.rect().fTop -
1275 rrect.rect().fTop + dr);
1276 SkPoint lowerRightOffset = SkPoint::Make(spotShadowRRect.rect().fRight -
1277 rrect.rect().fRight - dr,
1278 spotShadowRRect.rect().fBottom -
1279 rrect.rect().fBottom - dr);
1280 maxOffset = SkScalarSqrt(std::max(SkPointPriv::LengthSqd(upperLeftOffset),
1281 SkPointPriv::LengthSqd(lowerRightOffset))) + dr;
1282 }
1283 insetWidth += std::max(blurOutset, maxOffset);
1284 }
1285
1286 // Outset the shadow rrect to the border of the penumbra
1287 SkRect outsetRect = spotShadowRRect.rect().makeOutset(blurOutset, blurOutset);
1288 if (spotShadowRRect.isOval()) {
1289 spotShadowRRect = SkRRect::MakeOval(outsetRect);
1290 } else {
1291 SkScalar outsetRad = spotRadius + blurOutset;
1292 spotShadowRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
1293 }
1294
1295 // The ShadowRRectOp still uses 8888 colors, so it might get clamped if the shadow color
1296 // does not fit in bytes after being transformed to the destination color space. This can
1297 // happen if the destination color space is smaller than sRGB, which is highly unlikely.
1300 spotColor,
1301 viewMatrix,
1302 spotShadowRRect,
1303 2.0f * devSpaceSpotBlur,
1304 insetWidth);
1305 if (op) {
1306 this->addDrawOp(clip, std::move(op));
1307 }
1308 }
1309
1310 return true;
1311}
uint32_t GrColor
Definition GrColor.h:25
#define SkColorGetA(color)
Definition SkColor.h:61
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static float sk_float_rsqrt(float x)
SkPMColor4f SkColorToPMColor4f(SkColor c, const GrColorInfo &colorInfo)
Definition SkGr.cpp:275
#define SkScalarInvert(x)
Definition SkScalar.h:73
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:101
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:107
#define SK_ScalarNearlyZero
Definition SkScalar.h:99
#define SkScalarSqrt(x)
Definition SkScalar.h:42
#define SkScalarAbs(x)
Definition SkScalar.h:39
@ kDirectionalLight_ShadowFlag
@ kGeometricOnly_ShadowFlag
@ kTransparentOccluder_ShadowFlag
static T SkTAbs(T value)
Definition SkTemplates.h:43
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
static constexpr int kMScaleX
horizontal scale factor
Definition SkMatrix.h:353
static constexpr int kMTransY
vertical translation
Definition SkMatrix.h:358
void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
Definition SkMatrix.h:1803
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
Definition SkMatrix.cpp:770
bool rectStaysRect() const
Definition SkMatrix.h:271
bool isScaleTranslate() const
Definition SkMatrix.h:236
static constexpr int kMTransX
horizontal translation
Definition SkMatrix.h:355
bool isSimilarity(SkScalar tol=SK_ScalarNearlyZero) const
Definition SkMatrix.cpp:180
static SkScalar LengthSqd(const SkPoint &pt)
Definition SkPointPriv.h:63
static SkVector GetSimpleRadii(const SkRRect &rr)
Definition SkRRectPriv.h:22
static bool IsNearlySimpleCircular(const SkRRect &rr, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkRRect.cpp:342
SkVector getSimpleRadii() const
Definition SkRRect.h:111
bool isOval() const
Definition SkRRect.h:85
const SkRect & rect() const
Definition SkRRect.h:264
static SkRRect MakeOval(const SkRect &oval)
Definition SkRRect.h:162
bool transform(const SkMatrix &matrix, SkRRect *dst) const
Definition SkRRect.cpp:436
void setOval(const SkRect &oval)
Definition SkRRect.cpp:30
SkScalar width() const
Definition SkRRect.h:95
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition SkRRect.h:180
bool isRect() const
Definition SkRRect.h:84
bool isEmpty() const
Definition SkRRect.h:83
void setRect(const SkRect &rect)
Definition SkRRect.h:126
float SkScalar
Definition extension.cpp:12
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)
SkRRect rrect
Definition SkRecords.h:232
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350
GrOp::Owner Make(GrRecordingContext *context, GrColor color, const SkMatrix &viewMatrix, const SkRRect &rrect, SkScalar blurWidth, SkScalar insetWidth)
SkScalar fX
Definition SkPoint3.h:16
SkScalar fZ
Definition SkPoint3.h:16
SkScalar fY
Definition SkPoint3.h:16
float fX
x-axis value
static constexpr SkPoint Make(float x, float y)
float fY
y-axis value
uint32_t toBytes_RGBA() const
SkScalar fBottom
larger y-axis bounds
Definition extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition extension.cpp:14
SkRect makeOutset(float dx, float dy) const
Definition SkRect.h:1002
SkScalar fRight
larger x-axis bounds
Definition extension.cpp:16
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15

◆ drawGlyphRunList()

void skgpu::ganesh::SurfaceDrawContext::drawGlyphRunList ( SkCanvas canvas,
const GrClip clip,
const SkMatrix viewMatrix,
const sktext::GlyphRunList glyphRunList,
SkStrikeDeviceInfo  strikeDeviceInfo,
const SkPaint paint 
)

Draw the text specified by the GlyphRunList.

Parameters
viewMatrixtransformation matrix
glyphRunListtext, text positions, and paint.

Definition at line 331 of file SurfaceDrawContext.cpp.

336 {
339 SkDEBUGCODE(this->validate();)
340 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawGlyphRunList", fContext);
341
342 // Drawing text can cause us to do inline uploads. This is not supported for wrapped vulkan
343 // secondary command buffers because it would require stopping and starting a render pass which
344 // we don't have access to.
345 if (this->wrapsVkSecondaryCB()) {
346 return;
347 }
348
350
351 auto atlasDelegate = [&](const sktext::gpu::AtlasSubRun* subRun,
352 SkPoint drawOrigin,
353 const SkPaint& paint,
354 sk_sp<SkRefCnt> subRunStorage,
356 auto [drawingClip, op] = subRun->makeAtlasTextOp(
357 clip, viewMatrix, drawOrigin, paint, std::move(subRunStorage), this);
358 if (op != nullptr) {
359 this->addDrawOp(drawingClip, std::move(op));
360 }
361 };
362
363 textBlobCache->drawGlyphRunList(
364 canvas, viewMatrix, glyphRunList, paint, strikeDeviceInfo, atlasDelegate);
365}
sktext::gpu::TextBlobRedrawCoordinator * getTextBlobCache()
void drawGlyphRunList(SkCanvas *canvas, const SkMatrix &viewMatrix, const GlyphRunList &glyphRunList, const SkPaint &paint, SkStrikeDeviceInfo strikeDeviceInfo, const AtlasDrawDelegate &)

◆ drawImageLattice()

void skgpu::ganesh::SurfaceDrawContext::drawImageLattice ( const GrClip clip,
GrPaint &&  paint,
const SkMatrix viewMatrix,
GrSurfaceProxyView  view,
SkAlphaType  alphaType,
sk_sp< GrColorSpaceXform csxf,
GrSamplerState::Filter  filter,
std::unique_ptr< SkLatticeIter iter,
const SkRect dst 
)

Draw the image as a set of rects, specified by |iter|.

Definition at line 1459 of file SurfaceDrawContext.cpp.

1467 {
1470 SkDEBUGCODE(this->validate();)
1471 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawImageLattice", fContext);
1472
1473 AutoCheckFlush acf(this->drawingManager());
1474
1475 GrOp::Owner op =
1476 LatticeOp::MakeNonAA(fContext, std::move(paint), viewMatrix, std::move(view),
1477 alphaType, std::move(csxf), filter, std::move(iter), dst);
1478 this->addDrawOp(clip, std::move(op));
1479}
GrOp::Owner MakeNonAA(GrRecordingContext *context, GrPaint &&paint, const SkMatrix &viewMatrix, GrSurfaceProxyView view, SkAlphaType alphaType, sk_sp< GrColorSpaceXform > colorSpaceXform, GrSamplerState::Filter filter, std::unique_ptr< SkLatticeIter > iter, const SkRect &dst)

◆ drawMesh()

void skgpu::ganesh::SurfaceDrawContext::drawMesh ( const GrClip clip,
GrPaint &&  paint,
const SkMatrix viewMatrix,
const SkMesh mesh,
skia_private::TArray< std::unique_ptr< GrFragmentProcessor > >  children 
)

Draws a custom mesh with a paint.

Parameters
paintdescribes how to color pixels.
viewMatrixtransformation matrix
meshthe mesh to draw.
childrenchild effects referenced by SkMesh shaders

Definition at line 952 of file SurfaceDrawContext.cpp.

956 {
959 SkDEBUGCODE(this->validate();)
960 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawMesh", fContext);
961
962 AutoCheckFlush acf(this->drawingManager());
963
964 SkASSERT(mesh.isValid());
965
968 this->colorInfo().colorSpace(),
969 this->colorInfo().alphaType());
970 GrAAType aaType = fCanUseDynamicMSAA ? GrAAType::kMSAA : this->chooseAAType(GrAA::kNo);
972 std::move(paint),
973 mesh,
974 std::move(children),
975 viewMatrix,
976 aaType,
977 std::move(xform));
978 this->addDrawOp(clip, std::move(op));
979}
static sk_sp< GrColorSpaceXform > Make(SkColorSpace *src, SkAlphaType srcAT, SkColorSpace *dst, SkAlphaType dstAT)
bool isValid() const
Definition SkMesh.cpp:753
SkMeshSpecification * spec() const
Definition SkMesh.h:348
SkMesh mesh
Definition SkRecords.h:345
GrOp::Owner Make(GrRecordingContext *context, GrPaint &&paint, const SkMesh &mesh, TArray< std::unique_ptr< GrFragmentProcessor > > children, const SkMatrix &viewMatrix, GrAAType aaType, sk_sp< GrColorSpaceXform > colorSpaceXform)
static SkAlphaType AlphaType(const SkMeshSpecification &spec)
Definition SkMeshPriv.h:38
static SkColorSpace * ColorSpace(const SkMeshSpecification &spec)
Definition SkMeshPriv.h:34

◆ drawOval()

void skgpu::ganesh::SurfaceDrawContext::drawOval ( const GrClip clip,
GrPaint &&  paint,
GrAA  aa,
const SkMatrix viewMatrix,
const SkRect oval,
const GrStyle style 
)

Draws an oval.

Parameters
paintdescribes how to color pixels.
GrAAControls whether the oval is antialiased.
viewMatrixtransformation matrix
ovalthe bounding rect of the oval.
stylestyle to apply to the oval. Currently path effects are not allowed.

Definition at line 1350 of file SurfaceDrawContext.cpp.

1355 {
1358 SkDEBUGCODE(this->validate();)
1359 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawOval", fContext);
1360
1361 const SkStrokeRec& stroke = style.strokeRec();
1362
1363 if (oval.isEmpty() && !style.pathEffect()) {
1364 if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
1365 return;
1366 }
1367
1368 this->drawRect(clip, std::move(paint), aa, viewMatrix, oval, &style);
1369 return;
1370 }
1371
1372 AutoCheckFlush acf(this->drawingManager());
1373
1374 GrAAType aaType = this->chooseAAType(aa);
1375
1376 GrOp::Owner op;
1377#ifndef SK_ENABLE_OPTIMIZE_SIZE
1378 if (aaType == GrAAType::kCoverage &&
1379 !fCanUseDynamicMSAA &&
1380 !this->caps()->reducedShaderMode() &&
1382 oval.width() == oval.height() &&
1383 viewMatrix.isSimilarity()) {
1384 // In specific cases we use a dedicated circle op to try and get better perf.
1385 assert_alive(paint);
1386 op = GrOvalOpFactory::MakeCircleOp(fContext, std::move(paint), viewMatrix, oval, style,
1387 this->caps()->shaderCaps());
1388 }
1389#endif
1390 if (!op && style.isSimpleFill()) {
1391 // FillRRectOp has special geometry and a fragment-shader branch to conditionally evaluate
1392 // the arc equation. This same special geometry and fragment branch also turn out to be a
1393 // substantial optimization for drawing ovals (namely, by not evaluating the arc equation
1394 // inside the oval's inner diamond). Given these optimizations, it's a clear win to draw
1395 // ovals the exact same way we do round rects.
1396 assert_alive(paint);
1397 op = FillRRectOp::Make(fContext, this->arenaAlloc(), std::move(paint), viewMatrix,
1398 SkRRect::MakeOval(oval), oval, GrAA(aaType != GrAAType::kNone));
1399 }
1400#ifndef SK_ENABLE_OPTIMIZE_SIZE
1401 if (!op && (aaType == GrAAType::kCoverage || fCanUseDynamicMSAA)) {
1402 assert_alive(paint);
1403 op = GrOvalOpFactory::MakeOvalOp(fContext, std::move(paint), viewMatrix, oval, style,
1404 this->caps()->shaderCaps());
1405 }
1406#endif
1407 if (op) {
1408 this->addDrawOp(clip, std::move(op));
1409 return;
1410 }
1411
1412 assert_alive(paint);
1413 this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix,
1415 false, style, DoSimplify::kNo));
1416}
static GrOp::Owner MakeOvalOp(GrRecordingContext *, GrPaint &&, const SkMatrix &, const SkRect &oval, const GrStyle &style, const GrShaderCaps *)
static GrOp::Owner MakeCircleOp(GrRecordingContext *, GrPaint &&, const SkMatrix &, const SkRect &oval, const GrStyle &style, const GrShaderCaps *)
SkPathEffect * pathEffect() const
Definition GrStyle.h:119
bool isSimpleFill() const
Definition GrStyle.h:114
const SkStrokeRec & strokeRec() const
Definition GrStyle.h:140
Style getStyle() const
void drawRect(const GrClip *, GrPaint &&paint, GrAA, const SkMatrix &viewMatrix, const SkRect &, const GrStyle *style=nullptr)
SkRect oval
Definition SkRecords.h:249
GrOp::Owner Make(GrRecordingContext *ctx, SkArenaAlloc *arena, GrPaint &&paint, const SkMatrix &viewMatrix, const SkRRect &rrect, const SkRect &localRect, GrAA aa)
constexpr float height() const
Definition SkRect.h:769
constexpr float width() const
Definition SkRect.h:762
bool isEmpty() const
Definition SkRect.h:693

◆ drawPaint()

void skgpu::ganesh::SurfaceDrawContext::drawPaint ( const GrClip clip,
GrPaint &&  paint,
const SkMatrix viewMatrix 
)

Draw everywhere (respecting the clip) with the paint.

Definition at line 367 of file SurfaceDrawContext.cpp.

369 {
370 // Start with the render target, since that is the maximum content we could possibly fill.
371 // drawFilledQuad() will automatically restrict it to clip bounds for us if possible.
372 if (!paint.numTotalFragmentProcessors()) {
373 // The paint is trivial so we won't need to use local coordinates, so skip calculating the
374 // inverse view matrix.
375 SkRect r = this->asSurfaceProxy()->getBoundsRect();
376 this->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), r, r);
377 } else {
378 // Use the inverse view matrix to arrive at appropriate local coordinates for the paint.
379 SkMatrix localMatrix;
380 if (!viewMatrix.invert(&localMatrix)) {
381 return;
382 }
384 this->fillPixelsWithLocalMatrix(clip, std::move(paint), bounds, localMatrix);
385 }
386}
SkRect getBoundsRect() const
bool invert(SkMatrix *inverse) const
Definition SkMatrix.h:1206
void fillPixelsWithLocalMatrix(const GrClip *clip, GrPaint &&paint, const SkIRect &bounds, const SkMatrix &localMatrix)
void fillRectToRect(const GrClip *, GrPaint &&, GrAA, const SkMatrix &, const SkRect &rectToDraw, const SkRect &localRect)
static constexpr SkIRect MakeSize(const SkISize &size)
Definition SkRect.h:66

◆ drawPath()

void skgpu::ganesh::SurfaceDrawContext::drawPath ( const GrClip clip,
GrPaint &&  paint,
GrAA  aa,
const SkMatrix viewMatrix,
const SkPath path,
const GrStyle style 
)

Draws a path.

Parameters
paintdescribes how to color pixels.
GrAAControls whether the path is antialiased.
viewMatrixtransformation matrix
paththe path to draw
stylestyle to apply to the path.

Definition at line 1546 of file SurfaceDrawContext.cpp.

1551 {
1554 SkDEBUGCODE(this->validate();)
1555 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawPath", fContext);
1556
1557 GrStyledShape shape(path, style, DoSimplify::kNo);
1558 this->drawShape(clip, std::move(paint), aa, viewMatrix, std::move(shape));
1559}
void drawShape(const GrClip *, GrPaint &&, GrAA, const SkMatrix &viewMatrix, GrStyledShape &&)

◆ drawQuadSet()

void skgpu::ganesh::SurfaceDrawContext::drawQuadSet ( const GrClip clip,
GrPaint &&  paint,
const SkMatrix viewMatrix,
const GrQuadSetEntry  quads[],
int  cnt 
)

Definition at line 788 of file SurfaceDrawContext.cpp.

792 {
793 GrAAType aaType = this->chooseAAType(GrAA::kYes);
794
795 FillRectOp::AddFillRectOps(this, clip, fContext, std::move(paint), aaType, viewMatrix,
796 quads, cnt);
797}
static void AddFillRectOps(SurfaceDrawContext *, const GrClip *, GrRecordingContext *, GrPaint &&, GrAAType, const SkMatrix &viewMatrix, const GrQuadSetEntry quads[], int quadCount, const GrUserStencilSettings *=nullptr)

◆ drawRect()

void skgpu::ganesh::SurfaceDrawContext::drawRect ( const GrClip clip,
GrPaint &&  paint,
GrAA  aa,
const SkMatrix viewMatrix,
const SkRect rect,
const GrStyle style = nullptr 
)

Draw the rect using a paint.

Parameters
paintdescribes how to color pixels.
GrAAControls whether rect is antialiased
viewMatrixtransformation matrix
styleThe style to apply. Null means fill. Currently path effects are not allowed. The rects coords are used to access the paint (through texture matrix)

Definition at line 679 of file SurfaceDrawContext.cpp.

684 {
685 if (!style) {
686 style = &GrStyle::SimpleFill();
687 }
690 SkDEBUGCODE(this->validate();)
691 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawRect", fContext);
692
693 // Path effects should've been devolved to a path in SkGpuDevice
694 SkASSERT(!style->pathEffect());
695
696 AutoCheckFlush acf(this->drawingManager());
697
698 const SkStrokeRec& stroke = style->strokeRec();
699 if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
700 // Fills the rect, using rect as its own local coordinates
701 this->fillRectToRect(clip, std::move(paint), aa, viewMatrix, rect, rect);
702 return;
703 } else if ((stroke.getStyle() == SkStrokeRec::kStroke_Style ||
705 rect.width() &&
706 rect.height() &&
707 !this->caps()->reducedShaderMode()) {
708 // Only use the StrokeRectOp for non-empty rectangles. Empty rectangles will be processed by
709 // GrStyledShape to handle stroke caps and dashing properly.
710 //
711 // http://skbug.com/12206 -- there is a double-blend issue with the bevel version of
712 // AAStrokeRectOp, and if we increase the AA bloat for MSAA it becomes more pronounced.
713 // Don't use the bevel version with DMSAA.
714 GrAAType aaType = (fCanUseDynamicMSAA &&
715 stroke.getJoin() == SkPaint::kMiter_Join &&
717 : this->chooseAAType(aa);
718 GrOp::Owner op = ganesh::StrokeRectOp::Make(fContext, std::move(paint), aaType, viewMatrix,
719 rect, stroke);
720 // op may be null if the stroke is not supported or if using coverage aa and the view matrix
721 // does not preserve rectangles.
722 if (op) {
723 this->addDrawOp(clip, std::move(op));
724 return;
725 }
726 }
727 assert_alive(paint);
728 this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix,
729 GrStyledShape(rect, *style, DoSimplify::kNo));
730}
#define SK_ScalarSqrt2
Definition SkScalar.h:20
@ kMiter_Join
extends to miter limit
Definition SkPaint.h:359
SkPaint::Join getJoin() const
Definition SkStrokeRec.h:45
SkScalar getMiter() const
Definition SkStrokeRec.h:43
GrOp::Owner Make(GrRecordingContext *context, GrPaint &&paint, GrAAType aaType, const SkMatrix &viewMatrix, const SkRect &rect, const SkStrokeRec &stroke)

◆ drawRegion()

void skgpu::ganesh::SurfaceDrawContext::drawRegion ( const GrClip clip,
GrPaint &&  paint,
GrAA  aa,
const SkMatrix viewMatrix,
const SkRegion region,
const GrStyle style,
const GrUserStencilSettings ss = nullptr 
)

Draws a region.

Parameters
paintdescribes how to color pixels
viewMatrixtransformation matrix
aashould the rects of the region be antialiased.
regionthe region to be drawn
stylestyle to apply to the region

Definition at line 1315 of file SurfaceDrawContext.cpp.

1321 {
1324 SkDEBUGCODE(this->validate();)
1325 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawRegion", fContext);
1326
1327 if (GrAA::kYes == aa) {
1328 // GrRegionOp performs no antialiasing but is much faster, so here we check the matrix
1329 // to see whether aa is really required.
1330 if (!SkToBool(viewMatrix.getType() & ~(SkMatrix::kTranslate_Mask)) &&
1331 SkScalarIsInt(viewMatrix.getTranslateX()) &&
1332 SkScalarIsInt(viewMatrix.getTranslateY())) {
1333 aa = GrAA::kNo;
1334 }
1335 }
1336 bool complexStyle = !style.isSimpleFill();
1337 if (complexStyle || GrAA::kYes == aa) {
1338 SkPath path;
1339 region.getBoundaryPath(&path);
1340 path.setIsVolatile(true);
1341
1342 return this->drawPath(clip, std::move(paint), aa, viewMatrix, path, style);
1343 }
1344
1345 GrAAType aaType = (this->numSamples() > 1) ? GrAAType::kMSAA : GrAAType::kNone;
1346 GrOp::Owner op = RegionOp::Make(fContext, std::move(paint), viewMatrix, region, aaType, ss);
1347 this->addDrawOp(clip, std::move(op));
1348}
static bool SkScalarIsInt(SkScalar x)
Definition SkScalar.h:80
SkScalar getTranslateY() const
Definition SkMatrix.h:452
SkScalar getTranslateX() const
Definition SkMatrix.h:445
@ kTranslate_Mask
translation SkMatrix
Definition SkMatrix.h:193
TypeMask getType() const
Definition SkMatrix.h:207
bool getBoundaryPath(SkPath *path) const
void drawPath(const GrClip *, GrPaint &&, GrAA, const SkMatrix &viewMatrix, const SkPath &, const GrStyle &)
ClipOpAndAA opAA SkRegion region
Definition SkRecords.h:238
GrOp::Owner Make(GrRecordingContext *context, GrPaint &&paint, const SkMatrix &viewMatrix, const SkRegion &region, GrAAType aaType, const GrUserStencilSettings *stencilSettings)
Definition RegionOp.cpp:204

◆ drawRRect()

void skgpu::ganesh::SurfaceDrawContext::drawRRect ( const GrClip origClip,
GrPaint &&  paint,
GrAA  aa,
const SkMatrix viewMatrix,
const SkRRect rrect,
const GrStyle style 
)

Draw a roundrect using a paint.

Parameters
paintdescribes how to color pixels.
GrAAControls whether rrect is antialiased.
viewMatrixtransformation matrix
rrectthe roundrect to draw
stylestyle to apply to the rrect. Currently path effects are not allowed.

Definition at line 1005 of file SurfaceDrawContext.cpp.

1010 {
1013 SkDEBUGCODE(this->validate();)
1014 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawRRect", fContext);
1015
1016 SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice
1017
1018 const SkStrokeRec& stroke = style.strokeRec();
1019 if (stroke.getStyle() == SkStrokeRec::kFill_Style && rrect.isEmpty()) {
1020 return;
1021 }
1022
1023 const GrClip* clip = origClip;
1024 // It is not uncommon to clip to a round rect and then draw that same round rect. Since our
1025 // lower level clip code works from op bounds, which are SkRects, it doesn't detect that the
1026 // clip can be ignored. The following test attempts to mitigate the stencil clip cost but only
1027 // works for axis-aligned round rects. This also only works for filled rrects since the stroke
1028 // width outsets beyond the rrect itself.
1029 // TODO: skbug.com/10462 - There was mixed performance wins and regressions when this
1030 // optimization was turned on outside of Android Framework. I (michaelludwig) believe this is
1031 // do to the overhead in determining if an SkClipStack is just a rrect. Once that is improved,
1032 // re-enable this and see if we avoid the regressions.
1033#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
1034 SkRRect devRRect;
1035 if (clip && stroke.getStyle() == SkStrokeRec::kFill_Style &&
1036 rrect.transform(viewMatrix, &devRRect)) {
1037 GrClip::PreClipResult result = clip->preApply(devRRect.getBounds(), aa);
1038 switch(result.fEffect) {
1040 return;
1042 clip = nullptr;
1043 break;
1045 // Currently there's no general-purpose rrect-to-rrect contains function, and if we
1046 // got here, we know the devRRect's bounds aren't fully contained by the clip.
1047 // Testing for equality between the two is a reasonable stop-gap for now.
1048 if (result.fIsRRect && result.fRRect == devRRect) {
1049 // NOTE: On the android framework, we allow this optimization even when the clip
1050 // is non-AA and the draw is AA.
1051 if (result.fAA == aa || (result.fAA == GrAA::kNo && aa == GrAA::kYes)) {
1052 clip = nullptr;
1053 }
1054 }
1055 break;
1056 default:
1058 }
1059 }
1060#endif
1061
1062 AutoCheckFlush acf(this->drawingManager());
1063
1064 GrAAType aaType = this->chooseAAType(aa);
1065
1066 GrOp::Owner op;
1067#ifndef SK_ENABLE_OPTIMIZE_SIZE
1068 if (aaType == GrAAType::kCoverage &&
1069 !fCanUseDynamicMSAA &&
1070 !this->caps()->reducedShaderMode() &&
1071 rrect.isSimple() &&
1073 viewMatrix.rectStaysRect() && viewMatrix.isSimilarity()) {
1074 // In specific cases we use a dedicated circular round rect op to try and get better perf.
1075 assert_alive(paint);
1076 op = GrOvalOpFactory::MakeCircularRRectOp(fContext, std::move(paint), viewMatrix, rrect,
1077 stroke, this->caps()->shaderCaps());
1078 }
1079#endif
1080 if (!op && style.isSimpleFill()) {
1081 assert_alive(paint);
1082 op = FillRRectOp::Make(fContext, this->arenaAlloc(), std::move(paint), viewMatrix, rrect,
1083 rrect.rect(), GrAA(aaType != GrAAType::kNone));
1084 }
1085#ifndef SK_ENABLE_OPTIMIZE_SIZE
1086 if (!op && (aaType == GrAAType::kCoverage || fCanUseDynamicMSAA)) {
1087 assert_alive(paint);
1089 fContext, std::move(paint), viewMatrix, rrect, stroke, this->caps()->shaderCaps());
1090 }
1091#endif
1092 if (op) {
1093 this->addDrawOp(clip, std::move(op));
1094 return;
1095 }
1096
1097 assert_alive(paint);
1098 this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix,
1099 GrStyledShape(rrect, style, DoSimplify::kNo));
1100}
#define SkUNREACHABLE
Definition SkAssert.h:135
static GrOp::Owner MakeCircularRRectOp(GrRecordingContext *, GrPaint &&, const SkMatrix &, const SkRRect &, const SkStrokeRec &, const GrShaderCaps *)
static GrOp::Owner MakeRRectOp(GrRecordingContext *, GrPaint &&, const SkMatrix &, const SkRRect &, const SkStrokeRec &, const GrShaderCaps *)
const SkRect & getBounds() const
Definition SkRRect.h:279
bool isSimple() const
Definition SkRRect.h:86
GAsyncResult * result

◆ drawShape()

void skgpu::ganesh::SurfaceDrawContext::drawShape ( const GrClip clip,
GrPaint &&  paint,
GrAA  aa,
const SkMatrix viewMatrix,
GrStyledShape &&  shape 
)

Draws a shape.

Parameters
paintdescribes how to color pixels.
GrAAControls whether the path is antialiased.
viewMatrixtransformation matrix
shapethe shape to draw

Definition at line 1561 of file SurfaceDrawContext.cpp.

1565 {
1568 SkDEBUGCODE(this->validate();)
1569 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawShape", fContext);
1570
1571 if (shape.isEmpty()) {
1572 if (shape.inverseFilled()) {
1573 this->drawPaint(clip, std::move(paint), viewMatrix);
1574 }
1575 return;
1576 }
1577
1578 AutoCheckFlush acf(this->drawingManager());
1579
1580 // If we get here in drawShape(), we definitely need to use path rendering
1581 this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix, std::move(shape),
1582 /* attemptDrawSimple */ true);
1583}
bool isEmpty() const
bool inverseFilled() const
void drawPaint(const GrClip *, GrPaint &&, const SkMatrix &viewMatrix)

◆ drawStrokedLine()

void skgpu::ganesh::SurfaceDrawContext::drawStrokedLine ( const GrClip clip,
GrPaint &&  paint,
GrAA  aa,
const SkMatrix viewMatrix,
const SkPoint  points[2],
const SkStrokeRec stroke 
)

Definition at line 1671 of file SurfaceDrawContext.cpp.

1676 {
1678
1680 SkASSERT(stroke.getWidth() > 0);
1681 // Adding support for round capping would require a
1682 // SurfaceDrawContext::fillRRectWithLocalMatrix entry point
1683 SkASSERT(SkPaint::kRound_Cap != stroke.getCap());
1684
1685 const SkScalar halfWidth = 0.5f * stroke.getWidth();
1686 if (halfWidth <= 0.f) {
1687 // Prevents underflow when stroke width is epsilon > 0 (so technically not a hairline).
1688 // The CTM would need to have a scale near 1/epsilon in order for this to have meaningful
1689 // coverage (although that would likely overflow elsewhere and cause the draw to drop due
1690 // to non-finite bounds). At any other scale, this line is so thin, it's coverage is
1691 // negligible, so discarding the draw is visually equivalent.
1692 return;
1693 }
1694
1695 SkVector parallel = points[1] - points[0];
1696
1697 if (!SkPoint::Normalize(&parallel)) {
1698 parallel.fX = 1.0f;
1699 parallel.fY = 0.0f;
1700 }
1701 parallel *= halfWidth;
1702
1703 SkVector ortho = { parallel.fY, -parallel.fX };
1704 SkPoint p0 = points[0], p1 = points[1];
1705 if (stroke.getCap() == SkPaint::kSquare_Cap) {
1706 // Extra extension for square caps
1707 p0 -= parallel;
1708 p1 += parallel;
1709 }
1710
1711 // If we are using dmsaa or reduced shader mode then attempt to draw with FillRRectOp.
1712 if (this->caps()->drawInstancedSupport() &&
1713 (this->alwaysAntialias() ||
1714 (fContext->priv().caps()->reducedShaderMode() && aa == GrAA::kYes))) {
1715 SkMatrix localMatrix = SkMatrix::MakeAll(p1.fX - p0.fX, ortho.fX, p0.fX,
1716 p1.fY - p0.fY, ortho.fY, p0.fY,
1717 0, 0, 1);
1718 if (auto op = FillRRectOp::Make(fContext,
1719 this->arenaAlloc(),
1720 std::move(paint),
1721 SkMatrix::Concat(viewMatrix, localMatrix),
1722 SkRRect::MakeRect({0,-1,1,1}),
1723 localMatrix,
1724 GrAA::kYes)) {
1725 this->addDrawOp(clip, std::move(op));
1726 return;
1727 }
1728 }
1729
1730 // Order is TL, TR, BR, BL where arbitrarily "down" is p0 to p1 and "right" is positive
1731 SkPoint corners[4] = { p0 - ortho,
1732 p0 + ortho,
1733 p1 + ortho,
1734 p1 - ortho };
1735
1737
1738 assert_alive(paint);
1739 this->fillQuadWithEdgeAA(clip, std::move(paint), edgeAA, viewMatrix, corners, nullptr);
1740}
GrQuadAAFlags
static const int points[]
bool reducedShaderMode() const
Definition GrCaps.h:190
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
Definition SkMatrix.h:179
static SkMatrix Concat(const SkMatrix &a, const SkMatrix &b)
Definition SkMatrix.h:1775
@ kRound_Cap
adds circle
Definition SkPaint.h:335
@ kSquare_Cap
adds square
Definition SkPaint.h:336
static SkRRect MakeRect(const SkRect &r)
Definition SkRRect.h:149
SkScalar getWidth() const
Definition SkStrokeRec.h:42
SkPaint::Cap getCap() const
Definition SkStrokeRec.h:44
void fillQuadWithEdgeAA(const GrClip *clip, GrPaint &&paint, GrQuadAAFlags edgeAA, const SkMatrix &viewMatrix, const SkPoint points[4], const SkPoint optionalLocalPoints[4])
static float Normalize(SkVector *vec)
Definition SkPoint.cpp:71

◆ drawTexture()

void skgpu::ganesh::SurfaceDrawContext::drawTexture ( const GrClip clip,
GrSurfaceProxyView  view,
SkAlphaType  srcAlphaType,
GrSamplerState::Filter  filter,
GrSamplerState::MipmapMode  mm,
SkBlendMode  blendMode,
const SkPMColor4f color,
const SkRect srcRect,
const SkRect dstRect,
GrQuadAAFlags  edgeAA,
SkCanvas::SrcRectConstraint  constraint,
const SkMatrix viewMatrix,
sk_sp< GrColorSpaceXform colorSpaceXform 
)

Creates an op that draws a subrectangle of a texture. The passed color is modulated by the texture's color. 'srcRect' specifies the rectangle of the texture to draw. 'dstRect' specifies the rectangle to draw in local coords which will be transformed by 'viewMatrix' to device space.

Definition at line 580 of file SurfaceDrawContext.cpp.

592 {
593 // If we are using dmsaa then go through FillRRectOp (via fillRectToRect).
594 if ((this->alwaysAntialias() || this->caps()->reducedShaderMode()) &&
595 edgeAA != GrQuadAAFlags::kNone) {
596 auto [mustFilter, mustMM] = FilterAndMipmapHaveNoEffect(
597 GrQuad::MakeFromRect(dstRect, viewMatrix), GrQuad(srcRect));
598 if (!mustFilter) {
599 // Chromeos-jacuzzi devices (ARM Mali-G72 MP3) have issues with blitting with linear
600 // filtering. Likely some optimization or quantization causes fragments to be produced
601 // with small offset/error. This will result in a slight blending of pixels when
602 // sampling. Normally in most application this would be completely unnoticeable but when
603 // trying to use the gpu as a per pixel blit we will end up with slightly blurry
604 // results.
605 // See https://crbug.com/326980863
606 filter = GrSamplerState::Filter::kNearest;
607 }
608
610 paint.setColor4f(color);
611 std::unique_ptr<GrFragmentProcessor> fp;
612 if (constraint == SkCanvas::kStrict_SrcRectConstraint) {
613 fp = GrTextureEffect::MakeSubset(view, srcAlphaType, SkMatrix::I(),
614 GrSamplerState(filter, mm), srcRect,
615 *this->caps());
616 } else {
617 fp = GrTextureEffect::Make(view, srcAlphaType, SkMatrix::I(), filter, mm);
618 }
619 if (colorSpaceXform) {
620 fp = GrColorSpaceXformEffect::Make(std::move(fp), std::move(colorSpaceXform));
621 }
622 fp = GrBlendFragmentProcessor::Make<SkBlendMode::kModulate>(std::move(fp), nullptr);
623 paint.setColorFragmentProcessor(std::move(fp));
624 if (blendMode != SkBlendMode::kSrcOver) {
625 paint.setXPFactory(GrXPFactory::FromBlendMode(blendMode));
626 }
627 this->fillRectToRect(clip, std::move(paint), GrAA::kYes, viewMatrix, dstRect, srcRect);
628 return;
629 }
630
631 const SkRect* subset = constraint == SkCanvas::kStrict_SrcRectConstraint ?
632 &srcRect : nullptr;
633 DrawQuad quad{GrQuad::MakeFromRect(dstRect, viewMatrix), GrQuad(srcRect), edgeAA};
634
635 this->drawTexturedQuad(clip, std::move(view), srcAlphaType, std::move(colorSpaceXform), filter,
636 mm, color, blendMode, &quad, subset);
637}
SkColor4f color
@ kSrcOver
r = s + (1-sa)*d
static std::unique_ptr< GrFragmentProcessor > Make(std::unique_ptr< GrFragmentProcessor > child, SkColorSpace *src, SkAlphaType srcAT, SkColorSpace *dst, SkAlphaType dstAT)
static GrQuad MakeFromRect(const SkRect &, const SkMatrix &)
Definition GrQuad.cpp:107
static std::unique_ptr< GrFragmentProcessor > MakeSubset(GrSurfaceProxyView, SkAlphaType, const SkMatrix &, GrSamplerState, const SkRect &subset, const GrCaps &caps, const float border[4]=kDefaultBorder, bool alwaysUseShaderTileMode=false)
static std::unique_ptr< GrFragmentProcessor > Make(GrSurfaceProxyView, SkAlphaType, const SkMatrix &=SkMatrix::I(), GrSamplerState::Filter=GrSamplerState::Filter::kNearest, GrSamplerState::MipmapMode mipmapMode=GrSamplerState::MipmapMode::kNone)
static const GrXPFactory * FromBlendMode(SkBlendMode)
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
Definition SkCanvas.h:1542
const uint32_t fp
std::tuple< bool, bool > FilterAndMipmapHaveNoEffect(const GrQuad &srcQuad, const GrQuad &dstQuad)

◆ drawTextureQuad()

void skgpu::ganesh::SurfaceDrawContext::drawTextureQuad ( const GrClip clip,
GrSurfaceProxyView  view,
GrColorType  srcColorType,
SkAlphaType  srcAlphaType,
GrSamplerState::Filter  filter,
GrSamplerState::MipmapMode  mm,
SkBlendMode  mode,
const SkPMColor4f color,
const SkPoint  srcQuad[4],
const SkPoint  dstQuad[4],
GrQuadAAFlags  edgeAA,
const SkRect subset,
const SkMatrix viewMatrix,
sk_sp< GrColorSpaceXform texXform 
)
inline

Variant of drawTexture that instead draws the texture applied to 'dstQuad' transformed by 'viewMatrix', using the 'srcQuad' texture coordinates clamped to the optional 'subset'. If 'subset' is null, it's equivalent to using the fast src rect constraint. If 'subset' is provided, the strict src rect constraint is applied using 'subset'.

Definition at line 264 of file SurfaceDrawContext.h.

277 {
278 DrawQuad quad{GrQuad::MakeFromSkQuad(dstQuad, viewMatrix),
279 GrQuad::MakeFromSkQuad(srcQuad, SkMatrix::I()), edgeAA};
280 this->drawTexturedQuad(clip, std::move(view), srcAlphaType, std::move(texXform), filter, mm,
281 color, mode, &quad, subset);
282 }
static GrQuad MakeFromSkQuad(const SkPoint pts[4], const SkMatrix &)
Definition GrQuad.cpp:122

◆ drawTextureSet()

void skgpu::ganesh::SurfaceDrawContext::drawTextureSet ( const GrClip clip,
GrTextureSetEntry  set[],
int  cnt,
int  proxyRunCnt,
GrSamplerState::Filter  filter,
GrSamplerState::MipmapMode  mm,
SkBlendMode  mode,
SkCanvas::SrcRectConstraint  constraint,
const SkMatrix viewMatrix,
sk_sp< GrColorSpaceXform texXform 
)

Draws a set of textures with a shared filter, color, view matrix, color xform, and texture color xform. The textures must all have the same GrTextureType and GrConfig.

If any entries provide a non-null fDstClip array, it will be read from immediately based on fDstClipCount, so the pointer can become invalid after this returns.

'proxRunCnt' is the number of proxy changes encountered in the entry array. Technically this can be inferred from the array within this function, but the information is already known by SkGpuDevice, so no need to incur another iteration over the array.

Definition at line 899 of file SurfaceDrawContext.cpp.

908 {
911 SkDEBUGCODE(this->validate();)
912 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawTextureSet", fContext);
913
914 // Create the minimum number of GrTextureOps needed to draw this set. Individual
915 // GrTextureOps can rebind the texture between draws thus avoiding GrPaint (re)creation.
916 AutoCheckFlush acf(this->drawingManager());
917 GrAAType aaType = this->chooseAAType(GrAA::kYes);
918 auto clampType = GrColorTypeClampType(this->colorInfo().colorType());
919 auto saturate = clampType == GrClampType::kManual ? ganesh::TextureOp::Saturate::kYes
921 ganesh::TextureOp::AddTextureSetOps(this, clip, fContext, set, cnt, proxyRunCnt, filter, mm,
922 saturate, mode, aaType, constraint, viewMatrix,
923 std::move(texXform));
924}
static void AddTextureSetOps(skgpu::ganesh::SurfaceDrawContext *, const GrClip *, GrRecordingContext *, GrTextureSetEntry[], int cnt, int proxyRunCnt, GrSamplerState::Filter, GrSamplerState::MipmapMode, Saturate, SkBlendMode, GrAAType, SkCanvas::SrcRectConstraint, const SkMatrix &viewMatrix, sk_sp< GrColorSpaceXform > textureXform)

◆ drawVertices()

void skgpu::ganesh::SurfaceDrawContext::drawVertices ( const GrClip clip,
GrPaint &&  paint,
const SkMatrix viewMatrix,
sk_sp< SkVertices vertices,
GrPrimitiveType overridePrimType = nullptr,
bool  skipColorXform = false 
)

Draws vertices with a paint.

Parameters
paintdescribes how to color pixels.
viewMatrixtransformation matrix
verticesspecifies the mesh to draw.
overridePrimTypeprimitive type to draw. If NULL, derive prim type from vertices.
skipColorXformif true, do not apply a color space transfer function

Definition at line 926 of file SurfaceDrawContext.cpp.

931 {
934 SkDEBUGCODE(this->validate();)
935 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawVertices", fContext);
936
937 AutoCheckFlush acf(this->drawingManager());
938
939 SkASSERT(vertices);
940 auto xform = skipColorXform ? nullptr : this->colorInfo().refColorSpaceXformFromSRGB();
941 GrAAType aaType = fCanUseDynamicMSAA ? GrAAType::kMSAA : this->chooseAAType(GrAA::kNo);
943 std::move(paint),
944 std::move(vertices),
945 overridePrimType,
946 viewMatrix,
947 aaType,
948 std::move(xform));
949 this->addDrawOp(clip, std::move(op));
950}
sk_sp< GrColorSpaceXform > refColorSpaceXformFromSRGB() const
Definition GrColorInfo.h:41

◆ fillPixelsWithLocalMatrix()

void skgpu::ganesh::SurfaceDrawContext::fillPixelsWithLocalMatrix ( const GrClip clip,
GrPaint &&  paint,
const SkIRect bounds,
const SkMatrix localMatrix 
)
inline

Fills a block of pixels with a paint and a localMatrix, respecting the clip.

Definition at line 184 of file SurfaceDrawContext.h.

187 {
188 SkRect rect = SkRect::Make(bounds);
190 GrQuad::MakeFromRect(rect, localMatrix), GrQuadAAFlags::kNone};
191 this->drawFilledQuad(clip, std::move(paint), &quad);
192 }

◆ fillQuadWithEdgeAA()

void skgpu::ganesh::SurfaceDrawContext::fillQuadWithEdgeAA ( const GrClip clip,
GrPaint &&  paint,
GrQuadAAFlags  edgeAA,
const SkMatrix viewMatrix,
const SkPoint  points[4],
const SkPoint  optionalLocalPoints[4] 
)
inline

Similar to fillRectWithEdgeAA but draws an arbitrary 2D convex quadrilateral transformed by 'viewMatrix', with per-edge control over anti-aliasing. The quad should follow the ordering used by SkRect::toQuad(), which determines how the edge AA is applied:

  • "top" = points [0] and [1]
  • "right" = points[1] and [2]
  • "bottom" = points[2] and [3]
  • "left" = points[3] and [0]

The last argument, 'optionalLocalQuad', can be null if no separate local coordinates are necessary.

Definition at line 225 of file SurfaceDrawContext.h.

227 {
228 const SkPoint* localPoints = optionalLocalPoints ? optionalLocalPoints : points;
229 DrawQuad quad{GrQuad::MakeFromSkQuad(points, viewMatrix),
230 GrQuad::MakeFromSkQuad(localPoints, SkMatrix::I()), edgeAA};
231 this->drawFilledQuad(clip, std::move(paint), &quad);
232 }

◆ fillRectToRect()

void skgpu::ganesh::SurfaceDrawContext::fillRectToRect ( const GrClip clip,
GrPaint &&  paint,
GrAA  aa,
const SkMatrix viewMatrix,
const SkRect rectToDraw,
const SkRect localRect 
)

Maps a rectangle of shader coordinates to a rectangle and fills that rectangle.

Parameters
GrPaintdescribes how to color pixels.
GrAAControls whether rect is antialiased
SkMatrixtransformation matrix which applies to rectToDraw
rectToDrawthe rectangle to draw
localRectthe rectangle of shader coordinates applied to rectToDraw

Definition at line 732 of file SurfaceDrawContext.cpp.

737 {
738 DrawQuad quad{GrQuad::MakeFromRect(rectToDraw, viewMatrix), GrQuad(localRect),
740
741 // If we are using dmsaa then attempt to draw the rect with FillRRectOp.
742 if ((fContext->priv().caps()->reducedShaderMode() || this->alwaysAntialias()) &&
743 this->caps()->drawInstancedSupport() &&
744 aa == GrAA::kYes) { // If aa is kNo when using dmsaa, the rect is axis aligned. Don't use
745 // FillRRectOp because it might require dual source blending.
746 // http://skbug.com/11756
747 QuadOptimization opt = this->attemptQuadOptimization(clip, nullptr/*stencil*/, &quad,
748 &paint);
750 // The optimization was completely handled inside attempt().
751 return;
752 }
753
754 SkRect croppedRect, croppedLocal{};
755 const GrClip* optimizedClip = clip;
756 if (clip && viewMatrix.isScaleTranslate() && quad.fDevice.asRect(&croppedRect) &&
757 (!paint.usesLocalCoords() || quad.fLocal.asRect(&croppedLocal))) {
758 // The cropped quad is still a rect, and our view matrix preserves rects. Map it back
759 // to pre-matrix space.
760 SkMatrix inverse;
761 if (!viewMatrix.invert(&inverse)) {
762 return;
763 }
764 SkASSERT(inverse.rectStaysRect());
765 inverse.mapRect(&croppedRect);
767 optimizedClip = nullptr;
768 }
769 } else {
770 // Even if attemptQuadOptimization gave us an optimized quad, FillRRectOp needs a rect
771 // in pre-matrix space, so use the original rect. Also preserve the original clip.
772 croppedRect = rectToDraw;
773 croppedLocal = localRect;
774 }
775
776 if (auto op = FillRRectOp::Make(fContext, this->arenaAlloc(), std::move(paint),
777 viewMatrix, SkRRect::MakeRect(croppedRect), croppedLocal,
778 GrAA::kYes)) {
779 this->addDrawOp(optimizedClip, std::move(op));
780 return;
781 }
782 }
783
784 assert_alive(paint);
785 this->drawFilledQuad(clip, std::move(paint), &quad);
786}
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const

◆ fillRectWithEdgeAA()

void skgpu::ganesh::SurfaceDrawContext::fillRectWithEdgeAA ( const GrClip clip,
GrPaint &&  paint,
GrQuadAAFlags  edgeAA,
const SkMatrix viewMatrix,
const SkRect rect,
const SkRect optionalLocalRect = nullptr 
)
inline

Creates an op that draws a fill rect with per-edge control over anti-aliasing.

This is a specialized version of fillQuadWithEdgeAA, but is kept separate since knowing the geometry is a rectangle affords more optimizations.

Definition at line 200 of file SurfaceDrawContext.h.

202 {
203 if (edgeAA == GrQuadAAFlags::kAll) {
204 this->fillRectToRect(clip, std::move(paint), GrAA::kYes, viewMatrix, rect,
205 (optionalLocalRect) ? *optionalLocalRect : rect);
206 return;
207 }
208 const SkRect& localRect = optionalLocalRect ? *optionalLocalRect : rect;
209 DrawQuad quad{GrQuad::MakeFromRect(rect, viewMatrix), GrQuad(localRect), edgeAA};
210 this->drawFilledQuad(clip, std::move(paint), &quad);
211 }

◆ isBudgeted()

skgpu::Budgeted skgpu::ganesh::SurfaceDrawContext::isBudgeted ( ) const

Definition at line 1659 of file SurfaceDrawContext.cpp.

1659 {
1661
1662 if (fContext->abandoned()) {
1663 return skgpu::Budgeted::kNo;
1664 }
1665
1666 SkDEBUGCODE(this->validate();)
1667
1668 return this->asSurfaceProxy()->isBudgeted();
1669}
skgpu::Budgeted isBudgeted() const

◆ Make() [1/3]

std::unique_ptr< SurfaceDrawContext > skgpu::ganesh::SurfaceDrawContext::Make ( GrRecordingContext rContext,
GrColorType  colorType,
sk_sp< GrSurfaceProxy proxy,
sk_sp< SkColorSpace colorSpace,
GrSurfaceOrigin  origin,
const SkSurfaceProps surfaceProps 
)
static

Definition at line 131 of file SurfaceDrawContext.cpp.

136 {
137 if (!rContext || !proxy || colorType == GrColorType::kUnknown) {
138 return nullptr;
139 }
140
141 const GrBackendFormat& format = proxy->backendFormat();
143 skgpu::Swizzle writeSwizzle = rContext->priv().caps()->getWriteSwizzle(format, colorType);
144
145 GrSurfaceProxyView readView ( proxy, origin, readSwizzle);
146 GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
147
148 return std::make_unique<SurfaceDrawContext>(rContext,
149 std::move(readView),
150 std::move(writeView),
151 colorType,
152 std::move(colorSpace),
154}
virtual skgpu::Swizzle getWriteSwizzle(const GrBackendFormat &, GrColorType) const =0
skgpu::Swizzle getReadSwizzle(const GrBackendFormat &format, GrColorType colorType) const
Definition GrCaps.cpp:443
const GrBackendFormat & backendFormat() const
skgpu::Swizzle readSwizzle() const
GrSurfaceOrigin origin() const
uint32_t uint32_t * format

◆ Make() [2/3]

std::unique_ptr< SurfaceDrawContext > skgpu::ganesh::SurfaceDrawContext::Make ( GrRecordingContext rContext,
GrColorType  colorType,
sk_sp< SkColorSpace colorSpace,
SkBackingFit  fit,
SkISize  dimensions,
const SkSurfaceProps surfaceProps,
std::string_view  label,
int  sampleCnt = 1,
skgpu::Mipmapped  mipmapped = skgpu::Mipmapped::kNo,
skgpu::Protected  isProtected = skgpu::Protected::kNo,
GrSurfaceOrigin  origin = kBottomLeft_GrSurfaceOrigin,
skgpu::Budgeted  budgeted = skgpu::Budgeted::kYes 
)
static

Definition at line 205 of file SurfaceDrawContext.cpp.

216 {
217 if (!rContext) {
218 return nullptr;
219 }
220
221 auto format = rContext->priv().caps()->getDefaultBackendFormat(colorType, GrRenderable::kYes);
222 if (!format.isValid()) {
223 return nullptr;
224 }
226 format,
228 GrRenderable::kYes,
229 sampleCnt,
230 mipmapped,
231 fit,
232 budgeted,
233 isProtected,
234 label);
235 if (!proxy) {
236 return nullptr;
237 }
238
239 return SurfaceDrawContext::Make(rContext,
240 colorType,
241 std::move(proxy),
242 std::move(colorSpace),
243 origin,
245}
GrBackendFormat getDefaultBackendFormat(GrColorType, GrRenderable) const
Definition GrCaps.cpp:400
sk_sp< GrTextureProxy > createProxy(const GrBackendFormat &, SkISize dimensions, GrRenderable, int renderTargetSampleCnt, skgpu::Mipmapped, SkBackingFit, skgpu::Budgeted, GrProtected, std::string_view label, GrInternalSurfaceFlags=GrInternalSurfaceFlags::kNone, UseAllocator useAllocator=UseAllocator::kYes)
GrProxyProvider * proxyProvider()
skgpu::Mipmapped mipmapped() const
static std::unique_ptr< SurfaceDrawContext > Make(GrRecordingContext *, GrColorType, sk_sp< GrSurfaceProxy >, sk_sp< SkColorSpace >, GrSurfaceOrigin, const SkSurfaceProps &)

◆ Make() [3/3]

std::unique_ptr< SurfaceDrawContext > skgpu::ganesh::SurfaceDrawContext::Make ( GrRecordingContext rContext,
sk_sp< SkColorSpace colorSpace,
SkBackingFit  fit,
SkISize  dimensions,
const GrBackendFormat format,
int  sampleCnt,
skgpu::Mipmapped  mipmapped,
skgpu::Protected  isProtected,
skgpu::Swizzle  readSwizzle,
skgpu::Swizzle  writeSwizzle,
GrSurfaceOrigin  origin,
skgpu::Budgeted  budgeted,
const SkSurfaceProps surfaceProps,
std::string_view  label 
)
static

Takes custom swizzles rather than determining swizzles from color type and format. It will have color type kUnknown.

Definition at line 156 of file SurfaceDrawContext.cpp.

169 {
170 // It is probably not necessary to check if the context is abandoned here since uses of the
171 // SurfaceDrawContext which need the context will mostly likely fail later on without an
172 // issue. However having this hear adds some reassurance in case there is a path doesn't handle
173 // an abandoned context correctly. It also lets us early out of some extra work.
174 if (rContext->abandoned()) {
175 return nullptr;
176 }
177
179 format,
181 GrRenderable::kYes,
182 sampleCnt,
183 mipmapped,
184 fit,
185 budgeted,
186 isProtected,
187 label);
188 if (!proxy) {
189 return nullptr;
190 }
191
192 GrSurfaceProxyView readView ( proxy, origin, readSwizzle);
193 GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
194
195 auto sdc = std::make_unique<SurfaceDrawContext>(rContext,
196 std::move(readView),
197 std::move(writeView),
199 std::move(colorSpace),
201 sdc->discard();
202 return sdc;
203}

◆ MakeFromBackendTexture()

std::unique_ptr< SurfaceDrawContext > skgpu::ganesh::SurfaceDrawContext::MakeFromBackendTexture ( GrRecordingContext rContext,
GrColorType  colorType,
sk_sp< SkColorSpace colorSpace,
const GrBackendTexture tex,
int  sampleCnt,
GrSurfaceOrigin  origin,
const SkSurfaceProps surfaceProps,
sk_sp< skgpu::RefCntedCallback releaseHelper 
)
static

Definition at line 269 of file SurfaceDrawContext.cpp.

277 {
278 SkASSERT(sampleCnt > 0);
281 std::move(releaseHelper)));
282 if (!proxy) {
283 return nullptr;
284 }
285
286 return SurfaceDrawContext::Make(rContext, colorType, std::move(proxy), std::move(colorSpace),
288}
@ kBorrow_GrWrapOwnership
Definition GrTypesPriv.h:78
sk_sp< GrTextureProxy > wrapRenderableBackendTexture(const GrBackendTexture &, int sampleCnt, GrWrapOwnership, GrWrapCacheable, sk_sp< skgpu::RefCntedCallback > releaseHelper)

◆ MakeWithFallback()

std::unique_ptr< SurfaceDrawContext > skgpu::ganesh::SurfaceDrawContext::MakeWithFallback ( GrRecordingContext rContext,
GrColorType  colorType,
sk_sp< SkColorSpace colorSpace,
SkBackingFit  fit,
SkISize  dimensions,
const SkSurfaceProps surfaceProps,
int  sampleCnt,
skgpu::Mipmapped  mipmapped,
skgpu::Protected  isProtected,
GrSurfaceOrigin  origin = kBottomLeft_GrSurfaceOrigin,
skgpu::Budgeted  budgeted = skgpu::Budgeted::kYes 
)
static

Definition at line 247 of file SurfaceDrawContext.cpp.

258 {
259 const GrCaps* caps = rContext->priv().caps();
260 auto [ct, _] = caps->getFallbackColorTypeAndFormat(colorType, sampleCnt);
261 if (ct == GrColorType::kUnknown) {
262 return nullptr;
263 }
264 return SurfaceDrawContext::Make(rContext, ct, colorSpace, fit, dimensions, surfaceProps,
265 /*label=*/"MakeSurfaceDrawContextWithFallback", sampleCnt,
266 mipmapped, isProtected, origin, budgeted);
267}
std::tuple< GrColorType, GrBackendFormat > getFallbackColorTypeAndFormat(GrColorType, int sampleCount) const
Definition GrCaps.cpp:499

◆ maxWindowRectangles()

int skgpu::ganesh::SurfaceDrawContext::maxWindowRectangles ( ) const

Definition at line 799 of file SurfaceDrawContext.cpp.

799 {
800 return this->asRenderTargetProxy()->maxWindowRectangles(*this->caps());
801}
int maxWindowRectangles(const GrCaps &caps) const

◆ mustRenderClip()

bool skgpu::ganesh::SurfaceDrawContext::mustRenderClip ( uint32_t  clipStackGenID,
const SkIRect devClipBounds,
int  numClipAnalyticElements 
)

Definition at line 1501 of file SurfaceDrawContext.cpp.

1503 {
1504 auto opsTask = this->getOpsTask();
1505 return opsTask->fLastClipStackGenID != clipStackGenID ||
1506 !opsTask->fLastDevClipBounds.contains(devClipBounds) ||
1507 opsTask->fLastClipNumAnalyticElements != numClipAnalyticElements;
1508}

◆ numSamples()

int skgpu::ganesh::SurfaceDrawContext::numSamples ( ) const
inline

Definition at line 591 of file SurfaceDrawContext.h.

591{ return this->asRenderTargetProxy()->numSamples(); }

◆ refsWrappedObjects()

bool skgpu::ganesh::SurfaceDrawContext::refsWrappedObjects ( ) const
inline

Definition at line 582 of file SurfaceDrawContext.h.

582{ return this->asRenderTargetProxy()->refsWrappedObjects(); }

◆ setLastClip()

void skgpu::ganesh::SurfaceDrawContext::setLastClip ( uint32_t  clipStackGenID,
const SkIRect devClipBounds,
int  numClipAnalyticElements 
)

Definition at line 1492 of file SurfaceDrawContext.cpp.

1494 {
1495 auto opsTask = this->getOpsTask();
1496 opsTask->fLastClipStackGenID = clipStackGenID;
1497 opsTask->fLastDevClipBounds = devClipBounds;
1498 opsTask->fLastClipNumAnalyticElements = numClipAnalyticElements;
1499}

◆ stencilPath()

bool skgpu::ganesh::SurfaceDrawContext::stencilPath ( const GrHardClip clip,
GrAA  doStencilMSAA,
const SkMatrix viewMatrix,
const SkPath path 
)

Definition at line 861 of file SurfaceDrawContext.cpp.

864 {
865 SkIRect clipBounds = clip ? clip->getConservativeBounds()
866 : SkIRect::MakeSize(this->dimensions());
868
869 PathRenderer::CanDrawPathArgs canDrawArgs;
870 canDrawArgs.fCaps = fContext->priv().caps();
871 canDrawArgs.fProxy = this->asRenderTargetProxy();
872 canDrawArgs.fClipConservativeBounds = &clipBounds;
873 canDrawArgs.fViewMatrix = &viewMatrix;
874 canDrawArgs.fShape = &shape;
875 canDrawArgs.fPaint = nullptr;
876 canDrawArgs.fSurfaceProps = &fSurfaceProps;
877 canDrawArgs.fAAType = (doStencilMSAA == GrAA::kYes) ? GrAAType::kMSAA : GrAAType::kNone;
878 canDrawArgs.fHasUserStencilSettings = false;
879 auto pr = this->drawingManager()->getPathRenderer(canDrawArgs,
880 false,
882 if (!pr) {
883 SkDebugf("WARNING: No path renderer to stencil path.\n");
884 return false;
885 }
886
887 PathRenderer::StencilPathArgs args;
888 args.fContext = fContext;
889 args.fSurfaceDrawContext = this;
890 args.fClip = clip;
891 args.fClipConservativeBounds = &clipBounds;
892 args.fViewMatrix = &viewMatrix;
893 args.fShape = &shape;
894 args.fDoStencilMSAA = doStencilMSAA;
895 pr->stencilPath(args);
896 return true;
897}

◆ stencilRect()

void skgpu::ganesh::SurfaceDrawContext::stencilRect ( const GrClip clip,
const GrUserStencilSettings ss,
GrPaint &&  paint,
GrAA  doStencilMSAA,
const SkMatrix viewMatrix,
const SkRect rect,
const SkMatrix localMatrix = nullptr 
)
inline

Definition at line 524 of file SurfaceDrawContext.h.

530 {
531 // Since this provides stencil settings to drawFilledQuad, it performs a different AA type
532 // resolution compared to regular rect draws, which is the main reason it remains separate.
533 DrawQuad quad{GrQuad::MakeFromRect(rect, viewMatrix),
534 localMatrix ? GrQuad::MakeFromRect(rect, *localMatrix) : GrQuad(rect),
535 doStencilMSAA == GrAA::kYes ? GrQuadAAFlags::kAll : GrQuadAAFlags::kNone};
536 this->drawFilledQuad(clip, std::move(paint), &quad, ss);
537 }

◆ surfaceProps()

const SkSurfaceProps & skgpu::ganesh::SurfaceDrawContext::surfaceProps ( ) const
inline

Definition at line 592 of file SurfaceDrawContext.h.

592{ return fSurfaceProps; }

◆ uniqueID()

GrSurfaceProxy::UniqueID skgpu::ganesh::SurfaceDrawContext::uniqueID ( ) const
inline

Definition at line 567 of file SurfaceDrawContext.h.

567{ return this->asSurfaceProxy()->uniqueID(); }
UniqueID uniqueID() const

◆ waitOnSemaphores()

bool skgpu::ganesh::SurfaceDrawContext::waitOnSemaphores ( int  numSemaphores,
const GrBackendSemaphore  waitSemaphores[],
bool  deleteSemaphoresAfterWait 
)

The next time this SurfaceDrawContext is flushed, the gpu will wait on the passed in semaphores before executing any commands.

Definition at line 1510 of file SurfaceDrawContext.cpp.

1512 {
1515 SkDEBUGCODE(this->validate();)
1516 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "waitOnSemaphores", fContext);
1517
1518 AutoCheckFlush acf(this->drawingManager());
1519
1520 if (numSemaphores && !this->caps()->backendSemaphoreSupport()) {
1521 return false;
1522 }
1523
1524 auto direct = fContext->asDirectContext();
1525 if (!direct) {
1526 return false;
1527 }
1528
1529 auto resourceProvider = direct->priv().resourceProvider();
1530
1531 GrWrapOwnership ownership =
1532 deleteSemaphoresAfterWait ? kAdopt_GrWrapOwnership : kBorrow_GrWrapOwnership;
1533
1534 std::unique_ptr<std::unique_ptr<GrSemaphore>[]> grSemaphores(
1535 new std::unique_ptr<GrSemaphore>[numSemaphores]);
1536 for (int i = 0; i < numSemaphores; ++i) {
1537 grSemaphores[i] = resourceProvider->wrapBackendSemaphore(waitSemaphores[i],
1539 ownership);
1540 }
1541 this->drawingManager()->newWaitRenderTask(this->asSurfaceProxyRef(), std::move(grSemaphores),
1542 numSemaphores);
1543 return true;
1544}
GrWrapOwnership
Definition GrTypesPriv.h:76
@ kAdopt_GrWrapOwnership
Definition GrTypesPriv.h:81
virtual GrDirectContext * asDirectContext()
GrResourceProvider * resourceProvider()
GrDirectContextPriv priv()
void newWaitRenderTask(const sk_sp< GrSurfaceProxy > &proxy, std::unique_ptr< std::unique_ptr< GrSemaphore >[]>, int numSemaphores)
sk_sp< GrSurfaceProxy > asSurfaceProxyRef()

◆ willReplaceOpsTask()

void skgpu::ganesh::SurfaceDrawContext::willReplaceOpsTask ( OpsTask prevTask,
OpsTask nextTask 
)
overrideprivatevirtual

Override to be notified in subclass before the current ops task is replaced.

Reimplemented from skgpu::ganesh::SurfaceFillContext.

Definition at line 315 of file SurfaceDrawContext.cpp.

315 {
316 if (prevTask && fNeedsStencil) {
317 // Store the stencil values in memory upon completion of fOpsTask.
318 prevTask->setMustPreserveStencil();
319 // Reload the stencil buffer content at the beginning of newOpsTask.
320 // FIXME: Could the topo sort insert a task between these two that modifies the stencil
321 // values?
322 nextTask->setInitialStencilContent(OpsTask::StencilContent::kPreserved);
323 }
324#if GR_GPU_STATS && defined(GR_TEST_UTILS)
325 if (fCanUseDynamicMSAA) {
326 fContext->priv().dmsaaStats().fNumRenderPasses++;
327 }
328#endif
329}

◆ wrapsVkSecondaryCB()

bool skgpu::ganesh::SurfaceDrawContext::wrapsVkSecondaryCB ( ) const
inline

Definition at line 594 of file SurfaceDrawContext.h.

594{ return this->asRenderTargetProxy()->wrapsVkSecondaryCB(); }
bool wrapsVkSecondaryCB() const

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