Move more GPU text classes to sktext::gpu namespace.

Moves GlyphVector, TextStrike, StrikeCache, and SubRunAllocator.

Bug: skia:13118
Change-Id: Ifa4957b5cff280f44606dc62bfd30f6a03063c07
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/536102
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2022-05-05 11:08:03 -04:00 committed by SkCQ
parent 8d2fb64247
commit 35e1ca4b3b
43 changed files with 581 additions and 519 deletions

View File

@ -15,8 +15,8 @@
#include "src/core/SkUtils.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/text/GrStrikeCache.h"
#include "src/gpu/ganesh/text/GrTextBlob.h"
#include "src/text/gpu/StrikeCache.h"
#include "src/utils/SkUTF.h"
// From Project Guttenberg. This is UTF-8 text.
@ -77,7 +77,7 @@ class DirectMaskGlyphVertexFillBenchmark : public Benchmark {
private:
sk_sp<GrTextBlob> fBlob;
GrStrikeCache fCache;
sktext::gpu::StrikeCache fCache;
std::unique_ptr<char[]> fVertices;
};

View File

@ -191,8 +191,6 @@ skia_gpu_sources = [
"$_src/gpu/ganesh/GrStencilSettings.h",
"$_src/gpu/ganesh/GrStyle.cpp",
"$_src/gpu/ganesh/GrStyle.h",
"$_src/gpu/ganesh/GrSubRunAllocator.cpp",
"$_src/gpu/ganesh/GrSubRunAllocator.h",
"$_src/gpu/ganesh/GrSurface.cpp",
"$_src/gpu/ganesh/GrSurface.h",
"$_src/gpu/ganesh/GrSurfaceInfo.cpp",
@ -325,20 +323,17 @@ skia_gpu_sources = [
"$_src/gpu/ganesh/text/GrAtlasManager.h",
"$_src/gpu/ganesh/text/GrDistanceFieldAdjustTable.cpp",
"$_src/gpu/ganesh/text/GrDistanceFieldAdjustTable.h",
"$_src/gpu/ganesh/text/GrGlyphVector.cpp",
"$_src/gpu/ganesh/text/GrGlyphVector.h",
"$_src/gpu/ganesh/text/GrSDFMaskFilter.cpp",
"$_src/gpu/ganesh/text/GrSDFMaskFilter.h",
"$_src/gpu/ganesh/text/GrSDFTControl.cpp",
"$_src/gpu/ganesh/text/GrSDFTControl.h",
"$_src/gpu/ganesh/text/GrSlug.cpp",
"$_src/gpu/ganesh/text/GrStrikeCache.cpp",
"$_src/gpu/ganesh/text/GrStrikeCache.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/text/gpu/Glyph.h",
"$_src/text/gpu/GlyphVector.cpp",
"$_src/text/gpu/GlyphVector.h",
# GLSL
"$_src/gpu/ganesh/glsl/GrGLSL.cpp",
@ -832,4 +827,11 @@ skia_shared_gpu_sources = [
"$_src/gpu/tessellate/Tessellation.cpp",
"$_src/gpu/tessellate/Tessellation.h",
"$_src/gpu/tessellate/WangsFormula.h",
# text
"$_src/text/gpu/Glyph.h",
"$_src/text/gpu/StrikeCache.cpp",
"$_src/text/gpu/StrikeCache.h",
"$_src/text/gpu/SubRunAllocator.cpp",
"$_src/text/gpu/SubRunAllocator.h",
]

View File

@ -29,7 +29,6 @@ struct GrMockOptions;
class GrPath;
class GrResourceCache;
class GrResourceProvider;
class GrStrikeCache;
class GrSurfaceProxy;
class GrTextureProxy;
struct GrVkBackendContext;
@ -46,6 +45,10 @@ class Swizzle;
namespace v1 { class SmallPathAtlasMgr; }
}
namespace sktext::gpu {
class StrikeCache;
}
class SK_API GrDirectContext : public GrRecordingContext {
public:
#ifdef SK_GL
@ -856,11 +859,11 @@ private:
// after all of its users. Clients of fTaskGroup will generally want to ensure that they call
// wait() on it as they are being destroyed, to avoid the possibility of pending tasks being
// invoked after objects they depend upon have already been destroyed.
std::unique_ptr<SkTaskGroup> fTaskGroup;
std::unique_ptr<GrStrikeCache> fStrikeCache;
sk_sp<GrGpu> fGpu;
std::unique_ptr<GrResourceCache> fResourceCache;
std::unique_ptr<GrResourceProvider> fResourceProvider;
std::unique_ptr<SkTaskGroup> fTaskGroup;
std::unique_ptr<sktext::gpu::StrikeCache> fStrikeCache;
sk_sp<GrGpu> fGpu;
std::unique_ptr<GrResourceCache> fResourceCache;
std::unique_ptr<GrResourceProvider> fResourceProvider;
bool fDidTestPMConversions;
// true if the PM/UPM conversion succeeded; false otherwise

View File

@ -26,13 +26,16 @@ class GrProgramDesc;
class GrProgramInfo;
class GrProxyProvider;
class GrRecordingContextPriv;
class GrSubRunAllocator;
class GrSurfaceProxy;
class GrTextBlobRedrawCoordinator;
class GrThreadSafeCache;
class SkArenaAlloc;
class SkJSONWriter;
namespace sktext::gpu {
class SubRunAllocator;
}
#if GR_TEST_UTILS
class SkString;
#endif
@ -102,17 +105,19 @@ public:
// GrRecordingContext. Arenas does not maintain ownership of the pools it groups together.
class Arenas {
public:
Arenas(SkArenaAlloc*, GrSubRunAllocator*);
Arenas(SkArenaAlloc*, sktext::gpu::SubRunAllocator*);
// For storing pipelines and other complex data as-needed by ops
SkArenaAlloc* recordTimeAllocator() { return fRecordTimeAllocator; }
// For storing GrTextBlob SubRuns
GrSubRunAllocator* recordTimeSubRunAllocator() { return fRecordTimeSubRunAllocator; }
sktext::gpu::SubRunAllocator* recordTimeSubRunAllocator() {
return fRecordTimeSubRunAllocator;
}
private:
SkArenaAlloc* fRecordTimeAllocator;
GrSubRunAllocator* fRecordTimeSubRunAllocator;
sktext::gpu::SubRunAllocator* fRecordTimeSubRunAllocator;
};
protected:
@ -133,7 +138,7 @@ protected:
private:
bool fDDLRecording;
std::unique_ptr<SkArenaAlloc> fRecordTimeAllocator;
std::unique_ptr<GrSubRunAllocator> fRecordTimeSubRunAllocator;
std::unique_ptr<sktext::gpu::SubRunAllocator> fRecordTimeSubRunAllocator;
};
GrRecordingContext(sk_sp<GrContextThreadSafeProxy>, bool ddlRecording);

View File

@ -976,8 +976,6 @@ BASE_SRCS_ALL = [
"src/gpu/ganesh/GrStencilSettings.h",
"src/gpu/ganesh/GrStyle.cpp",
"src/gpu/ganesh/GrStyle.h",
"src/gpu/ganesh/GrSubRunAllocator.cpp",
"src/gpu/ganesh/GrSubRunAllocator.h",
"src/gpu/ganesh/GrSurface.cpp",
"src/gpu/ganesh/GrSurface.h",
"src/gpu/ganesh/GrSurfaceInfo.cpp",
@ -1221,15 +1219,11 @@ BASE_SRCS_ALL = [
"src/gpu/ganesh/text/GrAtlasManager.h",
"src/gpu/ganesh/text/GrDistanceFieldAdjustTable.cpp",
"src/gpu/ganesh/text/GrDistanceFieldAdjustTable.h",
"src/gpu/ganesh/text/GrGlyphVector.cpp",
"src/gpu/ganesh/text/GrGlyphVector.h",
"src/gpu/ganesh/text/GrSDFMaskFilter.cpp",
"src/gpu/ganesh/text/GrSDFMaskFilter.h",
"src/gpu/ganesh/text/GrSDFTControl.cpp",
"src/gpu/ganesh/text/GrSDFTControl.h",
"src/gpu/ganesh/text/GrSlug.cpp",
"src/gpu/ganesh/text/GrStrikeCache.cpp",
"src/gpu/ganesh/text/GrStrikeCache.h",
"src/gpu/ganesh/text/GrTextBlob.cpp",
"src/gpu/ganesh/text/GrTextBlob.h",
"src/gpu/ganesh/text/GrTextBlobRedrawCoordinator.cpp",
@ -1657,6 +1651,12 @@ BASE_SRCS_ALL = [
"src/sksl/transform/SkSLProgramWriter.h",
"src/sksl/transform/SkSLTransform.h",
"src/text/gpu/Glyph.h",
"src/text/gpu/GlyphVector.cpp",
"src/text/gpu/GlyphVector.h",
"src/text/gpu/StrikeCache.cpp",
"src/text/gpu/StrikeCache.h",
"src/text/gpu/SubRunAllocator.cpp",
"src/text/gpu/SubRunAllocator.h",
"src/utils/SkAnimCodecPlayer.cpp",
"src/utils/SkBase64.cpp",
"src/utils/SkBitSet.h",

View File

@ -4691,7 +4691,7 @@ generated_cc_atom(
"//include/core:SkTypeface_hdr",
"//include/private:SkMutex_hdr",
"//include/private:SkTemplates_hdr",
"//src/gpu/ganesh/text:GrStrikeCache_hdr",
"//src/text/gpu:StrikeCache_hdr",
],
)
@ -4743,7 +4743,7 @@ generated_cc_atom(
"//include/core:SkGraphics_hdr",
"//src/gpu/ganesh/text:GrSDFMaskFilter_hdr",
"//src/gpu/ganesh/text:GrSDFTControl_hdr",
"//src/gpu/ganesh/text:GrStrikeCache_hdr",
"//src/text/gpu:StrikeCache_hdr",
],
)

View File

@ -19,7 +19,7 @@
#include "src/core/SkScalerCache.h"
#if SK_SUPPORT_GPU
#include "src/gpu/ganesh/text/GrStrikeCache.h"
#include "src/text/gpu/StrikeCache.h"
#endif
bool gSkUseThreadLocalStrikeCaches_IAcknowledgeThisIsIncrediblyExperimental = false;
@ -345,8 +345,9 @@ void SkStrikeCache::validate() const {
}
#if SK_SUPPORT_GPU
sk_sp<GrTextStrike> SkStrike::findOrCreateGrStrike(GrStrikeCache* grStrikeCache) const {
return grStrikeCache->findOrCreateStrike(fStrikeSpec);
sk_sp<sktext::gpu::TextStrike> SkStrike::findOrCreateTextStrike(
sktext::gpu::StrikeCache* gpuStrikeCache) const {
return gpuStrikeCache->findOrCreateStrike(fStrikeSpec);
}
#endif

View File

@ -132,7 +132,8 @@ public:
}
#if SK_SUPPORT_GPU
sk_sp<GrTextStrike> findOrCreateGrStrike(GrStrikeCache* grStrikeCache) const;
sk_sp<sktext::gpu::TextStrike> findOrCreateTextStrike(
sktext::gpu::StrikeCache* gpuStrikeCache) const;
#endif
void prepareForMaskDrawing(

View File

@ -16,7 +16,7 @@
#if SK_SUPPORT_GPU
#include "src/gpu/ganesh/text/GrSDFMaskFilter.h"
#include "src/gpu/ganesh/text/GrSDFTControl.h"
#include "src/gpu/ganesh/text/GrStrikeCache.h"
#include "src/text/gpu/StrikeCache.h"
#endif
SkStrikeSpec::SkStrikeSpec(const SkDescriptor& descriptor, sk_sp<SkTypeface> typeface)
@ -189,7 +189,8 @@ SkStrikeSpec::MakeSDFT(const SkFont& font, const SkPaint& paint,
return std::make_tuple(std::move(strikeSpec), strikeToSourceScale, matrixRange);
}
sk_sp<GrTextStrike> SkStrikeSpec::findOrCreateGrStrike(GrStrikeCache* cache) const {
sk_sp<sktext::gpu::TextStrike> SkStrikeSpec::findOrCreateTextStrike(
sktext::gpu::StrikeCache* cache) const {
return cache->findOrCreateStrike(*this);
}
#endif

View File

@ -17,8 +17,10 @@
#if SK_SUPPORT_GPU
#include "src/gpu/ganesh/text/GrSDFTControl.h"
class GrStrikeCache;
class GrTextStrike;
namespace sktext::gpu {
class StrikeCache;
class TextStrike;
}
#endif
class SkFont;
@ -78,7 +80,7 @@ public:
const SkMatrix& deviceMatrix,
const GrSDFTControl& control);
sk_sp<GrTextStrike> findOrCreateGrStrike(GrStrikeCache* cache) const;
sk_sp<sktext::gpu::TextStrike> findOrCreateTextStrike(sktext::gpu::StrikeCache* cache) const;
#endif
SkScopedStrikeForGPU findOrCreateScopedStrike(SkStrikeForGPUCacheInterface* cache) const;

View File

@ -16,6 +16,9 @@ cc_library(
":Swizzle_src",
"//src/gpu/tessellate:FixedCountBufferUtils_src",
"//src/gpu/tessellate:Tessellation_src",
"//src/text/gpu:GlyphVector_src",
"//src/text/gpu:StrikeCache_src",
"//src/text/gpu:SubRunAllocator_src",
],
)

View File

@ -82,7 +82,6 @@ cc_library(
":GrStagingBufferManager_src",
":GrStencilSettings_src",
":GrStyle_src",
":GrSubRunAllocator_src",
":GrSurfaceInfo_src",
":GrSurfaceProxy_src",
":GrSurface_src",
@ -190,11 +189,9 @@ cc_library(
"//src/gpu/ganesh/tessellate/shaders:GrTessellationShader_src",
"//src/gpu/ganesh/text:GrAtlasManager_src",
"//src/gpu/ganesh/text:GrDistanceFieldAdjustTable_src",
"//src/gpu/ganesh/text:GrGlyphVector_src",
"//src/gpu/ganesh/text:GrSDFMaskFilter_src",
"//src/gpu/ganesh/text:GrSDFTControl_src",
"//src/gpu/ganesh/text:GrSlug_src",
"//src/gpu/ganesh/text:GrStrikeCache_src",
"//src/gpu/ganesh/text:GrTextBlobRedrawCoordinator_src",
"//src/gpu/ganesh/text:GrTextBlob_src",
],
@ -1148,9 +1145,9 @@ generated_cc_atom(
"//src/gpu/ganesh/mtl:GrMtlTrampoline_hdr",
"//src/gpu/ganesh/ops:SmallPathAtlasMgr_hdr",
"//src/gpu/ganesh/text:GrAtlasManager_hdr",
"//src/gpu/ganesh/text:GrStrikeCache_hdr",
"//src/gpu/ganesh/vk:GrVkGpu_hdr",
"//src/image:SkImage_GpuBase_hdr",
"//src/text/gpu:StrikeCache_hdr",
"//src/utils:SkJSONWriter_hdr",
"//src/utils:SkShaderUtils_hdr",
],
@ -2248,11 +2245,11 @@ generated_cc_atom(
deps = [
":GrCaps_hdr",
":GrNativeRect_hdr",
":GrSubRunAllocator_hdr",
":GrSurfaceProxy_hdr",
"//include/private/gpu/ganesh:GrTypesPriv_hdr",
"//src/core:SkArenaAlloc_hdr",
"//src/gpu:Swizzle_hdr",
"//src/text/gpu:SubRunAllocator_hdr",
],
)
@ -2714,28 +2711,6 @@ generated_cc_atom(
],
)
generated_cc_atom(
name = "GrSubRunAllocator_hdr",
hdrs = ["GrSubRunAllocator.h"],
visibility = ["//:__subpackages__"],
deps = [
"//include/core:SkMath_hdr",
"//include/core:SkSpan_hdr",
"//include/private:SkTemplates_hdr",
"//src/core:SkArenaAlloc_hdr",
],
)
generated_cc_atom(
name = "GrSubRunAllocator_src",
srcs = ["GrSubRunAllocator.cpp"],
visibility = ["//:__subpackages__"],
deps = [
":GrSubRunAllocator_hdr",
"//include/core:SkMath_hdr",
],
)
generated_cc_atom(
name = "GrSurfaceInfo_src",
srcs = ["GrSurfaceInfo.cpp"],

View File

@ -27,8 +27,8 @@
#include "src/gpu/ganesh/effects/GrSkSLFP.h"
#include "src/gpu/ganesh/mock/GrMockGpu.h"
#include "src/gpu/ganesh/text/GrAtlasManager.h"
#include "src/gpu/ganesh/text/GrStrikeCache.h"
#include "src/image/SkImage_GpuBase.h"
#include "src/text/gpu/StrikeCache.h"
#include "src/utils/SkShaderUtils.h"
#if SK_GPU_V1
#include "src/gpu/ganesh/ops/SmallPathAtlasMgr.h"
@ -69,6 +69,8 @@ public:
#define ASSERT_SINGLE_OWNER SKGPU_ASSERT_SINGLE_OWNER(this->singleOwner())
using StrikeCache = sktext::gpu::StrikeCache;
GrDirectContext::DirectContextID GrDirectContext::DirectContextID::Next() {
static std::atomic<uint32_t> nextID{1};
uint32_t id;
@ -226,7 +228,7 @@ bool GrDirectContext::init() {
SkASSERT(this->getTextBlobRedrawCoordinator());
SkASSERT(this->threadSafeCache());
fStrikeCache = std::make_unique<GrStrikeCache>();
fStrikeCache = std::make_unique<StrikeCache>();
fResourceCache = std::make_unique<GrResourceCache>(this->singleOwner(),
this->directContextID(),
this->contextID());

View File

@ -36,7 +36,7 @@ public:
GrDirectContext* context() { return static_cast<GrDirectContext*>(fContext); }
const GrDirectContext* context() const { return static_cast<const GrDirectContext*>(fContext); }
GrStrikeCache* getGrStrikeCache() { return this->context()->fStrikeCache.get(); }
sktext::gpu::StrikeCache* getStrikeCache() { return this->context()->fStrikeCache.get(); }
/**
* Finalizes all pending reads and writes to the surfaces and also performs an MSAA resolves

View File

@ -12,7 +12,6 @@
#include "src/gpu/ganesh/GrSimpleMesh.h"
class GrAtlasManager;
class GrStrikeCache;
class GrThreadSafeCache;
namespace skgpu {
@ -22,6 +21,10 @@ namespace skgpu {
struct VertexWriter;
} // namespace skgpu
namespace sktext::gpu {
class StrikeCache;
}
/*
* Abstract interface that supports creating vertices, indices, and meshes, as well as
* invoking GPU draw operations.
@ -139,7 +142,7 @@ public:
virtual GrResourceProvider* resourceProvider() const = 0;
uint32_t contextUniqueID() const;
virtual GrStrikeCache* strikeCache() const = 0;
virtual sktext::gpu::StrikeCache* strikeCache() const = 0;
virtual GrAtlasManager* atlasManager() const = 0;
virtual skgpu::v1::SmallPathAtlasMgr* smallPathAtlasManager() const = 0;

View File

@ -213,8 +213,8 @@ GrAppliedClip GrOpFlushState::detachAppliedClip() {
return fOpArgs->appliedClip() ? std::move(*fOpArgs->appliedClip()) : GrAppliedClip::Disabled();
}
GrStrikeCache* GrOpFlushState::strikeCache() const {
return fGpu->getContext()->priv().getGrStrikeCache();
sktext::gpu::StrikeCache* GrOpFlushState::strikeCache() const {
return fGpu->getContext()->priv().getStrikeCache();
}
GrAtlasManager* GrOpFlushState::atlasManager() const {

View File

@ -179,7 +179,7 @@ public:
GrThreadSafeCache* threadSafeCache() const final;
GrResourceProvider* resourceProvider() const final { return fResourceProvider; }
GrStrikeCache* strikeCache() const final;
sktext::gpu::StrikeCache* strikeCache() const final;
// At this point we know we're flushing so full access to the GrAtlasManager and
// SmallPathAtlasMgr is required (and permissible).

View File

@ -101,7 +101,7 @@ void GrRecordingContext::destroyDrawingManager() {
}
GrRecordingContext::Arenas::Arenas(SkArenaAlloc* recordTimeAllocator,
GrSubRunAllocator* subRunAllocator)
sktext::gpu::SubRunAllocator* subRunAllocator)
: fRecordTimeAllocator(recordTimeAllocator)
, fRecordTimeSubRunAllocator(subRunAllocator) {
// OwnedArenas should instantiate these before passing the bare pointer off to this struct.
@ -127,7 +127,7 @@ GrRecordingContext::Arenas GrRecordingContext::OwnedArenas::get() {
}
if (!fRecordTimeSubRunAllocator) {
fRecordTimeSubRunAllocator = std::make_unique<GrSubRunAllocator>();
fRecordTimeSubRunAllocator = std::make_unique<sktext::gpu::SubRunAllocator>();
}
return {fRecordTimeAllocator.get(), fRecordTimeSubRunAllocator.get()};

View File

@ -39,7 +39,7 @@ public:
GrDrawingManager* drawingManager() { return this->context()->drawingManager(); }
SkArenaAlloc* recordTimeAllocator() { return this->context()->arenas().recordTimeAllocator(); }
GrSubRunAllocator* recordTimeSubRunAllocator() {
sktext::gpu::SubRunAllocator* recordTimeSubRunAllocator() {
return this->context()->arenas().recordTimeSubRunAllocator();
}
GrRecordingContext::Arenas arenas() { return this->context()->arenas(); }

View File

@ -13,8 +13,8 @@
#include "src/gpu/Swizzle.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrNativeRect.h"
#include "src/gpu/ganesh/GrSubRunAllocator.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/text/gpu/SubRunAllocator.h"
class GrResourceProvider;
@ -32,13 +32,13 @@ public:
void flush() {
SkDEBUGCODE(fIsFlushed = true;)
}
GrSubRunAllocator* subRunAlloc() { return &fSubRunAllocator; }
sktext::gpu::SubRunAllocator* subRunAlloc() { return &fSubRunAllocator; }
private:
SkArenaAlloc fArenaAlloc{1024};
// An allocator specifically designed to minimize the overhead of sub runs. It provides a
// different dtor semantics than SkArenaAlloc.
GrSubRunAllocator fSubRunAllocator{1024};
sktext::gpu::SubRunAllocator fSubRunAllocator{1024};
SkDEBUGCODE(bool fIsFlushed = false;)
};

View File

@ -108,7 +108,7 @@ public:
UNIMPL(const GrSurfaceProxyView& writeView() const)
UNIMPL(const GrAppliedClip* appliedClip() const)
UNIMPL(bool usesMSAASurface() const)
UNIMPL(GrStrikeCache* strikeCache() const)
UNIMPL(sktext::gpu::StrikeCache* strikeCache() const)
UNIMPL(GrAtlasManager* atlasManager() const)
UNIMPL(SkTArray<GrSurfaceProxy*, true>* sampledProxyArray())
UNIMPL(GrDeferredUploadTarget* deferredUploadTarget())

View File

@ -19,7 +19,6 @@ class GrCaps;
class GrMeshDrawTarget;
class GrOpFlushState;
struct GrSimpleMesh;
class GrStrikeCache;
/**
* Base class for mesh-drawing GrDrawOps.

View File

@ -22,7 +22,6 @@ generated_cc_atom(
visibility = ["//:__subpackages__"],
deps = [
":GrAtlasManager_hdr",
":GrStrikeCache_hdr",
"//include/core:SkBitmap_hdr",
"//include/core:SkColorSpace_hdr",
"//include/core:SkImageEncoder_hdr",
@ -37,6 +36,7 @@ generated_cc_atom(
"//src/gpu/ganesh:GrTextureProxy_hdr",
"//src/gpu/ganesh:SurfaceContext_hdr",
"//src/text/gpu:Glyph_hdr",
"//src/text/gpu:StrikeCache_hdr",
],
)
@ -119,29 +119,6 @@ generated_cc_atom(
],
)
generated_cc_atom(
name = "GrStrikeCache_hdr",
hdrs = ["GrStrikeCache.h"],
visibility = ["//:__subpackages__"],
deps = [
"//include/private:SkTHash_hdr",
"//src/core:SkArenaAlloc_hdr",
"//src/core:SkStrikeSpec_hdr",
],
)
generated_cc_atom(
name = "GrStrikeCache_src",
srcs = ["GrStrikeCache.cpp"],
visibility = ["//:__subpackages__"],
deps = [
":GrStrikeCache_hdr",
"//src/core:SkArenaAlloc_hdr",
"//src/core:SkStrikeSpec_hdr",
"//src/text/gpu:Glyph_hdr",
],
)
generated_cc_atom(
name = "GrTextBlob_hdr",
hdrs = ["GrTextBlob.h"],
@ -159,8 +136,8 @@ generated_cc_atom(
"//src/core:SkTInternalLList_hdr",
"//src/core:SkTLazy_hdr",
"//src/gpu/ganesh:GrColor_hdr",
"//src/gpu/ganesh:GrSubRunAllocator_hdr",
"//src/gpu/ganesh/ops:GrOp_hdr",
"//src/text/gpu:SubRunAllocator_hdr",
],
)
@ -170,9 +147,7 @@ generated_cc_atom(
visibility = ["//:__subpackages__"],
deps = [
":GrAtlasManager_hdr",
":GrGlyphVector_hdr",
":GrSDFTControl_hdr",
":GrStrikeCache_hdr",
":GrTextBlob_hdr",
"//include/core:SkColorFilter_hdr",
"//include/core:SkScalar_hdr",
@ -194,14 +169,16 @@ generated_cc_atom(
"//src/gpu/ganesh:GrMeshDrawTarget_hdr",
"//src/gpu/ganesh:GrRecordingContextPriv_hdr",
"//src/gpu/ganesh:GrStyle_hdr",
"//src/gpu/ganesh:GrSubRunAllocator_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:StrikeCache_hdr",
"//src/text/gpu:SubRunAllocator_hdr",
],
)
@ -229,34 +206,3 @@ generated_cc_atom(
"//src/gpu/ganesh/v1:SurfaceDrawContext_v1_hdr",
],
)
generated_cc_atom(
name = "GrGlyphVector_hdr",
hdrs = ["GrGlyphVector.h"],
visibility = ["//:__subpackages__"],
deps = [
":GrStrikeCache_hdr",
"//include/core:SkSpan_hdr",
"//src/core:SkGlyphBuffer_hdr",
"//src/core:SkGlyph_hdr",
"//src/gpu/ganesh:GrDrawOpAtlas_hdr",
"//src/gpu/ganesh:GrMeshDrawTarget_hdr",
"//src/gpu/ganesh:GrSubRunAllocator_hdr",
"//src/text/gpu:Glyph_hdr",
],
)
generated_cc_atom(
name = "GrGlyphVector_src",
srcs = ["GrGlyphVector.cpp"],
visibility = ["//:__subpackages__"],
deps = [
":GrAtlasManager_hdr",
":GrGlyphVector_hdr",
"//include/private/chromium:SkChromeRemoteGlyphCache_hdr",
"//src/core:SkReadBuffer_hdr",
"//src/core:SkStrikeCache_hdr",
"//src/core:SkStrikeSpec_hdr",
"//src/core:SkWriteBuffer_hdr",
],
)

View File

@ -12,8 +12,9 @@
#include "src/core/SkAutoMalloc.h"
#include "src/core/SkDistanceFieldGen.h"
#include "src/gpu/ganesh/GrImageInfo.h"
#include "src/gpu/ganesh/text/GrStrikeCache.h"
#include "src/text/gpu/Glyph.h"
#include "src/text/gpu/StrikeCache.h"
using Glyph = sktext::gpu::Glyph;
using MaskFormat = skgpu::MaskFormat;

View File

@ -36,7 +36,7 @@ public:
~GrAtlasManager() override;
// if getViews returns nullptr, the client must not try to use other functions on the
// GrStrikeCache which use the atlas. This function *must* be called first, before other
// StrikeCache which use the atlas. This function *must* be called first, before other
// functions which use the atlas. Note that we can have proxies available but none active
// (i.e., none instantiated).
const GrSurfaceProxyView* getViews(skgpu::MaskFormat format, unsigned int* numActiveProxies) {
@ -120,7 +120,7 @@ private:
bool initAtlas(skgpu::MaskFormat);
// Change an expected 565 mask format to 8888 if 565 is not supported (will happen when using
// Metal on macOS). The actual conversion of the data is handled in get_packed_glyph_image() in
// GrStrikeCache.cpp
// StrikeCache.cpp
skgpu::MaskFormat resolveMaskFormat(skgpu::MaskFormat format) const {
if (skgpu::MaskFormat::kA565 == format &&
!fProxyProvider->caps()->getDefaultBackendFormat(GrColorType::kBGR_565,

View File

@ -1,62 +0,0 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkStrikeSpec.h"
#include "src/gpu/ganesh/text/GrStrikeCache.h"
#include "src/text/gpu/Glyph.h"
using Glyph = sktext::gpu::Glyph;
GrStrikeCache::~GrStrikeCache() {
this->freeAll();
}
void GrStrikeCache::freeAll() {
fCache.reset();
}
sk_sp<GrTextStrike> GrStrikeCache::findOrCreateStrike(const SkStrikeSpec& strikeSpec) {
if (sk_sp<GrTextStrike>* cached = fCache.find(strikeSpec.descriptor())) {
return *cached;
}
return this->generateStrike(strikeSpec);
}
sk_sp<GrTextStrike> GrStrikeCache::generateStrike(const SkStrikeSpec& strikeSpec) {
sk_sp<GrTextStrike> strike = sk_make_sp<GrTextStrike>(strikeSpec);
fCache.set(strike);
return strike;
}
const SkDescriptor& GrStrikeCache::HashTraits::GetKey(const sk_sp<GrTextStrike>& strike) {
return strike->fStrikeSpec.descriptor();
}
uint32_t GrStrikeCache::HashTraits::Hash(const SkDescriptor& descriptor) {
return descriptor.getChecksum();
}
GrTextStrike::GrTextStrike(const SkStrikeSpec& strikeSpec) : fStrikeSpec{strikeSpec} {}
Glyph* GrTextStrike::getGlyph(SkPackedGlyphID packedGlyphID) {
Glyph* glyph = fCache.findOrNull(packedGlyphID);
if (glyph == nullptr) {
glyph = fAlloc.make<Glyph>(packedGlyphID);
fCache.set(glyph);
}
return glyph;
}
const SkPackedGlyphID& GrTextStrike::HashTraits::GetKey(const Glyph* glyph) {
return glyph->fPackedID;
}
uint32_t GrTextStrike::HashTraits::Hash(SkPackedGlyphID key) {
return key.hash();
}

View File

@ -1,74 +0,0 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrStrikeCache_DEFINED
#define GrStrikeCache_DEFINED
#include "include/private/SkTHash.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkStrikeSpec.h"
class GrStrikeCache;
namespace sktext::gpu {
class Glyph;
}
// The GrTextStrike manages an SkArenaAlloc for Glyphs. The SkStrike is what actually creates
// the mask. The GrTextStrike may outlive the generating SkStrike. However, it retains a copy
// of it's SkDescriptor as a key to access (or regenerate) the SkStrike. GrTextStrikes are
// created by and owned by a GrStrikeCache.
class GrTextStrike : public SkNVRefCnt<GrTextStrike> {
public:
GrTextStrike(const SkStrikeSpec& strikeSpec);
sktext::gpu::Glyph* getGlyph(SkPackedGlyphID);
const SkStrikeSpec& strikeSpec() const { return fStrikeSpec; }
private:
// Key for retrieving the SkStrike for creating new atlas data.
const SkStrikeSpec fStrikeSpec;
struct HashTraits {
static const SkPackedGlyphID& GetKey(const sktext::gpu::Glyph* glyph);
static uint32_t Hash(SkPackedGlyphID key);
};
// Map SkPackedGlyphID -> Glyph*.
SkTHashTable<sktext::gpu::Glyph*, SkPackedGlyphID, HashTraits> fCache;
// Store for the glyph information.
SkArenaAlloc fAlloc{512};
friend class GrStrikeCache;
};
// GrStrikeCache manages strikes which are indexed by a SkStrike. These strikes can then be
// used to generate individual Glyph Masks.
class GrStrikeCache {
public:
~GrStrikeCache();
// The user of the cache may hold a long-lived ref to the returned strike.
sk_sp<GrTextStrike> findOrCreateStrike(const SkStrikeSpec& strikeSpec);
void freeAll();
private:
sk_sp<GrTextStrike> generateStrike(const SkStrikeSpec& strikeSpec);
struct HashTraits {
static const SkDescriptor& GetKey(const sk_sp<GrTextStrike>& strike);
static uint32_t Hash(const SkDescriptor& strikeSpec);
};
using StrikeHash = SkTHashTable<sk_sp<GrTextStrike>, const SkDescriptor&, HashTraits>;
StrikeHash fCache;
};
#endif // GrStrikeCache_DEFINED

View File

@ -24,17 +24,17 @@
#include "src/gpu/ganesh/GrMeshDrawTarget.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/GrStyle.h"
#include "src/gpu/ganesh/GrSubRunAllocator.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/effects/GrDistanceFieldGeoProc.h"
#include "src/gpu/ganesh/geometry/GrStyledShape.h"
#include "src/gpu/ganesh/text/GrAtlasManager.h"
#include "src/gpu/ganesh/text/GrGlyphVector.h"
#include "src/gpu/ganesh/text/GrSDFTControl.h"
#include "src/gpu/ganesh/text/GrStrikeCache.h"
#include "src/gpu/ganesh/text/GrTextBlob.h"
#include "src/text/gpu/Glyph.h"
#include "src/text/gpu/GlyphVector.h"
#include "src/text/gpu/StrikeCache.h"
#include "src/text/gpu/SubRunAllocator.h"
#include "src/gpu/ganesh/GrBlurUtils.h"
#include "src/gpu/ganesh/ops/AtlasTextOp.h"
@ -42,9 +42,13 @@
#include "src/gpu/ganesh/v1/SurfaceDrawContext_v1.h"
using AtlasTextOp = skgpu::v1::AtlasTextOp;
using Glyph = sktext::gpu::Glyph;
using MaskFormat = skgpu::MaskFormat;
using Glyph = sktext::gpu::Glyph;
using GlyphVector = sktext::gpu::GlyphVector;
using StrikeCache = sktext::gpu::StrikeCache;
using SubRunAllocator = sktext::gpu::SubRunAllocator;
// -- GPU Text -------------------------------------------------------------------------------------
// There are three broad types of SubRun implementations for drawing text using the GPU.
// GrTextBlob (runs with no postfix) - these runs support drawing for GrTextBlobs.
@ -101,10 +105,10 @@ public:
int dstPadding,
SkScalar strikeToSourceScale,
const SkZip<SkGlyphVariant, SkPoint>& accepted,
GrSubRunAllocator* alloc);
SubRunAllocator* alloc);
static std::optional<TransformedMaskVertexFiller> MakeFromBuffer(
SkReadBuffer& buffer, GrSubRunAllocator* alloc);
SkReadBuffer& buffer, SubRunAllocator* alloc);
int unflattenSize() const;
void flatten(SkWriteBuffer& buffer) const;
@ -208,7 +212,7 @@ TransformedMaskVertexFiller TransformedMaskVertexFiller::Make(
int dstPadding,
SkScalar strikeToSourceScale,
const SkZip<SkGlyphVariant, SkPoint>& accepted,
GrSubRunAllocator* alloc) {
SubRunAllocator* alloc) {
SkRect sourceBounds = SkRectPriv::MakeLargestInverted();
SkSpan<PositionAndExtent> positionAndExtent = alloc->makePODArray<PositionAndExtent>(
accepted,
@ -235,7 +239,7 @@ static bool check_glyph_count(SkReadBuffer& buffer, int glyphCount) {
}
std::optional<TransformedMaskVertexFiller> TransformedMaskVertexFiller::MakeFromBuffer(
SkReadBuffer& buffer, GrSubRunAllocator* alloc) {
SkReadBuffer& buffer, SubRunAllocator* alloc) {
int checkingMaskType = buffer.readInt();
if (!buffer.validate(0 <= checkingMaskType && checkingMaskType < skgpu::kMaskFormatCount)) {
return {};
@ -468,19 +472,19 @@ public:
SkScalar strikeToSourceScale,
SkSpan<SkPoint> positions,
SkSpan<SkGlyphID> glyphIDs,
std::unique_ptr<SkPath[], GrSubRunAllocator::ArrayDestroyer> paths,
std::unique_ptr<SkPath[], SubRunAllocator::ArrayDestroyer> paths,
const SkDescriptor& descriptor);
static PathOpSubmitter Make(const SkZip<SkGlyphVariant, SkPoint>& accepted,
bool isAntiAliased,
SkScalar strikeToSourceScale,
const SkDescriptor& descriptor,
GrSubRunAllocator* alloc);
SubRunAllocator* alloc);
int unflattenSize() const;
void flatten(SkWriteBuffer& buffer) const;
static std::optional<PathOpSubmitter> MakeFromBuffer(SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
SubRunAllocator* alloc,
const SkStrikeClient* client);
void submitOps(SkCanvas*,
@ -495,7 +499,7 @@ private:
const SkScalar fStrikeToSourceScale;
const SkSpan<const SkPoint> fPositions;
const SkSpan<const SkGlyphID> fGlyphIDs;
std::unique_ptr<SkPath[], GrSubRunAllocator::ArrayDestroyer> fPaths;
std::unique_ptr<SkPath[], SubRunAllocator::ArrayDestroyer> fPaths;
const SkAutoDescriptor fDescriptor;
};
@ -517,7 +521,7 @@ void PathOpSubmitter::flatten(SkWriteBuffer& buffer) const {
}
std::optional<PathOpSubmitter> PathOpSubmitter::MakeFromBuffer(SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
SubRunAllocator* alloc,
const SkStrikeClient* client) {
bool isAntiAlias = buffer.readInt();
SkScalar strikeToSourceScale = buffer.readScalar();
@ -572,7 +576,7 @@ PathOpSubmitter::PathOpSubmitter(
SkScalar strikeToSourceScale,
SkSpan<SkPoint> positions,
SkSpan<SkGlyphID> glyphIDs,
std::unique_ptr<SkPath[], GrSubRunAllocator::ArrayDestroyer> paths,
std::unique_ptr<SkPath[], SubRunAllocator::ArrayDestroyer> paths,
const SkDescriptor& descriptor)
: fIsAntiAliased{isAntiAliased}
, fStrikeToSourceScale{strikeToSourceScale}
@ -587,7 +591,7 @@ PathOpSubmitter PathOpSubmitter::Make(const SkZip<SkGlyphVariant, SkPoint>& acce
bool isAntiAliased,
SkScalar strikeToSourceScale,
const SkDescriptor& descriptor,
GrSubRunAllocator* alloc) {
SubRunAllocator* alloc) {
int glyphCount = SkCount(accepted);
SkPoint* positions = alloc->makePODArray<SkPoint>(glyphCount);
SkGlyphID* glyphIDs = alloc->makePODArray<SkGlyphID>(glyphCount);
@ -673,7 +677,7 @@ public:
bool isAntiAliased,
SkScalar strikeToSourceScale,
const SkDescriptor& descriptor,
GrSubRunAllocator* alloc) {
SubRunAllocator* alloc) {
return alloc->makeUnique<PathSubRun>(
PathOpSubmitter::Make(
accepted, isAntiAliased, strikeToSourceScale, descriptor, alloc));
@ -696,7 +700,7 @@ public:
const GrAtlasSubRun* testingOnly_atlasSubRun() const override { return nullptr; }
static GrSubRunOwner MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
SubRunAllocator* alloc,
const SkStrikeClient* client);
protected:
@ -717,7 +721,7 @@ void PathSubRun::doFlatten(SkWriteBuffer& buffer) const {
GrSubRunOwner PathSubRun::MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
SubRunAllocator* alloc,
const SkStrikeClient* client) {
auto pathOpSubmitter = PathOpSubmitter::MakeFromBuffer(buffer, alloc, client);
if (!buffer.validate(pathOpSubmitter.has_value())) { return nullptr; }
@ -732,18 +736,18 @@ public:
SkSpan<SkPoint> positions,
SkSpan<SkGlyphID> glyphIDs,
std::unique_ptr<sk_sp<SkDrawable>[],
GrSubRunAllocator::ArrayDestroyer> drawableData,
SubRunAllocator::ArrayDestroyer> drawableData,
const SkDescriptor& descriptor);
static DrawableOpSubmitter Make(const SkZip<SkGlyphVariant, SkPoint>& accepted,
SkScalar strikeToSourceScale,
const SkDescriptor& descriptor,
GrSubRunAllocator* alloc);
SubRunAllocator* alloc);
int unflattenSize() const;
void flatten(SkWriteBuffer& buffer) const;
static std::optional<DrawableOpSubmitter> MakeFromBuffer(SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
SubRunAllocator* alloc,
const SkStrikeClient* client);
void submitOps(SkCanvas*,
@ -757,7 +761,7 @@ private:
const SkScalar fStrikeToSourceScale;
const SkSpan<SkPoint> fPositions;
const SkSpan<SkGlyphID> fGlyphIDs;
std::unique_ptr<sk_sp<SkDrawable>[], GrSubRunAllocator::ArrayDestroyer> fDrawables;
std::unique_ptr<sk_sp<SkDrawable>[], SubRunAllocator::ArrayDestroyer> fDrawables;
const SkAutoDescriptor fDescriptor;
};
@ -780,7 +784,7 @@ void DrawableOpSubmitter::flatten(SkWriteBuffer& buffer) const {
}
std::optional<DrawableOpSubmitter> DrawableOpSubmitter::MakeFromBuffer(
SkReadBuffer& buffer, GrSubRunAllocator* alloc, const SkStrikeClient* client) {
SkReadBuffer& buffer, SubRunAllocator* alloc, const SkStrikeClient* client) {
SkScalar strikeToSourceScale = buffer.readScalar();
int glyphCount = buffer.readInt();
@ -830,7 +834,7 @@ DrawableOpSubmitter::DrawableOpSubmitter(
SkSpan<SkPoint> positions,
SkSpan<SkGlyphID> glyphIDs,
std::unique_ptr<sk_sp<SkDrawable>[],
GrSubRunAllocator::ArrayDestroyer> drawables,
SubRunAllocator::ArrayDestroyer> drawables,
const SkDescriptor& descriptor)
: fStrikeToSourceScale{strikeToSourceScale}
, fPositions{positions}
@ -843,7 +847,7 @@ DrawableOpSubmitter::DrawableOpSubmitter(
DrawableOpSubmitter DrawableOpSubmitter::Make(const SkZip<SkGlyphVariant, SkPoint>& accepted,
SkScalar strikeToSourceScale,
const SkDescriptor& descriptor,
GrSubRunAllocator* alloc) {
SubRunAllocator* alloc) {
int glyphCount = SkCount(accepted);
SkPoint* positions = alloc->makePODArray<SkPoint>(glyphCount);
SkGlyphID* glyphIDs = alloc->makePODArray<SkGlyphID>(glyphCount);
@ -892,7 +896,7 @@ template <typename SubRun>
GrSubRunOwner make_drawable_sub_run(const SkZip<SkGlyphVariant, SkPoint>& drawables,
SkScalar strikeToSourceScale,
const SkDescriptor& descriptor,
GrSubRunAllocator* alloc) {
SubRunAllocator* alloc) {
return alloc->makeUnique<SubRun>(
DrawableOpSubmitter::Make(drawables, strikeToSourceScale, descriptor, alloc));
}
@ -905,7 +909,7 @@ public:
static GrSubRunOwner MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
SubRunAllocator* alloc,
const SkStrikeClient* client);
void draw(SkCanvas* canvas,
@ -941,7 +945,7 @@ void DrawableSubRun::doFlatten(SkWriteBuffer& buffer) const {
GrSubRunOwner DrawableSubRun::MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
SubRunAllocator* alloc,
const SkStrikeClient* client) {
auto drawableOpSubmitter = DrawableOpSubmitter::MakeFromBuffer(buffer, alloc, client);
if (!buffer.validate(drawableOpSubmitter.has_value())) { return nullptr; }
@ -1076,18 +1080,18 @@ public:
MaskFormat format,
SkGlyphRect deviceBounds,
SkSpan<const DevicePosition> devicePositions,
GrGlyphVector&& glyphs,
GlyphVector&& glyphs,
bool glyphsOutOfBounds);
static GrSubRunOwner Make(const GrTextReferenceFrame* referenceFrame,
const SkZip<SkGlyphVariant, SkPoint>& accepted,
sk_sp<SkStrike>&& strike,
MaskFormat format,
GrSubRunAllocator* alloc);
SubRunAllocator* alloc);
static GrSubRunOwner MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
SubRunAllocator* alloc,
const SkStrikeClient* client);
void draw(SkCanvas*,
@ -1110,7 +1114,7 @@ public:
const SkPaint&,
skgpu::v1::SurfaceDrawContext*) const override;
void testingOnly_packedGlyphIDToGlyph(GrStrikeCache *cache) const override;
void testingOnly_packedGlyphIDToGlyph(StrikeCache *cache) const override;
std::tuple<bool, int>
regenerateAtlas(int begin, int end, GrMeshDrawTarget*) const override;
@ -1144,15 +1148,15 @@ private:
// The regenerateAtlas method mutates fGlyphs. It should be called from onPrepare which must
// be single threaded.
mutable GrGlyphVector fGlyphs;
mutable GlyphVector fGlyphs;
};
DirectMaskSubRun::DirectMaskSubRun(const GrTextReferenceFrame* referenceFrame,
MaskFormat format,
SkGlyphRect deviceBounds,
SkSpan<const DevicePosition> devicePositions,
GrGlyphVector&& glyphs,
bool glyphsOutOfBounds)
MaskFormat format,
SkGlyphRect deviceBounds,
SkSpan<const DevicePosition> devicePositions,
GlyphVector&& glyphs,
bool glyphsOutOfBounds)
: fReferenceFrame{referenceFrame}
, fMaskFormat{format}
, fGlyphDeviceBounds{deviceBounds}
@ -1161,12 +1165,12 @@ DirectMaskSubRun::DirectMaskSubRun(const GrTextReferenceFrame* referenceFrame,
, fGlyphs{std::move(glyphs)} { }
GrSubRunOwner DirectMaskSubRun::Make(const GrTextReferenceFrame* referenceFrame,
const SkZip<SkGlyphVariant, SkPoint>& accepted,
sk_sp<SkStrike>&& strike,
MaskFormat format,
GrSubRunAllocator* alloc) {
const SkZip<SkGlyphVariant, SkPoint>& accepted,
sk_sp<SkStrike>&& strike,
MaskFormat format,
SubRunAllocator* alloc) {
auto glyphLeftTop = alloc->makePODArray<DevicePosition>(accepted.size());
auto glyphIDs = alloc->makePODArray<GrGlyphVector::Variant>(accepted.size());
auto glyphIDs = alloc->makePODArray<GlyphVector::Variant>(accepted.size());
// Because this is the direct case, the maximum width or height is the size that fits in the
// atlas. This boundary is checked below to ensure that the call to SkGlyphRect below will
@ -1202,7 +1206,7 @@ GrSubRunOwner DirectMaskSubRun::Make(const GrTextReferenceFrame* referenceFrame,
SkSpan<const DevicePosition> leftTop{glyphLeftTop, goodPosCount};
return alloc->makeUnique<DirectMaskSubRun>(
referenceFrame, format, runBounds, leftTop,
GrGlyphVector{std::move(strike), {glyphIDs, goodPosCount}},
GlyphVector{std::move(strike), {glyphIDs, goodPosCount}},
glyphsExcluded);
}
@ -1220,9 +1224,9 @@ bool DirectMaskSubRun::canReuse(const SkPaint& paint, const SkMatrix& positionMa
}
GrSubRunOwner DirectMaskSubRun::MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
const SkStrikeClient* client) {
SkReadBuffer& buffer,
SubRunAllocator* alloc,
const SkStrikeClient* client) {
MaskFormat maskType = (MaskFormat)buffer.readInt();
SkGlyphRect runBounds;
pun_read(buffer, &runBounds);
@ -1236,7 +1240,7 @@ GrSubRunOwner DirectMaskSubRun::MakeFromBuffer(const GrTextReferenceFrame* refer
}
SkSpan<DevicePosition> positions(positionsData, glyphCount);
auto glyphVector = GrGlyphVector::MakeFromBuffer(buffer, client, alloc);
auto glyphVector = GlyphVector::MakeFromBuffer(buffer, client, alloc);
if (!buffer.validate(glyphVector.has_value())) { return nullptr; }
if (!buffer.validate(SkCount(glyphVector->glyphs()) == glyphCount)) { return nullptr; }
SkASSERT(buffer.isValid());
@ -1360,7 +1364,7 @@ std::tuple<const GrClip*, GrOp::Owner> DirectMaskSubRun::makeAtlasTextOp(const G
return {clip, std::move(op)};
}
void DirectMaskSubRun::testingOnly_packedGlyphIDToGlyph(GrStrikeCache *cache) const {
void DirectMaskSubRun::testingOnly_packedGlyphIDToGlyph(StrikeCache *cache) const {
fGlyphs.packedGlyphIDToGlyph(cache);
}
@ -1513,18 +1517,18 @@ class TransformedMaskSubRun final : public GrSubRun, public GrAtlasSubRun {
public:
TransformedMaskSubRun(const GrTextReferenceFrame* referenceFrame,
TransformedMaskVertexFiller&& vertexFiller,
GrGlyphVector&& glyphs);
GlyphVector&& glyphs);
static GrSubRunOwner Make(const GrTextReferenceFrame* referenceFrame,
const SkZip<SkGlyphVariant, SkPoint>& accepted,
sk_sp<SkStrike>&& strike,
SkScalar strikeToSourceScale,
MaskFormat maskType,
GrSubRunAllocator* alloc);
SubRunAllocator* alloc);
static GrSubRunOwner MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
SubRunAllocator* alloc,
const SkStrikeClient* client);
void draw(SkCanvas*,
@ -1547,7 +1551,7 @@ public:
const GrAtlasSubRun* testingOnly_atlasSubRun() const override;
void testingOnly_packedGlyphIDToGlyph(GrStrikeCache *cache) const override;
void testingOnly_packedGlyphIDToGlyph(StrikeCache *cache) const override;
std::tuple<bool, int> regenerateAtlas(int begin, int end, GrMeshDrawTarget*) const override;
@ -1574,12 +1578,12 @@ private:
// The regenerateAtlas method mutates fGlyphs. It should be called from onPrepare which must
// be single threaded.
mutable GrGlyphVector fGlyphs;
mutable GlyphVector fGlyphs;
};
TransformedMaskSubRun::TransformedMaskSubRun(const GrTextReferenceFrame* referenceFrame,
TransformedMaskVertexFiller&& vertexFiller,
GrGlyphVector&& glyphs)
GlyphVector&& glyphs)
: fReferenceFrame{referenceFrame}
, fVertexFiller{std::move(vertexFiller)}
, fGlyphs{std::move(glyphs)} { }
@ -1589,11 +1593,11 @@ GrSubRunOwner TransformedMaskSubRun::Make(const GrTextReferenceFrame* referenceF
sk_sp<SkStrike>&& strike,
SkScalar strikeToSourceScale,
MaskFormat maskType,
GrSubRunAllocator* alloc) {
SubRunAllocator* alloc) {
auto vertexFiller = TransformedMaskVertexFiller::Make(
maskType, 0, strikeToSourceScale, accepted, alloc);
auto glyphVector = GrGlyphVector::Make(std::move(strike), accepted.get<0>(), alloc);
auto glyphVector = GlyphVector::Make(std::move(strike), accepted.get<0>(), alloc);
return alloc->makeUnique<TransformedMaskSubRun>(
referenceFrame, std::move(vertexFiller), std::move(glyphVector));
@ -1601,12 +1605,12 @@ GrSubRunOwner TransformedMaskSubRun::Make(const GrTextReferenceFrame* referenceF
GrSubRunOwner TransformedMaskSubRun::MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
SubRunAllocator* alloc,
const SkStrikeClient* client) {
auto vertexFiller = TransformedMaskVertexFiller::MakeFromBuffer(buffer, alloc);
if (!buffer.validate(vertexFiller.has_value())) { return {}; }
auto glyphVector = GrGlyphVector::MakeFromBuffer(buffer, client, alloc);
auto glyphVector = GlyphVector::MakeFromBuffer(buffer, client, alloc);
if (!buffer.validate(glyphVector.has_value())) { return {}; }
if (!buffer.validate(SkCount(glyphVector->glyphs()) == vertexFiller->count())) { return {}; }
return alloc->makeUnique<TransformedMaskSubRun>(
@ -1676,7 +1680,7 @@ bool TransformedMaskSubRun::canReuse(const SkPaint& paint, const SkMatrix& posit
return true;
}
void TransformedMaskSubRun::testingOnly_packedGlyphIDToGlyph(GrStrikeCache *cache) const {
void TransformedMaskSubRun::testingOnly_packedGlyphIDToGlyph(StrikeCache *cache) const {
fGlyphs.packedGlyphIDToGlyph(cache);
}
@ -1722,7 +1726,7 @@ public:
bool antiAliased,
const GrSDFTMatrixRange& matrixRange,
TransformedMaskVertexFiller&& vertexFiller,
GrGlyphVector&& glyphs);
GlyphVector&& glyphs);
static GrSubRunOwner Make(const GrTextReferenceFrame* referenceFrame,
const SkZip<SkGlyphVariant, SkPoint>& accepted,
@ -1730,11 +1734,11 @@ public:
sk_sp<SkStrike>&& strike,
SkScalar strikeToSourceScale,
const GrSDFTMatrixRange& matrixRange,
GrSubRunAllocator* alloc);
SubRunAllocator* alloc);
static GrSubRunOwner MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
SubRunAllocator* alloc,
const SkStrikeClient* client);
void draw(SkCanvas*,
@ -1757,7 +1761,7 @@ public:
const GrAtlasSubRun* testingOnly_atlasSubRun() const override;
void testingOnly_packedGlyphIDToGlyph(GrStrikeCache *cache) const override;
void testingOnly_packedGlyphIDToGlyph(StrikeCache *cache) const override;
std::tuple<bool, int> regenerateAtlas(int begin, int end, GrMeshDrawTarget*) const override;
@ -1787,7 +1791,7 @@ private:
// The regenerateAtlas method mutates fGlyphs. It should be called from onPrepare which must
// be single threaded.
mutable GrGlyphVector fGlyphs;
mutable GlyphVector fGlyphs;
};
SDFTSubRun::SDFTSubRun(const GrTextReferenceFrame* referenceFrame,
@ -1795,7 +1799,7 @@ SDFTSubRun::SDFTSubRun(const GrTextReferenceFrame* referenceFrame,
bool antiAliased,
const GrSDFTMatrixRange& matrixRange,
TransformedMaskVertexFiller&& vertexFiller,
GrGlyphVector&& glyphs)
GlyphVector&& glyphs)
: fReferenceFrame{referenceFrame}
, fUseLCDText{useLCDText}
, fAntiAliased{antiAliased}
@ -1815,7 +1819,7 @@ GrSubRunOwner SDFTSubRun::Make(const GrTextReferenceFrame* referenceFrame,
sk_sp<SkStrike>&& strike,
SkScalar strikeToSourceScale,
const GrSDFTMatrixRange& matrixRange,
GrSubRunAllocator* alloc) {
SubRunAllocator* alloc) {
auto vertexFiller = TransformedMaskVertexFiller::Make(
MaskFormat::kA8,
SK_DistanceFieldInset,
@ -1823,7 +1827,7 @@ GrSubRunOwner SDFTSubRun::Make(const GrTextReferenceFrame* referenceFrame,
accepted,
alloc);
auto glyphVector = GrGlyphVector::Make(std::move(strike), accepted.get<0>(), alloc);
auto glyphVector = GlyphVector::Make(std::move(strike), accepted.get<0>(), alloc);
return alloc->makeUnique<SDFTSubRun>(
referenceFrame,
@ -1836,14 +1840,14 @@ GrSubRunOwner SDFTSubRun::Make(const GrTextReferenceFrame* referenceFrame,
GrSubRunOwner SDFTSubRun::MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
SubRunAllocator* alloc,
const SkStrikeClient* client) {
int useLCD = buffer.readInt();
int isAntiAliased = buffer.readInt();
GrSDFTMatrixRange matrixRange = GrSDFTMatrixRange::MakeFromBuffer(buffer);
auto vertexFiller = TransformedMaskVertexFiller::MakeFromBuffer(buffer, alloc);
if (!buffer.validate(vertexFiller.has_value())) { return {}; }
auto glyphVector = GrGlyphVector::MakeFromBuffer(buffer, client, alloc);
auto glyphVector = GlyphVector::MakeFromBuffer(buffer, client, alloc);
if (!buffer.validate(glyphVector.has_value())) { return {}; }
if (!buffer.validate(SkCount(glyphVector->glyphs()) == vertexFiller->count())) { return {}; }
return alloc->makeUnique<SDFTSubRun>(referenceFrame,
@ -1950,7 +1954,7 @@ bool SDFTSubRun::canReuse(const SkPaint& paint, const SkMatrix& positionMatrix)
return fMatrixRange.matrixInRange(positionMatrix);
}
void SDFTSubRun::testingOnly_packedGlyphIDToGlyph(GrStrikeCache *cache) const {
void SDFTSubRun::testingOnly_packedGlyphIDToGlyph(StrikeCache *cache) const {
fGlyphs.packedGlyphIDToGlyph(cache);
}
@ -2175,11 +2179,11 @@ sk_sp<GrTextBlob> GrTextBlob::Make(const SkGlyphRunList& glyphRunList,
// The neededForSubRun is optimized for DirectMaskSubRun which is by far the most common case.
size_t subRunSizeHint =
totalGlyphCount * sizeof(DevicePosition)
+ GrGlyphVector::GlyphVectorSize(totalGlyphCount)
+ GlyphVector::GlyphVectorSize(totalGlyphCount)
+ glyphRunList.runCount() * (sizeof(DirectMaskSubRun) + vertexDataToSubRunPadding);
auto [initializer, totalMemoryAllocated, alloc] =
GrSubRunAllocator::AllocateClassMemoryAndArena<GrTextBlob>(subRunSizeHint);
SubRunAllocator::AllocateClassMemoryAndArena<GrTextBlob>(subRunSizeHint);
SkColor initialLuminance = SkPaintPriv::ComputeLuminanceColor(paint);
sk_sp<GrTextBlob> blob = sk_sp<GrTextBlob>(initializer.initialize(
std::move(alloc), totalMemoryAllocated, positionMatrix, initialLuminance));
@ -2252,7 +2256,7 @@ const GrAtlasSubRun* GrTextBlob::testingOnlyFirstSubRun() const {
return fSubRunList.front().testingOnly_atlasSubRun();
}
GrTextBlob::GrTextBlob(GrSubRunAllocator&& alloc,
GrTextBlob::GrTextBlob(SubRunAllocator&& alloc,
int totalMemorySize,
const SkMatrix& positionMatrix,
SkColor initialLuminance)
@ -2324,7 +2328,7 @@ namespace {
// -- Slug -----------------------------------------------------------------------------------------
class Slug final : public GrSlug, public SkGlyphRunPainterInterface {
public:
Slug(GrSubRunAllocator&& alloc,
Slug(SubRunAllocator&& alloc,
SkRect sourceBounds,
const SkPaint& paint,
const SkMatrix& positionMatrix,
@ -2390,7 +2394,7 @@ public:
private:
// The allocator must come first because it needs to be destroyed last. Other fields of this
// structure may have pointers into it.
GrSubRunAllocator fAlloc;
SubRunAllocator fAlloc;
const SkRect fSourceBounds;
const SkPaint fInitialPaint;
const SkMatrix fInitialPositionMatrix;
@ -2398,7 +2402,7 @@ private:
GrSubRunList fSubRuns;
};
Slug::Slug(GrSubRunAllocator&& alloc,
Slug::Slug(SubRunAllocator&& alloc,
SkRect sourceBounds,
const SkPaint& initialPaint,
const SkMatrix& positionMatrix,
@ -2450,7 +2454,7 @@ sk_sp<GrSlug> Slug::MakeFromBuffer(SkReadBuffer& buffer, const SkStrikeClient* c
}
auto [initializer, _, alloc] =
GrSubRunAllocator::AllocateClassMemoryAndArena<Slug>(subRunsSizeHint);
SubRunAllocator::AllocateClassMemoryAndArena<Slug>(subRunsSizeHint);
sk_sp<Slug> slug = sk_sp<Slug>(
initializer.initialize(std::move(alloc), sourceBounds, paint, positionMatrix, origin));
@ -2499,11 +2503,11 @@ sk_sp<Slug> Slug::Make(const SkMatrixProvider& viewMatrix,
// common case.
size_t subRunSizeHint =
totalGlyphCount * sizeof(DevicePosition)
+ GrGlyphVector::GlyphVectorSize(totalGlyphCount)
+ GlyphVector::GlyphVectorSize(totalGlyphCount)
+ glyphRunList.runCount() * (sizeof(DirectMaskSubRun) + vertexDataToSubRunPadding);
auto [initializer, _, alloc] =
GrSubRunAllocator::AllocateClassMemoryAndArena<Slug>(subRunSizeHint);
SubRunAllocator::AllocateClassMemoryAndArena<Slug>(subRunSizeHint);
const SkMatrix positionMatrix =
position_matrix(viewMatrix.localToDevice(), glyphRunList.origin());
@ -2630,11 +2634,11 @@ void GrSubRun::flatten(SkWriteBuffer& buffer) const {
GrSubRunOwner GrSubRun::MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
SubRunAllocator* alloc,
const SkStrikeClient* client) {
using Maker = GrSubRunOwner (*)(const GrTextReferenceFrame*,
SkReadBuffer&,
GrSubRunAllocator*,
SubRunAllocator*,
const SkStrikeClient*);
static Maker makers[kSubRunTypeCount] = {

View File

@ -23,13 +23,12 @@
#include "src/core/SkTInternalLList.h"
#include "src/core/SkTLazy.h"
#include "src/gpu/ganesh/GrColor.h"
#include "src/gpu/ganesh/GrSubRunAllocator.h"
#include "src/gpu/ganesh/ops/GrOp.h"
#include "src/text/gpu/SubRunAllocator.h"
class GrAtlasManager;
class GrDeferredUploadTarget;
class GrMeshDrawTarget;
class GrStrikeCache;
class GrSubRun;
class SkMatrixProvider;
@ -40,6 +39,7 @@ class SkTextBlobRunIterator;
namespace sktext::gpu {
class Glyph;
class StrikeCache;
}
namespace skgpu::v1 { class SurfaceDrawContext; }
@ -59,7 +59,7 @@ namespace skgpu::v1 { class SurfaceDrawContext; }
// can fit in the atlas; the sizes between direct SubRun, and path SubRun. The destination
// rectangles are in source space.
class GrAtlasSubRun;
using GrAtlasSubRunOwner = std::unique_ptr<GrAtlasSubRun, GrSubRunAllocator::Destroyer>;
using GrAtlasSubRunOwner = std::unique_ptr<GrAtlasSubRun, sktext::gpu::SubRunAllocator::Destroyer>;
class GrAtlasSubRun {
public:
virtual ~GrAtlasSubRun() = default;
@ -82,7 +82,7 @@ public:
SkPoint drawOrigin,
SkIRect clip) const = 0;
virtual void testingOnly_packedGlyphIDToGlyph(GrStrikeCache* cache) 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.
@ -94,7 +94,7 @@ public:
// GrSubRun 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, GrSubRunAllocator::Destroyer>;
using GrSubRunOwner = std::unique_ptr<GrSubRun, sktext::gpu::SubRunAllocator::Destroyer>;
class GrBlobSubRun;
class GrSubRun {
public:
@ -111,7 +111,7 @@ public:
void flatten(SkWriteBuffer& buffer) const;
static GrSubRunOwner MakeFromBuffer(const GrTextReferenceFrame* referenceFrame,
SkReadBuffer& buffer,
GrSubRunAllocator* alloc,
sktext::gpu::SubRunAllocator* alloc,
const SkStrikeClient* client);
// Size hint for unflattening this run. If this is accurate, it will help with the allocation
@ -230,7 +230,7 @@ public:
const GrSDFTControl& control,
SkGlyphRunListPainter* painter);
GrTextBlob(GrSubRunAllocator&& alloc,
GrTextBlob(sktext::gpu::SubRunAllocator&& alloc,
int totalMemorySize,
const SkMatrix& positionMatrix,
SkColor initialLuminance);
@ -285,7 +285,7 @@ private:
// The allocator must come first because it needs to be destroyed last. Other fields of this
// structure may have pointers into it.
GrSubRunAllocator fAlloc;
sktext::gpu::SubRunAllocator fAlloc;
// Owner and list of the SubRun.
GrSubRunList fSubRunList;

View File

@ -53,7 +53,7 @@ public:
bool wrapsVkSecondaryCB() const { return this->asRenderTargetProxy()->wrapsVkSecondaryCB(); }
SkArenaAlloc* arenaAlloc() { return this->arenas()->arenaAlloc(); }
GrSubRunAllocator* subRunAlloc() { return this->arenas()->subRunAlloc(); }
sktext::gpu::SubRunAllocator* subRunAlloc() { return this->arenas()->subRunAlloc(); }
#if GR_TEST_UTILS
OpsTask* testingOnly_PeekLastOpsTask() { return fOpsTask.get(); }

View File

@ -4,6 +4,37 @@ licenses(["notice"])
exports_files_legacy()
generated_cc_atom(
name = "GlyphVector_hdr",
hdrs = ["GlyphVector.h"],
visibility = ["//:__subpackages__"],
deps = [
":Glyph_hdr",
":StrikeCache_hdr",
":SubRunAllocator_hdr",
"//include/core:SkSpan_hdr",
"//src/core:SkGlyphBuffer_hdr",
"//src/core:SkGlyph_hdr",
"//src/gpu/ganesh:GrDrawOpAtlas_hdr",
"//src/gpu/ganesh:GrMeshDrawTarget_hdr",
],
)
generated_cc_atom(
name = "GlyphVector_src",
srcs = ["GlyphVector.cpp"],
visibility = ["//:__subpackages__"],
deps = [
":GlyphVector_hdr",
"//include/private/chromium:SkChromeRemoteGlyphCache_hdr",
"//src/core:SkReadBuffer_hdr",
"//src/core:SkStrikeCache_hdr",
"//src/core:SkStrikeSpec_hdr",
"//src/core:SkWriteBuffer_hdr",
"//src/gpu/ganesh/text:GrAtlasManager_hdr",
],
)
generated_cc_atom(
name = "Glyph_hdr",
hdrs = ["Glyph.h"],
@ -14,3 +45,48 @@ generated_cc_atom(
"//src/gpu:AtlasTypes_hdr",
],
)
generated_cc_atom(
name = "StrikeCache_hdr",
hdrs = ["StrikeCache.h"],
visibility = ["//:__subpackages__"],
deps = [
"//include/private:SkTHash_hdr",
"//src/core:SkArenaAlloc_hdr",
"//src/core:SkStrikeSpec_hdr",
],
)
generated_cc_atom(
name = "StrikeCache_src",
srcs = ["StrikeCache.cpp"],
visibility = ["//:__subpackages__"],
deps = [
":Glyph_hdr",
":StrikeCache_hdr",
"//src/core:SkArenaAlloc_hdr",
"//src/core:SkStrikeSpec_hdr",
],
)
generated_cc_atom(
name = "SubRunAllocator_hdr",
hdrs = ["SubRunAllocator.h"],
visibility = ["//:__subpackages__"],
deps = [
"//include/core:SkMath_hdr",
"//include/core:SkSpan_hdr",
"//include/private:SkTemplates_hdr",
"//src/core:SkArenaAlloc_hdr",
],
)
generated_cc_atom(
name = "SubRunAllocator_src",
srcs = ["SubRunAllocator.cpp"],
visibility = ["//:__subpackages__"],
deps = [
":SubRunAllocator_hdr",
"//include/core:SkMath_hdr",
],
)

View File

@ -13,6 +13,7 @@
#include "src/gpu/AtlasTypes.h"
namespace sktext::gpu {
class Glyph {
public:
static skgpu::MaskFormat FormatFromSkGlyph(SkMask::Format format) {
@ -39,6 +40,6 @@ public:
skgpu::AtlasLocator fAtlasLocator;
};
}
} // namespace sktext::gpu
#endif
#endif // sktext_gpu_Glyph_DEFINED

View File

@ -5,27 +5,30 @@
* found in the LICENSE file.
*/
#include "src/gpu/ganesh/text/GrGlyphVector.h"
#include "src/text/gpu/GlyphVector.h"
#include "include/private/chromium/SkChromeRemoteGlyphCache.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkWriteBuffer.h"
#if SK_SUPPORT_GPU
#include "src/gpu/ganesh/text/GrAtlasManager.h"
#endif
using Glyph = sktext::gpu::Glyph;
using MaskFormat = skgpu::MaskFormat;
GrGlyphVector::GrGlyphVector(sk_sp<SkStrike>&& strike, SkSpan<Variant> glyphs)
: fStrike{std::move(strike)}
namespace sktext::gpu {
GlyphVector::GlyphVector(sk_sp<SkStrike>&& strike, SkSpan<Variant> glyphs)
: fSkStrike{std::move(strike)}
, fGlyphs{glyphs} {
SkASSERT(fStrike != nullptr);
SkASSERT(fSkStrike != nullptr);
SkASSERT(fGlyphs.size() > 0);
}
GrGlyphVector GrGlyphVector::Make(
sk_sp<SkStrike>&& strike, SkSpan<SkGlyphVariant> glyphs, GrSubRunAllocator* alloc) {
GlyphVector GlyphVector::Make(
sk_sp<SkStrike>&& strike, SkSpan<SkGlyphVariant> glyphs, SubRunAllocator* alloc) {
SkASSERT(strike != nullptr);
SkASSERT(glyphs.size() > 0);
Variant* variants = alloc->makePODArray<Variant>(glyphs.size());
@ -33,12 +36,12 @@ GrGlyphVector GrGlyphVector::Make(
variants[i] = gv.glyph()->getPackedID();
}
return GrGlyphVector{std::move(strike), SkMakeSpan(variants, glyphs.size())};
return GlyphVector{std::move(strike), SkMakeSpan(variants, glyphs.size())};
}
std::optional<GrGlyphVector> GrGlyphVector::MakeFromBuffer(SkReadBuffer& buffer,
const SkStrikeClient* client,
GrSubRunAllocator* alloc) {
std::optional<GlyphVector> GlyphVector::MakeFromBuffer(SkReadBuffer& buffer,
const SkStrikeClient* client,
SubRunAllocator* alloc) {
auto descriptor = SkAutoDescriptor::MakeFromBuffer(buffer);
if (!buffer.validate(descriptor.has_value())) { return {}; }
@ -65,15 +68,15 @@ std::optional<GrGlyphVector> GrGlyphVector::MakeFromBuffer(SkReadBuffer& buffer,
for (int i = 0; i < glyphCount; i++) {
variants[i].packedGlyphID = SkPackedGlyphID(buffer.readUInt());
}
return {GrGlyphVector{std::move(strike), SkMakeSpan(variants, glyphCount)}};
return {GlyphVector{std::move(strike), SkMakeSpan(variants, glyphCount)}};
}
void GrGlyphVector::flatten(SkWriteBuffer& buffer) {
void GlyphVector::flatten(SkWriteBuffer& buffer) {
// There should never be a glyph vector with zero glyphs.
SkASSERT(fGlyphs.size() != 0);
if (!fStrike) { SK_ABORT("Can't flatten with already drawn."); }
if (!fSkStrike) { SK_ABORT("Can't flatten with already drawn."); }
fStrike->getDescriptor().flatten(buffer);
fSkStrike->getDescriptor().flatten(buffer);
// Write out the span of packedGlyphIDs.
buffer.write32(SkTo<int32_t>(fGlyphs.size()));
@ -82,33 +85,34 @@ void GrGlyphVector::flatten(SkWriteBuffer& buffer) {
}
}
SkSpan<const Glyph*> GrGlyphVector::glyphs() const {
SkSpan<const Glyph*> GlyphVector::glyphs() const {
return SkMakeSpan(reinterpret_cast<const Glyph**>(fGlyphs.data()), fGlyphs.size());
}
// packedGlyphIDToGlyph must be run in single-threaded mode.
// If fStrike != nullptr then the conversion to Glyph* has not happened.
void GrGlyphVector::packedGlyphIDToGlyph(GrStrikeCache* cache) {
if (fStrike != nullptr) {
fGrStrike = cache->findOrCreateStrike(fStrike->strikeSpec());
// If fSkStrike != nullptr then the conversion to Glyph* has not happened.
void GlyphVector::packedGlyphIDToGlyph(StrikeCache* cache) {
if (fSkStrike != nullptr) {
fTextStrike = cache->findOrCreateStrike(fSkStrike->strikeSpec());
for (auto& variant : fGlyphs) {
variant.glyph = fGrStrike->getGlyph(variant.packedGlyphID);
variant.glyph = fTextStrike->getGlyph(variant.packedGlyphID);
}
// This must be pinned for the Atlas filling to work.
// TODO(herb): re-enable after the cut on 20220414
// fStrike->verifyPinnedStrike();
// fSkStrike->verifyPinnedStrike();
// Drop the ref on the strike that was taken in the SkGlyphRunPainter process* methods.
fStrike = nullptr;
fSkStrike = nullptr;
}
}
std::tuple<bool, int> GrGlyphVector::regenerateAtlas(int begin, int end,
MaskFormat maskFormat,
int srcPadding,
GrMeshDrawTarget* target) {
#if SK_SUPPORT_GPU
std::tuple<bool, int> GlyphVector::regenerateAtlas(int begin, int end,
MaskFormat maskFormat,
int srcPadding,
GrMeshDrawTarget* target) {
GrAtlasManager* atlasManager = target->atlasManager();
GrDeferredUploadTarget* uploadTarget = target->deferredUploadTarget();
@ -121,7 +125,7 @@ std::tuple<bool, int> GrGlyphVector::regenerateAtlas(int begin, int end,
// is set to kInvalidAtlasGeneration) or the atlas has changed in subsequent calls..
fBulkUseToken.reset();
SkBulkGlyphMetricsAndImages metricsAndImages{fGrStrike->strikeSpec()};
SkBulkGlyphMetricsAndImages metricsAndImages{fTextStrike->strikeSpec()};
// Update the atlas information in the GrStrike.
auto tokenTracker = uploadTarget->tokenTracker();
@ -129,7 +133,7 @@ std::tuple<bool, int> GrGlyphVector::regenerateAtlas(int begin, int end,
int glyphsPlacedInAtlas = 0;
bool success = true;
for (const Variant& variant : glyphs) {
sktext::gpu::Glyph* gpuGlyph = variant.glyph;
Glyph* gpuGlyph = variant.glyph;
SkASSERT(gpuGlyph != nullptr);
if (!atlasManager->hasGlyph(maskFormat, gpuGlyph)) {
@ -167,4 +171,6 @@ std::tuple<bool, int> GrGlyphVector::regenerateAtlas(int begin, int end,
return {true, end - begin};
}
}
#endif
} // namespace sktext::gpu

View File

@ -5,57 +5,63 @@
* found in the LICENSE file.
*/
#ifndef GrGlyphVector_DEFINED
#define GrGlyphVector_DEFINED
#ifndef sktext_gpu_GlyphVector_DEFINED
#define sktext_gpu_GlyphVector_DEFINED
#include "include/core/SkSpan.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkGlyphBuffer.h"
#if SK_SUPPORT_GPU
#include "src/gpu/ganesh/GrDrawOpAtlas.h"
#include "src/gpu/ganesh/GrMeshDrawTarget.h"
#include "src/gpu/ganesh/GrSubRunAllocator.h"
#include "src/gpu/ganesh/text/GrStrikeCache.h"
#endif
#include "src/text/gpu/Glyph.h"
#include "src/text/gpu/StrikeCache.h"
#include "src/text/gpu/SubRunAllocator.h"
class SkStrikeClient;
namespace sktext::gpu {
// -- GlyphVector ----------------------------------------------------------------------------------
// GlyphVector provides a way to delay the lookup of sktext::gpu::Glyphs until the code is running
// on the GPU in single threaded mode. The GlyphVector is created in a multi-threaded environment,
// but the GrStrikeCache is only single threaded (and must be single threaded because of the atlas).
class GrGlyphVector {
// GlyphVector provides a way to delay the lookup of Glyphs until the code is running on the GPU
// in single threaded mode. The GlyphVector is created in a multi-threaded environment, but the
// StrikeCache is only single threaded (and must be single threaded because of the atlas).
class GlyphVector {
public:
union Variant {
// Initially, filled with packed id, but changed to Glyph* in the onPrepare stage.
SkPackedGlyphID packedGlyphID;
sktext::gpu::Glyph* glyph;
Glyph* glyph;
// Add ctors to help SkArenaAlloc create arrays.
Variant() : glyph{nullptr} {}
Variant(SkPackedGlyphID id) : packedGlyphID{id} {}
};
GrGlyphVector(sk_sp<SkStrike>&& strike, SkSpan<Variant> glyphs);
GlyphVector(sk_sp<SkStrike>&& strike, SkSpan<Variant> glyphs);
static GrGlyphVector Make(
sk_sp<SkStrike>&& strike, SkSpan<SkGlyphVariant> glyphs, GrSubRunAllocator* alloc);
SkSpan<const sktext::gpu::Glyph*> glyphs() const;
static GlyphVector Make(
sk_sp<SkStrike>&& strike, SkSpan<SkGlyphVariant> glyphs, SubRunAllocator* alloc);
SkSpan<const Glyph*> glyphs() const;
static std::optional<GrGlyphVector> MakeFromBuffer(SkReadBuffer& buffer,
const SkStrikeClient* strikeClient,
GrSubRunAllocator* alloc);
static std::optional<GlyphVector> MakeFromBuffer(SkReadBuffer& buffer,
const SkStrikeClient* strikeClient,
SubRunAllocator* alloc);
void flatten(SkWriteBuffer& buffer);
// This doesn't need to include sizeof(GrGlyphVector) because this is embedded in each of
// This doesn't need to include sizeof(GlyphVector) because this is embedded in each of
// the sub runs.
int unflattenSize() const { return GlyphVectorSize(fGlyphs.size()); }
void packedGlyphIDToGlyph(GrStrikeCache* cache);
void packedGlyphIDToGlyph(StrikeCache* cache);
#if SK_SUPPORT_GPU
std::tuple<bool, int> regenerateAtlas(
int begin, int end,
skgpu::MaskFormat maskFormat,
int srcPadding,
GrMeshDrawTarget *);
#endif
static size_t GlyphVectorSize(size_t count) {
return sizeof(Variant) * count;
@ -63,10 +69,15 @@ public:
private:
friend class TestingPeer;
sk_sp<SkStrike> fStrike;
sk_sp<SkStrike> fSkStrike;
SkSpan<Variant> fGlyphs;
sk_sp<GrTextStrike> fGrStrike{nullptr};
sk_sp<TextStrike> fTextStrike{nullptr};
uint64_t fAtlasGeneration{skgpu::AtlasGenerationCounter::kInvalidGeneration};
#if SK_SUPPORT_GPU
GrDrawOpAtlas::BulkUseTokenUpdater fBulkUseToken;
#endif
};
#endif // GrGlyphVector_DEFINED
} // namespace sktext::gpu
#endif // sktext_gpu_GlyphVector_DEFINED

View File

@ -0,0 +1,63 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkStrikeSpec.h"
#include "src/text/gpu/Glyph.h"
#include "src/text/gpu/StrikeCache.h"
namespace sktext::gpu {
StrikeCache::~StrikeCache() {
this->freeAll();
}
void StrikeCache::freeAll() {
fCache.reset();
}
sk_sp<TextStrike> StrikeCache::findOrCreateStrike(const SkStrikeSpec& strikeSpec) {
if (sk_sp<TextStrike>* cached = fCache.find(strikeSpec.descriptor())) {
return *cached;
}
return this->generateStrike(strikeSpec);
}
sk_sp<TextStrike> StrikeCache::generateStrike(const SkStrikeSpec& strikeSpec) {
sk_sp<TextStrike> strike = sk_make_sp<TextStrike>(strikeSpec);
fCache.set(strike);
return strike;
}
const SkDescriptor& StrikeCache::HashTraits::GetKey(const sk_sp<TextStrike>& strike) {
return strike->fStrikeSpec.descriptor();
}
uint32_t StrikeCache::HashTraits::Hash(const SkDescriptor& descriptor) {
return descriptor.getChecksum();
}
TextStrike::TextStrike(const SkStrikeSpec& strikeSpec) : fStrikeSpec{strikeSpec} {}
Glyph* TextStrike::getGlyph(SkPackedGlyphID packedGlyphID) {
Glyph* glyph = fCache.findOrNull(packedGlyphID);
if (glyph == nullptr) {
glyph = fAlloc.make<Glyph>(packedGlyphID);
fCache.set(glyph);
}
return glyph;
}
const SkPackedGlyphID& TextStrike::HashTraits::GetKey(const Glyph* glyph) {
return glyph->fPackedID;
}
uint32_t TextStrike::HashTraits::Hash(SkPackedGlyphID key) {
return key.hash();
}
} // namespace sktext::gpu

View File

@ -0,0 +1,74 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef sktext_gpu_StrikeCache_DEFINED
#define sktext_gpu_StrikeCache_DEFINED
#include "include/private/SkTHash.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkStrikeSpec.h"
namespace sktext::gpu {
class Glyph;
class StrikeCache;
// The TextStrike manages an SkArenaAlloc for Glyphs. The SkStrike is what actually creates
// the mask. The TextStrike may outlive the generating SkStrike. However, it retains a copy
// of it's SkDescriptor as a key to access (or regenerate) the SkStrike. TextStrikes are
// created by and owned by a StrikeCache.
class TextStrike : public SkNVRefCnt<TextStrike> {
public:
TextStrike(const SkStrikeSpec& strikeSpec);
Glyph* getGlyph(SkPackedGlyphID);
const SkStrikeSpec& strikeSpec() const { return fStrikeSpec; }
private:
// Key for retrieving the SkStrike for creating new atlas data.
const SkStrikeSpec fStrikeSpec;
struct HashTraits {
static const SkPackedGlyphID& GetKey(const Glyph* glyph);
static uint32_t Hash(SkPackedGlyphID key);
};
// Map SkPackedGlyphID -> Glyph*.
SkTHashTable<Glyph*, SkPackedGlyphID, HashTraits> fCache;
// Store for the glyph information.
SkArenaAlloc fAlloc{512};
friend class StrikeCache;
};
// StrikeCache manages strikes which are indexed by a SkStrike. These strikes can then be
// used to generate individual Glyph Masks.
class StrikeCache {
public:
~StrikeCache();
// The user of the cache may hold a long-lived ref to the returned strike.
sk_sp<TextStrike> findOrCreateStrike(const SkStrikeSpec& strikeSpec);
void freeAll();
private:
sk_sp<TextStrike> generateStrike(const SkStrikeSpec& strikeSpec);
struct HashTraits {
static const SkDescriptor& GetKey(const sk_sp<TextStrike>& strike);
static uint32_t Hash(const SkDescriptor& strikeSpec);
};
using StrikeHash = SkTHashTable<sk_sp<TextStrike>, const SkDescriptor&, HashTraits>;
StrikeHash fCache;
};
} // namespace sktext::gpu
#endif // sktext_gpu_StrikeCache_DEFINED

View File

@ -6,15 +6,17 @@
*/
#include "include/core/SkMath.h"
#include "src/gpu/ganesh/GrSubRunAllocator.h"
#include "src/text/gpu/SubRunAllocator.h"
#include <cstddef>
#include <memory>
#include <new>
#include <utility>
// -- GrBagOfBytes ---------------------------------------------------------------------------------
GrBagOfBytes::GrBagOfBytes(char* bytes, size_t size, size_t firstHeapAllocation)
namespace sktext::gpu {
// -- BagOfBytes ---------------------------------------------------------------------------------
BagOfBytes::BagOfBytes(char* bytes, size_t size, size_t firstHeapAllocation)
: fFibProgression(size, firstHeapAllocation) {
SkASSERT_RELEASE(size < kMaxByteSize);
SkASSERT_RELEASE(firstHeapAllocation < kMaxByteSize);
@ -27,10 +29,10 @@ GrBagOfBytes::GrBagOfBytes(char* bytes, size_t size, size_t firstHeapAllocation)
}
}
GrBagOfBytes::GrBagOfBytes(size_t firstHeapAllocation)
: GrBagOfBytes(nullptr, 0, firstHeapAllocation) {}
BagOfBytes::BagOfBytes(size_t firstHeapAllocation)
: BagOfBytes(nullptr, 0, firstHeapAllocation) {}
GrBagOfBytes::~GrBagOfBytes() {
BagOfBytes::~BagOfBytes() {
Block* cursor = reinterpret_cast<Block*>(fEndByte);
while (cursor != nullptr) {
char* toDelete = cursor->fBlockStart;
@ -39,11 +41,11 @@ GrBagOfBytes::~GrBagOfBytes() {
}
}
GrBagOfBytes::Block::Block(char* previous, char* startOfBlock)
BagOfBytes::Block::Block(char* previous, char* startOfBlock)
: fBlockStart{startOfBlock}
, fPrevious{reinterpret_cast<Block*>(previous)} {}
void* GrBagOfBytes::alignedBytes(int size, int alignment) {
void* BagOfBytes::alignedBytes(int size, int alignment) {
SkASSERT_RELEASE(0 < size && size < kMaxByteSize);
SkASSERT_RELEASE(0 < alignment && alignment <= kMaxAlignment);
SkASSERT_RELEASE(SkIsPow2(alignment));
@ -51,7 +53,7 @@ void* GrBagOfBytes::alignedBytes(int size, int alignment) {
return this->allocateBytes(size, alignment);
}
void GrBagOfBytes::setupBytesAndCapacity(char* bytes, int size) {
void BagOfBytes::setupBytesAndCapacity(char* bytes, int size) {
// endByte must be aligned to the maximum alignment to allow tracking alignment using capacity;
// capacity and endByte are both aligned to max alignment.
intptr_t endByte = reinterpret_cast<intptr_t>(bytes + size - sizeof(Block)) & -kMaxAlignment;
@ -59,7 +61,7 @@ void GrBagOfBytes::setupBytesAndCapacity(char* bytes, int size) {
fCapacity = fEndByte - bytes;
}
void GrBagOfBytes::needMoreBytes(int requestedSize, int alignment) {
void BagOfBytes::needMoreBytes(int requestedSize, int alignment) {
int nextBlockSize = fFibProgression.nextBlockSize();
const int size = PlatformMinimumSizeWithOverhead(
std::max(requestedSize, nextBlockSize), kAllocationAlignment);
@ -76,16 +78,18 @@ void GrBagOfBytes::needMoreBytes(int requestedSize, int alignment) {
SkASSERT(fCapacity >= requestedSize);
}
// -- GrSubRunAllocator ----------------------------------------------------------------------------
GrSubRunAllocator::GrSubRunAllocator(char* bytes, int size, int firstHeapAllocation)
// -- SubRunAllocator ----------------------------------------------------------------------------
SubRunAllocator::SubRunAllocator(char* bytes, int size, int firstHeapAllocation)
: fAlloc{bytes, SkTo<size_t>(size), SkTo<size_t>(firstHeapAllocation)} {
SkASSERT_RELEASE(SkTFitsIn<size_t>(size));
SkASSERT_RELEASE(SkTFitsIn<size_t>(firstHeapAllocation));
SkASSERT_RELEASE(SkTFitsIn<size_t>(size));
SkASSERT_RELEASE(SkTFitsIn<size_t>(firstHeapAllocation));
}
GrSubRunAllocator::GrSubRunAllocator(int firstHeapAllocation)
: GrSubRunAllocator(nullptr, 0, firstHeapAllocation) { }
SubRunAllocator::SubRunAllocator(int firstHeapAllocation)
: SubRunAllocator(nullptr, 0, firstHeapAllocation) { }
void* GrSubRunAllocator::alignedBytes(int unsafeSize, int unsafeAlignment) {
void* SubRunAllocator::alignedBytes(int unsafeSize, int unsafeAlignment) {
return fAlloc.alignedBytes(unsafeSize, unsafeAlignment);
}
} // namespace sktext::gpu

View File

@ -5,8 +5,8 @@
* found in the LICENSE file.
*/
#ifndef GrSubRunAllocator_DEFINED
#define GrSubRunAllocator_DEFINED
#ifndef sktext_gpu_SubRunAllocator_DEFINED
#define sktext_gpu_SubRunAllocator_DEFINED
#include "include/core/SkMath.h"
#include "include/core/SkSpan.h"
@ -19,24 +19,26 @@
#include <tuple>
#include <utility>
// GrBagOfBytes parcels out bytes with a given size and alignment.
class GrBagOfBytes {
namespace sktext::gpu {
// BagOfBytes parcels out bytes with a given size and alignment.
class BagOfBytes {
public:
GrBagOfBytes(char* block, size_t blockSize, size_t firstHeapAllocation);
explicit GrBagOfBytes(size_t firstHeapAllocation = 0);
GrBagOfBytes(const GrBagOfBytes&) = delete;
GrBagOfBytes& operator=(const GrBagOfBytes&) = delete;
GrBagOfBytes(GrBagOfBytes&& that)
BagOfBytes(char* block, size_t blockSize, size_t firstHeapAllocation);
explicit BagOfBytes(size_t firstHeapAllocation = 0);
BagOfBytes(const BagOfBytes&) = delete;
BagOfBytes& operator=(const BagOfBytes&) = delete;
BagOfBytes(BagOfBytes&& that)
: fEndByte{std::exchange(that.fEndByte, nullptr)}
, fCapacity{that.fCapacity}
, fFibProgression{that.fFibProgression} {}
GrBagOfBytes& operator=(GrBagOfBytes&& that) {
this->~GrBagOfBytes();
new (this) GrBagOfBytes{std::move(that)};
BagOfBytes& operator=(BagOfBytes&& that) {
this->~BagOfBytes();
new (this) BagOfBytes{std::move(that)};
return *this;
}
~GrBagOfBytes();
~BagOfBytes();
// Given a requestedSize round up to the smallest size that accounts for all the per block
// overhead and alignment. It crashes if requestedSize is negative or too big.
@ -166,9 +168,9 @@ private:
};
template <typename T>
class GrSubRunInitializer {
class SubRunInitializer {
public:
GrSubRunInitializer(void* memory) : fMemory{memory} { SkASSERT(memory != nullptr); }
SubRunInitializer(void* memory) : fMemory{memory} { SkASSERT(memory != nullptr); }
template <typename... Args>
T* initialize(Args&&... args) {
// Warn on more than one initialization.
@ -185,7 +187,7 @@ private:
// unique_ptrs returned, are to assist in assuring the object's destructor is called.
// A note on zero length arrays: according to the standard a pointer must be returned, and it
// can't be a nullptr. In such a case, SkArena allocates one byte, but does not initialize it.
class GrSubRunAllocator {
class SubRunAllocator {
public:
struct Destroyer {
template <typename T>
@ -203,26 +205,26 @@ public:
template<class T>
inline static constexpr bool HasNoDestructor = std::is_trivially_destructible<T>::value;
GrSubRunAllocator(char* block, int blockSize, int firstHeapAllocation);
explicit GrSubRunAllocator(int firstHeapAllocation = 0);
GrSubRunAllocator(const GrSubRunAllocator&) = delete;
GrSubRunAllocator& operator=(const GrSubRunAllocator&) = delete;
GrSubRunAllocator(GrSubRunAllocator&&) = default;
GrSubRunAllocator& operator=(GrSubRunAllocator&&) = default;
SubRunAllocator(char* block, int blockSize, int firstHeapAllocation);
explicit SubRunAllocator(int firstHeapAllocation = 0);
SubRunAllocator(const SubRunAllocator&) = delete;
SubRunAllocator& operator=(const SubRunAllocator&) = delete;
SubRunAllocator(SubRunAllocator&&) = default;
SubRunAllocator& operator=(SubRunAllocator&&) = default;
template <typename T>
static std::tuple<GrSubRunInitializer<T>, int, GrSubRunAllocator>
static std::tuple<SubRunInitializer<T>, int, SubRunAllocator>
AllocateClassMemoryAndArena(int allocSizeHint) {
SkASSERT_RELEASE(allocSizeHint >= 0);
// Round the size after the object the optimal amount.
int extraSize = GrBagOfBytes::PlatformMinimumSizeWithOverhead(allocSizeHint, alignof(T));
int extraSize = BagOfBytes::PlatformMinimumSizeWithOverhead(allocSizeHint, alignof(T));
// Don't overflow or die.
SkASSERT_RELEASE(INT_MAX - SkTo<int>(sizeof(T)) > extraSize);
int totalMemorySize = sizeof(T) + extraSize;
void* memory = ::operator new (totalMemorySize);
GrSubRunAllocator alloc{SkTAddOffset<char>(memory, sizeof(T)), extraSize, extraSize/2};
SubRunAllocator alloc{SkTAddOffset<char>(memory, sizeof(T)), extraSize, extraSize/2};
return {memory, totalMemorySize, std::move(alloc)};
}
@ -278,6 +280,9 @@ public:
void* alignedBytes(int size, int alignment);
private:
GrBagOfBytes fAlloc;
BagOfBytes fAlloc;
};
#endif // GrSubRunAllocator_DEFINED
} // namespace sktext::gpu
#endif // sktext_gpu_SubRunAllocator_DEFINED

View File

@ -7201,8 +7201,8 @@ generated_cc_atom(
"//src/core:SkStrikeSpec_hdr",
"//src/core:SkWriteBuffer_hdr",
"//src/gpu/ganesh:GrResourceProvider_hdr",
"//src/gpu/ganesh:GrSubRunAllocator_hdr",
"//src/gpu/ganesh/text:GrGlyphVector_hdr",
"//src/text/gpu:GlyphVector_hdr",
"//src/text/gpu:SubRunAllocator_hdr",
],
)

View File

@ -7,31 +7,36 @@
#include "src/core/SkGlyph.h"
#include "src/gpu/ganesh/GrResourceProvider.h"
#include "src/gpu/ganesh/text/GrGlyphVector.h"
#include "src/core/SkGlyphBuffer.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkWriteBuffer.h"
#include "src/gpu/ganesh/GrSubRunAllocator.h"
#include "src/text/gpu/GlyphVector.h"
#include "src/text/gpu/SubRunAllocator.h"
#include "tests/Test.h"
using GlyphVector = sktext::gpu::GlyphVector;
using SubRunAllocator = sktext::gpu::SubRunAllocator;
namespace sktext::gpu {
class TestingPeer {
public:
static const SkDescriptor& GetDescriptor(const GrGlyphVector& v) {
return v.fStrike->getDescriptor();
static const SkDescriptor& GetDescriptor(const GlyphVector& v) {
return v.fSkStrike->getDescriptor();
}
static SkSpan<GrGlyphVector::Variant> GetGlyphs(const GrGlyphVector& v) {
static SkSpan<GlyphVector::Variant> GetGlyphs(const GlyphVector& v) {
return v.fGlyphs;
}
};
DEF_TEST(GrGlyphVector_Serialization, r) {
DEF_TEST(GlyphVector_Serialization, r) {
SkFont font;
auto [strikeSpec, _] = SkStrikeSpec::MakeCanonicalized(font);
GrSubRunAllocator alloc;
SubRunAllocator alloc;
SkBulkGlyphMetricsAndImages glyphFinder{strikeSpec};
const int N = 10;
@ -40,7 +45,7 @@ DEF_TEST(GrGlyphVector_Serialization, r) {
glyphs[i] = glyphFinder.glyph(SkPackedGlyphID(SkTo<SkGlyphID>(i + 1)));
}
GrGlyphVector src = GrGlyphVector::Make(
GlyphVector src = GlyphVector::Make(
strikeSpec.findOrCreateStrike(), SkMakeSpan(glyphs, N), &alloc);
SkBinaryWriteBuffer wBuffer;
@ -48,7 +53,7 @@ DEF_TEST(GrGlyphVector_Serialization, r) {
auto data = wBuffer.snapshotAsData();
SkReadBuffer rBuffer{data->data(), data->size()};
auto dst = GrGlyphVector::MakeFromBuffer(rBuffer, nullptr, &alloc);
auto dst = GlyphVector::MakeFromBuffer(rBuffer, nullptr, &alloc);
REPORTER_ASSERT(r, dst.has_value());
REPORTER_ASSERT(r, TestingPeer::GetDescriptor(src) == TestingPeer::GetDescriptor(*dst));
@ -59,7 +64,7 @@ DEF_TEST(GrGlyphVector_Serialization, r) {
}
}
DEF_TEST(GrGlyphVector_BadLengths, r) {
DEF_TEST(GlyphVector_BadLengths, r) {
{
SkFont font;
auto [strikeSpec, _] = SkStrikeSpec::MakeCanonicalized(font);
@ -70,8 +75,8 @@ DEF_TEST(GrGlyphVector_BadLengths, r) {
wBuffer.write32(0); // length
auto data = wBuffer.snapshotAsData();
SkReadBuffer rBuffer{data->data(), data->size()};
GrSubRunAllocator alloc;
auto dst = GrGlyphVector::MakeFromBuffer(rBuffer, nullptr, &alloc);
SubRunAllocator alloc;
auto dst = GlyphVector::MakeFromBuffer(rBuffer, nullptr, &alloc);
REPORTER_ASSERT(r, !dst.has_value());
}
@ -88,8 +93,8 @@ DEF_TEST(GrGlyphVector_BadLengths, r) {
wBuffer.writeUInt(12); // random data
auto data = wBuffer.snapshotAsData();
SkReadBuffer rBuffer{data->data(), data->size()};
GrSubRunAllocator alloc;
auto dst = GrGlyphVector::MakeFromBuffer(rBuffer, nullptr, &alloc);
SubRunAllocator alloc;
auto dst = GlyphVector::MakeFromBuffer(rBuffer, nullptr, &alloc);
REPORTER_ASSERT(r, !dst.has_value());
}
@ -106,8 +111,10 @@ DEF_TEST(GrGlyphVector_BadLengths, r) {
wBuffer.writeUInt(12); // random data
auto data = wBuffer.snapshotAsData();
SkReadBuffer rBuffer{data->data(), data->size()};
GrSubRunAllocator alloc;
auto dst = GrGlyphVector::MakeFromBuffer(rBuffer, nullptr, &alloc);
SubRunAllocator alloc;
auto dst = GlyphVector::MakeFromBuffer(rBuffer, nullptr, &alloc);
REPORTER_ASSERT(r, !dst.has_value());
}
}
} // namespace sktext::gpu

View File

@ -14,6 +14,9 @@
#include "tests/Test.h"
#include "tools/ToolUtils.h"
using BagOfBytes = sktext::gpu::BagOfBytes;
using SubRunAllocator = sktext::gpu::SubRunAllocator;
SkBitmap rasterize_blob(SkTextBlob* blob,
const SkPaint& paint,
GrRecordingContext* rContext,
@ -143,34 +146,34 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextBlobMoveAround, reporter, ctxInfo) {
}
}
DEF_TEST(GrBagOfBytesBasic, r) {
DEF_TEST(BagOfBytesBasic, r) {
const int k4K = 1 << 12;
{
// GrBagOfBytes::MinimumSizeWithOverhead(-1); // This should fail
GrBagOfBytes::PlatformMinimumSizeWithOverhead(0, 16);
GrBagOfBytes::PlatformMinimumSizeWithOverhead(
BagOfBytes::PlatformMinimumSizeWithOverhead(0, 16);
BagOfBytes::PlatformMinimumSizeWithOverhead(
std::numeric_limits<int>::max() - k4K - 1, 16);
// GrBagOfBytes::MinimumSizeWithOverhead(std::numeric_limits<int>::max() - k4K); // Fail
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(0, 1, 16, 16) == 31);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(1, 1, 16, 16) == 32);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(63, 1, 16, 16) == 94);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(0, 8, 16, 16) == 24);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(1, 8, 16, 16) == 32);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(63, 8, 16, 16) == 88);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(0, 16, 16, 16) == 16);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(1, 16, 16, 16) == 32);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(63, 16, 16, 16) == 80);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(0, 1, 16, 16) == 31);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(1, 1, 16, 16) == 32);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(63, 1, 16, 16) == 94);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(0, 8, 16, 16) == 24);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(1, 8, 16, 16) == 32);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(63, 8, 16, 16) == 88);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(0, 16, 16, 16) == 16);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(1, 16, 16, 16) == 32);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(63, 16, 16, 16) == 80);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(0, 1, 8, 16) == 23);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(1, 1, 8, 16) == 24);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(63, 1, 8, 16) == 86);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(0, 8, 8, 16) == 16);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(1, 8, 8, 16) == 24);
REPORTER_ASSERT(r, GrBagOfBytes::MinimumSizeWithOverhead(63, 8, 8, 16) == 80);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(0, 1, 8, 16) == 23);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(1, 1, 8, 16) == 24);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(63, 1, 8, 16) == 86);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(0, 8, 8, 16) == 16);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(1, 8, 8, 16) == 24);
REPORTER_ASSERT(r, BagOfBytes::MinimumSizeWithOverhead(63, 8, 8, 16) == 80);
}
{
GrBagOfBytes bob;
BagOfBytes bob;
// bob.alignedBytes(0, 1); // This should fail
// bob.alignedBytes(1, 0); // This should fail
// bob.alignedBytes(1, 3); // This should fail
@ -189,7 +192,7 @@ DEF_TEST(GrBagOfBytesBasic, r) {
// Force multiple block allocation
{
GrBagOfBytes bob;
BagOfBytes bob;
const int k64K = 1 << 16;
// By default allocation block sizes start at 1K and go up with fib. This should allocate
// 10 individual blocks.
@ -200,20 +203,20 @@ DEF_TEST(GrBagOfBytesBasic, r) {
}
// Helper for defining allocators with inline/reserved storage.
// For argument declarations, stick to the base type (GrSubRunAllocator).
// For argument declarations, stick to the base type (SubRunAllocator).
// Note: Inheriting from the storage first means the storage will outlive the
// GrSubRunAllocator, letting ~GrSubRunAllocator read it as it calls destructors.
// SubRunAllocator, letting ~SubRunAllocator read it as it calls destructors.
// (This is mostly only relevant for strict tools like MSAN.)
template <size_t inlineSize>
class GrSTSubRunAllocator : private GrBagOfBytes::Storage<inlineSize>, public GrSubRunAllocator {
class GrSTSubRunAllocator : private BagOfBytes::Storage<inlineSize>, public SubRunAllocator {
public:
explicit GrSTSubRunAllocator(int firstHeapAllocation =
GrBagOfBytes::PlatformMinimumSizeWithOverhead(inlineSize, 1))
: GrSubRunAllocator{this->data(), SkTo<int>(this->size()), firstHeapAllocation} {}
BagOfBytes::PlatformMinimumSizeWithOverhead(inlineSize, 1))
: SubRunAllocator{this->data(), SkTo<int>(this->size()), firstHeapAllocation} {}
};
DEF_TEST(GrSubRunAllocator, r) {
DEF_TEST(SubRunAllocator, r) {
static int created = 0;
static int destroyed = 0;
struct Foo {
@ -228,7 +231,7 @@ DEF_TEST(GrSubRunAllocator, r) {
char buf[10];
};
auto exercise = [&](GrSubRunAllocator* alloc) {
auto exercise = [&](SubRunAllocator* alloc) {
created = 0;
destroyed = 0;
{
@ -260,7 +263,7 @@ DEF_TEST(GrSubRunAllocator, r) {
// Exercise default arena
{
GrSubRunAllocator arena{0};
SubRunAllocator arena{0};
exercise(&arena);
}
@ -273,7 +276,7 @@ DEF_TEST(GrSubRunAllocator, r) {
// Exercise arena with a heap allocated starting block
{
std::unique_ptr<char[]> block{new char[1024]};
GrSubRunAllocator arena{block.get(), 1024, 0};
SubRunAllocator arena{block.get(), 1024, 0};
exercise(&arena);
}
@ -281,16 +284,16 @@ DEF_TEST(GrSubRunAllocator, r) {
{
created = 0;
destroyed = 0;
GrSubRunAllocator arena;
SubRunAllocator arena;
struct Node {
Node(std::unique_ptr<Node, GrSubRunAllocator::Destroyer> next)
Node(std::unique_ptr<Node, SubRunAllocator::Destroyer> next)
: fNext{std::move(next)} { created++; }
~Node() { destroyed++; }
std::unique_ptr<Node, GrSubRunAllocator::Destroyer> fNext;
std::unique_ptr<Node, SubRunAllocator::Destroyer> fNext;
};
std::unique_ptr<Node, GrSubRunAllocator::Destroyer> current = nullptr;
std::unique_ptr<Node, SubRunAllocator::Destroyer> current = nullptr;
for (int i = 0; i < 128; i++) {
current = arena.makeUnique<Node>(std::move(current));
}
@ -315,7 +318,7 @@ DEF_TEST(GrSubRunAllocator, r) {
}
{
GrSubRunAllocator arena(4096);
SubRunAllocator arena(4096);
void* ptr = arena.alignedBytes(4081, 8);
REPORTER_ASSERT(r, ((intptr_t)ptr & 7) == 0);
}

View File

@ -185,10 +185,10 @@ generated_cc_atom(
"//src/gpu/ganesh:GrSemaphore_hdr",
"//src/gpu/ganesh:GrTexture_hdr",
"//src/gpu/ganesh:SkGr_hdr",
"//src/gpu/ganesh/text:GrStrikeCache_hdr",
"//src/gpu/ganesh/text:GrTextBlobRedrawCoordinator_hdr",
"//src/gpu/ganesh/v1:SurfaceDrawContext_v1_hdr",
"//src/image:SkImage_Gpu_hdr",
"//src/text/gpu:StrikeCache_hdr",
],
)

View File

@ -24,10 +24,10 @@
#include "src/gpu/ganesh/GrSemaphore.h"
#include "src/gpu/ganesh/GrTexture.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/text/GrStrikeCache.h"
#include "src/gpu/ganesh/text/GrTextBlobRedrawCoordinator.h"
#include "src/gpu/ganesh/v1/SurfaceDrawContext_v1.h"
#include "src/image/SkImage_Gpu.h"
#include "src/text/gpu/StrikeCache.h"
#include <algorithm>