move regenerate() from VertexRegenerator to SubRun
Delete VertexRegenerator.
Change-Id: If48fb3664f8b0185d1e4c2c439f1e378641a669d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302272
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Herb Derby <herb@google.com>
diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp
index 71c4c60..3e016ca 100644
--- a/src/gpu/ops/GrAtlasTextOp.cpp
+++ b/src/gpu/ops/GrAtlasTextOp.cpp
@@ -216,8 +216,6 @@
subRun->prepareGrGlyphs(target->strikeCache());
// TODO4F: Preserve float colors
- GrTextBlob::VertexRegenerator regenerator(resourceProvider, subRun,
- target->deferredUploadTarget(), atlasManager);
// Where the subRun begins and ends relative to totalGlyphsRegened.
int subRunBegin = totalGlyphsRegened;
@@ -230,7 +228,7 @@
int drawBegin = totalGlyphsRegened - subRunBegin;
// drawEnd is either the end of the subRun or the end of the current quad buffer.
int drawEnd = std::min(subRunEnd, quadBufferEnd) - subRunBegin;
- auto[ok, glyphsRegenerated] = regenerator.regenerate(drawBegin, drawEnd);
+ auto[ok, glyphsRegenerated] = subRun->regenerateAtlas(drawBegin, drawEnd, target);
// There was a problem allocating the glyph in the atlas. Bail.
if (!ok) {
diff --git a/src/gpu/text/GrTextBlob.cpp b/src/gpu/text/GrTextBlob.cpp
index 9c2d92a..72c32a0 100644
--- a/src/gpu/text/GrTextBlob.cpp
+++ b/src/gpu/text/GrTextBlob.cpp
@@ -258,6 +258,68 @@
}
}
+std::tuple<bool, int> GrTextBlob::SubRun::regenerateAtlas(
+ int begin, int end, GrMeshDrawOp::Target *target) {
+ GrAtlasManager* atlasManager = target->atlasManager();
+ GrDeferredUploadTarget* uploadTarget = target->deferredUploadTarget();
+
+ uint64_t currentAtlasGen = atlasManager->atlasGeneration(this->maskFormat());
+
+ if (fAtlasGeneration != currentAtlasGen) {
+ // Calculate the texture coordinates for the vertexes during first use (fAtlasGeneration
+ // is set to kInvalidAtlasGeneration) or the atlas has changed in subsequent calls..
+ this->resetBulkUseToken();
+
+ SkASSERT(this->isPrepared());
+
+ SkBulkGlyphMetricsAndImages metricsAndImages{this->strikeSpec()};
+
+ // Update the atlas information in the GrStrike.
+ auto tokenTracker = uploadTarget->tokenTracker();
+ auto vertexData = this->vertexData().subspan(begin, end - begin);
+ int glyphsPlacedInAtlas = 0;
+ bool success = true;
+ for (auto [glyph, pos, rect] : vertexData) {
+ GrGlyph* grGlyph = glyph.grGlyph;
+ SkASSERT(grGlyph != nullptr);
+
+ if (!atlasManager->hasGlyph(this->maskFormat(), grGlyph)) {
+ const SkGlyph& skGlyph = *metricsAndImages.glyph(grGlyph->fPackedID);
+ auto code = atlasManager->addGlyphToAtlas(
+ skGlyph, this->atlasPadding(), grGlyph,
+ target->resourceProvider(), uploadTarget);
+ if (code != GrDrawOpAtlas::ErrorCode::kSucceeded) {
+ success = code != GrDrawOpAtlas::ErrorCode::kError;
+ break;
+ }
+ }
+ atlasManager->addGlyphToBulkAndSetUseToken(
+ this->bulkUseToken(), this->maskFormat(), grGlyph,
+ tokenTracker->nextDrawToken());
+ glyphsPlacedInAtlas++;
+ }
+
+ // Update atlas generation if there are no more glyphs to put in the atlas.
+ if (success && begin + glyphsPlacedInAtlas == this->glyphCount()) {
+ // Need to get the freshest value of the atlas' generation because
+ // updateTextureCoordinates may have changed it.
+ fAtlasGeneration = atlasManager->atlasGeneration(this->maskFormat());
+ }
+
+ return {success, glyphsPlacedInAtlas};
+ } else {
+ // The atlas hasn't changed, so our texture coordinates are still valid.
+ if (end == this->glyphCount()) {
+ // The atlas hasn't changed and the texture coordinates are all still valid. Update
+ // all the plots used to the new use token.
+ atlasManager->setUseTokenBulk(*this->bulkUseToken(),
+ uploadTarget->tokenTracker()->nextDrawToken(),
+ this->maskFormat());
+ }
+ return {true, end - begin};
+ }
+}
+
void GrTextBlob::SubRun::resetBulkUseToken() { fBulkUseToken.reset(); }
GrDrawOpAtlas::BulkUseTokenUpdater* GrTextBlob::SubRun::bulkUseToken() { return &fBulkUseToken; }
@@ -835,72 +897,3 @@
}
auto GrTextBlob::firstSubRun() const -> SubRun* { return fSubRunList.head(); }
-
-// -- GrTextBlob::VertexRegenerator ----------------------------------------------------------------
-GrTextBlob::VertexRegenerator::VertexRegenerator(GrResourceProvider* resourceProvider,
- GrTextBlob::SubRun* subRun,
- GrDeferredUploadTarget* uploadTarget,
- GrAtlasManager* fullAtlasManager)
- : fResourceProvider(resourceProvider)
- , fUploadTarget(uploadTarget)
- , fFullAtlasManager(fullAtlasManager)
- , fSubRun(subRun) { }
-
-
-std::tuple<bool, int> GrTextBlob::VertexRegenerator::regenerate(int begin, int end) {
- uint64_t currentAtlasGen = fFullAtlasManager->atlasGeneration(fSubRun->maskFormat());
-
- if (fSubRun->fAtlasGeneration != currentAtlasGen) {
- // Calculate the texture coordinates for the vertexes during first use (fAtlasGeneration
- // is set to kInvalidAtlasGeneration) or the atlas has changed in subsequent calls..
- fSubRun->resetBulkUseToken();
-
- SkASSERT(fSubRun->isPrepared());
-
- SkBulkGlyphMetricsAndImages metricsAndImages{fSubRun->strikeSpec()};
-
- // Update the atlas information in the GrStrike.
- auto tokenTracker = fUploadTarget->tokenTracker();
- auto vertexData = fSubRun->vertexData().subspan(begin, end - begin);
- int glyphsPlacedInAtlas = 0;
- bool success = true;
- for (auto [glyph, pos, rect] : vertexData) {
- GrGlyph* grGlyph = glyph.grGlyph;
- SkASSERT(grGlyph != nullptr);
-
- if (!fFullAtlasManager->hasGlyph(fSubRun->maskFormat(), grGlyph)) {
- const SkGlyph& skGlyph = *metricsAndImages.glyph(grGlyph->fPackedID);
- auto code = fFullAtlasManager->addGlyphToAtlas(
- skGlyph, fSubRun->atlasPadding(), grGlyph,
- fResourceProvider, fUploadTarget);
- if (code != GrDrawOpAtlas::ErrorCode::kSucceeded) {
- success = code != GrDrawOpAtlas::ErrorCode::kError;
- break;
- }
- }
- fFullAtlasManager->addGlyphToBulkAndSetUseToken(
- fSubRun->bulkUseToken(), fSubRun->maskFormat(), grGlyph,
- tokenTracker->nextDrawToken());
- glyphsPlacedInAtlas++;
- }
-
- // Update atlas generation if there are no more glyphs to put in the atlas.
- if (success && begin + glyphsPlacedInAtlas == fSubRun->glyphCount()) {
- // Need to get the freshest value of the atlas' generation because
- // updateTextureCoordinates may have changed it.
- fSubRun->fAtlasGeneration = fFullAtlasManager->atlasGeneration(fSubRun->maskFormat());
- }
-
- return {success, glyphsPlacedInAtlas};
- } else {
- // The atlas hasn't changed, so our texture coordinates are still valid.
- if (end == fSubRun->glyphCount()) {
- // The atlas hasn't changed and the texture coordinates are all still valid. Update
- // all the plots used to the new use token.
- fFullAtlasManager->setUseTokenBulk(*fSubRun->bulkUseToken(),
- fUploadTarget->tokenTracker()->nextDrawToken(),
- fSubRun->maskFormat());
- }
- return {true, end - begin};
- }
-}
diff --git a/src/gpu/text/GrTextBlob.h b/src/gpu/text/GrTextBlob.h
index 56db62a..7dab11f 100644
--- a/src/gpu/text/GrTextBlob.h
+++ b/src/gpu/text/GrTextBlob.h
@@ -21,6 +21,7 @@
#include "src/core/SkTLazy.h"
#include "src/gpu/GrColor.h"
#include "src/gpu/GrDrawOpAtlas.h"
+#include "src/gpu/ops/GrMeshDrawOp.h"
class GrAtlasManager;
class GrAtlasTextOp;
@@ -51,15 +52,10 @@
// * current Matrix|Origin - describes the matrix and origin that are currently in the SubRun's
// vertex data.
//
-// When handling repeated drawing using the same GrTextBlob initial data are compared to drawing
-// data to see if this blob can service this drawing. If it can, but small changes are needed to
-// the vertex data, the current data of the SubRuns is adjusted to conform to the drawing data
-// from the op using the VertexRegenerator.
//
class GrTextBlob final : public SkNVRefCnt<GrTextBlob>, public SkGlyphRunPainterInterface {
public:
class SubRun;
- class VertexRegenerator;
struct Key {
Key();
@@ -197,35 +193,6 @@
SkArenaAlloc fAlloc;
};
-/**
- * Used to produce vertices for a subrun of a blob. The vertices are cached in the blob itself.
- * This is invoked each time a sub run is drawn. It regenerates the vertex data as required either
- * because of changes to the atlas or because of different draw parameters (e.g. color change). In
- * rare cases the draw may have to interrupted and flushed in the middle of the sub run in order to
- * free up atlas space. Thus, this generator is stateful and should be invoked in a loop until the
- * entire sub run has been completed.
- */
-class GrTextBlob::VertexRegenerator {
-public:
- /**
- * Consecutive VertexRegenerators often use the same SkGlyphCache. If the same instance of
- * SkAutoGlyphCache is reused then it can save the cost of multiple detach/attach operations of
- * SkGlyphCache.
- */
- VertexRegenerator(GrResourceProvider*, GrTextBlob::SubRun* subRun,
- GrDeferredUploadTarget*, GrAtlasManager*);
-
- // Return {success, number of glyphs regenerated}
- std::tuple<bool, int> regenerate(int begin, int end);
-
-private:
-
- GrResourceProvider* fResourceProvider;
- GrDeferredUploadTarget* fUploadTarget;
- GrAtlasManager* fFullAtlasManager;
- SubRun* fSubRun;
-};
-
// -- GrTextBlob::SubRun ---------------------------------------------------------------------------
// Hold data to draw the different types of sub run. SubRuns are produced knowing all the
// glyphs that are included in them.
@@ -277,6 +244,8 @@
const SkGlyphRunList& glyphRunList,
GrRenderTargetContext* rtc);
+ std::tuple<bool, int> regenerateAtlas(int begin, int end, GrMeshDrawOp::Target* target);
+
// TODO when this object is more internal, drop the privacy
void resetBulkUseToken();
GrDrawOpAtlas::BulkUseTokenUpdater* bulkUseToken();