15346983b2e0726b4009cc546b01c58a8919e6c36bsalomon/*
25346983b2e0726b4009cc546b01c58a8919e6c36bsalomon * Copyright 2015 Google Inc.
35346983b2e0726b4009cc546b01c58a8919e6c36bsalomon *
45346983b2e0726b4009cc546b01c58a8919e6c36bsalomon * Use of this source code is governed by a BSD-style license that can be
55346983b2e0726b4009cc546b01c58a8919e6c36bsalomon * found in the LICENSE file.
65346983b2e0726b4009cc546b01c58a8919e6c36bsalomon */
75346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
87dae46a6783de5f6bc461870306eb7d648386980Brian Salomon#ifndef GrClearOp_DEFINED
97dae46a6783de5f6bc461870306eb7d648386980Brian Salomon#define GrClearOp_DEFINED
105346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
1129df76096fd30941086324902a82656df2d8becdcsmartdalton#include "GrFixedClip.h"
125346983b2e0726b4009cc546b01c58a8919e6c36bsalomon#include "GrGpu.h"
139cb6340a62a5d748e4189d50e51fa527c8c80c03egdaniel#include "GrGpuCommandBuffer.h"
1425a880960a9a689a745a01071ecba3fe494b5940Brian Salomon#include "GrOp.h"
15742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomon#include "GrOpFlushState.h"
165346983b2e0726b4009cc546b01c58a8919e6c36bsalomon#include "GrRenderTarget.h"
175346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
187dae46a6783de5f6bc461870306eb7d648386980Brian Salomonclass GrClearOp final : public GrOp {
195346983b2e0726b4009cc546b01c58a8919e6c36bsalomonpublic:
2025a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    DEFINE_OP_CLASS_ID
211b55a963a2374a14bb82eb887bb99ee91680f0ebreed
22f8334781914363caf537f22f012fcd5c03c60dadBrian Salomon    static std::unique_ptr<GrClearOp> Make(const GrFixedClip& clip, GrColor color,
23f8334781914363caf537f22f012fcd5c03c60dadBrian Salomon                                           GrRenderTarget* rt) {
24f8334781914363caf537f22f012fcd5c03c60dadBrian Salomon        std::unique_ptr<GrClearOp> op(new GrClearOp(clip, color, rt));
257dae46a6783de5f6bc461870306eb7d648386980Brian Salomon        if (!op->fRenderTarget) {
2629df76096fd30941086324902a82656df2d8becdcsmartdalton            return nullptr; // The clip did not contain any pixels within the render target.
2729df76096fd30941086324902a82656df2d8becdcsmartdalton        }
287dae46a6783de5f6bc461870306eb7d648386980Brian Salomon        return op;
295346983b2e0726b4009cc546b01c58a8919e6c36bsalomon    }
305346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
31f8334781914363caf537f22f012fcd5c03c60dadBrian Salomon    static std::unique_ptr<GrClearOp> Make(const SkIRect& rect, GrColor color, GrRenderTarget* rt,
32f8334781914363caf537f22f012fcd5c03c60dadBrian Salomon                                           bool fullScreen) {
33f8334781914363caf537f22f012fcd5c03c60dadBrian Salomon        return std::unique_ptr<GrClearOp>(new GrClearOp(rect, color, rt, fullScreen));
34784b7bf493c37236e3fe571aed6105939a9bc0c3Robert Phillips    }
35784b7bf493c37236e3fe571aed6105939a9bc0c3Robert Phillips
365346983b2e0726b4009cc546b01c58a8919e6c36bsalomon    const char* name() const override { return "Clear"; }
375346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
389dc2a9a972b1eb5c3bc8ee5952676250084c68b5Brian Salomon    SkString dumpInfo() const override {
3929df76096fd30941086324902a82656df2d8becdcsmartdalton        SkString string("Scissor [");
4029df76096fd30941086324902a82656df2d8becdcsmartdalton        if (fClip.scissorEnabled()) {
4129df76096fd30941086324902a82656df2d8becdcsmartdalton            const SkIRect& r = fClip.scissorRect();
4229df76096fd30941086324902a82656df2d8becdcsmartdalton            string.appendf("L: %d, T: %d, R: %d, B: %d", r.fLeft, r.fTop, r.fRight, r.fBottom);
4329df76096fd30941086324902a82656df2d8becdcsmartdalton        }
44294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        string.appendf("], Color: 0x%08x, RT: %d", fColor,
45294870ff119b89fc902773643b054f14e5d1f554Robert Phillips                                                   fRenderTarget.get()->uniqueID().asUInt());
4644fbc79e069c28103a44387d11c62e049ef2967drobertphillips        string.append(INHERITED::dumpInfo());
475346983b2e0726b4009cc546b01c58a8919e6c36bsalomon        return string;
485346983b2e0726b4009cc546b01c58a8919e6c36bsalomon    }
495346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
50fd8d013f0da10d94b43fb63002e56a3f4cd7f56dbsalomon    void setColor(GrColor color) { fColor = color; }
51fd8d013f0da10d94b43fb63002e56a3f4cd7f56dbsalomon
525346983b2e0726b4009cc546b01c58a8919e6c36bsalomonprivate:
537dae46a6783de5f6bc461870306eb7d648386980Brian Salomon    GrClearOp(const GrFixedClip& clip, GrColor color, GrRenderTarget* rt)
549199a9fef9896636f673372d2ac1c00af036bf85robertphillips        : INHERITED(ClassID())
5529df76096fd30941086324902a82656df2d8becdcsmartdalton        , fClip(clip)
5629df76096fd30941086324902a82656df2d8becdcsmartdalton        , fColor(color) {
5729df76096fd30941086324902a82656df2d8becdcsmartdalton        SkIRect rtRect = SkIRect::MakeWH(rt->width(), rt->height());
5829df76096fd30941086324902a82656df2d8becdcsmartdalton        if (fClip.scissorEnabled()) {
5953e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon            // Don't let scissors extend outside the RT. This may improve op combining.
6029df76096fd30941086324902a82656df2d8becdcsmartdalton            if (!fClip.intersect(rtRect)) {
6129df76096fd30941086324902a82656df2d8becdcsmartdalton                return;
6229df76096fd30941086324902a82656df2d8becdcsmartdalton            }
6329df76096fd30941086324902a82656df2d8becdcsmartdalton            if (fClip.scissorRect() == rtRect) {
6429df76096fd30941086324902a82656df2d8becdcsmartdalton                fClip.disableScissor();
6529df76096fd30941086324902a82656df2d8becdcsmartdalton            }
6629df76096fd30941086324902a82656df2d8becdcsmartdalton        }
6729df76096fd30941086324902a82656df2d8becdcsmartdalton        this->setBounds(SkRect::Make(fClip.scissorEnabled() ? fClip.scissorRect() : rtRect),
6829df76096fd30941086324902a82656df2d8becdcsmartdalton                        HasAABloat::kNo, IsZeroArea::kNo);
6929df76096fd30941086324902a82656df2d8becdcsmartdalton        fRenderTarget.reset(rt);
709199a9fef9896636f673372d2ac1c00af036bf85robertphillips    }
719199a9fef9896636f673372d2ac1c00af036bf85robertphillips
727dae46a6783de5f6bc461870306eb7d648386980Brian Salomon    GrClearOp(const SkIRect& rect, GrColor color, GrRenderTarget* rt, bool fullScreen)
73784b7bf493c37236e3fe571aed6105939a9bc0c3Robert Phillips        : INHERITED(ClassID())
74784b7bf493c37236e3fe571aed6105939a9bc0c3Robert Phillips        , fClip(GrFixedClip(rect))
75784b7bf493c37236e3fe571aed6105939a9bc0c3Robert Phillips        , fColor(color)
76784b7bf493c37236e3fe571aed6105939a9bc0c3Robert Phillips        , fRenderTarget(rt) {
77784b7bf493c37236e3fe571aed6105939a9bc0c3Robert Phillips        if (fullScreen) {
78784b7bf493c37236e3fe571aed6105939a9bc0c3Robert Phillips            fClip.disableScissor();
79784b7bf493c37236e3fe571aed6105939a9bc0c3Robert Phillips        }
80784b7bf493c37236e3fe571aed6105939a9bc0c3Robert Phillips        this->setBounds(SkRect::Make(rect), HasAABloat::kNo, IsZeroArea::kNo);
81784b7bf493c37236e3fe571aed6105939a9bc0c3Robert Phillips    }
82784b7bf493c37236e3fe571aed6105939a9bc0c3Robert Phillips
8325a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
84e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        // This could be much more complicated. Currently we look at cases where the new clear
85e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        // contains the old clear, or when the new clear is a subset of the old clear and is the
86e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        // same color.
877dae46a6783de5f6bc461870306eb7d648386980Brian Salomon        GrClearOp* cb = t->cast<GrClearOp>();
88e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        SkASSERT(cb->fRenderTarget == fRenderTarget);
899a7677273a3f270e6137d396e972c83c036a47a7Brian Salomon        if (fClip.windowRectsState() != cb->fClip.windowRectsState()) {
90bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton            return false;
91bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton        }
9229df76096fd30941086324902a82656df2d8becdcsmartdalton        if (cb->contains(this)) {
9329df76096fd30941086324902a82656df2d8becdcsmartdalton            fClip = cb->fClip;
9488cf17d099085b8085ab11571b5094163dbb2c84bsalomon            this->replaceBounds(*t);
95e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon            fColor = cb->fColor;
96e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon            return true;
9729df76096fd30941086324902a82656df2d8becdcsmartdalton        } else if (cb->fColor == fColor && this->contains(cb)) {
98e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon            return true;
99e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon        }
1005346983b2e0726b4009cc546b01c58a8919e6c36bsalomon        return false;
1015346983b2e0726b4009cc546b01c58a8919e6c36bsalomon    }
1025346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
1037dae46a6783de5f6bc461870306eb7d648386980Brian Salomon    bool contains(const GrClearOp* that) const {
10429df76096fd30941086324902a82656df2d8becdcsmartdalton        // The constructor ensures that scissor gets disabled on any clip that fills the entire RT.
10529df76096fd30941086324902a82656df2d8becdcsmartdalton        return !fClip.scissorEnabled() ||
10629df76096fd30941086324902a82656df2d8becdcsmartdalton               (that->fClip.scissorEnabled() &&
10729df76096fd30941086324902a82656df2d8becdcsmartdalton                fClip.scissorRect().contains(that->fClip.scissorRect()));
10829df76096fd30941086324902a82656df2d8becdcsmartdalton    }
10929df76096fd30941086324902a82656df2d8becdcsmartdalton
110742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomon    void onPrepare(GrOpFlushState*) override {}
1115346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
1129e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon    void onExecute(GrOpFlushState* state) override {
113c293a29bc2fced15ac44a66efa813d42cb3f2e0bBrian Salomon        state->commandBuffer()->clear(fRenderTarget.get(), fClip, fColor);
1145346983b2e0726b4009cc546b01c58a8919e6c36bsalomon    }
1155346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
11629df76096fd30941086324902a82656df2d8becdcsmartdalton    GrFixedClip                                             fClip;
1175346983b2e0726b4009cc546b01c58a8919e6c36bsalomon    GrColor                                                 fColor;
1185346983b2e0726b4009cc546b01c58a8919e6c36bsalomon    GrPendingIOResource<GrRenderTarget, kWrite_GrIOType>    fRenderTarget;
1191b55a963a2374a14bb82eb887bb99ee91680f0ebreed
12025a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    typedef GrOp INHERITED;
1215346983b2e0726b4009cc546b01c58a8919e6c36bsalomon};
1225346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
1235346983b2e0726b4009cc546b01c58a8919e6c36bsalomon#endif
124