59static thread_local void*
gCache =
nullptr;
60void* AtlasTextOp::operator
new(
size_t s) {
62 return std::exchange(
gCache,
nullptr);
65 return ::operator
new(
s);
68void AtlasTextOp::operator
delete(
void* bytes)
noexcept {
73 ::operator
delete(bytes);
81AtlasTextOp::AtlasTextOp(MaskType maskType,
90 , fNumGlyphs(glyphCount)
92 , fMaskType(static_cast<uint32_t>(maskType))
93 , fUsesLocalCoords(false)
94 , fNeedsGlyphTransform(needsTransform)
95 , fHasPerspective(needsTransform && geo->fDrawMatrix.hasPerspective())
96 , fUseGammaCorrectDistanceTable(false)
98 , fTail{&fHead->
fNext} {
108AtlasTextOp::AtlasTextOp(MaskType maskType,
113 bool useGammaCorrectDistanceTable,
119 , fNumGlyphs(glyphCount)
120 , fDFGPFlags(DFGPFlags)
121 , fMaskType(static_cast<uint32_t>(maskType))
122 , fUsesLocalCoords(false)
123 , fNeedsGlyphTransform(needsTransform)
124 , fHasPerspective(needsTransform && geo->fDrawMatrix.hasPerspective())
125 , fUseGammaCorrectDistanceTable(useGammaCorrectDistanceTable)
126 , fLuminanceColor(luminanceColor)
128 , fTail{&fHead->
fNext} {
148 std::move(supportData),
161#if defined(GR_TEST_UTILS)
162SkString AtlasTextOp::onDumpInfo()
const {
165 for(Geometry* geom = fHead; geom !=
nullptr; geom = geom->fNext) {
166 str.
appendf(
"%d: Color: 0x%08x Trans: %.2f,%.2f\n",
168 geom->fColor.toBytes_RGBA(),
169 geom->fDrawOrigin.x(),
170 geom->fDrawOrigin.y());
173 str += fProcessors.dumpProcessors();
188 color.setToUnknown();
195 switch (this->maskType()) {
197#if !defined(SK_DISABLE_SDF_TEXT)
204#if !defined(SK_DISABLE_SDF_TEXT)
216 caps, clampType, &fHead->
fColor);
220 fUsesLocalCoords = analysis.usesLocalCoords();
225 auto resourceProvider =
target->resourceProvider();
240 unsigned int numActiveViews;
243 SkDebugf(
"Could not allocate backing texture for atlas\n");
249#if !defined(SK_DISABLE_SDF_TEXT)
254 auto primProcProxies =
target->allocPrimProcProxyPtrs(kMaxTextures);
255 for (
unsigned i = 0; i < numActiveViews; ++i) {
256 primProcProxies[i] = views[i].
proxy();
259 target->sampledProxyArray()->push_back(views[i].proxy());
263 flushInfo.fPrimProcProxies = primProcProxies;
264 flushInfo.fIndexBuffer = resourceProvider->refNonAAQuadIndexBuffer();
266#if !defined(SK_DISABLE_SDF_TEXT)
267 if (this->usesDistanceFields()) {
268 flushInfo.fGeometryProcessor = this->setupDfProcessor(
target->allocator(),
269 *
target->caps().shaderCaps(),
270 localMatrix, views, numActiveViews);
274 auto filter = fNeedsGlyphTransform ? GrSamplerState::Filter::kLinear
275 : GrSamplerState::Filter::kNearest;
280 false, fColorSpaceXform, views, numActiveViews, filter,
281 maskFormat, localMatrix, fHasPerspective);
284 const int vertexStride = (
int)flushInfo.fGeometryProcessor->vertexStride();
289 const int maxQuadsPerBuffer = kMaxVertexBytes / quadSize;
291 int allGlyphsCursor = 0;
292 const int allGlyphsEnd = fNumGlyphs;
297 auto resetVertexBuffer = [&] {
299 quadEnd = std::min(maxQuadsPerBuffer, allGlyphsEnd - allGlyphsCursor);
301 vertices = (
char*)
target->makeVertexSpace(
304 &flushInfo.fVertexBuffer,
305 &flushInfo.fVertexOffset);
307 if (!vertices || !flushInfo.fVertexBuffer) {
308 SkDebugf(
"Could not allocate vertices\n");
314 if (!resetVertexBuffer()) {
318 for (
const Geometry* geo = fHead; geo !=
nullptr; geo = geo->
fNext) {
320 SkASSERTF((
int) subRun.vertexStride(geo->fDrawMatrix) == vertexStride,
321 "subRun stride: %d vertex buffer stride: %d\n",
322 (
int)subRun.vertexStride(geo->fDrawMatrix), vertexStride);
332 for (
int subRunCursor = 0; subRunCursor < subRunEnd;) {
335 int regenEnd = subRunCursor + std::min(subRunEnd - subRunCursor, quadEnd - quadCursor);
343 geo->fillVertexData(vertices + quadCursor * quadSize, subRunCursor, glyphsRegenerated);
345 subRunCursor += glyphsRegenerated;
346 quadCursor += glyphsRegenerated;
347 allGlyphsCursor += glyphsRegenerated;
348 flushInfo.fGlyphsToFlush += glyphsRegenerated;
350 if (quadCursor == quadEnd || subRunCursor < subRunEnd) {
353 if (subRunCursor < subRunEnd) {
356 this->createDrawForGeneratedGlyphs(
target, &flushInfo);
357 if (quadCursor == quadEnd && allGlyphsCursor < allGlyphsEnd) {
360 if(!resetVertexBuffer()) {
371 std::move(fProcessors),
379 FlushInfo* flushInfo)
const {
380 if (!flushInfo->fGlyphsToFlush) {
384 auto atlasManager =
target->atlasManager();
389 unsigned int numActiveViews;
390 const GrSurfaceProxyView* views = atlasManager->getViews(maskFormat, &numActiveViews);
393 if (!views || 0 == numActiveViews) {
400 flushInfo->fPrimProcProxies[i] = views[i].
proxy();
403 target->sampledProxyArray()->push_back(views[i].proxy());
405 for (
int d = 0;
d < flushInfo->fNumDraws; ++
d) {
406 flushInfo->fPrimProcProxies[i]->
ref();
409#if !defined(SK_DISABLE_SDF_TEXT)
410 if (this->usesDistanceFields()) {
413 views, numActiveViews, GrSamplerState::Filter::kLinear);
416 views, numActiveViews, GrSamplerState::Filter::kLinear);
421 auto filter = fNeedsGlyphTransform ? GrSamplerState::Filter::kLinear
422 : GrSamplerState::Filter::kNearest;
426 int maxGlyphsPerDraw =
static_cast<int>(flushInfo->fIndexBuffer->size() /
sizeof(uint16_t) / 6);
430 flushInfo->fVertexOffset);
431 target->recordDraw(flushInfo->fGeometryProcessor, mesh, 1, flushInfo->fPrimProcProxies,
434 flushInfo->fGlyphsToFlush = 0;
435 ++flushInfo->fNumDraws;
441 if (fDFGPFlags != that->fDFGPFlags ||
442 fMaskType != that->fMaskType ||
443 fUsesLocalCoords != that->fUsesLocalCoords ||
444 fNeedsGlyphTransform != that->fNeedsGlyphTransform ||
445 fHasPerspective != that->fHasPerspective ||
446 fUseGammaCorrectDistanceTable != that->fUseGammaCorrectDistanceTable) {
451 if (fProcessors != that->fProcessors) {
455 if (fUsesLocalCoords) {
459 const SkMatrix& thatFirstMatrix = that->fHead->fDrawMatrix;
465#if !defined(SK_DISABLE_SDF_TEXT)
466 if (this->usesDistanceFields()) {
467 SkASSERT(that->usesDistanceFields());
468 if (fLuminanceColor != that->fLuminanceColor) {
475 fHead->
fColor != that->fHead->fColor) {
481 fNumGlyphs += that->fNumGlyphs;
484 this->addGeometry(that->fHead);
485 that->fHead =
nullptr;
489#if !defined(SK_DISABLE_SDF_TEXT)
495 unsigned int numActiveViews)
const {
496 static constexpr int kDistanceAdjustLumShift = 5;
501 float redCorrection = dfAdjustTable->getAdjustment(
502 SkColorGetR(fLuminanceColor) >> kDistanceAdjustLumShift,
503 fUseGammaCorrectDistanceTable);
504 float greenCorrection = dfAdjustTable->getAdjustment(
505 SkColorGetG(fLuminanceColor) >> kDistanceAdjustLumShift,
506 fUseGammaCorrectDistanceTable);
507 float blueCorrection = dfAdjustTable->getAdjustment(
508 SkColorGetB(fLuminanceColor) >> kDistanceAdjustLumShift,
509 fUseGammaCorrectDistanceTable);
512 redCorrection, greenCorrection, blueCorrection);
514 GrSamplerState::Filter::kLinear, widthAdjust,
515 fDFGPFlags, localMatrix);
517#ifdef SK_GAMMA_APPLY_TO_A8
518 float correction = 0;
522 correction = dfAdjustTable->getAdjustment(
lum >> kDistanceAdjustLumShift,
523 fUseGammaCorrectDistanceTable);
526 GrSamplerState::Filter::kLinear, correction,
527 fDFGPFlags, localMatrix);
530 GrSamplerState::Filter::kLinear, fDFGPFlags,
GrProcessorAnalysisCoverage
std::function< void(GrSurfaceProxy *, skgpu::Mipmapped)> GrVisitProxyFunc
#define SkASSERTF(cond, fmt,...)
#define SkColorGetR(color)
#define SkColorGetG(color)
#define SkColorGetB(color)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static bool ok(int result)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
#define INHERITED(method,...)
#define ATRACE_ANDROID_FRAMEWORK_ALWAYS(fmt,...)
#define SK_GAMMA_EXPONENT
Type::kYUV Type::kRGBA() int(0.7 *637)
const GrSurfaceProxyView * getViews(skgpu::MaskFormat format, unsigned int *numActiveProxies)
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 constexpr size_t kDefaultBufferSize
sk_sp< GrColorSpaceXform > refColorSpaceXformFromSRGB() const
static GrGeometryProcessor * Make(SkArenaAlloc *arena, const GrShaderCaps &caps, const GrSurfaceProxyView *views, int numActiveViews, GrSamplerState params, uint32_t flags, const SkMatrix &localMatrixIfUsesLocalCoords)
static constexpr int kMaxTextures
static GrGeometryProcessor * Make(SkArenaAlloc *arena, const GrShaderCaps &caps, const GrSurfaceProxyView *views, int numActiveViews, GrSamplerState params, DistanceAdjust distanceAdjust, uint32_t flags, const SkMatrix &localMatrixIfUsesLocalCoords)
static constexpr int kMaxTextures
int numTextureSamplers() const
void executeDrawsAndUploadsForMeshDrawOp(const GrOp *op, const SkRect &chainBounds, const GrPipeline *, const GrUserStencilSettings *)
void setBounds(const SkRect &newBounds, HasAABloat aabloat, IsHairline zeroArea)
void visitProxies(const GrVisitProxyFunc &) const
Analysis finalize(const GrProcessorAnalysisColor &, const GrProcessorAnalysisCoverage, const GrAppliedClip *, const GrUserStencilSettings *, const GrCaps &, GrClampType, SkPMColor4f *inputColorOverride)
static const GrPipeline * CreatePipeline(const GrCaps *, SkArenaAlloc *, skgpu::Swizzle writeViewSwizzle, GrAppliedClip &&, const GrDstProxyView &, GrProcessorSet &&, GrPipeline::InputFlags pipelineFlags)
GrSurfaceProxy * proxy() const
static U8CPU computeLuminance(SkScalar gamma, SkColor c)
static bool CheapEqual(const SkMatrix &a, const SkMatrix &b)
bool invert(SkMatrix *inverse) const
static const SkMatrix & I()
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
CombineResult onCombineIfPossible(GrOp *t, SkArenaAlloc *, const GrCaps &caps) override
void onPrepareDraws(GrMeshDrawTarget *) override
GrProcessorSet::Analysis finalize(const GrCaps &, const GrAppliedClip *, GrClampType) override
FixedFunctionFlags fixedFunctionFlags() const override
void visitProxies(const GrVisitProxyFunc &) const override
void onExecute(GrOpFlushState *, const SkRect &chainBounds) override
@ kGrayscaleDistanceField
virtual std::tuple< bool, int > regenerateAtlas(int begin, int end, RegenerateAtlasDelegate) const =0
virtual int glyphCount() const =0
static const DistanceFieldAdjustTable * Get()
static const char * begin(const StringSlice &s)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
static float lum(float r, float g, float b)
static constexpr int kVerticesPerGlyph
static constexpr int kIndicesPerGlyph
static thread_local void * gCache
static DistanceAdjust Make(SkScalar r, SkScalar g, SkScalar b)
static const GrUserStencilSettings & kUnused
uint32_t toBytes_RGBA() const
static Geometry * Make(const sktext::gpu::AtlasSubRun &subRun, const SkMatrix &drawMatrix, SkPoint drawOrigin, SkIRect clipRect, sk_sp< SkRefCnt > &&supportData, const SkPMColor4f &color, SkArenaAlloc *alloc)
void fillVertexData(void *dst, int offset, int count) const
const SkMatrix fDrawMatrix
const sktext::gpu::AtlasSubRun & fSubRun
const SkPoint fDrawOrigin