Home | History | Annotate | Download | only in ops
      1 /*
      2  * Copyright 2015 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 GrClearOp_DEFINED
      9 #define GrClearOp_DEFINED
     10 
     11 #include "GrFixedClip.h"
     12 #include "GrGpu.h"
     13 #include "GrGpuCommandBuffer.h"
     14 #include "GrOp.h"
     15 #include "GrOpFlushState.h"
     16 #include "GrRenderTarget.h"
     17 
     18 class GrClearOp final : public GrOp {
     19 public:
     20     DEFINE_OP_CLASS_ID
     21 
     22     static std::unique_ptr<GrClearOp> Make(const GrFixedClip& clip, GrColor color,
     23                                            GrRenderTarget* rt) {
     24         std::unique_ptr<GrClearOp> op(new GrClearOp(clip, color, rt));
     25         if (!op->fRenderTarget) {
     26             return nullptr; // The clip did not contain any pixels within the render target.
     27         }
     28         return op;
     29     }
     30 
     31     static std::unique_ptr<GrClearOp> Make(const SkIRect& rect, GrColor color, GrRenderTarget* rt,
     32                                            bool fullScreen) {
     33         return std::unique_ptr<GrClearOp>(new GrClearOp(rect, color, rt, fullScreen));
     34     }
     35 
     36     const char* name() const override { return "Clear"; }
     37 
     38     SkString dumpInfo() const override {
     39         SkString string("Scissor [");
     40         if (fClip.scissorEnabled()) {
     41             const SkIRect& r = fClip.scissorRect();
     42             string.appendf("L: %d, T: %d, R: %d, B: %d", r.fLeft, r.fTop, r.fRight, r.fBottom);
     43         }
     44         string.appendf("], Color: 0x%08x, RT: %d", fColor,
     45                                                    fRenderTarget.get()->uniqueID().asUInt());
     46         string.append(INHERITED::dumpInfo());
     47         return string;
     48     }
     49 
     50     void setColor(GrColor color) { fColor = color; }
     51 
     52 private:
     53     GrClearOp(const GrFixedClip& clip, GrColor color, GrRenderTarget* rt)
     54         : INHERITED(ClassID())
     55         , fClip(clip)
     56         , fColor(color) {
     57         SkIRect rtRect = SkIRect::MakeWH(rt->width(), rt->height());
     58         if (fClip.scissorEnabled()) {
     59             // Don't let scissors extend outside the RT. This may improve op combining.
     60             if (!fClip.intersect(rtRect)) {
     61                 return;
     62             }
     63             if (fClip.scissorRect() == rtRect) {
     64                 fClip.disableScissor();
     65             }
     66         }
     67         this->setBounds(SkRect::Make(fClip.scissorEnabled() ? fClip.scissorRect() : rtRect),
     68                         HasAABloat::kNo, IsZeroArea::kNo);
     69         fRenderTarget.reset(rt);
     70     }
     71 
     72     GrClearOp(const SkIRect& rect, GrColor color, GrRenderTarget* rt, bool fullScreen)
     73         : INHERITED(ClassID())
     74         , fClip(GrFixedClip(rect))
     75         , fColor(color)
     76         , fRenderTarget(rt) {
     77         if (fullScreen) {
     78             fClip.disableScissor();
     79         }
     80         this->setBounds(SkRect::Make(rect), HasAABloat::kNo, IsZeroArea::kNo);
     81     }
     82 
     83     bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
     84         // This could be much more complicated. Currently we look at cases where the new clear
     85         // contains the old clear, or when the new clear is a subset of the old clear and is the
     86         // same color.
     87         GrClearOp* cb = t->cast<GrClearOp>();
     88         SkASSERT(cb->fRenderTarget == fRenderTarget);
     89         if (fClip.windowRectsState() != cb->fClip.windowRectsState()) {
     90             return false;
     91         }
     92         if (cb->contains(this)) {
     93             fClip = cb->fClip;
     94             this->replaceBounds(*t);
     95             fColor = cb->fColor;
     96             return true;
     97         } else if (cb->fColor == fColor && this->contains(cb)) {
     98             return true;
     99         }
    100         return false;
    101     }
    102 
    103     bool contains(const GrClearOp* that) const {
    104         // The constructor ensures that scissor gets disabled on any clip that fills the entire RT.
    105         return !fClip.scissorEnabled() ||
    106                (that->fClip.scissorEnabled() &&
    107                 fClip.scissorRect().contains(that->fClip.scissorRect()));
    108     }
    109 
    110     void onPrepare(GrOpFlushState*) override {}
    111 
    112     void onExecute(GrOpFlushState* state) override {
    113         state->commandBuffer()->clear(fRenderTarget.get(), fClip, fColor);
    114     }
    115 
    116     GrFixedClip                                             fClip;
    117     GrColor                                                 fColor;
    118     GrPendingIOResource<GrRenderTarget, kWrite_GrIOType>    fRenderTarget;
    119 
    120     typedef GrOp INHERITED;
    121 };
    122 
    123 #endif
    124