Index: src/core/SkRemote.h |
diff --git a/src/core/SkRemote.h b/src/core/SkRemote.h |
index 72914d438255b6ff8542b7e7fb0ccbf504d25984..ed99c0f8661335b8b5fbb87387c665bc3a3130a8 100644 |
--- a/src/core/SkRemote.h |
+++ b/src/core/SkRemote.h |
@@ -45,6 +45,7 @@ namespace SkRemote { |
virtual void define(ID, const Misc&) = 0; |
virtual void define(ID, const SkPath&) = 0; |
virtual void define(ID, const Stroke&) = 0; |
+ virtual void define(ID, SkXfermode*) = 0; |
virtual void undefine(ID) = 0; |
@@ -53,24 +54,37 @@ namespace SkRemote { |
virtual void setMatrix(ID matrix) = 0; |
- virtual void clipPath(ID path, SkRegion::Op, bool aa) = 0; |
- virtual void fillPath(ID path, ID misc) = 0; |
- virtual void strokePath(ID path, ID misc, ID stroke) = 0; |
+ // TODO: struct CommonIDs { ID misc; ID xfermode; ... } |
+ // for IDs that affect both fill + stroke? |
+ |
+ virtual void clipPath(ID path, SkRegion::Op, bool aa) = 0; |
+ virtual void fillPath(ID path, ID misc, ID xfermode) = 0; |
+ virtual void strokePath(ID path, ID misc, ID xfermode, ID stroke) = 0; |
}; |
class LookupScope; |
- // TODO: document |
+ // The Cache interface encapsulates the caching logic of the Client. |
+ // |
+ // Each lookup() method must always fill ID* with a valid value, |
+ // but ID may be cached. If so, the lookup() method returns true; |
+ // if not the lookup() method returns false and the Client must |
+ // then define() this ID -> Thing mapping before using the ID. |
+ // |
+ // The Caches may also add IDs to the LookupScope's list of IDs to |
+ // undefine() on destruction. This lets the Cache purge IDs. |
struct Cache { |
virtual ~Cache() {} |
- static Cache* CreateNeverCache(); |
- static Cache* CreateAlwaysCache(); |
+ static Cache* CreateNeverCache(); // Never caches anything. |
+ static Cache* CreateAlwaysCache(); // Caches by value (not deep pointer equality). |
+ // TODO: static Cache* CreateDeepCache(); // Caches by deep value. |
- virtual bool lookup(const SkMatrix&, ID*, LookupScope*) = 0; |
- virtual bool lookup(const Misc&, ID*, LookupScope*) = 0; |
- virtual bool lookup(const SkPath&, ID*, LookupScope*) = 0; |
- virtual bool lookup(const Stroke&, ID*, LookupScope*) = 0; |
+ virtual bool lookup(const SkMatrix&, ID*, LookupScope*) = 0; |
+ virtual bool lookup(const Misc&, ID*, LookupScope*) = 0; |
+ virtual bool lookup(const SkPath&, ID*, LookupScope*) = 0; |
+ virtual bool lookup(const Stroke&, ID*, LookupScope*) = 0; |
+ virtual bool lookup(const SkXfermode*, ID*, LookupScope*) = 0; |
virtual void cleanup(Encoder*) = 0; |
}; |
@@ -120,6 +134,7 @@ namespace SkRemote { |
void define(ID, const Misc&) override; |
void define(ID, const SkPath&) override; |
void define(ID, const Stroke&) override; |
+ void define(ID, SkXfermode*) override; |
void undefine(ID) override; |
@@ -128,13 +143,19 @@ namespace SkRemote { |
void setMatrix(ID matrix) override; |
- void clipPath(ID path, SkRegion::Op, bool aa) override; |
- void fillPath(ID path, ID misc) override; |
- void strokePath(ID path, ID misc, ID stroke) override; |
+ void clipPath(ID path, SkRegion::Op, bool aa) override; |
+ void fillPath(ID path, ID misc, ID xfermode) override; |
+ void strokePath(ID path, ID misc, ID xfermode, ID stroke) override; |
+ // Maps ID -> T. |
template <typename T, Type kType> |
class IDMap { |
public: |
+ ~IDMap() { |
+ // A well-behaved client always cleans up its definitions. |
+ SkASSERT(fMap.count() == 0); |
+ } |
+ |
void set(const ID& id, const T& val) { |
SkASSERT(id.type() == kType); |
fMap.set(id, val); |
@@ -156,10 +177,48 @@ namespace SkRemote { |
SkTHashMap<ID, T> fMap; |
}; |
- IDMap<SkMatrix, Type::kMatrix> fMatrix; |
- IDMap<Misc , Type::kMisc > fMisc; |
- IDMap<SkPath , Type::kPath > fPath; |
- IDMap<Stroke , Type::kStroke> fStroke; |
+ // Maps ID -> T*, and keeps the T alive by reffing it. |
+ template <typename T, Type kType> |
+ class ReffedIDMap { |
+ public: |
+ ReffedIDMap() { |
+ // A null ID always maps to nullptr. |
+ fMap.set(ID(kType), nullptr); |
+ } |
+ ~ReffedIDMap() { |
+ // A well-behaved client always cleans up its definitions. |
+ SkASSERT(fMap.count() == 1); |
+ } |
+ |
+ void set(const ID& id, T* val) { |
+ SkASSERT(id.type() == kType && val); |
+ fMap.set(id, SkRef(val)); |
+ } |
+ |
+ void remove(const ID& id) { |
+ SkASSERT(id.type() == kType); |
+ T** val = fMap.find(id); |
+ SkASSERT(val && *val); |
+ (*val)->unref(); |
+ fMap.remove(id); |
+ } |
+ |
+ T* find(const ID& id) const { |
+ SkASSERT(id.type() == kType); |
+ T** val = fMap.find(id); |
+ SkASSERT(val); |
+ return *val; |
+ } |
+ |
+ private: |
+ SkTHashMap<ID, T*> fMap; |
+ }; |
+ |
+ IDMap<SkMatrix, Type::kMatrix> fMatrix; |
+ IDMap<Misc , Type::kMisc > fMisc; |
+ IDMap<SkPath , Type::kPath > fPath; |
+ IDMap<Stroke , Type::kStroke> fStroke; |
+ ReffedIDMap<SkXfermode, Type::kXfermode> fXfermode; |
SkCanvas* fCanvas; |
}; |