Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: src/core/SkRemote.cpp

Issue 1418863002: SkRemote: refactoring (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: ID is not protocol sensitive Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkRemote.h ('k') | src/core/SkRemote_protocol.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "SkPath.h" 8 #include "SkPath.h"
9 #include "SkRect.h" 9 #include "SkRect.h"
10 #include "SkRemote.h" 10 #include "SkRemote.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 && a.fMiter == b.fMiter 65 && a.fMiter == b.fMiter
66 && a.fCap == b.fCap 66 && a.fCap == b.fCap
67 && a.fJoin == b.fJoin; 67 && a.fJoin == b.fJoin;
68 } 68 }
69 69
70 // The default SkGoodHash works fine for Stroke, as it's dense. 70 // The default SkGoodHash works fine for Stroke, as it's dense.
71 static_assert(sizeof(Stroke) == offsetof(Stroke, fJoin) + sizeof(Stroke().fJ oin), ""); 71 static_assert(sizeof(Stroke) == offsetof(Stroke, fJoin) + sizeof(Stroke().fJ oin), "");
72 72
73 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 73 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
74 74
75 class LookupScope { 75 class CachingEncoder final : public Encoder {
76 public: 76 public:
77 LookupScope(Cache* cache, Encoder* encoder) : fCache(cache), fEncoder(en coder) {} 77 explicit CachingEncoder(Encoder* wrapped) : fWrapped(wrapped) {}
78 ~LookupScope() { for (ID id : fToUndefine) { fEncoder->undefine(id); } }
79 void undefineWhenDone(ID id) { fToUndefine.push_back(id); }
80
81 template <typename T>
82 ID lookup(const T& val) {
83 ID id;
84 if (!fCache->lookup(val, &id, this)) {
85 fEncoder->define(id, val);
86 }
87 return id;
88 }
89 78
90 private: 79 private:
91 Cache* fCache; 80 struct Undef {
92 Encoder* fEncoder;
93 SkSTArray<4, ID> fToUndefine;
94 };
95
96
97 Cache* Cache::CreateNeverCache() {
98 struct NeverCache final : public Cache {
99 NeverCache()
100 : fNextMatrix (Type::kMatrix)
101 , fNextMisc (Type::kMisc)
102 , fNextPath (Type::kPath)
103 , fNextStroke (Type::kStroke)
104 , fNextShader (Type::kShader)
105 , fNextXfermode(Type::kXfermode)
106 {}
107 void cleanup(Encoder*) override {}
108
109 static bool Helper(ID* next, ID* id, LookupScope* ls) {
110 *id = ++(*next);
111 ls->undefineWhenDone(*id);
112 return false;
113 }
114
115 bool lookup(const SkMatrix&, ID* id, LookupScope* ls) override {
116 return Helper(&fNextMatrix, id, ls);
117 }
118 bool lookup(const Misc&, ID* id, LookupScope* ls) override {
119 return Helper(&fNextMisc, id, ls);
120 }
121 bool lookup(const SkPath&, ID* id, LookupScope* ls) override {
122 return Helper(&fNextPath, id, ls);
123 }
124 bool lookup(const Stroke&, ID* id, LookupScope* ls) override {
125 return Helper(&fNextStroke, id, ls);
126 }
127 bool lookup(const SkShader* shader, ID* id, LookupScope* ls) overrid e {
128 if (!shader) {
129 *id = ID(Type::kShader);
130 return true; // Null IDs are always defined.
131 }
132 return Helper(&fNextShader, id, ls);
133 }
134 bool lookup(const SkXfermode* xfermode, ID* id, LookupScope* ls) ove rride {
135 if (!xfermode) {
136 *id = ID(Type::kXfermode);
137 return true; // Null IDs are always defined.
138 }
139 return Helper(&fNextXfermode, id, ls);
140 }
141
142 ID fNextMatrix,
143 fNextMisc,
144 fNextPath,
145 fNextStroke,
146 fNextShader,
147 fNextXfermode;
148 };
149 return new NeverCache;
150 }
151
152 // These can't be declared locally inside AlwaysCache because of the templat ing. :(
153 namespace {
154 template <typename T, typename Map>
155 static bool always_cache_lookup(const T& val, Map* map, ID* next, ID* id ) {
156 if (const ID* found = map->find(val)) {
157 *id = *found;
158 return true;
159 }
160 *id = ++(*next);
161 map->set(val, *id);
162 return false;
163 }
164
165 struct Undefiner {
166 Encoder* fEncoder; 81 Encoder* fEncoder;
167
168 template <typename T> 82 template <typename T>
169 void operator()(const T&, ID* id) const { fEncoder->undefine(*id); } 83 void operator()(const T&, ID* id) const { fEncoder->undefine(*id); }
170 }; 84 };
171 85
172 // Maps const T* -> ID, and refs the key. nullptr always maps to ID(kTy pe). 86 ~CachingEncoder() override {
87 Undef undef{fWrapped};
88 fMatrix .foreach(undef);
89 fMisc .foreach(undef);
90 fPath .foreach(undef);
91 fStroke .foreach(undef);
92 fShader .foreach(undef);
93 fXfermode.foreach(undef);
94 }
95
96 template <typename Map, typename T>
97 ID define(Map* map, const T& v) {
98 if (const ID* id = map->find(v)) {
99 return *id;
100 }
101 ID id = fWrapped->define(v);
102 map->set(v, id);
103 return id;
104 }
105
106 ID define(const SkMatrix& v) override { return this->define(&fMatrix, v); }
107 ID define(const Misc& v) override { return this->define(&fMisc, v); }
108 ID define(const SkPath& v) override { return this->define(&fPath, v); }
109 ID define(const Stroke& v) override { return this->define(&fStroke, v); }
110 ID define(SkShader* v) override { return this->define(&fShader, v); }
111 ID define(SkXfermode* v) override { return this->define(&fXfermode, v); }
112
113 void undefine(ID) override {}
114
115 void save() override { fWrapped-> save(); }
116 void restore() override { fWrapped->restore(); }
117
118 void setMatrix(ID matrix) override { fWrapped->setMatrix(matrix); }
119
120 void clipPath(ID path, SkRegion::Op op, bool aa) override {
121 fWrapped->clipPath(path, op, aa);
122 }
123 void fillPath(ID path, ID misc, ID shader, ID xfermode) override {
124 fWrapped->fillPath(path, misc, shader, xfermode);
125 }
126 void strokePath(ID path, ID misc, ID shader, ID xfermode, ID stroke) ove rride {
127 fWrapped->strokePath(path, misc, shader, xfermode, stroke);
128 }
129
130 // Maps const T* -> ID, and refs the key.
173 template <typename T, Type kType> 131 template <typename T, Type kType>
174 class RefKeyMap { 132 class RefKeyMap {
175 public: 133 public:
176 RefKeyMap() {} 134 RefKeyMap() {}
177 ~RefKeyMap() { fMap.foreach([](const T* key, ID*) { key->unref(); }) ; } 135 ~RefKeyMap() { fMap.foreach([](const T* key, ID*) { SkSafeUnref(key) ; }); }
178 136
179 void set(const T* key, const ID& id) { 137 void set(const T* key, ID id) {
180 SkASSERT(key && id.type() == kType); 138 SkASSERT(id.type() == kType);
181 fMap.set(SkRef(key), id); 139 fMap.set(SkSafeRef(key), id);
182 } 140 }
183 141
184 void remove(const T* key) { 142 void remove(const T* key) {
185 SkASSERT(key);
186 fMap.remove(key); 143 fMap.remove(key);
187 key->unref(); 144 SkSafeUnref(key);
188 } 145 }
189 146
190 const ID* find(const T* key) const { 147 const ID* find(const T* key) const {
191 static const ID nullID(kType); 148 return fMap.find(key);
192 return key ? fMap.find(key) : &nullID;
193 } 149 }
194 150
195 template <typename Fn> 151 template <typename Fn>
196 void foreach(const Fn& fn) { fMap.foreach(fn); } 152 void foreach(const Fn& fn) {
153 fMap.foreach(fn);
154 }
197 private: 155 private:
198 SkTHashMap<const T*, ID> fMap; 156 SkTHashMap<const T*, ID> fMap;
199 }; 157 };
200 } // namespace
201 158
202 Cache* Cache::CreateAlwaysCache() { 159 SkTHashMap<SkMatrix, ID> fMatrix;
203 struct AlwaysCache final : public Cache { 160 SkTHashMap<Misc, ID, MiscHash> fMisc;
204 AlwaysCache() 161 SkTHashMap<SkPath, ID> fPath;
205 : fNextMatrix (Type::kMatrix) 162 SkTHashMap<Stroke, ID> fStroke;
206 , fNextMisc (Type::kMisc) 163 RefKeyMap<SkShader, Type::kShader> fShader;
207 , fNextPath (Type::kPath) 164 RefKeyMap<SkXfermode, Type::kXfermode> fXfermode;
208 , fNextStroke (Type::kStroke)
209 , fNextShader (Type::kShader)
210 , fNextXfermode(Type::kXfermode)
211 {}
212 165
213 void cleanup(Encoder* encoder) override { 166 Encoder* fWrapped;
214 Undefiner undef{encoder}; 167 };
215 fMatrix .foreach(undef);
216 fMisc .foreach(undef);
217 fPath .foreach(undef);
218 fStroke .foreach(undef);
219 fShader .foreach(undef);
220 fXfermode.foreach(undef);
221 }
222 168
223 169 Encoder* Encoder::CreateCachingEncoder(Encoder* wrapped) { return new Cachin gEncoder(wrapped); }
224 bool lookup(const SkMatrix& matrix, ID* id, LookupScope*) override {
225 return always_cache_lookup(matrix, &fMatrix, &fNextMatrix, id);
226 }
227 bool lookup(const Misc& misc, ID* id, LookupScope*) override {
228 return always_cache_lookup(misc, &fMisc, &fNextMisc, id);
229 }
230 bool lookup(const SkPath& path, ID* id, LookupScope*) override {
231 return always_cache_lookup(path, &fPath, &fNextPath, id);
232 }
233 bool lookup(const Stroke& stroke, ID* id, LookupScope*) override {
234 return always_cache_lookup(stroke, &fStroke, &fNextStroke, id);
235 }
236 bool lookup(const SkShader* shader, ID* id, LookupScope*) override {
237 return always_cache_lookup(shader, &fShader, &fNextShader, id);
238 }
239 bool lookup(const SkXfermode* xfermode, ID* id, LookupScope*) overri de {
240 return always_cache_lookup(xfermode, &fXfermode, &fNextXfermode, id);
241 }
242
243 SkTHashMap<SkMatrix, ID> fMatrix;
244 SkTHashMap<Misc, ID, MiscHash> fMisc;
245 SkTHashMap<SkPath, ID> fPath;
246 SkTHashMap<Stroke, ID> fStroke;
247 RefKeyMap<SkShader, Type::kShader> fShader;
248 RefKeyMap<SkXfermode, Type::kXfermode> fXfermode;
249
250 ID fNextMatrix,
251 fNextMisc,
252 fNextPath,
253 fNextStroke,
254 fNextShader,
255 fNextXfermode;
256 };
257 return new AlwaysCache;
258 }
259 170
260 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 171 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
261 172
262 Client::Client(Cache* cache, Encoder* encoder) 173 // Calls Encoder::define() when created, Encoder::undefine() when destroyed.
174 class Client::AutoID : ::SkNoncopyable {
175 public:
176 template <typename T>
177 explicit AutoID(Encoder* encoder, const T& val)
178 : fEncoder(encoder)
179 , fID(encoder->define(val)) {}
180 ~AutoID() { if (fEncoder) fEncoder->undefine(fID); }
181
182 AutoID(AutoID&& o) : fEncoder(o.fEncoder), fID(o.fID) {
183 o.fEncoder = nullptr;
184 }
185 AutoID& operator=(AutoID&&) = delete;
186
187 operator ID () const { return fID; }
188
189 private:
190 Encoder* fEncoder;
191 const ID fID;
192 };
193
194 template <typename T>
195 Client::AutoID Client::id(const T& val) { return AutoID(fEncoder, val); }
196
197 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
198
199 Client::Client(Encoder* encoder)
263 : SkCanvas(1,1) 200 : SkCanvas(1,1)
264 , fCache(cache)
265 , fEncoder(encoder) 201 , fEncoder(encoder)
266 {} 202 {}
267 203
268 Client::~Client() {
269 fCache->cleanup(fEncoder);
270 }
271
272 void Client::willSave() { fEncoder->save(); } 204 void Client::willSave() { fEncoder->save(); }
273 void Client::didRestore() { fEncoder->restore(); } 205 void Client::didRestore() { fEncoder->restore(); }
274 206
275 void Client::didConcat (const SkMatrix&) { this->didSetMatrix(this->getTot alMatrix()); } 207 void Client::didConcat (const SkMatrix&) { this->didSetMatrix(this->getTot alMatrix()); }
276 void Client::didSetMatrix(const SkMatrix& matrix) { 208 void Client::didSetMatrix(const SkMatrix& matrix) {
277 LookupScope ls(fCache, fEncoder); 209 fEncoder->setMatrix(this->id(matrix));
278 fEncoder->setMatrix(ls.lookup(matrix));
279 } 210 }
280 211
281 void Client::onDrawOval(const SkRect& oval, const SkPaint& paint) { 212 void Client::onDrawOval(const SkRect& oval, const SkPaint& paint) {
282 SkPath path; 213 SkPath path;
283 path.addOval(oval); 214 path.addOval(oval);
284 this->onDrawPath(path, paint); 215 this->onDrawPath(path, paint);
285 } 216 }
286 217
287 void Client::onDrawRect(const SkRect& rect, const SkPaint& paint) { 218 void Client::onDrawRect(const SkRect& rect, const SkPaint& paint) {
288 SkPath path; 219 SkPath path;
(...skipping 10 matching lines...) Expand all
299 void Client::onDrawDRRect(const SkRRect& outside, 230 void Client::onDrawDRRect(const SkRRect& outside,
300 const SkRRect& inside, 231 const SkRRect& inside,
301 const SkPaint& paint) { 232 const SkPaint& paint) {
302 SkPath path; 233 SkPath path;
303 path.addRRect(outside); 234 path.addRRect(outside);
304 path.addRRect(inside, SkPath::kCCW_Direction); 235 path.addRRect(inside, SkPath::kCCW_Direction);
305 this->onDrawPath(path, paint); 236 this->onDrawPath(path, paint);
306 } 237 }
307 238
308 void Client::onDrawPath(const SkPath& path, const SkPaint& paint) { 239 void Client::onDrawPath(const SkPath& path, const SkPaint& paint) {
309 LookupScope ls(fCache, fEncoder); 240 auto p = this->id(path),
310 ID p = ls.lookup(path), 241 m = this->id(Misc::CreateFrom(paint)),
311 m = ls.lookup(Misc::CreateFrom(paint)), 242 s = this->id(paint.getShader()),
312 s = ls.lookup(paint.getShader()), 243 x = this->id(paint.getXfermode());
313 x = ls.lookup(paint.getXfermode());
314 244
315 if (paint.getStyle() == SkPaint::kFill_Style) { 245 if (paint.getStyle() == SkPaint::kFill_Style) {
316 fEncoder->fillPath(p, m, s, x); 246 fEncoder->fillPath(p, m, s, x);
317 } else { 247 } else {
318 // TODO: handle kStrokeAndFill_Style 248 // TODO: handle kStrokeAndFill_Style
319 fEncoder->strokePath(p, m, s, x, ls.lookup(Stroke::CreateFrom(paint) )); 249 fEncoder->strokePath(p, m, s, x, this->id(Stroke::CreateFrom(paint)) );
320 } 250 }
321 } 251 }
322 252
323 void Client::onDrawPaint(const SkPaint& paint) { 253 void Client::onDrawPaint(const SkPaint& paint) {
324 SkPath path; 254 SkPath path;
325 path.setFillType(SkPath::kInverseWinding_FillType); // Either inverse F illType works fine. 255 path.setFillType(SkPath::kInverseWinding_FillType); // Either inverse F illType works fine.
326 this->onDrawPath(path, paint); 256 this->onDrawPath(path, paint);
327 } 257 }
328 258
329 void Client::onDrawText(const void* text, size_t byteLength, SkScalar x, 259 void Client::onDrawText(const void* text, size_t byteLength, SkScalar x,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 this->onClipPath(path, op, edgeStyle); 291 this->onClipPath(path, op, edgeStyle);
362 } 292 }
363 293
364 void Client::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyl e edgeStyle) { 294 void Client::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyl e edgeStyle) {
365 SkPath path; 295 SkPath path;
366 path.addRRect(rrect); 296 path.addRRect(rrect);
367 this->onClipPath(path, op, edgeStyle); 297 this->onClipPath(path, op, edgeStyle);
368 } 298 }
369 299
370 void Client::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle e dgeStyle) { 300 void Client::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle e dgeStyle) {
371 LookupScope ls(fCache, fEncoder); 301 fEncoder->clipPath(this->id(path), op, edgeStyle == kSoft_ClipEdgeStyle) ;
372 fEncoder->clipPath(ls.lookup(path), op, edgeStyle == kSoft_ClipEdgeStyle );
373 } 302 }
374 303
375 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 304 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
376 305
377 Server::Server(SkCanvas* canvas) : fCanvas(canvas) {} 306 Server::Server(SkCanvas* canvas) : fCanvas(canvas) {}
378 307
379 void Server::define(ID id, const SkMatrix& v) { fMatrix .set(id, v); } 308 template <typename Map, typename T>
380 void Server::define(ID id, const Misc& v) { fMisc .set(id, v); } 309 ID Server::define(Type type, Map* map, const T& val) {
381 void Server::define(ID id, const SkPath& v) { fPath .set(id, v); } 310 ID id(type, fNextID++);
382 void Server::define(ID id, const Stroke& v) { fStroke .set(id, v); } 311 map->set(id, val);
383 void Server::define(ID id, SkShader* v) { fShader .set(id, v); } 312 return id;
384 void Server::define(ID id, SkXfermode* v) { fXfermode.set(id, v); } 313 }
314
315 ID Server::define(const SkMatrix& v) { return this->define(Type::kMatrix, &fMatrix, v); }
316 ID Server::define(const Misc& v) { return this->define(Type::kMisc, &fMisc, v); }
317 ID Server::define(const SkPath& v) { return this->define(Type::kPath, &fPath, v); }
318 ID Server::define(const Stroke& v) { return this->define(Type::kStroke, &fStroke, v); }
319 ID Server::define(SkShader* v) { return this->define(Type::kShader, &fShader, v); }
320 ID Server::define(SkXfermode* v) { return this->define(Type::kXfermode, &fXfermode, v); }
385 321
386 void Server::undefine(ID id) { 322 void Server::undefine(ID id) {
387 switch(id.type()) { 323 switch(id.type()) {
388 case Type::kMatrix: return fMatrix .remove(id); 324 case Type::kMatrix: return fMatrix .remove(id);
389 case Type::kMisc: return fMisc .remove(id); 325 case Type::kMisc: return fMisc .remove(id);
390 case Type::kPath: return fPath .remove(id); 326 case Type::kPath: return fPath .remove(id);
391 case Type::kStroke: return fStroke .remove(id); 327 case Type::kStroke: return fStroke .remove(id);
392 case Type::kShader: return fShader .remove(id); 328 case Type::kShader: return fShader .remove(id);
393 case Type::kXfermode: return fXfermode.remove(id); 329 case Type::kXfermode: return fXfermode.remove(id);
394
395 case Type::kNone: SkASSERT(false);
396 }; 330 };
397 } 331 }
398 332
399 void Server:: save() { fCanvas->save(); } 333 void Server:: save() { fCanvas->save(); }
400 void Server::restore() { fCanvas->restore(); } 334 void Server::restore() { fCanvas->restore(); }
401 335
402 void Server::setMatrix(ID matrix) { fCanvas->setMatrix(fMatrix.find(matrix)) ; } 336 void Server::setMatrix(ID matrix) { fCanvas->setMatrix(fMatrix.find(matrix)) ; }
403 337
404 void Server::clipPath(ID path, SkRegion::Op op, bool aa) { 338 void Server::clipPath(ID path, SkRegion::Op op, bool aa) {
405 fCanvas->clipPath(fPath.find(path), op, aa); 339 fCanvas->clipPath(fPath.find(path), op, aa);
(...skipping 10 matching lines...) Expand all
416 SkPaint paint; 350 SkPaint paint;
417 paint.setStyle(SkPaint::kStroke_Style); 351 paint.setStyle(SkPaint::kStroke_Style);
418 fMisc .find(misc ).applyTo(&paint); 352 fMisc .find(misc ).applyTo(&paint);
419 fStroke.find(stroke).applyTo(&paint); 353 fStroke.find(stroke).applyTo(&paint);
420 paint.setShader (fShader .find(shader)); 354 paint.setShader (fShader .find(shader));
421 paint.setXfermode(fXfermode.find(xfermode)); 355 paint.setXfermode(fXfermode.find(xfermode));
422 fCanvas->drawPath(fPath.find(path), paint); 356 fCanvas->drawPath(fPath.find(path), paint);
423 } 357 }
424 358
425 } // namespace SkRemote 359 } // namespace SkRemote
OLDNEW
« no previous file with comments | « src/core/SkRemote.h ('k') | src/core/SkRemote_protocol.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698