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