aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar stephana <stephana@google.com>2016-04-25 07:01:22 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-04-25 07:01:23 -0700
commit1dc172165b8186950fda4a269bd1b12c11947b14 (patch)
treef1482ee0e2d88d139c990b212d479885df5d7c8a /src/gpu
parentedf7fcd8b9e339800edb61ae422f8b6c1b77c3e8 (diff)
Revert of Batch multiple single NVPR draw paths to instanced draws (patchset #5 id:80001 of https://codereview.chromium.org/1908433002/ )
Reason for revert: This causes what looks like significantly wrong results. Here is an example: https://gold.skia.org/diff?test=stroke-fill&left=cb47dc2cabbad7d146aedaac199ebace&top=2c6e65d597c574e3bb170a19ca9634c6 Original issue's description: > Batch multiple single NVPR draw paths to instanced draws > > Batch multiple single NVPR draw paths to instanced draws. > A draw path batch can be combined to other batch if the > batches do not overlap and have same draw characteristics. > > Join the batches in linked list and flatten the list to a > path list during draw time. > > Replace GrPathRendering::drawPath with GrPathRendering::drawPaths. > > Perf changes ARM, Shield TV device, Tegra X1 GPU: > desk_chalkboard.skp_1 21.5ms -> 17.8ms 0.83x > desk_mapsvg.skp_1 7.49ms -> 6.18ms 0.82x > Others results are more volatile. > GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1908433002 > > Committed: https://skia.googlesource.com/skia/+/3c33c389e9f8d14d86756ea1ddeba2097f31ad22 TBR=joshualitt@chromium.org,bsalomon@google.com,kkinnunen@nvidia.com # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true Review URL: https://codereview.chromium.org/1919843002
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrPath.h12
-rw-r--r--src/gpu/GrPathRendering.h32
-rw-r--r--src/gpu/batches/GrBatch.h3
-rw-r--r--src/gpu/batches/GrDrawPathBatch.cpp76
-rw-r--r--src/gpu/batches/GrDrawPathBatch.h15
-rw-r--r--src/gpu/gl/GrGLPath.cpp6
-rw-r--r--src/gpu/gl/GrGLPath.h1
-rw-r--r--src/gpu/gl/GrGLPathRendering.cpp85
-rw-r--r--src/gpu/gl/GrGLPathRendering.h9
9 files changed, 58 insertions, 181 deletions
diff --git a/src/gpu/GrPath.h b/src/gpu/GrPath.h
index 975dad0afd..4cb12f4325 100644
--- a/src/gpu/GrPath.h
+++ b/src/gpu/GrPath.h
@@ -36,18 +36,6 @@ public:
const SkRect& getBounds() const { return fBounds; }
GrPathRendering::FillType getFillType() const { return fFillType; }
-
- /**
- * Returns true if a path can be drawn in the same draw paths operation as the other
- * path. Should return true only when the condition holds transitively with all other paths in
- * the same group.
- * E.g.
- * canCombineDrawPathBatchWith(a) AND canCombineDrawPathBatchWith(b)
- * canCombineDrawPathBatchWith(a) AND canCombineDrawPathBatchWith(c)
- * implies
- * canCombineDrawPathBatchWith(b) AND canCombineDrawPathBatchWith(c)
- */
- virtual bool canCombineDrawPathBatchWith(const GrPath& other) const = 0;
#ifdef SK_DEBUG
bool isEqualTo(const SkPath& path, const GrStrokeInfo& stroke) const;
#endif
diff --git a/src/gpu/GrPathRendering.h b/src/gpu/GrPathRendering.h
index ca81b8f08f..8ee3d7b3e2 100644
--- a/src/gpu/GrPathRendering.h
+++ b/src/gpu/GrPathRendering.h
@@ -153,6 +153,17 @@ public:
this->onStencilPath(args, path);
}
+ void drawPath(const GrPipeline& pipeline,
+ const GrPrimitiveProcessor& primProc,
+ const GrStencilSettings& stencil,
+ const GrPath* path) {
+ fGpu->handleDirtyContext();
+ if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
+ fGpu->xferBarrier(pipeline.getRenderTarget(), barrierType);
+ }
+ this->onDrawPath(pipeline, primProc, stencil, path);
+ }
+
void drawPaths(const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
const GrStencilSettings& stencil,
@@ -173,23 +184,15 @@ public:
transformValues, transformType, count);
}
- void drawPaths(const GrPipeline& pipeline,
- const GrPrimitiveProcessor& primProc,
- const GrStencilSettings& stencil,
- const GrPath* const* paths,
- int count) {
- fGpu->handleDirtyContext();
- if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
- fGpu->xferBarrier(pipeline.getRenderTarget(), barrierType);
- }
- this->onDrawPaths(pipeline, primProc, stencil, paths, count);
- }
-
protected:
GrPathRendering(GrGpu* gpu)
: fGpu(gpu) {
}
virtual void onStencilPath(const StencilPathArgs&, const GrPath*) = 0;
+ virtual void onDrawPath(const GrPipeline&,
+ const GrPrimitiveProcessor&,
+ const GrStencilSettings&,
+ const GrPath*) = 0;
virtual void onDrawPaths(const GrPipeline&,
const GrPrimitiveProcessor&,
const GrStencilSettings&,
@@ -199,11 +202,6 @@ protected:
const float transformValues[],
PathTransformType,
int count) = 0;
- virtual void onDrawPaths(const GrPipeline&,
- const GrPrimitiveProcessor&,
- const GrStencilSettings&,
- const GrPath* const*,
- int count) = 0;
GrGpu* fGpu;
private:
diff --git a/src/gpu/batches/GrBatch.h b/src/gpu/batches/GrBatch.h
index 23be88d437..f0559330fe 100644
--- a/src/gpu/batches/GrBatch.h
+++ b/src/gpu/batches/GrBatch.h
@@ -28,8 +28,7 @@ class GrRenderTarget;
* Batches are created when GrContext processes a draw call. Batches of the same subclass may be
* merged using combineIfPossible. When two batches merge, one takes on the union of the data
* and the other is left empty. The merged batch becomes responsible for drawing the data from both
- * the original batches. The merged patch may ref the other batch, if this is more efficient than
- * moving the data from the other batch to the merged batch.
+ * the original batches.
*
* If there are any possible optimizations which might require knowing more about the full state of
* the draw, ie whether or not the GrBatch is allowed to tweak alpha for coverage, then this
diff --git a/src/gpu/batches/GrDrawPathBatch.cpp b/src/gpu/batches/GrDrawPathBatch.cpp
index fb9ca943dc..1395d08328 100644
--- a/src/gpu/batches/GrDrawPathBatch.cpp
+++ b/src/gpu/batches/GrDrawPathBatch.cpp
@@ -13,84 +13,18 @@ static void pre_translate_transform_values(const float* xforms,
SkString GrDrawPathBatch::dumpInfo() const {
SkString string;
- string.printf("Color: 0x%08x Fill: %x Path count: %d Paths: ", this->color(), this->fillType(),
- fTotalPathCount);
- const GrDrawPathBatch* batch = this;
- do {
- string.appendf("0x%p", batch->fPath.get());
- batch = batch->fNext.get();
- } while (batch);
- string.append("\n");
+ string.printf("PATH: 0x%p", fPath.get());
return string;
}
-bool GrDrawPathBatch::ListBoundsIntersects(const GrDrawPathBatch* a, const GrDrawPathBatch* b) {
- if (!SkRect::Intersects(a->fBounds, b->fBounds)) {
- return false;
- }
- if (!a->fNext && !b->fNext) {
- return true;
- }
- const GrDrawPathBatch* firstA = a;
- do {
- do {
- if (SkRect::Intersects(a->fPathBounds, b->fPathBounds)) {
- return true;
- }
- a = a->fNext.get();
- } while (a);
- a = firstA;
- b = b->fNext.get();
- } while (b);
- return false;
-}
-
-bool GrDrawPathBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) {
- GrDrawPathBatch* that = t->cast<GrDrawPathBatch>();
- if (this->color() != that->color() ||
- !this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
- return false;
- }
- if (!GrPipeline::AreEqual(*this->pipeline(), *that->pipeline(), false)) {
- return false;
- }
- if (that->fillType() != this->fillType() ||
- this->stencilSettings() != that->stencilSettings()) {
- return false;
- }
- if (ListBoundsIntersects(this, that)) {
- return false;
- }
- if (!fPath.get()->canCombineDrawPathBatchWith(*that->fPath.get())) {
- return false;
- }
- SkASSERT(!*fLastSlot);
- fLastSlot->reset(SkRef(that));
- fLastSlot = that->fLastSlot;
- fTotalPathCount += that->fTotalPathCount;
- this->joinBounds(that->fBounds);
- return true;
-}
-
void GrDrawPathBatch::onDraw(GrBatchFlushState* state) {
+ GrProgramDesc desc;
+
SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(),
this->overrides(),
this->viewMatrix()));
- if (fTotalPathCount > 1) {
- SkAutoSTMalloc<32, const GrPath*> paths(fTotalPathCount);
- GrDrawPathBatch* batch = this;
- int i = 0;
- do {
- paths[i++] = batch->fPath.get();
- batch = batch->fNext.get();
- } while (batch);
- state->gpu()->pathRendering()->drawPaths(*this->pipeline(), *pathProc,
- this->stencilSettings(), paths, fTotalPathCount);
- } else {
- const GrPath* path = fPath.get();
- state->gpu()->pathRendering()->drawPaths(*this->pipeline(), *pathProc,
- this->stencilSettings(), &path, 1);
- }
+ state->gpu()->pathRendering()->drawPath(*this->pipeline(), *pathProc, this->stencilSettings(),
+ fPath.get());
}
SkString GrDrawPathRangeBatch::dumpInfo() const {
diff --git a/src/gpu/batches/GrDrawPathBatch.h b/src/gpu/batches/GrDrawPathBatch.h
index 6d5c69a346..d29d046de3 100644
--- a/src/gpu/batches/GrDrawPathBatch.h
+++ b/src/gpu/batches/GrDrawPathBatch.h
@@ -76,26 +76,19 @@ private:
GrDrawPathBatch(const SkMatrix& viewMatrix, GrColor color, GrPathRendering::FillType fill,
const GrPath* path)
: INHERITED(ClassID(), viewMatrix, color, fill)
- , fPath(path)
- , fNext(nullptr)
- , fLastSlot(&fNext)
- , fTotalPathCount(1) {
+ , fPath(path) {
fBounds = path->getBounds();
viewMatrix.mapRect(&fBounds);
- fPathBounds = fBounds;
}
- static bool ListBoundsIntersects(const GrDrawPathBatch* a, const GrDrawPathBatch* b);
- bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override;
+
+ bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { return false; }
void onPrepare(GrBatchFlushState*) override {}
void onDraw(GrBatchFlushState* state) override;
GrPendingIOResource<const GrPath, kRead_GrIOType> fPath;
- SkRect fPathBounds;
- sk_sp<GrDrawPathBatch> fNext; // Batch union is made with a linked list of batch nodes.
- sk_sp<GrDrawPathBatch>* fLastSlot; // Points to the fNext of the last batch in the batch list.
- int fTotalPathCount;
+
typedef GrDrawPathBatchBase INHERITED;
};
diff --git a/src/gpu/gl/GrGLPath.cpp b/src/gpu/gl/GrGLPath.cpp
index e2d4703688..ed5a31d9d2 100644
--- a/src/gpu/gl/GrGLPath.cpp
+++ b/src/gpu/gl/GrGLPath.cpp
@@ -333,12 +333,6 @@ GrGLPath::GrGLPath(GrGLGpu* gpu, const SkPath& origSkPath, const GrStrokeInfo& o
this->registerWithCache(SkBudgeted::kYes);
}
-bool GrGLPath::canCombineDrawPathBatchWith(const GrPath& o) const {
- const GrGLPath* other = static_cast<const GrGLPath*>(&o);
- return fShouldStroke == other->fShouldStroke &&
- fShouldFill == other->fShouldFill;
-}
-
void GrGLPath::onRelease() {
if (0 != fPathID) {
static_cast<GrGLGpu*>(this->getGpu())->glPathRendering()->deletePaths(fPathID, 1);
diff --git a/src/gpu/gl/GrGLPath.h b/src/gpu/gl/GrGLPath.h
index 74d2f56bae..1ef1346133 100644
--- a/src/gpu/gl/GrGLPath.h
+++ b/src/gpu/gl/GrGLPath.h
@@ -37,7 +37,6 @@ public:
bool shouldStroke() const { return fShouldStroke; }
bool shouldFill() const { return fShouldFill; }
- bool canCombineDrawPathBatchWith(const GrPath& other) const override;
protected:
void onRelease() override;
void onAbandon() override;
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index 1c6d9b7ab7..0ecf58a8e1 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -145,10 +145,37 @@ void GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath*
}
}
+void GrGLPathRendering::onDrawPath(const GrPipeline& pipeline,
+ const GrPrimitiveProcessor& primProc,
+ const GrStencilSettings& stencil,
+ const GrPath* path) {
+ if (!this->gpu()->flushGLState(pipeline, primProc)) {
+ return;
+ }
+ const GrGLPath* glPath = static_cast<const GrGLPath*>(path);
+
+ this->flushPathStencilSettings(stencil);
+ SkASSERT(!fHWPathStencilSettings.isTwoSided());
+
+ GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode(
+ fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
+ GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
+
+ if (glPath->shouldStroke()) {
+ if (glPath->shouldFill()) {
+ GL_CALL(StencilFillPath(glPath->pathID(), fillMode, writeMask));
+ }
+ GL_CALL(StencilThenCoverStrokePath(glPath->pathID(), 0xffff, writeMask,
+ GR_GL_BOUNDING_BOX));
+ } else {
+ GL_CALL(StencilThenCoverFillPath(glPath->pathID(), fillMode, writeMask,
+ GR_GL_BOUNDING_BOX));
+ }
+}
+
void GrGLPathRendering::onDrawPaths(const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
- const GrStencilSettings& stencil,
- const GrPathRange* pathRange,
+ const GrStencilSettings& stencil, const GrPathRange* pathRange,
const void* indices, PathIndexType indexType,
const float transformValues[], PathTransformType transformType,
int count) {
@@ -188,60 +215,6 @@ void GrGLPathRendering::onDrawPaths(const GrPipeline& pipeline,
}
}
-void GrGLPathRendering::onDrawPaths(const GrPipeline& pipeline,
- const GrPrimitiveProcessor& primProc,
- const GrStencilSettings& stencil,
- const GrPath* const* paths,
- int count) {
- if (!count) {
- return;
- }
- if (!this->gpu()->flushGLState(pipeline, primProc)) {
- return;
- }
- this->flushPathStencilSettings(stencil);
- SkASSERT(!fHWPathStencilSettings.isTwoSided());
-
- GrGLenum fillMode =
- gr_stencil_op_to_gl_path_rendering_fill_mode(
- fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
- GrGLint writeMask =
- fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
- const GrGLPath* path = static_cast<const GrGLPath*>(paths[0]);
- if (count > 1) {
- SkAutoSTMalloc<32, GrGLuint> indexStorage(count);
- for (int i = 0; i < count; ++i) {
- indexStorage[i] = static_cast<const GrGLPath*>(paths[i])->pathID();
- }
- if (path->shouldStroke()) {
- if (path->shouldFill()) {
- GL_CALL(StencilFillPathInstanced(
- count, GR_GL_UNSIGNED_INT, indexStorage, 0,
- fillMode, writeMask, GR_GL_NONE, nullptr));
- }
- GL_CALL(StencilThenCoverStrokePathInstanced(
- count, GR_GL_UNSIGNED_INT, indexStorage, 0, 0xffff, writeMask,
- GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, GR_GL_NONE, nullptr));
- } else {
- GL_CALL(StencilThenCoverFillPathInstanced(
- count, GR_GL_UNSIGNED_INT, indexStorage, 0,
- fillMode, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
- GR_GL_NONE, nullptr));
- }
- } else {
- if (path->shouldStroke()) {
- if (path->shouldFill()) {
- GL_CALL(StencilFillPath(path->pathID(), fillMode, writeMask));
- }
- GL_CALL(StencilThenCoverStrokePath(path->pathID(), 0xffff, writeMask,
- GR_GL_BOUNDING_BOX));
- } else {
- GL_CALL(StencilThenCoverFillPath(path->pathID(), fillMode, writeMask,
- GR_GL_BOUNDING_BOX));
- }
- }
-}
-
void GrGLPathRendering::setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location,
GrGLenum genMode, GrGLint components,
const SkMatrix& matrix) {
diff --git a/src/gpu/gl/GrGLPathRendering.h b/src/gpu/gl/GrGLPathRendering.h
index 1299979e66..b39c866c6f 100644
--- a/src/gpu/gl/GrGLPathRendering.h
+++ b/src/gpu/gl/GrGLPathRendering.h
@@ -65,6 +65,10 @@ public:
protected:
void onStencilPath(const StencilPathArgs&, const GrPath*) override;
+ void onDrawPath(const GrPipeline&,
+ const GrPrimitiveProcessor&,
+ const GrStencilSettings&,
+ const GrPath*) override;
void onDrawPaths(const GrPipeline&,
const GrPrimitiveProcessor&,
const GrStencilSettings&,
@@ -74,11 +78,6 @@ protected:
const float transformValues[],
PathTransformType,
int count) override;
- void onDrawPaths(const GrPipeline&,
- const GrPrimitiveProcessor&,
- const GrStencilSettings&,
- const GrPath* const*,
- int count) override;
private:
/**
* Mark certain functionality as not supported.