Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | Private Member Functions | List of all members
CircleOp Class Referencefinal
Inheritance diagram for CircleOp:
GrMeshDrawOp GrDrawOp GrOp SkNoncopyable

Classes

struct  ArcParams
 

Public Member Functions

 CircleOp (GrProcessorSet *processorSet, const SkPMColor4f &color, const SkMatrix &viewMatrix, SkPoint center, SkScalar radius, const GrStyle &style, const ArcParams *arcParams)
 
const char * name () const override
 
void visitProxies (const GrVisitProxyFunc &func) const override
 
GrProcessorSet::Analysis finalize (const GrCaps &caps, const GrAppliedClip *clip, GrClampType clampType) override
 
FixedFunctionFlags fixedFunctionFlags () const override
 
- Public Member Functions inherited from GrDrawOp
 GrDrawOp (uint32_t classID)
 
virtual bool usesMSAA () const
 
virtual ClipResult clipToShape (skgpu::ganesh::SurfaceDrawContext *, SkClipOp, const SkMatrix &, const GrShape &, GrAA)
 
virtual bool usesStencil () const
 
- Public Member Functions inherited from GrOp
virtual ~GrOp ()=default
 
CombineResult combineIfPossible (GrOp *that, SkArenaAlloc *alloc, const GrCaps &caps)
 
const SkRectbounds () const
 
void setClippedBounds (const SkRect &clippedBounds)
 
bool hasAABloat () const
 
bool hasZeroArea () const
 
void operator delete (void *p)
 
template<typename T >
const Tcast () const
 
template<typename T >
Tcast ()
 
uint32_t classID () const
 
uint32_t uniqueID () const
 
void prePrepare (GrRecordingContext *context, const GrSurfaceProxyView &dstView, GrAppliedClip *clip, const GrDstProxyView &dstProxyView, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp)
 
void prepare (GrOpFlushState *state)
 
void execute (GrOpFlushState *state, const SkRect &chainBounds)
 
void chainConcat (GrOp::Owner)
 
bool isChainHead () const
 
bool isChainTail () const
 
GrOpnextInChain () const
 
GrOpprevInChain () const
 
GrOp::Owner cutChain ()
 
void setBounds (const SkRect &newBounds, HasAABloat aabloat, IsHairline zeroArea)
 
void setTransformedBounds (const SkRect &srcBounds, const SkMatrix &m, HasAABloat aabloat, IsHairline zeroArea)
 
void makeFullScreen (GrSurfaceProxy *proxy)
 

Static Public Member Functions

static GrOp::Owner Make (GrRecordingContext *context, GrPaint &&paint, const SkMatrix &viewMatrix, SkPoint center, SkScalar radius, const GrStyle &style, const ArcParams *arcParams=nullptr)
 
- Static Public Member Functions inherited from GrMeshDrawOp
static bool CanUpgradeAAOnMerge (GrAAType aa1, GrAAType aa2)
 
- Static Public Member Functions inherited from GrOp
template<typename Op , typename... Args>
static Owner Make (GrRecordingContext *context, Args &&... args)
 
template<typename Op , typename... Args>
static Owner MakeWithProcessorSet (GrRecordingContext *context, const SkPMColor4f &color, GrPaint &&paint, Args &&... args)
 
template<typename Op , typename... Args>
static Owner MakeWithExtraMemory (GrRecordingContext *context, size_t extraSize, Args &&... args)
 
static uint32_t GenOpClassID ()
 

Private Member Functions

GrProgramInfoprogramInfo () override
 
void onCreateProgramInfo (const GrCaps *caps, SkArenaAlloc *arena, const GrSurfaceProxyView &writeView, bool usesMSAASurface, GrAppliedClip &&appliedClip, const GrDstProxyView &dstProxyView, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp) override
 
void onPrepareDraws (GrMeshDrawTarget *target) override
 
void onExecute (GrOpFlushState *flushState, const SkRect &chainBounds) override
 
CombineResult onCombineIfPossible (GrOp *t, SkArenaAlloc *, const GrCaps &caps) override
 

Additional Inherited Members

- Public Types inherited from GrDrawOp
enum class  ClipResult { kFail , kClippedGeometrically , kClippedInShader , kClippedOut }
 
- Public Types inherited from GrOp
enum class  CombineResult { kMerged , kMayChain , kCannotCombine }
 
enum class  HasAABloat : bool { kNo = false , kYes = true }
 
enum class  IsHairline : bool { kNo = false , kYes = true }
 
using Owner = std::unique_ptr< GrOp >
 
- Protected Types inherited from GrDrawOp
enum class  FixedFunctionFlags : uint32_t { kNone = 0x0 , kUsesHWAA = 0x1 , kUsesStencil = 0x2 }
 
- Protected Member Functions inherited from GrMeshDrawOp
 GrMeshDrawOp (uint32_t classID)
 
void createProgramInfo (const GrCaps *caps, SkArenaAlloc *arena, const GrSurfaceProxyView &writeView, bool usesMSAASurface, GrAppliedClip &&appliedClip, const GrDstProxyView &dstProxyView, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp)
 
void createProgramInfo (GrMeshDrawTarget *)
 
virtual void onPrePrepareDraws (GrRecordingContext *, const GrSurfaceProxyView &writeView, GrAppliedClip *, const GrDstProxyView &, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp)
 
- Protected Member Functions inherited from GrDrawOp
 GR_DECL_BITFIELD_CLASS_OPS_FRIENDS (FixedFunctionFlags)
 
- Static Protected Member Functions inherited from GrMeshDrawOp
static bool CombinedQuadCountWillOverflow (GrAAType aaType, bool willBeUpgradedToAA, int combinedQuadCount)
 

Detailed Description

Definition at line 985 of file GrOvalOpFactory.cpp.

Constructor & Destructor Documentation

◆ CircleOp()

CircleOp::CircleOp ( GrProcessorSet processorSet,
const SkPMColor4f color,
const SkMatrix viewMatrix,
SkPoint  center,
SkScalar  radius,
const GrStyle style,
const ArcParams arcParams 
)
inline

Definition at line 1041 of file GrOvalOpFactory.cpp.

1044 : GrMeshDrawOp(ClassID())
1045 , fHelper(processorSet, GrAAType::kCoverage) {
1046 const SkStrokeRec& stroke = style.strokeRec();
1047 SkStrokeRec::Style recStyle = stroke.getStyle();
1048
1049 fRoundCaps = false;
1050
1051 viewMatrix.mapPoints(&center, 1);
1052 radius = viewMatrix.mapRadius(radius);
1053 SkScalar strokeWidth = viewMatrix.mapRadius(stroke.getWidth());
1054
1055 bool isStrokeOnly =
1057 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == recStyle;
1058
1059 SkScalar innerRadius = -SK_ScalarHalf;
1060 SkScalar outerRadius = radius;
1061 SkScalar halfWidth = 0;
1062 if (hasStroke) {
1064 halfWidth = SK_ScalarHalf;
1065 } else {
1066 halfWidth = SkScalarHalf(strokeWidth);
1067 }
1068
1069 outerRadius += halfWidth;
1070 if (isStrokeOnly) {
1071 innerRadius = radius - halfWidth;
1072 }
1073 }
1074
1075 // The radii are outset for two reasons. First, it allows the shader to simply perform
1076 // simpler computation because the computed alpha is zero, rather than 50%, at the radius.
1077 // Second, the outer radius is used to compute the verts of the bounding box that is
1078 // rendered and the outset ensures the box will cover all partially covered by the circle.
1079 outerRadius += SK_ScalarHalf;
1080 innerRadius -= SK_ScalarHalf;
1081 bool stroked = isStrokeOnly && innerRadius > 0.0f;
1082 fViewMatrixIfUsingLocalCoords = viewMatrix;
1083
1084 // This makes every point fully inside the intersection plane.
1085 static constexpr SkScalar kUnusedIsectPlane[] = {0.f, 0.f, 1.f};
1086 // This makes every point fully outside the union plane.
1087 static constexpr SkScalar kUnusedUnionPlane[] = {0.f, 0.f, 0.f};
1088 static constexpr SkPoint kUnusedRoundCaps[] = {{1e10f, 1e10f}, {1e10f, 1e10f}};
1089 SkRect devBounds = SkRect::MakeLTRB(center.fX - outerRadius, center.fY - outerRadius,
1090 center.fX + outerRadius, center.fY + outerRadius);
1091 if (arcParams) {
1092 // The shader operates in a space where the circle is translated to be centered at the
1093 // origin. Here we compute points on the unit circle at the starting and ending angles.
1094 SkPoint startPoint, stopPoint;
1095 startPoint.fY = SkScalarSin(arcParams->fStartAngleRadians);
1096 startPoint.fX = SkScalarCos(arcParams->fStartAngleRadians);
1097 SkScalar endAngle = arcParams->fStartAngleRadians + arcParams->fSweepAngleRadians;
1098 stopPoint.fY = SkScalarSin(endAngle);
1099 stopPoint.fX = SkScalarCos(endAngle);
1100
1101 // Adjust the start and end points based on the view matrix (to handle rotated arcs)
1102 startPoint = viewMatrix.mapVector(startPoint.fX, startPoint.fY);
1103 stopPoint = viewMatrix.mapVector(stopPoint.fX, stopPoint.fY);
1104 startPoint.normalize();
1105 stopPoint.normalize();
1106
1107 // We know the matrix is a similarity here. Detect mirroring which will affect how we
1108 // should orient the clip planes for arcs.
1109 SkASSERT(viewMatrix.isSimilarity());
1110 auto upperLeftDet = viewMatrix.getScaleX()*viewMatrix.getScaleY() -
1111 viewMatrix.getSkewX() *viewMatrix.getSkewY();
1112 if (upperLeftDet < 0) {
1113 std::swap(startPoint, stopPoint);
1114 }
1115
1116 fRoundCaps = style.strokeRec().getWidth() > 0 &&
1118 SkPoint roundCaps[2];
1119 if (fRoundCaps) {
1120 // Compute the cap center points in the normalized space.
1121 SkScalar midRadius = (innerRadius + outerRadius) / (2 * outerRadius);
1122 roundCaps[0] = startPoint * midRadius;
1123 roundCaps[1] = stopPoint * midRadius;
1124 } else {
1125 roundCaps[0] = kUnusedRoundCaps[0];
1126 roundCaps[1] = kUnusedRoundCaps[1];
1127 }
1128
1129 // Like a fill without useCenter, butt-cap stroke can be implemented by clipping against
1130 // radial lines. We treat round caps the same way, but tack coverage of circles at the
1131 // center of the butts.
1132 // However, in both cases we have to be careful about the half-circle.
1133 // case. In that case the two radial lines are equal and so that edge gets clipped
1134 // twice. Since the shared edge goes through the center we fall back on the !useCenter
1135 // case.
1136 auto absSweep = SkScalarAbs(arcParams->fSweepAngleRadians);
1137 bool useCenter = (arcParams->fUseCenter || isStrokeOnly) &&
1138 !SkScalarNearlyEqual(absSweep, SK_ScalarPI);
1139 if (useCenter) {
1140 SkVector norm0 = {startPoint.fY, -startPoint.fX};
1141 SkVector norm1 = {stopPoint.fY, -stopPoint.fX};
1142 // This ensures that norm0 is always the clockwise plane, and norm1 is CCW.
1143 if (arcParams->fSweepAngleRadians < 0) {
1144 std::swap(norm0, norm1);
1145 }
1146 norm0.negate();
1147 fClipPlane = true;
1148 if (absSweep > SK_ScalarPI) {
1149 fCircles.emplace_back(Circle{
1150 color,
1151 innerRadius,
1152 outerRadius,
1153 {norm0.fX, norm0.fY, 0.5f},
1154 {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2]},
1155 {norm1.fX, norm1.fY, 0.5f},
1156 {roundCaps[0], roundCaps[1]},
1157 devBounds,
1158 stroked});
1159 fClipPlaneIsect = false;
1160 fClipPlaneUnion = true;
1161 } else {
1162 fCircles.emplace_back(Circle{
1163 color,
1164 innerRadius,
1165 outerRadius,
1166 {norm0.fX, norm0.fY, 0.5f},
1167 {norm1.fX, norm1.fY, 0.5f},
1168 {kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnusedUnionPlane[2]},
1169 {roundCaps[0], roundCaps[1]},
1170 devBounds,
1171 stroked});
1172 fClipPlaneIsect = true;
1173 fClipPlaneUnion = false;
1174 }
1175 } else {
1176 // We clip to a secant of the original circle.
1177 startPoint.scale(radius);
1178 stopPoint.scale(radius);
1179 SkVector norm = {startPoint.fY - stopPoint.fY, stopPoint.fX - startPoint.fX};
1180 norm.normalize();
1181 if (arcParams->fSweepAngleRadians > 0) {
1182 norm.negate();
1183 }
1184 SkScalar d = -norm.dot(startPoint) + 0.5f;
1185
1186 fCircles.emplace_back(
1187 Circle{color,
1188 innerRadius,
1189 outerRadius,
1190 {norm.fX, norm.fY, d},
1191 {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2]},
1192 {kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnusedUnionPlane[2]},
1193 {roundCaps[0], roundCaps[1]},
1194 devBounds,
1195 stroked});
1196 fClipPlane = true;
1197 fClipPlaneIsect = false;
1198 fClipPlaneUnion = false;
1199 }
1200 } else {
1201 fCircles.emplace_back(
1202 Circle{color,
1203 innerRadius,
1204 outerRadius,
1205 {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2]},
1206 {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2]},
1207 {kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnusedUnionPlane[2]},
1208 {kUnusedRoundCaps[0], kUnusedRoundCaps[1]},
1209 devBounds,
1210 stroked});
1211 fClipPlane = false;
1212 fClipPlaneIsect = false;
1213 fClipPlaneUnion = false;
1214 }
1215 // Use the original radius and stroke radius for the bounds so that it does not include the
1216 // AA bloat.
1217 radius += halfWidth;
1218 this->setBounds(
1219 {center.fX - radius, center.fY - radius, center.fX + radius, center.fY + radius},
1221 fVertCount = circle_type_to_vert_count(stroked);
1222 fIndexCount = circle_type_to_index_count(stroked);
1223 fAllFill = !stroked;
1224 }
static const int strokeWidth
Definition BlurTest.cpp:60
static int circle_type_to_index_count(bool stroked)
static int circle_type_to_vert_count(bool stroked)
SkColor4f color
#define SkASSERT(cond)
Definition SkAssert.h:116
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:101
#define SkScalarSin(radians)
Definition SkScalar.h:45
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:107
#define SkScalarHalf(a)
Definition SkScalar.h:75
#define SK_ScalarHalf
Definition SkScalar.h:19
#define SkScalarCos(radians)
Definition SkScalar.h:46
#define SkScalarAbs(x)
Definition SkScalar.h:39
#define SK_ScalarPI
Definition SkScalar.h:21
static SkScalar center(float pos0, float pos1)
void setBounds(const SkRect &newBounds, HasAABloat aabloat, IsHairline zeroArea)
Definition GrOp.h:279
const SkStrokeRec & strokeRec() const
Definition GrStyle.h:140
SkScalar mapRadius(SkScalar radius) const
SkScalar getSkewY() const
Definition SkMatrix.h:430
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
Definition SkMatrix.cpp:770
SkScalar getSkewX() const
Definition SkMatrix.h:438
SkScalar getScaleX() const
Definition SkMatrix.h:415
SkScalar getScaleY() const
Definition SkMatrix.h:422
bool isSimilarity(SkScalar tol=SK_ScalarNearlyZero) const
Definition SkMatrix.cpp:180
void mapVector(SkScalar dx, SkScalar dy, SkVector *result) const
Definition SkMatrix.h:1524
@ kRound_Cap
adds circle
Definition SkPaint.h:335
Style getStyle() const
@ kStrokeAndFill_Style
Definition SkStrokeRec.h:36
SkScalar getWidth() const
Definition SkStrokeRec.h:42
SkPaint::Cap getCap() const
Definition SkStrokeRec.h:44
T & emplace_back(Args &&... args)
Definition SkTArray.h:243
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
float SkScalar
Definition extension.cpp:12
void negate()
float fX
x-axis value
float dot(const SkVector &vec) const
void scale(float scale, SkPoint *dst) const
Definition SkPoint.cpp:17
float fY
y-axis value
bool normalize()
Definition SkPoint.cpp:22
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition SkRect.h:646

Member Function Documentation

◆ finalize()

GrProcessorSet::Analysis CircleOp::finalize ( const GrCaps ,
const GrAppliedClip ,
GrClampType   
)
inlineoverridevirtual

This is called after the GrAppliedClip has been computed and just prior to recording the op or combining it with a previously recorded op. The op should convert any proxies or resources it owns to "pending io" status so that resource allocation can be more optimal. Additionally, at this time the op must report whether a copy of the destination (or destination texture itself) needs to be provided to the GrXferProcessor when this op executes.

Implements GrDrawOp.

Definition at line 1236 of file GrOvalOpFactory.cpp.

1237 {
1238 SkPMColor4f* color = &fCircles.front().fColor;
1239 return fHelper.finalizeProcessors(caps, clip, clampType,
1241 &fWideColor);
1242 }
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
GrProcessorSet::Analysis finalizeProcessors(const GrCaps &caps, const GrAppliedClip *clip, GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage, GrProcessorAnalysisColor *geometryColor)

◆ fixedFunctionFlags()

FixedFunctionFlags CircleOp::fixedFunctionFlags ( ) const
inlineoverridevirtual

Reimplemented from GrDrawOp.

Definition at line 1244 of file GrOvalOpFactory.cpp.

1244{ return fHelper.fixedFunctionFlags(); }
GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const

◆ Make()

static GrOp::Owner CircleOp::Make ( GrRecordingContext context,
GrPaint &&  paint,
const SkMatrix viewMatrix,
SkPoint  center,
SkScalar  radius,
const GrStyle style,
const ArcParams arcParams = nullptr 
)
inlinestatic

Definition at line 999 of file GrOvalOpFactory.cpp.

1005 {
1006 SkASSERT(circle_stays_circle(viewMatrix));
1007 if (style.hasPathEffect()) {
1008 return nullptr;
1009 }
1010 const SkStrokeRec& stroke = style.strokeRec();
1011 SkStrokeRec::Style recStyle = stroke.getStyle();
1012 if (arcParams) {
1013 // Arc support depends on the style.
1014 switch (recStyle) {
1016 // This produces a strange result that this op doesn't implement.
1017 return nullptr;
1019 // This supports all fills.
1020 break;
1022 // Strokes that don't use the center point are supported with butt and round
1023 // caps.
1024 if (arcParams->fUseCenter || stroke.getCap() == SkPaint::kSquare_Cap) {
1025 return nullptr;
1026 }
1027 break;
1029 // Hairline only supports butt cap. Round caps could be emulated by slightly
1030 // extending the angle range if we ever care to.
1031 if (arcParams->fUseCenter || stroke.getCap() != SkPaint::kButt_Cap) {
1032 return nullptr;
1033 }
1034 break;
1035 }
1036 }
1037 return Helper::FactoryHelper<CircleOp>(context, std::move(paint), viewMatrix, center,
1038 radius, style, arcParams);
1039 }
bool hasPathEffect() const
Definition GrStyle.h:122
@ kButt_Cap
no stroke extension
Definition SkPaint.h:334
@ kSquare_Cap
adds square
Definition SkPaint.h:336
const Paint & paint

◆ name()

const char * CircleOp::name ( ) const
inlineoverridevirtual

Implements GrOp.

Definition at line 1226 of file GrOvalOpFactory.cpp.

1226{ return "CircleOp"; }

◆ onCombineIfPossible()

CombineResult CircleOp::onCombineIfPossible ( GrOp t,
SkArenaAlloc ,
const GrCaps caps 
)
inlineoverrideprivatevirtual

Reimplemented from GrOp.

Definition at line 1420 of file GrOvalOpFactory.cpp.

1420 {
1421 CircleOp* that = t->cast<CircleOp>();
1422
1423 // can only represent 65535 unique vertices with 16-bit indices
1424 if (fVertCount + that->fVertCount > 65536) {
1426 }
1427
1428 if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
1430 }
1431
1432 if (fHelper.usesLocalCoords() &&
1433 !SkMatrixPriv::CheapEqual(fViewMatrixIfUsingLocalCoords,
1434 that->fViewMatrixIfUsingLocalCoords)) {
1436 }
1437
1438 // Because we've set up the ops that don't use the planes with noop values
1439 // we can just accumulate used planes by later ops.
1440 fClipPlane |= that->fClipPlane;
1441 fClipPlaneIsect |= that->fClipPlaneIsect;
1442 fClipPlaneUnion |= that->fClipPlaneUnion;
1443 fRoundCaps |= that->fRoundCaps;
1444 fWideColor |= that->fWideColor;
1445
1446 fCircles.push_back_n(that->fCircles.size(), that->fCircles.begin());
1447 fVertCount += that->fVertCount;
1448 fIndexCount += that->fIndexCount;
1449 fAllFill = fAllFill && that->fAllFill;
1451 }
const T & cast() const
Definition GrOp.h:148
const SkRect & bounds() const
Definition GrOp.h:122
bool isCompatible(const GrSimpleMeshDrawOpHelper &that, const GrCaps &, const SkRect &thisBounds, const SkRect &thatBounds, bool ignoreAAType=false) const
static bool CheapEqual(const SkMatrix &a, const SkMatrix &b)
T * push_back_n(int n)
Definition SkTArray.h:262
int size() const
Definition SkTArray.h:416

◆ onCreateProgramInfo()

void CircleOp::onCreateProgramInfo ( const GrCaps caps,
SkArenaAlloc arena,
const GrSurfaceProxyView writeView,
bool  usesMSAASurface,
GrAppliedClip &&  appliedClip,
const GrDstProxyView dstProxyView,
GrXferBarrierFlags  renderPassXferBarriers,
GrLoadOp  colorLoadOp 
)
inlineoverrideprivatevirtual

Implements GrMeshDrawOp.

Definition at line 1249 of file GrOvalOpFactory.cpp.

1256 {
1257 SkASSERT(!usesMSAASurface);
1258
1259 SkMatrix localMatrix;
1260 if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) {
1261 return;
1262 }
1263
1264 GrGeometryProcessor* gp = CircleGeometryProcessor::Make(arena, !fAllFill, fClipPlane,
1265 fClipPlaneIsect, fClipPlaneUnion,
1266 fRoundCaps, fWideColor,
1267 localMatrix);
1268
1269 fProgramInfo = fHelper.createProgramInfo(caps,
1270 arena,
1271 writeView,
1272 usesMSAASurface,
1273 std::move(appliedClip),
1274 dstProxyView,
1275 gp,
1277 renderPassXferBarriers,
1278 colorLoadOp);
1279 }
static GrGeometryProcessor * Make(SkArenaAlloc *arena, bool stroke, bool clipPlane, bool isectPlane, bool unionPlane, bool roundCaps, bool wideColor, const SkMatrix &localMatrix)
GrProgramInfo * createProgramInfo(const GrCaps *, SkArenaAlloc *, const GrSurfaceProxyView &writeView, bool usesMSAASurface, GrAppliedClip &&, const GrDstProxyView &, GrGeometryProcessor *, GrPrimitiveType, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp)
bool invert(SkMatrix *inverse) const
Definition SkMatrix.h:1206

◆ onExecute()

void CircleOp::onExecute ( GrOpFlushState flushState,
const SkRect chainBounds 
)
inlineoverrideprivatevirtual

Implements GrOp.

Definition at line 1410 of file GrOvalOpFactory.cpp.

1410 {
1411 if (!fProgramInfo || !fMesh) {
1412 return;
1413 }
1414
1415 flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds);
1416 flushState->bindTextures(fProgramInfo->geomProc(), nullptr, fProgramInfo->pipeline());
1417 flushState->drawMesh(*fMesh);
1418 }
void drawMesh(const GrSimpleMesh &mesh)
void bindPipelineAndScissorClip(const GrProgramInfo &programInfo, const SkRect &drawBounds)
void bindTextures(const GrGeometryProcessor &geomProc, const GrSurfaceProxy &singleGeomProcTexture, const GrPipeline &pipeline)
const GrPipeline & pipeline() const
const GrGeometryProcessor & geomProc() const

◆ onPrepareDraws()

void CircleOp::onPrepareDraws ( GrMeshDrawTarget target)
inlineoverrideprivatevirtual

Implements GrMeshDrawOp.

Definition at line 1281 of file GrOvalOpFactory.cpp.

1281 {
1282 if (!fProgramInfo) {
1283 this->createProgramInfo(target);
1284 if (!fProgramInfo) {
1285 return;
1286 }
1287 }
1288
1289 sk_sp<const GrBuffer> vertexBuffer;
1290 int firstVertex;
1291 VertexWriter vertices = target->makeVertexWriter(fProgramInfo->geomProc().vertexStride(),
1292 fVertCount, &vertexBuffer, &firstVertex);
1293 if (!vertices) {
1294 SkDebugf("Could not allocate vertices\n");
1295 return;
1296 }
1297
1298 sk_sp<const GrBuffer> indexBuffer = nullptr;
1299 int firstIndex = 0;
1300 uint16_t* indices = target->makeIndexSpace(fIndexCount, &indexBuffer, &firstIndex);
1301 if (!indices) {
1302 SkDebugf("Could not allocate indices\n");
1303 return;
1304 }
1305
1306 int currStartVertex = 0;
1307 for (const auto& circle : fCircles) {
1308 SkScalar innerRadius = circle.fInnerRadius;
1309 SkScalar outerRadius = circle.fOuterRadius;
1310 VertexColor color(circle.fColor, fWideColor);
1311 const SkRect& bounds = circle.fDevBounds;
1312
1313 // The inner radius in the vertex data must be specified in normalized space.
1314 innerRadius = innerRadius / outerRadius;
1315 SkPoint radii = { outerRadius, innerRadius };
1316
1318 SkScalar halfWidth = 0.5f * bounds.width();
1319
1320 SkVector geoClipPlane = { 0, 0 };
1321 SkScalar offsetClipDist = SK_Scalar1;
1322 if (!circle.fStroked && fClipPlane && fClipPlaneIsect &&
1323 (circle.fClipPlane[0] * circle.fIsectPlane[0] +
1324 circle.fClipPlane[1] * circle.fIsectPlane[1]) < 0.0f) {
1325 // Acute arc. Clip the vertices to the perpendicular half-plane. We've constructed
1326 // fClipPlane to be clockwise, and fISectPlane to be CCW, so we can can rotate them
1327 // each 90 degrees to point "out", then average them. We back off by 1/2 pixel so
1328 // the AA can extend just past the center of the circle.
1329 geoClipPlane.set(circle.fClipPlane[1] - circle.fIsectPlane[1],
1330 circle.fIsectPlane[0] - circle.fClipPlane[0]);
1331 SkAssertResult(geoClipPlane.normalize());
1332 offsetClipDist = 0.5f / halfWidth;
1333 }
1334
1335 for (int i = 0; i < 8; ++i) {
1336 // This clips the normalized offset to the half-plane we computed above. Then we
1337 // compute the vertex position from this.
1338 SkScalar dist = std::min(kOctagonOuter[i].dot(geoClipPlane) + offsetClipDist, 0.0f);
1339 SkVector offset = kOctagonOuter[i] - geoClipPlane * dist;
1340 vertices << (center + offset * halfWidth)
1341 << color
1342 << offset
1343 << radii;
1344 if (fClipPlane) {
1345 vertices << circle.fClipPlane;
1346 }
1347 if (fClipPlaneIsect) {
1348 vertices << circle.fIsectPlane;
1349 }
1350 if (fClipPlaneUnion) {
1351 vertices << circle.fUnionPlane;
1352 }
1353 if (fRoundCaps) {
1354 vertices << circle.fRoundCapCenters;
1355 }
1356 }
1357
1358 if (circle.fStroked) {
1359 // compute the inner ring
1360
1361 for (int i = 0; i < 8; ++i) {
1362 vertices << (center + kOctagonInner[i] * circle.fInnerRadius)
1363 << color
1364 << kOctagonInner[i] * innerRadius
1365 << radii;
1366 if (fClipPlane) {
1367 vertices << circle.fClipPlane;
1368 }
1369 if (fClipPlaneIsect) {
1370 vertices << circle.fIsectPlane;
1371 }
1372 if (fClipPlaneUnion) {
1373 vertices << circle.fUnionPlane;
1374 }
1375 if (fRoundCaps) {
1376 vertices << circle.fRoundCapCenters;
1377 }
1378 }
1379 } else {
1380 // filled
1381 vertices << center << color << SkPoint::Make(0, 0) << radii;
1382 if (fClipPlane) {
1383 vertices << circle.fClipPlane;
1384 }
1385 if (fClipPlaneIsect) {
1386 vertices << circle.fIsectPlane;
1387 }
1388 if (fClipPlaneUnion) {
1389 vertices << circle.fUnionPlane;
1390 }
1391 if (fRoundCaps) {
1392 vertices << circle.fRoundCapCenters;
1393 }
1394 }
1395
1396 const uint16_t* primIndices = circle_type_to_indices(circle.fStroked);
1397 const int primIndexCount = circle_type_to_index_count(circle.fStroked);
1398 for (int i = 0; i < primIndexCount; ++i) {
1399 *indices++ = primIndices[i] + currStartVertex;
1400 }
1401
1402 currStartVertex += circle_type_to_vert_count(circle.fStroked);
1403 }
1404
1405 fMesh = target->allocMesh();
1406 fMesh->setIndexed(std::move(indexBuffer), fIndexCount, firstIndex, 0, fVertCount - 1,
1407 GrPrimitiveRestart::kNo, std::move(vertexBuffer), firstVertex);
1408 }
static const uint16_t * circle_type_to_indices(bool stroked)
static constexpr SkPoint kOctagonOuter[]
static constexpr SkPoint kOctagonInner[]
#define SkAssertResult(cond)
Definition SkAssert.h:123
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define SK_Scalar1
Definition SkScalar.h:18
void createProgramInfo(const GrCaps *caps, SkArenaAlloc *arena, const GrSurfaceProxyView &writeView, bool usesMSAASurface, GrAppliedClip &&appliedClip, const GrDstProxyView &dstProxyView, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp)
uint32_t * target
SINT T dot(const Vec< N, T > &a, const Vec< N, T > &b)
Definition SkVx.h:964
Point offset
void setIndexed(sk_sp< const GrBuffer > indexBuffer, int indexCount, int baseIndex, uint16_t minIndexValue, uint16_t maxIndexValue, GrPrimitiveRestart, sk_sp< const GrBuffer > vertexBuffer, int baseVertex)
static constexpr SkPoint Make(float x, float y)
void set(float x, float y)
constexpr float centerX() const
Definition SkRect.h:776
constexpr float centerY() const
Definition SkRect.h:785
constexpr float width() const
Definition SkRect.h:762

◆ programInfo()

GrProgramInfo * CircleOp::programInfo ( )
inlineoverrideprivatevirtual

Implements GrMeshDrawOp.

Definition at line 1247 of file GrOvalOpFactory.cpp.

1247{ return fProgramInfo; }

◆ visitProxies()

void CircleOp::visitProxies ( const GrVisitProxyFunc func) const
inlineoverridevirtual

Reimplemented from GrOp.

Definition at line 1228 of file GrOvalOpFactory.cpp.

1228 {
1229 if (fProgramInfo) {
1230 fProgramInfo->visitFPProxies(func);
1231 } else {
1232 fHelper.visitProxies(func);
1233 }
1234 }
void visitFPProxies(const GrVisitProxyFunc &func) const
void visitProxies(const GrVisitProxyFunc &func) const

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