Index: src/gpu/GrAARectRenderer.cpp |
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp |
index 5050f3da5966545122380558f682f02ea3f0fef0..440e703ee880941b624949c5469c310a583c1690 100644 |
--- a/src/gpu/GrAARectRenderer.cpp |
+++ b/src/gpu/GrAARectRenderer.cpp |
@@ -32,9 +32,10 @@ static void set_inset_fan(SkPoint* pts, size_t stride, |
} |
static const GrGeometryProcessor* create_fill_rect_gp(bool tweakAlphaForCoverage, |
- const SkMatrix& viewMatrix, |
+ const SkMatrix& localMatrix, |
bool usesLocalCoords, |
- bool coverageIgnored) { |
+ bool coverageIgnored, |
+ bool transformCoords) { |
using namespace GrDefaultGeoProcFactory; |
Color color(Color::kAttribute_Type); |
@@ -48,9 +49,18 @@ static const GrGeometryProcessor* create_fill_rect_gp(bool tweakAlphaForCoverage |
coverageType = Coverage::kAttribute_Type; |
} |
Coverage coverage(coverageType); |
- LocalCoords localCoords(usesLocalCoords ? LocalCoords::kUsePosition_Type : |
- LocalCoords::kUnused_Type); |
- return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix); |
+ LocalCoords::Type localCoordsType; |
+ if (usesLocalCoords) { |
+ localCoordsType = transformCoords ? LocalCoords::kHasTransformed_Type : |
+ LocalCoords::kUsePosition_Type; |
+ } else { |
+ localCoordsType = LocalCoords::kUnused_Type; |
+ } |
+ LocalCoords localCoords(localCoordsType); |
+ if (usesLocalCoords && !transformCoords) { |
+ localCoords.fMatrix = &localMatrix; |
+ } |
+ return Create(color, coverage, localCoords, SkMatrix::I()); |
} |
GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); |
@@ -62,6 +72,7 @@ public: |
SkMatrix fViewMatrix; |
SkRect fRect; |
SkRect fDevRect; |
+ const SkTArray<const GrCoordTransform*, true>* fCoordTransforms; |
}; |
static GrBatch* Create(const Geometry& geometry) { |
@@ -97,21 +108,27 @@ public: |
void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { |
bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); |
- SkAutoTUnref<const GrGeometryProcessor> gp(create_fill_rect_gp(canTweakAlphaForCoverage, |
- this->viewMatrix(), |
- this->usesLocalCoords(), |
- this->coverageIgnored())); |
- if (!gp) { |
- SkDebugf("Couldn't create GrGeometryProcessor\n"); |
+ SkMatrix localMatrix; |
+ if (this->usesLocalCoords() && !this->viewMatrix().invert(&localMatrix)) { |
+ SkDebugf("could not invert viewmatrix\n"); |
return; |
} |
+ SkAutoTUnref<const GrGeometryProcessor> gp(create_fill_rect_gp(canTweakAlphaForCoverage, |
+ localMatrix, |
+ this->usesLocalCoords(), |
+ this->coverageIgnored(), |
+ fTransformLocalCoords)); |
+ |
batchTarget->initDraw(gp, pipeline); |
size_t vertexStride = gp->getVertexStride(); |
- SkASSERT(canTweakAlphaForCoverage ? |
- vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) : |
- vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); |
+#ifdef SK_DEBUG |
+ size_t testStride = sizeof(SkPoint) + sizeof(GrColor); |
+ testStride += canTweakAlphaForCoverage ? 0 : sizeof(GrColor); |
+ testStride += fTransformLocalCoords ? sizeof(SkPoint) : 0; |
+ SkASSERT(testStride == vertexStride); |
+#endif |
int instanceCount = fGeoData.count(); |
SkAutoTUnref<const GrIndexBuffer> indexBuffer(this->getIndexBuffer( |
@@ -132,8 +149,10 @@ public: |
vertexStride, |
args.fColor, |
args.fViewMatrix, |
+ localMatrix, |
args.fRect, |
args.fDevRect, |
+ *args.fCoordTransforms, |
canTweakAlphaForCoverage); |
} |
@@ -150,6 +169,12 @@ private: |
this->setBounds(geometry.fDevRect); |
} |
+ void onSetPipeline() override { |
+ fTransformLocalCoords = this->pipeline()->coordTransforms().count() == 1 && |
+ this->usesLocalCoords(); |
+ fGeoData[0].fCoordTransforms = &this->pipeline()->coordTransforms(); |
+ } |
+ |
static const int kNumAAFillRectsInIndexBuffer = 256; |
static const int kVertsPerAAFillRect = 8; |
static const int kIndicesPerAAFillRect = 30; |
@@ -178,7 +203,8 @@ private: |
bool coverageIgnored() const { return fBatch.fCoverageIgnored; } |
bool onCombineIfPossible(GrBatch* t) override { |
- if (!this->pipeline()->isEqual(*t->pipeline())) { |
+ // If we have one coord transform then we will transform on the cpu |
+ if (!this->pipeline()->isEqual(*t->pipeline(), fTransformLocalCoords)) { |
return false; |
} |
@@ -212,8 +238,10 @@ private: |
size_t vertexStride, |
GrColor color, |
const SkMatrix& viewMatrix, |
+ const SkMatrix& localMatrix, |
const SkRect& rect, |
const SkRect& devRect, |
+ const SkTArray<const GrCoordTransform*, true>& coordTransforms, |
bool tweakAlphaForCoverage) const { |
intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset; |
@@ -264,6 +292,15 @@ private: |
*((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1]; |
} |
+ if (fTransformLocalCoords) { |
+ SkASSERT(coordTransforms.count() == 1); |
+ SkMatrix localCoordMatrix = |
+ GrGLPrimitiveProcessor::GetTransformMatrix(localMatrix, |
+ *coordTransforms[0]); |
+ SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(verts + vertexStride - sizeof(SkPoint)); |
+ localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8); |
+ } |
+ |
// Make verts point to vertex color and then set all the color and coverage vertex attrs |
// values. |
verts += sizeof(SkPoint); |
@@ -308,6 +345,7 @@ private: |
bool fCanTweakAlphaForCoverage; |
}; |
+ bool fTransformLocalCoords; |
BatchTracker fBatch; |
SkSTArray<1, Geometry, true> fGeoData; |
}; |
@@ -402,6 +440,29 @@ void GrAARectRenderer::StrokeAARect(GrDrawTarget* target, |
GR_DECLARE_STATIC_UNIQUE_KEY(gMiterIndexBufferKey); |
GR_DECLARE_STATIC_UNIQUE_KEY(gBevelIndexBufferKey); |
+static const GrGeometryProcessor* create_stroke_rect_gp(bool tweakAlphaForCoverage, |
+ const SkMatrix& viewMatrix, |
+ bool usesLocalCoords, |
+ bool coverageIgnored) { |
+ using namespace GrDefaultGeoProcFactory; |
+ |
+ Color color(Color::kAttribute_Type); |
+ Coverage::Type coverageType; |
+ // TODO remove coverage if coverage is ignored |
+ /*if (coverageIgnored) { |
+ coverageType = Coverage::kNone_Type; |
+ } else*/ if (tweakAlphaForCoverage) { |
+ coverageType = Coverage::kSolid_Type; |
+ } else { |
+ coverageType = Coverage::kAttribute_Type; |
+ } |
+ Coverage coverage(coverageType); |
+ LocalCoords localCoords(usesLocalCoords ? LocalCoords::kUsePosition_Type : |
+ LocalCoords::kUnused_Type); |
+ return CreateForDeviceSpace(color, coverage, localCoords, viewMatrix); |
+} |
+ |
+ |
class AAStrokeRectBatch : public GrBatch { |
public: |
// TODO support AA rotated stroke rects by copying around view matrices |
@@ -447,10 +508,10 @@ public: |
void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { |
bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); |
- SkAutoTUnref<const GrGeometryProcessor> gp(create_fill_rect_gp(canTweakAlphaForCoverage, |
- this->viewMatrix(), |
- this->usesLocalCoords(), |
- this->coverageIgnored())); |
+ SkAutoTUnref<const GrGeometryProcessor> gp(create_stroke_rect_gp(canTweakAlphaForCoverage, |
+ this->viewMatrix(), |
+ this->usesLocalCoords(), |
+ this->coverageIgnored())); |
if (!gp) { |
SkDebugf("Couldn't create GrGeometryProcessor\n"); |
return; |