| /* |
| * Copyright 2017 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef gr_instanced_InstancedOp_DEFINED |
| #define gr_instanced_InstancedOp_DEFINED |
| |
| |
| #include "../private/GrInstancedPipelineInfo.h" |
| #include "GrMemoryPool.h" |
| #include "ops/GrDrawOp.h" |
| #include "instanced/InstancedRenderingTypes.h" |
| |
| #include "SkTInternalLList.h" |
| |
| namespace gr_instanced { |
| |
| class InstancedRendering; |
| class OpAllocator; |
| |
| class InstancedOp : public GrDrawOp { |
| public: |
| SK_DECLARE_INTERNAL_LLIST_INTERFACE(InstancedOp); |
| |
| ~InstancedOp() override; |
| const char* name() const override { return "InstancedOp"; } |
| |
| void visitProxies(VisitProxyFunc func) const override { |
| fProcessors.visitProxies(func); |
| } |
| |
| SkString dumpInfo() const override { |
| SkString string; |
| string.printf( |
| "AA: %d, ShapeTypes: 0x%02x, IShapeTypes: 0x%02x, Persp %d, " |
| "NonSquare: %d, PLoad: %0.2f, Tracked: %d, NumDraws: %d, " |
| "GeomChanges: %d\n", |
| (unsigned)fInfo.fAAType, |
| fInfo.fShapeTypes, |
| fInfo.fInnerShapeTypes, |
| fInfo.fHasPerspective, |
| fInfo.fNonSquare, |
| fPixelLoad, |
| fIsTracked, |
| fNumDraws, |
| fNumChangesInGeometry); |
| string.append(INHERITED::dumpInfo()); |
| return string; |
| } |
| |
| struct Draw { |
| Instance fInstance; |
| IndexRange fGeometry; |
| Draw* fNext; |
| }; |
| |
| Draw& getSingleDraw() const { SkASSERT(fHeadDraw && !fHeadDraw->fNext); return *fHeadDraw; } |
| Instance& getSingleInstance() const { return this->getSingleDraw().fInstance; } |
| |
| void appendRRectParams(const SkRRect&); |
| void appendParamsTexel(const SkScalar* vals, int count); |
| void appendParamsTexel(SkScalar x, SkScalar y, SkScalar z, SkScalar w); |
| void appendParamsTexel(SkScalar x, SkScalar y, SkScalar z); |
| FixedFunctionFlags fixedFunctionFlags() const override { |
| return GrAATypeIsHW(fInfo.aaType()) ? FixedFunctionFlags::kUsesHWAA |
| : FixedFunctionFlags::kNone; |
| } |
| RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*) override; |
| |
| // Registers the op with the InstancedRendering list of tracked ops. |
| void wasRecorded(GrRenderTargetOpList*) override; |
| |
| protected: |
| InstancedOp(uint32_t classID, GrPaint&&, OpAllocator*); |
| |
| bool fIsTracked : 1; |
| bool fRequiresBarrierOnOverlap : 1; |
| bool fAllowsSRGBInputs : 1; |
| bool fDisableSRGBOutputConversion : 1; |
| int fNumDraws; |
| int fNumChangesInGeometry; |
| Draw* fHeadDraw; |
| Draw* fTailDraw; |
| OpAllocator* fAllocator; |
| InstancedRendering* fInstancedRendering; |
| OpInfo fInfo; |
| SkScalar fPixelLoad; |
| GrProcessorSet fProcessors; |
| SkSTArray<5, ParamsTexel, true> fParams; |
| |
| private: |
| bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override; |
| void onPrepare(GrOpFlushState*) override {} |
| void onExecute(GrOpFlushState*) override; |
| |
| typedef GrDrawOp INHERITED; |
| |
| friend class InstancedRendering; |
| friend class OpAllocator; |
| }; |
| |
| class OpAllocator : public SkNoncopyable { |
| public: |
| virtual ~OpAllocator(); |
| |
| /** |
| * These methods make a new record internally for an instanced draw, and return an op that is |
| * effectively just an index to that record. The returned op is not self-contained, but |
| * rather relies on this class to handle the rendering. The client must call beginFlush() on |
| * this class before attempting to flush ops returned by it. It is invalid to record new |
| * draws between beginFlush() and endFlush(). |
| */ |
| std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&, |
| GrPaint&&, GrAA, |
| const GrInstancedPipelineInfo&); |
| |
| std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&, |
| GrPaint&&, const SkRect& localRect, |
| GrAA, |
| const GrInstancedPipelineInfo&); |
| |
| std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&, |
| GrPaint&&, |
| const SkMatrix& localMatrix, GrAA, |
| const GrInstancedPipelineInfo&); |
| |
| std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordOval(const SkRect&, const SkMatrix&, |
| GrPaint&&, GrAA, |
| const GrInstancedPipelineInfo&); |
| |
| std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordRRect(const SkRRect&, const SkMatrix&, |
| GrPaint&&, GrAA, |
| const GrInstancedPipelineInfo&); |
| |
| std::unique_ptr<GrDrawOp> SK_WARN_UNUSED_RESULT recordDRRect(const SkRRect& outer, |
| const SkRRect& inner, |
| const SkMatrix&, GrPaint&&, GrAA, |
| const GrInstancedPipelineInfo&); |
| |
| InstancedOp::Draw* allocateDraw() { return fDrawPool.allocate(); } |
| void releaseDraw(InstancedOp::Draw* draw) { fDrawPool.release(draw); } |
| |
| protected: |
| OpAllocator(const GrCaps*); |
| |
| private: |
| bool selectAntialiasMode(const SkMatrix& viewMatrix, GrAA aa, const GrInstancedPipelineInfo&, |
| GrAAType*); |
| virtual std::unique_ptr<InstancedOp> makeOp(GrPaint&&) = 0; |
| |
| std::unique_ptr<InstancedOp> SK_WARN_UNUSED_RESULT recordShape( |
| ShapeType, const SkRect& bounds, |
| const SkMatrix& viewMatrix, GrPaint&&, |
| const SkRect& localRect, GrAA aa, |
| const GrInstancedPipelineInfo&); |
| |
| GrObjectMemoryPool<InstancedOp::Draw> fDrawPool; |
| sk_sp<const GrCaps> fCaps; |
| }; |
| |
| } |
| |
| #endif |