Flutter Engine
The Flutter Engine
Public Types | Public Member Functions | Static Public 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 SkArc &arc, 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 ()
 
virtual SurfaceFillContextasFillContext ()
 
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)
 

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 567 of file SurfaceDrawContext.h.

Member Enumeration Documentation

◆ QuadOptimization

Enumerator
kDiscarded 
kSubmitted 
kClipApplied 
kCropped 

Definition at line 389 of file SurfaceDrawContext.cpp.

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

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 295 of file SurfaceDrawContext.cpp.

301 : SurfaceFillContext(rContext,
302 std::move(readView),
303 std::move(writeView),
304 {colorType, kPremul_SkAlphaType, std::move(colorSpace)})
305 , fSurfaceProps(surfaceProps)
306 , fCanUseDynamicMSAA(
307 (fSurfaceProps.flags() & SkSurfaceProps::kDynamicMSAA_Flag) &&
308 rContext->priv().caps()->supportsDynamicMSAA(this->asRenderTargetProxy())) {
309 SkDEBUGCODE(this->validate();)
310}
@ 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 312 of file SurfaceDrawContext.cpp.

312 {
314}
#define ASSERT_SINGLE_OWNER

Member Function Documentation

◆ accessRenderTarget()

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

Definition at line 613 of file SurfaceDrawContext.h.

613{ 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;)
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
Definition: GrTypesPriv.h:228
GrAAType
Definition: GrTypesPriv.h:200
static constexpr GrClampType GrColorTypeClampType(GrColorType colorType)
Definition: GrTypesPriv.h:868
#define SkASSERT(cond)
Definition: SkAssert.h:116
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
bool msaaResolvesAutomatically() const
Definition: GrCaps.h:100
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()
void addDrawOp(const GrClip *, GrOp::Owner, const std::function< WillAddOpFn > &=std::function< WillAddOpFn >())
if(end==-1)
Optional< SkRect > bounds
Definition: SkRecords.h:189
const myers::Point & get(const myers::Segment &)

◆ addDrawOp() [2/2]

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

Definition at line 577 of file SurfaceDrawContext.h.

577{ this->addDrawOp(nullptr, std::move(op)); }

◆ alwaysAntialias()

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

Definition at line 593 of file SurfaceDrawContext.h.

593 {
594 return fSurfaceProps.flags() & SkSurfaceProps::kDynamicMSAA_Flag;
595 }

◆ canUseDynamicMSAA()

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

Definition at line 590 of file SurfaceDrawContext.h.

590{ return fCanUseDynamicMSAA; }

◆ chooseAA()

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

Definition at line 597 of file SurfaceDrawContext.h.

597 {
598 return GrAA(paint.isAntiAlias() || this->alwaysAntialias());
599 }
GrAA
Definition: GrTypesPriv.h:173
const Paint & paint
Definition: color_source.cc:38

◆ chooseAAType()

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

Definition at line 601 of file SurfaceDrawContext.h.

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

◆ clearStencilClip()

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

Definition at line 514 of file SurfaceDrawContext.h.

514 {
515 this->internalStencilClear(&scissor, insideStencilMask);
516 }

◆ 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
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
Definition: GrColorInfo.cpp:44
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()
Definition: SkMatrix.cpp:1544
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)
Definition: SkRect.h:32
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 SkArc arc,
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 1419 of file SurfaceDrawContext.cpp.

1424 {
1427 SkDEBUGCODE(this->validate();)
1428 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawArc", fContext);
1429
1430 AutoCheckFlush acf(this->drawingManager());
1431
1432#ifndef SK_ENABLE_OPTIMIZE_SIZE
1433 GrAAType aaType = this->chooseAAType(aa);
1434 if (aaType == GrAAType::kCoverage) {
1435 const GrShaderCaps* shaderCaps = this->caps()->shaderCaps();
1437 std::move(paint),
1438 viewMatrix,
1439 arc.fOval,
1440 arc.fStartAngle,
1441 arc.fSweepAngle,
1442 arc.isWedge(),
1443 style,
1444 shaderCaps);
1445 if (op) {
1446 this->addDrawOp(clip, std::move(op));
1447 return;
1448 }
1449 assert_alive(paint);
1450 }
1451#endif
1452 this->drawShapeUsingPathRenderer(clip,
1453 std::move(paint),
1454 aa,
1455 viewMatrix,
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 SkArc &arc, const GrStyle &style, DoSimplify=DoSimplify::kYes)
SkScalar fSweepAngle
Definition: SkArc.h:60
SkScalar fStartAngle
Definition: SkArc.h:58
SkRect fOval
Definition: SkArc.h:55
bool isWedge() const
Definition: SkArc.h:28

◆ 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 984 of file SurfaceDrawContext.cpp.

990 {
993 SkDEBUGCODE(this->validate();)
994 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawAtlas", fContext);
995
996 AutoCheckFlush acf(this->drawingManager());
997
998 GrAAType aaType = this->chooseAAType(GrAA::kNo);
999 GrOp::Owner op = DrawAtlasOp::Make(fContext, std::move(paint), viewMatrix,
1000 aaType, spriteCount, xform, texRect, colors);
1001 this->addDrawOp(clip, std::move(op));
1002}
PODArray< SkColor > colors
Definition: SkRecords.h:276
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)
Definition: DrawableOp.cpp:19

◆ 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 1105 of file SurfaceDrawContext.cpp.

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

337 {
340 SkDEBUGCODE(this->validate();)
341 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawGlyphRunList", fContext);
342
343 // Drawing text can cause us to do inline uploads. This is not supported for wrapped vulkan
344 // secondary command buffers because it would require stopping and starting a render pass which
345 // we don't have access to.
346 if (this->wrapsVkSecondaryCB()) {
347 return;
348 }
349
351
352 auto atlasDelegate = [&](const sktext::gpu::AtlasSubRun* subRun,
353 SkPoint drawOrigin,
354 const SkPaint& paint,
355 sk_sp<SkRefCnt> subRunStorage,
357 auto [drawingClip, op] = subRun->makeAtlasTextOp(
358 clip, viewMatrix, drawOrigin, paint, std::move(subRunStorage), this);
359 if (op != nullptr) {
360 this->addDrawOp(drawingClip, std::move(op));
361 }
362 };
363
364 textBlobCache->drawGlyphRunList(
365 canvas, viewMatrix, glyphRunList, paint, strikeDeviceInfo, atlasDelegate);
366}
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}
dst
Definition: cp.py:12
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)
Definition: LatticeOp.cpp:401

◆ 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 953 of file SurfaceDrawContext.cpp.

957 {
960 SkDEBUGCODE(this->validate();)
961 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawMesh", fContext);
962
963 AutoCheckFlush acf(this->drawingManager());
964
965 SkASSERT(mesh.isValid());
966
969 this->colorInfo().colorSpace(),
970 this->colorInfo().alphaType());
971 GrAAType aaType = fCanUseDynamicMSAA ? GrAAType::kMSAA : this->chooseAAType(GrAA::kNo);
973 std::move(paint),
974 mesh,
975 std::move(children),
976 viewMatrix,
977 aaType,
978 std::move(xform));
979 this->addDrawOp(clip, std::move(op));
980}
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 1351 of file SurfaceDrawContext.cpp.

1356 {
1359 SkDEBUGCODE(this->validate();)
1360 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawOval", fContext);
1361
1362 const SkStrokeRec& stroke = style.strokeRec();
1363
1364 if (oval.isEmpty() && !style.pathEffect()) {
1365 if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
1366 return;
1367 }
1368
1369 this->drawRect(clip, std::move(paint), aa, viewMatrix, oval, &style);
1370 return;
1371 }
1372
1373 AutoCheckFlush acf(this->drawingManager());
1374
1375 GrAAType aaType = this->chooseAAType(aa);
1376
1377 GrOp::Owner op;
1378#ifndef SK_ENABLE_OPTIMIZE_SIZE
1379 if (aaType == GrAAType::kCoverage &&
1380 !fCanUseDynamicMSAA &&
1381 !this->caps()->reducedShaderMode() &&
1383 oval.width() == oval.height() &&
1384 viewMatrix.isSimilarity()) {
1385 // In specific cases we use a dedicated circle op to try and get better perf.
1386 assert_alive(paint);
1387 op = GrOvalOpFactory::MakeCircleOp(fContext, std::move(paint), viewMatrix, oval, style,
1388 this->caps()->shaderCaps());
1389 }
1390#endif
1391 if (!op && style.isSimpleFill()) {
1392 // FillRRectOp has special geometry and a fragment-shader branch to conditionally evaluate
1393 // the arc equation. This same special geometry and fragment branch also turn out to be a
1394 // substantial optimization for drawing ovals (namely, by not evaluating the arc equation
1395 // inside the oval's inner diamond). Given these optimizations, it's a clear win to draw
1396 // ovals the exact same way we do round rects.
1397 assert_alive(paint);
1398 op = FillRRectOp::Make(fContext, this->arenaAlloc(), std::move(paint), viewMatrix,
1400 }
1401#ifndef SK_ENABLE_OPTIMIZE_SIZE
1402 if (!op && (aaType == GrAAType::kCoverage || fCanUseDynamicMSAA)) {
1403 assert_alive(paint);
1404 op = GrOvalOpFactory::MakeOvalOp(fContext, std::move(paint), viewMatrix, oval, style,
1405 this->caps()->shaderCaps());
1406 }
1407#endif
1408 if (op) {
1409 this->addDrawOp(clip, std::move(op));
1410 return;
1411 }
1412
1413 assert_alive(paint);
1414 this->drawShapeUsingPathRenderer(clip, std::move(paint), aa, viewMatrix,
1416 false, style, DoSimplify::kNo));
1417}
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
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 368 of file SurfaceDrawContext.cpp.

370 {
371 // Start with the render target, since that is the maximum content we could possibly fill.
372 // drawFilledQuad() will automatically restrict it to clip bounds for us if possible.
373 if (!paint.numTotalFragmentProcessors()) {
374 // The paint is trivial so we won't need to use local coordinates, so skip calculating the
375 // inverse view matrix.
376 SkRect r = this->asSurfaceProxy()->getBoundsRect();
377 this->fillRectToRect(clip, std::move(paint), GrAA::kNo, SkMatrix::I(), r, r);
378 } else {
379 // Use the inverse view matrix to arrive at appropriate local coordinates for the paint.
380 SkMatrix localMatrix;
381 if (!viewMatrix.invert(&localMatrix)) {
382 return;
383 }
385 this->fillPixelsWithLocalMatrix(clip, std::move(paint), bounds, localMatrix);
386 }
387}
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 789 of file SurfaceDrawContext.cpp.

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

◆ 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 680 of file SurfaceDrawContext.cpp.

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

1322 {
1325 SkDEBUGCODE(this->validate();)
1326 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawRegion", fContext);
1327
1328 if (GrAA::kYes == aa) {
1329 // GrRegionOp performs no antialiasing but is much faster, so here we check the matrix
1330 // to see whether aa is really required.
1331 if (!SkToBool(viewMatrix.getType() & ~(SkMatrix::kTranslate_Mask)) &&
1332 SkScalarIsInt(viewMatrix.getTranslateX()) &&
1333 SkScalarIsInt(viewMatrix.getTranslateY())) {
1334 aa = GrAA::kNo;
1335 }
1336 }
1337 bool complexStyle = !style.isSimpleFill();
1338 if (complexStyle || GrAA::kYes == aa) {
1339 SkPath path;
1341 path.setIsVolatile(true);
1342
1343 return this->drawPath(clip, std::move(paint), aa, viewMatrix, path, style);
1344 }
1345
1346 GrAAType aaType = (this->numSamples() > 1) ? GrAAType::kMSAA : GrAAType::kNone;
1347 GrOp::Owner op = RegionOp::Make(fContext, std::move(paint), viewMatrix, region, aaType, ss);
1348 this->addDrawOp(clip, std::move(op));
1349}
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
Definition: SkPath.h:59
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 1006 of file SurfaceDrawContext.cpp.

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

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

◆ 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
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228

◆ 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 900 of file SurfaceDrawContext.cpp.

909 {
912 SkDEBUGCODE(this->validate();)
913 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawTextureSet", fContext);
914
915 // Create the minimum number of GrTextureOps needed to draw this set. Individual
916 // GrTextureOps can rebind the texture between draws thus avoiding GrPaint (re)creation.
917 AutoCheckFlush acf(this->drawingManager());
918 GrAAType aaType = this->chooseAAType(GrAA::kYes);
919 auto clampType = GrColorTypeClampType(this->colorInfo().colorType());
920 auto saturate = clampType == GrClampType::kManual ? ganesh::TextureOp::Saturate::kYes
922 ganesh::TextureOp::AddTextureSetOps(this, clip, fContext, set, cnt, proxyRunCnt, filter, mm,
923 saturate, mode, aaType, constraint, viewMatrix,
924 std::move(texXform));
925}
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)
Definition: TextureOp.cpp:1275
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 to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
Definition: switches.h:76

◆ 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 927 of file SurfaceDrawContext.cpp.

932 {
935 SkDEBUGCODE(this->validate();)
936 GR_CREATE_TRACE_MARKER_CONTEXT("SurfaceDrawContext", "drawVertices", fContext);
937
938 AutoCheckFlush acf(this->drawingManager());
939
940 SkASSERT(vertices);
941 auto xform = skipColorXform ? nullptr : this->colorInfo().refColorSpaceXformFromSRGB();
942 GrAAType aaType = fCanUseDynamicMSAA ? GrAAType::kMSAA : this->chooseAAType(GrAA::kNo);
944 std::move(paint),
945 std::move(vertices),
946 overridePrimType,
947 viewMatrix,
948 aaType,
949 std::move(xform));
950 this->addDrawOp(clip, std::move(op));
951}
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 {
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 733 of file SurfaceDrawContext.cpp.

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

◆ 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 132 of file SurfaceDrawContext.cpp.

137 {
138 if (!rContext || !proxy || colorType == GrColorType::kUnknown) {
139 return nullptr;
140 }
141
142 const GrBackendFormat& format = proxy->backendFormat();
144 skgpu::Swizzle writeSwizzle = rContext->priv().caps()->getWriteSwizzle(format, colorType);
145
146 GrSurfaceProxyView readView ( proxy, origin, readSwizzle);
147 GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
148
149 return std::make_unique<SurfaceDrawContext>(rContext,
150 std::move(readView),
151 std::move(writeView),
152 colorType,
153 std::move(colorSpace),
155}
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 206 of file SurfaceDrawContext.cpp.

217 {
218 if (!rContext) {
219 return nullptr;
220 }
221
223 if (!format.isValid()) {
224 return nullptr;
225 }
227 format,
230 sampleCnt,
231 mipmapped,
232 fit,
233 budgeted,
234 isProtected,
235 label);
236 if (!proxy) {
237 return nullptr;
238 }
239
240 return SurfaceDrawContext::Make(rContext,
241 colorType,
242 std::move(proxy),
243 std::move(colorSpace),
244 origin,
246}
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 157 of file SurfaceDrawContext.cpp.

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

◆ 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 270 of file SurfaceDrawContext.cpp.

278 {
279 SkASSERT(sampleCnt > 0);
282 std::move(releaseHelper)));
283 if (!proxy) {
284 return nullptr;
285 }
286
287 return SurfaceDrawContext::Make(rContext, colorType, std::move(proxy), std::move(colorSpace),
289}
@ kBorrow_GrWrapOwnership
Definition: GrTypesPriv.h:79
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 248 of file SurfaceDrawContext.cpp.

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

◆ maxWindowRectangles()

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

Definition at line 800 of file SurfaceDrawContext.cpp.

800 {
801 return this->asRenderTargetProxy()->maxWindowRectangles(*this->caps());
802}
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 588 of file SurfaceDrawContext.h.

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

◆ refsWrappedObjects()

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

Definition at line 579 of file SurfaceDrawContext.h.

579{ 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 862 of file SurfaceDrawContext.cpp.

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

◆ 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 521 of file SurfaceDrawContext.h.

527 {
528 // Since this provides stencil settings to drawFilledQuad, it performs a different AA type
529 // resolution compared to regular rect draws, which is the main reason it remains separate.
530 DrawQuad quad{GrQuad::MakeFromRect(rect, viewMatrix),
531 localMatrix ? GrQuad::MakeFromRect(rect, *localMatrix) : GrQuad(rect),
532 doStencilMSAA == GrAA::kYes ? GrQuadAAFlags::kAll : GrQuadAAFlags::kNone};
533 this->drawFilledQuad(clip, std::move(paint), &quad, ss);
534 }
@ kYes
Do pre-clip the geometry before applying the (perspective) matrix.
@ kNone
Definition: layer.h:53

◆ surfaceProps()

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

Definition at line 589 of file SurfaceDrawContext.h.

589{ return fSurfaceProps; }

◆ uniqueID()

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

Definition at line 564 of file SurfaceDrawContext.h.

564{ 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:77
@ kAdopt_GrWrapOwnership
Definition: GrTypesPriv.h:82
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()

◆ wrapsVkSecondaryCB()

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

Definition at line 591 of file SurfaceDrawContext.h.

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

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