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:
parent
4759dcaa8b
commit
b2db9797c5
@ -511,6 +511,7 @@ private:
|
||||
bool hasSomeAntiAliasing() const;
|
||||
|
||||
friend class GrAtlasSubRun;
|
||||
friend class GrTextBlob;
|
||||
friend class SkFontPriv;
|
||||
friend class SkGlyphRunListPainter;
|
||||
friend class SkTextBlobCacheDiffCanvas;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user