diff options
Diffstat (limited to 'src/gpu/instanced/InstancedRendering.cpp')
-rw-r--r-- | src/gpu/instanced/InstancedRendering.cpp | 158 |
1 files changed, 96 insertions, 62 deletions
diff --git a/src/gpu/instanced/InstancedRendering.cpp b/src/gpu/instanced/InstancedRendering.cpp index ef2264b0ef..179552c852 100644 --- a/src/gpu/instanced/InstancedRendering.cpp +++ b/src/gpu/instanced/InstancedRendering.cpp @@ -22,32 +22,31 @@ InstancedRendering::InstancedRendering(GrGpu* gpu) } std::unique_ptr<GrDrawOp> InstancedRendering::recordRect(const SkRect& rect, - const SkMatrix& viewMatrix, GrColor color, - GrAA aa, - const GrInstancedPipelineInfo& info, - GrAAType* aaType) { - return this->recordShape(ShapeType::kRect, rect, viewMatrix, color, rect, aa, info, aaType); + const SkMatrix& viewMatrix, + GrPaint&& paint, GrAA aa, + const GrInstancedPipelineInfo& info) { + return this->recordShape(ShapeType::kRect, rect, viewMatrix, std::move(paint), rect, aa, info); } std::unique_ptr<GrDrawOp> InstancedRendering::recordRect(const SkRect& rect, - const SkMatrix& viewMatrix, GrColor color, - const SkRect& localRect, GrAA aa, - const GrInstancedPipelineInfo& info, - GrAAType* aaType) { - return this->recordShape(ShapeType::kRect, rect, viewMatrix, color, localRect, aa, info, - aaType); + const SkMatrix& viewMatrix, + GrPaint&& paint, const SkRect& localRect, + GrAA aa, + const GrInstancedPipelineInfo& info) { + return this->recordShape(ShapeType::kRect, rect, viewMatrix, std::move(paint), localRect, aa, + info); } std::unique_ptr<GrDrawOp> InstancedRendering::recordRect(const SkRect& rect, - const SkMatrix& viewMatrix, GrColor color, + const SkMatrix& viewMatrix, + GrPaint&& paint, const SkMatrix& localMatrix, GrAA aa, - const GrInstancedPipelineInfo& info, - GrAAType* aaType) { + const GrInstancedPipelineInfo& info) { if (localMatrix.hasPerspective()) { return nullptr; // Perspective is not yet supported in the local matrix. } - if (std::unique_ptr<Op> op = this->recordShape(ShapeType::kRect, rect, viewMatrix, color, rect, - aa, info, aaType)) { + if (std::unique_ptr<Op> op = this->recordShape(ShapeType::kRect, rect, viewMatrix, + std::move(paint), rect, aa, info)) { op->getSingleInstance().fInfo |= kLocalMatrix_InfoFlag; op->appendParamsTexel(localMatrix.getScaleX(), localMatrix.getSkewX(), localMatrix.getTranslateX()); @@ -60,39 +59,39 @@ std::unique_ptr<GrDrawOp> InstancedRendering::recordRect(const SkRect& rect, } std::unique_ptr<GrDrawOp> InstancedRendering::recordOval(const SkRect& oval, - const SkMatrix& viewMatrix, GrColor color, - GrAA aa, - const GrInstancedPipelineInfo& info, - GrAAType* aaType) { - return this->recordShape(ShapeType::kOval, oval, viewMatrix, color, oval, aa, info, aaType); + const SkMatrix& viewMatrix, + GrPaint&& paint, GrAA aa, + const GrInstancedPipelineInfo& info) { + return this->recordShape(ShapeType::kOval, oval, viewMatrix, std::move(paint), oval, aa, info); } std::unique_ptr<GrDrawOp> InstancedRendering::recordRRect(const SkRRect& rrect, - const SkMatrix& viewMatrix, GrColor color, - GrAA aa, - const GrInstancedPipelineInfo& info, - GrAAType* aaType) { + const SkMatrix& viewMatrix, + GrPaint&& paint, GrAA aa, + const GrInstancedPipelineInfo& info) { if (std::unique_ptr<Op> op = - this->recordShape(GetRRectShapeType(rrect), rrect.rect(), viewMatrix, color, - rrect.rect(), aa, info, aaType)) { + this->recordShape(GetRRectShapeType(rrect), rrect.rect(), viewMatrix, + std::move(paint), rrect.rect(), aa, info)) { op->appendRRectParams(rrect); return std::move(op); } return nullptr; } -std::unique_ptr<GrDrawOp> InstancedRendering::recordDRRect( - const SkRRect& outer, const SkRRect& inner, const SkMatrix& viewMatrix, GrColor color, - GrAA aa, const GrInstancedPipelineInfo& info, GrAAType* aaType) { +std::unique_ptr<GrDrawOp> InstancedRendering::recordDRRect(const SkRRect& outer, + const SkRRect& inner, + const SkMatrix& viewMatrix, + GrPaint&& paint, GrAA aa, + const GrInstancedPipelineInfo& info) { if (inner.getType() > SkRRect::kSimple_Type) { return nullptr; // Complex inner round rects are not yet supported. } if (SkRRect::kEmpty_Type == inner.getType()) { - return this->recordRRect(outer, viewMatrix, color, aa, info, aaType); + return this->recordRRect(outer, viewMatrix, std::move(paint), aa, info); } if (std::unique_ptr<Op> op = - this->recordShape(GetRRectShapeType(outer), outer.rect(), viewMatrix, color, - outer.rect(), aa, info, aaType)) { + this->recordShape(GetRRectShapeType(outer), outer.rect(), viewMatrix, + std::move(paint), outer.rect(), aa, info)) { op->appendRRectParams(outer); ShapeType innerShapeType = GetRRectShapeType(inner); op->fInfo.fInnerShapeTypes |= GetShapeFlag(innerShapeType); @@ -105,28 +104,31 @@ std::unique_ptr<GrDrawOp> InstancedRendering::recordDRRect( } std::unique_ptr<InstancedRendering::Op> InstancedRendering::recordShape( - ShapeType type, const SkRect& bounds, const SkMatrix& viewMatrix, GrColor color, - const SkRect& localRect, GrAA aa, const GrInstancedPipelineInfo& info, GrAAType* aaType) { + ShapeType type, const SkRect& bounds, const SkMatrix& viewMatrix, GrPaint&& paint, + const SkRect& localRect, GrAA aa, const GrInstancedPipelineInfo& info) { SkASSERT(State::kRecordingDraws == fState); if (info.fIsRenderingToFloat && fGpu->caps()->avoidInstancedDrawsToFPTargets()) { return nullptr; } - if (!this->selectAntialiasMode(viewMatrix, aa, info, aaType)) { + GrAAType aaType; + if (!this->selectAntialiasMode(viewMatrix, aa, info, &aaType)) { return nullptr; } - std::unique_ptr<Op> op = this->makeOp(); - op->fInfo.setAAType(*aaType); + GrColor color = paint.getColor(); + std::unique_ptr<Op> op = this->makeOp(std::move(paint)); + op->fInfo.setAAType(aaType); op->fInfo.fShapeTypes = GetShapeFlag(type); op->fInfo.fCannotDiscard = true; - + op->fDrawColorsAreOpaque = GrColorIsOpaque(color); + op->fDrawColorsAreSame = true; Instance& instance = op->getSingleInstance(); instance.fInfo = (int)type << kShapeType_InfoBit; Op::HasAABloat aaBloat = - (*aaType == GrAAType::kCoverage) ? Op::HasAABloat::kYes : Op::HasAABloat::kNo; + (aaType == GrAAType::kCoverage) ? Op::HasAABloat::kYes : Op::HasAABloat::kNo; Op::IsZeroArea zeroArea = (bounds.isEmpty()) ? Op::IsZeroArea::kYes : Op::IsZeroArea::kNo; // The instanced shape renderer draws rectangles of [-1, -1, +1, +1], so we find the matrix that @@ -229,9 +231,10 @@ inline bool InstancedRendering::selectAntialiasMode(const SkMatrix& viewMatrix, return false; } -InstancedRendering::Op::Op(uint32_t classID, InstancedRendering* ir) +InstancedRendering::Op::Op(uint32_t classID, GrPaint&& paint, InstancedRendering* ir) : INHERITED(classID) , fInstancedRendering(ir) + , fProcessors(std::move(paint)) , fIsTracked(false) , fNumDraws(1) , fNumChangesInGeometry(0) { @@ -329,20 +332,17 @@ void InstancedRendering::Op::appendParamsTexel(SkScalar x, SkScalar y, SkScalar fInfo.fHasParams = true; } -void InstancedRendering::Op::getFragmentProcessorAnalysisInputs( - FragmentProcessorAnalysisInputs* input) const { - input->colorInput()->setToConstant(this->getSingleInstance().fColor); - +bool InstancedRendering::Op::xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) { + GrProcessorSet::FragmentProcessorAnalysis analysis; + GrPipelineInput coverageInput; if (GrAAType::kCoverage == fInfo.aaType() || (GrAAType::kNone == fInfo.aaType() && !fInfo.isSimpleRects() && fInfo.fCannotDiscard)) { - input->coverageInput()->setToUnknown(); + coverageInput = GrPipelineInput(); } else { - input->coverageInput()->setToSolidCoverage(); + coverageInput = GrColor_WHITE; } -} + analysis.init(this->getSingleInstance().fColor, coverageInput, fProcessors, clip, caps); -void InstancedRendering::Op::applyPipelineOptimizations( - const GrPipelineOptimizations& optimizations) { Draw& draw = this->getSingleDraw(); // This will assert if we have > 1 command. SkASSERT(draw.fGeometry.isEmpty()); SkASSERT(SkIsPow2(fInfo.fShapeTypes)); @@ -363,17 +363,23 @@ void InstancedRendering::Op::applyPipelineOptimizations( } GrColor overrideColor; - if (optimizations.getOverrideColorIfSet(&overrideColor)) { + if (analysis.initialColorProcessorsToEliminate(&overrideColor)) { SkASSERT(State::kRecordingDraws == fInstancedRendering->fState); - this->getSingleInstance().fColor = overrideColor; + this->getSingleDraw().fInstance.fColor = overrideColor; } - fInfo.fUsesLocalCoords = optimizations.readsLocalCoords(); - fInfo.fCannotTweakAlphaForCoverage = !optimizations.canTweakAlphaForCoverage(); + fInfo.fCannotTweakAlphaForCoverage = + !analysis.isCompatibleWithCoverageAsAlpha() || + !GrXPFactory::CompatibleWithCoverageAsAlpha(fProcessors.xpFactory(), + analysis.isOutputColorOpaque()); + + fInfo.fUsesLocalCoords = analysis.usesLocalCoords(); + return GrXPFactory::WillNeedDstTexture(fProcessors.xpFactory(), caps, analysis); } void InstancedRendering::Op::wasRecorded() { SkASSERT(!fIsTracked); fInstancedRendering->fTrackedOps.addToTail(this); + fProcessors.makePendingExecution(); fIsTracked = true; } @@ -383,9 +389,7 @@ bool InstancedRendering::Op::onCombineIfPossible(GrOp* other, const GrCaps& caps SkASSERT(fTailDraw); SkASSERT(that->fTailDraw); - if (!OpInfo::CanCombine(fInfo, that->fInfo) || - !GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), - that->bounds(), caps)) { + if (!OpInfo::CanCombine(fInfo, that->fInfo) || fProcessors != that->fProcessors) { return false; } @@ -406,7 +410,9 @@ bool InstancedRendering::Op::onCombineIfPossible(GrOp* other, const GrCaps& caps this->joinBounds(*that); fInfo = combinedInfo; fPixelLoad += that->fPixelLoad; - + fDrawColorsAreOpaque = fDrawColorsAreOpaque && that->fDrawColorsAreOpaque; + fDrawColorsAreSame = fDrawColorsAreSame && that->fDrawColorsAreSame && + fHeadDraw->fInstance.fColor == that->fHeadDraw->fInstance.fColor; // Adopt the other op's draws. fNumDraws += that->fNumDraws; fNumChangesInGeometry += that->fNumChangesInGeometry; @@ -462,12 +468,40 @@ void InstancedRendering::Op::onExecute(GrOpFlushState* state) { SkASSERT(state->gpu() == fInstancedRendering->gpu()); state->gpu()->handleDirtyContext(); - if (GrXferBarrierType barrierType = this->pipeline()->xferBarrierType(*state->gpu()->caps())) { - state->gpu()->xferBarrier(this->pipeline()->getRenderTarget(), barrierType); - } + GrProcessorSet::FragmentProcessorAnalysis analysis; + GrPipelineInput coverageInput; + if (GrAAType::kCoverage == fInfo.aaType() || + (GrAAType::kNone == fInfo.aaType() && !fInfo.isSimpleRects() && fInfo.fCannotDiscard)) { + coverageInput = GrPipelineInput(); + } else { + coverageInput = GrColor_WHITE; + } + GrPipelineInput colorInput; + if (fDrawColorsAreSame) { + colorInput = fHeadDraw->fInstance.fColor; + } else if (fDrawColorsAreOpaque) { + colorInput = GrPipelineInput::Opaque::kYes; + } + const GrAppliedClip* clip = state->drawOpArgs().fAppliedClip; + analysis.init(colorInput, coverageInput, fProcessors, clip, state->caps()); + + GrPipeline pipeline; + GrPipeline::InitArgs args; + args.fAnalysis = &analysis; + args.fAppliedClip = clip; + args.fCaps = &state->caps(); + args.fProcessors = &fProcessors; + args.fFlags = GrAATypeIsHW(fInfo.aaType()) ? GrPipeline::kHWAntialias_Flag : 0; + args.fRenderTarget = state->drawOpArgs().fRenderTarget; + args.fDstTexture = state->drawOpArgs().fDstTexture; + pipeline.init(args); + + if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*state->gpu()->caps())) { + state->gpu()->xferBarrier(pipeline.getRenderTarget(), barrierType); + } InstanceProcessor instProc(fInfo, fInstancedRendering->fParamsBuffer.get()); - fInstancedRendering->onDraw(*this->pipeline(), instProc, this); + fInstancedRendering->onDraw(pipeline, instProc, this); } void InstancedRendering::endFlush() { |