37bool skews_are_relevant(
const SkMatrix&
m) {
51 float norm =
std::max(absScaleX + absSkewY, absSkewX + absScaleY);
53 return absSkewX > kTol * norm || absSkewY > kTol * norm;
64 enum class Type :
bool { kRect, kMatrix };
65 LocalCoords(
const SkRect& localRect)
68 LocalCoords(
const SkMatrix& localMatrix)
69 :
fType(Type::kMatrix)
86 const char*
name()
const override {
return "FillRRectOp"; }
88 FixedFunctionFlags fixedFunctionFlags()
const override {
return fHelper.
fixedFunctionFlags(); }
99#if defined(GR_TEST_UTILS)
100 SkString onDumpInfo()
const override;
116 friend class ::GrSimpleMeshDrawOpHelper;
119 enum class ProcessorFlags {
121 kUseHWDerivatives = 1 << 0,
122 kHasLocalCoords = 1 << 1,
124 kMSAAEnabled = 1 << 3,
127 constexpr static int kNumProcessorFlags = 5;
141 GrProgramInfo* programInfo()
override {
return fProgramInfo; }
144 void onCreateProgramInfo(
const GrCaps*,
147 bool usesMSAASurface,
154 ProcessorFlags fProcessorFlags;
157 Instance(
const SkMatrix& viewMatrix,
159 const LocalCoords& localCoords,
170 Instance* fHeadInstance;
171 Instance** fTailInstance;
172 int fInstanceCount = 1;
177 int fBaseInstance = 0;
188bool can_use_hw_derivatives_with_coverage(
const GrShaderCaps&,
197 const LocalCoords& localCoords,
218 if (can_use_hw_derivatives_with_coverage(*caps->
shaderCaps(), viewMatrix,
rrect)) {
221 flags |= ProcessorFlags::kUseHWDerivatives;
224 flags |= ProcessorFlags::kFakeNonAA;
227 return Helper::FactoryHelper<FillRRectOpImpl>(ctx, std::move(
paint), arena, viewMatrix,
rrect,
236 const LocalCoords& localCoords,
237 ProcessorFlags processorFlags)
239 , fHelper(processorSet,
240 (processorFlags & ProcessorFlags::kFakeNonAA)
243 , fProcessorFlags(processorFlags & ~(ProcessorFlags::kHasLocalCoords |
244 ProcessorFlags::kWideColor |
245 ProcessorFlags::kMSAAEnabled))
246 , fHeadInstance(arena->
make<Instance>(viewMatrix,
rrect, localCoords, paintColor))
247 , fTailInstance(&fHeadInstance->
fNext) {
261 SkASSERT(fHeadInstance->fNext ==
nullptr);
265 (aa ==
GrAA::kNo) == (fProcessorFlags & ProcessorFlags::kFakeNonAA)) {
268 if (clipMatrix == fHeadInstance->fViewMatrix) {
276 SkASSERT(!fHeadInstance->fViewMatrix.hasPerspective());
281 if (!fHeadInstance->fViewMatrix.invert(&clipToView)) {
282 return ClipResult::kClippedOut;
287 if (skews_are_relevant(clipToView)) {
308 if (fHeadInstance->fRRect.isRect() &&
clipRRect.isRect()) {
311 return ClipResult::kClippedOut;
325 SkRect devISectBounds = fHeadInstance->fViewMatrix.mapRect(isectRRect.
rect());
326 if (devISectBounds.
width() < 1.f || devISectBounds.
height() < 1.f) {
332 auto rect = sk_bit_cast<skvx::float4>(fHeadInstance->fRRect.rect());
333 auto local = sk_bit_cast<skvx::float4>(fHeadInstance->fLocalCoords.fRect);
334 auto isect = sk_bit_cast<skvx::float4>(isectRRect.
rect());
335 auto rectToLocalSize = (
local - skvx::shuffle<2,3,0,1>(
local)) /
336 (
rect - skvx::shuffle<2,3,0,1>(
rect));
337 auto localCoordsRect = (isect -
rect) * rectToLocalSize +
local;
338 fHeadInstance->fLocalCoords.fRect.setLTRB(localCoordsRect.x(),
341 localCoordsRect.w());
345 fHeadInstance->fRRect = isectRRect;
346 return ClipResult::kClippedGeometrically;
355 SkASSERT(fHeadInstance->fNext ==
nullptr);
358 auto analysis = fHelper.finalizeProcessors(caps,
clip, clampType,
360 &fHeadInstance->fColor, &isWideColor);
362 fProcessorFlags |= ProcessorFlags::kWideColor;
364 if (analysis.usesLocalCoords()) {
365 fProcessorFlags |= ProcessorFlags::kHasLocalCoords;
373 auto that = op->
cast<FillRRectOpImpl>();
374 if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds()) ||
375 fProcessorFlags != that->fProcessorFlags) {
376 return CombineResult::kCannotCombine;
379 *fTailInstance = that->fHeadInstance;
380 fTailInstance = that->fTailInstance;
381 fInstanceCount += that->fInstanceCount;
382 return CombineResult::kMerged;
385#if defined(GR_TEST_UTILS)
386SkString FillRRectOpImpl::onDumpInfo()
const {
388 str += fHelper.dumpInfo();
390 for (Instance* tmp = fHeadInstance; tmp; tmp = tmp->fNext, ++
i) {
391 str.
appendf(
"%d: Color: [%.2f, %.2f, %.2f, %.2f] ",
392 i, tmp->fColor.fR, tmp->fColor.fG, tmp->fColor.fB, tmp->fColor.fA);
394 str.
appendf(
"ViewMatrix: [%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f] ",
395 m[0],
m[1],
m[2],
m[3],
m[4],
m[5],
m[6],
m[7],
m[8]);
396 SkRect r = tmp->fRRect.rect();
406 return arena->
make([&](
void* ptr) {
407 return new (ptr) Processor(aaType,
flags);
411 const char*
name()
const override {
return "FillRRectOp::Processor"; }
414 b->addBits(kNumProcessorFlags, (uint32_t)
fFlags,
"flags");
430 if (
fFlags & ProcessorFlags::kHasLocalCoords) {
431 fInstanceAttribs.emplace_back(
"translate_and_localrotate",
434 fInstanceAttribs.emplace_back(
437 fInstanceAttribs.emplace_back(
"translate_and_localrotate",
441 fColorAttrib = &fInstanceAttribs.push_back(
443 SkASSERT(fInstanceAttribs.size() <= kMaxInstanceAttribs);
445 fInstanceAttribs.size());
448 inline static constexpr Attribute kVertexAttribs[] = {
454 const ProcessorFlags
fFlags;
456 constexpr static int kMaxInstanceAttribs = 6;
465struct CoverageVertex {
479static constexpr CoverageVertex kVertexData[] = {
481 {{{0,0,0,1}}, {{-1,+1}}, {{0,-1}}, {{+1,0}}, 1, 1},
482 {{{1,0,0,0}}, {{-1,-1}}, {{0,+1}}, {{+1,0}}, 1, 1},
485 {{{1,0,0,0}}, {{-1,-1}}, {{+1,0}}, {{0,+1}}, 1, 1},
486 {{{0,1,0,0}}, {{+1,-1}}, {{-1,0}}, {{0,+1}}, 1, 1},
489 {{{0,1,0,0}}, {{+1,-1}}, {{0,+1}}, {{-1,0}}, 1, 1},
490 {{{0,0,1,0}}, {{+1,+1}}, {{0,-1}}, {{-1,0}}, 1, 1},
493 {{{0,0,1,0}}, {{+1,+1}}, {{-1,0}}, {{0,-1}}, 1, 1},
494 {{{0,0,0,1}}, {{-1,+1}}, {{+1,0}}, {{0,-1}}, 1, 1},
498 {{{0,0,0,1}}, {{-1,+1}}, {{0,-1}}, {{-1,0}}, 0, 1},
499 {{{1,0,0,0}}, {{-1,-1}}, {{0,+1}}, {{-1,0}}, 0, 1},
502 {{{1,0,0,0}}, {{-1,-1}}, {{+1,0}}, {{0,-1}}, 0, 1},
503 {{{0,1,0,0}}, {{+1,-1}}, {{-1,0}}, {{0,-1}}, 0, 1},
506 {{{0,1,0,0}}, {{+1,-1}}, {{0,+1}}, {{+1,0}}, 0, 1},
507 {{{0,0,1,0}}, {{+1,+1}}, {{0,-1}}, {{+1,0}}, 0, 1},
510 {{{0,0,1,0}}, {{+1,+1}}, {{-1,0}}, {{0,+1}}, 0, 1},
511 {{{0,0,0,1}}, {{-1,+1}}, {{+1,0}}, {{0,+1}}, 0, 1},
515 {{{1,0,0,0}}, {{-1,-1}}, {{ 0,+1}}, {{-1, 0}}, 0, 0},
516 {{{1,0,0,0}}, {{-1,-1}}, {{ 0,+1}}, {{+1, 0}}, 1, 0},
517 {{{1,0,0,0}}, {{-1,-1}}, {{+1, 0}}, {{ 0,+1}}, 1, 0},
518 {{{1,0,0,0}}, {{-1,-1}}, {{+1, 0}}, {{ 0,-1}}, 0, 0},
519 {{{1,0,0,0}}, {{-1,-1}}, {{+kOctoOffset,0}}, {{-1,-1}}, 0, 0},
520 {{{1,0,0,0}}, {{-1,-1}}, {{0,+kOctoOffset}}, {{-1,-1}}, 0, 0},
523 {{{0,1,0,0}}, {{+1,-1}}, {{-1, 0}}, {{ 0,-1}}, 0, 0},
524 {{{0,1,0,0}}, {{+1,-1}}, {{-1, 0}}, {{ 0,+1}}, 1, 0},
525 {{{0,1,0,0}}, {{+1,-1}}, {{ 0,+1}}, {{-1, 0}}, 1, 0},
526 {{{0,1,0,0}}, {{+1,-1}}, {{ 0,+1}}, {{+1, 0}}, 0, 0},
527 {{{0,1,0,0}}, {{+1,-1}}, {{0,+kOctoOffset}}, {{+1,-1}}, 0, 0},
528 {{{0,1,0,0}}, {{+1,-1}}, {{-kOctoOffset,0}}, {{+1,-1}}, 0, 0},
531 {{{0,0,1,0}}, {{+1,+1}}, {{ 0,-1}}, {{+1, 0}}, 0, 0},
532 {{{0,0,1,0}}, {{+1,+1}}, {{ 0,-1}}, {{-1, 0}}, 1, 0},
533 {{{0,0,1,0}}, {{+1,+1}}, {{-1, 0}}, {{ 0,-1}}, 1, 0},
534 {{{0,0,1,0}}, {{+1,+1}}, {{-1, 0}}, {{ 0,+1}}, 0, 0},
535 {{{0,0,1,0}}, {{+1,+1}}, {{-kOctoOffset,0}}, {{+1,+1}}, 0, 0},
536 {{{0,0,1,0}}, {{+1,+1}}, {{0,-kOctoOffset}}, {{+1,+1}}, 0, 0},
539 {{{0,0,0,1}}, {{-1,+1}}, {{+1, 0}}, {{ 0,+1}}, 0, 0},
540 {{{0,0,0,1}}, {{-1,+1}}, {{+1, 0}}, {{ 0,-1}}, 1, 0},
541 {{{0,0,0,1}}, {{-1,+1}}, {{ 0,-1}}, {{+1, 0}}, 1, 0},
542 {{{0,0,0,1}}, {{-1,+1}}, {{ 0,-1}}, {{-1, 0}}, 0, 0},
543 {{{0,0,0,1}}, {{-1,+1}}, {{0,-kOctoOffset}}, {{-1,+1}}, 0, 0},
544 {{{0,0,0,1}}, {{-1,+1}}, {{+kOctoOffset,0}}, {{-1,+1}}, 0, 0}};
548static constexpr uint16_t kIndexData[] = {
591 this->createProgramInfo(
target);
596 if (VertexWriter instanceWriter =
target->makeVertexWriter(instanceStride, fInstanceCount,
597 &fInstanceBuffer, &fBaseInstance)) {
598 SkDEBUGCODE(
auto end = instanceWriter.mark(instanceStride * fInstanceCount));
599 for (Instance*
i = fHeadInstance;
i;
i =
i->fNext) {
600 auto [l, t, r,
b] =
i->fRRect.rect();
605 m.setScaleTranslate((r - l)/2, (
b - t)/2, (l + r)/2, (t +
b)/2);
607 m.postConcat(
i->fViewMatrix);
612 radiiX *= 2 / (r - l);
613 radiiY *= 2 / (
b - t);
615 instanceWriter << radiiX << radiiY
616 <<
m.getScaleX() <<
m.getSkewX() <<
m.getSkewY() <<
m.getScaleY()
617 <<
m.getTranslateX() <<
m.getTranslateY();
619 if (fProcessorFlags & ProcessorFlags::kHasLocalCoords) {
621 instanceWriter << 0.f << 0.f
622 <<
i->fLocalCoords.fRect;
624 SkASSERT(
i->fLocalCoords.fType == LocalCoords::Type::kMatrix);
626 const SkMatrix& localMatrix =
i->fLocalCoords.fMatrix;
630 instanceWriter << v.
x() << u.
y()
631 << l0 << (l0.
x() + u.
x()) << (l0.
y() + v.
y());
635 instanceWriter << VertexColor(
i->fColor, fProcessorFlags & ProcessorFlags::kWideColor);
644 kIndexData, gIndexBufferKey);
654class FillRRectOpImpl::Processor::Impl :
public ProgramImpl {
661 void onEmitCode(EmitArgs&
args, GrGPArgs* gpArgs)
override {
665 const auto& proc =
args.fGeomProc.cast<Processor>();
666 bool useHWDerivatives = (proc.fFlags & ProcessorFlags::kUseHWDerivatives);
668 SkASSERT(proc.vertexStride() ==
sizeof(CoverageVertex));
672 f->codeAppendf(
"half4 %s;",
args.fOutputColor);
681 (proc.fFlags & ProcessorFlags::kMSAAEnabled)
683 : (!(proc.fFlags & ProcessorFlags::kFakeNonAA))
688 v->
codeAppend(
"float2 corner = corner_and_radius_outsets.xy;");
689 v->
codeAppend(
"float2 radius_outset = corner_and_radius_outsets.zw;");
690 v->
codeAppend(
"float2 aa_bloat_direction = aa_bloat_and_coverage.xy;");
691 v->
codeAppend(
"float is_linear_coverage = aa_bloat_and_coverage.w;");
694 v->
codeAppend(
"float2 pixellength = inversesqrt("
695 "float2(dot(skew.xz, skew.xz), dot(skew.yw, skew.yw)));");
696 v->
codeAppend(
"float4 normalized_axis_dirs = skew * pixellength.xyxy;");
697 v->
codeAppend(
"float2 axiswidths = (abs(normalized_axis_dirs.xy) + "
698 "abs(normalized_axis_dirs.zw));");
699 v->
codeAppend(
"float2 aa_bloatradius = axiswidths * pixellength * .5;");
702 v->
codeAppend(
"float4 radii_and_neighbors = radii_selector"
703 "* float4x4(radii_x, radii_y, radii_x.yxwz, radii_y.wzyx);");
704 v->
codeAppend(
"float2 radii = radii_and_neighbors.xy;");
705 v->
codeAppend(
"float2 neighbor_radii = radii_and_neighbors.zw;");
707 v->
codeAppend(
"float coverage_multiplier = 1;");
708 v->
codeAppend(
"if (any(greaterThan(aa_bloatradius, float2(1)))) {");
713 v->
codeAppend(
"corner = max(abs(corner), aa_bloatradius) * sign(corner);");
714 v->
codeAppend(
"coverage_multiplier = 1 / (max(aa_bloatradius.x, 1) * "
715 "max(aa_bloatradius.y, 1));");
722 v->
codeAppend(
"float coverage = aa_bloat_and_coverage.z;");
723 if (proc.fFlags & ProcessorFlags::kMSAAEnabled) {
725 v->
codeAppendf(
"coverage = (coverage - .5) * aa_bloat_multiplier + .5;");
728 v->
codeAppend(
"if (any(lessThan(radii, aa_bloatradius * 1.5))) {");
733 v->
codeAppend(
"aa_bloat_direction = sign(corner);");
735 v->
codeAppend(
"aa_bloat_direction = -aa_bloat_direction;");
742 v->
codeAppend(
"radii = clamp(radii, pixellength * 1.5, 2 - pixellength * 1.5);");
743 v->
codeAppend(
"neighbor_radii = clamp(neighbor_radii, pixellength * 1.5, "
744 "2 - pixellength * 1.5);");
746 v->
codeAppend(
"float2 spacing = 2 - radii - neighbor_radii;");
747 v->
codeAppend(
"float2 extra_pad = max(pixellength * .0625 - spacing, float2(0));");
754 "aa_bloat_direction * aa_bloatradius * aa_bloat_multiplier;");
755 v->
codeAppend(
"float2 vertexpos = corner + radius_outset * radii + aa_outset;");
762 v->
codeAppend(
"if (aa_bloat_direction.x != 0 && vertexpos.x * corner.x < 0) {");
763 v->
codeAppend(
"float backset = abs(vertexpos.x);");
766 "backset * sign(corner.y) * pixellength.y/pixellength.x;");
767 v->
codeAppend(
"coverage = (coverage - .5) * abs(corner.x) / "
768 "(abs(corner.x) + backset) + .5;");
770 v->
codeAppend(
"if (aa_bloat_direction.y != 0 && vertexpos.y * corner.y < 0) {");
771 v->
codeAppend(
"float backset = abs(vertexpos.y);");
774 "backset * sign(corner.x) * pixellength.x/pixellength.y;");
775 v->
codeAppend(
"coverage = (coverage - .5) * abs(corner.y) / "
776 "(abs(corner.y) + backset) + .5;");
781 v->
codeAppend(
"float2x2 skewmatrix = float2x2(skew.xy, skew.zw);");
782 v->
codeAppend(
"float2 devcoord = vertexpos * skewmatrix + translate_and_localrotate.xy;");
786 if (proc.fFlags & ProcessorFlags::kHasLocalCoords) {
789 v->
codeAppend(
"float2 T = vertexpos * .5 + .5;");
790 v->
codeAppend(
"float2 localcoord = localrect.xy * (1 - T) + "
791 "localrect.zw * T + "
792 "translate_and_localrotate.zw * T.yx;");
799 v->
codeAppend(
"if (0 != is_linear_coverage) {");
802 v->
codeAppendf(
"%s.xy = float2(0, coverage * coverage_multiplier);",
807 v->
codeAppend(
"float2 arccoord = 1 - abs(radius_outset) + aa_outset/radii * corner;");
811 v->
codeAppendf(
"%s.xy = float2(arccoord.x+1, arccoord.y);", arcCoord.vsOut());
812 if (!useHWDerivatives) {
814 v->
codeAppendf(
"float2x2 derivatives = inverse(skewmatrix);");
815 v->
codeAppendf(
"%s.zw = derivatives * (arccoord/radii * 2);", arcCoord.vsOut());
820 f->codeAppendf(
"float x_plus_1=%s.x, y=%s.y;", arcCoord.fsIn(), arcCoord.fsIn());
821 f->codeAppendf(
"half coverage;");
822 f->codeAppendf(
"if (0 == x_plus_1) {");
823 f->codeAppendf(
"coverage = half(y);");
824 f->codeAppendf(
"} else {");
825 f->codeAppendf(
"float fn = x_plus_1 * (x_plus_1 - 2);");
826 f->codeAppendf(
"fn = fma(y,y, fn);");
827 if (useHWDerivatives) {
828 f->codeAppendf(
"float fnwidth = fwidth(fn);");
831 f->codeAppendf(
"float gx=%s.z, gy=%s.w;", arcCoord.fsIn(), arcCoord.fsIn());
832 f->codeAppendf(
"float fnwidth = abs(gx) + abs(gy);");
834 f->codeAppendf(
"coverage = .5 - half(fn/fnwidth);");
835 if (proc.fFlags & ProcessorFlags::kMSAAEnabled) {
839 f->codeAppendf(
"coverage = clamp(coverage, 0, 1);");
840 if (!(proc.fFlags & ProcessorFlags::kMSAAEnabled)) {
844 if (proc.fFlags & ProcessorFlags::kFakeNonAA) {
845 f->codeAppendf(
"coverage = (coverage >= .5) ? 1 : 0;");
847 f->codeAppendf(
"half4 %s = half4(coverage);",
args.fOutputCoverage);
851std::unique_ptr<GrGeometryProcessor::ProgramImpl> FillRRectOpImpl::Processor::makeProgramImpl(
853 return std::make_unique<Impl>();
856void FillRRectOpImpl::onCreateProgramInfo(
const GrCaps* caps,
859 bool usesMSAASurface,
864 if (usesMSAASurface) {
865 fProcessorFlags |= ProcessorFlags::kMSAAEnabled;
868 fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, usesMSAASurface,
869 std::move(appliedClip), dstProxyView, gp,
887bool can_use_hw_derivatives_with_coverage(
const skvx::float2& devScale,
890 if (devRadii[1] < devRadii[0]) {
891 devRadii = skvx::shuffle<1,0>(devRadii);
893 float minDevRadius =
std::max(devRadii[0], 1.f);
896 return minDevRadius * minDevRadius * 5 > devRadii[1];
899bool can_use_hw_derivatives_with_coverage(
const skvx::float2& devScale,
901 return can_use_hw_derivatives_with_coverage(devScale,
skvx::float2::Load(&cornerRadii));
905bool can_use_hw_derivatives_with_coverage(
const GrShaderCaps& shaderCaps,
929 return can_use_hw_derivatives_with_coverage(devScale,
931 can_use_hw_derivatives_with_coverage(devScale,
936 for (
int i = 0;
i < 4; ++
i) {
938 if (!can_use_hw_derivatives_with_coverage(devScale,
rrect.
radii(corner))) {
945 SK_ABORT(
"Invalid round rect type.");
972#if defined(GR_TEST_UTILS)
976GR_DRAW_OP_TEST_DEFINE(FillRRectOp) {
978 SkMatrix viewMatrix = GrTest::TestMatrix(random);
982 float w =
rect.width();
983 float h =
rect.height();
std::array< float, 2 > fRadiusOutset
std::array< float, 2 > fCorner
std::array< float, 4 > fRadiiSelector
std::array< float, 2 > fAABloatDirection
#define DEFINE_OP_CLASS_ID
std::function< void(GrSurfaceProxy *, skgpu::Mipmapped)> GrVisitProxyFunc
@ kFloat2_GrVertexAttribType
@ kFloat4_GrVertexAttribType
#define GR_MAKE_BITFIELD_CLASS_OPS(X)
#define GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(X)
#define SKGPU_DECLARE_STATIC_UNIQUE_KEY(name)
#define SKGPU_DEFINE_STATIC_UNIQUE_KEY(name)
#define SK_ABORT(message,...)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
#define SK_ScalarNearlyZero
#define SK_ScalarRoot2Over2
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
sk_sp< const GrBuffer > fIndexBuffer
sk_sp< const GrBuffer > fVertexBuffer
const GrCaps * caps() const
const GrShaderCaps * shaderCaps() const
bool drawInstancedSupport() const
void setData(const GrGLSLProgramDataManager &pdman, const GrFragmentProcessor &processor)
void codeAppend(const char *str)
void codeAppendf(const char format[],...) SK_PRINTF_LIKE(2
void emitAttributes(const GrGeometryProcessor &)
void addPassThroughAttribute(const GrShaderVar &vsVar, const char *output, Interpolation=Interpolation::kInterpolated)
void addVarying(const char *name, GrGLSLVarying *varying, Interpolation=Interpolation::kInterpolated)
void setInstanceAttributesWithImplicitOffsets(const Attribute *attrs, int attrCount)
virtual std::unique_ptr< ProgramImpl > makeProgramImpl(const GrShaderCaps &) const =0
virtual void addToKey(const GrShaderCaps &, skgpu::KeyBuilder *) const =0
size_t instanceStride() const
static Attribute MakeColorAttribute(const char *name, bool wideColor)
void setVertexAttributesWithImplicitOffsets(const Attribute *attrs, int attrCount)
void drawIndexedInstanced(int indexCount, int baseIndex, int instanceCount, int baseInstance, int baseVertex)
void bindPipelineAndScissorClip(const GrProgramInfo &programInfo, const SkRect &drawBounds)
void bindBuffers(sk_sp< const GrBuffer > indexBuffer, sk_sp< const GrBuffer > instanceBuffer, sk_sp< const GrBuffer > vertexBuffer, GrPrimitiveRestart primitiveRestart=GrPrimitiveRestart::kNo)
void bindTextures(const GrGeometryProcessor &geomProc, const GrSurfaceProxy &singleGeomProcTexture, const GrPipeline &pipeline)
std::unique_ptr< GrOp > Owner
virtual const char * name() const =0
const GrPipeline & pipeline() const
const GrGeometryProcessor & geomProc() const
void visitFPProxies(const GrVisitProxyFunc &func) const
GrRecordingContextPriv priv()
void visitProxies(const GrVisitProxyFunc &func) const
GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
static constexpr int kMScaleX
horizontal scale factor
SkScalar getSkewY() const
SkMatrix & setSkewX(SkScalar v)
SkPoint mapPoint(SkPoint pt) const
SkScalar getSkewX() const
bool rectStaysRect() const
SkScalar getScaleX() const
SkMatrix & preConcat(const SkMatrix &other)
SkScalar getScaleY() const
bool hasPerspective() const
static constexpr int kMSkewY
vertical skew factor
static constexpr int kMScaleY
vertical scale factor
static constexpr int kMSkewX
horizontal skew factor
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
SkMatrix & setSkewY(SkScalar v)
void mapVector(SkScalar dx, SkScalar dy, SkVector *result) const
static const SkVector * GetRadiiArray(const SkRRect &rr)
static SkRRect ConservativeIntersect(const SkRRect &a, const SkRRect &b)
SkVector getSimpleRadii() const
const SkRect & rect() const
SkVector radii(Corner corner) const
@ kOval_Type
non-zero width and height filled with radii
@ kSimple_Type
non-zero width and height with equal radii
@ kEmpty_Type
zero width or height
@ kNinePatch_Type
non-zero width and height with axis-aligned radii
@ kRect_Type
non-zero width and height, and zeroed radii
@ kComplex_Type
non-zero width and height with arbitrary radii
bool transform(const SkMatrix &matrix, SkRRect *dst) const
void setNinePatch(const SkRect &rect, SkScalar leftRad, SkScalar topRad, SkScalar rightRad, SkScalar bottomRad)
const SkRect & getBounds() const
void setRect(const SkRect &rect)
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
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)
clipRRect(r.rrect, r.opAA.op(), r.opAA.aa())) DRAW(ClipRect
Optional< SkRect > bounds
sk_sp< SkBlender > blender SkRect rect
constexpr std::array< std::array< float, 2 >, 2 > kRect
DEF_SWITCHES_START aot vmservice shared library name
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 keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
GrOp::Owner Make(GrRecordingContext *ctx, SkArenaAlloc *arena, GrPaint &&paint, const SkMatrix &viewMatrix, const SkRRect &rrect, const SkRect &localRect, GrAA aa)
GrOp::Owner Make(GrRecordingContext *ctx, SkArenaAlloc *arena, GrPaint &&paint, const SkMatrix &viewMatrix, const SkRRect &rrect, const SkMatrix &localMatrix, GrAA aa)
static void make(SkBitmap *bitmap, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace)
SIT void strided_load2(const T *v, Vec< 1, T > &a, Vec< 1, T > &b)
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
constexpr float y() const
constexpr float x() const
SkScalar fBottom
larger y-axis bounds
bool intersect(const SkRect &r)
SkScalar fLeft
smaller x-axis bounds
SkScalar fRight
larger x-axis bounds
constexpr float height() const
constexpr float width() const
SkScalar fTop
smaller y-axis bounds
bool fShaderDerivativeSupport
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)