diff options
-rw-r--r-- | src/core/SkLatticeIter.cpp | 1 | ||||
-rw-r--r-- | src/gpu/GrRenderTargetContext.cpp | 8 | ||||
-rw-r--r-- | src/gpu/ops/GrLatticeOp.cpp | 149 | ||||
-rw-r--r-- | src/gpu/ops/GrLatticeOp.h | 14 | ||||
-rw-r--r-- | tools/gpu/GrTest.cpp | 14 |
5 files changed, 142 insertions, 44 deletions
diff --git a/src/core/SkLatticeIter.cpp b/src/core/SkLatticeIter.cpp index 4fe9352d0a..9b2a279f2e 100644 --- a/src/core/SkLatticeIter.cpp +++ b/src/core/SkLatticeIter.cpp @@ -17,6 +17,7 @@ static bool valid_divs(const int* divs, int count, int start, int end) { if (prev >= divs[i] || divs[i] >= end) { return false; } + prev = divs[i]; } return true; diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index e9be8d6ef2..2a13ea3a1c 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -1415,11 +1415,9 @@ void GrRenderTargetContext::drawImageLattice(const GrClip& clip, AutoCheckFlush acf(this->drawingManager()); - std::unique_ptr<GrLegacyMeshDrawOp> op = GrLatticeOp::MakeNonAA( - paint.getColor(), viewMatrix, imageWidth, imageHeight, std::move(iter), dst); - - GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone); - this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op)); + std::unique_ptr<GrDrawOp> op = GrLatticeOp::MakeNonAA(std::move(paint), viewMatrix, imageWidth, + imageHeight, std::move(iter), dst); + this->addDrawOp(clip, std::move(op)); } bool GrRenderTargetContext::prepareForExternalIO(int numSemaphores, diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp index 50b957cd21..3e35cb4239 100644 --- a/src/gpu/ops/GrLatticeOp.cpp +++ b/src/gpu/ops/GrLatticeOp.cpp @@ -6,11 +6,12 @@ */ #include "GrLatticeOp.h" - #include "GrDefaultGeoProcFactory.h" +#include "GrDrawOpTest.h" #include "GrMeshDrawOp.h" #include "GrOpFlushState.h" #include "GrResourceProvider.h" +#include "GrSimpleMeshDrawOpHelper.h" #include "SkBitmap.h" #include "SkLatticeIter.h" #include "SkRect.h" @@ -21,16 +22,29 @@ static sk_sp<GrGeometryProcessor> create_gp() { LocalCoords::kHasExplicit_Type, SkMatrix::I()); } -class NonAALatticeOp final : public GrLegacyMeshDrawOp { +namespace { + +class NonAALatticeOp final : public GrMeshDrawOp { +private: + using Helper = GrSimpleMeshDrawOpHelper; + public: DEFINE_OP_CLASS_ID static const int kVertsPerRect = 4; static const int kIndicesPerRect = 6; - NonAALatticeOp(GrColor color, const SkMatrix& viewMatrix, int imageWidth, int imageHeight, - std::unique_ptr<SkLatticeIter> iter, const SkRect& dst) - : INHERITED(ClassID()) { + static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix, + int imageWidth, int imageHeight, + std::unique_ptr<SkLatticeIter> iter, const SkRect& dst) { + return Helper::FactoryHelper<NonAALatticeOp>(std::move(paint), viewMatrix, imageWidth, + imageHeight, std::move(iter), dst); + } + + NonAALatticeOp(Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix, + int imageWidth, int imageHeight, std::unique_ptr<SkLatticeIter> iter, + const SkRect& dst) + : INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kNone) { Patch& patch = fPatches.push_back(); patch.fViewMatrix = viewMatrix; patch.fColor = color; @@ -55,22 +69,19 @@ public: fPatches[i].fDst.fRight, fPatches[i].fDst.fBottom); } - str.append(DumpPipelineInfo(*this->pipeline())); - str.append(INHERITED::dumpInfo()); + str += fHelper.dumpInfo(); + str += INHERITED::dumpInfo(); return str; } -private: - void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color, - GrProcessorAnalysisCoverage* coverage) const override { - color->setToUnknown(); - *coverage = GrProcessorAnalysisCoverage::kNone; - } + FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); } - void applyPipelineOptimizations(const PipelineOptimizations& analysioptimizations) override { - analysioptimizations.getOverrideColorIfSet(&fPatches[0].fColor); + RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override { + return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kNone, + &fPatches.front().fColor); } +private: void onPrepareDraws(Target* target) const override { sk_sp<GrGeometryProcessor> gp(create_gp()); if (!gp) { @@ -133,13 +144,12 @@ private: positions, vertexStride, kVertsPerRect * patch.fIter->numRectsToDraw()); } } - helper.recordDraw(target, gp.get(), this->pipeline()); + helper.recordDraw(target, gp.get(), fHelper.makePipeline(target)); } bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override { NonAALatticeOp* that = t->cast<NonAALatticeOp>(); - if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), - that->bounds(), caps)) { + if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) { return false; } @@ -158,19 +168,106 @@ private: GrColor fColor; }; + Helper fHelper; + SkSTArray<1, Patch, true> fPatches; int fImageWidth; int fImageHeight; - SkSTArray<1, Patch, true> fPatches; - typedef GrLegacyMeshDrawOp INHERITED; + typedef GrMeshDrawOp INHERITED; }; +} // anonymous namespace + namespace GrLatticeOp { -std::unique_ptr<GrLegacyMeshDrawOp> MakeNonAA(GrColor color, const SkMatrix& viewMatrix, - int imageWidth, int imageHeight, - std::unique_ptr<SkLatticeIter> iter, - const SkRect& dst) { - return std::unique_ptr<GrLegacyMeshDrawOp>( - new NonAALatticeOp(color, viewMatrix, imageWidth, imageHeight, std::move(iter), dst)); +std::unique_ptr<GrDrawOp> MakeNonAA(GrPaint&& paint, const SkMatrix& viewMatrix, int imageWidth, + int imageHeight, std::unique_ptr<SkLatticeIter> iter, + const SkRect& dst) { + return NonAALatticeOp::Make(std::move(paint), viewMatrix, imageWidth, imageHeight, + std::move(iter), dst); } }; + +#if GR_TEST_UTILS + +/** Randomly divides subset into count divs. */ +static void init_random_divs(int divs[], int count, int subsetStart, int subsetStop, + SkRandom* random) { + // Rules for lattice divs: Must be strictly increasing and in the range + // [subsetStart, subsetStop). + // Not terribly efficient alg for generating random divs: + // 1) Start with minimum legal pixels between each div. + // 2) Randomly assign the remaining pixels of the subset to divs. + // 3) Convert from pixel counts to div offsets. + + // 1) Initially each divs[i] represents the number of pixels between + // div i-1 and i. The initial div is allowed to be at subsetStart. There + // must be one pixel spacing between subsequent divs. + divs[0] = 0; + for (int i = 1; i < count; ++i) { + divs[i] = 1; + } + // 2) Assign the remaining subset pixels to fall + int subsetLength = subsetStop - subsetStart; + for (int i = 0; i < subsetLength - count; ++i) { + // +1 because count divs means count+1 intervals. + int entry = random->nextULessThan(count + 1); + // We don't have an entry to to store the count after the last div + if (entry < count) { + divs[entry]++; + } + } + // 3) Now convert the counts between divs to pixel indices, incorporating the subset's offset. + int offset = subsetStart; + for (int i = 0; i < count; ++i) { + divs[i] += offset; + offset = divs[i]; + } +} + +GR_DRAW_OP_TEST_DEFINE(NonAALatticeOp) { + int imgW = random->nextRangeU(1, 1000); + int imgH = random->nextRangeU(1, 1000); + SkCanvas::Lattice lattice; + SkIRect subset; + if (random->nextBool()) { + subset.fLeft = random->nextULessThan(imgW); + subset.fRight = random->nextRangeU(subset.fLeft + 1, imgW); + subset.fTop = random->nextULessThan(imgH); + subset.fBottom = random->nextRangeU(subset.fTop + 1, imgH); + } else { + subset.setXYWH(0, 0, imgW, imgH); + } + // SkCanvas::Lattice allows bounds to be null. However, SkCanvas creates a temp Lattice with a + // non-null bounds before creating a SkLatticeIter since SkLatticeIter requires a bounds. + lattice.fBounds = ⊂ + lattice.fXCount = random->nextRangeU(1, subset.width()); + lattice.fYCount = random->nextRangeU(1, subset.height()); + std::unique_ptr<int[]> xdivs(new int[lattice.fXCount]); + std::unique_ptr<int[]> ydivs(new int[lattice.fYCount]); + init_random_divs(xdivs.get(), lattice.fXCount, subset.fLeft, subset.fRight, random); + init_random_divs(ydivs.get(), lattice.fYCount, subset.fTop, subset.fBottom, random); + lattice.fXDivs = xdivs.get(); + lattice.fYDivs = ydivs.get(); + bool hasFlags = random->nextBool(); + std::unique_ptr<SkCanvas::Lattice::Flags[]> flags; + if (hasFlags) { + int n = (lattice.fXCount + 1) * (lattice.fYCount + 1); + flags.reset(new SkCanvas::Lattice::Flags[n]); + for (int i = 0; i < n; ++i) { + flags[i] = random->nextBool() ? SkCanvas::Lattice::kTransparent_Flags + : (SkCanvas::Lattice::Flags)0; + } + } + lattice.fFlags = flags.get(); + SkRect dst; + dst.fLeft = random->nextRangeScalar(-2000.5f, 1000.f); + dst.fTop = random->nextRangeScalar(-2000.5f, 1000.f); + dst.fRight = dst.fLeft + random->nextRangeScalar(0.5f, 1000.f); + dst.fBottom = dst.fTop + random->nextRangeScalar(0.5f, 1000.f); + std::unique_ptr<SkLatticeIter> iter(new SkLatticeIter(lattice, dst)); + SkMatrix viewMatrix = GrTest::TestMatrixPreservesRightAngles(random); + SkASSERT(SkLatticeIter::Valid(imgW, imgH, lattice)); + return NonAALatticeOp::Make(std::move(paint), viewMatrix, imgW, imgH, std::move(iter), dst); +} + +#endif diff --git a/src/gpu/ops/GrLatticeOp.h b/src/gpu/ops/GrLatticeOp.h index 65aa622894..cce8f322d8 100644 --- a/src/gpu/ops/GrLatticeOp.h +++ b/src/gpu/ops/GrLatticeOp.h @@ -8,19 +8,19 @@ #ifndef GLatticeOp_DEFINED #define GLatticeOp_DEFINED -#include "GrColor.h" -#include "SkRefCnt.h" +#include <memory> +#include "GrTypes.h" -class GrLegacyMeshDrawOp; +class GrDrawOp; +class GrPaint; class SkLatticeIter; class SkMatrix; struct SkRect; namespace GrLatticeOp { -std::unique_ptr<GrLegacyMeshDrawOp> MakeNonAA(GrColor color, const SkMatrix& viewMatrix, - int imageWidth, int imageHeight, - std::unique_ptr<SkLatticeIter> iter, - const SkRect& dst); +std::unique_ptr<GrDrawOp> MakeNonAA(GrPaint&& paint, const SkMatrix& viewMatrix, int imageWidth, + int imageHeight, std::unique_ptr<SkLatticeIter> iter, + const SkRect& dst); }; #endif diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp index ec8af81f94..61f3d82c33 100644 --- a/tools/gpu/GrTest.cpp +++ b/tools/gpu/GrTest.cpp @@ -306,14 +306,14 @@ void GrDrawingManager::testingOnly_removeOnFlushCallbackObject(GrOnFlushCallback ////////////////////////////////////////////////////////////////////////////// #define DRAW_OP_TEST_EXTERN(Op) \ - extern std::unique_ptr<GrDrawOp> Op##__Test(GrPaint&&, SkRandom*, GrContext*, GrFSAAType); + extern std::unique_ptr<GrDrawOp> Op##__Test(GrPaint&&, SkRandom*, GrContext*, GrFSAAType) #define LEGACY_MESH_DRAW_OP_TEST_EXTERN(Op) \ - extern std::unique_ptr<GrLegacyMeshDrawOp> Op##__Test(SkRandom*, GrContext*); + extern std::unique_ptr<GrLegacyMeshDrawOp> Op##__Test(SkRandom*, GrContext*) #define DRAW_OP_TEST_ENTRY(Op) Op##__Test -LEGACY_MESH_DRAW_OP_TEST_EXTERN(AAFlatteningConvexPathOp) +LEGACY_MESH_DRAW_OP_TEST_EXTERN(AAFlatteningConvexPathOp); LEGACY_MESH_DRAW_OP_TEST_EXTERN(AnalyticRectOp); LEGACY_MESH_DRAW_OP_TEST_EXTERN(DashOp); LEGACY_MESH_DRAW_OP_TEST_EXTERN(DefaultPathOp); @@ -324,13 +324,14 @@ LEGACY_MESH_DRAW_OP_TEST_EXTERN(TextBlobOp); LEGACY_MESH_DRAW_OP_TEST_EXTERN(VerticesOp); DRAW_OP_TEST_EXTERN(AAConvexPathOp); -DRAW_OP_TEST_EXTERN(AAFillRectOp) +DRAW_OP_TEST_EXTERN(AAFillRectOp); DRAW_OP_TEST_EXTERN(AAHairlineOp); DRAW_OP_TEST_EXTERN(AAStrokeRectOp); -DRAW_OP_TEST_EXTERN(CircleOp) +DRAW_OP_TEST_EXTERN(CircleOp); DRAW_OP_TEST_EXTERN(DIEllipseOp); DRAW_OP_TEST_EXTERN(EllipseOp); -DRAW_OP_TEST_EXTERN(NonAAFillRectOp) +DRAW_OP_TEST_EXTERN(NonAAFillRectOp); +DRAW_OP_TEST_EXTERN(NonAALatticeOp); DRAW_OP_TEST_EXTERN(NonAAStrokeRectOp); DRAW_OP_TEST_EXTERN(RRectOp); @@ -359,6 +360,7 @@ void GrDrawRandomOp(SkRandom* random, GrRenderTargetContext* renderTargetContext DRAW_OP_TEST_ENTRY(DIEllipseOp), DRAW_OP_TEST_ENTRY(EllipseOp), DRAW_OP_TEST_ENTRY(NonAAFillRectOp), + DRAW_OP_TEST_ENTRY(NonAALatticeOp), DRAW_OP_TEST_ENTRY(NonAAStrokeRectOp), DRAW_OP_TEST_ENTRY(RRectOp), }; |