40#if defined(GR_TEST_UTILS)
51 if (pts[1] == pts[0]) {
65 *parallelScale = vecSrc.
length();
66 *perpScale = vecSrcPerp.
length();
73 if (pts[1] == pts[0]) {
84 ptsRot[1].fY = pts[0].fY;
90 SkASSERT(phase < intervals[0] + intervals[1]);
91 if (phase >= intervals[0] && phase != 0) {
92 SkScalar srcIntervalLen = intervals[0] + intervals[1];
93 return srcIntervalLen - phase;
100 if (pts[1].fX <= pts[0].fX) {
103 SkScalar srcIntervalLen = intervals[0] + intervals[1];
105 SkScalar temp = totalLen / srcIntervalLen;
107 *endingInt = totalLen - numFullIntervals * srcIntervalLen + phase;
108 temp = *endingInt / srcIntervalLen;
110 if (0 == *endingInt) {
111 *endingInt = srcIntervalLen;
113 if (*endingInt > intervals[0]) {
114 return *endingInt - intervals[0];
135 SkScalar intervalLength = startInterval + endInterval;
139 SkScalar halfDevRectHeight =
rect.height() * perpScale / 2.f;
140 SkRect dashRect = {
offset - bloatX, -halfDevRectHeight,
141 offset +
len + bloatX, halfDevRectHeight };
143 if (kRound_DashCap == cap) {
157 rectParam.
setLTRB(halfOffLen + 0.5f, -halfStroke + 0.5f,
158 halfOffLen + startInterval - 0.5f, halfStroke - 0.5f);
178 bool usesLocalCoords);
197 const LineData& geometry,
199 AAMode aaMode,
bool fullDash,
201 return GrOp::Make<DashOpImpl>(context, std::move(
paint), geometry, cap,
202 aaMode, fullDash, stencilSettings);
205 const char*
name()
const override {
return "DashOp"; }
215 FixedFunctionFlags fixedFunctionFlags()
const override {
218 flags |= FixedFunctionFlags::kUsesHWAA;
221 flags |= FixedFunctionFlags::kUsesStencil;
231 fUsesLocalCoords = analysis.usesLocalCoords();
241 , fColor(
paint.getColor4f())
242 , fFullDash(fullDash)
246 , fStencilSettings(stencilSettings) {
247 fLines.push_back(geometry);
250 SkScalar halfStrokeWidth = 0.5f * geometry.fSrcStrokeWidth;
253 bounds.set(geometry.fPtsRot[0], geometry.fPtsRot[1]);
254 bounds.outset(xBloat, halfStrokeWidth);
257 SkMatrix& combinedMatrix = fLines[0].fSrcRotInv;
258 combinedMatrix.
postConcat(geometry.fViewMatrix);
266 DashDraw(
const LineData& geo) {
267 memcpy(
fPtsRot, geo.fPtsRot,
sizeof(geo.fPtsRot));
268 memcpy(
fIntervals, geo.fIntervals,
sizeof(geo.fIntervals));
284 GrProgramInfo* programInfo()
override {
return fProgramInfo; }
286 void onCreateProgramInfo(
const GrCaps* caps,
289 bool usesMSAASurface,
295 DashCap capType = (this->cap() ==
SkPaint::kRound_Cap) ? kRound_DashCap : kNonRound_DashCap;
298 if (this->fullDash()) {
299 gp = make_dash_gp(arena, this->
color(), this->aaMode(), capType,
300 this->viewMatrix(), fUsesLocalCoords);
306 fUsesLocalCoords ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type;
309 Coverage::kSolid_Type,
315 SkDebugf(
"Could not create GrGeometryProcessor\n");
323 std::move(appliedClip),
326 std::move(fProcessorSet),
328 renderPassXferBarriers,
335 int instanceCount = fLines.size();
340 this->createProgramInfo(
target);
348 bool fullDash = this->fullDash();
353 static const int kNumStackDashes = 128;
357 int totalRectCount = 0;
360 for (
int i = 0;
i < instanceCount;
i++) {
361 const LineData&
args = fLines[
i];
372 halfSrcStroke =
std::max(halfSrcStroke, 0.5f /
args.fPerpendicularScale);
375 SkScalar strokeAdj = hasCap ? halfSrcStroke : 0.0f;
378 bool lineDone =
false;
383 SkRect& startRect = rects[rectOffset++];
384 SkRect& endRect = rects[rectOffset++];
386 bool hasStartRect =
false;
390 if (
draw.fPhase > 0 &&
draw.fPhase <
draw.fIntervals[0]) {
392 startPts[0] =
draw.fPtsRot[0];
393 startPts[1].
fY = startPts[0].
fY;
397 startRect.
outset(strokeAdj, halfSrcStroke);
400 startAdj =
draw.fIntervals[0] +
draw.fIntervals[1] -
draw.fPhase;
406 startAdj += calc_start_adjustment(
draw.fIntervals,
draw.fPhase);
408 draw.fPtsRot[0].fX += startAdj;
414 draw.fPtsRot[1].fX -= endAdj;
415 if (
draw.fPtsRot[0].fX >=
draw.fPtsRot[1].fX) {
419 bool hasEndRect =
false;
422 if (useAA && !lineDone) {
426 if (0 == endAdj && endingInterval !=
draw.fIntervals[0]) {
428 endPts[1] =
draw.fPtsRot[1];
429 endPts[0].
fY = endPts[1].
fY;
430 endPts[0].
fX = endPts[1].
fX - endingInterval;
433 endRect.
outset(strokeAdj, halfSrcStroke);
436 endAdj = endingInterval +
draw.fIntervals[1];
438 draw.fPtsRot[1].fX -= endAdj;
439 if (
draw.fPtsRot[0].fX >=
draw.fPtsRot[1].fX) {
445 if (
draw.fPtsRot[0].fX ==
draw.fPtsRot[1].fX &&
446 (0 != endAdj || 0 == startAdj) &&
464 devIntervals[0] =
draw.fIntervals[0] *
args.fParallelScale;
465 devIntervals[1] =
draw.fIntervals[1] *
args.fParallelScale;
480 SkScalar startOffset = devIntervals[1] * 0.5f + devPhase;
484 switch (this->aaMode()) {
501 if (devIntervals[1] <= 0.f && useAA) {
506 draw.fPtsRot[0].fX -= hasStartRect ? startAdj : 0;
507 draw.fPtsRot[1].fX += hasEndRect ? endAdj : 0;
509 startRect.
outset(strokeAdj, halfSrcStroke);
515 args.fSrcRotInv.mapPoints(devicePts,
draw.fPtsRot, 2);
518 lineLength += 2.f * halfDevStroke;
520 devIntervals[0] = lineLength;
523 totalRectCount += !lineDone ? 1 : 0;
524 totalRectCount += hasStartRect ? 1 : 0;
525 totalRectCount += hasEndRect ? 1 : 0;
530 startOffset -= halfDevStroke;
535 args.fSrcRotInv.mapPoints(devicePts,
draw.fPtsRot, 2);
538 draw.fLineLength += 2.f * halfDevStroke;
542 draw.fPtsRot[1].fX,
draw.fPtsRot[1].fY);
543 bounds.outset(bloatX + strokeAdj, bloatY + halfSrcStroke);
548 startRect.
outset(bloatX, bloatY);
553 endRect.
outset(bloatX, bloatY);
556 draw.fStartOffset = startOffset;
557 draw.fDevBloatX = devBloatX;
558 draw.fPerpendicularScale =
args.fPerpendicularScale;
560 draw.fHasStartRect = hasStartRect;
561 draw.fLineDone = lineDone;
562 draw.fHasEndRect = hasEndRect;
565 if (!totalRectCount) {
570 VertexWriter vertices{ helper.vertices() };
576 for (
int i = 0;
i < instanceCount;
i++) {
577 const LineData& geom = fLines[
i];
581 setup_dashed_rect(rects[rectIndex], vertices, geom.fSrcRotInv,
582 draws[
i].fStartOffset, draws[
i].fDevBloatX,
583 draws[
i].fLineLength, draws[
i].fIntervals[0],
584 draws[
i].fIntervals[1], draws[
i].fStrokeWidth,
585 draws[
i].fPerpendicularScale,
595 setup_dashed_rect(rects[rectIndex], vertices, geom.fSrcRotInv,
596 draws[
i].fStartOffset, draws[
i].fDevBloatX,
597 draws[
i].fIntervals[0], draws[
i].fIntervals[0],
598 draws[
i].fIntervals[1], draws[
i].fStrokeWidth,
599 draws[
i].fPerpendicularScale, capType);
608 setup_dashed_rect(rects[rectIndex], vertices, geom.fSrcRotInv,
609 draws[
i].fStartOffset, draws[
i].fDevBloatX,
610 draws[
i].fIntervals[0], draws[
i].fIntervals[0],
611 draws[
i].fIntervals[1], draws[
i].fStrokeWidth,
612 draws[
i].fPerpendicularScale, capType);
620 fMesh = helper.mesh();
624 if (!fProgramInfo || !fMesh) {
634 auto that = t->
cast<DashOpImpl>();
635 if (fProcessorSet != that->fProcessorSet) {
636 return CombineResult::kCannotCombine;
639 if (this->aaMode() != that->aaMode()) {
640 return CombineResult::kCannotCombine;
643 if (this->fullDash() != that->fullDash()) {
644 return CombineResult::kCannotCombine;
647 if (this->cap() != that->cap()) {
648 return CombineResult::kCannotCombine;
652 if (this->
color() != that->color()) {
653 return CombineResult::kCannotCombine;
657 return CombineResult::kCannotCombine;
660 fLines.push_back_n(that->fLines.size(), that->fLines.begin());
661 return CombineResult::kMerged;
664#if defined(GR_TEST_UTILS)
665 SkString onDumpInfo()
const override {
667 for (
const auto& geo : fLines) {
668 string.
appendf(
"Pt0: [%.2f, %.2f], Pt1: [%.2f, %.2f], Width: %.2f, Ival0: %.2f, "
669 "Ival1 : %.2f, Phase: %.2f\n",
670 geo.fPtsRot[0].fX, geo.fPtsRot[0].fY,
671 geo.fPtsRot[1].fX, geo.fPtsRot[1].fY,
677 string += fProcessorSet.dumpProcessors();
683 const SkMatrix& viewMatrix()
const {
return fLines[0].fViewMatrix; }
684 AAMode aaMode()
const {
return fAAMode; }
685 bool fullDash()
const {
return fFullDash; }
690 bool fUsesLocalCoords : 1;
721 bool usesLocalCoords);
723 const char*
name()
const override {
return "DashingCircleEffect"; }
725 void addToKey(
const GrShaderCaps&, KeyBuilder*)
const override;
727 std::unique_ptr<ProgramImpl> makeProgramImpl(
const GrShaderCaps&)
const override;
733 bool usesLocalCoords);
737 bool fUsesLocalCoords;
751class DashingCircleEffect::Impl :
public ProgramImpl {
758 void onEmitCode(EmitArgs&, GrGPArgs*)
override;
763 UniformHandle fParamUniform;
764 UniformHandle fColorUniform;
765 UniformHandle fLocalMatrixUniform;
768void DashingCircleEffect::Impl::onEmitCode(EmitArgs&
args, GrGPArgs* gpArgs) {
769 const DashingCircleEffect& dce =
args.fGeomProc.cast<DashingCircleEffect>();
779 varyingHandler->
addVarying(
"DashParam", &dashParams);
780 vertBuilder->codeAppendf(
"%s = %s;", dashParams.vsOut(), dce.fInDashParams.name());
784 varyingHandler->
addVarying(
"CircleParams", &circleParams);
785 vertBuilder->codeAppendf(
"%s = %s;", circleParams.vsOut(), dce.fInCircleParams.name());
790 this->setupUniformColor(fragBuilder, uniformHandler,
args.fOutputColor, &fColorUniform);
793 WriteOutputPosition(vertBuilder, gpArgs, dce.fInPosition.name());
794 if (dce.fUsesLocalCoords) {
795 WriteLocalCoord(vertBuilder,
799 dce.fInPosition.asShaderVar(),
801 &fLocalMatrixUniform);
805 fragBuilder->
codeAppendf(
"half xShifted = half(%s.x - floor(%s.x / %s.z) * %s.z);",
806 dashParams.fsIn(), dashParams.fsIn(), dashParams.fsIn(),
808 fragBuilder->
codeAppendf(
"half2 fragPosShifted = half2(xShifted, half(%s.y));",
810 fragBuilder->
codeAppendf(
"half2 center = half2(%s.y, 0.0);", circleParams.fsIn());
811 fragBuilder->
codeAppend(
"half dist = length(center - fragPosShifted);");
813 fragBuilder->
codeAppendf(
"half diff = dist - %s.x;", circleParams.fsIn());
814 fragBuilder->
codeAppend(
"diff = 1.0 - diff;");
815 fragBuilder->
codeAppend(
"half alpha = saturate(diff);");
818 fragBuilder->
codeAppendf(
"alpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;", circleParams.fsIn());
820 fragBuilder->
codeAppendf(
"half4 %s = half4(alpha);",
args.fOutputCoverage);
826 const DashingCircleEffect& dce = geomProc.
cast<DashingCircleEffect>();
827 if (dce.fColor != fColor) {
828 pdman.
set4fv(fColorUniform, 1, dce.fColor.vec());
831 SetTransform(pdman, shaderCaps, fLocalMatrixUniform, dce.fLocalMatrix, &fLocalMatrix);
840 bool usesLocalCoords) {
841 return arena->
make([&](
void* ptr) {
842 return new (ptr) DashingCircleEffect(
color, aaMode, localMatrix, usesLocalCoords);
846void DashingCircleEffect::addToKey(
const GrShaderCaps& caps, KeyBuilder*
b)
const {
848 key |= fUsesLocalCoords ? 0x1 : 0x0;
849 key |=
static_cast<uint32_t
>(fAAMode) << 1;
850 key |= ProgramImpl::ComputeMatrixKey(caps, fLocalMatrix) << 3;
854std::unique_ptr<GrGeometryProcessor::ProgramImpl> DashingCircleEffect::makeProgramImpl(
856 return std::make_unique<Impl>();
862 bool usesLocalCoords)
863 :
INHERITED(kDashingCircleEffect_ClassID)
865 , fLocalMatrix(localMatrix)
866 , fUsesLocalCoords(usesLocalCoords)
871 this->setVertexAttributesWithImplicitOffsets(&fInPosition, 3);
876#if defined(GR_TEST_UTILS)
878 AAMode aaMode =
static_cast<AAMode>(
d->fRandom->nextULessThan(kAAModeCnt));
885 d->fRandom->nextBool());
908 bool usesLocalCoords);
910 const char*
name()
const override {
return "DashingEffect"; }
912 bool usesLocalCoords()
const {
return fUsesLocalCoords; }
922 bool usesLocalCoords);
926 bool fUsesLocalCoords;
940class DashingLineEffect::Impl :
public ProgramImpl {
947 void onEmitCode(EmitArgs&, GrGPArgs*)
override;
952 UniformHandle fLocalMatrixUniform;
953 UniformHandle fColorUniform;
956void DashingLineEffect::Impl::onEmitCode(EmitArgs&
args, GrGPArgs* gpArgs) {
957 const DashingLineEffect&
de =
args.fGeomProc.cast<DashingLineEffect>();
968 varyingHandler->
addVarying(
"DashParams", &inDashParams);
969 vertBuilder->codeAppendf(
"%s = %s;", inDashParams.vsOut(),
de.fInDashParams.name());
974 varyingHandler->
addVarying(
"RectParams", &inRectParams);
975 vertBuilder->codeAppendf(
"%s = %s;", inRectParams.vsOut(),
de.fInRect.name());
980 this->setupUniformColor(fragBuilder, uniformHandler,
args.fOutputColor, &fColorUniform);
983 WriteOutputPosition(vertBuilder, gpArgs,
de.fInPosition.name());
984 if (
de.usesLocalCoords()) {
985 WriteLocalCoord(vertBuilder,
989 de.fInPosition.asShaderVar(),
991 &fLocalMatrixUniform);
995 fragBuilder->
codeAppendf(
"half xShifted = half(%s.x - floor(%s.x / %s.z) * %s.z);",
996 inDashParams.fsIn(), inDashParams.fsIn(), inDashParams.fsIn(),
997 inDashParams.fsIn());
998 fragBuilder->
codeAppendf(
"half2 fragPosShifted = half2(xShifted, half(%s.y));",
999 inDashParams.fsIn());
1004 fragBuilder->
codeAppendf(
"xSub = half(min(fragPosShifted.x - %s.x, 0.0));",
1005 inRectParams.fsIn());
1006 fragBuilder->
codeAppendf(
"xSub += half(min(%s.z - fragPosShifted.x, 0.0));",
1007 inRectParams.fsIn());
1008 fragBuilder->
codeAppendf(
"ySub = half(min(fragPosShifted.y - %s.y, 0.0));",
1009 inRectParams.fsIn());
1010 fragBuilder->
codeAppendf(
"ySub += half(min(%s.w - fragPosShifted.y, 0.0));",
1011 inRectParams.fsIn());
1015 "half alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));");
1016 }
else if (
de.fAAMode == AAMode::kCoverageWithMSAA) {
1020 fragBuilder->
codeAppendf(
"xSub = half(min(fragPosShifted.x - %s.x, 0.0));",
1021 inRectParams.fsIn());
1022 fragBuilder->
codeAppendf(
"xSub += half(min(%s.z - fragPosShifted.x, 0.0));",
1023 inRectParams.fsIn());
1025 fragBuilder->
codeAppendf(
"half alpha = (1.0 + max(xSub, -1.0));");
1029 fragBuilder->
codeAppendf(
"alpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;",
1030 inRectParams.fsIn());
1031 fragBuilder->
codeAppendf(
"alpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;",
1032 inRectParams.fsIn());
1034 fragBuilder->
codeAppendf(
"half4 %s = half4(alpha);",
args.fOutputCoverage);
1040 const DashingLineEffect&
de = geomProc.
cast<DashingLineEffect>();
1041 if (
de.fColor != fColor) {
1042 pdman.
set4fv(fColorUniform, 1,
de.fColor.vec());
1045 SetTransform(pdman, shaderCaps, fLocalMatrixUniform,
de.fLocalMatrix, &fLocalMatrix);
1054 bool usesLocalCoords) {
1055 return arena->
make([&](
void* ptr) {
1056 return new (ptr) DashingLineEffect(
color, aaMode, localMatrix, usesLocalCoords);
1060void DashingLineEffect::addToKey(
const GrShaderCaps& caps, KeyBuilder*
b)
const {
1062 key |= fUsesLocalCoords ? 0x1 : 0x0;
1063 key |=
static_cast<int>(fAAMode) << 1;
1064 key |= ProgramImpl::ComputeMatrixKey(caps, fLocalMatrix) << 3;
1068std::unique_ptr<GrGeometryProcessor::ProgramImpl> DashingLineEffect::makeProgramImpl(
1070 return std::make_unique<Impl>();
1076 bool usesLocalCoords)
1079 , fLocalMatrix(localMatrix)
1080 , fUsesLocalCoords(usesLocalCoords)
1085 this->setVertexAttributesWithImplicitOffsets(&fInPosition, 3);
1090#if defined(GR_TEST_UTILS)
1092 AAMode aaMode =
static_cast<AAMode>(
d->fRandom->nextULessThan(kAAModeCnt));
1099 d->fRandom->nextBool());
1110 bool usesLocalCoords) {
1118 case kRound_DashCap:
1120 case kNonRound_DashCap:
1143 DashOpImpl::LineData lineData;
1147 SkASSERT(phase >= 0 && phase < intervals[0] + intervals[1]);
1150 if (pts[0].fY != pts[1].fY || pts[0].fX > pts[1].fX) {
1152 align_to_x_axis(pts, &rotMatrix, lineData.fPtsRot);
1153 if (!rotMatrix.
invert(&lineData.fSrcRotInv)) {
1154 SkDebugf(
"Failed to create invertible rotation matrix!\n");
1158 lineData.fSrcRotInv.reset();
1159 memcpy(lineData.fPtsRot, pts, 2 *
sizeof(
SkPoint));
1163 calc_dash_scaling(&lineData.fParallelScale, &lineData.fPerpendicularScale, viewMatrix, pts);
1169 SkScalar offInterval = intervals[1] * lineData.fParallelScale;
1178 bool fullDash = offInterval > 0.f || aaMode !=
AAMode::kNone;
1180 lineData.fViewMatrix = viewMatrix;
1181 lineData.fPhase = phase;
1182 lineData.fIntervals[0] = intervals[0];
1183 lineData.fIntervals[1] = intervals[1];
1192 if (pts[0].fX != pts[1].fX && pts[0].fY != pts[1].fY) {
1207 if (0 == intervals[0] && 0 == intervals[1]) {
1214 if (intervals[0] != 0.f) {
1229#if defined(GR_TEST_UTILS)
1233GR_DRAW_OP_TEST_DEFINE(DashOpImpl) {
1234 SkMatrix viewMatrix = GrTest::TestMatrixPreservesRightAngles(random);
1237 aaMode =
static_cast<AAMode>(random->nextULessThan(kAAModeCnt));
1238 }
while (AAMode::kCoverageWithMSAA == aaMode && numSamples <= 1);
1242 if (random->nextBool()) {
1245 pts[0].
fY = random->nextF() * 10.f;
1247 pts[1].
fY = random->nextF() * 10.f;
1250 pts[0].
fX = random->nextF() * 10.f;
1252 pts[1].
fX = random->nextF() * 10.f;
1263 kOpenOpen_Intervals ,
1264 kOpenClose_Intervals,
1265 kCloseOpen_Intervals,
1269 kOpenClose_Intervals :
1270 Intervals(random->nextULessThan(kCloseOpen_Intervals + 1));
1271 static const SkScalar kIntervalMin = 0.1f;
1272 static const SkScalar kIntervalMinCircles = 1.f;
1273 static const SkScalar kIntervalMax = 10.f;
1274 switch (intervalType) {
1275 case kOpenOpen_Intervals:
1276 intervals[0] = random->nextRangeScalar(kIntervalMin, kIntervalMax);
1277 intervals[1] = random->nextRangeScalar(kIntervalMin, kIntervalMax);
1279 case kOpenClose_Intervals: {
1282 intervals[1] = random->nextRangeScalar(
min, kIntervalMax);
1285 case kCloseOpen_Intervals:
1286 intervals[0] = random->nextRangeScalar(kIntervalMin, kIntervalMax);
1293 SkScalar phase = random->nextRangeScalar(0, intervals[0] + intervals[1]);
1298 p.setStrokeCap(cap);
1304 style, GrGetRandomStencil(random, context));
static SkM44 inv(const SkM44 &m)
static const int strokeWidth
SkScalar fPerpendicularScale
#define DEFINE_OP_CLASS_ID
GrProcessorAnalysisCoverage
#define GR_DECLARE_GEOMETRY_PROCESSOR_TEST
#define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(...)
std::function< void(GrSurfaceProxy *, skgpu::Mipmapped)> GrVisitProxyFunc
@ kFloat2_GrVertexAttribType
@ kFloat3_GrVertexAttribType
@ kFloat4_GrVertexAttribType
constexpr SkPMColor4f SK_PMColor4fILLEGAL
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
#define INHERITED(method,...)
#define SkScalarInvert(x)
#define SkScalarFloorToScalar(x)
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
void setData(const GrGLSLProgramDataManager &pdman, const GrFragmentProcessor &processor)
virtual void set4fv(UniformHandle, int arrayCount, const float v[]) const =0
void codeAppend(const char *str)
void codeAppendf(const char format[],...) SK_PRINTF_LIKE(2
void emitAttributes(const GrGeometryProcessor &)
void addVarying(const char *name, GrGLSLVarying *varying, Interpolation=Interpolation::kInterpolated)
GrGeometryProcessor(ClassID)
virtual std::unique_ptr< ProgramImpl > makeProgramImpl(const GrShaderCaps &) const =0
size_t vertexStride() const
virtual void addToKey(const GrShaderCaps &, skgpu::KeyBuilder *) const =0
void drawMesh(const GrSimpleMesh &mesh)
void bindPipelineAndScissorClip(const GrProgramInfo &programInfo, const SkRect &drawBounds)
void bindTextures(const GrGeometryProcessor &geomProc, const GrSurfaceProxy &singleGeomProcTexture, const GrPipeline &pipeline)
std::unique_ptr< GrOp > Owner
void setTransformedBounds(const SkRect &srcBounds, const SkMatrix &m, HasAABloat aabloat, IsHairline zeroArea)
void visitProxies(const GrVisitProxyFunc &) const
Analysis finalize(const GrProcessorAnalysisColor &, const GrProcessorAnalysisCoverage, const GrAppliedClip *, const GrUserStencilSettings *, const GrCaps &, GrClampType, SkPMColor4f *inputColorOverride)
virtual const char * name() const =0
const GrPipeline & pipeline() const
const GrGeometryProcessor & geomProc() const
void visitFPProxies(const GrVisitProxyFunc &func) const
static GrQuad MakeFromRect(const SkRect &, const SkMatrix &)
static GrProgramInfo * CreateProgramInfo(const GrCaps *, SkArenaAlloc *, const GrPipeline *, const GrSurfaceProxyView &writeView, bool usesMSAASurface, GrGeometryProcessor *, GrPrimitiveType, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp, const GrUserStencilSettings *=&GrUserStencilSettings::kUnused)
const SkScalar * dashIntervals() const
int dashIntervalCnt() const
SkScalar dashPhase() const
const SkStrokeRec & strokeRec() const
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
static bool CheapEqual(const SkMatrix &a, const SkMatrix &b)
SkMatrix & postConcat(const SkMatrix &other)
void mapVectors(SkVector dst[], const SkVector src[], int count) const
bool preservesRightAngles(SkScalar tol=SK_ScalarNearlyZero) const
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
SkMatrix & setSinCos(SkScalar sinValue, SkScalar cosValue, SkScalar px, SkScalar py)
bool invert(SkMatrix *inverse) const
static const SkMatrix & InvalidMatrix()
@ kButt_Cap
no stroke extension
static constexpr int kCapCount
@ kStroke_Style
set to stroke geometry
static void RotateCW(const SkPoint &src, SkPoint *dst)
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
SkScalar getWidth() const
SkPaint::Cap getCap() const
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static float max(float r, float g, float b)
static float min(float r, float g, float b)
GrGeometryProcessor * MakeForDeviceSpace(SkArenaAlloc *, const Color &, const Coverage &, const LocalCoords &, const SkMatrix &viewMatrix)
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
unsigned useCenter Optional< SkMatrix > matrix
Optional< SkRect > bounds
sk_sp< SkBlender > blender SkRect rect
const CatchEntryMove de[]
DEF_SWITCHES_START aot vmservice shared library name
GrOp::Owner MakeDashLineOp(GrRecordingContext *context, GrPaint &&paint, const SkMatrix &viewMatrix, const SkPoint pts[2], AAMode aaMode, const GrStyle &style, const GrUserStencilSettings *stencilSettings)
bool CanDrawDashLine(const SkPoint pts[2], const GrStyle &style, const SkMatrix &viewMatrix)
static const GrUserStencilSettings & kUnused
void set(float x, float y)
static float Distance(const SkPoint &a, const SkPoint &b)
void scale(float scale, SkPoint *dst) const
static SkRGBA4f FromBytes_RGBA(uint32_t color)
void outset(float dx, float dy)
void setLTRB(float left, float top, float right, float bottom)
void setBounds(const SkPoint pts[], int count)
void writeQuad(const Args &... remainder)
static TriStrip< float > TriStripFromRect(const SkRect &r)