Index: src/gpu/GrDrawContext.cpp |
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp |
index 2e4b13f03ee0e87f5f1e75b2d2e8758d96660801..63534867805f427ff168d5a3e1a57578658bd30e 100644 |
--- a/src/gpu/GrDrawContext.cpp |
+++ b/src/gpu/GrDrawContext.cpp |
@@ -15,6 +15,7 @@ |
#include "GrRenderTarget.h" |
#include "GrRenderTargetPriv.h" |
#include "GrResourceProvider.h" |
+#include "GrInstancedRendering.h" |
#include "SkSurfacePriv.h" |
#include "batches/GrBatch.h" |
@@ -71,6 +72,13 @@ GrDrawContext::GrDrawContext(GrContext* context, |
, fSingleOwner(singleOwner) |
#endif |
{ |
+ fInstancedRenderingFlags = GrInstancedRendering::kColorWrite_Flag; |
+ if (fRenderTarget->isStencilBufferMultisampled()) { |
+ fInstancedRenderingFlags |= GrInstancedRendering::kStencilBufferMSAA_Flag; |
+ } |
+ if (fRenderTarget->isUnifiedMultisampled()) { |
+ fInstancedRenderingFlags |= GrInstancedRendering::kColorBufferMSAA_Flag; |
+ } |
SkDEBUGCODE(this->validate();) |
} |
@@ -249,30 +257,44 @@ static bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) { |
return viewMatrix.preservesRightAngles(); |
} |
-static bool should_apply_coverage_aa(const GrPaint& paint, GrRenderTarget* rt) { |
- return paint.isAntiAlias() && !rt->isUnifiedMultisampled(); |
+static bool should_apply_coverage_aa(const GrPaint& paint, GrRenderTarget* rt, bool* useHWAA) { |
+ if (!paint.isAntiAlias()) { |
+ *useHWAA = false; |
+ return false; |
+ } else { |
+ *useHWAA = rt->isUnifiedMultisampled(); |
+ return !rt->isUnifiedMultisampled(); |
+ } |
} |
GrDrawBatch* GrDrawContext::getFillRectBatch(const GrPaint& paint, |
const SkMatrix& viewMatrix, |
- const SkRect& rect) { |
- |
- GrDrawBatch* batch = nullptr; |
- if (should_apply_coverage_aa(paint, fRenderTarget)) { |
+ const SkRect& rect, |
+ uint32_t extraInstRenderFlags, |
+ bool* useHWAA) { |
+ if (GrInstancedRendering* ir = this->getDrawTarget()->instancedRendering()) { |
+ if (GrDrawBatch* batch = ir->recordRect(rect, viewMatrix, paint.getColor(), |
+ paint.isAntiAlias(), |
+ fInstancedRenderingFlags | extraInstRenderFlags, |
+ useHWAA)) { |
+ return batch; |
+ } |
+ } |
+ if (should_apply_coverage_aa(paint, fRenderTarget, useHWAA)) { |
// The fill path can handle rotation but not skew. |
if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
SkRect devBoundRect; |
viewMatrix.mapRect(&devBoundRect, rect); |
- batch = GrRectBatchFactory::CreateAAFill(paint.getColor(), viewMatrix, |
- rect, devBoundRect); |
+ return GrRectBatchFactory::CreateAAFill(paint.getColor(), viewMatrix, rect, |
+ devBoundRect); |
} |
} else { |
// filled BW rect |
- batch = GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rect, |
- nullptr, nullptr); |
+ return GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rect, nullptr, |
+ nullptr); |
} |
- return batch; |
+ return nullptr; |
} |
void GrDrawContext::drawRect(const GrClip& clip, |
@@ -327,13 +349,14 @@ void GrDrawContext::drawRect(const GrClip& clip, |
} |
bool snapToPixelCenters = false; |
+ bool useHWAA; |
SkAutoTUnref<GrDrawBatch> batch; |
if (width < 0) { |
- batch.reset(this->getFillRectBatch(paint, viewMatrix, rect)); |
+ batch.reset(this->getFillRectBatch(paint, viewMatrix, rect, 0, &useHWAA)); |
} else { |
GrColor color = paint.getColor(); |
- if (should_apply_coverage_aa(paint, fRenderTarget)) { |
+ if (should_apply_coverage_aa(paint, fRenderTarget, &useHWAA)) { |
// The stroke path needs the rect to remain axis aligned (no rotation or skew). |
if (viewMatrix.rectStaysRect()) { |
batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect, |
@@ -354,6 +377,7 @@ void GrDrawContext::drawRect(const GrClip& clip, |
if (batch) { |
GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
+ pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, useHWAA); |
if (snapToPixelCenters) { |
pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag, |
@@ -389,9 +413,13 @@ bool GrDrawContextPriv::drawAndStencilRect(const SkIRect* scissorRect, |
paint.setAntiAlias(doAA); |
paint.setCoverageSetOpXPFactory(op, invert); |
- SkAutoTUnref<GrDrawBatch> batch(fDrawContext->getFillRectBatch(paint, viewMatrix, rect)); |
+ bool useHWAA; |
+ SkAutoTUnref<GrDrawBatch> batch( |
+ fDrawContext->getFillRectBatch(paint, viewMatrix, rect, |
+ GrInstancedRendering::kStencilWrite_Flag, &useHWAA)); |
if (batch) { |
GrPipelineBuilder pipelineBuilder(paint, fDrawContext->fRenderTarget, GrClip::WideOpen()); |
+ pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, useHWAA); |
pipelineBuilder.setStencil(ss); |
fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, batch, scissorRect); |
@@ -416,20 +444,26 @@ void GrDrawContext::fillRectToRect(const GrClip& clip, |
AutoCheckFlush acf(fDrawingManager); |
+ bool useHWAA; |
SkAutoTUnref<GrDrawBatch> batch; |
- if (should_apply_coverage_aa(paint, fRenderTarget) && |
- view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
- batch.reset(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(), viewMatrix, rectToDraw, |
- localRect)); |
- } else { |
- batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rectToDraw, |
- &localRect, nullptr)); |
+ if (GrInstancedRendering* ir = this->getDrawTarget()->instancedRendering()) { |
+ batch.reset(ir->recordRect(rectToDraw, viewMatrix, paint.getColor(), localRect, |
+ paint.isAntiAlias(), fInstancedRenderingFlags, &useHWAA)); |
} |
- |
- if (batch) { |
- GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
- this->drawBatch(&pipelineBuilder, batch); |
+ if (!batch) { |
+ if (should_apply_coverage_aa(paint, fRenderTarget, &useHWAA) && |
+ view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
+ batch.reset(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(), viewMatrix, |
+ rectToDraw, localRect)); |
+ } else { |
+ batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, |
+ rectToDraw, &localRect, nullptr)); |
+ } |
} |
+ |
+ GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
+ pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, useHWAA); |
+ this->drawBatch(&pipelineBuilder, batch); |
} |
void GrDrawContext::fillRectWithLocalMatrix(const GrClip& clip, |
@@ -444,17 +478,25 @@ void GrDrawContext::fillRectWithLocalMatrix(const GrClip& clip, |
AutoCheckFlush acf(fDrawingManager); |
+ bool useHWAA; |
SkAutoTUnref<GrDrawBatch> batch; |
- if (should_apply_coverage_aa(paint, fRenderTarget) && |
- view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
- batch.reset(GrAAFillRectBatch::Create(paint.getColor(), viewMatrix, localMatrix, |
- rectToDraw)); |
- } else { |
- batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rectToDraw, |
- nullptr, &localMatrix)); |
+ if (GrInstancedRendering* ir = this->getDrawTarget()->instancedRendering()) { |
+ batch.reset(ir->recordRect(rectToDraw, viewMatrix, paint.getColor(), localMatrix, |
+ paint.isAntiAlias(), fInstancedRenderingFlags, &useHWAA)); |
+ } |
+ if (!batch) { |
+ if (should_apply_coverage_aa(paint, fRenderTarget, &useHWAA) && |
+ view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
+ batch.reset(GrAAFillRectBatch::Create(paint.getColor(), viewMatrix, localMatrix, |
+ rectToDraw)); |
+ } else { |
+ batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, |
+ rectToDraw, nullptr, &localMatrix)); |
+ } |
} |
GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
+ pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, useHWAA); |
this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
} |
@@ -548,25 +590,28 @@ void GrDrawContext::drawRRect(const GrClip& clip, |
AutoCheckFlush acf(fDrawingManager); |
- if (should_apply_coverage_aa(paint, fRenderTarget)) { |
- GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); |
- |
- SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateRRectBatch(paint.getColor(), |
- viewMatrix, |
- rrect, |
- strokeInfo, |
- shaderCaps)); |
- if (batch) { |
- GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
- this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
- return; |
- } |
+ bool useHWAA; |
+ SkAutoTUnref<GrDrawBatch> batch; |
+ if (this->getDrawTarget()->instancedRendering() && strokeInfo.isFillStyle()) { |
+ GrInstancedRendering* ir = this->getDrawTarget()->instancedRendering(); |
+ batch.reset(ir->recordRRect(rrect, viewMatrix, paint.getColor(), paint.isAntiAlias(), |
+ fInstancedRenderingFlags, &useHWAA)); |
+ } |
+ if (!batch && should_apply_coverage_aa(paint, fRenderTarget, &useHWAA)) { |
+ batch.reset(GrOvalRenderer::CreateRRectBatch(paint.getColor(), viewMatrix, rrect, |
+ strokeInfo, fContext->caps()->shaderCaps())); |
} |
- SkPath path; |
- path.setIsVolatile(true); |
- path.addRRect(rrect); |
- this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); |
+ if (batch) { |
+ GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
+ pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, useHWAA); |
+ this->drawBatch(&pipelineBuilder, batch); |
+ } else { |
+ SkPath path; |
+ path.setIsVolatile(true); |
+ path.addRRect(rrect); |
+ this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); |
+ } |
} |
bool GrDrawContext::drawFilledDRRect(const GrClip& clip, |
@@ -577,6 +622,19 @@ bool GrDrawContext::drawFilledDRRect(const GrClip& clip, |
SkASSERT(!origInner.isEmpty()); |
SkASSERT(!origOuter.isEmpty()); |
+ if (GrInstancedRendering* ir = this->getDrawTarget()->instancedRendering()) { |
+ bool useHWAA; |
+ SkAutoTUnref<GrDrawBatch> batch(ir->recordDRRect(origOuter, origInner, viewMatrix, |
+ paintIn.getColor(), paintIn.isAntiAlias(), |
+ fInstancedRenderingFlags, &useHWAA)); |
+ if (batch) { |
+ GrPipelineBuilder pipelineBuilder(paintIn, fRenderTarget, clip); |
+ pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, useHWAA); |
+ this->drawBatch(&pipelineBuilder, batch); |
+ return true; |
+ } |
+ } |
+ |
bool applyAA = paintIn.isAntiAlias() && !fRenderTarget->isUnifiedMultisampled(); |
GrPrimitiveEdgeType innerEdgeType = applyAA ? kInverseFillAA_GrProcessorEdgeType : |
@@ -675,24 +733,28 @@ void GrDrawContext::drawOval(const GrClip& clip, |
AutoCheckFlush acf(fDrawingManager); |
- if (should_apply_coverage_aa(paint, fRenderTarget)) { |
- GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); |
- SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.getColor(), |
- viewMatrix, |
- oval, |
- strokeInfo, |
- shaderCaps)); |
- if (batch) { |
- GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
- this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
- return; |
- } |
+ bool useHWAA; |
+ SkAutoTUnref<GrDrawBatch> batch; |
+ if (this->getDrawTarget()->instancedRendering() && strokeInfo.isFillStyle()) { |
+ GrInstancedRendering* ir = this->getDrawTarget()->instancedRendering(); |
+ batch.reset(ir->recordOval(oval, viewMatrix, paint.getColor(), paint.isAntiAlias(), |
+ fInstancedRenderingFlags, &useHWAA)); |
+ } |
+ if (!batch && should_apply_coverage_aa(paint, fRenderTarget, &useHWAA)) { |
+ batch.reset(GrOvalRenderer::CreateOvalBatch(paint.getColor(), viewMatrix, oval, strokeInfo, |
+ fContext->caps()->shaderCaps())); |
} |
- SkPath path; |
- path.setIsVolatile(true); |
- path.addOval(oval); |
- this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); |
+ if (batch) { |
+ GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
+ pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, useHWAA); |
+ this->drawBatch(&pipelineBuilder, batch); |
+ } else { |
+ SkPath path; |
+ path.setIsVolatile(true); |
+ path.addOval(oval); |
+ this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); |
+ } |
} |
void GrDrawContext::drawImageNine(const GrClip& clip, |
@@ -811,45 +873,52 @@ void GrDrawContext::drawPath(const GrClip& clip, |
} |
AutoCheckFlush acf(fDrawingManager); |
- |
- if (should_apply_coverage_aa(paint, fRenderTarget) && !strokeInfo.isDashed()) { |
- if (strokeInfo.getWidth() < 0 && !path.isConvex()) { |
- // Concave AA paths are expensive - try to avoid them for special cases |
- SkRect rects[2]; |
- |
- if (is_nested_rects(viewMatrix, path, strokeInfo, rects)) { |
- SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFillNestedRects( |
- paint.getColor(), viewMatrix, rects)); |
- |
- GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
- this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
- return; |
- } |
+ SkAutoTUnref<GrDrawBatch> fastBatch; |
+ bool useHWAA; |
+ |
+ // Paths are expensive - try to avoid them for special cases |
+ SkRect nestedRects[2]; |
+ SkRect ovalRect; |
+ if (strokeInfo.isFillStyle() && !path.isConvex() && |
+ is_nested_rects(viewMatrix, path, strokeInfo, nestedRects)) { |
+ if (GrInstancedRendering* ir = this->getDrawTarget()->instancedRendering()) { |
+ SkASSERT(nestedRects[0].contains(nestedRects[1])); |
+ fastBatch.reset(ir->recordDRRect(SkRRect::MakeRect(nestedRects[0]), |
+ SkRRect::MakeRect(nestedRects[1]), viewMatrix, |
+ paint.getColor(), paint.isAntiAlias(), |
+ fInstancedRenderingFlags, &useHWAA)); |
} |
- SkRect ovalRect; |
- bool isOval = path.isOval(&ovalRect); |
- |
- if (isOval && !path.isInverseFillType()) { |
- GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); |
- SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.getColor(), |
- viewMatrix, |
- ovalRect, |
- strokeInfo, |
- shaderCaps)); |
- if (batch) { |
- GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
- this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
- return; |
- } |
+ if (!fastBatch && should_apply_coverage_aa(paint, fRenderTarget, &useHWAA)) { |
+ fastBatch.reset(GrRectBatchFactory::CreateAAFillNestedRects(paint.getColor(), |
+ viewMatrix, nestedRects)); |
+ } |
+ } else if (!path.isInverseFillType() && path.isOval(&ovalRect)) { |
+ if (this->getDrawTarget()->instancedRendering() && strokeInfo.isFillStyle()) { |
+ GrInstancedRendering* ir = this->getDrawTarget()->instancedRendering(); |
+ fastBatch.reset(ir->recordOval(ovalRect, viewMatrix, paint.getColor(), |
+ paint.isAntiAlias(), fInstancedRenderingFlags, |
+ &useHWAA)); |
+ } |
+ if (!fastBatch && !strokeInfo.isDashed() && |
+ should_apply_coverage_aa(paint, fRenderTarget, &useHWAA)) { |
+ fastBatch.reset(GrOvalRenderer::CreateOvalBatch(paint.getColor(), viewMatrix, |
+ ovalRect, strokeInfo, |
+ fContext->caps()->shaderCaps())); |
} |
} |
- // Note that internalDrawPath may sw-rasterize the path into a scratch texture. |
- // Scratch textures can be recycled after they are returned to the texture |
- // cache. This presents a potential hazard for buffered drawing. However, |
- // the writePixels that uploads to the scratch will perform a flush so we're |
- // OK. |
- this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); |
+ if (fastBatch) { |
+ GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
+ pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, useHWAA); |
+ this->drawBatch(&pipelineBuilder, fastBatch); |
+ } else { |
+ // Note that internalDrawPath may sw-rasterize the path into a scratch texture. |
+ // Scratch textures can be recycled after they are returned to the texture |
+ // cache. This presents a potential hazard for buffered drawing. However, |
+ // the writePixels that uploads to the scratch will perform a flush so we're |
+ // OK. |
+ this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); |
+ } |
} |
bool GrDrawContextPriv::drawAndStencilPath(const SkIRect* scissorRect, |
@@ -940,7 +1009,8 @@ void GrDrawContext::internalDrawPath(const GrClip& clip, |
// the src color (either the input alpha or in the frag shader) to implement |
// aa. If we have some future driver-mojo path AA that can do the right |
// thing WRT to the blend then we'll need some query on the PR. |
- bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTarget); |
+ bool useHWAA; |
+ bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTarget, &useHWAA); |
const bool isStencilDisabled = true; |
bool isStencilBufferMSAA = fRenderTarget->isStencilBufferMultisampled(); |
@@ -1016,6 +1086,7 @@ void GrDrawContext::internalDrawPath(const GrClip& clip, |
} |
GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
+ pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, useHWAA); |
GrPathRenderer::DrawPathArgs args; |
args.fTarget = this->getDrawTarget(); |