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; 24e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillipsclass GrRenderTargetOpList; 254d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 26abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon/** 2753e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon * GrOp is the base class for all Ganesh deferred GPU operations. To facilitate reordering and to 2853e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon * minimize draw calls, Ganesh does not generate geometry inline with draw calls. Instead, it 2953e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon * captures the arguments to the draw and then generates the geometry when flushing. This gives GrOp 3053e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon * subclasses complete freedom to decide how/when to combine in order to produce fewer draw calls 3153e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon * and minimize state changes. 324d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * 3325a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * Ops of the same subclass may be merged using combineIfPossible. When two ops merge, one 3425a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * takes on the union of the data and the other is left empty. The merged op becomes responsible 3525a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * for drawing the data from both the original ops. 364d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * 374d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt * If there are any possible optimizations which might require knowing more about the full state of 3825a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * the draw, e.g. whether or not the GrOp is allowed to tweak alpha for coverage, then this 3925a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * information will be communicated to the GrOp prior to geometry generation. 40db4758c75fdd30ef58096c685e2d749aacaf3d92bsalomon * 4125a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * The bounds of the op must contain all the vertices in device space *irrespective* of the clip. 42db4758c75fdd30ef58096c685e2d749aacaf3d92bsalomon * The bounds are used in determining which clip elements must be applied and thus the bounds cannot 43db4758c75fdd30ef58096c685e2d749aacaf3d92bsalomon * in turn depend upon the clip. 444d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt */ 4525a880960a9a689a745a01071ecba3fe494b5940Brian Salomon#define GR_OP_SPEW 0 4625a880960a9a689a745a01071ecba3fe494b5940Brian Salomon#if GR_OP_SPEW 4725a880960a9a689a745a01071ecba3fe494b5940Brian Salomon #define GrOP_SPEW(code) code 4825a880960a9a689a745a01071ecba3fe494b5940Brian Salomon #define GrOP_INFO(...) SkDebugf(__VA_ARGS__) 49ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt#else 5025a880960a9a689a745a01071ecba3fe494b5940Brian Salomon #define GrOP_SPEW(code) 5125a880960a9a689a745a01071ecba3fe494b5940Brian Salomon #define GrOP_INFO(...) 52ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt#endif 534d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 541b55a963a2374a14bb82eb887bb99ee91680f0ebreed// A helper macro to generate a class static id 5525a880960a9a689a745a01071ecba3fe494b5940Brian Salomon#define DEFINE_OP_CLASS_ID \ 561b55a963a2374a14bb82eb887bb99ee91680f0ebreed static uint32_t ClassID() { \ 5725a880960a9a689a745a01071ecba3fe494b5940Brian Salomon static uint32_t kClassID = GenOpClassID(); \ 581b55a963a2374a14bb82eb887bb99ee91680f0ebreed return kClassID; \ 591b55a963a2374a14bb82eb887bb99ee91680f0ebreed } 601b55a963a2374a14bb82eb887bb99ee91680f0ebreed 61f8334781914363caf537f22f012fcd5c03c60dadBrian Salomonclass GrOp : private SkNoncopyable { 624d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualittpublic: 6325a880960a9a689a745a01071ecba3fe494b5940Brian Salomon GrOp(uint32_t classID); 6425a880960a9a689a745a01071ecba3fe494b5940Brian Salomon virtual ~GrOp(); 654d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 664d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt virtual const char* name() const = 0; 674d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 6825a880960a9a689a745a01071ecba3fe494b5940Brian Salomon bool combineIfPossible(GrOp* that, const GrCaps& caps) { 694d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt if (this->classID() != that->classID()) { 704d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt return false; 714d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt } 724d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 73cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon return this->onCombineIfPossible(that, caps); 744d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt } 754d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 7688cf17d099085b8085ab11571b5094163dbb2c84bsalomon const SkRect& bounds() const { 7788cf17d099085b8085ab11571b5094163dbb2c84bsalomon SkASSERT(kUninitialized_BoundsFlag != fBoundsFlags); 7888cf17d099085b8085ab11571b5094163dbb2c84bsalomon return fBounds; 7988cf17d099085b8085ab11571b5094163dbb2c84bsalomon } 8088cf17d099085b8085ab11571b5094163dbb2c84bsalomon 819e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon void setClippedBounds(const SkRect& clippedBounds) { 829e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon fBounds = clippedBounds; 839e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon // The clipped bounds already incorporate any effect of the bounds flags. 849e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon fBoundsFlags = 0; 859e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon } 869e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon 8788cf17d099085b8085ab11571b5094163dbb2c84bsalomon bool hasAABloat() const { 8888cf17d099085b8085ab11571b5094163dbb2c84bsalomon SkASSERT(fBoundsFlags != kUninitialized_BoundsFlag); 8988cf17d099085b8085ab11571b5094163dbb2c84bsalomon return SkToBool(fBoundsFlags & kAABloat_BoundsFlag); 9088cf17d099085b8085ab11571b5094163dbb2c84bsalomon } 9188cf17d099085b8085ab11571b5094163dbb2c84bsalomon 9288cf17d099085b8085ab11571b5094163dbb2c84bsalomon bool hasZeroArea() const { 9388cf17d099085b8085ab11571b5094163dbb2c84bsalomon SkASSERT(fBoundsFlags != kUninitialized_BoundsFlag); 9488cf17d099085b8085ab11571b5094163dbb2c84bsalomon return SkToBool(fBoundsFlags & kZeroArea_BoundsFlag); 9588cf17d099085b8085ab11571b5094163dbb2c84bsalomon } 9699c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 974d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt void* operator new(size_t size); 984d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt void operator delete(void* target); 994d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 1004d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt void* operator new(size_t size, void* placement) { 1014d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt return ::operator new(size, placement); 1024d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt } 1034d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt void operator delete(void* target, void* placement) { 1044d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt ::operator delete(target, placement); 1054d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt } 1064d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 1074d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt /** 10825a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * Helper for safely down-casting to a GrOp subclass 109abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon */ 1101b55a963a2374a14bb82eb887bb99ee91680f0ebreed template <typename T> const T& cast() const { 1111b55a963a2374a14bb82eb887bb99ee91680f0ebreed SkASSERT(T::ClassID() == this->classID()); 1121b55a963a2374a14bb82eb887bb99ee91680f0ebreed return *static_cast<const T*>(this); 1131b55a963a2374a14bb82eb887bb99ee91680f0ebreed } 1141b55a963a2374a14bb82eb887bb99ee91680f0ebreed 1151b55a963a2374a14bb82eb887bb99ee91680f0ebreed template <typename T> T* cast() { 1161b55a963a2374a14bb82eb887bb99ee91680f0ebreed SkASSERT(T::ClassID() == this->classID()); 1171b55a963a2374a14bb82eb887bb99ee91680f0ebreed return static_cast<T*>(this); 1181b55a963a2374a14bb82eb887bb99ee91680f0ebreed } 1194d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 12025a880960a9a689a745a01071ecba3fe494b5940Brian Salomon uint32_t classID() const { SkASSERT(kIllegalOpID != fClassID); return fClassID; } 1214d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt 12208e65e718a3464a594e6dfca0351dfed19ac2445joshualitt // We lazily initialize the uniqueID because currently the only user is GrAuditTrail 1239d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary uint32_t uniqueID() const { 12425a880960a9a689a745a01071ecba3fe494b5940Brian Salomon if (kIllegalOpID == fUniqueID) { 12525a880960a9a689a745a01071ecba3fe494b5940Brian Salomon fUniqueID = GenOpID(); 12608e65e718a3464a594e6dfca0351dfed19ac2445joshualitt } 1279d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary return fUniqueID; 12808e65e718a3464a594e6dfca0351dfed19ac2445joshualitt } 129ca1f07eb5f976a39845721b434b780c5a705f3d9joshualitt 130bde428513ff3bd98a3d4f1c66ac779411233f817Brian Salomon /** 131d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon * This is called to notify the op that it has been recorded into a GrOpList. Ops can use this 132d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon * to begin preparations for the flush of the op list. Note that the op still may either be 133d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon * combined into another op or have another op combined into it via combineIfPossible() after 134d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon * this call is made. 135d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon */ 136e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips virtual void wasRecorded(GrRenderTargetOpList*) {} 137d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon 138d543e0a835002cc423de0d09c86eea99a0c0a2baBrian Salomon /** 139bde428513ff3bd98a3d4f1c66ac779411233f817Brian Salomon * Called prior to executing. The op should perform any resource creation or data transfers 140bde428513ff3bd98a3d4f1c66ac779411233f817Brian Salomon * necessary before execute() is called. 141bde428513ff3bd98a3d4f1c66ac779411233f817Brian Salomon */ 142742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomon void prepare(GrOpFlushState* state) { this->onPrepare(state); } 1435346983b2e0726b4009cc546b01c58a8919e6c36bsalomon 14425a880960a9a689a745a01071ecba3fe494b5940Brian Salomon /** Issues the op's commands to GrGpu. */ 1459e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon void execute(GrOpFlushState* state) { this->onExecute(state); } 1465346983b2e0726b4009cc546b01c58a8919e6c36bsalomon 14725a880960a9a689a745a01071ecba3fe494b5940Brian Salomon /** Used for spewing information about ops when debugging. */ 14844fbc79e069c28103a44387d11c62e049ef2967drobertphillips virtual SkString dumpInfo() const { 14944fbc79e069c28103a44387d11c62e049ef2967drobertphillips SkString string; 15025a880960a9a689a745a01071ecba3fe494b5940Brian Salomon string.appendf("OpBounds: [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", 15144fbc79e069c28103a44387d11c62e049ef2967drobertphillips fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom); 15244fbc79e069c28103a44387d11c62e049ef2967drobertphillips return string; 15344fbc79e069c28103a44387d11c62e049ef2967drobertphillips } 1545346983b2e0726b4009cc546b01c58a8919e6c36bsalomon 155178ce3eddd326feee608af65cdeedb08e1af91c3Robert Phillips virtual bool needsCommandBufferIsolation() const { return false; } 156178ce3eddd326feee608af65cdeedb08e1af91c3Robert Phillips 1574d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualittprotected: 15888cf17d099085b8085ab11571b5094163dbb2c84bsalomon /** 15925a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * Indicates that the op will produce geometry that extends beyond its bounds for the 16088cf17d099085b8085ab11571b5094163dbb2c84bsalomon * purpose of ensuring that the fragment shader runs on partially covered pixels for 16188cf17d099085b8085ab11571b5094163dbb2c84bsalomon * non-MSAA antialiasing. 16288cf17d099085b8085ab11571b5094163dbb2c84bsalomon */ 16388cf17d099085b8085ab11571b5094163dbb2c84bsalomon enum class HasAABloat { 16488cf17d099085b8085ab11571b5094163dbb2c84bsalomon kYes, 16588cf17d099085b8085ab11571b5094163dbb2c84bsalomon kNo 16688cf17d099085b8085ab11571b5094163dbb2c84bsalomon }; 16788cf17d099085b8085ab11571b5094163dbb2c84bsalomon /** 16825a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * Indicates that the geometry represented by the op has zero area (e.g. it is hairline or 16925a880960a9a689a745a01071ecba3fe494b5940Brian Salomon * points). 17088cf17d099085b8085ab11571b5094163dbb2c84bsalomon */ 17188cf17d099085b8085ab11571b5094163dbb2c84bsalomon enum class IsZeroArea { 17288cf17d099085b8085ab11571b5094163dbb2c84bsalomon kYes, 17388cf17d099085b8085ab11571b5094163dbb2c84bsalomon kNo 17488cf17d099085b8085ab11571b5094163dbb2c84bsalomon }; 17588cf17d099085b8085ab11571b5094163dbb2c84bsalomon void setBounds(const SkRect& newBounds, HasAABloat aabloat, IsZeroArea zeroArea) { 17688cf17d099085b8085ab11571b5094163dbb2c84bsalomon fBounds = newBounds; 17788cf17d099085b8085ab11571b5094163dbb2c84bsalomon this->setBoundsFlags(aabloat, zeroArea); 17888cf17d099085b8085ab11571b5094163dbb2c84bsalomon } 17988cf17d099085b8085ab11571b5094163dbb2c84bsalomon void setTransformedBounds(const SkRect& srcBounds, const SkMatrix& m, 18088cf17d099085b8085ab11571b5094163dbb2c84bsalomon HasAABloat aabloat, IsZeroArea zeroArea) { 18188cf17d099085b8085ab11571b5094163dbb2c84bsalomon m.mapRect(&fBounds, srcBounds); 18288cf17d099085b8085ab11571b5094163dbb2c84bsalomon this->setBoundsFlags(aabloat, zeroArea); 18388cf17d099085b8085ab11571b5094163dbb2c84bsalomon } 18499c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 18525a880960a9a689a745a01071ecba3fe494b5940Brian Salomon void joinBounds(const GrOp& that) { 18688cf17d099085b8085ab11571b5094163dbb2c84bsalomon if (that.hasAABloat()) { 18788cf17d099085b8085ab11571b5094163dbb2c84bsalomon fBoundsFlags |= kAABloat_BoundsFlag; 18888cf17d099085b8085ab11571b5094163dbb2c84bsalomon } 18988cf17d099085b8085ab11571b5094163dbb2c84bsalomon if (that.hasZeroArea()) { 19088cf17d099085b8085ab11571b5094163dbb2c84bsalomon fBoundsFlags |= kZeroArea_BoundsFlag; 19188cf17d099085b8085ab11571b5094163dbb2c84bsalomon } 19288cf17d099085b8085ab11571b5094163dbb2c84bsalomon return fBounds.joinPossiblyEmptyRect(that.fBounds); 19399c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt } 19499c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 19525a880960a9a689a745a01071ecba3fe494b5940Brian Salomon void replaceBounds(const GrOp& that) { 19688cf17d099085b8085ab11571b5094163dbb2c84bsalomon fBounds = that.fBounds; 19788cf17d099085b8085ab11571b5094163dbb2c84bsalomon fBoundsFlags = that.fBoundsFlags; 19888cf17d099085b8085ab11571b5094163dbb2c84bsalomon } 1991b55a963a2374a14bb82eb887bb99ee91680f0ebreed 20025a880960a9a689a745a01071ecba3fe494b5940Brian Salomon static uint32_t GenOpClassID() { return GenID(&gCurrOpClassID); } 201abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon 202abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonprivate: 20325a880960a9a689a745a01071ecba3fe494b5940Brian Salomon virtual bool onCombineIfPossible(GrOp*, const GrCaps& caps) = 0; 204abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon 205742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomon virtual void onPrepare(GrOpFlushState*) = 0; 2069e50f7b11e9a9d3dc23c924bbb0f0b85c6f1d6cbBrian Salomon virtual void onExecute(GrOpFlushState*) = 0; 2075346983b2e0726b4009cc546b01c58a8919e6c36bsalomon 208abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon static uint32_t GenID(int32_t* idCounter) { 2091b55a963a2374a14bb82eb887bb99ee91680f0ebreed // The atomic inc returns the old value not the incremented value. So we add 210abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon // 1 to the returned value. 211abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon uint32_t id = static_cast<uint32_t>(sk_atomic_inc(idCounter)) + 1; 212abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon if (!id) { 21325a880960a9a689a745a01071ecba3fe494b5940Brian Salomon SkFAIL("This should never wrap as it should only be called once for each GrOp " 214abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon "subclass."); 215abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon } 216abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon return id; 217abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon } 218abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon 21988cf17d099085b8085ab11571b5094163dbb2c84bsalomon void setBoundsFlags(HasAABloat aabloat, IsZeroArea zeroArea) { 22088cf17d099085b8085ab11571b5094163dbb2c84bsalomon fBoundsFlags = 0; 22188cf17d099085b8085ab11571b5094163dbb2c84bsalomon fBoundsFlags |= (HasAABloat::kYes == aabloat) ? kAABloat_BoundsFlag : 0; 22288cf17d099085b8085ab11571b5094163dbb2c84bsalomon fBoundsFlags |= (IsZeroArea ::kYes == zeroArea) ? kZeroArea_BoundsFlag : 0; 22388cf17d099085b8085ab11571b5094163dbb2c84bsalomon } 22488cf17d099085b8085ab11571b5094163dbb2c84bsalomon 225abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon enum { 22625a880960a9a689a745a01071ecba3fe494b5940Brian Salomon kIllegalOpID = 0, 227abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon }; 228abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon 22988cf17d099085b8085ab11571b5094163dbb2c84bsalomon enum BoundsFlags { 23088cf17d099085b8085ab11571b5094163dbb2c84bsalomon kAABloat_BoundsFlag = 0x1, 23188cf17d099085b8085ab11571b5094163dbb2c84bsalomon kZeroArea_BoundsFlag = 0x2, 23288cf17d099085b8085ab11571b5094163dbb2c84bsalomon SkDEBUGCODE(kUninitialized_BoundsFlag = 0x4) 23388cf17d099085b8085ab11571b5094163dbb2c84bsalomon }; 23488cf17d099085b8085ab11571b5094163dbb2c84bsalomon 23588cf17d099085b8085ab11571b5094163dbb2c84bsalomon const uint16_t fClassID; 23688cf17d099085b8085ab11571b5094163dbb2c84bsalomon uint16_t fBoundsFlags; 23788cf17d099085b8085ab11571b5094163dbb2c84bsalomon 23825a880960a9a689a745a01071ecba3fe494b5940Brian Salomon static uint32_t GenOpID() { return GenID(&gCurrOpUniqueID); } 23908e65e718a3464a594e6dfca0351dfed19ac2445joshualitt mutable uint32_t fUniqueID; 24088cf17d099085b8085ab11571b5094163dbb2c84bsalomon SkRect fBounds; 24188cf17d099085b8085ab11571b5094163dbb2c84bsalomon 24225a880960a9a689a745a01071ecba3fe494b5940Brian Salomon static int32_t gCurrOpUniqueID; 24325a880960a9a689a745a01071ecba3fe494b5940Brian Salomon static int32_t gCurrOpClassID; 244abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon}; 245abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon 2464d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt#endif 247