aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/instanced/InstancedRendering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/instanced/InstancedRendering.cpp')
-rw-r--r--src/gpu/instanced/InstancedRendering.cpp158
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() {