add bilerp atlas support flag
Move the compile-time flag SK_EXPERIMENTAL_ADD_ATLAS_PADDING, to a runtime flag in GrContextOptions. Bug: chromium:1275890 Change-Id: I7e051cd4834ac44958b1431976535519e8bdaa3e Reviewed-on: https://skia-review.googlesource.com/c/skia/+/482416 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
parent
0f2390f7fb
commit
c279e7640b
@ -51,7 +51,7 @@ class DirectMaskGlyphVertexFillBenchmark : public Benchmark {
|
||||
const SkPoint drawOrigin = glyphRunList.origin();
|
||||
drawMatrix.preTranslate(drawOrigin.x(), drawOrigin.y());
|
||||
GrSDFTControl control{false, props.isUseDeviceIndependentFonts(), 256, 256};
|
||||
fBlob = GrTextBlob::Make(glyphRunList, paint, drawMatrix, control, &painter);
|
||||
fBlob = GrTextBlob::Make(glyphRunList, paint, drawMatrix, false, control, &painter);
|
||||
|
||||
SkASSERT(!fBlob->subRunList().isEmpty());
|
||||
GrAtlasSubRun* subRun = fBlob->subRunList().front().testingOnly_atlasSubRun();
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "include/private/chromium/GrSlug.h"
|
||||
#include "tools/ToolUtils.h"
|
||||
|
||||
#if SK_SUPPORT_GPU && defined(SK_EXPERIMENTAL_ADD_ATLAS_PADDING)
|
||||
#if SK_SUPPORT_GPU && defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG)
|
||||
class SlugGM : public skiagm::GM {
|
||||
public:
|
||||
SlugGM(const char* txt)
|
||||
|
@ -270,6 +270,16 @@ struct SK_API GrContextOptions {
|
||||
*/
|
||||
bool fEnableExperimentalHardwareTessellation = false;
|
||||
|
||||
/**
|
||||
* If true, then add 1 pixel padding to all glyph masks in the atlas to support bi-lerp
|
||||
* rendering of all glyphs. This must be set to true to use GrSlug.
|
||||
*/
|
||||
#if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG) || defined(SK_EXPERIMENTAL_ADD_ATLAS_PADDING)
|
||||
bool fSupportBilerpFromGlyphAtlas = true;
|
||||
#else
|
||||
bool fSupportBilerpFromGlyphAtlas = false;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Uses a reduced variety of shaders. May perform less optimally in steady state but can reduce
|
||||
* jank due to shader compilations.
|
||||
|
@ -15,6 +15,11 @@ class SkCanvas;
|
||||
class SkPaint;
|
||||
class SkTextBlob;
|
||||
|
||||
// You can use GrSlug to simulate drawTextBlob by defining the following at compile time.
|
||||
// SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG
|
||||
// For Skia, add this to your args.gn file.
|
||||
// extra_cflags = ["-D", "SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG"]
|
||||
|
||||
// GrSlug encapsulates an SkTextBlob at a specific origin, using a specific paint. It can be
|
||||
// manipulated using matrix and clip changes to the canvas. If the canvas is transformed, then
|
||||
// the GrSlug will also transform with smaller glyphs using bi-linear interpolation to render. You
|
||||
|
@ -505,7 +505,8 @@ GrOp::Owner AtlasTextOp::CreateOpTestingOnly(SurfaceDrawContext* sdc,
|
||||
rContext->priv().getSDFTControl(sdc->surfaceProps().isUseDeviceIndependentFonts());
|
||||
|
||||
SkGlyphRunListPainter* painter = sdc->glyphRunPainter();
|
||||
sk_sp<GrTextBlob> blob = GrTextBlob::Make(glyphRunList, skPaint, drawMatrix, control, painter);
|
||||
sk_sp<GrTextBlob> blob = GrTextBlob::Make(
|
||||
glyphRunList, skPaint, drawMatrix, false, control, painter);
|
||||
|
||||
if (blob->subRunList().isEmpty()) {
|
||||
return nullptr;
|
||||
|
@ -31,9 +31,8 @@
|
||||
#include "src/gpu/v1/Device_v1.h"
|
||||
#include "src/gpu/v1/SurfaceDrawContext_v1.h"
|
||||
|
||||
// Defining SK_EXPERIMENTAL_ADD_ATLAS_PADDING will cause all glyphs in the atlas to have a one
|
||||
// pixel border to support bi-lerping on demand.
|
||||
// #define SK_EXPERIMENTAL_ADD_ATLAS_PADDING
|
||||
// Note:
|
||||
// In order to use GrSlugs, you need to set the fSupportBilerpFromGlyphAtlas on GrContextOptions.
|
||||
|
||||
// Naming conventions
|
||||
// * drawMatrix - the CTM from the canvas.
|
||||
@ -713,11 +712,11 @@ void DirectMaskSubRun::testingOnly_packedGlyphIDToGrGlyph(GrStrikeCache *cache)
|
||||
|
||||
std::tuple<bool, int>
|
||||
DirectMaskSubRun::regenerateAtlas(int begin, int end, GrMeshDrawTarget* target) const {
|
||||
#if defined(SK_EXPERIMENTAL_ADD_ATLAS_PADDING)
|
||||
if (fBlob->supportBilerpAtlas()) {
|
||||
return fGlyphs.regenerateAtlas(begin, end, fMaskFormat, 1, target, true);
|
||||
#else
|
||||
} else {
|
||||
return fGlyphs.regenerateAtlas(begin, end, fMaskFormat, 0, target, false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// The 99% case. No clip. Non-color only.
|
||||
@ -1553,6 +1552,7 @@ GrTextBlob::~GrTextBlob() = default;
|
||||
sk_sp<GrTextBlob> GrTextBlob::Make(const SkGlyphRunList& glyphRunList,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix& positionMatrix,
|
||||
bool supportBilerpAtlas,
|
||||
const GrSDFTControl& control,
|
||||
SkGlyphRunListPainter* painter) {
|
||||
// The difference in alignment from the per-glyph data to the SubRun;
|
||||
@ -1573,8 +1573,9 @@ sk_sp<GrTextBlob> GrTextBlob::Make(const SkGlyphRunList& glyphRunList,
|
||||
void* allocation = ::operator new (allocationSize);
|
||||
|
||||
SkColor initialLuminance = SkPaintPriv::ComputeLuminanceColor(paint);
|
||||
sk_sp<GrTextBlob> blob{new (allocation)
|
||||
GrTextBlob(bytesNeededForSubRun, positionMatrix, initialLuminance)};
|
||||
sk_sp<GrTextBlob> blob{
|
||||
new (allocation) GrTextBlob(
|
||||
bytesNeededForSubRun, supportBilerpAtlas, positionMatrix, initialLuminance)};
|
||||
|
||||
const uint64_t uniqueID = glyphRunList.uniqueID();
|
||||
for (auto& glyphRun : glyphRunList) {
|
||||
@ -1627,10 +1628,12 @@ const GrTextBlob::Key& GrTextBlob::key() const { return fKey; }
|
||||
size_t GrTextBlob::size() const { return fSize; }
|
||||
|
||||
GrTextBlob::GrTextBlob(int allocSize,
|
||||
bool supportBilerpAtlas,
|
||||
const SkMatrix& positionMatrix,
|
||||
SkColor initialLuminance)
|
||||
: fAlloc{SkTAddOffset<char>(this, sizeof(GrTextBlob)), allocSize, allocSize/2}
|
||||
, fSize{allocSize}
|
||||
, fSupportBilerpAtlas{supportBilerpAtlas}
|
||||
, fInitialPositionMatrix{positionMatrix}
|
||||
, fInitialLuminance{initialLuminance} { }
|
||||
|
||||
@ -1698,6 +1701,7 @@ public:
|
||||
using DevicePosition = skvx::Vec<2, int16_t>;
|
||||
|
||||
DirectMaskSubRunNoCache(GrMaskFormat format,
|
||||
bool supportBilerpAtlas,
|
||||
const SkRect& bounds,
|
||||
SkSpan<const DevicePosition> devicePositions,
|
||||
GlyphVector&& glyphs);
|
||||
@ -1705,6 +1709,7 @@ public:
|
||||
static GrAtlasSubRunOwner Make(const SkZip<SkGlyphVariant, SkPoint>& drawables,
|
||||
sk_sp<SkStrike>&& strike,
|
||||
GrMaskFormat format,
|
||||
bool supportBilerpAtlas,
|
||||
GrSubRunAllocator* alloc);
|
||||
|
||||
size_t vertexStride(const SkMatrix& drawMatrix) const override;
|
||||
@ -1732,6 +1737,9 @@ public:
|
||||
private:
|
||||
const GrMaskFormat fMaskFormat;
|
||||
|
||||
// Support bilerping from the atlas.
|
||||
const bool fSupportBilerpAtlas;
|
||||
|
||||
// The vertex bounds in device space. The bounds are the joined rectangles of all the glyphs.
|
||||
const SkRect fGlyphDeviceBounds;
|
||||
const SkSpan<const DevicePosition> fLeftTopDevicePos;
|
||||
@ -1745,10 +1753,12 @@ private:
|
||||
};
|
||||
|
||||
DirectMaskSubRunNoCache::DirectMaskSubRunNoCache(GrMaskFormat format,
|
||||
bool supportBilerpAtlas,
|
||||
const SkRect& deviceBounds,
|
||||
SkSpan<const DevicePosition> devicePositions,
|
||||
GlyphVector&& glyphs)
|
||||
: fMaskFormat{format}
|
||||
, fSupportBilerpAtlas{supportBilerpAtlas}
|
||||
, fGlyphDeviceBounds{deviceBounds}
|
||||
, fLeftTopDevicePos{devicePositions}
|
||||
, fGlyphs{std::move(glyphs)} { }
|
||||
@ -1756,6 +1766,7 @@ DirectMaskSubRunNoCache::DirectMaskSubRunNoCache(GrMaskFormat format,
|
||||
GrAtlasSubRunOwner DirectMaskSubRunNoCache::Make(const SkZip<SkGlyphVariant, SkPoint>& drawables,
|
||||
sk_sp<SkStrike>&& strike,
|
||||
GrMaskFormat format,
|
||||
bool supportBilerpAtlas,
|
||||
GrSubRunAllocator* alloc) {
|
||||
DevicePosition* glyphLeftTop = alloc->makePODArray<DevicePosition>(drawables.size());
|
||||
|
||||
@ -1793,7 +1804,7 @@ GrAtlasSubRunOwner DirectMaskSubRunNoCache::Make(const SkZip<SkGlyphVariant, SkP
|
||||
|
||||
SkSpan<const DevicePosition> leftTop{glyphLeftTop, goodPosCount};
|
||||
return alloc->makeUnique<DirectMaskSubRunNoCache>(
|
||||
format, runBounds.rect(), leftTop,
|
||||
format, supportBilerpAtlas, runBounds.rect(), leftTop,
|
||||
GlyphVector{std::move(strike), {glyphIDs, goodPosCount}});
|
||||
}
|
||||
|
||||
@ -1875,11 +1886,11 @@ void DirectMaskSubRunNoCache::testingOnly_packedGlyphIDToGrGlyph(GrStrikeCache *
|
||||
|
||||
std::tuple<bool, int>
|
||||
DirectMaskSubRunNoCache::regenerateAtlas(int begin, int end, GrMeshDrawTarget* target) const {
|
||||
#if defined(SK_EXPERIMENTAL_ADD_ATLAS_PADDING)
|
||||
if (fSupportBilerpAtlas) {
|
||||
return fGlyphs.regenerateAtlas(begin, end, fMaskFormat, 1, target, true);
|
||||
#else
|
||||
} else {
|
||||
return fGlyphs.regenerateAtlas(begin, end, fMaskFormat, 0, target, false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// The 99% case. No clip. Non-color only.
|
||||
@ -2389,7 +2400,10 @@ void GrSubRunNoCachePainter::processDeviceMasks(
|
||||
auto addGlyphsWithSameFormat = [&] (const SkZip<SkGlyphVariant, SkPoint>& drawable,
|
||||
GrMaskFormat format,
|
||||
sk_sp<SkStrike>&& runStrike) {
|
||||
this->draw(DirectMaskSubRunNoCache::Make(drawable, std::move(runStrike), format, fAlloc));
|
||||
const bool padAtlas =
|
||||
fSDC->recordingContext()->priv().options().fSupportBilerpFromGlyphAtlas;
|
||||
this->draw(DirectMaskSubRunNoCache::Make(
|
||||
drawable, std::move(runStrike), format, padAtlas, fAlloc));
|
||||
};
|
||||
|
||||
add_multi_mask_format(addGlyphsWithSameFormat, drawables, std::move(strike));
|
||||
@ -2818,11 +2832,7 @@ void DirectMaskSubRunSlug::testingOnly_packedGlyphIDToGrGlyph(GrStrikeCache *cac
|
||||
|
||||
std::tuple<bool, int>
|
||||
DirectMaskSubRunSlug::regenerateAtlas(int begin, int end, GrMeshDrawTarget* target) const {
|
||||
#if defined(SK_EXPERIMENTAL_ADD_ATLAS_PADDING)
|
||||
return fGlyphs.regenerateAtlas(begin, end, fMaskFormat, 1, target, true);
|
||||
#else
|
||||
return fGlyphs.regenerateAtlas(begin, end, fMaskFormat, 0, target, false);
|
||||
#endif
|
||||
return fGlyphs.regenerateAtlas(begin, end, fMaskFormat, 1, target, true);
|
||||
}
|
||||
|
||||
// The 99% case. No clip. Non-color only.
|
||||
@ -3662,6 +3672,8 @@ sk_sp<GrSlug>
|
||||
SurfaceDrawContext::convertGlyphRunListToSlug(const SkMatrixProvider& viewMatrix,
|
||||
const SkGlyphRunList& glyphRunList,
|
||||
const SkPaint& paint) {
|
||||
SkASSERT(fContext->priv().options().fSupportBilerpFromGlyphAtlas);
|
||||
|
||||
GrSDFTControl control =
|
||||
this->recordingContext()->priv().getSDFTControl(
|
||||
this->surfaceProps().isUseDeviceIndependentFonts());
|
||||
|
@ -222,6 +222,7 @@ public:
|
||||
static sk_sp<GrTextBlob> Make(const SkGlyphRunList& glyphRunList,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix& positionMatrix,
|
||||
bool supportBilerpAtlas,
|
||||
const GrSDFTControl& control,
|
||||
SkGlyphRunListPainter* painter);
|
||||
|
||||
@ -238,6 +239,7 @@ public:
|
||||
void addKey(const Key& key);
|
||||
bool hasPerspective() const;
|
||||
const SkMatrix& initialPositionMatrix() const { return fInitialPositionMatrix; }
|
||||
bool supportBilerpAtlas() const { return fSupportBilerpAtlas; }
|
||||
|
||||
std::tuple<SkScalar, SkScalar> scaleBounds() const { return {fMaxMinScale, fMinMaxScale}; }
|
||||
bool canReuse(const SkPaint& paint, const SkMatrix& positionMatrix) const;
|
||||
@ -248,7 +250,10 @@ public:
|
||||
const GrSubRunList& subRunList() const { return fSubRunList; }
|
||||
|
||||
private:
|
||||
GrTextBlob(int allocSize, const SkMatrix& positionMatrix, SkColor initialLuminance);
|
||||
GrTextBlob(int allocSize,
|
||||
bool supportBilerpAtlas,
|
||||
const SkMatrix& positionMatrix,
|
||||
SkColor initialLuminance);
|
||||
|
||||
// Methods to satisfy SkGlyphRunPainterInterface
|
||||
void processDeviceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables,
|
||||
@ -276,6 +281,9 @@ private:
|
||||
// Overall size of this struct plus vertices and glyphs at the end.
|
||||
const int fSize;
|
||||
|
||||
// Support using bilerp for directly mapped sub runs.
|
||||
const bool fSupportBilerpAtlas;
|
||||
|
||||
// The initial view matrix combined with the initial origin. Used to determine if a cached
|
||||
// subRun can be used in this draw situation.
|
||||
const SkMatrix fInitialPositionMatrix;
|
||||
|
@ -52,8 +52,10 @@ void GrTextBlobCache::drawGlyphRunList(const GrClip* clip,
|
||||
this->remove(blob.get());
|
||||
}
|
||||
|
||||
const bool padAtlas =
|
||||
sdc->recordingContext()->priv().options().fSupportBilerpFromGlyphAtlas;
|
||||
blob = GrTextBlob::Make(
|
||||
glyphRunList, paint, positionMatrix, control, sdc->glyphRunPainter());
|
||||
glyphRunList, paint, positionMatrix, padAtlas, control, sdc->glyphRunPainter());
|
||||
|
||||
if (canCache) {
|
||||
blob->addKey(key);
|
||||
|
@ -48,9 +48,6 @@
|
||||
#include "src/image/SkSurface_Gpu.h"
|
||||
#include "src/utils/SkUTF.h"
|
||||
|
||||
// Define this for testing text blob draw using a slug.
|
||||
// #define SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG
|
||||
|
||||
#define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(fContext->priv().singleOwner())
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user