Respect max index buffer sizes in GrFillRectOp::MakeSet
This is required before we can lower the max AA quad count (again).
Bug: b/143572065 skia:9601
Change-Id: Iea5884ffff9bd62f62527fcb597dac97d33ecd76
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/254438
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/src/gpu/ops/GrFillRectOp.cpp b/src/gpu/ops/GrFillRectOp.cpp
index ec6fa0b..2ee183a 100644
--- a/src/gpu/ops/GrFillRectOp.cpp
+++ b/src/gpu/ops/GrFillRectOp.cpp
@@ -178,13 +178,11 @@
DEFINE_OP_CLASS_ID
private:
- // For GrFillRectOp::MakeSet's use of addQuad
- friend std::unique_ptr<GrDrawOp> GrFillRectOp::MakeSet(
- GrRecordingContext*,
- GrPaint&&,
- GrAAType, const SkMatrix& viewMatrix,
- const GrRenderTargetContext::QuadSetEntry quads[], int quadCount,
- const GrUserStencilSettings*);
+ friend class ::GrFillRectOp; // for access to addQuad
+
+#if GR_TEST_UTILS
+ int numQuads() const final { return fQuads.count(); }
+#endif
void onPrepareDraws(Target* target) override {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
@@ -297,19 +295,29 @@
// But since it's avoiding the op list management, it must update the op's bounds. This is only
// used with quad sets, which uses the same view matrix for each quad so this assumes that the
// device quad type of the new quad is the same as the op's.
- void addQuad(const GrQuad& deviceQuad, const GrQuad& localQuad,
+ bool addQuad(const GrQuad& deviceQuad, const GrQuad& localQuad,
const SkPMColor4f& color, GrQuadAAFlags edgeAA, GrAAType aaType) {
// The new quad's aa type should be the same as the first quad's or none, except when the
// first quad's aa type was already downgraded to none, in which case the stored type must
// be lifted to back to the requested type.
- if (aaType != fHelper.aaType()) {
- if (aaType != GrAAType::kNone) {
- // Original quad was downgraded to non-aa, lift back up to this quad's required type
- SkASSERT(fHelper.aaType() == GrAAType::kNone);
- fHelper.setAAType(aaType);
+ if (aaType != fHelper.aaType() && aaType != GrAAType::kNone) {
+ auto indexBufferOption = GrQuadPerEdgeAA::CalcIndexBufferOption(aaType,
+ fQuads.count()+1);
+ if (fQuads.count()+1 > GrQuadPerEdgeAA::QuadLimit(indexBufferOption)) {
+ // Promoting to the new aaType would've caused an overflow of the indexBuffer
+ // limit
+ return false;
}
- // else the new quad could have been downgraded but the other quads can't be, so don't
- // reset the op's accumulated aa type.
+
+ // Original quad was downgraded to non-aa, lift back up to this quad's required type
+ SkASSERT(fHelper.aaType() == GrAAType::kNone);
+ fHelper.setAAType(aaType);
+ } else {
+ auto indexBufferOption = GrQuadPerEdgeAA::CalcIndexBufferOption(fHelper.aaType(),
+ fQuads.count()+1);
+ if (fQuads.count()+1 > GrQuadPerEdgeAA::QuadLimit(indexBufferOption)) {
+ return false; // This op can't grow any more
+ }
}
// Update the bounds and add the quad to this op's storage
@@ -318,6 +326,7 @@
this->setBounds(newBounds, HasAABloat(fHelper.aaType() == GrAAType::kCoverage),
IsHairline::kNo);
fQuads.append(deviceQuad, { color, edgeAA }, fHelper.isTrivial() ? nullptr : &localQuad);
+ return true;
}
struct ColorAndAA {
@@ -335,45 +344,46 @@
} // anonymous namespace
-namespace GrFillRectOp {
-
-std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
- GrPaint&& paint,
- GrAAType aaType,
- GrQuadAAFlags aaFlags,
- const GrQuad& deviceQuad,
- const GrQuad& localQuad,
- const GrUserStencilSettings* stencil) {
+std::unique_ptr<GrDrawOp> GrFillRectOp::Make(GrRecordingContext* context,
+ GrPaint&& paint,
+ GrAAType aaType,
+ GrQuadAAFlags aaFlags,
+ const GrQuad& deviceQuad,
+ const GrQuad& localQuad,
+ const GrUserStencilSettings* stencil) {
return FillRectOp::Make(context, std::move(paint), aaType, aaFlags, stencil,
deviceQuad, localQuad);
}
-std::unique_ptr<GrDrawOp> MakeNonAARect(GrRecordingContext* context,
- GrPaint&& paint,
- const SkMatrix& view,
- const SkRect& rect,
- const GrUserStencilSettings* stencil) {
+std::unique_ptr<GrDrawOp> GrFillRectOp::MakeNonAARect(GrRecordingContext* context,
+ GrPaint&& paint,
+ const SkMatrix& view,
+ const SkRect& rect,
+ const GrUserStencilSettings* stencil) {
return FillRectOp::Make(context, std::move(paint), GrAAType::kNone, GrQuadAAFlags::kNone,
stencil, GrQuad::MakeFromRect(rect, view), GrQuad(rect));
}
-std::unique_ptr<GrDrawOp> MakeSet(GrRecordingContext* context,
- GrPaint&& paint,
- GrAAType aaType,
- const SkMatrix& viewMatrix,
- const GrRenderTargetContext::QuadSetEntry quads[],
- int cnt,
- const GrUserStencilSettings* stencilSettings) {
+std::unique_ptr<GrDrawOp> GrFillRectOp::MakeOp(GrRecordingContext* context,
+ GrPaint&& paint,
+ GrAAType aaType,
+ const SkMatrix& viewMatrix,
+ const GrRenderTargetContext::QuadSetEntry quads[],
+ int cnt,
+ const GrUserStencilSettings* stencilSettings,
+ int* numConsumed) {
// First make a draw op for the first quad in the set
SkASSERT(cnt > 0);
paint.setColor4f(quads[0].fColor);
- std::unique_ptr<GrDrawOp> op = FillRectOp::Make(context, std::move(paint), aaType,
+ std::unique_ptr<GrDrawOp> op = FillRectOp::Make(
+ context, std::move(paint), aaType,
quads[0].fAAFlags, stencilSettings,
GrQuad::MakeFromRect(quads[0].fRect, viewMatrix),
GrQuad::MakeFromRect(quads[0].fRect, quads[0].fLocalMatrix));
- auto* fillRects = op->cast<FillRectOp>();
+ FillRectOp* fillRects = op->cast<FillRectOp>();
+ *numConsumed = 1;
// Accumulate remaining quads similar to onCombineIfPossible() without creating an op
for (int i = 1; i < cnt; ++i) {
GrQuad deviceQuad = GrQuad::MakeFromRect(quads[i].fRect, viewMatrix);
@@ -383,18 +393,52 @@
GrQuadUtils::ResolveAAType(aaType, quads[i].fAAFlags, deviceQuad,
&resolvedAA, &resolvedEdgeFlags);
- fillRects->addQuad(deviceQuad,
- GrQuad::MakeFromRect(quads[i].fRect, quads[i].fLocalMatrix),
- quads[i].fColor, resolvedEdgeFlags,resolvedAA);
+ if (!fillRects->addQuad(deviceQuad,
+ GrQuad::MakeFromRect(quads[i].fRect, quads[i].fLocalMatrix),
+ quads[i].fColor, resolvedEdgeFlags, resolvedAA)) {
+ break;
+ }
+
+ (*numConsumed)++;
}
return op;
}
-} // namespace GrFillRectOp
+void GrFillRectOp::AddFillRectOps(GrRenderTargetContext* rtc,
+ const GrClip& clip,
+ GrRecordingContext* context,
+ GrPaint&& paint,
+ GrAAType aaType,
+ const SkMatrix& viewMatrix,
+ const GrRenderTargetContext::QuadSetEntry quads[],
+ int cnt,
+ const GrUserStencilSettings* stencilSettings) {
+
+ int offset = 0;
+ int numLeft = cnt;
+ while (numLeft) {
+ int numConsumed = 0;
+
+ std::unique_ptr<GrDrawOp> op = MakeOp(context, GrPaint::Clone(paint), aaType, viewMatrix,
+ &quads[offset], numLeft, stencilSettings,
+ &numConsumed);
+
+ offset += numConsumed;
+ numLeft -= numConsumed;
+
+ rtc->addDrawOp(clip, std::move(op));
+ }
+
+ SkASSERT(offset == cnt);
+}
#if GR_TEST_UTILS
+uint32_t GrFillRectOp::ClassID() {
+ return FillRectOp::ClassID();
+}
+
#include "src/gpu/GrDrawOpTest.h"
#include "src/gpu/SkGr.h"
@@ -417,35 +461,11 @@
if (random->nextBool()) {
if (random->nextBool()) {
- if (random->nextBool()) {
- // Local matrix with a set op
- uint32_t extraQuadCt = random->nextRangeU(1, 4);
- SkTArray<GrRenderTargetContext::QuadSetEntry> quads(extraQuadCt + 1);
- quads.push_back(
- {rect, SkPMColor4f::FromBytes_RGBA(SkColorToPremulGrColor(random->nextU())),
- GrTest::TestMatrixInvertible(random), aaFlags});
- for (uint32_t i = 0; i < extraQuadCt; ++i) {
- GrQuadAAFlags aaFlags = GrQuadAAFlags::kNone;
- aaFlags |= random->nextBool() ? GrQuadAAFlags::kLeft : GrQuadAAFlags::kNone;
- aaFlags |= random->nextBool() ? GrQuadAAFlags::kTop : GrQuadAAFlags::kNone;
- aaFlags |= random->nextBool() ? GrQuadAAFlags::kRight : GrQuadAAFlags::kNone;
- aaFlags |= random->nextBool() ? GrQuadAAFlags::kBottom : GrQuadAAFlags::kNone;
-
- quads.push_back(
- {GrTest::TestRect(random),
- SkPMColor4f::FromBytes_RGBA(SkColorToPremulGrColor(random->nextU())),
- GrTest::TestMatrixInvertible(random), aaFlags});
- }
-
- return GrFillRectOp::MakeSet(context, std::move(paint), aaType, viewMatrix,
- quads.begin(), quads.count(), stencil);
- } else {
- // Single local matrix
- SkMatrix localMatrix = GrTest::TestMatrixInvertible(random);
- return GrFillRectOp::Make(context, std::move(paint), aaType, aaFlags,
- GrQuad::MakeFromRect(rect, viewMatrix),
- GrQuad::MakeFromRect(rect, localMatrix), stencil);
- }
+ // Single local matrix
+ SkMatrix localMatrix = GrTest::TestMatrixInvertible(random);
+ return GrFillRectOp::Make(context, std::move(paint), aaType, aaFlags,
+ GrQuad::MakeFromRect(rect, viewMatrix),
+ GrQuad::MakeFromRect(rect, localMatrix), stencil);
} else {
// Pass local rect directly
SkRect localRect = GrTest::TestRect(random);