36#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
45static constexpr SkScalar kIdealMinMIP = 12;
46static constexpr SkScalar kMaxMIP = 162;
48static constexpr SkScalar kMaxDim = 73;
50static constexpr SkScalar kMaxSize = 2*kMaxMIP;
55static const int kAntiAliasPad = 1;
70 return Helper::FactoryHelper<SmallPathOp>(context, std::move(
paint), shape, viewMatrix,
71 gammaCorrect, stencilSettings);
75 const SkMatrix& viewMatrix,
bool gammaCorrect,
81 this->setTransformedBounds(shape.
bounds(), viewMatrix, HasAABloat::kYes, IsHairline::kNo);
83#if defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
84 fUsesDistanceField =
true;
87 fUsesDistanceField = this->
bounds().width() > kMaxMIP || this->
bounds().height() > kMaxMIP;
90 fUsesDistanceField = fUsesDistanceField || viewMatrix.
hasPerspective();
92 fShapes.emplace_back(
Entry{
color, shape, viewMatrix});
94 fGammaCorrect = gammaCorrect;
97 const char*
name()
const override {
return "SmallPathOp"; }
103 FixedFunctionFlags fixedFunctionFlags()
const override {
return fHelper.
fixedFunctionFlags(); }
109 &fShapes.front().fColor, &fWideColor);
127 void onCreateProgramInfo(
const GrCaps*,
130 bool usesMSAASurface,
150 int instanceCount = fShapes.size();
152 auto atlasMgr =
target->smallPathAtlasManager();
161 flushInfo.fPrimProcProxies =
target->allocPrimProcProxyPtrs(kMaxTextures);
163 int numActiveProxies;
165 for (
int i = 0;
i < numActiveProxies; ++
i) {
168 flushInfo.fPrimProcProxies[
i] = views[
i].
proxy();
169 target->sampledProxyArray()->push_back(views[
i].proxy());
173 const SkMatrix& ctm = fShapes[0].fViewMatrix;
180 if (fUsesDistanceField) {
196 target->allocator(), *
target->caps().shaderCaps(), this->color(), fWideColor,
197 nullptr, views, numActiveProxies,
202 const size_t kVertexStride = flushInfo.fGeometryProcessor->vertexStride();
209 VertexWriter vertices =
target->makeVertexWriter(
211 &flushInfo.fVertexBuffer, &flushInfo.fVertexOffset);
213 flushInfo.fIndexBuffer =
target->resourceProvider()->refNonAAQuadIndexBuffer();
214 if (!vertices || !flushInfo.fIndexBuffer) {
215 SkDebugf(
"Could not allocate vertices\n");
219 flushInfo.fInstancesToFlush = 0;
220 for (
int i = 0;
i < instanceCount;
i++) {
224 if (fUsesDistanceField) {
228 if (
args.fViewMatrix.hasPerspective()) {
231 args.fViewMatrix.mapRect(&xformedBounds,
bounds);
259 if (mipSize < kIdealMinMIP) {
263 }
while (newMipSize < kIdealMinMIP);
264 while (newMipSize > 4 * mipSize) {
267 mipSize = newMipSize;
274 shapeData = atlasMgr->findOrCreate(
args.fShape, ceilDesiredDimension);
278 if (!this->addDFPathToAtlas(
target,
283 ceilDesiredDimension,
285 atlasMgr->deleteCacheEntry(shapeData);
291 shapeData = atlasMgr->findOrCreate(
args.fShape,
args.fViewMatrix);
293 if (!this->addBMPathToAtlas(
target,
299 atlasMgr->deleteCacheEntry(shapeData);
305 auto uploadTarget =
target->deferredUploadTarget();
306 atlasMgr->setUseToken(shapeData, uploadTarget->tokenTracker()->nextDrawToken());
308 this->writePathVertices(vertices, VertexColor(
args.fColor, fWideColor),
309 args.fViewMatrix, shapeData);
310 flushInfo.fInstancesToFlush++;
313 this->flush(
target, &flushInfo);
317 FlushInfo* flushInfo,
325 auto resourceProvider =
target->resourceProvider();
326 auto uploadTarget =
target->deferredUploadTarget();
335 this->flush(
target, flushInfo);
348 FlushInfo* flushInfo,
370 scaledBounds.
roundOut(&devPathBounds);
372 int width = devPathBounds.
width() + 2 * kAntiAliasPad;
373 int height = devPathBounds.
height() + 2 * kAntiAliasPad;
376 SkScalar translateY = kAntiAliasPad - dy;
400 width *
sizeof(
unsigned char));
412 paint.setAntiAlias(
true);
417 rasterClip.
setRect(devPathBounds);
418 draw.fRC = &rasterClip;
419 draw.fCTM = &drawMatrix;
426 (
const unsigned char*)
dst.addr(),
427 dst.width(),
dst.height(),
dst.rowBytes());
436 return this->addToAtlasWithRetry(
target, flushInfo, atlasMgr,
442 FlushInfo* flushInfo,
465 shapeDevBounds.
roundOut(&devPathBounds);
467 int width = devPathBounds.
width() + 2 * kAntiAliasPad;
468 int height = devPathBounds.
height() + 2 * kAntiAliasPad;
471 SkScalar translateY = kAntiAliasPad - dy;
490 paint.setAntiAlias(
true);
495 rasterClip.
setRect(devPathBounds);
497 draw.fRC = &rasterClip;
498 draw.fCTM = &drawMatrix;
505 return this->addToAtlasWithRetry(
target, flushInfo, atlasMgr,
507 drawBounds, 0, shapeData);
510 void writePathVertices(VertexWriter& vertices,
511 const VertexColor&
color,
515 if (!fUsesDistanceField) {
523 if (fUsesDistanceField) {
526 translatedBounds.toQuad(pts);
529 vertices <<
out[0] <<
color << texCoords.l << texCoords.t;
530 vertices <<
out[3] <<
color << texCoords.l << texCoords.b;
531 vertices <<
out[1] <<
color << texCoords.r << texCoords.t;
532 vertices <<
out[2] <<
color << texCoords.r << texCoords.b;
541 auto atlasMgr =
target->smallPathAtlasManager();
546 int numActiveProxies;
552 flushInfo->fPrimProcProxies[
i] = views[
i].
proxy();
555 target->sampledProxyArray()->push_back(views[
i].proxy());
559 if (fUsesDistanceField) {
568 if (flushInfo->fInstancesToFlush) {
570 mesh->setIndexedPatterned(flushInfo->fIndexBuffer,
572 flushInfo->fInstancesToFlush,
574 flushInfo->fVertexBuffer,
576 flushInfo->fVertexOffset);
577 target->recordDraw(flushInfo->fGeometryProcessor,
mesh, 1, flushInfo->fPrimProcProxies,
580 flushInfo->fInstancesToFlush;
581 flushInfo->fInstancesToFlush = 0;
593 bool usesDistanceField()
const {
return fUsesDistanceField; }
596 SmallPathOp* that = t->
cast<SmallPathOp>();
597 if (!fHelper.
isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
598 return CombineResult::kCannotCombine;
601 if (this->usesDistanceField() != that->usesDistanceField()) {
602 return CombineResult::kCannotCombine;
605 const SkMatrix& thisCtm = this->fShapes[0].fViewMatrix;
606 const SkMatrix& thatCtm = that->fShapes[0].fViewMatrix;
608 if (this->usesDistanceField()) {
611 return CombineResult::kCannotCombine;
617 return CombineResult::kCannotCombine;
621 return CombineResult::kCannotCombine;
628 return CombineResult::kCannotCombine;
632 fShapes.push_back_n(that->fShapes.size(), that->fShapes.begin());
633 fWideColor |= that->fWideColor;
634 return CombineResult::kMerged;
637#if defined(GR_TEST_UTILS)
638 SkString onDumpInfo()
const override {
640 for (
const auto& geo : fShapes) {
641 string.
appendf(
"Color: 0x%08x\n", geo.fColor.toBytes_RGBA());
643 string += fHelper.dumpInfo();
648 bool fUsesDistanceField;
669 if (!
args.fCaps->shaderCaps()->fShaderDerivativeSupport) {
673 if (!
args.fShape->hasUnstyledKey()) {
678 if (!
args.fShape->style().isSimpleFill()) {
686 if (
args.fShape->inverseFilled()) {
690 SkScalar scaleFactors[2] = { 1, 1 };
692 if (!
args.fViewMatrix->hasPerspective() && !
args.fViewMatrix->getMinMaxScales(scaleFactors)) {
696 if (!scaleFactors[0] || scaleFactors[1]/scaleFactors[0] > 4) {
707 if (maxDim > kMaxDim || kMinSize > minSize || maxSize > kMaxSize) {
714bool SmallPathRenderer::onDrawPath(
const DrawPathArgs&
args) {
716 "SmallPathRenderer::onDrawPath");
724 args.fGammaCorrect,
args.fUserStencilSettings);
725 args.fSurfaceDrawContext->addDrawOp(
args.fClip, std::move(op));
732#if defined(GR_TEST_UTILS)
734GR_DRAW_OP_TEST_DEFINE(SmallPathOp) {
735 SkMatrix viewMatrix = GrTest::TestMatrix(random);
736 bool gammaCorrect = random->nextBool();
745 GrGetRandomStencil(random, context));
sk_bzero(glyphs, sizeof(glyphs))
#define GR_AUDIT_TRAIL_AUTO_FRAME(audit_trail, framename)
bool GrGenerateDistanceFieldFromPath(unsigned char *distanceField, const SkPath &path, const SkMatrix &drawMatrix, int width, int height, size_t rowBytes)
@ kGammaCorrect_DistanceFieldEffectFlag
@ kWideColor_DistanceFieldEffectFlag
@ kPerspective_DistanceFieldEffectFlag
@ kSimilarity_DistanceFieldEffectFlag
@ kScaleOnly_DistanceFieldEffectFlag
#define DEFINE_OP_CLASS_ID
std::function< void(GrSurfaceProxy *, skgpu::Mipmapped)> GrVisitProxyFunc
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
bool SkGenerateDistanceFieldFromA8Image(unsigned char *distanceField, const unsigned char *image, int width, int height, size_t rowBytes)
#define SK_DistanceFieldPad
static constexpr int32_t SK_MaxS32
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
#define INHERITED(method,...)
#define SkScalarInvert(x)
#define SkScalarFloorToScalar(x)
#define SkScalarCeilToInt(x)
#define SK_ScalarNearlyZero
#define SkScalarPow(b, e)
#define SkScalarCeilToScalar(x)
GrGeometryProcessor * fGeometryProcessor
sk_sp< const GrBuffer > fIndexBuffer
sk_sp< const GrBuffer > fVertexBuffer
const GrSurfaceProxy ** fPrimProcProxies
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
static GrGeometryProcessor * Make(SkArenaAlloc *arena, const GrShaderCaps &caps, const SkPMColor4f &color, bool wideColor, sk_sp< GrColorSpaceXform > colorSpaceXform, const GrSurfaceProxyView *views, int numActiveViews, GrSamplerState p, skgpu::MaskFormat format, const SkMatrix &localMatrix, bool usesW)
static constexpr int kMaxTextures
static GrGeometryProcessor * Make(SkArenaAlloc *arena, const GrShaderCaps &caps, const GrSurfaceProxyView *views, int numActiveViews, GrSamplerState params, const SkMatrix &localMatrix, uint32_t flags)
static constexpr int kMaxTextures
int numTextureSamplers() const
void executeDrawsAndUploadsForMeshDrawOp(const GrOp *op, const SkRect &chainBounds, const GrPipeline *, const GrUserStencilSettings *)
std::unique_ptr< GrOp > Owner
static int NumIndicesPerNonAAQuad()
static int MaxNumNonAAQuads()
static int NumVertsPerNonAAQuad()
GrProcessorSet::Analysis finalizeProcessors(const GrCaps &caps, const GrAppliedClip *clip, GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage, GrProcessorAnalysisColor *geometryColor)
void visitProxies(const GrVisitProxyFunc &func) const
GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const
bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil &that, const GrCaps &, const SkRect &thisBounds, const SkRect &thatBounds, bool ignoreAAType=false) const
bool usesLocalCoords() const
const GrUserStencilSettings * stencilSettings() const
const GrPipeline * createPipeline(GrOpFlushState *flushState)
static const GrStyle & SimpleFill()
void asPath(SkPath *out) const
bool hasUnstyledKey() const
GrSurfaceProxy * proxy() const
static bool CheapEqual(const SkMatrix &a, const SkMatrix &b)
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
static constexpr int kMTransY
vertical translation
void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const
SkScalar getTranslateY() const
SkMatrix & set(int index, SkScalar value)
SkMatrix & setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
bool invert(SkMatrix *inverse) const
bool isScaleTranslate() const
static constexpr int kMTransX
horizontal translation
bool hasPerspective() const
SkScalar get(int index) const
bool isSimilarity(SkScalar tol=SK_ScalarNearlyZero) const
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
SkScalar getTranslateX() const
@ kFill_Style
set to fill geometry
bool setRect(const SkIRect &)
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
std::array< uint16_t, 4 > getUVs() const
void insetSrc(int padding)
PlotLocator plotLocator() const
GrDrawOpAtlas::ErrorCode addToAtlas(GrResourceProvider *, GrDeferredUploadTarget *, int width, int height, const void *image, skgpu::AtlasLocator *)
const GrSurfaceProxyView * getViews(int *numActiveProxies)
skgpu::AtlasLocator fAtlasLocator
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)
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
Optional< SkRect > bounds
sk_sp< const SkImage > image
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
DEF_SWITCHES_START aot vmservice shared library name
SkIRect makeOutset(int32_t dx, int32_t dy) const
constexpr int32_t height() const
int32_t fTop
smaller y-axis bounds
constexpr int32_t width() const
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
int32_t fLeft
smaller x-axis bounds
static SkImageInfo MakeA8(int width, int height)
static SkRect Make(const SkISize &size)
SkScalar fBottom
larger y-axis bounds
constexpr SkRect makeOffset(float dx, float dy) const
SkScalar fLeft
smaller x-axis bounds
SkScalar fRight
larger x-axis bounds
void roundOut(SkIRect *dst) const
void offset(float dx, float dy)
constexpr float height() const
constexpr float width() const
SkScalar fTop
smaller y-axis bounds
static TriStrip< uint16_t > TriStripFromUVs(const std::array< uint16_t, 4 > &rect)
static TriStrip< float > TriStripFromRect(const SkRect &r)