Moving GrTextBlob to sktext::gpu

Bug: skia:13118
Change-Id: Id7c92b2e1af9febb3e576c244fcff3aedd27f408
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/542646
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
Jim Van Verth 2022-05-23 11:34:17 -04:00 committed by SkCQ
parent ccf94835ee
commit 3149a7b283
21 changed files with 512 additions and 419 deletions

View File

@ -16,8 +16,8 @@
#include "src/core/SkUtils.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/text/GrTextBlob.h"
#include "src/text/gpu/StrikeCache.h"
#include "src/text/gpu/TextBlob.h"
#include "src/utils/SkTestCanvas.h"
#include "src/utils/SkUTF.h"
@ -56,20 +56,20 @@ class DirectMaskGlyphVertexFillBenchmark : public Benchmark {
SkMatrix drawMatrix = view;
const SkPoint drawOrigin = glyphRunList.origin();
drawMatrix.preTranslate(drawOrigin.x(), drawOrigin.y());
fBlob = GrTextBlob::Make(glyphRunList,
paint,
drawMatrix,
device->strikeDeviceInfo(),
SkStrikeCache::GlobalStrikeCache());
fBlob = sktext::gpu::TextBlob::Make(glyphRunList,
paint,
drawMatrix,
device->strikeDeviceInfo(),
SkStrikeCache::GlobalStrikeCache());
const GrAtlasSubRun* subRun = fBlob->testingOnlyFirstSubRun();
const sktext::gpu::AtlasSubRun* subRun = fBlob->testingOnlyFirstSubRun();
SkASSERT(subRun);
subRun->testingOnly_packedGlyphIDToGlyph(&fCache);
fVertices.reset(new char[subRun->vertexStride(drawMatrix) * subRun->glyphCount() * 4]);
}
void onDraw(int loops, SkCanvas* canvas) override {
const GrAtlasSubRun* subRun = fBlob->testingOnlyFirstSubRun();
const sktext::gpu::AtlasSubRun* subRun = fBlob->testingOnlyFirstSubRun();
SkASSERT(subRun);
SkIRect clip = SkIRect::MakeEmpty();
@ -84,7 +84,7 @@ class DirectMaskGlyphVertexFillBenchmark : public Benchmark {
}
private:
sk_sp<GrTextBlob> fBlob;
sk_sp<sktext::gpu::TextBlob> fBlob;
sktext::gpu::StrikeCache fCache;
std::unique_ptr<char[]> fVertices;
};

View File

@ -324,8 +324,6 @@ skia_gpu_sources = [
# text
"$_src/gpu/ganesh/text/GrAtlasManager.cpp",
"$_src/gpu/ganesh/text/GrAtlasManager.h",
"$_src/gpu/ganesh/text/GrTextBlob.cpp",
"$_src/gpu/ganesh/text/GrTextBlob.h",
"$_src/gpu/ganesh/text/GrTextBlobRedrawCoordinator.cpp",
"$_src/gpu/ganesh/text/GrTextBlobRedrawCoordinator.h",
@ -834,4 +832,6 @@ skia_shared_gpu_sources = [
"$_src/text/gpu/StrikeCache.h",
"$_src/text/gpu/SubRunAllocator.cpp",
"$_src/text/gpu/SubRunAllocator.h",
"$_src/text/gpu/TextBlob.cpp",
"$_src/text/gpu/TextBlob.h",
]

View File

@ -1218,8 +1218,6 @@ BASE_SRCS_ALL = [
"src/gpu/ganesh/tessellate/VertexChunkPatchAllocator.h",
"src/gpu/ganesh/text/GrAtlasManager.cpp",
"src/gpu/ganesh/text/GrAtlasManager.h",
"src/gpu/ganesh/text/GrTextBlob.cpp",
"src/gpu/ganesh/text/GrTextBlob.h",
"src/gpu/ganesh/text/GrTextBlobRedrawCoordinator.cpp",
"src/gpu/ganesh/text/GrTextBlobRedrawCoordinator.h",
"src/gpu/ganesh/v1/ClipStack.cpp",
@ -1656,6 +1654,8 @@ BASE_SRCS_ALL = [
"src/text/gpu/StrikeCache.h",
"src/text/gpu/SubRunAllocator.cpp",
"src/text/gpu/SubRunAllocator.h",
"src/text/gpu/TextBlob.cpp",
"src/text/gpu/TextBlob.h",
"src/utils/SkAnimCodecPlayer.cpp",
"src/utils/SkBase64.cpp",
"src/utils/SkBitSet.h",

View File

@ -5552,8 +5552,8 @@ generated_cc_atom(
"//include/private:SkTHash_hdr",
"//include/private/chromium:SkChromeRemoteGlyphCache_hdr",
"//src/gpu/ganesh:GrDrawOpAtlas_hdr",
"//src/gpu/ganesh/text:GrTextBlob_hdr",
"//src/text/gpu:SDFTControl_hdr",
"//src/text/gpu:TextBlob_hdr",
],
)

View File

@ -34,8 +34,8 @@
#if SK_SUPPORT_GPU
#include "include/gpu/GrContextOptions.h"
#include "src/gpu/ganesh/GrDrawOpAtlas.h"
#include "src/gpu/ganesh/text/GrTextBlob.h"
#include "src/text/gpu/SDFTControl.h"
#include "src/text/gpu/TextBlob.h"
#endif
namespace {

View File

@ -15,8 +15,11 @@
#include "src/core/SkScalerContext.h"
#include "src/core/SkTextBlobPriv.h"
#if SK_SUPPORT_GPU
#if (SK_SUPPORT_GPU || SK_GRAPHITE_ENABLED)
#include "src/text/gpu/SDFTControl.h"
#endif
#if SK_SUPPORT_GPU
class GrColorInfo;
namespace skgpu { namespace v1 { class SurfaceDrawContext; }}
#endif
@ -84,7 +87,7 @@ private:
const SkScalerContextFlags fScalerContextFlags;
};
#if SK_SUPPORT_GPU
#if (SK_SUPPORT_GPU || SK_GRAPHITE_ENABLED)
class SkGlyphRunListPainter {
public:
// A nullptr for process means that the calls to the cache will be performed, but none of the
@ -139,5 +142,5 @@ public:
const SkFont& runFont,
const sktext::gpu::SDFTMatrixRange& matrixRange) = 0;
};
#endif // SK_SUPPORT_GPU
#endif // SK_SUPPORT_GPU || SK_GRAPHITE_ENABLED
#endif // SkGlyphRunPainter_DEFINED

View File

@ -23,6 +23,7 @@ cc_library(
"//src/text/gpu:Slug_src",
"//src/text/gpu:StrikeCache_src",
"//src/text/gpu:SubRunAllocator_src",
"//src/text/gpu:TextBlob_src",
],
)

View File

@ -189,7 +189,6 @@ cc_library(
"//src/gpu/ganesh/tessellate:StrokeTessellator_src",
"//src/gpu/ganesh/text:GrAtlasManager_src",
"//src/gpu/ganesh/text:GrTextBlobRedrawCoordinator_src",
"//src/gpu/ganesh/text:GrTextBlob_src",
],
)
@ -2209,7 +2208,7 @@ generated_cc_atom(
"//src/gpu/ganesh/effects:GrSkSLFP_hdr",
"//src/gpu/ganesh/ops:AtlasTextOp_hdr",
"//src/gpu/ganesh/text:GrTextBlobRedrawCoordinator_hdr",
"//src/gpu/ganesh/text:GrTextBlob_hdr",
"//src/text/gpu:TextBlob_hdr",
"//src/utils:SkJSONWriter_hdr",
],
)

View File

@ -21,8 +21,8 @@
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/SurfaceContext.h"
#include "src/gpu/ganesh/effects/GrSkSLFP.h"
#include "src/gpu/ganesh/text/GrTextBlob.h"
#include "src/gpu/ganesh/text/GrTextBlobRedrawCoordinator.h"
#include "src/text/gpu/TextBlob.h"
#if SK_GPU_V1
#include "src/gpu/ganesh/ops/AtlasTextOp.h"

View File

@ -108,7 +108,7 @@ AtlasTextOp::AtlasTextOp(MaskType maskType,
this->setBounds(deviceRect, HasAABloat::kNo, IsHairline::kNo);
}
auto AtlasTextOp::Geometry::MakeForBlob(const GrAtlasSubRun& subRun,
auto AtlasTextOp::Geometry::MakeForBlob(const sktext::gpu::AtlasSubRun& subRun,
const SkMatrix& drawMatrix,
SkPoint drawOrigin,
SkIRect clipRect,
@ -281,7 +281,7 @@ void AtlasTextOp::onPrepareDraws(GrMeshDrawTarget* target) {
resetVertexBuffer();
for (const Geometry* geo = fHead; geo != nullptr; geo = geo->fNext) {
const GrAtlasSubRun& subRun = geo->fSubRun;
const sktext::gpu::AtlasSubRun& subRun = geo->fSubRun;
SkASSERTF((int) subRun.vertexStride(geo->fDrawMatrix) == vertexStride,
"subRun stride: %d vertex buffer stride: %d\n",
(int)subRun.vertexStride(geo->fDrawMatrix), vertexStride);
@ -511,10 +511,10 @@ GrOp::Owner AtlasTextOp::CreateOpTestingOnly(SurfaceDrawContext* sdc,
SkScalerContextFlags::kBoostContrast,
&control};
sk_sp<GrTextBlob> blob = GrTextBlob::Make(
sk_sp<sktext::gpu::TextBlob> blob = sktext::gpu::TextBlob::Make(
glyphRunList, skPaint, drawMatrix, strikeDeviceInfo, SkStrikeCache::GlobalStrikeCache());
const GrAtlasSubRun* subRun = blob->testingOnlyFirstSubRun();
const sktext::gpu::AtlasSubRun* subRun = blob->testingOnlyFirstSubRun();
if (!subRun) {
return nullptr;
}

View File

@ -11,7 +11,7 @@
#include "src/gpu/AtlasTypes.h"
#include "src/gpu/ganesh/effects/GrDistanceFieldGeoProc.h"
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"
#include "src/gpu/ganesh/text/GrTextBlob.h"
#include "src/text/gpu/TextBlob.h"
class GrRecordingContext;
@ -34,7 +34,7 @@ public:
static void ClearCache();
struct Geometry {
Geometry(const GrAtlasSubRun& subRun,
Geometry(const sktext::gpu::AtlasSubRun& subRun,
const SkMatrix& drawMatrix,
SkPoint drawOrigin,
SkIRect clipRect,
@ -49,7 +49,7 @@ public:
SkASSERT(fSupportDataKeepAlive != nullptr);
}
static Geometry* MakeForBlob(const GrAtlasSubRun& subRun,
static Geometry* MakeForBlob(const sktext::gpu::AtlasSubRun& subRun,
const SkMatrix& drawMatrix,
SkPoint drawOrigin,
SkIRect clipRect,
@ -59,9 +59,9 @@ public:
void fillVertexData(void* dst, int offset, int count) const;
const GrAtlasSubRun& fSubRun;
const sktext::gpu::AtlasSubRun& fSubRun;
// Keep the GrTextBlob or Slug alive until the op is deleted.
// Keep the TextBlob or Slug alive until the op is deleted.
sk_sp<SkRefCnt> fSupportDataKeepAlive;
const SkMatrix fDrawMatrix;

View File

@ -219,7 +219,7 @@ generated_cc_atom(
":GrMeshDrawOp_hdr",
"//src/gpu:AtlasTypes_hdr",
"//src/gpu/ganesh/effects:GrDistanceFieldGeoProc_hdr",
"//src/gpu/ganesh/text:GrTextBlob_hdr",
"//src/text/gpu:TextBlob_hdr",
],
)

View File

@ -42,81 +42,18 @@ generated_cc_atom(
],
)
generated_cc_atom(
name = "GrTextBlob_hdr",
hdrs = ["GrTextBlob.h"],
visibility = ["//:__subpackages__"],
deps = [
"//include/core:SkPoint3_hdr",
"//include/core:SkRefCnt_hdr",
"//include/private/chromium:Slug_hdr",
"//src/core:SkDevice_hdr",
"//src/core:SkGlyphRunPainter_hdr",
"//src/core:SkIPoint16_hdr",
"//src/core:SkMaskFilterBase_hdr",
"//src/core:SkOpts_hdr",
"//src/core:SkRectPriv_hdr",
"//src/core:SkStrikeSpec_hdr",
"//src/core:SkTInternalLList_hdr",
"//src/core:SkTLazy_hdr",
"//src/gpu/ganesh:GrColor_hdr",
"//src/gpu/ganesh/ops:GrOp_hdr",
"//src/text/gpu:SubRunAllocator_hdr",
],
)
generated_cc_atom(
name = "GrTextBlob_src",
srcs = ["GrTextBlob.cpp"],
visibility = ["//:__subpackages__"],
deps = [
":GrAtlasManager_hdr",
":GrTextBlob_hdr",
"//include/core:SkColorFilter_hdr",
"//include/core:SkScalar_hdr",
"//include/gpu:GrRecordingContext_hdr",
"//include/private:SkTemplates_hdr",
"//include/private/chromium:SkChromeRemoteGlyphCache_hdr",
"//include/private/chromium:Slug_hdr",
"//src/core:SkEnumerate_hdr",
"//src/core:SkFontPriv_hdr",
"//src/core:SkGlyph_hdr",
"//src/core:SkMaskFilterBase_hdr",
"//src/core:SkMatrixProvider_hdr",
"//src/core:SkPaintPriv_hdr",
"//src/core:SkReadBuffer_hdr",
"//src/core:SkStrikeCache_hdr",
"//src/core:SkStrikeSpec_hdr",
"//src/gpu/ganesh:GrBlurUtils_hdr",
"//src/gpu/ganesh:GrClip_hdr",
"//src/gpu/ganesh:GrMeshDrawTarget_hdr",
"//src/gpu/ganesh:GrStyle_hdr",
"//src/gpu/ganesh:SkGr_hdr",
"//src/gpu/ganesh/effects:GrDistanceFieldGeoProc_hdr",
"//src/gpu/ganesh/geometry:GrStyledShape_hdr",
"//src/gpu/ganesh/ops:AtlasTextOp_hdr",
"//src/gpu/ganesh/v1:Device_v1_hdr",
"//src/gpu/ganesh/v1:SurfaceDrawContext_v1_hdr",
"//src/text/gpu:GlyphVector_hdr",
"//src/text/gpu:Glyph_hdr",
"//src/text/gpu:SDFTControl_hdr",
"//src/text/gpu:StrikeCache_hdr",
"//src/text/gpu:SubRunAllocator_hdr",
],
)
generated_cc_atom(
name = "GrTextBlobRedrawCoordinator_hdr",
hdrs = ["GrTextBlobRedrawCoordinator.h"],
visibility = ["//:__subpackages__"],
deps = [
":GrTextBlob_hdr",
"//include/core:SkRefCnt_hdr",
"//include/private:SkSpinlock_hdr",
"//include/private:SkTArray_hdr",
"//include/private:SkTHash_hdr",
"//src/core:SkMessageBus_hdr",
"//src/core:SkTextBlobPriv_hdr",
"//src/text/gpu:TextBlob_hdr",
],
)

View File

@ -10,6 +10,8 @@
#include "src/core/SkStrikeCache.h"
#include "src/gpu/ganesh/v1/SurfaceDrawContext_v1.h"
using TextBlob = sktext::gpu::TextBlob;
DECLARE_SKMESSAGEBUS_MESSAGE(GrTextBlobRedrawCoordinator::PurgeBlobMessage, uint32_t, true)
// This function is captured by the above macro using implementations from SkMessageBus.h
@ -34,9 +36,9 @@ void GrTextBlobRedrawCoordinator::drawGlyphRunList(SkCanvas* canvas,
SkMatrix positionMatrix{viewMatrix.localToDevice()};
positionMatrix.preTranslate(glyphRunList.origin().x(), glyphRunList.origin().y());
auto [canCache, key] = GrTextBlob::Key::Make(
auto [canCache, key] = TextBlob::Key::Make(
glyphRunList, paint, positionMatrix, strikeDeviceInfo);
sk_sp<GrTextBlob> blob;
sk_sp<TextBlob> blob;
if (canCache) {
blob = this->find(key);
}
@ -47,7 +49,7 @@ void GrTextBlobRedrawCoordinator::drawGlyphRunList(SkCanvas* canvas,
this->remove(blob.get());
}
blob = GrTextBlob::Make(
blob = TextBlob::Make(
glyphRunList, paint, positionMatrix,
strikeDeviceInfo, SkStrikeCache::GlobalStrikeCache());
@ -62,23 +64,23 @@ void GrTextBlobRedrawCoordinator::drawGlyphRunList(SkCanvas* canvas,
blob->draw(canvas, clip, viewMatrix, glyphRunList.origin(), paint, sdc);
}
sk_sp<GrTextBlob> GrTextBlobRedrawCoordinator::addOrReturnExisting(
const SkGlyphRunList& glyphRunList, sk_sp<GrTextBlob> blob) {
sk_sp<TextBlob> GrTextBlobRedrawCoordinator::addOrReturnExisting(
const SkGlyphRunList& glyphRunList, sk_sp<TextBlob> blob) {
SkAutoSpinlock lock{fSpinLock};
blob = this->internalAdd(std::move(blob));
glyphRunList.temporaryShuntBlobNotifyAddedToCache(fMessageBusID);
return blob;
}
sk_sp<GrTextBlob> GrTextBlobRedrawCoordinator::find(const GrTextBlob::Key& key) {
sk_sp<TextBlob> GrTextBlobRedrawCoordinator::find(const TextBlob::Key& key) {
SkAutoSpinlock lock{fSpinLock};
const BlobIDCacheEntry* idEntry = fBlobIDCache.find(key.fUniqueID);
if (idEntry == nullptr) {
return nullptr;
}
sk_sp<GrTextBlob> blob = idEntry->find(key);
GrTextBlob* blobPtr = blob.get();
sk_sp<TextBlob> blob = idEntry->find(key);
TextBlob* blobPtr = blob.get();
if (blobPtr != nullptr && blobPtr != fBlobList.head()) {
fBlobList.remove(blobPtr);
fBlobList.addToHead(blobPtr);
@ -86,17 +88,17 @@ sk_sp<GrTextBlob> GrTextBlobRedrawCoordinator::find(const GrTextBlob::Key& key)
return blob;
}
void GrTextBlobRedrawCoordinator::remove(GrTextBlob* blob) {
void GrTextBlobRedrawCoordinator::remove(TextBlob* blob) {
SkAutoSpinlock lock{fSpinLock};
this->internalRemove(blob);
}
void GrTextBlobRedrawCoordinator::internalRemove(GrTextBlob* blob) {
void GrTextBlobRedrawCoordinator::internalRemove(TextBlob* blob) {
auto id = blob->key().fUniqueID;
auto* idEntry = fBlobIDCache.find(id);
if (idEntry != nullptr) {
sk_sp<GrTextBlob> stillExists = idEntry->find(blob->key());
sk_sp<TextBlob> stillExists = idEntry->find(blob->key());
if (blob == stillExists.get()) {
fCurrentSize -= blob->size();
fBlobList.remove(blob);
@ -157,7 +159,7 @@ bool GrTextBlobRedrawCoordinator::isOverBudget() const {
return fCurrentSize > fSizeBudget;
}
void GrTextBlobRedrawCoordinator::internalCheckPurge(GrTextBlob* blob) {
void GrTextBlobRedrawCoordinator::internalCheckPurge(TextBlob* blob) {
// First, purge all stale blob IDs.
this->internalPurgeStaleBlobs();
@ -165,7 +167,7 @@ void GrTextBlobRedrawCoordinator::internalCheckPurge(GrTextBlob* blob) {
if (fCurrentSize > fSizeBudget) {
TextBlobList::Iter iter;
iter.init(fBlobList, TextBlobList::Iter::kTail_IterStart);
GrTextBlob* lruBlob = nullptr;
TextBlob* lruBlob = nullptr;
while (fCurrentSize > fSizeBudget && (lruBlob = iter.get()) && lruBlob != blob) {
// Backup the iterator before removing and unrefing the blob
iter.prev();
@ -181,14 +183,14 @@ void GrTextBlobRedrawCoordinator::internalCheckPurge(GrTextBlob* blob) {
}
}
sk_sp<GrTextBlob> GrTextBlobRedrawCoordinator::internalAdd(sk_sp<GrTextBlob> blob) {
sk_sp<TextBlob> GrTextBlobRedrawCoordinator::internalAdd(sk_sp<TextBlob> blob) {
auto id = blob->key().fUniqueID;
auto* idEntry = fBlobIDCache.find(id);
if (!idEntry) {
idEntry = fBlobIDCache.set(id, BlobIDCacheEntry(id));
}
if (sk_sp<GrTextBlob> alreadyIn = idEntry->find(blob->key()); alreadyIn) {
if (sk_sp<TextBlob> alreadyIn = idEntry->find(blob->key()); alreadyIn) {
blob = std::move(alreadyIn);
} else {
fBlobList.addToHead(blob.get());
@ -209,7 +211,7 @@ uint32_t GrTextBlobRedrawCoordinator::BlobIDCacheEntry::GetKey(
return entry.fID;
}
void GrTextBlobRedrawCoordinator::BlobIDCacheEntry::addBlob(sk_sp<GrTextBlob> blob) {
void GrTextBlobRedrawCoordinator::BlobIDCacheEntry::addBlob(sk_sp<TextBlob> blob) {
SkASSERT(blob);
SkASSERT(blob->key().fUniqueID == fID);
SkASSERT(!this->find(blob->key()));
@ -217,7 +219,7 @@ void GrTextBlobRedrawCoordinator::BlobIDCacheEntry::addBlob(sk_sp<GrTextBlob> bl
fBlobs.emplace_back(std::move(blob));
}
void GrTextBlobRedrawCoordinator::BlobIDCacheEntry::removeBlob(GrTextBlob* blob) {
void GrTextBlobRedrawCoordinator::BlobIDCacheEntry::removeBlob(TextBlob* blob) {
SkASSERT(blob);
SkASSERT(blob->key().fUniqueID == fID);
@ -227,13 +229,13 @@ void GrTextBlobRedrawCoordinator::BlobIDCacheEntry::removeBlob(GrTextBlob* blob)
fBlobs.removeShuffle(index);
}
sk_sp<GrTextBlob>
GrTextBlobRedrawCoordinator::BlobIDCacheEntry::find(const GrTextBlob::Key& key) const {
sk_sp<TextBlob>
GrTextBlobRedrawCoordinator::BlobIDCacheEntry::find(const TextBlob::Key& key) const {
auto index = this->findBlobIndex(key);
return index < 0 ? nullptr : fBlobs[index];
}
int GrTextBlobRedrawCoordinator::BlobIDCacheEntry::findBlobIndex(const GrTextBlob::Key& key) const {
int GrTextBlobRedrawCoordinator::BlobIDCacheEntry::findBlobIndex(const TextBlob::Key& key) const {
for (int i = 0; i < fBlobs.count(); ++i) {
if (fBlobs[i]->key() == key) {
return i;

View File

@ -14,7 +14,7 @@
#include "include/private/SkTHash.h"
#include "src/core/SkMessageBus.h"
#include "src/core/SkTextBlobPriv.h"
#include "src/gpu/ganesh/text/GrTextBlob.h"
#include "src/text/gpu/TextBlob.h"
#include <functional>
@ -22,7 +22,7 @@
// to pick the best data for the draw. In addition, it provides a central service for managing
// resource usage through a messageBus.
// The draw data is stored in a three-tiered system. The first tier is keyed by the SkTextBlob's
// uniqueID. The second tier uses the GrTextBlob's key to get a general match for the draw. The
// uniqueID. The second tier uses the sktext::gpu::TextBlob's key to get a general match for the draw. The
// last tier queries each sub run using canReuse to determine if each sub run can handle the
// drawing parameters.
class GrTextBlobRedrawCoordinator {
@ -57,7 +57,7 @@ public:
private:
friend class GrTextBlobTestingPeer;
using TextBlobList = SkTInternalLList<GrTextBlob>;
using TextBlobList = SkTInternalLList<sktext::gpu::TextBlob>;
struct BlobIDCacheEntry {
BlobIDCacheEntry();
@ -65,34 +65,36 @@ private:
static uint32_t GetKey(const BlobIDCacheEntry& entry);
void addBlob(sk_sp<GrTextBlob> blob);
void addBlob(sk_sp<sktext::gpu::TextBlob> blob);
void removeBlob(GrTextBlob* blob);
void removeBlob(sktext::gpu::TextBlob* blob);
sk_sp<GrTextBlob> find(const GrTextBlob::Key& key) const;
sk_sp<sktext::gpu::TextBlob> find(const sktext::gpu::TextBlob::Key& key) const;
int findBlobIndex(const GrTextBlob::Key& key) const;
int findBlobIndex(const sktext::gpu::TextBlob::Key& key) const;
uint32_t fID;
// Current clients don't generate multiple GrAtlasTextBlobs per SkTextBlob, so an array w/
// linear search is acceptable. If usage changes, we should re-evaluate this structure.
SkSTArray<1, sk_sp<GrTextBlob>> fBlobs;
SkSTArray<1, sk_sp<sktext::gpu::TextBlob>> fBlobs;
};
// If not already in the cache, then add it else, return the text blob from the cache.
sk_sp<GrTextBlob> addOrReturnExisting(
const SkGlyphRunList& glyphRunList, sk_sp<GrTextBlob> blob) SK_EXCLUDES(fSpinLock);
sk_sp<sktext::gpu::TextBlob> addOrReturnExisting(
const SkGlyphRunList& glyphRunList,
sk_sp<sktext::gpu::TextBlob> blob) SK_EXCLUDES(fSpinLock);
sk_sp<GrTextBlob> find(const GrTextBlob::Key& key) SK_EXCLUDES(fSpinLock);
sk_sp<sktext::gpu::TextBlob> find(const sktext::gpu::TextBlob::Key& key) SK_EXCLUDES(fSpinLock);
void remove(GrTextBlob* blob) SK_EXCLUDES(fSpinLock);
void remove(sktext::gpu::TextBlob* blob) SK_EXCLUDES(fSpinLock);
void internalPurgeStaleBlobs() SK_REQUIRES(fSpinLock);
sk_sp<GrTextBlob> internalAdd(sk_sp<GrTextBlob> blob) SK_REQUIRES(fSpinLock);
void internalRemove(GrTextBlob* blob) SK_REQUIRES(fSpinLock);
sk_sp<sktext::gpu::TextBlob>
internalAdd(sk_sp<sktext::gpu::TextBlob> blob) SK_REQUIRES(fSpinLock);
void internalRemove(sktext::gpu::TextBlob* blob) SK_REQUIRES(fSpinLock);
void internalCheckPurge(GrTextBlob* blob = nullptr) SK_REQUIRES(fSpinLock);
void internalCheckPurge(sktext::gpu::TextBlob* blob = nullptr) SK_REQUIRES(fSpinLock);
static const int kDefaultBudget = 1 << 22;

View File

@ -166,3 +166,66 @@ generated_cc_atom(
"//src/core:SkWriteBuffer_hdr",
],
)
generated_cc_atom(
name = "TextBlob_hdr",
hdrs = ["TextBlob.h"],
visibility = ["//:__subpackages__"],
deps = [
":SubRunAllocator_hdr",
"//include/core:SkPoint3_hdr",
"//include/core:SkRefCnt_hdr",
"//include/private/chromium:Slug_hdr",
"//src/core:SkDevice_hdr",
"//src/core:SkGlyphRunPainter_hdr",
"//src/core:SkIPoint16_hdr",
"//src/core:SkMaskFilterBase_hdr",
"//src/core:SkOpts_hdr",
"//src/core:SkRectPriv_hdr",
"//src/core:SkStrikeSpec_hdr",
"//src/core:SkTInternalLList_hdr",
"//src/core:SkTLazy_hdr",
"//src/gpu/ganesh:GrColor_hdr",
"//src/gpu/ganesh/ops:GrOp_hdr",
],
)
generated_cc_atom(
name = "TextBlob_src",
srcs = ["TextBlob.cpp"],
visibility = ["//:__subpackages__"],
deps = [
":GlyphVector_hdr",
":Glyph_hdr",
":SDFTControl_hdr",
":StrikeCache_hdr",
":SubRunAllocator_hdr",
":TextBlob_hdr",
"//include/core:SkColorFilter_hdr",
"//include/core:SkScalar_hdr",
"//include/gpu:GrRecordingContext_hdr",
"//include/private:SkTemplates_hdr",
"//include/private/chromium:SkChromeRemoteGlyphCache_hdr",
"//include/private/chromium:Slug_hdr",
"//src/core:SkEnumerate_hdr",
"//src/core:SkFontPriv_hdr",
"//src/core:SkGlyph_hdr",
"//src/core:SkMaskFilterBase_hdr",
"//src/core:SkMatrixProvider_hdr",
"//src/core:SkPaintPriv_hdr",
"//src/core:SkReadBuffer_hdr",
"//src/core:SkStrikeCache_hdr",
"//src/core:SkStrikeSpec_hdr",
"//src/gpu/ganesh:GrBlurUtils_hdr",
"//src/gpu/ganesh:GrClip_hdr",
"//src/gpu/ganesh:GrMeshDrawTarget_hdr",
"//src/gpu/ganesh:GrStyle_hdr",
"//src/gpu/ganesh:SkGr_hdr",
"//src/gpu/ganesh/effects:GrDistanceFieldGeoProc_hdr",
"//src/gpu/ganesh/geometry:GrStyledShape_hdr",
"//src/gpu/ganesh/ops:AtlasTextOp_hdr",
"//src/gpu/ganesh/text:GrAtlasManager_hdr",
"//src/gpu/ganesh/v1:Device_v1_hdr",
"//src/gpu/ganesh/v1:SurfaceDrawContext_v1_hdr",
],
)

View File

@ -13,10 +13,9 @@
#include <atomic>
namespace sktext::gpu { class Slug; }
sk_sp<sktext::gpu::Slug> SkMakeSlugFromBuffer(SkReadBuffer& buffer, const SkStrikeClient* client);
namespace sktext::gpu {
class Slug;
sk_sp<Slug> SkMakeSlugFromBuffer(SkReadBuffer& buffer, const SkStrikeClient* client);
TextReferenceFrame::~TextReferenceFrame() = default;
@ -61,7 +60,7 @@ uint32_t Slug::NextUniqueID() {
return nextUnique++;
}
// Most of Slug's implementation is in GrTextBlob.cpp to share common code.
// Most of Slug's implementation is in TextBlob.cpp to share common code.
} // namespace sktext::gpu

View File

@ -5,8 +5,8 @@
* found in the LICENSE file.
*/
#ifndef GrTextBlob_DEFINED
#define GrTextBlob_DEFINED
#ifndef sktext_gpu_TextBlob_DEFINED
#define sktext_gpu_TextBlob_DEFINED
#include <algorithm>
#include <limits>
@ -23,14 +23,17 @@
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkTInternalLList.h"
#include "src/core/SkTLazy.h"
#if SK_SUPPORT_GPU
#include "src/gpu/ganesh/GrColor.h"
#include "src/gpu/ganesh/ops/GrOp.h"
#endif
#include "src/text/gpu/SubRunAllocator.h"
#if SK_SUPPORT_GPU
class GrAtlasManager;
class GrDeferredUploadTarget;
class GrMeshDrawTarget;
class GrSubRun;
#endif
class SkMatrixProvider;
class SkStrikeClient;
@ -45,9 +48,11 @@ class StrikeCache;
namespace skgpu::v1 { class SurfaceDrawContext; }
// -- GrAtlasSubRun --------------------------------------------------------------------------------
// GrAtlasSubRun is the API that AtlasTextOp uses to generate vertex data for drawing.
// There are three different ways GrAtlasSubRun is specialized.
namespace sktext::gpu {
// -- AtlasSubRun --------------------------------------------------------------------------------
// AtlasSubRun is the API that AtlasTextOp uses to generate vertex data for drawing.
// There are three different ways AtlasSubRun is specialized.
// * DirectMaskSubRun* - this is by far the most common type of SubRun. The mask pixels are
// in 1:1 correspondence with the pixels on the device. The destination rectangles in this
// SubRun are in device space. This SubRun handles color glyphs.
@ -59,13 +64,15 @@ namespace skgpu::v1 { class SurfaceDrawContext; }
// * SDFTSubRun* - scaled distance field text handles largish single color glyphs that still
// can fit in the atlas; the sizes between direct SubRun, and path SubRun. The destination
// rectangles are in source space.
class GrAtlasSubRun {
class AtlasSubRun {
public:
virtual ~GrAtlasSubRun() = default;
virtual ~AtlasSubRun() = default;
virtual size_t vertexStride(const SkMatrix& drawMatrix) const = 0;
virtual int glyphCount() const = 0;
#if SK_SUPPORT_GPU
virtual size_t vertexStride(const SkMatrix& drawMatrix) const = 0;
virtual std::tuple<const GrClip*, GrOp::Owner>
makeAtlasTextOp(
const GrClip*,
@ -81,23 +88,25 @@ public:
SkPoint drawOrigin,
SkIRect clip) const = 0;
virtual void testingOnly_packedGlyphIDToGlyph(sktext::gpu::StrikeCache* cache) const = 0;
// This call is not thread safe. It should only be called from GrDrawOp::onPrepare which
// is single threaded.
virtual std::tuple<bool, int> regenerateAtlas(
int begin, int end, GrMeshDrawTarget* target) const = 0;
#endif
virtual void testingOnly_packedGlyphIDToGlyph(StrikeCache* cache) const = 0;
};
// -- GrSubRun -------------------------------------------------------------------------------------
// GrSubRun defines the most basic functionality of a SubRun; the ability to draw, and the
// -- SubRun -------------------------------------------------------------------------------------
// SubRun defines the most basic functionality of a SubRun; the ability to draw, and the
// ability to be in a list.
class GrSubRun;
using GrSubRunOwner = std::unique_ptr<GrSubRun, sktext::gpu::SubRunAllocator::Destroyer>;
class GrBlobSubRun;
class GrSubRun {
class SubRun;
using SubRunOwner = std::unique_ptr<SubRun, SubRunAllocator::Destroyer>;
class BlobSubRun;
class SubRun {
public:
virtual ~GrSubRun();
virtual ~SubRun();
#if SK_SUPPORT_GPU
// Produce GPU ops for this subRun or just draw them.
virtual void draw(SkCanvas*,
const GrClip*,
@ -105,13 +114,14 @@ public:
SkPoint drawOrigin,
const SkPaint&,
skgpu::v1::SurfaceDrawContext*) const = 0;
#endif
virtual const GrBlobSubRun* blobCast() const;
virtual const BlobSubRun* blobCast() const;
void flatten(SkWriteBuffer& buffer) const;
static GrSubRunOwner MakeFromBuffer(const sktext::gpu::TextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
sktext::gpu::SubRunAllocator* alloc,
const SkStrikeClient* client);
static SubRunOwner MakeFromBuffer(const TextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
sktext::gpu::SubRunAllocator* alloc,
const SkStrikeClient* client);
// Size hint for unflattening this run. If this is accurate, it will help with the allocation
// of the slug. If it's off then there may be more allocations needed to unflatten.
@ -123,7 +133,7 @@ public:
// Return the underlying atlas SubRun if it exists. Otherwise, return nullptr.
// * Don't use this API. It is only to support testing.
virtual const GrAtlasSubRun* testingOnly_atlasSubRun() const = 0;
virtual const AtlasSubRun* testingOnly_atlasSubRun() const = 0;
protected:
enum SubRunType : int;
@ -131,21 +141,21 @@ protected:
virtual void doFlatten(SkWriteBuffer& buffer) const = 0;
private:
friend class GrSubRunList;
GrSubRunOwner fNext;
friend class SubRunList;
SubRunOwner fNext;
};
// -- GrSubRunList ---------------------------------------------------------------------------------
class GrSubRunList {
// -- SubRunList ---------------------------------------------------------------------------------
class SubRunList {
public:
class Iterator {
public:
using value_type = GrSubRun;
using value_type = SubRun;
using difference_type = ptrdiff_t;
using pointer = value_type*;
using reference = value_type&;
using iterator_category = std::input_iterator_tag;
Iterator(GrSubRun* subRun) : fPtr{subRun} { }
Iterator(SubRun* subRun) : fPtr{subRun} { }
Iterator& operator++() { fPtr = fPtr->fNext.get(); return *this; }
Iterator operator++(int) { Iterator tmp(*this); operator++(); return tmp; }
bool operator==(const Iterator& rhs) const { return fPtr == rhs.fPtr; }
@ -153,11 +163,11 @@ public:
reference operator*() { return *fPtr; }
private:
GrSubRun* fPtr;
SubRun* fPtr;
};
void append(GrSubRunOwner subRun) {
GrSubRunOwner* newTail = &subRun->fNext;
void append(SubRunOwner subRun) {
SubRunOwner* newTail = &subRun->fNext;
*fTail = std::move(subRun);
fTail = newTail;
}
@ -166,30 +176,30 @@ public:
Iterator end() { return Iterator{nullptr}; }
Iterator begin() const { return Iterator{ fHead.get()}; }
Iterator end() const { return Iterator{nullptr}; }
GrSubRun& front() const {return *fHead; }
SubRun& front() const {return *fHead; }
private:
GrSubRunOwner fHead{nullptr};
GrSubRunOwner* fTail{&fHead};
SubRunOwner fHead{nullptr};
SubRunOwner* fTail{&fHead};
};
// -- GrTextBlob -----------------------------------------------------------------------------------
// A GrTextBlob contains a fully processed SkTextBlob, suitable for nearly immediate drawing
// -- TextBlob -----------------------------------------------------------------------------------
// A TextBlob contains a fully processed SkTextBlob, suitable for nearly immediate drawing
// on the GPU. These are initially created with valid positions and colors, but with invalid
// texture coordinates.
//
// A GrTextBlob contains a number of SubRuns that are created in the blob's arena. Each SubRun
// A TextBlob contains a number of SubRuns that are created in the blob's arena. Each SubRun
// tracks its own glyph and position data.
//
// In these classes, I'm trying to follow the convention about matrices and origins.
// * drawMatrix and drawOrigin - describes transformations for the current draw command.
// * positionMatrix - is equal to drawMatrix * [drawOrigin-as-translation-matrix]
// * initial Matrix - describes the combined initial matrix and origin the GrTextBlob was created
// * initial Matrix - describes the combined initial matrix and origin the TextBlob was created
// with.
//
//
class GrTextBlob final : public sktext::gpu::TextReferenceFrame,
public SkGlyphRunPainterInterface {
class TextBlob final : public TextReferenceFrame,
public SkGlyphRunPainterInterface {
public:
// Key is not used as part of a hash map, so the hash is never taken. It's only used in a
// list search using operator =().
@ -219,23 +229,23 @@ public:
bool operator==(const Key& other) const;
};
SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrTextBlob);
SK_DECLARE_INTERNAL_LLIST_INTERFACE(TextBlob);
// Make a GrTextBlob and its sub runs.
static sk_sp<GrTextBlob> Make(const SkGlyphRunList& glyphRunList,
const SkPaint& paint,
const SkMatrix& positionMatrix,
SkStrikeDeviceInfo strikeDeviceInfo,
SkStrikeForGPUCacheInterface* strikeCache);
// Make a TextBlob and its sub runs.
static sk_sp<TextBlob> Make(const SkGlyphRunList& glyphRunList,
const SkPaint& paint,
const SkMatrix& positionMatrix,
SkStrikeDeviceInfo strikeDeviceInfo,
SkStrikeForGPUCacheInterface* strikeCache);
GrTextBlob(sktext::gpu::SubRunAllocator&& alloc,
int totalMemorySize,
const SkMatrix& positionMatrix,
SkColor initialLuminance);
TextBlob(SubRunAllocator&& alloc,
int totalMemorySize,
const SkMatrix& positionMatrix,
SkColor initialLuminance);
~GrTextBlob() override;
~TextBlob() override;
// Change memory management to handle the data after GrTextBlob, but in the same allocation
// Change memory management to handle the data after TextBlob, but in the same allocation
// of memory. Only allow placement new.
void operator delete(void* p);
void* operator new(size_t);
@ -252,13 +262,15 @@ public:
const Key& key() const;
size_t size() const { return SkTo<size_t>(fSize); }
#if SK_SUPPORT_GPU
void draw(SkCanvas*,
const GrClip* clip,
const SkMatrixProvider& viewMatrix,
SkPoint drawOrigin,
const SkPaint& paint,
skgpu::v1::SurfaceDrawContext* sdc);
const GrAtlasSubRun* testingOnlyFirstSubRun() const;
#endif
const AtlasSubRun* testingOnlyFirstSubRun() const;
private:
// Methods to satisfy SkGlyphRunPainterInterface
@ -283,10 +295,10 @@ private:
// The allocator must come first because it needs to be destroyed last. Other fields of this
// structure may have pointers into it.
sktext::gpu::SubRunAllocator fAlloc;
SubRunAllocator fAlloc;
// Owner and list of the SubRun.
GrSubRunList fSubRunList;
SubRunList fSubRunList;
// Overall size of this struct plus vertices and glyphs at the end.
const int fSize;
@ -302,6 +314,9 @@ private:
bool fSomeGlyphsExcluded{false};
};
} // namespace sktext::gpu
// TODO: why is this only in v1?
namespace skgpu::v1 {
sk_sp<sktext::gpu::Slug> MakeSlug(const SkMatrixProvider& drawMatrix,
const SkGlyphRunList& glyphRunList,
@ -310,4 +325,5 @@ sk_sp<sktext::gpu::Slug> MakeSlug(const SkMatrixProvider& drawMatrix,
SkStrikeDeviceInfo strikeDeviceInfo,
SkStrikeForGPUCacheInterface* strikeCache);
} // namespace skgpu::v1
#endif // GrTextBlob_DEFINED
#endif // sktext_gpu_TextBlob_DEFINED

View File

@ -2679,7 +2679,7 @@ generated_cc_atom(
"//src/core:SkDevice_hdr",
"//src/core:SkSurfacePriv_hdr",
"//src/gpu/ganesh:GrColorInfo_hdr",
"//src/gpu/ganesh/text:GrTextBlob_hdr",
"//src/text/gpu:TextBlob_hdr",
"//tools:ToolUtils_hdr",
],
)

View File

@ -13,7 +13,7 @@
#include "src/core/SkDevice.h"
#include "src/core/SkSurfacePriv.h"
#include "src/gpu/ganesh/GrColorInfo.h"
#include "src/gpu/ganesh/text/GrTextBlob.h"
#include "src/text/gpu/TextBlob.h"
#include "tests/Test.h"
#include "tools/ToolUtils.h"
@ -327,6 +327,8 @@ DEF_TEST(SubRunAllocator, r) {
}
}
using TextBlob = sktext::gpu::TextBlob;
DEF_TEST(KeyEqualityOnPerspective, r) {
SkTextBlobBuilder builder;
SkFont font(SkTypeface::MakeDefault(), 16);
@ -346,11 +348,11 @@ DEF_TEST(KeyEqualityOnPerspective, r) {
SkMatrix matrix2;
matrix2.setAll(1, 0, 0, 0, 1, 0, 2, 2, 1);
auto key1 = std::get<1>(
GrTextBlob::Key::Make(glyphRunList, paint, matrix1, strikeDevice));
TextBlob::Key::Make(glyphRunList, paint, matrix1, strikeDevice));
auto key2 = std::get<1>(
GrTextBlob::Key::Make(glyphRunList, paint, matrix1, strikeDevice));
TextBlob::Key::Make(glyphRunList, paint, matrix1, strikeDevice));
auto key3 = std::get<1>(
GrTextBlob::Key::Make(glyphRunList, paint, matrix2, strikeDevice));
TextBlob::Key::Make(glyphRunList, paint, matrix2, strikeDevice));
REPORTER_ASSERT(r, key1 == key2);
REPORTER_ASSERT(r, !(key1 == key3));
}