diff options
-rw-r--r-- | src/gpu/ops/GrAtlasTextOp.cpp | 21 | ||||
-rw-r--r-- | src/gpu/ops/GrAtlasTextOp.h | 8 | ||||
-rw-r--r-- | src/gpu/text/GrAtlasTextBlob.cpp | 32 |
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)); + } } } } |