aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/gpu/ops/GrAtlasTextOp.cpp21
-rw-r--r--src/gpu/ops/GrAtlasTextOp.h8
-rw-r--r--src/gpu/text/GrAtlasTextBlob.cpp32
3 files changed, 40 insertions, 21 deletions
diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp
index 257fb3b9e9..21e7c6fa69 100644
--- a/src/gpu/ops/GrAtlasTextOp.cpp
+++ b/src/gpu/ops/GrAtlasTextOp.cpp
@@ -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
diff --git a/src/gpu/ops/GrAtlasTextOp.h b/src/gpu/ops/GrAtlasTextOp.h
index 07627367cc..622b993d44 100644
--- a/src/gpu/ops/GrAtlasTextOp.h
+++ b/src/gpu/ops/GrAtlasTextOp.h
@@ -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;
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index be83dc1085..a6dbd67286 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -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));
+ }
}
}
}