| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #ifndef SkRemote_DEFINED | 8 #ifndef SkRemote_DEFINED |
| 9 #define SkRemote_DEFINED | 9 #define SkRemote_DEFINED |
| 10 | 10 |
| 11 #include "SkCanvas.h" | 11 #include "SkCanvas.h" |
| 12 #include "SkPaint.h" | 12 #include "SkPaint.h" |
| 13 #include "SkRemote_protocol.h" | 13 #include "SkRemote_protocol.h" |
| 14 #include "SkShader.h" | 14 #include "SkShader.h" |
| 15 #include "SkTHash.h" | 15 #include "SkTHash.h" |
| 16 #include "SkTypes.h" | 16 #include "SkTypes.h" |
| 17 | 17 |
| 18 // TODO: document | 18 // TODO: document |
| 19 | 19 |
| 20 namespace SkRemote { | 20 namespace SkRemote { |
| 21 // TODO: document | 21 |
| 22 // General purpose identifier. Holds a Type and a 56-bit value. |
| 23 class ID { |
| 24 public: |
| 25 ID() {} |
| 26 ID(Type type, uint64_t val) { |
| 27 fVal = (uint64_t)type << 56 | val; |
| 28 SkASSERT(this->type() == type && this->val() == val); |
| 29 } |
| 30 |
| 31 Type type() const { return (Type)(fVal >> 56); } |
| 32 uint64_t val() const { return fVal & ~((uint64_t)0xFF << 56); } |
| 33 |
| 34 bool operator==(ID o) const { return fVal == o.fVal; } |
| 35 |
| 36 private: |
| 37 uint64_t fVal; |
| 38 }; |
| 39 |
| 40 // Fields from SkPaint used by stroke, fill, and text draws. |
| 22 struct Misc { | 41 struct Misc { |
| 23 SkColor fColor; | 42 SkColor fColor; |
| 24 SkFilterQuality fFilterQuality; | 43 SkFilterQuality fFilterQuality; |
| 25 bool fAntiAlias, fDither; | 44 bool fAntiAlias, fDither; |
| 26 | 45 |
| 27 static Misc CreateFrom(const SkPaint&); | 46 static Misc CreateFrom(const SkPaint&); |
| 28 void applyTo(SkPaint*) const; | 47 void applyTo(SkPaint*) const; |
| 29 }; | 48 }; |
| 30 | 49 |
| 31 // TODO: document | 50 // Fields from SkPaint used by stroke draws only. |
| 32 struct Stroke { | 51 struct Stroke { |
| 33 SkScalar fWidth, fMiter; | 52 SkScalar fWidth, fMiter; |
| 34 SkPaint::Cap fCap; | 53 SkPaint::Cap fCap; |
| 35 SkPaint::Join fJoin; | 54 SkPaint::Join fJoin; |
| 36 | 55 |
| 37 static Stroke CreateFrom(const SkPaint&); | 56 static Stroke CreateFrom(const SkPaint&); |
| 38 void applyTo(SkPaint*) const; | 57 void applyTo(SkPaint*) const; |
| 39 }; | 58 }; |
| 40 | 59 |
| 41 // TODO: document | 60 // TODO: document |
| 42 struct Encoder { | 61 struct Encoder { |
| 43 virtual ~Encoder() {} | 62 virtual ~Encoder() {} |
| 44 | 63 |
| 45 virtual void define(ID, const SkMatrix&) = 0; | 64 static Encoder* CreateCachingEncoder(Encoder*); |
| 46 virtual void define(ID, const Misc&) = 0; | 65 |
| 47 virtual void define(ID, const SkPath&) = 0; | 66 virtual ID define(const SkMatrix&) = 0; |
| 48 virtual void define(ID, const Stroke&) = 0; | 67 virtual ID define(const Misc&) = 0; |
| 49 virtual void define(ID, SkShader*) = 0; | 68 virtual ID define(const SkPath&) = 0; |
| 50 virtual void define(ID, SkXfermode*) = 0; | 69 virtual ID define(const Stroke&) = 0; |
| 70 virtual ID define(SkShader*) = 0; |
| 71 virtual ID define(SkXfermode*) = 0; |
| 51 | 72 |
| 52 virtual void undefine(ID) = 0; | 73 virtual void undefine(ID) = 0; |
| 53 | 74 |
| 54 virtual void save() = 0; | 75 virtual void save() = 0; |
| 55 virtual void restore() = 0; | 76 virtual void restore() = 0; |
| 56 | 77 |
| 57 virtual void setMatrix(ID matrix) = 0; | 78 virtual void setMatrix(ID matrix) = 0; |
| 58 | 79 |
| 59 // TODO: struct CommonIDs { ID misc, shader, xfermode; ... } | 80 // TODO: struct CommonIDs { ID misc, shader, xfermode; ... } |
| 60 // for IDs that affect both fill + stroke? | 81 // for IDs that affect both fill + stroke? |
| 61 | 82 |
| 62 virtual void clipPath(ID path, SkRegion::Op, bool aa)
= 0; | 83 virtual void clipPath(ID path, SkRegion::Op, bool aa)
= 0; |
| 63 virtual void fillPath(ID path, ID misc, ID shader, ID xfermode)
= 0; | 84 virtual void fillPath(ID path, ID misc, ID shader, ID xfermode)
= 0; |
| 64 virtual void strokePath(ID path, ID misc, ID shader, ID xfermode, ID str
oke) = 0; | 85 virtual void strokePath(ID path, ID misc, ID shader, ID xfermode, ID str
oke) = 0; |
| 65 }; | 86 }; |
| 66 | 87 |
| 67 class LookupScope; | 88 // An SkCanvas that translates to Encoder calls. |
| 68 | |
| 69 // The Cache interface encapsulates the caching logic of the Client. | |
| 70 // | |
| 71 // Each lookup() method must always fill ID* with a valid value, | |
| 72 // but ID may be cached. If so, the lookup() method returns true; | |
| 73 // if not the lookup() method returns false and the Client must | |
| 74 // then define() this ID -> Thing mapping before using the ID. | |
| 75 // | |
| 76 // The Caches may also add IDs to the LookupScope's list of IDs to | |
| 77 // undefine() on destruction. This lets the Cache purge IDs. | |
| 78 struct Cache { | |
| 79 virtual ~Cache() {} | |
| 80 | |
| 81 static Cache* CreateNeverCache(); // Never caches anything. | |
| 82 static Cache* CreateAlwaysCache(); // Caches by value (not deep pointer
equality). | |
| 83 // TODO: static Cache* CreateDeepCache(); // Caches by deep value. | |
| 84 | |
| 85 virtual bool lookup(const SkMatrix&, ID*, LookupScope*) = 0; | |
| 86 virtual bool lookup(const Misc&, ID*, LookupScope*) = 0; | |
| 87 virtual bool lookup(const SkPath&, ID*, LookupScope*) = 0; | |
| 88 virtual bool lookup(const Stroke&, ID*, LookupScope*) = 0; | |
| 89 virtual bool lookup(const SkShader*, ID*, LookupScope*) = 0; | |
| 90 virtual bool lookup(const SkXfermode*, ID*, LookupScope*) = 0; | |
| 91 | |
| 92 virtual void cleanup(Encoder*) = 0; | |
| 93 }; | |
| 94 | |
| 95 // TODO: document | |
| 96 class Client final : public SkCanvas { | 89 class Client final : public SkCanvas { |
| 97 public: | 90 public: |
| 98 Client(Cache*, Encoder*); | 91 explicit Client(Encoder*); |
| 99 ~Client(); | |
| 100 | 92 |
| 101 private: | 93 private: |
| 94 class AutoID; |
| 95 |
| 96 template <typename T> |
| 97 AutoID id(const T&); |
| 98 |
| 102 void willSave() override; | 99 void willSave() override; |
| 103 void didRestore() override; | 100 void didRestore() override; |
| 104 | 101 |
| 105 void didConcat(const SkMatrix&) override; | 102 void didConcat(const SkMatrix&) override; |
| 106 void didSetMatrix(const SkMatrix&) override; | 103 void didSetMatrix(const SkMatrix&) override; |
| 107 | 104 |
| 108 void onClipPath (const SkPath&, SkRegion::Op, ClipEdgeStyle) override; | 105 void onClipPath (const SkPath&, SkRegion::Op, ClipEdgeStyle) override; |
| 109 void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override; | 106 void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override; |
| 110 void onClipRect (const SkRect&, SkRegion::Op, ClipEdgeStyle) override; | 107 void onClipRect (const SkRect&, SkRegion::Op, ClipEdgeStyle) override; |
| 111 | 108 |
| 112 void onDrawOval(const SkRect&, const SkPaint&) override; | 109 void onDrawOval(const SkRect&, const SkPaint&) override; |
| 113 void onDrawRRect(const SkRRect&, const SkPaint&) override; | 110 void onDrawRRect(const SkRRect&, const SkPaint&) override; |
| 114 void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) overri
de; | 111 void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) overri
de; |
| 115 void onDrawPath(const SkPath&, const SkPaint&) override; | 112 void onDrawPath(const SkPath&, const SkPaint&) override; |
| 116 void onDrawRect(const SkRect&, const SkPaint&) override; | 113 void onDrawRect(const SkRect&, const SkPaint&) override; |
| 117 void onDrawPaint(const SkPaint&) override; | 114 void onDrawPaint(const SkPaint&) override; |
| 118 | 115 |
| 119 void onDrawText(const void*, size_t, SkScalar, | 116 void onDrawText(const void*, size_t, SkScalar, |
| 120 SkScalar, const SkPaint&) override; | 117 SkScalar, const SkPaint&) override; |
| 121 void onDrawPosText(const void*, size_t, const SkPoint[], | 118 void onDrawPosText(const void*, size_t, const SkPoint[], |
| 122 const SkPaint&) override; | 119 const SkPaint&) override; |
| 123 void onDrawPosTextH(const void*, size_t, const SkScalar[], SkScalar, | 120 void onDrawPosTextH(const void*, size_t, const SkScalar[], SkScalar, |
| 124 const SkPaint&) override; | 121 const SkPaint&) override; |
| 125 | 122 |
| 126 Cache* fCache; | |
| 127 Encoder* fEncoder; | 123 Encoder* fEncoder; |
| 128 }; | 124 }; |
| 129 | 125 |
| 130 // TODO: document | 126 // An Encoder that translates back to SkCanvas calls. |
| 131 class Server final : public Encoder { | 127 class Server final : public Encoder { |
| 132 public: | 128 public: |
| 133 explicit Server(SkCanvas*); | 129 explicit Server(SkCanvas*); |
| 134 | 130 |
| 135 private: | 131 private: |
| 136 void define(ID, const SkMatrix&) override; | 132 ID define(const SkMatrix&) override; |
| 137 void define(ID, const Misc&) override; | 133 ID define(const Misc&) override; |
| 138 void define(ID, const SkPath&) override; | 134 ID define(const SkPath&) override; |
| 139 void define(ID, const Stroke&) override; | 135 ID define(const Stroke&) override; |
| 140 void define(ID, SkShader*) override; | 136 ID define(SkShader*) override; |
| 141 void define(ID, SkXfermode*) override; | 137 ID define(SkXfermode*) override; |
| 142 | 138 |
| 143 void undefine(ID) override; | 139 void undefine(ID) override; |
| 144 | 140 |
| 145 void save() override; | 141 void save() override; |
| 146 void restore() override; | 142 void restore() override; |
| 147 | 143 |
| 148 void setMatrix(ID matrix) override; | 144 void setMatrix(ID matrix) override; |
| 149 | 145 |
| 150 void clipPath(ID path, SkRegion::Op, bool aa) ove
rride; | 146 void clipPath(ID path, SkRegion::Op, bool aa) ove
rride; |
| 151 void fillPath(ID path, ID misc, ID shader, ID xfermode) ove
rride; | 147 void fillPath(ID path, ID misc, ID shader, ID xfermode) ove
rride; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 178 } | 174 } |
| 179 | 175 |
| 180 private: | 176 private: |
| 181 SkTHashMap<ID, T> fMap; | 177 SkTHashMap<ID, T> fMap; |
| 182 }; | 178 }; |
| 183 | 179 |
| 184 // Maps ID -> T*, and keeps the T alive by reffing it. | 180 // Maps ID -> T*, and keeps the T alive by reffing it. |
| 185 template <typename T, Type kType> | 181 template <typename T, Type kType> |
| 186 class ReffedIDMap { | 182 class ReffedIDMap { |
| 187 public: | 183 public: |
| 188 ReffedIDMap() { | 184 ReffedIDMap() {} |
| 189 // A null ID always maps to nullptr. | |
| 190 fMap.set(ID(kType), nullptr); | |
| 191 } | |
| 192 ~ReffedIDMap() { | 185 ~ReffedIDMap() { |
| 193 // A well-behaved client always cleans up its definitions. | 186 // A well-behaved client always cleans up its definitions. |
| 194 SkASSERT(fMap.count() == 1); | 187 SkASSERT(fMap.count() == 0); |
| 195 } | 188 } |
| 196 | 189 |
| 197 void set(const ID& id, T* val) { | 190 void set(const ID& id, T* val) { |
| 198 SkASSERT(id.type() == kType && val); | 191 SkASSERT(id.type() == kType); |
| 199 fMap.set(id, SkRef(val)); | 192 fMap.set(id, SkSafeRef(val)); |
| 200 } | 193 } |
| 201 | 194 |
| 202 void remove(const ID& id) { | 195 void remove(const ID& id) { |
| 203 SkASSERT(id.type() == kType); | 196 SkASSERT(id.type() == kType); |
| 204 T** val = fMap.find(id); | 197 T** val = fMap.find(id); |
| 205 SkASSERT(val && *val); | 198 SkASSERT(val); |
| 206 (*val)->unref(); | 199 SkSafeUnref(*val); |
| 207 fMap.remove(id); | 200 fMap.remove(id); |
| 208 } | 201 } |
| 209 | 202 |
| 210 T* find(const ID& id) const { | 203 T* find(const ID& id) const { |
| 211 SkASSERT(id.type() == kType); | 204 SkASSERT(id.type() == kType); |
| 212 T** val = fMap.find(id); | 205 T** val = fMap.find(id); |
| 213 SkASSERT(val); | 206 SkASSERT(val); |
| 214 return *val; | 207 return *val; |
| 215 } | 208 } |
| 216 | 209 |
| 217 private: | 210 private: |
| 218 SkTHashMap<ID, T*> fMap; | 211 SkTHashMap<ID, T*> fMap; |
| 219 }; | 212 }; |
| 220 | 213 |
| 214 template <typename Map, typename T> |
| 215 ID define(Type, Map*, const T&); |
| 216 |
| 221 IDMap<SkMatrix, Type::kMatrix> fMatrix; | 217 IDMap<SkMatrix, Type::kMatrix> fMatrix; |
| 222 IDMap<Misc , Type::kMisc > fMisc; | 218 IDMap<Misc , Type::kMisc > fMisc; |
| 223 IDMap<SkPath , Type::kPath > fPath; | 219 IDMap<SkPath , Type::kPath > fPath; |
| 224 IDMap<Stroke , Type::kStroke> fStroke; | 220 IDMap<Stroke , Type::kStroke> fStroke; |
| 225 ReffedIDMap<SkShader, Type::kShader> fShader; | 221 ReffedIDMap<SkShader, Type::kShader> fShader; |
| 226 ReffedIDMap<SkXfermode, Type::kXfermode> fXfermode; | 222 ReffedIDMap<SkXfermode, Type::kXfermode> fXfermode; |
| 227 | 223 |
| 228 SkCanvas* fCanvas; | 224 SkCanvas* fCanvas; |
| 225 uint64_t fNextID = 0; |
| 229 }; | 226 }; |
| 230 | 227 |
| 231 } // namespace SkRemote | 228 } // namespace SkRemote |
| 232 | 229 |
| 233 #endif//SkRemote_DEFINED | 230 #endif//SkRemote_DEFINED |
| OLD | NEW |