subclass GrPathSubRun from GrSubRun

Move PathGlyph to GrPathSubRun, and make the array for the path
data directly in the alloc instead of in a vector.

Change-Id: I861cb934e356f526f96e593d25019b00451f77b8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302640
Reviewed-by: Herb Derby <herb@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2020-07-14 15:39:25 -04:00 committed by Skia Commit-Bot
parent 4759dcaa8b
commit b2db9797c5
3 changed files with 121 additions and 122 deletions

View File

@ -511,6 +511,7 @@ private:
bool hasSomeAntiAliasing() const;
friend class GrAtlasSubRun;
friend class GrTextBlob;
friend class SkFontPriv;
friend class SkGlyphRunListPainter;
friend class SkTextBlobCacheDiffCanvas;

View File

@ -39,11 +39,91 @@ bool GrTextBlob::Key::operator==(const GrTextBlob::Key& other) const {
return 0 == memcmp(this, &other, sizeof(Key));
}
// -- GrTextBlob::PathGlyph ------------------------------------------------------------------------
GrTextBlob::PathGlyph::PathGlyph(const SkPath& path, SkPoint origin)
// -- GrPathSubRun::PathGlyph ----------------------------------------------------------------------
GrPathSubRun::PathGlyph::PathGlyph(const SkPath& path, SkPoint origin)
: fPath(path)
, fOrigin(origin) {}
// -- GrPathSubRun ---------------------------------------------------------------------------------
GrPathSubRun::GrPathSubRun(bool isAntiAliased,
const SkStrikeSpec& strikeSpec,
SkSpan<PathGlyph> paths)
: fIsAntiAliased{isAntiAliased}
, fStrikeSpec{strikeSpec}
, fPaths{paths} {}
void GrPathSubRun::draw(const GrClip* clip,
const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList,
GrRenderTargetContext* rtc) {
SkASSERT(!fPaths.empty());
SkPoint drawOrigin = glyphRunList.origin();
const SkPaint& drawPaint = glyphRunList.paint();
SkPaint runPaint{drawPaint};
runPaint.setAntiAlias(fIsAntiAliased);
// If there are shaders, blurs or styles, the path must be scaled into source
// space independently of the CTM. This allows the CTM to be correct for the
// different effects.
GrStyle style(runPaint);
bool needsExactCTM = runPaint.getShader()
|| style.applies()
|| runPaint.getMaskFilter();
// Calculate the matrix that maps the path glyphs from their size in the strike to
// the graphics source space.
SkScalar scale = this->fStrikeSpec.strikeToSourceRatio();
SkMatrix strikeToSource = SkMatrix::Scale(scale, scale);
strikeToSource.postTranslate(drawOrigin.x(), drawOrigin.y());
if (!needsExactCTM) {
for (const auto& pathPos : fPaths) {
const SkPath& path = pathPos.fPath;
const SkPoint pos = pathPos.fOrigin; // Transform the glyph to source space.
SkMatrix pathMatrix = strikeToSource;
pathMatrix.postTranslate(pos.x(), pos.y());
SkPreConcatMatrixProvider strikeToDevice(viewMatrix, pathMatrix);
GrStyledShape shape(path, drawPaint);
GrBlurUtils::drawShapeWithMaskFilter(
rtc->priv().getContext(), rtc, clip, runPaint, strikeToDevice, shape);
}
} else {
// Transform the path to device because the deviceMatrix must be unchanged to
// draw effect, filter or shader paths.
for (const auto& pathPos : fPaths) {
const SkPath& path = pathPos.fPath;
const SkPoint pos = pathPos.fOrigin;
// Transform the glyph to source space.
SkMatrix pathMatrix = strikeToSource;
pathMatrix.postTranslate(pos.x(), pos.y());
SkPath deviceOutline;
path.transform(pathMatrix, &deviceOutline);
deviceOutline.setIsVolatile(true);
GrStyledShape shape(deviceOutline, drawPaint);
GrBlurUtils::drawShapeWithMaskFilter(
rtc->priv().getContext(), rtc, clip, runPaint, viewMatrix, shape);
}
}
}
auto GrPathSubRun::MakePaths(
const SkZip<SkGlyphVariant, SkPoint>& drawables,
bool isAntiAliased,
const SkStrikeSpec& strikeSpec,
SkArenaAlloc* alloc) -> GrSubRun* {
PathGlyph* pathData = alloc->makeInitializedArray<PathGlyph>(
drawables.size(),
[&](size_t i) -> PathGlyph {
auto [variant, pos] = drawables[i];
return {*variant.path(), pos};
});
return alloc->make<GrPathSubRun>(
isAntiAliased, strikeSpec, SkMakeSpan(pathData, drawables.size()));
};
// -- GrAtlasSubRun --------------------------------------------------------------------------------
GrAtlasSubRun::GrAtlasSubRun(SubRunType type, GrTextBlob* textBlob, const SkStrikeSpec& strikeSpec,
GrMaskFormat format, SkRect vertexBounds,
@ -54,17 +134,8 @@ GrAtlasSubRun::GrAtlasSubRun(SubRunType type, GrTextBlob* textBlob, const SkStri
, fStrikeSpec{strikeSpec}
, fVertexBounds{vertexBounds}
, fVertexData{vertexData} {
SkASSERT(fType != kTransformedPath);
}
GrAtlasSubRun::GrAtlasSubRun(GrTextBlob* textBlob, const SkStrikeSpec& strikeSpec)
: fBlob{textBlob}
, fType{kTransformedPath}
, fMaskFormat{kA8_GrMaskFormat}
, fStrikeSpec{strikeSpec}
, fVertexBounds{SkRect::MakeEmpty()}
, fVertexData{SkSpan<VertexData>{}} { }
static SkPMColor4f generate_filtered_color(const SkPaint& paint, const GrColorInfo& colorInfo) {
SkColor4f c = paint.getColor4f();
if (auto* xform = colorInfo.colorSpaceXformFromSRGB()) {
@ -189,72 +260,13 @@ GrAtlasSubRun::makeAtlasTextOp(const GrClip* clip,
return {clip, std::move(op)};
}
void GrAtlasSubRun::drawPaths(const GrClip* clip,
const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList,
GrRenderTargetContext* rtc) {
SkASSERT(!this->paths().empty());
SkPoint drawOrigin = glyphRunList.origin();
const SkPaint& drawPaint = glyphRunList.paint();
SkPaint runPaint{drawPaint};
runPaint.setAntiAlias(this->isAntiAliased());
// If there are shaders, blurs or styles, the path must be scaled into source
// space independently of the CTM. This allows the CTM to be correct for the
// different effects.
GrStyle style(runPaint);
bool needsExactCTM = runPaint.getShader()
|| style.applies()
|| runPaint.getMaskFilter();
// Calculate the matrix that maps the path glyphs from their size in the strike to
// the graphics source space.
SkScalar scale = this->strikeSpec().strikeToSourceRatio();
SkMatrix strikeToSource = SkMatrix::Scale(scale, scale);
strikeToSource.postTranslate(drawOrigin.x(), drawOrigin.y());
if (!needsExactCTM) {
for (const auto& pathPos : this->paths()) {
const SkPath& path = pathPos.fPath;
const SkPoint pos = pathPos.fOrigin; // Transform the glyph to source space.
SkMatrix pathMatrix = strikeToSource;
pathMatrix.postTranslate(pos.x(), pos.y());
SkPreConcatMatrixProvider strikeToDevice(viewMatrix, pathMatrix);
GrStyledShape shape(path, drawPaint);
GrBlurUtils::drawShapeWithMaskFilter(
rtc->priv().getContext(), rtc, clip, runPaint, strikeToDevice, shape);
}
} else {
// Transform the path to device because the deviceMatrix must be unchanged to
// draw effect, filter or shader paths.
for (const auto& pathPos : this->paths()) {
const SkPath& path = pathPos.fPath;
const SkPoint pos = pathPos.fOrigin;
// Transform the glyph to source space.
SkMatrix pathMatrix = strikeToSource;
pathMatrix.postTranslate(pos.x(), pos.y());
SkPath deviceOutline;
path.transform(pathMatrix, &deviceOutline);
deviceOutline.setIsVolatile(true);
GrStyledShape shape(deviceOutline, drawPaint);
GrBlurUtils::drawShapeWithMaskFilter(
rtc->priv().getContext(), rtc, clip, runPaint, viewMatrix, shape);
}
}
}
void GrAtlasSubRun::draw(const GrClip* clip,
const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList,
GrRenderTargetContext* rtc) {
if (this->drawAsPaths()) {
this->drawPaths(clip, viewMatrix, glyphRunList, rtc);
} else {
auto[drawingClip, op] = this->makeAtlasTextOp(clip, viewMatrix, glyphRunList, rtc);
if (op != nullptr) {
rtc->priv().addDrawOp(drawingClip, std::move(op));
}
auto[drawingClip, op] = this->makeAtlasTextOp(clip, viewMatrix, glyphRunList, rtc);
if (op != nullptr) {
rtc->priv().addDrawOp(drawingClip, std::move(op));
}
}
@ -517,8 +529,6 @@ void GrAtlasSubRun::fillVertexData(
}
break;
}
case kTransformedPath:
SK_ABORT("Paths don't generate vertex data.");
}
}
@ -528,16 +538,13 @@ int GrAtlasSubRun::glyphCount() const {
bool GrAtlasSubRun::drawAsDistanceFields() const { return fType == kTransformedSDFT; }
bool GrAtlasSubRun::drawAsPaths() const { return fType == kTransformedPath; }
bool GrAtlasSubRun::needsTransform() const {
return fType == kTransformedPath ||
fType == kTransformedMask ||
return fType == kTransformedMask ||
fType == kTransformedSDFT;
}
bool GrAtlasSubRun::needsPadding() const {
return fType == kTransformedPath || fType == kTransformedMask;
return fType == kTransformedMask;
}
int GrAtlasSubRun::atlasPadding() const {
@ -549,7 +556,7 @@ auto GrAtlasSubRun::vertexData() const -> SkSpan<const VertexData> {
}
bool GrAtlasSubRun::hasW() const {
if (fType == kTransformedSDFT || fType == kTransformedMask || fType == kTransformedPath) {
if (fType == kTransformedSDFT || fType == kTransformedMask) {
return fBlob->hasPerspective();
}
@ -597,20 +604,6 @@ void GrAtlasSubRun::setAntiAliased(bool antiAliased) { fAntiAliased = antiAliase
bool GrAtlasSubRun::isAntiAliased() const { return fAntiAliased; }
const SkStrikeSpec& GrAtlasSubRun::strikeSpec() const { return fStrikeSpec; }
auto GrAtlasSubRun::MakePaths(
const SkZip<SkGlyphVariant, SkPoint>& drawables,
const SkFont& runFont,
const SkStrikeSpec& strikeSpec,
GrTextBlob* blob,
SkArenaAlloc* alloc) -> GrSubRun* {
GrAtlasSubRun* subRun = alloc->make<GrAtlasSubRun>(blob, strikeSpec);
subRun->setAntiAliased(runFont.hasSomeAntiAliasing());
for (auto [variant, pos] : drawables) {
subRun->fPaths.emplace_back(*variant.path(), pos);
}
return subRun;
};
auto GrAtlasSubRun::MakeSDFT(
const SkZip<SkGlyphVariant, SkPoint>& drawables,
const SkFont& runFont,
@ -877,7 +870,10 @@ void GrTextBlob::processSourcePaths(const SkZip<SkGlyphVariant, SkPoint>& drawab
const SkFont& runFont,
const SkStrikeSpec& strikeSpec) {
this->setHasBitmap();
GrSubRun* subRun = GrAtlasSubRun::MakePaths(drawables, runFont, strikeSpec, this, &fAlloc);
GrSubRun* subRun = GrPathSubRun::MakePaths(drawables,
runFont.hasSomeAntiAliasing(),
strikeSpec,
&fAlloc);
this->insertSubRun(subRun);
}

View File

@ -72,14 +72,6 @@ public:
bool operator==(const Key& other) const;
};
// Any glyphs that can't be rendered with the base or override descriptor
// are rendered as paths
struct PathGlyph {
PathGlyph(const SkPath& path, SkPoint origin);
SkPath fPath;
SkPoint fOrigin;
};
SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrTextBlob);
// Change memory management to handle the data after GrTextBlob, but in the same allocation
@ -200,6 +192,34 @@ public:
private:
SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrSubRun);
};
// -- GrPathSubRun ---------------------------------------------------------------------------------
class GrPathSubRun : public GrSubRun {
struct PathGlyph;
public:
GrPathSubRun(bool isAntiAliased, const SkStrikeSpec& strikeSpec, SkSpan<PathGlyph> paths);
void draw(const GrClip* clip,
const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList,
GrRenderTargetContext* rtc) override;
static GrSubRun* MakePaths(const SkZip<SkGlyphVariant, SkPoint>& drawables,
bool isAntiAliased,
const SkStrikeSpec& strikeSpec,
SkArenaAlloc* alloc);
private:
struct PathGlyph {
PathGlyph(const SkPath& path, SkPoint origin);
SkPath fPath;
SkPoint fOrigin;
};
const bool fIsAntiAliased;
const SkStrikeSpec fStrikeSpec;
const SkSpan<const PathGlyph> fPaths;
};
// -- GrAtlasSubRun --------------------------------------------------------------------------------
// Hold data to draw the different types of sub run. SubRuns are produced knowing all the
@ -208,7 +228,6 @@ class GrAtlasSubRun : public GrSubRun {
enum SubRunType {
kDirectMask,
kTransformedMask,
kTransformedPath,
kTransformedSDFT
};
@ -234,20 +253,12 @@ public:
SkRect vertexBounds,
const SkSpan<VertexData>& vertexData);
// SubRun for paths
GrAtlasSubRun(GrTextBlob* textBlob, const SkStrikeSpec& strikeSpec);
std::tuple<const GrClip*, std::unique_ptr<GrDrawOp>>
makeAtlasTextOp(const GrClip* clip,
const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList,
GrRenderTargetContext* rtc);
void drawPaths(const GrClip* clip,
const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList,
GrRenderTargetContext* rtc);
void draw(const GrClip* clip,
const SkMatrixProvider& viewMatrix,
const SkGlyphRunList& glyphRunList,
@ -277,12 +288,6 @@ public:
const SkStrikeSpec& strikeSpec() const;
static GrSubRun* MakePaths(const SkZip<SkGlyphVariant, SkPoint>& drawables,
const SkFont& runFont,
const SkStrikeSpec& strikeSpec,
GrTextBlob* blob,
SkArenaAlloc* alloc);
static GrSubRun* MakeSDFT(const SkZip<SkGlyphVariant, SkPoint>& drawables,
const SkFont& runFont,
const SkStrikeSpec& strikeSpec,
@ -342,8 +347,6 @@ private:
bool hasW() const;
void setUseLCDText(bool useLCDText);
void setAntiAliased(bool antiAliased);
SkSpan<const GrTextBlob::PathGlyph> paths() const { return SkMakeSpan(fPaths); }
bool drawAsPaths() const;
// df properties
bool hasUseLCDText() const;
@ -373,7 +376,6 @@ private:
// source space. The bounds are the joined rectangles of all the glyphs.
const SkRect fVertexBounds;
const SkSpan<VertexData> fVertexData;
std::vector<GrTextBlob::PathGlyph> fPaths;
uint64_t fAtlasGeneration{GrDrawOpAtlas::kInvalidAtlasGeneration};
}; // SubRun