GrOp.h revision 178ce3eddd326feee608af65cdeedb08e1af91c3
14d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt/*
24d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * Copyright 2015 Google Inc.
34d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt *
44d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * Use of this source code is governed by a BSD-style license that can be
54d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * found in the LICENSE file.
64d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt */
74d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
853e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon#ifndef GrOp_DEFINED
953e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon#define GrOp_DEFINED
104d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
112c4bd0798e929acb9663668985eabe74d7378c46bungeman#include "../private/SkAtomics.h"
12294870ff119b89fc902773643b054f14e5d1f554Robert Phillips#include "GrGpuResource.h"
13dbe1e6f0c32bd07b7669b1b1ac3c7f58c9b8d773joshualitt#include "GrNonAtomicRef.h"
1454d212e1bfaea0be88c3c40820d0b1ae0daebecfBrian Salomon#include "GrXferProcessor.h"
1588cf17d099085b8085ab11571b5094163dbb2c84bsalomon#include "SkMatrix.h"
1616b991390bb988b194a868ab8de66db4c21c7c13bsalomon#include "SkRect.h"
175346983b2e0726b4009cc546b01c58a8919e6c36bsalomon#include "SkString.h"
184d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
192c4bd0798e929acb9663668985eabe74d7378c46bungeman#include <new>
202c4bd0798e929acb9663668985eabe74d7378c46bungeman
2116b991390bb988b194a868ab8de66db4c21c7c13bsalomonclass GrCaps;
229cb6340a62a5d748e4189d50e51fa527c8c80c03egdanielclass GrGpuCommandBuffer;
23742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomonclass GrOpFlushState;
244d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
25abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon/**
2653e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon * GrOp is the base class for all Ganesh deferred GPU operations. To facilitate reordering and to
2753e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon * minimize draw calls, Ganesh does not generate geometry inline with draw calls. Instead, it
2853e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon * captures the arguments to the draw and then generates the geometry when flushing. This gives GrOp
2953e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon * subclasses complete freedom to decide how/when to combine in order to produce fewer draw calls
3053e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon * and minimize state changes.
314d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt *
3225a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * Ops of the same subclass may be merged using combineIfPossible. When two ops merge, one
3325a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * takes on the union of the data and the other is left empty. The merged op becomes responsible
3425a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * for drawing the data from both the original ops.
354d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt *
364d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * If there are any possible optimizations which might require knowing more about the full state of
3725a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * the draw, e.g. whether or not the GrOp is allowed to tweak alpha for coverage, then this
3825a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * information will be communicated to the GrOp prior to geometry generation.
39db4758c75fdd30ef58096c685e2d749aacaf3d92bsalomon *
4025a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * The bounds of the op must contain all the vertices in device space *irrespective* of the clip.
41db4758c75fdd30ef58096c685e2d749aacaf3d92bsalomon * The bounds are used in determining which clip elements must be applied and thus the bounds cannot
42db4758c75fdd30ef58096c685e2d749aacaf3d92bsalomon * in turn depend upon the clip.
434d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt */
4425a880960a9a689a745a01071ecba3fe494b5940Brian Salomon#define GR_OP_SPEW 0
4525a880960a9a689a745a01071ecba3fe494b5940Brian Salomon#if GR_OP_SPEW
4625a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    #define GrOP_SPEW(code) code
4725a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    #define GrOP_INFO(...) SkDebugf(__VA_ARGS__)
48ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt#else
4925a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    #define GrOP_SPEW(code)
5025a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    #define GrOP_INFO(...)
51ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt#endif
524d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
531b55a963a2374a14bb82eb887bb99ee91680f0ebreed// A helper macro to generate a class static id
5425a880960a9a689a745a01071ecba3fe494b5940Brian Salomon#define DEFINE_OP_CLASS_ID \
551b55a963a2374a14bb82eb887bb99ee91680f0ebreed    static uint32_t ClassID() { \
5625a880960a9a689a745a01071ecba3fe494b5940Brian Salomon        static uint32_t kClassID = GenOpClassID(); \
571b55a963a2374a14bb82eb887bb99ee91680f0ebreed        return kClassID; \
581b55a963a2374a14bb82eb887bb99ee91680f0ebreed    }
591b55a963a2374a14bb82eb887bb99ee91680f0ebreed
60f8334781914363caf537f22f012fcd5c03c60dadBrian Salomonclass GrOp : private SkNoncopyable {
614d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualittpublic:
6225a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    GrOp(uint32_t classID);
6325a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    virtual ~GrOp();
644d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
654d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    virtual const char* name() const = 0;
664d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
6725a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    bool combineIfPossible(GrOp* that, const GrCaps& caps) {
684d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt        if (this->classID() != that->classID()) {
694d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt            return false;
704d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt        }
714d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
72cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon        return this->onCombineIfPossible(that, caps);
734d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    }
744d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
7588cf17d099085b8085ab11571b5094163dbb2c84bsalomon    const SkRect& bounds() const {
7688cf17d099085b8085ab11571b5094163dbb2c84bsalomon        SkASSERT(kUninitialized_BoundsFlag != fBoundsFlags);
7788cf17d099085b8085ab11571b5094163dbb2c84bsalomon        return fBounds;
7888cf17d099085b8085ab11571b5094163dbb2c84bsalomon    }
7988cf17d099085b8085ab11571b5094163dbb2c84bsalomon
809e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon    void setClippedBounds(const SkRect& clippedBounds) {
819e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon        fBounds = clippedBounds;
829e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon        // The clipped bounds already incorporate any effect of the bounds flags.
839e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon        fBoundsFlags = 0;
849e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon    }
859e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon
8688cf17d099085b8085ab11571b5094163dbb2c84bsalomon    bool hasAABloat() const {
8788cf17d099085b8085ab11571b5094163dbb2c84bsalomon        SkASSERT(fBoundsFlags != kUninitialized_BoundsFlag);
8888cf17d099085b8085ab11571b5094163dbb2c84bsalomon        return SkToBool(fBoundsFlags & kAABloat_BoundsFlag);
8988cf17d099085b8085ab11571b5094163dbb2c84bsalomon    }
9088cf17d099085b8085ab11571b5094163dbb2c84bsalomon
9188cf17d099085b8085ab11571b5094163dbb2c84bsalomon    bool hasZeroArea() const {
9288cf17d099085b8085ab11571b5094163dbb2c84bsalomon        SkASSERT(fBoundsFlags != kUninitialized_BoundsFlag);
9388cf17d099085b8085ab11571b5094163dbb2c84bsalomon        return SkToBool(fBoundsFlags & kZeroArea_BoundsFlag);
9488cf17d099085b8085ab11571b5094163dbb2c84bsalomon    }
9599c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt
964d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    void* operator new(size_t size);
974d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    void operator delete(void* target);
984d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
994d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    void* operator new(size_t size, void* placement) {
1004d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt        return ::operator new(size, placement);
1014d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    }
1024d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    void operator delete(void* target, void* placement) {
1034d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt        ::operator delete(target, placement);
1044d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    }
1054d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
1064d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    /**
10725a880960a9a689a745a01071ecba3fe494b5940Brian Salomon     * Helper for safely down-casting to a GrOp subclass
108abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon     */
1091b55a963a2374a14bb82eb887bb99ee91680f0ebreed    template <typename T> const T& cast() const {
1101b55a963a2374a14bb82eb887bb99ee91680f0ebreed        SkASSERT(T::ClassID() == this->classID());
1111b55a963a2374a14bb82eb887bb99ee91680f0ebreed        return *static_cast<const T*>(this);
1121b55a963a2374a14bb82eb887bb99ee91680f0ebreed    }
1131b55a963a2374a14bb82eb887bb99ee91680f0ebreed
1141b55a963a2374a14bb82eb887bb99ee91680f0ebreed    template <typename T> T* cast() {
1151b55a963a2374a14bb82eb887bb99ee91680f0ebreed        SkASSERT(T::ClassID() == this->classID());
1161b55a963a2374a14bb82eb887bb99ee91680f0ebreed        return static_cast<T*>(this);
1171b55a963a2374a14bb82eb887bb99ee91680f0ebreed    }
1184d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
11925a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    uint32_t classID() const { SkASSERT(kIllegalOpID != fClassID); return fClassID; }
1204d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
12108e65e718a3464a594e6dfca0351dfed19ac2445joshualitt    // We lazily initialize the uniqueID because currently the only user is GrAuditTrail
1229d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    uint32_t uniqueID() const {
12325a880960a9a689a745a01071ecba3fe494b5940Brian Salomon        if (kIllegalOpID == fUniqueID) {
12425a880960a9a689a745a01071ecba3fe494b5940Brian Salomon            fUniqueID = GenOpID();
12508e65e718a3464a594e6dfca0351dfed19ac2445joshualitt        }
1269d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary        return fUniqueID;
12708e65e718a3464a594e6dfca0351dfed19ac2445joshualitt    }
128ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt
129bde428513ff3bd98a3d4f1c66ac779411233f817Brian Salomon    /**
130d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon     * This is called to notify the op that it has been recorded into a GrOpList. Ops can use this
131d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon     * to begin preparations for the flush of the op list. Note that the op still may either be
132d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon     * combined into another op or have another op combined into it via combineIfPossible() after
133d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon     * this call is made.
134d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon     */
135d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon    virtual void wasRecorded() {}
136d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon
137d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon    /**
138bde428513ff3bd98a3d4f1c66ac779411233f817Brian Salomon     * Called prior to executing. The op should perform any resource creation or data transfers
139bde428513ff3bd98a3d4f1c66ac779411233f817Brian Salomon     * necessary before execute() is called.
140bde428513ff3bd98a3d4f1c66ac779411233f817Brian Salomon     */
141742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomon    void prepare(GrOpFlushState* state) { this->onPrepare(state); }
1425346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
14325a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    /** Issues the op's commands to GrGpu. */
1449e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon    void execute(GrOpFlushState* state) { this->onExecute(state); }
1455346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
14625a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    /** Used for spewing information about ops when debugging. */
14744fbc79e069c28103a44387d11c62e049ef2967drobertphillips    virtual SkString dumpInfo() const {
14844fbc79e069c28103a44387d11c62e049ef2967drobertphillips        SkString string;
14925a880960a9a689a745a01071ecba3fe494b5940Brian Salomon        string.appendf("OpBounds: [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n",
15044fbc79e069c28103a44387d11c62e049ef2967drobertphillips                       fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom);
15144fbc79e069c28103a44387d11c62e049ef2967drobertphillips        return string;
15244fbc79e069c28103a44387d11c62e049ef2967drobertphillips    }
1535346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
154178ce3eddd326feee608af65cdeedb08e1af91c3Robert Phillips    virtual bool needsCommandBufferIsolation() const { return false; }
155178ce3eddd326feee608af65cdeedb08e1af91c3Robert Phillips
1564d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualittprotected:
15788cf17d099085b8085ab11571b5094163dbb2c84bsalomon    /**
15825a880960a9a689a745a01071ecba3fe494b5940Brian Salomon     * Indicates that the op will produce geometry that extends beyond its bounds for the
15988cf17d099085b8085ab11571b5094163dbb2c84bsalomon     * purpose of ensuring that the fragment shader runs on partially covered pixels for
16088cf17d099085b8085ab11571b5094163dbb2c84bsalomon     * non-MSAA antialiasing.
16188cf17d099085b8085ab11571b5094163dbb2c84bsalomon     */
16288cf17d099085b8085ab11571b5094163dbb2c84bsalomon    enum class HasAABloat {
16388cf17d099085b8085ab11571b5094163dbb2c84bsalomon        kYes,
16488cf17d099085b8085ab11571b5094163dbb2c84bsalomon        kNo
16588cf17d099085b8085ab11571b5094163dbb2c84bsalomon    };
16688cf17d099085b8085ab11571b5094163dbb2c84bsalomon    /**
16725a880960a9a689a745a01071ecba3fe494b5940Brian Salomon     * Indicates that the geometry represented by the op has zero area (e.g. it is hairline or
16825a880960a9a689a745a01071ecba3fe494b5940Brian Salomon     * points).
16988cf17d099085b8085ab11571b5094163dbb2c84bsalomon     */
17088cf17d099085b8085ab11571b5094163dbb2c84bsalomon    enum class IsZeroArea {
17188cf17d099085b8085ab11571b5094163dbb2c84bsalomon        kYes,
17288cf17d099085b8085ab11571b5094163dbb2c84bsalomon        kNo
17388cf17d099085b8085ab11571b5094163dbb2c84bsalomon    };
17488cf17d099085b8085ab11571b5094163dbb2c84bsalomon    void setBounds(const SkRect& newBounds, HasAABloat aabloat, IsZeroArea zeroArea) {
17588cf17d099085b8085ab11571b5094163dbb2c84bsalomon        fBounds = newBounds;
17688cf17d099085b8085ab11571b5094163dbb2c84bsalomon        this->setBoundsFlags(aabloat, zeroArea);
17788cf17d099085b8085ab11571b5094163dbb2c84bsalomon    }
17888cf17d099085b8085ab11571b5094163dbb2c84bsalomon    void setTransformedBounds(const SkRect& srcBounds, const SkMatrix& m,
17988cf17d099085b8085ab11571b5094163dbb2c84bsalomon                              HasAABloat aabloat, IsZeroArea zeroArea) {
18088cf17d099085b8085ab11571b5094163dbb2c84bsalomon        m.mapRect(&fBounds, srcBounds);
18188cf17d099085b8085ab11571b5094163dbb2c84bsalomon        this->setBoundsFlags(aabloat, zeroArea);
18288cf17d099085b8085ab11571b5094163dbb2c84bsalomon    }
18399c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt
18425a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    void joinBounds(const GrOp& that) {
18588cf17d099085b8085ab11571b5094163dbb2c84bsalomon        if (that.hasAABloat()) {
18688cf17d099085b8085ab11571b5094163dbb2c84bsalomon            fBoundsFlags |= kAABloat_BoundsFlag;
18788cf17d099085b8085ab11571b5094163dbb2c84bsalomon        }
18888cf17d099085b8085ab11571b5094163dbb2c84bsalomon        if (that.hasZeroArea()) {
18988cf17d099085b8085ab11571b5094163dbb2c84bsalomon            fBoundsFlags |= kZeroArea_BoundsFlag;
19088cf17d099085b8085ab11571b5094163dbb2c84bsalomon        }
19188cf17d099085b8085ab11571b5094163dbb2c84bsalomon        return fBounds.joinPossiblyEmptyRect(that.fBounds);
19299c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt    }
19399c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt
19425a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    void replaceBounds(const GrOp& that) {
19588cf17d099085b8085ab11571b5094163dbb2c84bsalomon        fBounds = that.fBounds;
19688cf17d099085b8085ab11571b5094163dbb2c84bsalomon        fBoundsFlags = that.fBoundsFlags;
19788cf17d099085b8085ab11571b5094163dbb2c84bsalomon    }
1981b55a963a2374a14bb82eb887bb99ee91680f0ebreed
19925a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    static uint32_t GenOpClassID() { return GenID(&gCurrOpClassID); }
200abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon
201abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonprivate:
20225a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    virtual bool onCombineIfPossible(GrOp*, const GrCaps& caps) = 0;
203abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon
204742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomon    virtual void onPrepare(GrOpFlushState*) = 0;
2059e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon    virtual void onExecute(GrOpFlushState*) = 0;
2065346983b2e0726b4009cc546b01c58a8919e6c36bsalomon
207abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon    static uint32_t GenID(int32_t* idCounter) {
2081b55a963a2374a14bb82eb887bb99ee91680f0ebreed        // The atomic inc returns the old value not the incremented value. So we add
209abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon        // 1 to the returned value.
210abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon        uint32_t id = static_cast<uint32_t>(sk_atomic_inc(idCounter)) + 1;
211abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon        if (!id) {
21225a880960a9a689a745a01071ecba3fe494b5940Brian Salomon            SkFAIL("This should never wrap as it should only be called once for each GrOp "
213abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon                   "subclass.");
214abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon        }
215abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon        return id;
216abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon    }
217abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon
21888cf17d099085b8085ab11571b5094163dbb2c84bsalomon    void setBoundsFlags(HasAABloat aabloat, IsZeroArea zeroArea) {
21988cf17d099085b8085ab11571b5094163dbb2c84bsalomon        fBoundsFlags = 0;
22088cf17d099085b8085ab11571b5094163dbb2c84bsalomon        fBoundsFlags |= (HasAABloat::kYes == aabloat) ? kAABloat_BoundsFlag : 0;
22188cf17d099085b8085ab11571b5094163dbb2c84bsalomon        fBoundsFlags |= (IsZeroArea ::kYes == zeroArea) ? kZeroArea_BoundsFlag : 0;
22288cf17d099085b8085ab11571b5094163dbb2c84bsalomon    }
22388cf17d099085b8085ab11571b5094163dbb2c84bsalomon
224abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon    enum {
22525a880960a9a689a745a01071ecba3fe494b5940Brian Salomon        kIllegalOpID = 0,
226abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon    };
227abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon
22888cf17d099085b8085ab11571b5094163dbb2c84bsalomon    enum BoundsFlags {
22988cf17d099085b8085ab11571b5094163dbb2c84bsalomon        kAABloat_BoundsFlag                     = 0x1,
23088cf17d099085b8085ab11571b5094163dbb2c84bsalomon        kZeroArea_BoundsFlag                    = 0x2,
23188cf17d099085b8085ab11571b5094163dbb2c84bsalomon        SkDEBUGCODE(kUninitialized_BoundsFlag   = 0x4)
23288cf17d099085b8085ab11571b5094163dbb2c84bsalomon    };
23388cf17d099085b8085ab11571b5094163dbb2c84bsalomon
23488cf17d099085b8085ab11571b5094163dbb2c84bsalomon    const uint16_t                      fClassID;
23588cf17d099085b8085ab11571b5094163dbb2c84bsalomon    uint16_t                            fBoundsFlags;
23688cf17d099085b8085ab11571b5094163dbb2c84bsalomon
23725a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    static uint32_t GenOpID() { return GenID(&gCurrOpUniqueID); }
23808e65e718a3464a594e6dfca0351dfed19ac2445joshualitt    mutable uint32_t                    fUniqueID;
23988cf17d099085b8085ab11571b5094163dbb2c84bsalomon    SkRect                              fBounds;
24088cf17d099085b8085ab11571b5094163dbb2c84bsalomon
24125a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    static int32_t                      gCurrOpUniqueID;
24225a880960a9a689a745a01071ecba3fe494b5940Brian Salomon    static int32_t                      gCurrOpClassID;
243abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon};
244abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon
2454d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt#endif
246