Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2010 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef GrRenderTargetOpList_DEFINED
      9 #define GrRenderTargetOpList_DEFINED
     10 
     11 #include "GrAppliedClip.h"
     12 #include "GrOpList.h"
     13 #include "GrPathRendering.h"
     14 #include "GrPrimitiveProcessor.h"
     15 #include "ops/GrOp.h"
     16 #include "SkArenaAlloc.h"
     17 #include "SkClipStack.h"
     18 #include "SkMatrix.h"
     19 #include "SkStringUtils.h"
     20 #include "SkStrokeRec.h"
     21 #include "SkTArray.h"
     22 #include "SkTLazy.h"
     23 #include "SkTypes.h"
     24 
     25 class GrAuditTrail;
     26 class GrClearOp;
     27 class GrCaps;
     28 class GrRenderTargetProxy;
     29 
     30 class GrRenderTargetOpList final : public GrOpList {
     31 private:
     32     using DstProxy = GrXferProcessor::DstProxy;
     33 
     34 public:
     35     GrRenderTargetOpList(GrRenderTargetProxy*, GrResourceProvider*, GrAuditTrail*);
     36 
     37     ~GrRenderTargetOpList() override;
     38 
     39     void makeClosed(const GrCaps& caps) override {
     40         if (this->isClosed()) {
     41             return;
     42         }
     43 
     44         this->forwardCombine(caps);
     45 
     46         INHERITED::makeClosed(caps);
     47     }
     48 
     49     bool isEmpty() const { return fRecordedOps.empty(); }
     50 
     51     /**
     52      * Empties the draw buffer of any queued up draws.
     53      */
     54     void endFlush() override;
     55 
     56     /**
     57      * Together these two functions flush all queued up draws to GrCommandBuffer. The return value
     58      * of executeOps() indicates whether any commands were actually issued to the GPU.
     59      */
     60     void onPrepare(GrOpFlushState* flushState) override;
     61     bool onExecute(GrOpFlushState* flushState) override;
     62 
     63     uint32_t addOp(std::unique_ptr<GrOp> op, const GrCaps& caps) {
     64         auto addDependency = [ &caps, this ] (GrSurfaceProxy* p) {
     65             this->addDependency(p, caps);
     66         };
     67 
     68         op->visitProxies(addDependency);
     69 
     70         this->recordOp(std::move(op), caps);
     71 
     72         return this->uniqueID();
     73     }
     74 
     75     uint32_t addOp(std::unique_ptr<GrOp> op, const GrCaps& caps,
     76                    GrAppliedClip&& clip, const DstProxy& dstProxy) {
     77         auto addDependency = [ &caps, this ] (GrSurfaceProxy* p) {
     78             this->addDependency(p, caps);
     79         };
     80 
     81         op->visitProxies(addDependency);
     82         clip.visitProxies(addDependency);
     83 
     84         this->recordOp(std::move(op), caps, clip.doesClip() ? &clip : nullptr, &dstProxy);
     85 
     86         return this->uniqueID();
     87     }
     88 
     89     void discard();
     90 
     91     /** Clears the entire render target */
     92     void fullClear(const GrCaps& caps, GrColor color);
     93 
     94     /**
     95      * Copies a pixel rectangle from one surface to another. This call may finalize
     96      * reserved vertex/index data (as though a draw call was made). The src pixels
     97      * copied are specified by srcRect. They are copied to a rect of the same
     98      * size in dst with top left at dstPoint. If the src rect is clipped by the
     99      * src bounds then  pixel values in the dst rect corresponding to area clipped
    100      * by the src rect are not overwritten. This method is not guaranteed to succeed
    101      * depending on the type of surface, configs, etc, and the backend-specific
    102      * limitations.
    103      */
    104     bool copySurface(const GrCaps& caps,
    105                      GrSurfaceProxy* dst,
    106                      GrSurfaceProxy* src,
    107                      const SkIRect& srcRect,
    108                      const SkIPoint& dstPoint) override;
    109 
    110     GrRenderTargetOpList* asRenderTargetOpList() override { return this; }
    111 
    112     SkDEBUGCODE(void dump() const override;)
    113 
    114     SkDEBUGCODE(int numOps() const override { return fRecordedOps.count(); })
    115     SkDEBUGCODE(int numClips() const override { return fNumClips; })
    116     SkDEBUGCODE(void visitProxies_debugOnly(const GrOp::VisitProxyFunc&) const;)
    117 
    118 private:
    119     friend class GrRenderTargetContextPriv; // for stencil clip state. TODO: this is invasive
    120 
    121     struct RecordedOp {
    122         RecordedOp(std::unique_ptr<GrOp> op, GrAppliedClip* appliedClip, const DstProxy* dstProxy)
    123                 : fOp(std::move(op)), fAppliedClip(appliedClip) {
    124             if (dstProxy) {
    125                 fDstProxy = *dstProxy;
    126             }
    127         }
    128 
    129         void visitProxies(const GrOp::VisitProxyFunc& func) const {
    130             if (fOp) {
    131                 fOp->visitProxies(func);
    132             }
    133             if (fDstProxy.proxy()) {
    134                 func(fDstProxy.proxy());
    135             }
    136             if (fAppliedClip) {
    137                 fAppliedClip->visitProxies(func);
    138             }
    139         }
    140 
    141         std::unique_ptr<GrOp> fOp;
    142         DstProxy fDstProxy;
    143         GrAppliedClip* fAppliedClip;
    144     };
    145 
    146     void purgeOpsWithUninstantiatedProxies() override;
    147 
    148     void gatherProxyIntervals(GrResourceAllocator*) const override;
    149 
    150     void recordOp(std::unique_ptr<GrOp>, const GrCaps& caps,
    151                   GrAppliedClip* = nullptr, const DstProxy* = nullptr);
    152 
    153     void forwardCombine(const GrCaps&);
    154 
    155     // If this returns true then b has been merged into a's op.
    156     bool combineIfPossible(const RecordedOp& a, GrOp* b, const GrAppliedClip* bClip,
    157                            const DstProxy* bDstTexture, const GrCaps&);
    158 
    159     uint32_t                       fLastClipStackGenID;
    160     SkIRect                        fLastDevClipBounds;
    161     int                            fLastClipNumAnalyticFPs;
    162 
    163     // For ops/opList we have mean: 5 stdDev: 28
    164     SkSTArray<5, RecordedOp, true> fRecordedOps;
    165 
    166     // MDB TODO: 4096 for the first allocation of the clip space will be huge overkill.
    167     // Gather statistics to determine the correct size.
    168     SkArenaAlloc                   fClipAllocator{4096};
    169     SkDEBUGCODE(int                fNumClips;)
    170 
    171     typedef GrOpList INHERITED;
    172 };
    173 
    174 #endif
    175