aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2018-05-09 00:40:52 -0600
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-09 15:12:45 +0000
commit3917b1e9bc23b9f2e5b44128f1be9d3a8c9bacff (patch)
treea0a2533a2633b3507503d55fed043569ba62bd32
parente8f9e913b6daca22f0760e979cdd95580d2a836b (diff)
ccpr: Cleanup on-flush path stats
Adds a wrapper struct to limit the number of free variables. Fixes a bug where we preallocated draw instances for clip paths. Counts conic weights and preallocates their buffer as well. Bug: skia: Change-Id: I72779c9017322a0dc64461c8cb927f975406b9af Reviewed-on: https://skia-review.googlesource.com/126844 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Chris Dalton <csmartdalton@google.com>
-rw-r--r--src/gpu/ccpr/GrCCGeometry.h7
-rw-r--r--src/gpu/ccpr/GrCCPathParser.cpp14
-rw-r--r--src/gpu/ccpr/GrCCPathParser.h22
-rw-r--r--src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp62
-rw-r--r--src/gpu/ccpr/GrCoverageCountingPathRenderer.h1
5 files changed, 61 insertions, 45 deletions
diff --git a/src/gpu/ccpr/GrCCGeometry.h b/src/gpu/ccpr/GrCCGeometry.h
index 571b3c0a52..5c5d1d2672 100644
--- a/src/gpu/ccpr/GrCCGeometry.h
+++ b/src/gpu/ccpr/GrCCGeometry.h
@@ -49,9 +49,10 @@ public:
bool operator==(const PrimitiveTallies&);
};
- GrCCGeometry(int numSkPoints = 0, int numSkVerbs = 0)
+ GrCCGeometry(int numSkPoints = 0, int numSkVerbs = 0, int numConicWeights = 0)
: fPoints(numSkPoints * 3) // Reserve for a 3x expansion in points and verbs.
- , fVerbs(numSkVerbs * 3) {}
+ , fVerbs(numSkVerbs * 3)
+ , fConicWeights(numConicWeights * 3/2) {}
const SkTArray<SkPoint, true>& points() const { SkASSERT(!fBuildingContour); return fPoints; }
const SkTArray<Verb, true>& verbs() const { SkASSERT(!fBuildingContour); return fVerbs; }
@@ -124,8 +125,8 @@ private:
SkDEBUGCODE(bool fBuildingContour = false);
SkSTArray<128, SkPoint, true> fPoints;
- SkSTArray<32, float, true> fConicWeights;
SkSTArray<128, Verb, true> fVerbs;
+ SkSTArray<32, float, true> fConicWeights;
};
inline void GrCCGeometry::PrimitiveTallies::operator+=(const PrimitiveTallies& b) {
diff --git a/src/gpu/ccpr/GrCCPathParser.cpp b/src/gpu/ccpr/GrCCPathParser.cpp
index 1629a191a5..b29bec7cb1 100644
--- a/src/gpu/ccpr/GrCCPathParser.cpp
+++ b/src/gpu/ccpr/GrCCPathParser.cpp
@@ -21,13 +21,13 @@
using TriPointInstance = GrCCCoverageProcessor::TriPointInstance;
using QuadPointInstance = GrCCCoverageProcessor::QuadPointInstance;
-GrCCPathParser::GrCCPathParser(int maxTotalPaths, int maxPathPoints, int numSkPoints,
- int numSkVerbs)
- : fLocalDevPtsBuffer(maxPathPoints + 1) // Overallocate by one point to accomodate for
- // overflow with Sk4f. (See parsePath.)
- , fGeometry(numSkPoints, numSkVerbs)
- , fPathsInfo(maxTotalPaths)
- , fScissorSubBatches(maxTotalPaths)
+GrCCPathParser::GrCCPathParser(int numPaths, const PathStats& pathStats)
+ // Overallocate by one point to accomodate for overflow with Sk4f. (See parsePath.)
+ : fLocalDevPtsBuffer(pathStats.fMaxPointsPerPath + 1)
+ , fGeometry(pathStats.fNumTotalSkPoints, pathStats.fNumTotalSkVerbs,
+ pathStats.fNumTotalConicWeights)
+ , fPathsInfo(numPaths)
+ , fScissorSubBatches(numPaths)
, fTotalPrimitiveCounts{PrimitiveTallies(), PrimitiveTallies()} {
// Batches decide what to draw by looking where the previous one ended. Define initial batches
// that "end" at the beginning of the data. These will not be drawn, but will only be be read by
diff --git a/src/gpu/ccpr/GrCCPathParser.h b/src/gpu/ccpr/GrCCPathParser.h
index 973c873f2b..b48a0b8adf 100644
--- a/src/gpu/ccpr/GrCCPathParser.h
+++ b/src/gpu/ccpr/GrCCPathParser.h
@@ -10,9 +10,11 @@
#include "GrMesh.h"
#include "GrNonAtomicRef.h"
-#include "GrTessellator.h"
+#include "SkPath.h"
+#include "SkPathPriv.h"
#include "SkRect.h"
#include "SkRefCnt.h"
+#include "GrTessellator.h"
#include "ccpr/GrCCCoverageProcessor.h"
#include "ccpr/GrCCGeometry.h"
#include "ops/GrDrawOp.h"
@@ -32,7 +34,16 @@ public:
enum class ScissorMode : int { kNonScissored = 0, kScissored = 1 };
static constexpr int kNumScissorModes = 2;
- GrCCPathParser(int maxTotalPaths, int maxPathPoints, int numSkPoints, int numSkVerbs);
+ struct PathStats {
+ int fMaxPointsPerPath = 0;
+ int fNumTotalSkPoints = 0;
+ int fNumTotalSkVerbs = 0;
+ int fNumTotalConicWeights = 0;
+
+ void statPath(const SkPath&);
+ };
+
+ GrCCPathParser(int numPaths, const PathStats&);
~GrCCPathParser() {
// Enforce the contract that the client always calls saveParsedPath or discardParsedPath.
@@ -151,4 +162,11 @@ private:
mutable SkSTArray<32, GrPipeline::DynamicState> fDynamicStatesScratchBuffer;
};
+inline void GrCCPathParser::PathStats::statPath(const SkPath& path) {
+ fMaxPointsPerPath = SkTMax(fMaxPointsPerPath, path.countPoints());
+ fNumTotalSkPoints += path.countPoints();
+ fNumTotalSkVerbs += path.countVerbs();
+ fNumTotalConicWeights += SkPathPriv::ConicWeightCnt(path);
+}
+
#endif
diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
index 26348964ea..6c2c00b91b 100644
--- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
+++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
@@ -254,6 +254,7 @@ void GrCoverageCountingPathRenderer::preFlush(GrOnFlushResourceProvider* onFlush
using PathInstance = GrCCPathProcessor::Instance;
SkASSERT(!fFlushing);
+ SkASSERT(fFlushingRTPathIters.empty());
SkASSERT(!fPerFlushIndexBuffer);
SkASSERT(!fPerFlushVertexBuffer);
SkASSERT(!fPerFlushInstanceBuffer);
@@ -267,40 +268,38 @@ void GrCoverageCountingPathRenderer::preFlush(GrOnFlushResourceProvider* onFlush
fPerFlushResourcesAreValid = false;
- // Count the paths that are being flushed.
- int maxTotalPaths = 0, maxPathPoints = 0, numSkPoints = 0, numSkVerbs = 0;
- SkDEBUGCODE(int numClipPaths = 0);
+ // Count up the paths about to be flushed so we can preallocate buffers.
+ int numPathDraws = 0;
+ int numClipPaths = 0;
+ GrCCPathParser::PathStats flushingPathStats;
+ fFlushingRTPathIters.reserve(numOpListIDs);
for (int i = 0; i < numOpListIDs; ++i) {
- auto it = fRTPendingPathsMap.find(opListIDs[i]);
- if (fRTPendingPathsMap.end() == it) {
+ auto iter = fRTPendingPathsMap.find(opListIDs[i]);
+ if (fRTPendingPathsMap.end() == iter) {
continue;
}
- const RTPendingPaths& rtPendingPaths = it->second;
+ const RTPendingPaths& rtPendingPaths = iter->second;
SkTInternalLList<DrawPathsOp>::Iter drawOpsIter;
drawOpsIter.init(rtPendingPaths.fDrawOps,
SkTInternalLList<DrawPathsOp>::Iter::kHead_IterStart);
while (DrawPathsOp* op = drawOpsIter.get()) {
for (const DrawPathsOp::SingleDraw* draw = op->head(); draw; draw = draw->fNext) {
- ++maxTotalPaths;
- maxPathPoints = SkTMax(draw->fPath.countPoints(), maxPathPoints);
- numSkPoints += draw->fPath.countPoints();
- numSkVerbs += draw->fPath.countVerbs();
+ ++numPathDraws;
+ flushingPathStats.statPath(draw->fPath);
}
drawOpsIter.next();
}
- maxTotalPaths += rtPendingPaths.fClipPaths.size();
- SkDEBUGCODE(numClipPaths += rtPendingPaths.fClipPaths.size());
+ numClipPaths += rtPendingPaths.fClipPaths.size();
for (const auto& clipsIter : rtPendingPaths.fClipPaths) {
- const SkPath& path = clipsIter.second.deviceSpacePath();
- maxPathPoints = SkTMax(path.countPoints(), maxPathPoints);
- numSkPoints += path.countPoints();
- numSkVerbs += path.countVerbs();
+ flushingPathStats.statPath(clipsIter.second.deviceSpacePath());
}
+
+ fFlushingRTPathIters.push_back(std::move(iter));
}
- if (!maxTotalPaths) {
+ if (0 == numPathDraws + numClipPaths) {
return; // Nothing to draw.
}
@@ -318,7 +317,7 @@ void GrCoverageCountingPathRenderer::preFlush(GrOnFlushResourceProvider* onFlush
}
fPerFlushInstanceBuffer =
- onFlushRP->makeBuffer(kVertex_GrBufferType, maxTotalPaths * sizeof(PathInstance));
+ onFlushRP->makeBuffer(kVertex_GrBufferType, numPathDraws * sizeof(PathInstance));
if (!fPerFlushInstanceBuffer) {
SkDebugf("WARNING: failed to allocate path instance buffer. No paths will be drawn.\n");
return;
@@ -328,35 +327,31 @@ void GrCoverageCountingPathRenderer::preFlush(GrOnFlushResourceProvider* onFlush
SkASSERT(pathInstanceData);
int pathInstanceIdx = 0;
- fPerFlushPathParser = sk_make_sp<GrCCPathParser>(maxTotalPaths, maxPathPoints, numSkPoints,
- numSkVerbs);
- SkDEBUGCODE(int skippedTotalPaths = 0);
+ fPerFlushPathParser = sk_make_sp<GrCCPathParser>(numPathDraws + numClipPaths,
+ flushingPathStats);
+ SkDEBUGCODE(int numSkippedPaths = 0);
// Allocate atlas(es) and fill out GPU instance buffers.
- for (int i = 0; i < numOpListIDs; ++i) {
- auto it = fRTPendingPathsMap.find(opListIDs[i]);
- if (fRTPendingPathsMap.end() == it) {
- continue;
- }
- RTPendingPaths& rtPendingPaths = it->second;
+ for (const auto& iter : fFlushingRTPathIters) {
+ RTPendingPaths* rtPendingPaths = &iter->second;
SkTInternalLList<DrawPathsOp>::Iter drawOpsIter;
- drawOpsIter.init(rtPendingPaths.fDrawOps,
+ drawOpsIter.init(rtPendingPaths->fDrawOps,
SkTInternalLList<DrawPathsOp>::Iter::kHead_IterStart);
while (DrawPathsOp* op = drawOpsIter.get()) {
pathInstanceIdx = op->setupResources(onFlushRP, pathInstanceData, pathInstanceIdx);
drawOpsIter.next();
- SkDEBUGCODE(skippedTotalPaths += op->numSkippedInstances_debugOnly());
+ SkDEBUGCODE(numSkippedPaths += op->numSkippedInstances_debugOnly());
}
- for (auto& clipsIter : rtPendingPaths.fClipPaths) {
+ for (auto& clipsIter : rtPendingPaths->fClipPaths) {
clipsIter.second.placePathInAtlas(this, onFlushRP, fPerFlushPathParser.get());
}
}
fPerFlushInstanceBuffer->unmap();
- SkASSERT(pathInstanceIdx == maxTotalPaths - skippedTotalPaths - numClipPaths);
+ SkASSERT(pathInstanceIdx == numPathDraws - numSkippedPaths);
if (!fPerFlushAtlases.empty()) {
auto coverageCountBatchID = fPerFlushPathParser->closeCurrentBatch();
@@ -528,8 +523,9 @@ void GrCoverageCountingPathRenderer::postFlush(GrDeferredUploadToken, const uint
fPerFlushVertexBuffer.reset();
fPerFlushIndexBuffer.reset();
// We wait to erase these until after flush, once Ops and FPs are done accessing their data.
- for (int i = 0; i < numOpListIDs; ++i) {
- fRTPendingPathsMap.erase(opListIDs[i]);
+ for (const auto& iter : fFlushingRTPathIters) {
+ fRTPendingPathsMap.erase(iter);
}
+ fFlushingRTPathIters.reset();
SkDEBUGCODE(fFlushing = false);
}
diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.h b/src/gpu/ccpr/GrCoverageCountingPathRenderer.h
index da3c2e7086..0e9ed7b8b1 100644
--- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.h
+++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.h
@@ -220,6 +220,7 @@ private:
// A map from render target ID to the individual render target's pending paths.
std::map<uint32_t, RTPendingPaths> fRTPendingPathsMap;
+ SkSTArray<4, std::map<uint32_t, RTPendingPaths>::iterator> fFlushingRTPathIters;
SkDEBUGCODE(int fPendingDrawOpsCount = 0);
sk_sp<const GrBuffer> fPerFlushIndexBuffer;