From febb22469999b928850182ebc57bfd6fbd7402d6 Mon Sep 17 00:00:00 2001 From: msarett Date: Fri, 26 Aug 2016 12:49:27 -0700 Subject: [PATCH] Reduce CPU overhead on drawRegion() Only batch when the view matrices are the same. This allows us to skip applying the matrix and uploading local coords. drawregion Bench on Nexus 6P: Before 4.69ms After 2.83ms This puts SkiaGL nearly on par with OpenGL. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2282983003 Review-Url: https://codereview.chromium.org/2282983003 --- gm/drawregion.cpp | 2 ++ src/gpu/batches/GrRegionBatch.cpp | 45 +++++++++++++------------------ 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/gm/drawregion.cpp b/gm/drawregion.cpp index 1e9d6c55e2..a2633f9d9f 100644 --- a/gm/drawregion.cpp +++ b/gm/drawregion.cpp @@ -37,6 +37,8 @@ protected: } void onDraw(SkCanvas* canvas) override { + canvas->translate(10, 10); + SkPaint paint; paint.setStyle(SkPaint::kFill_Style); paint.setColor(0xFFFF00FF); diff --git a/src/gpu/batches/GrRegionBatch.cpp b/src/gpu/batches/GrRegionBatch.cpp index 271f6c5b7e..058baf0ef8 100644 --- a/src/gpu/batches/GrRegionBatch.cpp +++ b/src/gpu/batches/GrRegionBatch.cpp @@ -17,31 +17,26 @@ static const int kVertsPerInstance = 4; static const int kIndicesPerInstance = 6; -static sk_sp make_gp(bool readsCoverage) { +static sk_sp make_gp(bool readsCoverage, const SkMatrix& viewMatrix) { using namespace GrDefaultGeoProcFactory; Color color(Color::kAttribute_Type); Coverage coverage(readsCoverage ? Coverage::kSolid_Type : Coverage::kNone_Type); - LocalCoords localCoords(LocalCoords::kHasExplicit_Type); - return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMatrix::I()); + LocalCoords localCoords(LocalCoords::kUsePosition_Type); + return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, viewMatrix); } -static int tesselate_region(intptr_t vertices, +static void tesselate_region(intptr_t vertices, size_t vertexStride, GrColor color, - const SkMatrix& viewMatrix, const SkRegion& region) { SkRegion::Iterator iter(region); intptr_t verts = vertices; while (!iter.done()) { - SkIRect rect = iter.rect(); + SkRect rect = SkRect::Make(iter.rect()); SkPoint* position = (SkPoint*) verts; - position->setIRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vertexStride); - - static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); - SkPoint* localPosition = (SkPoint*) (verts + kLocalOffset); - localPosition->setIRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vertexStride); + position->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vertexStride); static const int kColorOffset = sizeof(SkPoint); GrColor* vertColor = reinterpret_cast(verts + kColorOffset); @@ -53,13 +48,6 @@ static int tesselate_region(intptr_t vertices, verts += vertexStride * kVertsPerInstance; iter.next(); } - - SkPoint* positions = reinterpret_cast(vertices); - int numRects = region.computeRegionComplexity(); - SkMatrixPriv::MapPointsWithStride(viewMatrix, positions, vertexStride, - numRects * kVertsPerInstance); - - return numRects; } class RegionBatch : public GrVertexBatch { @@ -67,11 +55,11 @@ public: DEFINE_BATCH_CLASS_ID RegionBatch(GrColor color, const SkMatrix& viewMatrix, const SkRegion& region) - : INHERITED(ClassID()) { - + : INHERITED(ClassID()) + , fViewMatrix(viewMatrix) + { RegionInfo& info = fRegions.push_back(); info.fColor = color; - info.fViewMatrix = viewMatrix; info.fRegion = region; SkRect bounds = SkRect::Make(region.getBounds()); @@ -108,13 +96,12 @@ public: private: void onPrepareDraws(Target* target) const override { - sk_sp gp = make_gp(fOverrides.readsCoverage()); + sk_sp gp = make_gp(fOverrides.readsCoverage(), fViewMatrix); if (!gp) { SkDebugf("Couldn't create GrGeometryProcessor\n"); return; } - SkASSERT(gp->getVertexStride() == - sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)); + SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorAttr)); int numRegions = fRegions.count(); int numRects = 0; @@ -134,8 +121,8 @@ private: intptr_t verts = reinterpret_cast(vertices); for (int i = 0; i < numRegions; i++) { - int numRectsInRegion = tesselate_region(verts, vertexStride, fRegions[i].fColor, - fRegions[i].fViewMatrix, fRegions[i].fRegion); + tesselate_region(verts, vertexStride, fRegions[i].fColor, fRegions[i].fRegion); + int numRectsInRegion = fRegions[i].fRegion.computeRegionComplexity(); verts += numRectsInRegion * kVertsPerInstance * vertexStride; } helper.recordDraw(target, gp.get()); @@ -148,6 +135,10 @@ private: return false; } + if (fViewMatrix != that->fViewMatrix) { + return false; + } + fRegions.push_back_n(that->fRegions.count(), that->fRegions.begin()); this->joinBounds(*that); return true; @@ -155,10 +146,10 @@ private: struct RegionInfo { GrColor fColor; - SkMatrix fViewMatrix; SkRegion fRegion; }; + SkMatrix fViewMatrix; GrXPOverridesForBatch fOverrides; SkSTArray<1, RegionInfo, true> fRegions; -- 2.34.1