Some more clipped text optimizations.
* Limit size of text batches to keep inside default vertex buffer size * Expand geodata allocation by 1.5x rather than 2x * Don't add text subruns that lie outside the clip rect Bug: skia:3990 Change-Id: I2b8f8bc5599d14c43e0a98e9633bc51980a7619c Reviewed-on: https://skia-review.googlesource.com/62861 Commit-Queue: Jim Van Verth <jvanverth@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
4d3f20f9b3
commit
c8a65e3e6e
@ -315,18 +315,27 @@ bool GrAtlasTextOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
|
||||
}
|
||||
}
|
||||
|
||||
// Keep the batch vertex buffer size below 32K so we don't have to create a special one
|
||||
// We use the largest possible vertex size for this
|
||||
static const int kVertexSize = sizeof(SkPoint) + sizeof(SkColor) + 2 * sizeof(uint16_t);
|
||||
static const int kMaxGlyphs = 32768 / (4 * kVertexSize);
|
||||
if (this->fNumGlyphs + that->fNumGlyphs > kMaxGlyphs) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fNumGlyphs += that->numGlyphs();
|
||||
|
||||
// Reallocate space for geo data if necessary and then import that's geo data.
|
||||
int newGeoCount = that->fGeoCount + fGeoCount;
|
||||
// We assume (and here enforce) that the allocation size is the smallest power of two that
|
||||
// is greater than or equal to the number of geometries (and at least
|
||||
// kMinGeometryAllocated).
|
||||
int newAllocSize = GrNextPow2(newGeoCount);
|
||||
int currAllocSize = SkTMax<int>(kMinGeometryAllocated, GrNextPow2(fGeoCount));
|
||||
|
||||
if (newGeoCount > currAllocSize) {
|
||||
// We reallocate at a rate of 1.5x to try to get better total memory usage
|
||||
if (newGeoCount > fGeoDataAllocSize) {
|
||||
int newAllocSize = fGeoDataAllocSize + fGeoDataAllocSize/2;
|
||||
while (newAllocSize < newGeoCount) {
|
||||
newAllocSize += newAllocSize / 2;
|
||||
}
|
||||
fGeoData.realloc(newAllocSize);
|
||||
fGeoDataAllocSize = newAllocSize;
|
||||
}
|
||||
|
||||
// We steal the ref on the blobs from the other AtlasTextOp and set its count to 0 so that
|
||||
|
@ -117,8 +117,12 @@ public:
|
||||
GrPixelConfigIsClamped dstIsClamped) override;
|
||||
|
||||
private:
|
||||
// The minimum number of Geometry we will try to allocate.
|
||||
static constexpr auto kMinGeometryAllocated = 4;
|
||||
|
||||
GrAtlasTextOp(GrPaint&& paint)
|
||||
: INHERITED(ClassID())
|
||||
, fGeoDataAllocSize(kMinGeometryAllocated)
|
||||
, fColor(paint.getColor())
|
||||
, fSRGBFlags(GrPipeline::SRGBFlagsFromPaint(paint))
|
||||
, fProcessors(std::move(paint)) {}
|
||||
@ -176,9 +180,6 @@ private:
|
||||
|
||||
sk_sp<GrGeometryProcessor> setupDfProcessor() const;
|
||||
|
||||
// The minimum number of Geometry we will try to allocate.
|
||||
enum { kMinGeometryAllocated = 4 };
|
||||
|
||||
enum MaskType {
|
||||
kGrayscaleCoverageMask_MaskType,
|
||||
kLCDCoverageMask_MaskType,
|
||||
@ -190,6 +191,7 @@ private:
|
||||
};
|
||||
|
||||
SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
|
||||
int fGeoDataAllocSize;
|
||||
GrColor fColor;
|
||||
uint32_t fSRGBFlags;
|
||||
GrProcessorSet fProcessors;
|
||||
|
@ -306,31 +306,39 @@ inline void GrAtlasTextBlob::flushRun(GrRenderTargetContext* rtc, const GrClip&
|
||||
continue;
|
||||
}
|
||||
|
||||
bool skipClip = false;
|
||||
bool submitOp = true;
|
||||
SkIRect clipRect = SkIRect::MakeEmpty();
|
||||
SkRect rtBounds = SkRect::MakeWH(rtc->width(), rtc->height());
|
||||
SkRRect clipRRect;
|
||||
GrAA aa;
|
||||
// we can clip geometrically if we're not using SDFs,
|
||||
// We can clip geometrically if we're not using SDFs,
|
||||
// and we have an axis-aligned rectangular non-AA clip
|
||||
bool skipClip = false;
|
||||
SkIRect clipRect = SkIRect::MakeEmpty();
|
||||
if (!info.drawAsDistanceFields() && clip.isRRect(rtBounds, &clipRRect, &aa) &&
|
||||
clipRRect.isRect() && GrAA::kNo == aa) {
|
||||
skipClip = true;
|
||||
// we only need to do clipping work if the subrun isn't contained by the clip
|
||||
// We only need to do clipping work if the subrun isn't contained by the clip
|
||||
SkRect subRunBounds;
|
||||
this->computeSubRunBounds(&subRunBounds, run, subRun, viewMatrix, x, y);
|
||||
if (!clipRRect.getBounds().contains(subRunBounds)) {
|
||||
clipRRect.getBounds().round(&clipRect);
|
||||
// If the subrun is completely outside, don't add an op for it
|
||||
if (!clipRRect.getBounds().intersects(subRunBounds)) {
|
||||
submitOp = false;
|
||||
} else {
|
||||
clipRRect.getBounds().round(&clipRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto op = this->makeOp(info, glyphCount, run, subRun, viewMatrix, x, y, clipRect,
|
||||
std::move(paint), props, distanceAdjustTable, cache, rtc);
|
||||
if (op) {
|
||||
if (skipClip) {
|
||||
rtc->addDrawOp(GrNoClip(), std::move(op));
|
||||
} else {
|
||||
rtc->addDrawOp(clip, std::move(op));
|
||||
if (submitOp) {
|
||||
auto op = this->makeOp(info, glyphCount, run, subRun, viewMatrix, x, y, clipRect,
|
||||
std::move(paint), props, distanceAdjustTable, cache, rtc);
|
||||
if (op) {
|
||||
if (skipClip) {
|
||||
rtc->addDrawOp(GrNoClip(), std::move(op));
|
||||
} else {
|
||||
rtc->addDrawOp(clip, std::move(op));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user