本文整理汇总了C++中SkIRect::makeOffset方法的典型用法代码示例。如果您正苦于以下问题:C++ SkIRect::makeOffset方法的具体用法?C++ SkIRect::makeOffset怎么用?C++ SkIRect::makeOffset使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SkIRect
的用法示例。
在下文中一共展示了SkIRect::makeOffset方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: outputProperties
sk_sp<SkImage> SkImage::makeWithFilter(const SkImageFilter* filter, const SkIRect& subset,
const SkIRect& clipBounds, SkIRect* outSubset,
SkIPoint* offset) const {
if (!filter || !outSubset || !offset || !this->bounds().contains(subset)) {
return nullptr;
}
SkColorSpace* colorSpace = as_IB(this)->onImageInfo().colorSpace();
sk_sp<SkSpecialImage> srcSpecialImage = SkSpecialImage::MakeFromImage(
subset, sk_ref_sp(const_cast<SkImage*>(this)), colorSpace);
if (!srcSpecialImage) {
return nullptr;
}
sk_sp<SkImageFilterCache> cache(
SkImageFilterCache::Create(SkImageFilterCache::kDefaultTransientSize));
SkImageFilter::OutputProperties outputProperties(colorSpace);
SkImageFilter::Context context(SkMatrix::I(), clipBounds, cache.get(), outputProperties);
sk_sp<SkSpecialImage> result = filter->filterImage(srcSpecialImage.get(), context, offset);
if (!result) {
return nullptr;
}
*outSubset = SkIRect::MakeWH(result->width(), result->height());
if (!outSubset->intersect(clipBounds.makeOffset(-offset->x(), -offset->y()))) {
return nullptr;
}
offset->fX += outSubset->x();
offset->fY += outSubset->y();
// Note that here we're returning the special image's entire backing store, loose padding
// and all!
return result->asImage();
}
示例2: validator
sk_sp<SkImage> SkImage_Lazy::onMakeSubset(const SkIRect& subset) const {
SkASSERT(fInfo.bounds().contains(subset));
SkASSERT(fInfo.bounds() != subset);
const SkIRect generatorSubset = subset.makeOffset(fOrigin.x(), fOrigin.y());
Validator validator(fSharedGenerator, &generatorSubset, fInfo.refColorSpace());
return validator ? sk_sp<SkImage>(new SkImage_Lazy(&validator)) : nullptr;
}
示例3: onFilterNodeBounds
SkIRect SkOffsetImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
MapDirection direction) const {
SkIPoint vec = map_offset_vector(ctm, fOffset);
if (kReverse_MapDirection == direction) {
SkPointPriv::Negate(vec);
}
return src.makeOffset(vec.fX, vec.fY);
}
示例4: onFilterNodeBounds
SkIRect SkDropShadowImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
MapDirection direction) const {
SkVector offsetVec = SkVector::Make(fDx, fDy);
if (kReverse_MapDirection == direction) {
offsetVec.negate();
}
ctm.mapVectors(&offsetVec, 1);
SkIRect dst = src.makeOffset(SkScalarCeilToInt(offsetVec.x()),
SkScalarCeilToInt(offsetVec.y()));
SkVector sigma = SkVector::Make(fSigmaX, fSigmaY);
ctm.mapVectors(&sigma, 1);
dst.outset(SkScalarCeilToInt(SkScalarMul(sigma.x(), SkIntToScalar(3))),
SkScalarCeilToInt(SkScalarMul(sigma.y(), SkIntToScalar(3))));
if (fShadowMode == kDrawShadowAndForeground_ShadowMode) {
dst.join(src);
}
return dst;
}
示例5: setCoverageCountAtlas
void GrCCPathCacheEntry::setCoverageCountAtlas(
GrOnFlushResourceProvider* onFlushRP, GrCCAtlas* atlas, const SkIVector& atlasOffset,
const GrOctoBounds& octoBounds, const SkIRect& devIBounds, const SkIVector& maskShift) {
SkASSERT(fOnFlushRefCnt > 0);
SkASSERT(!fCachedAtlas); // Otherwise we would need to call releaseCachedAtlas().
if (this->hasBeenEvicted()) {
// This entry will never be found in the path cache again. Don't bother trying to save an
// atlas texture for it in the GrResourceCache.
return;
}
fCachedAtlas = atlas->refOrMakeCachedAtlas(onFlushRP);
fCachedAtlas->incrOnFlushRefCnt(fOnFlushRefCnt);
fCachedAtlas->addPathPixels(devIBounds.height() * devIBounds.width());
fAtlasOffset = atlasOffset + maskShift;
fOctoBounds.setOffset(octoBounds, -maskShift.fX, -maskShift.fY);
fDevIBounds = devIBounds.makeOffset(-maskShift.fX, -maskShift.fY);
}
示例6: context
sk_sp<SkImage> SkImage::makeWithFilter(const SkImageFilter* filter, const SkIRect& subset,
const SkIRect& clipBounds, SkIRect* outSubset,
SkIPoint* offset) const {
if (!filter || !outSubset || !offset || !this->bounds().contains(subset)) {
return nullptr;
}
sk_sp<SkSpecialImage> srcSpecialImage = SkSpecialImage::MakeFromImage(
subset, sk_ref_sp(const_cast<SkImage*>(this)));
if (!srcSpecialImage) {
return nullptr;
}
// FIXME: build a cache here.
SkImageFilter::Context context(SkMatrix::I(), clipBounds, nullptr);
sk_sp<SkSpecialImage> result =
filter->filterImage(srcSpecialImage.get(), context, offset);
if (!result) {
return nullptr;
}
SkIRect fullSize = SkIRect::MakeWH(result->width(), result->height());
#if SK_SUPPORT_GPU
if (result->isTextureBacked()) {
GrContext* context = result->getContext();
sk_sp<GrTexture> texture = result->asTextureRef(context);
fullSize = SkIRect::MakeWH(texture->width(), texture->height());
}
#endif
*outSubset = SkIRect::MakeWH(result->width(), result->height());
if (!outSubset->intersect(clipBounds.makeOffset(-offset->x(), -offset->y()))) {
return nullptr;
}
offset->fX += outSubset->x();
offset->fY += outSubset->y();
// This isn't really a "tight" subset, but includes any texture padding.
return result->makeTightSubset(fullSize);
}
示例7: MakeFromGpu
sk_sp<SkSpecialImage> SkDisplacementMapEffect::onFilterImage(SkSpecialImage* source,
const Context& ctx,
SkIPoint* offset) const {
SkIPoint colorOffset = SkIPoint::Make(0, 0);
sk_sp<SkSpecialImage> color(this->filterInput(1, source, ctx, &colorOffset));
if (!color) {
return nullptr;
}
SkIPoint displOffset = SkIPoint::Make(0, 0);
sk_sp<SkSpecialImage> displ(this->filterInput(0, source, ctx, &displOffset));
if (!displ) {
return nullptr;
}
const SkIRect srcBounds = SkIRect::MakeXYWH(colorOffset.x(), colorOffset.y(),
color->width(), color->height());
// Both paths do bounds checking on color pixel access, we don't need to
// pad the color bitmap to bounds here.
SkIRect bounds;
if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
return nullptr;
}
SkIRect displBounds;
displ = this->applyCropRect(ctx, displ.get(), &displOffset, &displBounds);
if (!displ) {
return nullptr;
}
if (!bounds.intersect(displBounds)) {
return nullptr;
}
const SkIRect colorBounds = bounds.makeOffset(-colorOffset.x(), -colorOffset.y());
SkVector scale = SkVector::Make(fScale, fScale);
ctx.ctm().mapVectors(&scale, 1);
#if SK_SUPPORT_GPU
if (source->isTextureBacked()) {
GrContext* context = source->getContext();
sk_sp<GrTexture> colorTexture(color->asTextureRef(context));
sk_sp<GrTexture> displTexture(displ->asTextureRef(context));
if (!colorTexture || !displTexture) {
return nullptr;
}
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = bounds.width();
desc.fHeight = bounds.height();
desc.fConfig = kSkia8888_GrPixelConfig;
SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture(desc));
if (!dst) {
return nullptr;
}
GrPaint paint;
SkMatrix offsetMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(displTexture.get());
offsetMatrix.preTranslate(SkIntToScalar(colorOffset.fX - displOffset.fX),
SkIntToScalar(colorOffset.fY - displOffset.fY));
paint.addColorFragmentProcessor(
GrDisplacementMapEffect::Create(fXChannelSelector,
fYChannelSelector,
scale,
displTexture.get(),
offsetMatrix,
colorTexture.get(),
SkISize::Make(color->width(),
color->height())))->unref();
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
SkMatrix matrix;
matrix.setTranslate(-SkIntToScalar(colorBounds.x()), -SkIntToScalar(colorBounds.y()));
SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTarget()));
if (!drawContext) {
return nullptr;
}
drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(colorBounds));
offset->fX = bounds.left();
offset->fY = bounds.top();
return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(bounds.width(), bounds.height()),
kNeedNewImageUniqueID_SpecialImage,
dst);
}
#endif
SkBitmap colorBM, displBM;
if (!color->getROPixels(&colorBM) || !displ->getROPixels(&displBM)) {
return nullptr;
}
//.........这里部分代码省略.........
示例8: inputBoundsF
sk_sp<SkSpecialImage> SkBlurImageFilter::onFilterImage(SkSpecialImage* source,
const Context& ctx,
SkIPoint* offset) const {
SkIPoint inputOffset = SkIPoint::Make(0, 0);
sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset));
if (!input) {
return nullptr;
}
SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.fX, inputOffset.fY,
input->width(), input->height());
SkIRect dstBounds;
if (!this->applyCropRect(this->mapContext(ctx), inputBounds, &dstBounds)) {
return nullptr;
}
if (!inputBounds.intersect(dstBounds)) {
return nullptr;
}
const SkVector sigma = map_sigma(fSigma, ctx.ctm());
#if SK_SUPPORT_GPU
if (input->peekTexture() && input->peekTexture()->getContext()) {
if (0 == sigma.x() && 0 == sigma.y()) {
offset->fX = inputBounds.x();
offset->fY = inputBounds.y();
return input->makeSubset(inputBounds.makeOffset(-inputOffset.x(),
-inputOffset.y()));
}
GrTexture* inputTexture = input->peekTexture();
offset->fX = dstBounds.fLeft;
offset->fY = dstBounds.fTop;
inputBounds.offset(-inputOffset);
dstBounds.offset(-inputOffset);
SkRect inputBoundsF(SkRect::Make(inputBounds));
SkAutoTUnref<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(inputTexture->getContext(),
inputTexture,
false,
source->props().allowSRGBInputs(),
SkRect::Make(dstBounds),
&inputBoundsF,
sigma.x(),
sigma.y()));
if (!tex) {
return nullptr;
}
return SkSpecialImage::MakeFromGpu(source->internal_getProxy(),
SkIRect::MakeWH(dstBounds.width(), dstBounds.height()),
kNeedNewImageUniqueID_SpecialImage,
tex, &source->props());
}
#endif
int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX;
int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY;
get_box3_params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffsetX);
get_box3_params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffsetY);
if (kernelSizeX < 0 || kernelSizeY < 0) {
return nullptr;
}
if (kernelSizeX == 0 && kernelSizeY == 0) {
offset->fX = inputBounds.x();
offset->fY = inputBounds.y();
return input->makeSubset(inputBounds.makeOffset(-inputOffset.x(),
-inputOffset.y()));
}
SkPixmap inputPixmap;
if (!input->peekPixels(&inputPixmap)) {
return nullptr;
}
if (inputPixmap.colorType() != kN32_SkColorType) {
return nullptr;
}
SkImageInfo info = SkImageInfo::Make(dstBounds.width(), dstBounds.height(),
inputPixmap.colorType(), inputPixmap.alphaType());
SkBitmap tmp, dst;
if (!tmp.tryAllocPixels(info) || !dst.tryAllocPixels(info)) {
return nullptr;
}
SkAutoLockPixels tmpLock(tmp), dstLock(dst);
offset->fX = dstBounds.fLeft;
offset->fY = dstBounds.fTop;
SkPMColor* t = tmp.getAddr32(0, 0);
SkPMColor* d = dst.getAddr32(0, 0);
int w = dstBounds.width(), h = dstBounds.height();
const SkPMColor* s = inputPixmap.addr32(inputBounds.x() - inputOffset.x(),
//.........这里部分代码省略.........
示例9: saveParsedPath
void GrCCPathParser::saveParsedPath(ScissorMode scissorMode, const SkIRect& clippedDevIBounds,
int16_t atlasOffsetX, int16_t atlasOffsetY) {
SkASSERT(fParsingPath);
fPathsInfo.emplace_back(scissorMode, atlasOffsetX, atlasOffsetY);
// Tessellate fans from very large and/or simple paths, in order to reduce overdraw.
int numVerbs = fGeometry.verbs().count() - fCurrPathVerbsIdx - 1;
int64_t tessellationWork = (int64_t)numVerbs * (32 - SkCLZ(numVerbs)); // N log N.
int64_t fanningWork = (int64_t)clippedDevIBounds.height() * clippedDevIBounds.width();
if (tessellationWork * (50*50) + (100*100) < fanningWork) { // Don't tessellate under 100x100.
fCurrPathPrimitiveCounts.fTriangles =
fCurrPathPrimitiveCounts.fWeightedTriangles = 0;
const SkTArray<GrCCGeometry::Verb, true>& verbs = fGeometry.verbs();
const SkTArray<SkPoint, true>& pts = fGeometry.points();
int ptsIdx = fCurrPathPointsIdx;
// Build an SkPath of the Redbook fan. We use "winding" fill type right now because we are
// producing a coverage count, and must fill in every region that has non-zero wind. The
// path processor will convert coverage count to the appropriate fill type later.
SkPath fan;
fan.setFillType(SkPath::kWinding_FillType);
SkASSERT(GrCCGeometry::Verb::kBeginPath == verbs[fCurrPathVerbsIdx]);
for (int i = fCurrPathVerbsIdx + 1; i < fGeometry.verbs().count(); ++i) {
switch (verbs[i]) {
case GrCCGeometry::Verb::kBeginPath:
SK_ABORT("Invalid GrCCGeometry");
continue;
case GrCCGeometry::Verb::kBeginContour:
fan.moveTo(pts[ptsIdx++]);
continue;
case GrCCGeometry::Verb::kLineTo:
fan.lineTo(pts[ptsIdx++]);
continue;
case GrCCGeometry::Verb::kMonotonicQuadraticTo:
case GrCCGeometry::Verb::kMonotonicConicTo:
fan.lineTo(pts[ptsIdx + 1]);
ptsIdx += 2;
continue;
case GrCCGeometry::Verb::kMonotonicCubicTo:
fan.lineTo(pts[ptsIdx + 2]);
ptsIdx += 3;
continue;
case GrCCGeometry::Verb::kEndClosedContour:
case GrCCGeometry::Verb::kEndOpenContour:
fan.close();
continue;
}
}
GrTessellator::WindingVertex* vertices = nullptr;
int count = GrTessellator::PathToVertices(fan, std::numeric_limits<float>::infinity(),
SkRect::Make(clippedDevIBounds), &vertices);
SkASSERT(0 == count % 3);
for (int i = 0; i < count; i += 3) {
int tessWinding = vertices[i].fWinding;
SkASSERT(tessWinding == vertices[i + 1].fWinding);
SkASSERT(tessWinding == vertices[i + 2].fWinding);
// Ensure this triangle's points actually wind in the same direction as tessWinding.
// CCPR shaders use the sign of wind to determine which direction to bloat, so even for
// "wound" triangles the winding sign and point ordering need to agree.
float ax = vertices[i].fPos.fX - vertices[i + 1].fPos.fX;
float ay = vertices[i].fPos.fY - vertices[i + 1].fPos.fY;
float bx = vertices[i].fPos.fX - vertices[i + 2].fPos.fX;
float by = vertices[i].fPos.fY - vertices[i + 2].fPos.fY;
float wind = ax*by - ay*bx;
if ((wind > 0) != (-tessWinding > 0)) { // Tessellator has opposite winding sense.
std::swap(vertices[i + 1].fPos, vertices[i + 2].fPos);
}
if (1 == abs(tessWinding)) {
++fCurrPathPrimitiveCounts.fTriangles;
} else {
++fCurrPathPrimitiveCounts.fWeightedTriangles;
}
}
fPathsInfo.back().adoptFanTessellation(vertices, count);
}
fTotalPrimitiveCounts[(int)scissorMode] += fCurrPathPrimitiveCounts;
if (ScissorMode::kScissored == scissorMode) {
fScissorSubBatches.push_back() = {fTotalPrimitiveCounts[(int)ScissorMode::kScissored],
clippedDevIBounds.makeOffset(atlasOffsetX, atlasOffsetY)};
}
SkDEBUGCODE(fParsingPath = false);
}
示例10: find
GrCCPathCache::OnFlushEntryRef GrCCPathCache::find(
GrOnFlushResourceProvider* onFlushRP, const GrShape& shape,
const SkIRect& clippedDrawBounds, const SkMatrix& viewMatrix, SkIVector* maskShift) {
if (!shape.hasUnstyledKey()) {
return OnFlushEntryRef();
}
WriteKeyHelper writeKeyHelper(shape);
if (writeKeyHelper.allocCountU32() > kMaxKeyDataCountU32) {
return OnFlushEntryRef();
}
SkASSERT(fScratchKey->unique());
fScratchKey->resetDataCountU32(writeKeyHelper.allocCountU32());
writeKeyHelper.write(shape, fScratchKey->data());
MaskTransform m(viewMatrix, maskShift);
GrCCPathCacheEntry* entry = nullptr;
if (HashNode* node = fHashTable.find(*fScratchKey)) {
entry = node->entry();
SkASSERT(fLRU.isInList(entry));
if (!fuzzy_equals(m, entry->fMaskTransform)) {
// The path was reused with an incompatible matrix.
if (entry->unique()) {
// This entry is unique: recycle it instead of deleting and malloc-ing a new one.
SkASSERT(0 == entry->fOnFlushRefCnt); // Because we are unique.
entry->fMaskTransform = m;
entry->fHitCount = 0;
entry->fHitRect = SkIRect::MakeEmpty();
entry->releaseCachedAtlas(this);
} else {
this->evict(*fScratchKey);
entry = nullptr;
}
}
}
if (!entry) {
if (fHashTable.count() >= kMaxCacheCount) {
SkDEBUGCODE(HashNode* node = fHashTable.find(*fLRU.tail()->fCacheKey));
SkASSERT(node && node->entry() == fLRU.tail());
this->evict(*fLRU.tail()->fCacheKey); // We've exceeded our limit.
}
// Create a new entry in the cache.
sk_sp<Key> permanentKey = Key::Make(fInvalidatedKeysInbox.uniqueID(),
writeKeyHelper.allocCountU32(), fScratchKey->data());
SkASSERT(*permanentKey == *fScratchKey);
SkASSERT(!fHashTable.find(*permanentKey));
entry = fHashTable.set(HashNode(this, std::move(permanentKey), m, shape))->entry();
SkASSERT(fHashTable.count() <= kMaxCacheCount);
} else {
fLRU.remove(entry); // Will be re-added at head.
}
SkDEBUGCODE(HashNode* node = fHashTable.find(*fScratchKey));
SkASSERT(node && node->entry() == entry);
fLRU.addToHead(entry);
if (0 == entry->fOnFlushRefCnt) {
// Only update the time stamp and hit count if we haven't seen this entry yet during the
// current flush.
entry->fTimestamp = this->quickPerFlushTimestamp();
++entry->fHitCount;
if (entry->fCachedAtlas) {
SkASSERT(SkToBool(entry->fCachedAtlas->peekOnFlushRefCnt()) ==
SkToBool(entry->fCachedAtlas->getOnFlushProxy()));
if (!entry->fCachedAtlas->getOnFlushProxy()) {
if (sk_sp<GrTextureProxy> onFlushProxy = onFlushRP->findOrCreateProxyByUniqueKey(
entry->fCachedAtlas->textureKey(), GrCCAtlas::kTextureOrigin)) {
onFlushProxy->priv().setIgnoredByResourceAllocator();
entry->fCachedAtlas->setOnFlushProxy(std::move(onFlushProxy));
}
}
if (!entry->fCachedAtlas->getOnFlushProxy()) {
// Our atlas's backing texture got purged from the GrResourceCache. Release the
// cached atlas.
entry->releaseCachedAtlas(this);
}
}
}
entry->fHitRect.join(clippedDrawBounds.makeOffset(-maskShift->x(), -maskShift->y()));
SkASSERT(!entry->fCachedAtlas || entry->fCachedAtlas->getOnFlushProxy());
return OnFlushEntryRef::OnFlushRef(entry);
}
示例11: parseDeviceSpaceFill
void GrCCFiller::parseDeviceSpaceFill(const SkPath& path, const SkPoint* deviceSpacePts,
GrScissorTest scissorTest, const SkIRect& clippedDevIBounds,
const SkIVector& devToAtlasOffset) {
SkASSERT(!fInstanceBuffer); // Can't call after prepareToDraw().
SkASSERT(!path.isEmpty());
int currPathPointsIdx = fGeometry.points().count();
int currPathVerbsIdx = fGeometry.verbs().count();
PrimitiveTallies currPathPrimitiveCounts = PrimitiveTallies();
fGeometry.beginPath();
const float* conicWeights = SkPathPriv::ConicWeightData(path);
int ptsIdx = 0;
int conicWeightsIdx = 0;
bool insideContour = false;
for (SkPath::Verb verb : SkPathPriv::Verbs(path)) {
switch (verb) {
case SkPath::kMove_Verb:
if (insideContour) {
currPathPrimitiveCounts += fGeometry.endContour();
}
fGeometry.beginContour(deviceSpacePts[ptsIdx]);
++ptsIdx;
insideContour = true;
continue;
case SkPath::kClose_Verb:
if (insideContour) {
currPathPrimitiveCounts += fGeometry.endContour();
}
insideContour = false;
continue;
case SkPath::kLine_Verb:
fGeometry.lineTo(&deviceSpacePts[ptsIdx - 1]);
++ptsIdx;
continue;
case SkPath::kQuad_Verb:
fGeometry.quadraticTo(&deviceSpacePts[ptsIdx - 1]);
ptsIdx += 2;
continue;
case SkPath::kCubic_Verb:
fGeometry.cubicTo(&deviceSpacePts[ptsIdx - 1]);
ptsIdx += 3;
continue;
case SkPath::kConic_Verb:
fGeometry.conicTo(&deviceSpacePts[ptsIdx - 1], conicWeights[conicWeightsIdx]);
ptsIdx += 2;
++conicWeightsIdx;
continue;
default:
SK_ABORT("Unexpected path verb.");
}
}
SkASSERT(ptsIdx == path.countPoints());
SkASSERT(conicWeightsIdx == SkPathPriv::ConicWeightCnt(path));
if (insideContour) {
currPathPrimitiveCounts += fGeometry.endContour();
}
fPathInfos.emplace_back(scissorTest, devToAtlasOffset);
// Tessellate fans from very large and/or simple paths, in order to reduce overdraw.
int numVerbs = fGeometry.verbs().count() - currPathVerbsIdx - 1;
int64_t tessellationWork = (int64_t)numVerbs * (32 - SkCLZ(numVerbs)); // N log N.
int64_t fanningWork = (int64_t)clippedDevIBounds.height() * clippedDevIBounds.width();
if (tessellationWork * (50*50) + (100*100) < fanningWork) { // Don't tessellate under 100x100.
fPathInfos.back().tessellateFan(fGeometry, currPathVerbsIdx, currPathPointsIdx,
clippedDevIBounds, &currPathPrimitiveCounts);
}
fTotalPrimitiveCounts[(int)scissorTest] += currPathPrimitiveCounts;
if (GrScissorTest::kEnabled == scissorTest) {
fScissorSubBatches.push_back() = {fTotalPrimitiveCounts[(int)GrScissorTest::kEnabled],
clippedDevIBounds.makeOffset(devToAtlasOffset.fX,
devToAtlasOffset.fY)};
}
}