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 |