Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Member Functions | Friends | List of all members
skgpu::ganesh::AtlasTextOp Class Referencefinal

#include <AtlasTextOp.h>

Inheritance diagram for skgpu::ganesh::AtlasTextOp:
GrMeshDrawOp GrDrawOp GrOp SkNoncopyable

Classes

struct  Geometry
 

Public Types

enum class  MaskType : uint32_t {
  kGrayscaleCoverage , kLCDCoverage , kColorBitmap , kAliasedDistanceField ,
  kGrayscaleDistanceField , kLCDDistanceField , kLCDBGRDistanceField , kLast = kLCDBGRDistanceField
}
 
- Public Types inherited from GrDrawOp
enum class  ClipResult { kFail , kClippedGeometrically , kClippedInShader , kClippedOut }
 
- Public Types inherited from GrOp
enum class  CombineResult { kMerged , kMayChain , kCannotCombine }
 
enum class  HasAABloat : bool { kNo = false , kYes = true }
 
enum class  IsHairline : bool { kNo = false , kYes = true }
 
using Owner = std::unique_ptr< GrOp >
 

Public Member Functions

DEFINE_OP_CLASS_ID ~AtlasTextOp () override
 
void * operator new (size_t s)
 
void operator delete (void *b) noexcept
 
const char * name () const override
 
void visitProxies (const GrVisitProxyFunc &) const override
 
FixedFunctionFlags fixedFunctionFlags () const override
 
GrProcessorSet::Analysis finalize (const GrCaps &, const GrAppliedClip *, GrClampType) override
 
- Public Member Functions inherited from GrDrawOp
 GrDrawOp (uint32_t classID)
 
virtual bool usesMSAA () const
 
virtual ClipResult clipToShape (skgpu::ganesh::SurfaceDrawContext *, SkClipOp, const SkMatrix &, const GrShape &, GrAA)
 
virtual bool usesStencil () const
 
- Public Member Functions inherited from GrOp
virtual ~GrOp ()=default
 
CombineResult combineIfPossible (GrOp *that, SkArenaAlloc *alloc, const GrCaps &caps)
 
const SkRectbounds () const
 
void setClippedBounds (const SkRect &clippedBounds)
 
bool hasAABloat () const
 
bool hasZeroArea () const
 
void operator delete (void *p)
 
template<typename T >
const Tcast () const
 
template<typename T >
Tcast ()
 
uint32_t classID () const
 
uint32_t uniqueID () const
 
void prePrepare (GrRecordingContext *context, const GrSurfaceProxyView &dstView, GrAppliedClip *clip, const GrDstProxyView &dstProxyView, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp)
 
void prepare (GrOpFlushState *state)
 
void execute (GrOpFlushState *state, const SkRect &chainBounds)
 
void chainConcat (GrOp::Owner)
 
bool isChainHead () const
 
bool isChainTail () const
 
GrOpnextInChain () const
 
GrOpprevInChain () const
 
GrOp::Owner cutChain ()
 
void setBounds (const SkRect &newBounds, HasAABloat aabloat, IsHairline zeroArea)
 
void setTransformedBounds (const SkRect &srcBounds, const SkMatrix &m, HasAABloat aabloat, IsHairline zeroArea)
 
void makeFullScreen (GrSurfaceProxy *proxy)
 

Static Public Member Functions

static void ClearCache ()
 
- Static Public Member Functions inherited from GrMeshDrawOp
static bool CanUpgradeAAOnMerge (GrAAType aa1, GrAAType aa2)
 
- Static Public Member Functions inherited from GrOp
template<typename Op , typename... Args>
static Owner Make (GrRecordingContext *context, Args &&... args)
 
template<typename Op , typename... Args>
static Owner MakeWithProcessorSet (GrRecordingContext *context, const SkPMColor4f &color, GrPaint &&paint, Args &&... args)
 
template<typename Op , typename... Args>
static Owner MakeWithExtraMemory (GrRecordingContext *context, size_t extraSize, Args &&... args)
 
static uint32_t GenOpClassID ()
 

Static Public Attributes

static constexpr int kMaskTypeCount = static_cast<int>(MaskType::kLast) + 1
 

Private Member Functions

GrProgramInfoprogramInfo () override
 
void onCreateProgramInfo (const GrCaps *, SkArenaAlloc *, const GrSurfaceProxyView &writeView, bool usesMSAASurface, GrAppliedClip &&, const GrDstProxyView &, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp) override
 
void onPrePrepareDraws (GrRecordingContext *, const GrSurfaceProxyView &writeView, GrAppliedClip *, const GrDstProxyView &, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp) override
 
void onPrepareDraws (GrMeshDrawTarget *) override
 
void onExecute (GrOpFlushState *, const SkRect &chainBounds) override
 
CombineResult onCombineIfPossible (GrOp *t, SkArenaAlloc *, const GrCaps &caps) override
 

Friends

class GrOp
 

Additional Inherited Members

- Protected Types inherited from GrDrawOp
enum class  FixedFunctionFlags : uint32_t { kNone = 0x0 , kUsesHWAA = 0x1 , kUsesStencil = 0x2 }
 
- Protected Member Functions inherited from GrMeshDrawOp
 GrMeshDrawOp (uint32_t classID)
 
void createProgramInfo (const GrCaps *caps, SkArenaAlloc *arena, const GrSurfaceProxyView &writeView, bool usesMSAASurface, GrAppliedClip &&appliedClip, const GrDstProxyView &dstProxyView, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp)
 
void createProgramInfo (GrMeshDrawTarget *)
 
- Protected Member Functions inherited from GrDrawOp
 GR_DECL_BITFIELD_CLASS_OPS_FRIENDS (FixedFunctionFlags)
 
- Static Protected Member Functions inherited from GrMeshDrawOp
static bool CombinedQuadCountWillOverflow (GrAAType aaType, bool willBeUpgradedToAA, int combinedQuadCount)
 

Detailed Description

Definition at line 52 of file AtlasTextOp.h.

Member Enumeration Documentation

◆ MaskType

enum class skgpu::ganesh::AtlasTextOp::MaskType : uint32_t
strong
Enumerator
kGrayscaleCoverage 
kLCDCoverage 
kColorBitmap 
kAliasedDistanceField 
kGrayscaleDistanceField 
kLCDDistanceField 
kLCDBGRDistanceField 
kLast 

Definition at line 121 of file AtlasTextOp.h.

Constructor & Destructor Documentation

◆ ~AtlasTextOp()

DEFINE_OP_CLASS_ID skgpu::ganesh::AtlasTextOp::~AtlasTextOp ( )
inlineoverride

Definition at line 56 of file AtlasTextOp.h.

56 {
57 for (const Geometry* g = fHead; g != nullptr;) {
58 const Geometry* next = g->fNext;
59 g->~Geometry();
60 g = next;
61 }
62 }
static float next(float f)

Member Function Documentation

◆ ClearCache()

void skgpu::ganesh::AtlasTextOp::ClearCache ( )
static

Definition at line 76 of file AtlasTextOp.cpp.

76 {
77 ::operator delete(gCache);
78 gCache = nullptr;
79}
static thread_local void * gCache

◆ finalize()

GrProcessorSet::Analysis skgpu::ganesh::AtlasTextOp::finalize ( const GrCaps ,
const GrAppliedClip ,
GrClampType   
)
overridevirtual

This is called after the GrAppliedClip has been computed and just prior to recording the op or combining it with a previously recorded op. The op should convert any proxies or resources it owns to "pending io" status so that resource allocation can be more optimal. Additionally, at this time the op must report whether a copy of the destination (or destination texture itself) needs to be provided to the GrXferProcessor when this op executes.

Implements GrDrawOp.

Definition at line 182 of file AtlasTextOp.cpp.

184 {
187 if (this->maskType() == MaskType::kColorBitmap) {
188 color.setToUnknown();
189 } else {
190 // finalize() is called before any merging is done, so at this point there's at most one
191 // Geometry with a color. Later, for non-bitmap ops, we may have mixed colors.
192 color.setToConstant(fHead->fColor);
193 }
194
195 switch (this->maskType()) {
197#if !defined(SK_DISABLE_SDF_TEXT)
200#endif
202 break;
204#if !defined(SK_DISABLE_SDF_TEXT)
207#endif
209 break;
212 break;
213 }
214
215 auto analysis = fProcessors.finalize(color, coverage, clip, &GrUserStencilSettings::kUnused,
216 caps, clampType, &fHead->fColor);
217 // TODO(michaelludwig): Once processor analysis can be done external to op creation/finalization
218 // the atlas op metadata can be fully const. This is okay for now since finalize() happens
219 // before the op is merged, so during combineIfPossible, metadata is effectively const.
220 fUsesLocalCoords = analysis.usesLocalCoords();
221 return analysis;
222}
GrProcessorAnalysisCoverage
SkColor4f color
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
Analysis finalize(const GrProcessorAnalysisColor &, const GrProcessorAnalysisCoverage, const GrAppliedClip *, const GrUserStencilSettings *, const GrCaps &, GrClampType, SkPMColor4f *inputColorOverride)
static const GrUserStencilSettings & kUnused

◆ fixedFunctionFlags()

GrDrawOp::FixedFunctionFlags skgpu::ganesh::AtlasTextOp::fixedFunctionFlags ( ) const
overridevirtual

Reimplemented from GrDrawOp.

Definition at line 178 of file AtlasTextOp.cpp.

◆ name()

const char * skgpu::ganesh::AtlasTextOp::name ( ) const
inlineoverridevirtual

Implements GrOp.

Definition at line 113 of file AtlasTextOp.h.

113{ return "AtlasTextOp"; }

◆ onCombineIfPossible()

GrOp::CombineResult skgpu::ganesh::AtlasTextOp::onCombineIfPossible ( GrOp t,
SkArenaAlloc ,
const GrCaps caps 
)
overrideprivatevirtual

Reimplemented from GrOp.

Definition at line 438 of file AtlasTextOp.cpp.

438 {
439 auto that = t->cast<AtlasTextOp>();
440
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) {
447 // All flags must match for an op to be combined
449 }
450
451 if (fProcessors != that->fProcessors) {
453 }
454
455 if (fUsesLocalCoords) {
456 // If the fragment processors use local coordinates, the GPs compute them using the inverse
457 // of the view matrix stored in a uniform, so all geometries must have the same matrix.
458 const SkMatrix& thisFirstMatrix = fHead->fDrawMatrix;
459 const SkMatrix& thatFirstMatrix = that->fHead->fDrawMatrix;
460 if (!SkMatrixPriv::CheapEqual(thisFirstMatrix, thatFirstMatrix)) {
462 }
463 }
464
465#if !defined(SK_DISABLE_SDF_TEXT)
466 if (this->usesDistanceFields()) {
467 SkASSERT(that->usesDistanceFields());
468 if (fLuminanceColor != that->fLuminanceColor) {
470 }
471 } else
472#endif
473 {
474 if (this->maskType() == MaskType::kColorBitmap &&
475 fHead->fColor != that->fHead->fColor) {
476 // This ensures all merged bitmap color text ops have a constant color
478 }
479 }
480
481 fNumGlyphs += that->fNumGlyphs;
482
483 // After concat, that's geometry list is emptied so it will not unref the blobs when destructed
484 this->addGeometry(that->fHead);
485 that->fHead = nullptr;
487}
#define SkASSERT(cond)
Definition SkAssert.h:116
const T & cast() const
Definition GrOp.h:148
static bool CheapEqual(const SkMatrix &a, const SkMatrix &b)

◆ onCreateProgramInfo()

void skgpu::ganesh::AtlasTextOp::onCreateProgramInfo ( const GrCaps ,
SkArenaAlloc ,
const GrSurfaceProxyView writeView,
bool  usesMSAASurface,
GrAppliedClip &&  ,
const GrDstProxyView ,
GrXferBarrierFlags  renderPassXferBarriers,
GrLoadOp  colorLoadOp 
)
inlineoverrideprivatevirtual

Implements GrMeshDrawOp.

Definition at line 182 of file AtlasTextOp.h.

189 {
190 // We cannot surface the AtlasTextOp's programInfo at record time. As currently
191 // implemented, the GP is modified at flush time based on the number of pages in the
192 // atlas.
193 }

◆ onExecute()

void skgpu::ganesh::AtlasTextOp::onExecute ( GrOpFlushState flushState,
const SkRect chainBounds 
)
overrideprivatevirtual

Implements GrOp.

Definition at line 369 of file AtlasTextOp.cpp.

369 {
370 auto pipeline = GrSimpleMeshDrawOpHelper::CreatePipeline(flushState,
371 std::move(fProcessors),
373
374 flushState->executeDrawsAndUploadsForMeshDrawOp(this, chainBounds, pipeline,
376}
void executeDrawsAndUploadsForMeshDrawOp(const GrOp *op, const SkRect &chainBounds, const GrPipeline *, const GrUserStencilSettings *)
static const GrPipeline * CreatePipeline(const GrCaps *, SkArenaAlloc *, skgpu::Swizzle writeViewSwizzle, GrAppliedClip &&, const GrDstProxyView &, GrProcessorSet &&, GrPipeline::InputFlags pipelineFlags)

◆ onPrepareDraws()

void skgpu::ganesh::AtlasTextOp::onPrepareDraws ( GrMeshDrawTarget target)
overrideprivatevirtual

Implements GrMeshDrawOp.

Definition at line 224 of file AtlasTextOp.cpp.

224 {
225 auto resourceProvider = target->resourceProvider();
226
227 // If we need local coordinates, compute an inverse view matrix. If this is solid color, the
228 // processor analysis will not require local coords and the GPs will skip local coords when
229 // the matrix is identity. When the shaders require local coords, combineIfPossible requires all
230 // all geometries to have same draw matrix.
231 SkMatrix localMatrix = SkMatrix::I();
232 if (fUsesLocalCoords && !fHead->fDrawMatrix.invert(&localMatrix)) {
233 return;
234 }
235
236 GrAtlasManager* atlasManager = target->atlasManager();
237
238 MaskFormat maskFormat = this->maskFormat();
239
240 unsigned int numActiveViews;
241 const GrSurfaceProxyView* views = atlasManager->getViews(maskFormat, &numActiveViews);
242 if (!views) {
243 SkDebugf("Could not allocate backing texture for atlas\n");
244 return;
245 }
246 SkASSERT(views[0].proxy());
247
248 static constexpr int kMaxTextures = GrBitmapTextGeoProc::kMaxTextures;
249#if !defined(SK_DISABLE_SDF_TEXT)
250 static_assert(GrDistanceFieldA8TextGeoProc::kMaxTextures == kMaxTextures);
251 static_assert(GrDistanceFieldLCDTextGeoProc::kMaxTextures == kMaxTextures);
252#endif
253
254 auto primProcProxies = target->allocPrimProcProxyPtrs(kMaxTextures);
255 for (unsigned i = 0; i < numActiveViews; ++i) {
256 primProcProxies[i] = views[i].proxy();
257 // This op does not know its atlas proxies when it is added to a OpsTasks, so the proxies
258 // don't get added during the visitProxies call. Thus we add them here.
259 target->sampledProxyArray()->push_back(views[i].proxy());
260 }
261
262 FlushInfo flushInfo;
263 flushInfo.fPrimProcProxies = primProcProxies;
264 flushInfo.fIndexBuffer = resourceProvider->refNonAAQuadIndexBuffer();
265
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);
271 } else
272#endif
273 {
274 auto filter = fNeedsGlyphTransform ? GrSamplerState::Filter::kLinear
275 : GrSamplerState::Filter::kNearest;
276 // Bitmap text uses a single color, combineIfPossible ensures all geometries have the same
277 // color, so we can use the first's without worry.
278 flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
279 target->allocator(), *target->caps().shaderCaps(), fHead->fColor,
280 /*wideColor=*/false, fColorSpaceXform, views, numActiveViews, filter,
281 maskFormat, localMatrix, fHasPerspective);
282 }
283
284 const int vertexStride = (int)flushInfo.fGeometryProcessor->vertexStride();
285
286 // Ensure we don't request an insanely large contiguous vertex allocation.
287 static const int kMaxVertexBytes = GrBufferAllocPool::kDefaultBufferSize;
288 const int quadSize = vertexStride * kVerticesPerGlyph;
289 const int maxQuadsPerBuffer = kMaxVertexBytes / quadSize;
290
291 int allGlyphsCursor = 0;
292 const int allGlyphsEnd = fNumGlyphs;
293 int quadCursor;
294 int quadEnd;
295 char* vertices;
296
297 auto resetVertexBuffer = [&] {
298 quadCursor = 0;
299 quadEnd = std::min(maxQuadsPerBuffer, allGlyphsEnd - allGlyphsCursor);
300
301 vertices = (char*)target->makeVertexSpace(
302 vertexStride,
303 kVerticesPerGlyph * quadEnd,
304 &flushInfo.fVertexBuffer,
305 &flushInfo.fVertexOffset);
306
307 if (!vertices || !flushInfo.fVertexBuffer) {
308 SkDebugf("Could not allocate vertices\n");
309 return false;
310 }
311 return true;
312 };
313
314 if (!resetVertexBuffer()) {
315 return;
316 }
317
318 for (const Geometry* geo = fHead; geo != nullptr; geo = geo->fNext) {
319 const sktext::gpu::AtlasSubRun& subRun = geo->fSubRun;
320 SkASSERTF((int) subRun.vertexStride(geo->fDrawMatrix) == vertexStride,
321 "subRun stride: %d vertex buffer stride: %d\n",
322 (int)subRun.vertexStride(geo->fDrawMatrix), vertexStride);
323
324 const int subRunEnd = subRun.glyphCount();
325 auto regenerateDelegate = [&](sktext::gpu::GlyphVector* glyphs,
326 int begin,
327 int end,
328 skgpu::MaskFormat maskFormat,
329 int padding) {
330 return glyphs->regenerateAtlasForGanesh(begin, end, maskFormat, padding, target);
331 };
332 for (int subRunCursor = 0; subRunCursor < subRunEnd;) {
333 // Regenerate the atlas for the remainder of the glyphs in the run, or the remainder
334 // of the glyphs to fill the vertex buffer.
335 int regenEnd = subRunCursor + std::min(subRunEnd - subRunCursor, quadEnd - quadCursor);
336 auto[ok, glyphsRegenerated] = subRun.regenerateAtlas(subRunCursor, regenEnd,
337 regenerateDelegate);
338 // There was a problem allocating the glyph in the atlas. Bail.
339 if (!ok) {
340 return;
341 }
342
343 geo->fillVertexData(vertices + quadCursor * quadSize, subRunCursor, glyphsRegenerated);
344
345 subRunCursor += glyphsRegenerated;
346 quadCursor += glyphsRegenerated;
347 allGlyphsCursor += glyphsRegenerated;
348 flushInfo.fGlyphsToFlush += glyphsRegenerated;
349
350 if (quadCursor == quadEnd || subRunCursor < subRunEnd) {
351 // Flush if not all the glyphs are drawn because either the quad buffer is full or
352 // the atlas is out of space.
353 if (subRunCursor < subRunEnd) {
355 }
356 this->createDrawForGeneratedGlyphs(target, &flushInfo);
357 if (quadCursor == quadEnd && allGlyphsCursor < allGlyphsEnd) {
358 // If the vertex buffer is full and there are still glyphs to draw then
359 // get a new buffer.
360 if(!resetVertexBuffer()) {
361 return;
362 }
363 }
364 }
365 }
366 }
367}
uint16_t glyphs[5]
#define SkASSERTF(cond, fmt,...)
Definition SkAssert.h:117
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static bool ok(int result)
#define ATRACE_ANDROID_FRAMEWORK_ALWAYS(fmt,...)
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
GrSurfaceProxy * proxy() const
bool invert(SkMatrix *inverse) const
Definition SkMatrix.h:1206
static const SkMatrix & I()
virtual std::tuple< bool, int > regenerateAtlas(int begin, int end, RegenerateAtlasDelegate) const =0
virtual int glyphCount() const =0
static const char * begin(const StringSlice &s)
Definition editor.cpp:252
glong glong end
uint32_t * target
static constexpr int kVerticesPerGlyph

◆ onPrePrepareDraws()

void skgpu::ganesh::AtlasTextOp::onPrePrepareDraws ( GrRecordingContext ,
const GrSurfaceProxyView writeView,
GrAppliedClip ,
const GrDstProxyView ,
GrXferBarrierFlags  renderPassXferBarriers,
GrLoadOp  colorLoadOp 
)
inlineoverrideprivatevirtual

Reimplemented from GrMeshDrawOp.

Definition at line 195 of file AtlasTextOp.h.

200 {
201 // TODO [PI]: implement
202 }

◆ operator delete()

void skgpu::ganesh::AtlasTextOp::operator delete ( void *  b)
noexcept

Definition at line 68 of file AtlasTextOp.cpp.

68 {
69 if (gCache == nullptr) {
70 gCache = bytes;
71 return;
72 }
73 ::operator delete(bytes);
74}

◆ operator new()

void * skgpu::ganesh::AtlasTextOp::operator new ( size_t  s)

Definition at line 60 of file AtlasTextOp.cpp.

60 {
61 if (gCache != nullptr) {
62 return std::exchange(gCache, nullptr);
63 }
64
65 return ::operator new(s);
66}
struct MyStruct s

◆ programInfo()

GrProgramInfo * skgpu::ganesh::AtlasTextOp::programInfo ( )
inlineoverrideprivatevirtual

Implements GrMeshDrawOp.

Definition at line 169 of file AtlasTextOp.h.

169 {
170 // TODO [PI]: implement
171 return nullptr;
172 }

◆ visitProxies()

void skgpu::ganesh::AtlasTextOp::visitProxies ( const GrVisitProxyFunc func) const
overridevirtual

Reimplemented from GrOp.

Definition at line 157 of file AtlasTextOp.cpp.

157 {
158 fProcessors.visitProxies(func);
159}
void visitProxies(const GrVisitProxyFunc &) const

Friends And Related Symbol Documentation

◆ GrOp

friend class GrOp
friend

Definition at line 139 of file AtlasTextOp.h.

Member Data Documentation

◆ kMaskTypeCount

constexpr int skgpu::ganesh::AtlasTextOp::kMaskTypeCount = static_cast<int>(MaskType::kLast) + 1
inlinestaticconstexpr

Definition at line 136 of file AtlasTextOp.h.


The documentation for this class was generated from the following files: