| 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();
|
|
|