Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(296)

Unified Diff: src/gpu/batches/GrDrawPathBatch.cpp

Issue 1507203002: Improve nvpr glyph batching (Closed) Base URL: https://skia.googlesource.com/skia.git@upload_drawpathbatch
Patch Set: re-fix issue dependencies Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/batches/GrDrawPathBatch.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/batches/GrDrawPathBatch.cpp
diff --git a/src/gpu/batches/GrDrawPathBatch.cpp b/src/gpu/batches/GrDrawPathBatch.cpp
index c2007ce933b7399cf4e9ab55307d7615e87da0cd..3264c0fbafe49f84a56dfc8d6fdb89082c6d11a6 100644
--- a/src/gpu/batches/GrDrawPathBatch.cpp
+++ b/src/gpu/batches/GrDrawPathBatch.cpp
@@ -7,6 +7,10 @@
#include "GrDrawPathBatch.h"
+static void pre_translate_transform_values(const float* xforms,
+ GrPathRendering::PathTransformType type, int count,
+ SkScalar x, SkScalar y, float* dst);
+
SkString GrDrawPathBatch::dumpInfo() const {
SkString string;
string.printf("PATH: 0x%p", fPath.get());
@@ -25,51 +29,59 @@ void GrDrawPathBatch::onDraw(GrBatchFlushState* state) {
state->gpu()->pathRendering()->drawPath(args, fPath.get());
}
-GrDrawPathRangeBatch::~GrDrawPathRangeBatch() {
- for (DrawList::Iter iter(fDraws); iter.get(); iter.next()) {
- (*iter.get())->unref();
- }
-}
-
SkString GrDrawPathRangeBatch::dumpInfo() const {
SkString string;
- string.printf("RANGE: 0x%p COUNTS: [", *fDraws.head());
+ string.printf("RANGE: 0x%p COUNTS: [", fPathRange.get());
for (DrawList::Iter iter(fDraws); iter.get(); iter.next()) {
- string.appendf("%d ,", (*iter.get())->count());
+ string.appendf("%d, ", iter.get()->fInstanceData->count());
}
string.remove(string.size() - 2, 2);
string.append("]");
return string;
}
-GrDrawPathRangeBatch::GrDrawPathRangeBatch(const SkMatrix& viewMatrix, const SkMatrix& localMatrix,
- GrColor color, GrPathRendering::FillType fill,
- GrPathRange* range, GrPathRangeDraw* draw,
- const SkRect& bounds)
+GrDrawPathRangeBatch::GrDrawPathRangeBatch(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x,
+ SkScalar y, GrColor color,
+ GrPathRendering::FillType fill, GrPathRange* range,
+ const InstanceData* instanceData, const SkRect& bounds)
: INHERITED(ClassID(), viewMatrix, color, fill)
, fPathRange(range)
- , fLocalMatrix(localMatrix) {
- SkDEBUGCODE(draw->fUsedInBatch = true;)
- fDraws.addToHead(SkRef(draw));
- fTotalPathCount = draw->count();
+ , fTotalPathCount(instanceData->count())
+ , fScale(scale) {
+ fDraws.addToHead()->set(instanceData, x, y);
fBounds = bounds;
}
bool GrDrawPathRangeBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) {
GrDrawPathRangeBatch* that = t->cast<GrDrawPathRangeBatch>();
- if (this->fPathRange.get() != that->fPathRange.get()) {
- return false;
- }
- if (!GrPathRangeDraw::CanMerge(**this->fDraws.head(), **that->fDraws.head())) {
+ if (this->fPathRange.get() != that->fPathRange.get() ||
+ this->transformType() != that->transformType() ||
+ this->fScale != that->fScale ||
+ this->color() != that->color() ||
+ !this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
return false;
}
if (!GrPipeline::AreEqual(*this->pipeline(), *that->pipeline(), false)) {
return false;
}
- if (this->color() != that->color() ||
- !this->viewMatrix().cheapEqualTo(that->viewMatrix()) ||
- !fLocalMatrix.cheapEqualTo(that->fLocalMatrix)) {
- return false;
+ switch (fDraws.head()->fInstanceData->transformType()) {
+ case GrPathRendering::kNone_PathTransformType:
+ if (this->fDraws.head()->fX != that->fDraws.head()->fX ||
+ this->fDraws.head()->fY != that->fDraws.head()->fY) {
+ return false;
+ }
+ break;
+ case GrPathRendering::kTranslateX_PathTransformType:
+ if (this->fDraws.head()->fY != that->fDraws.head()->fY) {
+ return false;
+ }
+ break;
+ case GrPathRendering::kTranslateY_PathTransformType:
+ if (this->fDraws.head()->fX != that->fDraws.head()->fX) {
+ return false;
+ }
+ break;
+ default: break;
}
// TODO: Check some other things here. (winding, opaque, pathProc color, vm, ...)
// Try to combine this call with the previous DrawPaths. We do this by stenciling all the
@@ -85,47 +97,117 @@ bool GrDrawPathRangeBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) {
}
SkASSERT(!that->overrides().willColorBlendWithDst());
fTotalPathCount += that->fTotalPathCount;
- while (GrPathRangeDraw** head = that->fDraws.head()) {
- fDraws.addToTail(*head);
- // We're stealing that's refs, so pop without unreffing.
+ while (Draw* head = that->fDraws.head()) {
+ Draw* draw = fDraws.addToTail();
+ draw->fInstanceData.reset(head->fInstanceData.detach());
+ draw->fX = head->fX;
+ draw->fY = head->fY;
that->fDraws.popHead();
}
return true;
}
void GrDrawPathRangeBatch::onDraw(GrBatchFlushState* state) {
- GrProgramDesc desc;
+ const Draw& head = *fDraws.head();
+
+ SkMatrix drawMatrix(this->viewMatrix());
+ drawMatrix.preScale(fScale, fScale);
+ drawMatrix.preTranslate(head.fX, head.fY);
+
+ SkMatrix localMatrix;
+ localMatrix.setScale(fScale, fScale);
+ localMatrix.preTranslate(head.fX, head.fY);
+
SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(),
this->overrides(),
- this->viewMatrix(),
- fLocalMatrix));
+ drawMatrix,
+ localMatrix));
+
+ GrProgramDesc desc;
state->gpu()->buildProgramDesc(&desc, *pathProc, *this->pipeline());
GrPathRendering::DrawPathArgs args(pathProc, this->pipeline(),
- &desc, &this->stencilSettings());
+ &desc, &this->stencilSettings());
+
if (fDraws.count() == 1) {
- const GrPathRangeDraw& draw = **fDraws.head();
- state->gpu()->pathRendering()->drawPaths(args, fPathRange.get(), draw.indices(),
- GrPathRange::kU16_PathIndexType, draw.transforms(), draw.transformType(),
- draw.count());
- return;
+ const InstanceData& instances = *head.fInstanceData;
+ state->gpu()->pathRendering()->drawPaths(args, fPathRange.get(), instances.indices(),
+ GrPathRange::kU16_PathIndexType,
+ instances.transformValues(),
+ instances.transformType(),
+ instances.count());
+ } else {
+ int floatsPerTransform = GrPathRendering::PathTransformSize(this->transformType());
+#if defined(GOOGLE3)
+ //Stack frame size is limited in GOOGLE3.
+ SkAutoSTMalloc<512, float> transformStorage(transformSize * fTotalPathCount);
+ SkAutoSTMalloc<256, uint16_t> indexStorage(fTotalPathCount);
+#else
+ SkAutoSTMalloc<4096, float> transformStorage(floatsPerTransform * fTotalPathCount);
+ SkAutoSTMalloc<2048, uint16_t> indexStorage(fTotalPathCount);
+#endif
+ int idx = 0;
+ for (DrawList::Iter iter(fDraws); iter.get(); iter.next()) {
+ const Draw& draw = *iter.get();
+ const InstanceData& instances = *draw.fInstanceData;
+ memcpy(&indexStorage[idx], instances.indices(), instances.count() * sizeof(uint16_t));
+ pre_translate_transform_values(instances.transformValues(), this->transformType(),
+ instances.count(),
+ draw.fX - head.fX, draw.fY - head.fY,
+ &transformStorage[floatsPerTransform * idx]);
+ idx += instances.count();
+
+ // TODO: Support mismatched transform types if we start using more types other than 2D.
+ SkASSERT(instances.transformType() == this->transformType());
+ }
+ SkASSERT(idx == fTotalPathCount);
+
+ state->gpu()->pathRendering()->drawPaths(args, fPathRange.get(), indexStorage,
+ GrPathRange::kU16_PathIndexType, transformStorage,
+ this->transformType(), fTotalPathCount);
}
+}
- GrPathRendering::PathTransformType transformType = (*fDraws.head())->transformType();
- int floatsPerTransform = GrPathRendering::PathTransformSize(transformType);
- SkAutoSTMalloc<512, float> transformStorage(floatsPerTransform * fTotalPathCount);
- SkAutoSTMalloc<256, uint16_t> indexStorage(fTotalPathCount);
- uint16_t* indices = indexStorage.get();
- float* transforms = transformStorage.get();
- for (DrawList::Iter iter(fDraws); iter.get(); iter.next()) {
- SkASSERT((*iter.get())->transformType() == transformType);
- int cnt = (*iter.get())->count();
- memcpy(indices, (*iter.get())->indices(), cnt * sizeof(uint16_t));
- indices += cnt;
- memcpy(transforms, (*iter.get())->transforms(), cnt * floatsPerTransform * sizeof(float));
- transforms += cnt * floatsPerTransform;
+inline void pre_translate_transform_values(const float* xforms,
+ GrPathRendering::PathTransformType type, int count,
+ SkScalar x, SkScalar y, float* dst) {
+ if (0 == x && 0 == y) {
+ memcpy(dst, xforms, count * GrPathRendering::PathTransformSize(type) * sizeof(float));
+ return;
+ }
+ switch (type) {
+ case GrPathRendering::kNone_PathTransformType:
+ SkFAIL("Cannot pre-translate kNone_PathTransformType.");
+ break;
+ case GrPathRendering::kTranslateX_PathTransformType:
+ SkASSERT(0 == y);
+ for (int i = 0; i < count; i++) {
+ dst[i] = xforms[i] + x;
+ }
+ break;
+ case GrPathRendering::kTranslateY_PathTransformType:
+ SkASSERT(0 == x);
+ for (int i = 0; i < count; i++) {
+ dst[i] = xforms[i] + y;
+ }
+ break;
+ case GrPathRendering::kTranslate_PathTransformType:
+ for (int i = 0; i < 2 * count; i += 2) {
+ dst[i] = xforms[i] + x;
+ dst[i + 1] = xforms[i + 1] + y;
+ }
+ break;
+ case GrPathRendering::kAffine_PathTransformType:
+ for (int i = 0; i < 6 * count; i += 6) {
+ dst[i] = xforms[i];
+ dst[i + 1] = xforms[i + 1];
+ dst[i + 2] = xforms[i] * x + xforms[i + 1] * y + xforms[i + 2];
+ dst[i + 3] = xforms[i + 3];
+ dst[i + 4] = xforms[i + 4];
+ dst[i + 5] = xforms[i + 3] * x + xforms[i + 4] * y + xforms[i + 5];
+ }
+ break;
+ default:
+ SkFAIL("Unknown transform type.");
+ break;
}
- SkASSERT(indices - indexStorage.get() == fTotalPathCount);
- state->gpu()->pathRendering()->drawPaths(args, fPathRange.get(), indexStorage.get(),
- GrPathRange::kU16_PathIndexType, transformStorage.get(), transformType,
- fTotalPathCount);
}
« no previous file with comments | « src/gpu/batches/GrDrawPathBatch.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698