diff options
author | 2017-07-14 15:17:41 -0600 | |
---|---|---|
committer | 2017-07-14 21:45:35 +0000 | |
commit | 1a325d25b941ef801b3e9b2c0342da43cf35cdba (patch) | |
tree | 3f65d36541399e1ae6a529a534119815a2c5ba36 /src/gpu/ccpr/GrCoverageCountingPathRenderer.h | |
parent | 588fb040b3ad410cdb10c87f9a7884b6eb825e90 (diff) |
Coverage counting path renderer
Initial implementation of a GPU path renderer that draws antialiased
paths by counting coverage in an offscreen buffer.
Initially disabled until it has had time to soak.
Bug: skia:
Change-Id: I003d8cfdf8dc62641581b5ea2dc4f0aa00108df6
Reviewed-on: https://skia-review.googlesource.com/21541
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu/ccpr/GrCoverageCountingPathRenderer.h')
-rw-r--r-- | src/gpu/ccpr/GrCoverageCountingPathRenderer.h | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.h b/src/gpu/ccpr/GrCoverageCountingPathRenderer.h new file mode 100644 index 0000000000..f55d0e1835 --- /dev/null +++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.h @@ -0,0 +1,135 @@ +/* + * 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 GrCoverageCountingPathRenderer_DEFINED +#define GrCoverageCountingPathRenderer_DEFINED + +#include "GrAllocator.h" +#include "GrOnFlushResourceProvider.h" +#include "GrPathRenderer.h" +#include "SkTInternalLList.h" +#include "ccpr/GrCCPRAtlas.h" +#include "ccpr/GrCCPRCoverageOpsBuilder.h" +#include "ops/GrDrawOp.h" +#include <map> + +/** + * This is a path renderer that draws antialiased paths by counting coverage in an offscreen + * buffer. (See GrCCPRCoverageProcessor, GrCCPRPathProcessor) + * + * It also serves as the per-render-target tracker for pending path draws, and at the start of + * flush, it compiles GPU buffers and renders a "coverage count atlas" for the upcoming paths. + */ +class GrCoverageCountingPathRenderer + : public GrPathRenderer + , public GrOnFlushCallbackObject { + + struct RTPendingOps; + +public: + static bool IsSupported(const GrCaps&); + static sk_sp<GrCoverageCountingPathRenderer> CreateIfSupported(const GrCaps&); + + // GrPathRenderer overrides. + StencilSupport onGetStencilSupport(const GrShape&) const override { + return GrPathRenderer::kNoSupport_StencilSupport; + } + bool onCanDrawPath(const CanDrawPathArgs& args) const override; + bool onDrawPath(const DrawPathArgs&) final; + + // GrOnFlushCallbackObject overrides. + void preFlush(GrOnFlushResourceProvider*, const uint32_t* opListIDs, int numOpListIDs, + SkTArray<sk_sp<GrRenderTargetContext>>* results) override; + void postFlush() override; + + // This is the Op that ultimately draws a path into its final destination, using the atlas we + // generate at flush time. + class DrawPathsOp : public GrDrawOp { + public: + DEFINE_OP_CLASS_ID + SK_DECLARE_INTERNAL_LLIST_INTERFACE(DrawPathsOp); + + DrawPathsOp(GrCoverageCountingPathRenderer*, const DrawPathArgs&, GrColor); + + // GrDrawOp overrides. + const char* name() const override { return "GrCoverageCountingPathRenderer::DrawPathsOp"; } + FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; } + RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*) override; + void wasRecorded(GrRenderTargetOpList*) override; + bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override; + void onPrepare(GrOpFlushState*) override {} + void onExecute(GrOpFlushState*) override; + + private: + SkPath::FillType getFillType() const { + SkASSERT(fDebugInstanceCount >= 1); + return fHeadDraw.fPath.getFillType(); + } + + struct SingleDraw { + using ScissorMode = GrCCPRCoverageOpsBuilder::ScissorMode; + SkIRect fClipBounds; + ScissorMode fScissorMode; + SkMatrix fMatrix; + SkPath fPath; + GrColor fColor; + SingleDraw* fNext = nullptr; + }; + + SingleDraw& getOnlyPathDraw() { + SkASSERT(&fHeadDraw == fTailDraw); + SkASSERT(1 == fDebugInstanceCount); + return fHeadDraw; + } + + struct AtlasBatch { + const GrCCPRAtlas* fAtlas; + int fEndInstanceIdx; + }; + + void addAtlasBatch(const GrCCPRAtlas* atlas, int endInstanceIdx) { + SkASSERT(endInstanceIdx > fBaseInstance); + SkASSERT(fAtlasBatches.empty() || + endInstanceIdx > fAtlasBatches.back().fEndInstanceIdx); + fAtlasBatches.push_back() = {atlas, endInstanceIdx}; + } + + GrCoverageCountingPathRenderer* const fCCPR; + const uint32_t fSRGBFlags; + GrProcessorSet fProcessors; + SingleDraw fHeadDraw; + SingleDraw* fTailDraw; + RTPendingOps* fOwningRTPendingOps; + int fBaseInstance; + SkDEBUGCODE(int fDebugInstanceCount;) + SkSTArray<1, AtlasBatch, true> fAtlasBatches; + + friend class GrCoverageCountingPathRenderer; + + typedef GrDrawOp INHERITED; + }; + +private: + GrCoverageCountingPathRenderer() = default; + + struct RTPendingOps { + SkTInternalLList<DrawPathsOp> fOpList; + GrCCPRCoverageOpsBuilder::MaxBufferItems fMaxBufferItems; + GrSTAllocator<256, DrawPathsOp::SingleDraw> fDrawsAllocator; + }; + + // Map from render target ID to the individual render target's pending path ops. + std::map<uint32_t, RTPendingOps> fRTPendingOpsMap; + + sk_sp<GrBuffer> fPerFlushIndexBuffer; + sk_sp<GrBuffer> fPerFlushVertexBuffer; + sk_sp<GrBuffer> fPerFlushInstanceBuffer; + GrSTAllocator<4, GrCCPRAtlas> fPerFlushAtlases; + SkDEBUGCODE(bool fFlushing = false;) +}; + +#endif |