Index: src/gpu/batches/GrAAFillRectBatch.cpp |
diff --git a/src/gpu/batches/GrAAFillRectBatch.cpp b/src/gpu/batches/GrAAFillRectBatch.cpp |
index ffbab9654e52d61f127a0f8ffa0020fc2ba9ef58..79b086a4fa3c847a3967ace283c09508daa0bfd6 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,10 +45,8 @@ 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) { |
+static sk_sp<GrGeometryProcessor> create_fill_rect_gp(const GrXPOverridesForBatch& overrides, |
+ bool hasLocalMatrix) { |
using namespace GrDefaultGeoProcFactory; |
Color color(Color::kAttribute_Type); |
@@ -63,15 +61,9 @@ static sk_sp<GrGeometryProcessor> create_fill_rect_gp( |
} |
Coverage coverage(coverageType); |
+ LocalCoords lc = hasLocalMatrix ? LocalCoords::kHasExplicit_Type : LocalCoords::kUsePosition_Type; |
// 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); |
- } |
+ return GrDefaultGeoProcFactory::Make(color, coverage, lc, SkMatrix::I()); |
} |
static void generate_aa_fill_rect_geometry(intptr_t verts, |
@@ -186,147 +178,39 @@ static void generate_aa_fill_rect_geometry(intptr_t verts, |
} |
} |
} |
- |
-class AAFillRectNoLocalMatrixBatch : 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}); |
- fBounds = devRect; |
- } |
- |
- const char* name() const override { return "AAFillRectBatchNoLocalMatrix"; } |
- |
- 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: |
- 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); |
- 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(); |
- |
- 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, |
- nullptr); |
- } |
- helper.recordDraw(target, gp.get()); |
- } |
- |
- bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
- AAFillRectNoLocalMatrixBatch* that = t->cast<AAFillRectNoLocalMatrixBatch>(); |
- 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()); |
- this->joinBounds(that->bounds()); |
- return true; |
- } |
- |
- struct RectInfo { |
- 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}); |
+ const SkRect& devRect, |
+ const SkMatrix* localMatrix) : INHERITED(ClassID()) { |
+ if (localMatrix) { |
+ void* mem = fRectData.append(sizeof(RectWithLocalMatrixInfo)); |
+ new (mem) RectWithLocalMatrixInfo(color, viewMatrix, rect, devRect, *localMatrix); |
+ fUseLocalMatrix = true; |
+ } else { |
+ void* mem = fRectData.append(sizeof(RectInfo)); |
+ new (mem) RectInfo(color, viewMatrix, rect, devRect); |
+ fUseLocalMatrix = false; |
+ } |
fBounds = devRect; |
+ fRectCnt = 1; |
} |
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("# 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; |
@@ -336,56 +220,77 @@ 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; |
+ if (!overrides.readsLocalCoords() && false) { |
+ fUseLocalMatrix = false; |
+ } |
} |
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); |
+ sk_sp<GrGeometryProcessor> gp = create_fill_rect_gp(fOverrides, fUseLocalMatrix); |
if (!gp) { |
SkDebugf("Couldn't create GrGeometryProcessor\n"); |
return; |
} |
- SkASSERT(fOverrides.canTweakAlphaForCoverage() ? |
- gp->getVertexStride() == |
- sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) : |
- gp->getVertexStride() == |
- sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordCoverage)); |
- |
+ if (fOverrides.canTweakAlphaForCoverage()) { |
+ if (fUseLocalMatrix) { |
+ SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)); |
+ } else { |
+ SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorAttr)); |
+ } |
+ } else { |
+ if (fUseLocalMatrix) { |
+ SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordCoverage)); |
+ } else { |
+ SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); |
+ } |
+ } |
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()); |
+ 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(); |
+ 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, |
- &fRects[i].fLocalMatrix); |
+ const SkMatrix* localMatrix = nullptr; |
+ if (fUseLocalMatrix) { |
+ if (HasLocalMatrix::kYes == 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 { |
+ return false; |
AAFillRectLocalMatrixBatch* that = t->cast<AAFillRectLocalMatrixBatch>(); |
if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), |
that->bounds(), caps)) { |
@@ -398,21 +303,68 @@ private: |
fOverrides = that->fOverrides; |
} |
- fRects.push_back_n(that->fRects.count(), that->fRects.begin()); |
+ fRectData.append(that->fRectData.count(), that->fRectData.begin()); |
+ fRectCnt += that->fRectCnt; |
this->joinBounds(that->bounds()); |
+ fUseLocalMatrix = (fUseLocalMatrix || that->fUseLocalMatrix); |
return true; |
} |
+ enum class HasLocalMatrix : uint32_t { kNo, kYes }; |
+ |
struct RectInfo { |
+ public: |
+ RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, |
+ const SkRect& devRect) |
+ : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kNo) {} |
+ HasLocalMatrix hasLocalMatrix() const { return 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: |
+ 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; |
- SkMatrix fLocalMatrix; |
SkRect fRect; |
SkRect fDevRect; |
}; |
+ 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; |
+ }; |
+ |
+ 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) + |
+ (HasLocalMatrix::kYes == prev->hasLocalMatrix() |
+ ? sizeof(RectWithLocalMatrixInfo) |
+ : sizeof(RectInfo)); |
+ return reinterpret_cast<const RectInfo*>(next); |
+ } |
+ |
GrXPOverridesForBatch fOverrides; |
- SkSTArray<1, RectInfo, true> fRects; |
+ SkTDArray<uint8_t> fRectData; |
+ int fRectCnt; |
+ bool fUseLocalMatrix; |
typedef GrVertexBatch INHERITED; |
}; |
@@ -423,7 +375,7 @@ GrDrawBatch* Create(GrColor color, |
const SkMatrix& viewMatrix, |
const SkRect& rect, |
const SkRect& devRect) { |
- return new AAFillRectNoLocalMatrixBatch(color, viewMatrix, rect, devRect); |
+ return new AAFillRectLocalMatrixBatch(color, viewMatrix, rect, devRect, nullptr); |
} |
GrDrawBatch* Create(GrColor color, |
@@ -431,7 +383,7 @@ GrDrawBatch* Create(GrColor color, |
const SkMatrix& localMatrix, |
const SkRect& rect, |
const SkRect& devRect) { |
- return new AAFillRectLocalMatrixBatch(color, viewMatrix, localMatrix, rect, devRect); |
+ return new AAFillRectLocalMatrixBatch(color, viewMatrix, rect, devRect, &localMatrix); |
} |
GrDrawBatch* Create(GrColor color, |