diff options
author | 2016-07-06 07:03:26 -0700 | |
---|---|---|
committer | 2016-07-06 07:03:26 -0700 | |
commit | 4be9a30aed390bd37681242252fe29d7839bad19 (patch) | |
tree | 7fe85039f4b0c04dcf981513621c15b1f6810b95 /src/gpu | |
parent | 8e5a588ab3fc7268e7750009484dbe1d0742b1c2 (diff) |
Increase batching for AA fill rects.
This allows batching of rects provided without a local matrix when local coords are required and when the view matrix changes.
It also allows batching of rects with a local matrix with rects without a local matrix.
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2116823002
Committed: https://skia.googlesource.com/skia/+/e525ecaf63f225f1da6e9834f7a291c06ad44d23
Review-Url: https://codereview.chromium.org/2116823002
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/batches/GrAAFillRectBatch.cpp | 290 |
1 files changed, 106 insertions, 184 deletions
diff --git a/src/gpu/batches/GrAAFillRectBatch.cpp b/src/gpu/batches/GrAAFillRectBatch.cpp index ffbab9654e..fedde70398 100644 --- a/src/gpu/batches/GrAAFillRectBatch.cpp +++ b/src/gpu/batches/GrAAFillRectBatch.cpp @@ -13,9 +13,9 @@ #include "GrResourceKey.h" #include "GrResourceProvider.h" #include "GrTypes.h" +#include "GrVertexBatch.h" #include "SkMatrix.h" #include "SkRect.h" -#include "GrVertexBatch.h" GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); @@ -45,35 +45,6 @@ const GrBuffer* get_index_buffer(GrResourceProvider* resourceProvider) { gAAFillRectIndexBufferKey); } -static sk_sp<GrGeometryProcessor> create_fill_rect_gp( - const SkMatrix& viewMatrix, - const GrXPOverridesForBatch& overrides, - GrDefaultGeoProcFactory::LocalCoords::Type localCoordsType) { - using namespace GrDefaultGeoProcFactory; - - Color color(Color::kAttribute_Type); - Coverage::Type coverageType; - // TODO remove coverage if coverage is ignored - /*if (coverageIgnored) { - coverageType = Coverage::kNone_Type; - } else*/ if (overrides.canTweakAlphaForCoverage()) { - coverageType = Coverage::kSolid_Type; - } else { - coverageType = Coverage::kAttribute_Type; - } - Coverage coverage(coverageType); - - // We assume the caller has inverted the viewmatrix - if (LocalCoords::kHasExplicit_Type == localCoordsType) { - LocalCoords localCoords(localCoordsType); - return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMatrix::I()); - } else { - LocalCoords localCoords(overrides.readsLocalCoords() ? localCoordsType : - LocalCoords::kUnused_Type); - return MakeForDeviceSpace(color, coverage, localCoords, viewMatrix); - } -} - static void generate_aa_fill_rect_geometry(intptr_t verts, size_t vertexStride, GrColor color, @@ -137,7 +108,7 @@ static void generate_aa_fill_rect_geometry(intptr_t verts, if (localMatrix) { SkMatrix invViewMatrix; if (!viewMatrix.invert(&invViewMatrix)) { - SkASSERT(false); + SkDebugf("View matrix is non-invertible, local coords will be wrong."); invViewMatrix = SkMatrix::I(); } SkMatrix localCoordMatrix; @@ -186,28 +157,37 @@ static void generate_aa_fill_rect_geometry(intptr_t verts, } } } - -class AAFillRectNoLocalMatrixBatch : public GrVertexBatch { +class AAFillRectBatch : public GrVertexBatch { public: DEFINE_BATCH_CLASS_ID - AAFillRectNoLocalMatrixBatch(GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect, - const SkRect& devRect) : INHERITED(ClassID()) { - fRects.emplace_back(RectInfo{color, viewMatrix, rect, devRect}); + + AAFillRectBatch(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& rect, + const SkRect& devRect, + const SkMatrix* localMatrix) : INHERITED(ClassID()) { + if (localMatrix) { + void* mem = fRectData.push_back_n(sizeof(RectWithLocalMatrixInfo)); + new (mem) RectWithLocalMatrixInfo(color, viewMatrix, rect, devRect, *localMatrix); + } else { + void* mem = fRectData.push_back_n(sizeof(RectInfo)); + new (mem) RectInfo(color, viewMatrix, rect, devRect); + } fBounds = devRect; + fRectCnt = 1; } - const char* name() const override { return "AAFillRectBatchNoLocalMatrix"; } + const char* name() const override { return "AAFillRectBatch"; } SkString dumpInfo() const override { SkString str; - str.appendf("# batched: %d\n", fRects.count()); - for (int i = 0; i < fRects.count(); ++i) { - const RectInfo& info = fRects[i]; + str.appendf("# batched: %d\n", fRectCnt); + const RectInfo* info = this->first(); + for (int i = 0; i < fRectCnt; ++i) { + const SkRect& rect = info->rect(); str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", - i, info.fColor, - info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight, info.fRect.fBottom); + i, info->color(), rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); + info = this->next(info); } str.append(INHERITED::dumpInfo()); return str; @@ -217,30 +197,39 @@ public: GrInitInvariantOutput* coverage, GrBatchToXPOverrides* overrides) const override { // When this is called on a batch, there is only one rect - color->setKnownFourComponents(fRects[0].fColor); + color->setKnownFourComponents(this->first()->color()); coverage->setUnknownSingleComponent(); } void initBatchTracker(const GrXPOverridesForBatch& overrides) override { - overrides.getOverrideColorIfSet(&fRects[0].fColor); + GrColor color; + if (overrides.getOverrideColorIfSet(&color)) { + this->first()->setColor(color); + } fOverrides = overrides; } private: - AAFillRectNoLocalMatrixBatch() : INHERITED(ClassID()) {} - void onPrepareDraws(Target* target) const override { - sk_sp<GrGeometryProcessor> gp = - create_fill_rect_gp(fRects[0].fViewMatrix, fOverrides, - GrDefaultGeoProcFactory::LocalCoords::kUsePosition_Type); + bool needLocalCoords = fOverrides.readsLocalCoords(); + using namespace GrDefaultGeoProcFactory; + + Color color(Color::kAttribute_Type); + Coverage::Type coverageType; + if (fOverrides.canTweakAlphaForCoverage()) { + coverageType = Coverage::kSolid_Type; + } else { + coverageType = Coverage::kAttribute_Type; + } + Coverage coverage(coverageType); + LocalCoords lc = needLocalCoords ? LocalCoords::kHasExplicit_Type + : LocalCoords::kUnused_Type; + sk_sp<GrGeometryProcessor> gp = GrDefaultGeoProcFactory::Make(color, coverage, lc, + SkMatrix::I()); if (!gp) { SkDebugf("Couldn't create GrGeometryProcessor\n"); return; } - SkASSERT(fOverrides.canTweakAlphaForCoverage() ? - gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) : - gp->getVertexStride() == - sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); size_t vertexStride = gp->getVertexStride(); @@ -248,171 +237,104 @@ private: InstancedHelper helper; void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer, kVertsPerAAFillRect, - kIndicesPerAAFillRect, fRects.count()); + kIndicesPerAAFillRect, fRectCnt); if (!vertices || !indexBuffer) { SkDebugf("Could not allocate vertices\n"); return; } - for (int i = 0; i < fRects.count(); i++) { + const RectInfo* info = this->first(); + const SkMatrix* localMatrix = nullptr; + for (int i = 0; i < fRectCnt; i++) { intptr_t verts = reinterpret_cast<intptr_t>(vertices) + i * kVertsPerAAFillRect * vertexStride; - generate_aa_fill_rect_geometry(verts, vertexStride, - fRects[i].fColor, fRects[i].fViewMatrix, - fRects[i].fRect, fRects[i].fDevRect, fOverrides, - nullptr); + if (needLocalCoords) { + if (info->hasLocalMatrix()) { + localMatrix = &static_cast<const RectWithLocalMatrixInfo*>(info)->localMatrix(); + } else { + localMatrix = &SkMatrix::I(); + } + } + generate_aa_fill_rect_geometry(verts, vertexStride, info->color(), + info->viewMatrix(), info->rect(), + info->devRect(), fOverrides, localMatrix); + info = this->next(info); } helper.recordDraw(target, gp.get()); } bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { - AAFillRectNoLocalMatrixBatch* that = t->cast<AAFillRectNoLocalMatrixBatch>(); + AAFillRectBatch* that = t->cast<AAFillRectBatch>(); if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), that->bounds(), caps)) { return false; } - // We apply the viewmatrix to the rect points on the cpu. However, if the pipeline uses - // local coords then we won't be able to batch. We could actually upload the viewmatrix - // using vertex attributes in these cases, but haven't investigated that - if (fOverrides.readsLocalCoords() && - !fRects[0].fViewMatrix.cheapEqualTo(that->fRects[0].fViewMatrix)) { - return false; - } - // In the event of two batches, one who can tweak, one who cannot, we just fall back to // not tweaking if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakAlphaForCoverage()) { fOverrides = that->fOverrides; } - fRects.push_back_n(that->fRects.count(), that->fRects.begin()); + fRectData.push_back_n(that->fRectData.count(), that->fRectData.begin()); + fRectCnt += that->fRectCnt; this->joinBounds(that->bounds()); return true; } struct RectInfo { + public: + RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, + const SkRect& devRect) + : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kNo) {} + bool hasLocalMatrix() const { return HasLocalMatrix::kYes == fHasLocalMatrix; } + GrColor color() const { return fColor; } + const SkMatrix& viewMatrix() const { return fViewMatrix; } + const SkRect& rect() const { return fRect; } + const SkRect& devRect() const { return fDevRect; } + + void setColor(GrColor color) { fColor = color; } + protected: + enum class HasLocalMatrix : uint32_t { kNo, kYes }; + + RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, + const SkRect& devRect, HasLocalMatrix hasLM) + : fHasLocalMatrix(hasLM) + , fColor(color) + , fViewMatrix(viewMatrix) + , fRect(rect) + , fDevRect(devRect) {} + + HasLocalMatrix fHasLocalMatrix; GrColor fColor; SkMatrix fViewMatrix; SkRect fRect; SkRect fDevRect; }; - GrXPOverridesForBatch fOverrides; - SkSTArray<1, RectInfo, true> fRects; - - typedef GrVertexBatch INHERITED; -}; - -class AAFillRectLocalMatrixBatch : public GrVertexBatch { -public: - DEFINE_BATCH_CLASS_ID - - AAFillRectLocalMatrixBatch(GrColor color, - const SkMatrix& viewMatrix, - const SkMatrix& localMatrix, - const SkRect& rect, - const SkRect& devRect) : INHERITED(ClassID()) { - fRects.emplace_back(RectInfo{color, viewMatrix, localMatrix, rect, devRect}); - fBounds = devRect; - } - - const char* name() const override { return "AAFillRectBatchLocalMatrix"; } - - SkString dumpInfo() const override { - SkString str; - str.appendf("# batched: %d\n", fRects.count()); - for (int i = 0; i < fRects.count(); ++i) { - const RectInfo& info = fRects[i]; - str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", - i, info.fColor, - info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight, info.fRect.fBottom); - } - str.append(INHERITED::dumpInfo()); - return str; - } - - void computePipelineOptimizations(GrInitInvariantOutput* color, - GrInitInvariantOutput* coverage, - GrBatchToXPOverrides* overrides) const override { - // When this is called on a batch, there is only one rect - color->setKnownFourComponents(fRects[0].fColor); - coverage->setUnknownSingleComponent(); - } - - void initBatchTracker(const GrXPOverridesForBatch& overrides) override { - overrides.getOverrideColorIfSet(&fRects[0].fColor); - fOverrides = overrides; - } - -private: - AAFillRectLocalMatrixBatch() : INHERITED(ClassID()) {} - - void onPrepareDraws(Target* target) const override { - sk_sp<GrGeometryProcessor> gp = - create_fill_rect_gp(fRects[0].fViewMatrix, fOverrides, - GrDefaultGeoProcFactory::LocalCoords::kHasExplicit_Type); - if (!gp) { - SkDebugf("Couldn't create GrGeometryProcessor\n"); - return; - } - SkASSERT(fOverrides.canTweakAlphaForCoverage() ? - gp->getVertexStride() == - sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) : - gp->getVertexStride() == - sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordCoverage)); - - size_t vertexStride = gp->getVertexStride(); - - SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resourceProvider())); - InstancedHelper helper; - void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride, - indexBuffer, kVertsPerAAFillRect, - kIndicesPerAAFillRect, fRects.count()); - if (!vertices || !indexBuffer) { - SkDebugf("Could not allocate vertices\n"); - return; - } - - for (int i = 0; i < fRects.count(); i++) { - intptr_t verts = reinterpret_cast<intptr_t>(vertices) + - i * kVertsPerAAFillRect * vertexStride; - generate_aa_fill_rect_geometry(verts, vertexStride, fRects[i].fColor, - fRects[i].fViewMatrix, fRects[i].fRect, - fRects[i].fDevRect, fOverrides, - &fRects[i].fLocalMatrix); - } - helper.recordDraw(target, gp.get()); - } - - bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { - AAFillRectLocalMatrixBatch* that = t->cast<AAFillRectLocalMatrixBatch>(); - if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), - that->bounds(), caps)) { - return false; - } - - // In the event of two batches, one who can tweak, one who cannot, we just fall back to - // not tweaking - if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakAlphaForCoverage()) { - fOverrides = that->fOverrides; - } - - fRects.push_back_n(that->fRects.count(), that->fRects.begin()); - this->joinBounds(that->bounds()); - return true; - } - - struct RectInfo { - GrColor fColor; - SkMatrix fViewMatrix; + struct RectWithLocalMatrixInfo : public RectInfo { + public: + RectWithLocalMatrixInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, + const SkRect& devRect, const SkMatrix& localMatrix) + : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kYes) + , fLocalMatrix(localMatrix) {} + const SkMatrix& localMatrix() const { return fLocalMatrix; } + private: SkMatrix fLocalMatrix; - SkRect fRect; - SkRect fDevRect; }; + RectInfo* first() { return reinterpret_cast<RectInfo*>(fRectData.begin()); } + const RectInfo* first() const { return reinterpret_cast<const RectInfo*>(fRectData.begin()); } + const RectInfo* next(const RectInfo* prev) const { + intptr_t next = reinterpret_cast<intptr_t>(prev) + + (prev->hasLocalMatrix() ? sizeof(RectWithLocalMatrixInfo) + : sizeof(RectInfo)); + return reinterpret_cast<const RectInfo*>(next); + } + GrXPOverridesForBatch fOverrides; - SkSTArray<1, RectInfo, true> fRects; + SkSTArray<4 * sizeof(RectWithLocalMatrixInfo), uint8_t, true> fRectData; + int fRectCnt; typedef GrVertexBatch INHERITED; }; @@ -423,7 +345,7 @@ GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, const SkRect& devRect) { - return new AAFillRectNoLocalMatrixBatch(color, viewMatrix, rect, devRect); + return new AAFillRectBatch(color, viewMatrix, rect, devRect, nullptr); } GrDrawBatch* Create(GrColor color, @@ -431,7 +353,7 @@ GrDrawBatch* Create(GrColor color, const SkMatrix& localMatrix, const SkRect& rect, const SkRect& devRect) { - return new AAFillRectLocalMatrixBatch(color, viewMatrix, localMatrix, rect, devRect); + return new AAFillRectBatch(color, viewMatrix, rect, devRect, &localMatrix); } GrDrawBatch* Create(GrColor color, |