Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(578)

Unified Diff: src/gpu/instanced/InstancedRendering.cpp

Issue 2123693002: Revert of Begin instanced rendering for simple shapes (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/instanced/InstancedRendering.h ('k') | src/gpu/instanced/InstancedRenderingTypes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/instanced/InstancedRendering.cpp
diff --git a/src/gpu/instanced/InstancedRendering.cpp b/src/gpu/instanced/InstancedRendering.cpp
deleted file mode 100644
index 165bff494b3fa0ab1f241c844ec59afb8b582da9..0000000000000000000000000000000000000000
--- a/src/gpu/instanced/InstancedRendering.cpp
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "InstancedRendering.h"
-
-#include "GrBatchFlushState.h"
-#include "GrPipeline.h"
-#include "GrResourceProvider.h"
-#include "instanced/InstanceProcessor.h"
-
-namespace gr_instanced {
-
-InstancedRendering::InstancedRendering(GrGpu* gpu, AntialiasMode lastSupportedAAMode,
- bool canRenderToFloat)
- : fGpu(SkRef(gpu)),
- fLastSupportedAAMode(lastSupportedAAMode),
- fCanRenderToFloat(canRenderToFloat),
- fState(State::kRecordingDraws),
- fDrawPool(1024 * sizeof(Batch::Draw), 1024 * sizeof(Batch::Draw)) {
-}
-
-GrDrawBatch* InstancedRendering::recordRect(const SkRect& rect, const SkMatrix& viewMatrix,
- GrColor color, bool antialias,
- const GrInstancedPipelineInfo& info, bool* useHWAA) {
- return this->recordShape(ShapeType::kRect, rect, viewMatrix, color, rect, antialias, info,
- useHWAA);
-}
-
-GrDrawBatch* InstancedRendering::recordRect(const SkRect& rect, const SkMatrix& viewMatrix,
- GrColor color, const SkRect& localRect, bool antialias,
- const GrInstancedPipelineInfo& info, bool* useHWAA) {
- return this->recordShape(ShapeType::kRect, rect, viewMatrix, color, localRect, antialias, info,
- useHWAA);
-}
-
-GrDrawBatch* InstancedRendering::recordRect(const SkRect& rect, const SkMatrix& viewMatrix,
- GrColor color, const SkMatrix& localMatrix,
- bool antialias, const GrInstancedPipelineInfo& info,
- bool* useHWAA) {
- if (localMatrix.hasPerspective()) {
- return nullptr; // Perspective is not yet supported in the local matrix.
- }
- if (Batch* batch = this->recordShape(ShapeType::kRect, rect, viewMatrix, color, rect, antialias,
- info, useHWAA)) {
- batch->getSingleInstance().fInfo |= kLocalMatrix_InfoFlag;
- batch->appendParamsTexel(localMatrix.getScaleX(), localMatrix.getSkewX(),
- localMatrix.getTranslateX());
- batch->appendParamsTexel(localMatrix.getSkewY(), localMatrix.getScaleY(),
- localMatrix.getTranslateY());
- batch->fInfo.fHasLocalMatrix = true;
- return batch;
- }
- return nullptr;
-}
-
-GrDrawBatch* InstancedRendering::recordOval(const SkRect& oval, const SkMatrix& viewMatrix,
- GrColor color, bool antialias,
- const GrInstancedPipelineInfo& info, bool* useHWAA) {
- return this->recordShape(ShapeType::kOval, oval, viewMatrix, color, oval, antialias, info,
- useHWAA);
-}
-
-GrDrawBatch* InstancedRendering::recordRRect(const SkRRect& rrect, const SkMatrix& viewMatrix,
- GrColor color, bool antialias,
- const GrInstancedPipelineInfo& info, bool* useHWAA) {
- if (Batch* batch = this->recordShape(GetRRectShapeType(rrect), rrect.rect(), viewMatrix, color,
- rrect.rect(), antialias, info, useHWAA)) {
- batch->appendRRectParams(rrect);
- return batch;
- }
- return nullptr;
-}
-
-GrDrawBatch* InstancedRendering::recordDRRect(const SkRRect& outer, const SkRRect& inner,
- const SkMatrix& viewMatrix, GrColor color,
- bool antialias, const GrInstancedPipelineInfo& info,
- bool* useHWAA) {
- 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, antialias, info, useHWAA);
- }
- if (Batch* batch = this->recordShape(GetRRectShapeType(outer), outer.rect(), viewMatrix, color,
- outer.rect(), antialias, info, useHWAA)) {
- batch->appendRRectParams(outer);
- ShapeType innerShapeType = GetRRectShapeType(inner);
- batch->fInfo.fInnerShapeTypes |= GetShapeFlag(innerShapeType);
- batch->getSingleInstance().fInfo |= ((int)innerShapeType << kInnerShapeType_InfoBit);
- batch->appendParamsTexel(inner.rect().asScalars(), 4);
- batch->appendRRectParams(inner);
- return batch;
- }
- return nullptr;
-}
-
-InstancedRendering::Batch* InstancedRendering::recordShape(ShapeType type, const SkRect& bounds,
- const SkMatrix& viewMatrix,
- GrColor color, const SkRect& localRect,
- bool antialias,
- const GrInstancedPipelineInfo& info,
- bool* useHWAA) {
- SkASSERT(State::kRecordingDraws == fState);
-
- if (info.fIsRenderingToFloat && !fCanRenderToFloat) {
- return nullptr;
- }
-
- AntialiasMode antialiasMode;
- if (!this->selectAntialiasMode(viewMatrix, antialias, info, useHWAA, &antialiasMode)) {
- return nullptr;
- }
-
- Batch* batch = this->createBatch();
- batch->fInfo.fAntialiasMode = antialiasMode;
- batch->fInfo.fShapeTypes = GetShapeFlag(type);
- batch->fInfo.fCannotDiscard = !info.fCanDiscard;
-
- Instance& instance = batch->getSingleInstance();
- instance.fInfo = (int)type << kShapeType_InfoBit;
-
- // The instanced shape renderer draws rectangles of [-1, -1, +1, +1], so we find the matrix that
- // will map this rectangle to the same device coordinates as "viewMatrix * bounds".
- float sx = 0.5f * bounds.width();
- float sy = 0.5f * bounds.height();
- float tx = sx + bounds.fLeft;
- float ty = sy + bounds.fTop;
- if (!viewMatrix.hasPerspective()) {
- float* m = instance.fShapeMatrix2x3;
- m[0] = viewMatrix.getScaleX() * sx;
- m[1] = viewMatrix.getSkewX() * sy;
- m[2] = viewMatrix.getTranslateX() +
- viewMatrix.getScaleX() * tx + viewMatrix.getSkewX() * ty;
-
- m[3] = viewMatrix.getSkewY() * sx;
- m[4] = viewMatrix.getScaleY() * sy;
- m[5] = viewMatrix.getTranslateY() +
- viewMatrix.getSkewY() * tx + viewMatrix.getScaleY() * ty;
-
- // Since 'm' is a 2x3 matrix that maps the rect [-1, +1] into the shape's device-space quad,
- // it's quite simple to find the bounding rectangle:
- float devBoundsHalfWidth = fabsf(m[0]) + fabsf(m[1]);
- float devBoundsHalfHeight = fabsf(m[3]) + fabsf(m[4]);
- batch->fBounds.fLeft = m[2] - devBoundsHalfWidth;
- batch->fBounds.fRight = m[2] + devBoundsHalfWidth;
- batch->fBounds.fTop = m[5] - devBoundsHalfHeight;
- batch->fBounds.fBottom = m[5] + devBoundsHalfHeight;
-
- // TODO: Is this worth the CPU overhead?
- batch->fInfo.fNonSquare =
- fabsf(devBoundsHalfHeight - devBoundsHalfWidth) > 0.5f || // Early out.
- fabs(m[0] * m[3] + m[1] * m[4]) > 1e-3f || // Skew?
- fabs(m[0] * m[0] + m[1] * m[1] - m[3] * m[3] - m[4] * m[4]) > 1e-2f; // Diff. lengths?
- } else {
- SkMatrix shapeMatrix(viewMatrix);
- shapeMatrix.preTranslate(tx, ty);
- shapeMatrix.preScale(sx, sy);
- instance.fInfo |= kPerspective_InfoFlag;
-
- float* m = instance.fShapeMatrix2x3;
- m[0] = SkScalarToFloat(shapeMatrix.getScaleX());
- m[1] = SkScalarToFloat(shapeMatrix.getSkewX());
- m[2] = SkScalarToFloat(shapeMatrix.getTranslateX());
- m[3] = SkScalarToFloat(shapeMatrix.getSkewY());
- m[4] = SkScalarToFloat(shapeMatrix.getScaleY());
- m[5] = SkScalarToFloat(shapeMatrix.getTranslateY());
-
- // Send the perspective column as a param.
- batch->appendParamsTexel(shapeMatrix[SkMatrix::kMPersp0], shapeMatrix[SkMatrix::kMPersp1],
- shapeMatrix[SkMatrix::kMPersp2]);
- batch->fInfo.fHasPerspective = true;
-
- viewMatrix.mapRect(&batch->fBounds, bounds);
-
- batch->fInfo.fNonSquare = true;
- }
-
- instance.fColor = color;
-
- const float* rectAsFloats = localRect.asScalars(); // Ensure SkScalar == float.
- memcpy(&instance.fLocalRect, rectAsFloats, 4 * sizeof(float));
-
- return batch;
-}
-
-inline bool InstancedRendering::selectAntialiasMode(const SkMatrix& viewMatrix, bool antialias,
- const GrInstancedPipelineInfo& info,
- bool* useHWAA, AntialiasMode* antialiasMode) {
- SkASSERT(!info.fColorDisabled || info.fDrawingShapeToStencil);
- SkASSERT(!info.fIsMixedSampled || info.fIsMultisampled);
-
- if (!info.fIsMultisampled || fGpu->caps()->multisampleDisableSupport()) {
- SkASSERT(fLastSupportedAAMode >= AntialiasMode::kCoverage);
- if (!antialias) {
- if (info.fDrawingShapeToStencil && !info.fCanDiscard) {
- // We can't draw to the stencil buffer without discard (or sample mask if MSAA).
- return false;
- }
- *antialiasMode = AntialiasMode::kNone;
- *useHWAA = false;
- return true;
- }
-
- if (info.canUseCoverageAA() && viewMatrix.preservesRightAngles()) {
- *antialiasMode = AntialiasMode::kCoverage;
- *useHWAA = false;
- return true;
- }
- }
-
- if (info.fIsMultisampled && fLastSupportedAAMode >= AntialiasMode::kMSAA) {
- if (!info.fIsMixedSampled || info.fColorDisabled) {
- *antialiasMode = AntialiasMode::kMSAA;
- *useHWAA = true;
- return true;
- }
- if (fLastSupportedAAMode >= AntialiasMode::kMixedSamples) {
- *antialiasMode = AntialiasMode::kMixedSamples;
- *useHWAA = true;
- return true;
- }
- }
-
- return false;
-}
-
-InstancedRendering::Batch::Batch(uint32_t classID, InstancedRendering* ir)
- : INHERITED(classID),
- fInstancedRendering(ir),
- fIsTracked(false),
- fNumDraws(1),
- fNumChangesInGeometry(0) {
- fHeadDraw = fTailDraw = (Draw*)fInstancedRendering->fDrawPool.allocate(sizeof(Draw));
-#ifdef SK_DEBUG
- fHeadDraw->fGeometry = {-1, 0};
-#endif
- fHeadDraw->fNext = nullptr;
-}
-
-InstancedRendering::Batch::~Batch() {
- if (fIsTracked) {
- fInstancedRendering->fTrackedBatches.remove(this);
- }
-
- Draw* draw = fHeadDraw;
- while (draw) {
- Draw* next = draw->fNext;
- fInstancedRendering->fDrawPool.release(draw);
- draw = next;
- }
-}
-
-void InstancedRendering::Batch::appendRRectParams(const SkRRect& rrect) {
- SkASSERT(!fIsTracked);
- switch (rrect.getType()) {
- case SkRRect::kSimple_Type: {
- const SkVector& radii = rrect.getSimpleRadii();
- this->appendParamsTexel(radii.x(), radii.y(), rrect.width(), rrect.height());
- return;
- }
- case SkRRect::kNinePatch_Type: {
- float twoOverW = 2 / rrect.width();
- float twoOverH = 2 / rrect.height();
- const SkVector& radiiTL = rrect.radii(SkRRect::kUpperLeft_Corner);
- const SkVector& radiiBR = rrect.radii(SkRRect::kLowerRight_Corner);
- this->appendParamsTexel(radiiTL.x() * twoOverW, radiiBR.x() * twoOverW,
- radiiTL.y() * twoOverH, radiiBR.y() * twoOverH);
- return;
- }
- case SkRRect::kComplex_Type: {
- /**
- * The x and y radii of each arc are stored in separate vectors,
- * in the following order:
- *
- * __x1 _ _ _ x3__
- * y1 | | y2
- *
- * | |
- *
- * y3 |__ _ _ _ __| y4
- * x2 x4
- *
- */
- float twoOverW = 2 / rrect.width();
- float twoOverH = 2 / rrect.height();
- const SkVector& radiiTL = rrect.radii(SkRRect::kUpperLeft_Corner);
- const SkVector& radiiTR = rrect.radii(SkRRect::kUpperRight_Corner);
- const SkVector& radiiBR = rrect.radii(SkRRect::kLowerRight_Corner);
- const SkVector& radiiBL = rrect.radii(SkRRect::kLowerLeft_Corner);
- this->appendParamsTexel(radiiTL.x() * twoOverW, radiiBL.x() * twoOverW,
- radiiTR.x() * twoOverW, radiiBR.x() * twoOverW);
- this->appendParamsTexel(radiiTL.y() * twoOverH, radiiTR.y() * twoOverH,
- radiiBL.y() * twoOverH, radiiBR.y() * twoOverH);
- return;
- }
- default: return;
- }
-}
-
-void InstancedRendering::Batch::appendParamsTexel(const SkScalar* vals, int count) {
- SkASSERT(!fIsTracked);
- SkASSERT(count <= 4 && count >= 0);
- const float* valsAsFloats = vals; // Ensure SkScalar == float.
- memcpy(&fParams.push_back(), valsAsFloats, count * sizeof(float));
- fInfo.fHasParams = true;
-}
-
-void InstancedRendering::Batch::appendParamsTexel(SkScalar x, SkScalar y, SkScalar z, SkScalar w) {
- SkASSERT(!fIsTracked);
- ParamsTexel& texel = fParams.push_back();
- texel.fX = SkScalarToFloat(x);
- texel.fY = SkScalarToFloat(y);
- texel.fZ = SkScalarToFloat(z);
- texel.fW = SkScalarToFloat(w);
- fInfo.fHasParams = true;
-}
-
-void InstancedRendering::Batch::appendParamsTexel(SkScalar x, SkScalar y, SkScalar z) {
- SkASSERT(!fIsTracked);
- ParamsTexel& texel = fParams.push_back();
- texel.fX = SkScalarToFloat(x);
- texel.fY = SkScalarToFloat(y);
- texel.fZ = SkScalarToFloat(z);
- fInfo.fHasParams = true;
-}
-
-void InstancedRendering::Batch::initBatchTracker(const GrXPOverridesForBatch& overrides) {
- Draw& draw = this->getSingleDraw(); // This will assert if we have > 1 command.
- SkASSERT(draw.fGeometry.isEmpty());
- SkASSERT(SkIsPow2(fInfo.fShapeTypes));
- SkASSERT(!fIsTracked);
-
- if (kRect_ShapeFlag == fInfo.fShapeTypes) {
- draw.fGeometry = InstanceProcessor::GetIndexRangeForRect(fInfo.fAntialiasMode);
- } else if (kOval_ShapeFlag == fInfo.fShapeTypes) {
- draw.fGeometry = InstanceProcessor::GetIndexRangeForOval(fInfo.fAntialiasMode, fBounds);
- } else {
- draw.fGeometry = InstanceProcessor::GetIndexRangeForRRect(fInfo.fAntialiasMode);
- }
-
- if (!fParams.empty()) {
- SkASSERT(fInstancedRendering->fParams.count() < (int)kParamsIdx_InfoMask); // TODO: cleaner.
- this->getSingleInstance().fInfo |= fInstancedRendering->fParams.count();
- fInstancedRendering->fParams.push_back_n(fParams.count(), fParams.begin());
- }
-
- GrColor overrideColor;
- if (overrides.getOverrideColorIfSet(&overrideColor)) {
- SkASSERT(State::kRecordingDraws == fInstancedRendering->fState);
- this->getSingleInstance().fColor = overrideColor;
- }
- fInfo.fUsesLocalCoords = overrides.readsLocalCoords();
- fInfo.fCannotTweakAlphaForCoverage = !overrides.canTweakAlphaForCoverage();
-
- fInstancedRendering->fTrackedBatches.addToTail(this);
- fIsTracked = true;
-}
-
-bool InstancedRendering::Batch::onCombineIfPossible(GrBatch* other, const GrCaps& caps) {
- Batch* that = static_cast<Batch*>(other);
- SkASSERT(fInstancedRendering == that->fInstancedRendering);
- SkASSERT(fTailDraw);
- SkASSERT(that->fTailDraw);
-
- if (!fInfo.canJoin(that->fInfo) ||
- !GrPipeline::CanCombine(*this->pipeline(), this->bounds(),
- *that->pipeline(), that->bounds(), caps)) {
- return false;
- }
-
- fBounds.join(that->fBounds);
- fInfo.join(that->fInfo);
-
- // Adopt the other batch's draws.
- fNumDraws += that->fNumDraws;
- fNumChangesInGeometry += that->fNumChangesInGeometry;
- if (fTailDraw->fGeometry != that->fHeadDraw->fGeometry) {
- ++fNumChangesInGeometry;
- }
- fTailDraw->fNext = that->fHeadDraw;
- fTailDraw = that->fTailDraw;
-
- that->fHeadDraw = that->fTailDraw = nullptr;
-
- return true;
-}
-
-void InstancedRendering::Batch::computePipelineOptimizations(GrInitInvariantOutput* color,
- GrInitInvariantOutput* coverage,
- GrBatchToXPOverrides* overrides) const {
- // We need to be careful about fInfo here and consider how it might change as batches combine.
- // e.g. We can't make an assumption based on fInfo.isSimpleRects() because the batch might
- // later combine with a non-rect.
- color->setUnknownFourComponents();
- if (fInfo.fAntialiasMode >= AntialiasMode::kMSAA) {
- coverage->setKnownSingleComponent(255);
- } else if (AntialiasMode::kNone == fInfo.fAntialiasMode && !fInfo.fCannotDiscard) {
- coverage->setKnownSingleComponent(255);
- } else {
- coverage->setUnknownSingleComponent();
- }
-}
-
-void InstancedRendering::beginFlush(GrResourceProvider* rp) {
- SkASSERT(State::kRecordingDraws == fState);
- fState = State::kFlushing;
-
- if (fTrackedBatches.isEmpty()) {
- return;
- }
-
- if (!fVertexBuffer) {
- fVertexBuffer.reset(InstanceProcessor::FindOrCreateVertexBuffer(fGpu));
- if (!fVertexBuffer) {
- return;
- }
- }
-
- if (!fIndexBuffer) {
- fIndexBuffer.reset(InstanceProcessor::FindOrCreateIndex8Buffer(fGpu));
- if (!fIndexBuffer) {
- return;
- }
- }
-
- if (!fParams.empty()) {
- fParamsBuffer.reset(rp->createBuffer(fParams.count() * sizeof(ParamsTexel),
- kTexel_GrBufferType, kDynamic_GrAccessPattern,
- GrResourceProvider::kNoPendingIO_Flag,
- fParams.begin()));
- if (!fParamsBuffer) {
- return;
- }
- }
-
- this->onBeginFlush(rp);
-}
-
-void InstancedRendering::Batch::onDraw(GrBatchFlushState* state) {
- SkASSERT(State::kFlushing == fInstancedRendering->fState);
- SkASSERT(state->gpu() == fInstancedRendering->gpu());
-
- state->gpu()->handleDirtyContext();
- if (GrXferBarrierType barrierType = this->pipeline()->xferBarrierType(*state->gpu()->caps())) {
- state->gpu()->xferBarrier(this->pipeline()->getRenderTarget(), barrierType);
- }
-
- InstanceProcessor instProc(fInfo, fInstancedRendering->fParamsBuffer);
- fInstancedRendering->onDraw(*this->pipeline(), instProc, this);
-}
-
-void InstancedRendering::endFlush() {
- // The caller is expected to delete all tracked batches (i.e. batches whose initBatchTracker
- // method has been called) before ending the flush.
- SkASSERT(fTrackedBatches.isEmpty());
- fParams.reset();
- fParamsBuffer.reset();
- this->onEndFlush();
- fState = State::kRecordingDraws;
- // Hold on to the shape coords and index buffers.
-}
-
-void InstancedRendering::resetGpuResources(ResetType resetType) {
- fVertexBuffer.reset();
- fIndexBuffer.reset();
- fParamsBuffer.reset();
- this->onResetGpuResources(resetType);
-}
-
-}
« no previous file with comments | « src/gpu/instanced/InstancedRendering.h ('k') | src/gpu/instanced/InstancedRenderingTypes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698