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

View File

@ -324,8 +324,6 @@ skia_gpu_sources = [
# text # text
"$_src/gpu/ganesh/text/GrAtlasManager.cpp", "$_src/gpu/ganesh/text/GrAtlasManager.cpp",
"$_src/gpu/ganesh/text/GrAtlasManager.h", "$_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.cpp",
"$_src/gpu/ganesh/text/GrTextBlobRedrawCoordinator.h", "$_src/gpu/ganesh/text/GrTextBlobRedrawCoordinator.h",
@ -834,4 +832,6 @@ skia_shared_gpu_sources = [
"$_src/text/gpu/StrikeCache.h", "$_src/text/gpu/StrikeCache.h",
"$_src/text/gpu/SubRunAllocator.cpp", "$_src/text/gpu/SubRunAllocator.cpp",
"$_src/text/gpu/SubRunAllocator.h", "$_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/tessellate/VertexChunkPatchAllocator.h",
"src/gpu/ganesh/text/GrAtlasManager.cpp", "src/gpu/ganesh/text/GrAtlasManager.cpp",
"src/gpu/ganesh/text/GrAtlasManager.h", "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.cpp",
"src/gpu/ganesh/text/GrTextBlobRedrawCoordinator.h", "src/gpu/ganesh/text/GrTextBlobRedrawCoordinator.h",
"src/gpu/ganesh/v1/ClipStack.cpp", "src/gpu/ganesh/v1/ClipStack.cpp",
@ -1656,6 +1654,8 @@ BASE_SRCS_ALL = [
"src/text/gpu/StrikeCache.h", "src/text/gpu/StrikeCache.h",
"src/text/gpu/SubRunAllocator.cpp", "src/text/gpu/SubRunAllocator.cpp",
"src/text/gpu/SubRunAllocator.h", "src/text/gpu/SubRunAllocator.h",
"src/text/gpu/TextBlob.cpp",
"src/text/gpu/TextBlob.h",
"src/utils/SkAnimCodecPlayer.cpp", "src/utils/SkAnimCodecPlayer.cpp",
"src/utils/SkBase64.cpp", "src/utils/SkBase64.cpp",
"src/utils/SkBitSet.h", "src/utils/SkBitSet.h",

View File

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

View File

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

View File

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

View File

@ -23,6 +23,7 @@ cc_library(
"//src/text/gpu:Slug_src", "//src/text/gpu:Slug_src",
"//src/text/gpu:StrikeCache_src", "//src/text/gpu:StrikeCache_src",
"//src/text/gpu:SubRunAllocator_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/tessellate:StrokeTessellator_src",
"//src/gpu/ganesh/text:GrAtlasManager_src", "//src/gpu/ganesh/text:GrAtlasManager_src",
"//src/gpu/ganesh/text:GrTextBlobRedrawCoordinator_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/effects:GrSkSLFP_hdr",
"//src/gpu/ganesh/ops:AtlasTextOp_hdr", "//src/gpu/ganesh/ops:AtlasTextOp_hdr",
"//src/gpu/ganesh/text:GrTextBlobRedrawCoordinator_hdr", "//src/gpu/ganesh/text:GrTextBlobRedrawCoordinator_hdr",
"//src/gpu/ganesh/text:GrTextBlob_hdr", "//src/text/gpu:TextBlob_hdr",
"//src/utils:SkJSONWriter_hdr", "//src/utils:SkJSONWriter_hdr",
], ],
) )

View File

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

View File

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

View File

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

View File

@ -219,7 +219,7 @@ generated_cc_atom(
":GrMeshDrawOp_hdr", ":GrMeshDrawOp_hdr",
"//src/gpu:AtlasTypes_hdr", "//src/gpu:AtlasTypes_hdr",
"//src/gpu/ganesh/effects:GrDistanceFieldGeoProc_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( generated_cc_atom(
name = "GrTextBlobRedrawCoordinator_hdr", name = "GrTextBlobRedrawCoordinator_hdr",
hdrs = ["GrTextBlobRedrawCoordinator.h"], hdrs = ["GrTextBlobRedrawCoordinator.h"],
visibility = ["//:__subpackages__"], visibility = ["//:__subpackages__"],
deps = [ deps = [
":GrTextBlob_hdr",
"//include/core:SkRefCnt_hdr", "//include/core:SkRefCnt_hdr",
"//include/private:SkSpinlock_hdr", "//include/private:SkSpinlock_hdr",
"//include/private:SkTArray_hdr", "//include/private:SkTArray_hdr",
"//include/private:SkTHash_hdr", "//include/private:SkTHash_hdr",
"//src/core:SkMessageBus_hdr", "//src/core:SkMessageBus_hdr",
"//src/core:SkTextBlobPriv_hdr", "//src/core:SkTextBlobPriv_hdr",
"//src/text/gpu:TextBlob_hdr",
], ],
) )

View File

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

View File

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

View File

@ -166,3 +166,66 @@ generated_cc_atom(
"//src/core:SkWriteBuffer_hdr", "//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> #include <atomic>
namespace sktext::gpu { class Slug; }
sk_sp<sktext::gpu::Slug> SkMakeSlugFromBuffer(SkReadBuffer& buffer, const SkStrikeClient* client);
namespace sktext::gpu { namespace sktext::gpu {
class Slug;
sk_sp<Slug> SkMakeSlugFromBuffer(SkReadBuffer& buffer, const SkStrikeClient* client);
TextReferenceFrame::~TextReferenceFrame() = default; TextReferenceFrame::~TextReferenceFrame() = default;
@ -61,7 +60,7 @@ uint32_t Slug::NextUniqueID() {
return nextUnique++; 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 } // namespace sktext::gpu

View File

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

View File

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