diff options
Diffstat (limited to 'src/core/SkRemote.cpp')
-rw-r--r-- | src/core/SkRemote.cpp | 284 |
1 files changed, 109 insertions, 175 deletions
diff --git a/src/core/SkRemote.cpp b/src/core/SkRemote.cpp index 7c662d3233..21fbdf3d97 100644 --- a/src/core/SkRemote.cpp +++ b/src/core/SkRemote.cpp @@ -72,210 +72,141 @@ namespace SkRemote { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // - class LookupScope { + class CachingEncoder final : public Encoder { public: - LookupScope(Cache* cache, Encoder* encoder) : fCache(cache), fEncoder(encoder) {} - ~LookupScope() { for (ID id : fToUndefine) { fEncoder->undefine(id); } } - void undefineWhenDone(ID id) { fToUndefine.push_back(id); } - - template <typename T> - ID lookup(const T& val) { - ID id; - if (!fCache->lookup(val, &id, this)) { - fEncoder->define(id, val); - } - return id; - } + explicit CachingEncoder(Encoder* wrapped) : fWrapped(wrapped) {} private: - Cache* fCache; - Encoder* fEncoder; - SkSTArray<4, ID> fToUndefine; - }; + struct Undef { + Encoder* fEncoder; + template <typename T> + void operator()(const T&, ID* id) const { fEncoder->undefine(*id); } + }; + ~CachingEncoder() override { + Undef undef{fWrapped}; + fMatrix .foreach(undef); + fMisc .foreach(undef); + fPath .foreach(undef); + fStroke .foreach(undef); + fShader .foreach(undef); + fXfermode.foreach(undef); + } - Cache* Cache::CreateNeverCache() { - struct NeverCache final : public Cache { - NeverCache() - : fNextMatrix (Type::kMatrix) - , fNextMisc (Type::kMisc) - , fNextPath (Type::kPath) - , fNextStroke (Type::kStroke) - , fNextShader (Type::kShader) - , fNextXfermode(Type::kXfermode) - {} - void cleanup(Encoder*) override {} - - static bool Helper(ID* next, ID* id, LookupScope* ls) { - *id = ++(*next); - ls->undefineWhenDone(*id); - return false; + template <typename Map, typename T> + ID define(Map* map, const T& v) { + if (const ID* id = map->find(v)) { + return *id; } + ID id = fWrapped->define(v); + map->set(v, id); + return id; + } - bool lookup(const SkMatrix&, ID* id, LookupScope* ls) override { - return Helper(&fNextMatrix, id, ls); - } - bool lookup(const Misc&, ID* id, LookupScope* ls) override { - return Helper(&fNextMisc, id, ls); - } - bool lookup(const SkPath&, ID* id, LookupScope* ls) override { - return Helper(&fNextPath, id, ls); - } - bool lookup(const Stroke&, ID* id, LookupScope* ls) override { - return Helper(&fNextStroke, id, ls); - } - bool lookup(const SkShader* shader, ID* id, LookupScope* ls) override { - if (!shader) { - *id = ID(Type::kShader); - return true; // Null IDs are always defined. - } - return Helper(&fNextShader, id, ls); - } - bool lookup(const SkXfermode* xfermode, ID* id, LookupScope* ls) override { - if (!xfermode) { - *id = ID(Type::kXfermode); - return true; // Null IDs are always defined. - } - return Helper(&fNextXfermode, id, ls); - } + ID define(const SkMatrix& v) override { return this->define(&fMatrix, v); } + ID define(const Misc& v) override { return this->define(&fMisc, v); } + ID define(const SkPath& v) override { return this->define(&fPath, v); } + ID define(const Stroke& v) override { return this->define(&fStroke, v); } + ID define(SkShader* v) override { return this->define(&fShader, v); } + ID define(SkXfermode* v) override { return this->define(&fXfermode, v); } - ID fNextMatrix, - fNextMisc, - fNextPath, - fNextStroke, - fNextShader, - fNextXfermode; - }; - return new NeverCache; - } + void undefine(ID) override {} - // These can't be declared locally inside AlwaysCache because of the templating. :( - namespace { - template <typename T, typename Map> - static bool always_cache_lookup(const T& val, Map* map, ID* next, ID* id) { - if (const ID* found = map->find(val)) { - *id = *found; - return true; - } - *id = ++(*next); - map->set(val, *id); - return false; - } + void save() override { fWrapped-> save(); } + void restore() override { fWrapped->restore(); } - struct Undefiner { - Encoder* fEncoder; + void setMatrix(ID matrix) override { fWrapped->setMatrix(matrix); } - template <typename T> - void operator()(const T&, ID* id) const { fEncoder->undefine(*id); } - }; + void clipPath(ID path, SkRegion::Op op, bool aa) override { + fWrapped->clipPath(path, op, aa); + } + void fillPath(ID path, ID misc, ID shader, ID xfermode) override { + fWrapped->fillPath(path, misc, shader, xfermode); + } + void strokePath(ID path, ID misc, ID shader, ID xfermode, ID stroke) override { + fWrapped->strokePath(path, misc, shader, xfermode, stroke); + } - // Maps const T* -> ID, and refs the key. nullptr always maps to ID(kType). + // Maps const T* -> ID, and refs the key. template <typename T, Type kType> class RefKeyMap { public: RefKeyMap() {} - ~RefKeyMap() { fMap.foreach([](const T* key, ID*) { key->unref(); }); } + ~RefKeyMap() { fMap.foreach([](const T* key, ID*) { SkSafeUnref(key); }); } - void set(const T* key, const ID& id) { - SkASSERT(key && id.type() == kType); - fMap.set(SkRef(key), id); + void set(const T* key, ID id) { + SkASSERT(id.type() == kType); + fMap.set(SkSafeRef(key), id); } void remove(const T* key) { - SkASSERT(key); fMap.remove(key); - key->unref(); + SkSafeUnref(key); } const ID* find(const T* key) const { - static const ID nullID(kType); - return key ? fMap.find(key) : &nullID; + return fMap.find(key); } template <typename Fn> - void foreach(const Fn& fn) { fMap.foreach(fn); } + void foreach(const Fn& fn) { + fMap.foreach(fn); + } private: SkTHashMap<const T*, ID> fMap; }; - } // namespace - - Cache* Cache::CreateAlwaysCache() { - struct AlwaysCache final : public Cache { - AlwaysCache() - : fNextMatrix (Type::kMatrix) - , fNextMisc (Type::kMisc) - , fNextPath (Type::kPath) - , fNextStroke (Type::kStroke) - , fNextShader (Type::kShader) - , fNextXfermode(Type::kXfermode) - {} - - void cleanup(Encoder* encoder) override { - Undefiner undef{encoder}; - fMatrix .foreach(undef); - fMisc .foreach(undef); - fPath .foreach(undef); - fStroke .foreach(undef); - fShader .foreach(undef); - fXfermode.foreach(undef); - } + SkTHashMap<SkMatrix, ID> fMatrix; + SkTHashMap<Misc, ID, MiscHash> fMisc; + SkTHashMap<SkPath, ID> fPath; + SkTHashMap<Stroke, ID> fStroke; + RefKeyMap<SkShader, Type::kShader> fShader; + RefKeyMap<SkXfermode, Type::kXfermode> fXfermode; - bool lookup(const SkMatrix& matrix, ID* id, LookupScope*) override { - return always_cache_lookup(matrix, &fMatrix, &fNextMatrix, id); - } - bool lookup(const Misc& misc, ID* id, LookupScope*) override { - return always_cache_lookup(misc, &fMisc, &fNextMisc, id); - } - bool lookup(const SkPath& path, ID* id, LookupScope*) override { - return always_cache_lookup(path, &fPath, &fNextPath, id); - } - bool lookup(const Stroke& stroke, ID* id, LookupScope*) override { - return always_cache_lookup(stroke, &fStroke, &fNextStroke, id); - } - bool lookup(const SkShader* shader, ID* id, LookupScope*) override { - return always_cache_lookup(shader, &fShader, &fNextShader, id); - } - bool lookup(const SkXfermode* xfermode, ID* id, LookupScope*) override { - return always_cache_lookup(xfermode, &fXfermode, &fNextXfermode, id); - } + Encoder* fWrapped; + }; - SkTHashMap<SkMatrix, ID> fMatrix; - SkTHashMap<Misc, ID, MiscHash> fMisc; - SkTHashMap<SkPath, ID> fPath; - SkTHashMap<Stroke, ID> fStroke; - RefKeyMap<SkShader, Type::kShader> fShader; - RefKeyMap<SkXfermode, Type::kXfermode> fXfermode; - - ID fNextMatrix, - fNextMisc, - fNextPath, - fNextStroke, - fNextShader, - fNextXfermode; - }; - return new AlwaysCache; - } + Encoder* Encoder::CreateCachingEncoder(Encoder* wrapped) { return new CachingEncoder(wrapped); } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // + + // Calls Encoder::define() when created, Encoder::undefine() when destroyed. + class Client::AutoID : ::SkNoncopyable { + public: + template <typename T> + explicit AutoID(Encoder* encoder, const T& val) + : fEncoder(encoder) + , fID(encoder->define(val)) {} + ~AutoID() { if (fEncoder) fEncoder->undefine(fID); } + + AutoID(AutoID&& o) : fEncoder(o.fEncoder), fID(o.fID) { + o.fEncoder = nullptr; + } + AutoID& operator=(AutoID&&) = delete; + + operator ID () const { return fID; } + + private: + Encoder* fEncoder; + const ID fID; + }; + + template <typename T> + Client::AutoID Client::id(const T& val) { return AutoID(fEncoder, val); } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // - Client::Client(Cache* cache, Encoder* encoder) + Client::Client(Encoder* encoder) : SkCanvas(1,1) - , fCache(cache) , fEncoder(encoder) {} - Client::~Client() { - fCache->cleanup(fEncoder); - } - void Client::willSave() { fEncoder->save(); } void Client::didRestore() { fEncoder->restore(); } void Client::didConcat (const SkMatrix&) { this->didSetMatrix(this->getTotalMatrix()); } void Client::didSetMatrix(const SkMatrix& matrix) { - LookupScope ls(fCache, fEncoder); - fEncoder->setMatrix(ls.lookup(matrix)); + fEncoder->setMatrix(this->id(matrix)); } void Client::onDrawOval(const SkRect& oval, const SkPaint& paint) { @@ -306,17 +237,16 @@ namespace SkRemote { } void Client::onDrawPath(const SkPath& path, const SkPaint& paint) { - LookupScope ls(fCache, fEncoder); - ID p = ls.lookup(path), - m = ls.lookup(Misc::CreateFrom(paint)), - s = ls.lookup(paint.getShader()), - x = ls.lookup(paint.getXfermode()); + auto p = this->id(path), + m = this->id(Misc::CreateFrom(paint)), + s = this->id(paint.getShader()), + x = this->id(paint.getXfermode()); if (paint.getStyle() == SkPaint::kFill_Style) { fEncoder->fillPath(p, m, s, x); } else { // TODO: handle kStrokeAndFill_Style - fEncoder->strokePath(p, m, s, x, ls.lookup(Stroke::CreateFrom(paint))); + fEncoder->strokePath(p, m, s, x, this->id(Stroke::CreateFrom(paint))); } } @@ -368,20 +298,26 @@ namespace SkRemote { } void Client::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { - LookupScope ls(fCache, fEncoder); - fEncoder->clipPath(ls.lookup(path), op, edgeStyle == kSoft_ClipEdgeStyle); + fEncoder->clipPath(this->id(path), op, edgeStyle == kSoft_ClipEdgeStyle); } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Server::Server(SkCanvas* canvas) : fCanvas(canvas) {} - void Server::define(ID id, const SkMatrix& v) { fMatrix .set(id, v); } - void Server::define(ID id, const Misc& v) { fMisc .set(id, v); } - void Server::define(ID id, const SkPath& v) { fPath .set(id, v); } - void Server::define(ID id, const Stroke& v) { fStroke .set(id, v); } - void Server::define(ID id, SkShader* v) { fShader .set(id, v); } - void Server::define(ID id, SkXfermode* v) { fXfermode.set(id, v); } + template <typename Map, typename T> + ID Server::define(Type type, Map* map, const T& val) { + ID id(type, fNextID++); + map->set(id, val); + return id; + } + + ID Server::define(const SkMatrix& v) { return this->define(Type::kMatrix, &fMatrix, v); } + ID Server::define(const Misc& v) { return this->define(Type::kMisc, &fMisc, v); } + ID Server::define(const SkPath& v) { return this->define(Type::kPath, &fPath, v); } + ID Server::define(const Stroke& v) { return this->define(Type::kStroke, &fStroke, v); } + ID Server::define(SkShader* v) { return this->define(Type::kShader, &fShader, v); } + ID Server::define(SkXfermode* v) { return this->define(Type::kXfermode, &fXfermode, v); } void Server::undefine(ID id) { switch(id.type()) { @@ -391,8 +327,6 @@ namespace SkRemote { case Type::kStroke: return fStroke .remove(id); case Type::kShader: return fShader .remove(id); case Type::kXfermode: return fXfermode.remove(id); - - case Type::kNone: SkASSERT(false); }; } |