blob: 39618362c8b123ce2f7a667b2aad63a049045c08 [file] [log] [blame]
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SurfaceDrawContext_v1_DEFINED
#define SurfaceDrawContext_v1_DEFINED
#include "include/core/SkCanvas.h"
#include "include/core/SkDrawable.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSurface.h"
#include "include/core/SkSurfaceProps.h"
#include "include/private/base/SkTArray.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkDevice.h"
#include "src/gpu/ganesh/GrPaint.h"
#include "src/gpu/ganesh/GrRenderTargetProxy.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/GrXferProcessor.h"
#include "src/gpu/ganesh/SurfaceFillContext.h"
#include "src/gpu/ganesh/geometry/GrQuad.h"
#include "src/gpu/ganesh/ops/OpsTask.h"
class GrBackendSemaphore;
class GrClip;
class GrColorSpaceXform;
class GrDrawOp;
class GrDstProxyView;
class GrHardClip;
class GrOp;
struct GrQuadSetEntry;
class GrRenderTarget;
class GrStyledShape;
class GrStyle;
class GrTextureProxy;
struct GrTextureSetEntry;
struct GrUserStencilSettings;
struct SkDrawShadowRec;
struct SkIPoint;
struct SkIRect;
class SkLatticeIter;
class SkMatrix;
class SkPaint;
class SkPath;
struct SkPoint;
struct SkRect;
class SkRegion;
class SkRRect;
struct SkRSXform;
class SkTextBlob;
class SkVertices;
namespace sktext {
class GlyphRunList;
}
namespace skgpu::ganesh {
/**
* A helper object to orchestrate commands (draws, etc...) for GrSurfaces that are GrRenderTargets.
*/
class SurfaceDrawContext final : public SurfaceFillContext {
public:
static std::unique_ptr<SurfaceDrawContext> Make(GrRecordingContext*,
GrColorType,
sk_sp<GrSurfaceProxy>,
sk_sp<SkColorSpace>,
GrSurfaceOrigin,
const SkSurfaceProps&);
/* Uses the default texture format for the color type */
static std::unique_ptr<SurfaceDrawContext> Make(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);
/**
* Takes custom swizzles rather than determining swizzles from color type and format.
* It will have color type kUnknown.
*/
static std::unique_ptr<SurfaceDrawContext> Make(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);
// Same as previous factory but will try to use fallback GrColorTypes if the one passed in
// fails. The fallback GrColorType will have at least the number of channels and precision per
// channel as the passed in GrColorType. It may also swizzle the changes (e.g., BGRA -> RGBA).
// SRGB-ness will be preserved.
static std::unique_ptr<SurfaceDrawContext> MakeWithFallback(
GrRecordingContext*,
GrColorType,
sk_sp<SkColorSpace>,
SkBackingFit,
SkISize dimensions,
const SkSurfaceProps&,
int sampleCnt,
skgpu::Mipmapped,
skgpu::Protected,
GrSurfaceOrigin = kBottomLeft_GrSurfaceOrigin,
skgpu::Budgeted = skgpu::Budgeted::kYes);
// Creates a SurfaceDrawContext that wraps the passed in GrBackendTexture.
static std::unique_ptr<SurfaceDrawContext> MakeFromBackendTexture(
GrRecordingContext*,
GrColorType,
sk_sp<SkColorSpace>,
const GrBackendTexture&,
int sampleCnt,
GrSurfaceOrigin,
const SkSurfaceProps&,
sk_sp<skgpu::RefCntedCallback> releaseHelper);
SurfaceDrawContext(GrRecordingContext*,
GrSurfaceProxyView readView,
GrSurfaceProxyView writeView,
GrColorType,
sk_sp<SkColorSpace>,
const SkSurfaceProps&);
~SurfaceDrawContext() override;
/**
* Draw everywhere (respecting the clip) with the paint.
*/
void drawPaint(const GrClip*, GrPaint&&, const SkMatrix& viewMatrix);
/**
* Draw the rect using a paint.
* @param paint describes how to color pixels.
* @param GrAA Controls whether rect is antialiased
* @param viewMatrix transformation matrix
* @param style The style to apply. Null means fill. Currently path effects are not
* allowed.
* The rects coords are used to access the paint (through texture matrix)
*/
void drawRect(const GrClip*,
GrPaint&& paint,
GrAA,
const SkMatrix& viewMatrix,
const SkRect&,
const GrStyle* style = nullptr);
/**
* Maps a rectangle of shader coordinates to a rectangle and fills that rectangle.
*
* @param GrPaint describes how to color pixels.
* @param GrAA Controls whether rect is antialiased
* @param SkMatrix transformation matrix which applies to rectToDraw
* @param rectToDraw the rectangle to draw
* @param localRect the rectangle of shader coordinates applied to rectToDraw
*/
void fillRectToRect(const GrClip*,
GrPaint&&,
GrAA,
const SkMatrix&,
const SkRect& rectToDraw,
const SkRect& localRect);
/**
* Fills a block of pixels with a paint and a localMatrix, respecting the clip.
*/
void fillPixelsWithLocalMatrix(const GrClip* clip,
GrPaint&& paint,
const SkIRect& bounds,
const SkMatrix& localMatrix) {
SkRect rect = SkRect::Make(bounds);
DrawQuad quad{GrQuad::MakeFromRect(rect, SkMatrix::I()),
GrQuad::MakeFromRect(rect, localMatrix), GrQuadAAFlags::kNone};
this->drawFilledQuad(clip, std::move(paint), &quad);
}
/**
* 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.
*/
void fillRectWithEdgeAA(const GrClip* clip, GrPaint&& paint, GrQuadAAFlags edgeAA,
const SkMatrix& viewMatrix, const SkRect& rect,
const SkRect* optionalLocalRect = nullptr) {
if (edgeAA == GrQuadAAFlags::kAll) {
this->fillRectToRect(clip, std::move(paint), GrAA::kYes, viewMatrix, rect,
(optionalLocalRect) ? *optionalLocalRect : rect);
return;
}
const SkRect& localRect = optionalLocalRect ? *optionalLocalRect : rect;
DrawQuad quad{GrQuad::MakeFromRect(rect, viewMatrix), GrQuad(localRect), edgeAA};
this->drawFilledQuad(clip, std::move(paint), &quad);
}
/**
* 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.
*/
void fillQuadWithEdgeAA(const GrClip* clip, GrPaint&& paint, GrQuadAAFlags edgeAA,
const SkMatrix& viewMatrix, const SkPoint points[4],
const SkPoint optionalLocalPoints[4]) {
const SkPoint* localPoints = optionalLocalPoints ? optionalLocalPoints : points;
DrawQuad quad{GrQuad::MakeFromSkQuad(points, viewMatrix),
GrQuad::MakeFromSkQuad(localPoints, SkMatrix::I()), edgeAA};
this->drawFilledQuad(clip, std::move(paint), &quad);
}
// TODO(michaelludwig) - remove if the bulk API is not useful for SkiaRenderer
void drawQuadSet(const GrClip* clip, GrPaint&& paint, const SkMatrix& viewMatrix,
const GrQuadSetEntry[], int cnt);
/**
* 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.
*/
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>);
/**
* 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'.
*/
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) {
DrawQuad quad{GrQuad::MakeFromSkQuad(dstQuad, viewMatrix),
GrQuad::MakeFromSkQuad(srcQuad, SkMatrix::I()), edgeAA};
this->drawTexturedQuad(clip, std::move(view), srcAlphaType, std::move(texXform), filter, mm,
color, mode, &quad, subset);
}
/**
* 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.
*/
void drawTextureSet(const GrClip*,
GrTextureSetEntry[],
int cnt,
int proxyRunCnt,
GrSamplerState::Filter,
GrSamplerState::MipmapMode,
SkBlendMode mode,
SkCanvas::SrcRectConstraint,
const SkMatrix& viewMatrix,
sk_sp<GrColorSpaceXform> texXform);
/**
* Draw a roundrect using a paint.
*
* @param paint describes how to color pixels.
* @param GrAA Controls whether rrect is antialiased.
* @param viewMatrix transformation matrix
* @param rrect the roundrect to draw
* @param style style to apply to the rrect. Currently path effects are not allowed.
*/
void drawRRect(const GrClip*,
GrPaint&&,
GrAA,
const SkMatrix& viewMatrix,
const SkRRect& rrect,
const GrStyle& style);
/**
* Use a fast method to render the ambient and spot shadows for a path.
* Will return false if not possible for the given path.
*
* @param viewMatrix transformation matrix
* @param path the path to shadow
* @param rec parameters for shadow rendering
*/
bool drawFastShadow(const GrClip*,
const SkMatrix& viewMatrix,
const SkPath& path,
const SkDrawShadowRec& rec);
/**
* Draws a path.
*
* @param paint describes how to color pixels.
* @param GrAA Controls whether the path is antialiased.
* @param viewMatrix transformation matrix
* @param path the path to draw
* @param style style to apply to the path.
*/
void drawPath(const GrClip*,
GrPaint&&,
GrAA,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStyle&);
/**
* Draws a shape.
*
* @param paint describes how to color pixels.
* @param GrAA Controls whether the path is antialiased.
* @param viewMatrix transformation matrix
* @param shape the shape to draw
*/
void drawShape(const GrClip*,
GrPaint&&,
GrAA,
const SkMatrix& viewMatrix,
GrStyledShape&&);
/**
* Draws vertices with a paint.
*
* @param paint describes how to color pixels.
* @param viewMatrix transformation matrix
* @param vertices specifies the mesh to draw.
* @param overridePrimType primitive type to draw. If NULL, derive prim type from vertices.
* @param skipColorXform if true, do not apply a color space transfer function
*/
void drawVertices(const GrClip*,
GrPaint&& paint,
const SkMatrix& viewMatrix,
sk_sp<SkVertices> vertices,
GrPrimitiveType* overridePrimType = nullptr,
bool skipColorXform = false);
/**
* Draws a custom mesh with a paint.
*
* @param paint describes how to color pixels.
* @param viewMatrix transformation matrix
* @param mesh the mesh to draw.
* @param children child effects referenced by SkMesh shaders
*/
void drawMesh(const GrClip*,
GrPaint&& paint,
const SkMatrix& viewMatrix,
const SkMesh& mesh,
skia_private::TArray<std::unique_ptr<GrFragmentProcessor>> children);
/**
* Draws textured sprites from an atlas with a paint. This currently does not support AA for the
* sprite rectangle edges.
*
* @param paint describes how to color pixels.
* @param viewMatrix transformation matrix
* @param spriteCount number of sprites.
* @param xform array of compressed transformation data, required.
* @param texRect array of texture rectangles used to access the paint.
* @param colors optional array of per-sprite colors, supercedes
* the paint's color field.
*/
void drawAtlas(const GrClip*,
GrPaint&& paint,
const SkMatrix& viewMatrix,
int spriteCount,
const SkRSXform xform[],
const SkRect texRect[],
const SkColor colors[]);
/**
* Draws a region.
*
* @param paint describes how to color pixels
* @param viewMatrix transformation matrix
* @param aa should the rects of the region be antialiased.
* @param region the region to be drawn
* @param style style to apply to the region
*/
void drawRegion(const GrClip*,
GrPaint&& paint,
GrAA aa,
const SkMatrix& viewMatrix,
const SkRegion& region,
const GrStyle& style,
const GrUserStencilSettings* ss = nullptr);
/**
* Draws an oval.
*
* @param paint describes how to color pixels.
* @param GrAA Controls whether the oval is antialiased.
* @param viewMatrix transformation matrix
* @param oval the bounding rect of the oval.
* @param style style to apply to the oval. Currently path effects are not allowed.
*/
void drawOval(const GrClip*,
GrPaint&& paint,
GrAA,
const SkMatrix& viewMatrix,
const SkRect& oval,
const GrStyle& style);
/**
* Draws a partial arc of an oval.
*
* @param paint describes how to color pixels.
* @param GrGrAA Controls whether the arc is antialiased.
* @param viewMatrix transformation matrix.
* @param oval the bounding rect of the oval.
* @param startAngle starting angle in degrees.
* @param sweepAngle angle to sweep in degrees. Must be in (-360, 360)
* @param useCenter true 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.
* @param style style to apply to the oval.
*/
void drawArc(const GrClip*,
GrPaint&& paint,
GrAA,
const SkMatrix& viewMatrix,
const SkArc& arc,
const GrStyle& style);
/**
* Draw the image as a set of rects, specified by |iter|.
*/
void drawImageLattice(const GrClip*,
GrPaint&&,
const SkMatrix& viewMatrix,
GrSurfaceProxyView,
SkAlphaType alphaType,
sk_sp<GrColorSpaceXform>,
GrSamplerState::Filter,
std::unique_ptr<SkLatticeIter>,
const SkRect& dst);
/**
* Draw the text specified by the GlyphRunList.
*
* @param viewMatrix transformation matrix
* @param glyphRunList text, text positions, and paint.
*/
void drawGlyphRunList(SkCanvas*,
const GrClip*,
const SkMatrix& viewMatrix,
const sktext::GlyphRunList& glyphRunList,
SkStrikeDeviceInfo strikeDeviceInfo,
const SkPaint& paint);
/**
* Adds the necessary signal and wait semaphores and adds the passed in SkDrawable to the
* command stream.
*/
void drawDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>, const SkRect& bounds);
// called to note the last clip drawn to the stencil buffer.
// TODO: remove after clipping overhaul.
void setLastClip(uint32_t clipStackGenID,
const SkIRect& devClipBounds,
int numClipAnalyticElements);
// called to determine if we have to render the clip into SB.
// TODO: remove after clipping overhaul.
bool mustRenderClip(uint32_t clipStackGenID,
const SkIRect& devClipBounds,
int numClipAnalyticElements);
void clearStencilClip(const SkIRect& scissor, bool insideStencilMask) {
this->internalStencilClear(&scissor, insideStencilMask);
}
// While this can take a general clip, since ClipStack relies on this function, it must take
// care to only provide hard clips or we could get stuck in a loop. The general clip is needed
// so that path renderers can use this function.
void stencilRect(const GrClip* clip,
const GrUserStencilSettings* ss,
GrPaint&& paint,
GrAA doStencilMSAA,
const SkMatrix& viewMatrix,
const SkRect& rect,
const SkMatrix* localMatrix = nullptr) {
// Since this provides stencil settings to drawFilledQuad, it performs a different AA type
// resolution compared to regular rect draws, which is the main reason it remains separate.
DrawQuad quad{GrQuad::MakeFromRect(rect, viewMatrix),
localMatrix ? GrQuad::MakeFromRect(rect, *localMatrix) : GrQuad(rect),
doStencilMSAA == GrAA::kYes ? GrQuadAAFlags::kAll : GrQuadAAFlags::kNone};
this->drawFilledQuad(clip, std::move(paint), &quad, ss);
}
// Fills the user stencil bits with a non-zero value at every sample inside the path. This will
// likely be implemented with a Redbook algorithm, but it is not guaranteed. The samples being
// rendered to must be zero initially.
bool stencilPath(const GrHardClip*,
GrAA doStencilMSAA,
const SkMatrix& viewMatrix,
const SkPath&);
/**
* Draws a path, either AA or not, and touches the stencil buffer with the user stencil settings
* for each color sample written.
*/
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;
/*
* This unique ID will not change for a given SurfaceDrawContext. However, it is _NOT_
* guaranteed to match the uniqueID of the underlying GrRenderTarget - beware!
*/
GrSurfaceProxy::UniqueID uniqueID() const { return this->asSurfaceProxy()->uniqueID(); }
// Allows caller of addDrawOp to know which op list an op will be added to.
using WillAddOpFn = void(GrOp*, uint32_t opsTaskID);
// These perform processing specific to GrDrawOp-derived ops before recording them into an
// op list. Before adding the op to an op list the WillAddOpFn is called. Note that it
// will not be called in the event that the op is discarded. Moreover, the op may merge into
// another op after the function is called (either before addDrawOp returns or some time later).
//
// If the clip pointer is null, no clipping will be performed.
void addDrawOp(const GrClip*,
GrOp::Owner,
const std::function<WillAddOpFn>& = std::function<WillAddOpFn>());
void addDrawOp(GrOp::Owner op) { this->addDrawOp(nullptr, std::move(op)); }
bool refsWrappedObjects() const { return this->asRenderTargetProxy()->refsWrappedObjects(); }
/**
* The next time this SurfaceDrawContext is flushed, the gpu will wait on the passed in
* semaphores before executing any commands.
*/
bool waitOnSemaphores(int numSemaphores, const GrBackendSemaphore waitSemaphores[],
bool deleteSemaphoresAfterWait);
int numSamples() const { return this->asRenderTargetProxy()->numSamples(); }
const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
bool canUseDynamicMSAA() const { return fCanUseDynamicMSAA; }
bool wrapsVkSecondaryCB() const { return this->asRenderTargetProxy()->wrapsVkSecondaryCB(); }
bool alwaysAntialias() const {
return fSurfaceProps.flags() & SkSurfaceProps::kDynamicMSAA_Flag;
}
GrAA chooseAA(const SkPaint& paint) {
return GrAA(paint.isAntiAlias() || this->alwaysAntialias());
}
GrAAType chooseAAType(GrAA aa) {
if (this->numSamples() > 1 || fCanUseDynamicMSAA) {
// Always trigger DMSAA when it's available. The coverage ops that know how to handle
// both single and multisample targets without popping will do so without calling
// chooseAAType.
return GrAAType::kMSAA;
}
return (aa == GrAA::kYes) ? GrAAType::kCoverage : GrAAType::kNone;
}
// This entry point should only be called if the backing GPU object is known to be
// instantiated.
GrRenderTarget* accessRenderTarget() { return this->asSurfaceProxy()->peekRenderTarget(); }
#if defined(GR_TEST_UTILS)
void testingOnly_SetPreserveOpsOnFullClear() { fPreserveOpsOnFullClear_TestingOnly = true; }
#endif
void drawStrokedLine(const GrClip*, GrPaint&&, GrAA, const SkMatrix&, const SkPoint[2],
const SkStrokeRec&);
private:
enum class QuadOptimization;
void willReplaceOpsTask(OpsTask* prevTask, OpsTask* nextTask) override;
OpsTask::CanDiscardPreviousOps canDiscardPreviousOpsOnFullClear() const override;
void setNeedsStencil();
void internalStencilClear(const SkIRect* scissor, bool insideStencilMask);
// 'stencilSettings' are provided merely for decision making purposes; When non-null,
// optimization strategies that submit special ops are avoided.
//
// 'quad' should be the original draw request on input, and will be updated as
// appropriate depending on the returned optimization level.
//
// If kSubmitted is returned, the provided paint was consumed. Otherwise it is left unchanged.
QuadOptimization attemptQuadOptimization(const GrClip* clip,
const GrUserStencilSettings* stencilSettings,
DrawQuad* quad,
GrPaint* paint);
// The overall AA policy is determined by the quad's edge flags: kNone is no AA, and anything
// else uses some form of anti-aliasing. If 'ss' is non-null, that will be MSAA; otherwise it's
// MSAA or analytic coverage per chooseAAType(). This will always attempt to apply
// quad optimizations, so all quad/rect public APIs should rely on this function for consistent
// clipping behavior. 'quad' will be modified in place to reflect final rendered geometry.
void drawFilledQuad(const GrClip* clip,
GrPaint&& paint,
DrawQuad* quad,
const GrUserStencilSettings* ss = nullptr);
// Like drawFilledQuad but does not require using a GrPaint or FP for texturing.
// 'quad' may be modified in place to reflect final geometry.
void drawTexturedQuad(const GrClip* clip,
GrSurfaceProxyView proxyView,
SkAlphaType alphaType,
sk_sp<GrColorSpaceXform> textureXform,
GrSamplerState::Filter filter,
GrSamplerState::MipmapMode,
const SkPMColor4f& color,
SkBlendMode blendMode,
DrawQuad* quad,
const SkRect* subset = nullptr);
// Tries to detect if the given shape is a simple, and draws it without path rendering if
// we know how.
bool drawSimpleShape(const GrClip*, GrPaint*, GrAA, const SkMatrix&, const GrStyledShape&);
// If 'attemptDrawSimple' is true, of if the original shape is marked as having been simplfied,
// this will attempt to re-route through drawSimpleShape() to see if we can avoid path rendering
// one more time.
void drawShapeUsingPathRenderer(const GrClip*, GrPaint&&, GrAA, const SkMatrix&,
GrStyledShape&&, bool attemptDrawSimple = false);
// Makes a copy of the proxy if it is necessary for the draw and places the texture that should
// be used by GrXferProcessor to access the destination color in 'result'. If the return
// value is false then a texture copy could not be made.
//
// The op should have already had setClippedBounds called on it.
[[nodiscard]] bool setupDstProxyView(const SkRect& opBounds,
bool opRequiresMSAA,
GrDstProxyView* result);
OpsTask* replaceOpsTaskIfModifiesColor();
const SkSurfaceProps fSurfaceProps;
const bool fCanUseDynamicMSAA;
bool fNeedsStencil = false;
#if defined(GR_TEST_UTILS)
bool fPreserveOpsOnFullClear_TestingOnly = false;
#endif
};
} // namespace skgpu::ganesh
#endif // SurfaceDrawContext_v1_DEFINED