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

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

Issue 1774013002: Archive SkRemote-related code. I want to start fresh. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 9 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
(Empty)
1 /*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkCanvas.h"
9 #include "SkColorFilter.h"
10 #include "SkDrawLooper.h"
11 #include "SkImage.h"
12 #include "SkImageFilter.h"
13 #include "SkMaskFilter.h"
14 #include "SkNinePatchIter.h"
15 #include "SkPath.h"
16 #include "SkPathEffect.h"
17 #include "SkRasterizer.h"
18 #include "SkRect.h"
19 #include "SkRemote.h"
20 #include "SkShader.h"
21 #include "SkTHash.h"
22 #include "SkTextBlob.h"
23
24 namespace SkRemote {
25
26 Misc Misc::CreateFrom(const SkPaint& paint) {
27 Misc misc = {
28 paint.getColor(),
29 paint.getFilterQuality(),
30 paint.isAntiAlias(),
31 paint.isDither(),
32 };
33 return misc;
34 }
35
36 void Misc::applyTo(SkPaint* paint) const {
37 paint->setColor (fColor);
38 paint->setFilterQuality(fFilterQuality);
39 paint->setAntiAlias (fAntiAlias);
40 paint->setDither (fDither);
41 }
42
43 static bool operator==(const Misc& a, const Misc& b) {
44 return a.fColor == b.fColor
45 && a.fFilterQuality == b.fFilterQuality
46 && a.fAntiAlias == b.fAntiAlias
47 && a.fDither == b.fDither;
48 }
49
50 // Misc carries 10 bytes of data in a 12 byte struct, so we need a custom ha sh.
51 static_assert(sizeof(Misc) > offsetof(Misc, fDither) + sizeof(Misc().fDither ), "");
52 struct MiscHash {
53 uint32_t operator()(const Misc& misc) {
54 return SkChecksum::Murmur3(&misc, offsetof(Misc, fDither) + sizeof(M isc().fDither));
55 }
56 };
57
58 Stroke Stroke::CreateFrom(const SkPaint& paint) {
59 Stroke stroke = {
60 paint.getStrokeWidth(),
61 paint.getStrokeMiter(),
62 paint.getStrokeCap(),
63 paint.getStrokeJoin(),
64 };
65 return stroke;
66 }
67
68 void Stroke::applyTo(SkPaint* paint) const {
69 paint->setStrokeWidth(fWidth);
70 paint->setStrokeMiter(fMiter);
71 paint->setStrokeCap (fCap);
72 paint->setStrokeJoin (fJoin);
73 }
74
75 static bool operator==(const Stroke& a, const Stroke& b) {
76 return a.fWidth == b.fWidth
77 && a.fMiter == b.fMiter
78 && a.fCap == b.fCap
79 && a.fJoin == b.fJoin;
80 }
81
82 // The default SkGoodHash works fine for Stroke, as it's dense.
83 static_assert(sizeof(Stroke) == offsetof(Stroke, fJoin) + sizeof(Stroke().fJ oin), "");
84
85 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
86
87 class Canvas final : public SkCanvas {
88 public:
89 explicit Canvas(Encoder* encoder)
90 : SkCanvas(1,1)
91 , fEncoder(encoder) {}
92
93 private:
94 // Calls Encoder::define() when created, Encoder::undefine() when destro yed.
95 class AutoID : ::SkNoncopyable {
96 public:
97 template <typename T>
98 explicit AutoID(Encoder* encoder, const T& val)
99 : fEncoder(encoder)
100 , fID(encoder->define(val)) {}
101 ~AutoID() { if (fEncoder) fEncoder->undefine(fID); }
102
103 AutoID(AutoID&& o) : fEncoder(o.fEncoder), fID(o.fID) {
104 o.fEncoder = nullptr;
105 }
106 AutoID& operator=(AutoID&&) = delete;
107
108 operator ID () const { return fID; }
109
110 private:
111 Encoder* fEncoder;
112 const ID fID;
113 };
114
115 // Like AutoID, but for CommonIDs.
116 class AutoCommonIDs : ::SkNoncopyable {
117 public:
118 explicit AutoCommonIDs(Encoder* encoder, const SkPaint& paint)
119 : fEncoder(encoder) {
120 fIDs.misc = fEncoder->define(Misc::CreateFrom(paint));
121 fIDs.patheffect = fEncoder->define(paint.getPathEffect());
122 fIDs.shader = fEncoder->define(paint.getShader());
123 fIDs.xfermode = fEncoder->define(paint.getXfermode());
124 fIDs.maskfilter = fEncoder->define(paint.getMaskFilter());
125 fIDs.colorfilter = fEncoder->define(paint.getColorFilter());
126 fIDs.rasterizer = fEncoder->define(paint.getRasterizer());
127 fIDs.looper = fEncoder->define(paint.getLooper());
128 fIDs.imagefilter = fEncoder->define(paint.getImageFilter());
129 }
130 ~AutoCommonIDs() {
131 if (fEncoder) {
132 fEncoder->undefine(fIDs.misc);
133 fEncoder->undefine(fIDs.patheffect);
134 fEncoder->undefine(fIDs.shader);
135 fEncoder->undefine(fIDs.xfermode);
136 fEncoder->undefine(fIDs.maskfilter);
137 fEncoder->undefine(fIDs.colorfilter);
138 fEncoder->undefine(fIDs.rasterizer);
139 fEncoder->undefine(fIDs.looper);
140 fEncoder->undefine(fIDs.imagefilter);
141 }
142 }
143
144 AutoCommonIDs(AutoCommonIDs&& o) : fEncoder(o.fEncoder), fIDs(o.fIDs ) {
145 o.fEncoder = nullptr;
146 }
147 AutoID& operator=(AutoID&&) = delete;
148
149 operator Encoder::CommonIDs () const { return fIDs; }
150
151 private:
152 Encoder* fEncoder;
153 Encoder::CommonIDs fIDs;
154 };
155
156 template <typename T>
157 AutoID id(const T& val) { return AutoID(fEncoder, val); }
158
159 AutoCommonIDs commonIDs(const SkPaint& paint) { return AutoCommonIDs(fEn coder, paint); }
160
161 void willSave() override { fEncoder-> save(); }
162 void didRestore() override { fEncoder->restore(); }
163 SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override {
164 SkPath path;
165 if (rec.fBounds) {
166 path.addRect(*rec.fBounds);
167 }
168 const SkPaint defaultPaint;
169 const SkPaint* paint = rec.fPaint;
170 if (!paint) {
171 paint = &defaultPaint;
172 }
173 fEncoder->saveLayer(this->id(path), this->commonIDs(*paint), rec.fSa veLayerFlags);
174 return kNoLayer_SaveLayerStrategy;
175 }
176
177 void didConcat(const SkMatrix&) override { this->didSetMatrix(this->g etTotalMatrix()); }
178 void didSetMatrix(const SkMatrix& matrix) override {
179 fEncoder->setMatrix(this->id(matrix));
180 }
181
182 void onDrawOval(const SkRect& oval, const SkPaint& paint) override {
183 SkPath path;
184 path.addOval(oval);
185 this->onDrawPath(path, paint);
186 }
187
188 void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
189 SkPath path;
190 path.addRect(rect);
191 this->onDrawPath(path, paint);
192 }
193
194 void onDrawRRect(const SkRRect& rrect, const SkPaint& paint) override {
195 SkPath path;
196 path.addRRect(rrect);
197 this->onDrawPath(path, paint);
198 }
199
200 void onDrawDRRect(const SkRRect& outside, const SkRRect& inside,
201 const SkPaint& paint) override {
202 SkPath path;
203 path.addRRect(outside);
204 path.addRRect(inside, SkPath::kCCW_Direction);
205 this->onDrawPath(path, paint);
206 }
207
208 void onDrawPath(const SkPath& path, const SkPaint& paint) override {
209 auto common = this->commonIDs(paint);
210 auto p = this->id(path);
211
212 if (paint.getStyle() == SkPaint::kFill_Style) {
213 fEncoder->fillPath(p, common);
214 } else {
215 // TODO: handle kStrokeAndFill_Style
216 fEncoder->strokePath(p, common, this->id(Stroke::CreateFrom(pain t)));
217 }
218 }
219
220 void onDrawPaint(const SkPaint& paint) override {
221 SkPath path;
222 path.setFillType(SkPath::kInverseWinding_FillType); // Either inver se FillType is fine.
223 this->onDrawPath(path, paint);
224 }
225
226 void onDrawPoints(PointMode mode,
227 size_t count,
228 const SkPoint pts[],
229 const SkPaint& paint) override {
230 // TODO
231 }
232
233 void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) overri de {
234 // TODO
235 this->INHERITED::onDrawDrawable(drawable, matrix);
236 }
237
238 void onDrawPicture(const SkPicture* pic,
239 const SkMatrix* matrix,
240 const SkPaint* paint) override {
241 // TODO
242 this->INHERITED::onDrawPicture(pic, matrix, paint);
243 }
244
245 void onDrawVertices(VertexMode vmode,
246 int vertexCount,
247 const SkPoint vertices[],
248 const SkPoint texs[],
249 const SkColor colors[],
250 SkXfermode* xmode,
251 const uint16_t indices[],
252 int indexCount,
253 const SkPaint& paint) override {
254 // TODO
255 }
256
257 void onDrawPatch(const SkPoint cubics[12],
258 const SkColor colors[4],
259 const SkPoint texCoords[4],
260 SkXfermode* xmode,
261 const SkPaint& paint) override {
262 // TODO
263 }
264
265 void onDrawAtlas(const SkImage* atlas,
266 const SkRSXform xform[],
267 const SkRect tex[],
268 const SkColor colors[],
269 int count,
270 SkXfermode::Mode mode,
271 const SkRect* cull,
272 const SkPaint* paint) override {
273 // TODO
274 }
275
276 void onDrawBitmap(const SkBitmap& bitmap,
277 SkScalar left,
278 SkScalar top,
279 const SkPaint* paint) override {
280 auto src = SkRect::MakeWH(bitmap.width(), bitmap.height()),
281 dst = src.makeOffset(left, top);
282 this->onDrawBitmapRect(bitmap, &src, dst, paint, kStrict_SrcRectCons traint);
283 }
284
285 void onDrawBitmapRect(const SkBitmap& bitmap,
286 const SkRect* src,
287 const SkRect& dst,
288 const SkPaint* paint,
289 SrcRectConstraint constraint) override {
290 SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(bitmap));
291 this->onDrawImageRect(image, src, dst, paint, constraint);
292 }
293
294 void onDrawImage(const SkImage* image,
295 SkScalar left,
296 SkScalar top,
297 const SkPaint* paint) override {
298 if (!image) {
299 return;
300 }
301 auto src = SkRect::MakeWH(image->width(), image->height()),
302 dst = src.makeOffset(left, top);
303 this->onDrawImageRect(image, &src, dst, paint, kStrict_SrcRectConstr aint);
304 }
305
306 void onDrawImageRect(const SkImage* image,
307 const SkRect* src,
308 const SkRect& dst,
309 const SkPaint* paint,
310 SrcRectConstraint constraint) override {
311 // TODO: this is all a (likely buggy) hack to get images drawing qui ckly.
312 if (!image) {
313 return;
314 }
315
316 auto bounds = SkRect::MakeWH(image->width(), image->height());
317 if (!src) {
318 src = &bounds;
319 }
320 auto matrix = SkMatrix::MakeRectToRect(*src, dst, SkMatrix::kFill_Sc aleToFit);
321
322 SkAutoTUnref<SkImage> subset;
323 if (src) {
324 if (!bounds.intersect(*src)) {
325 return;
326 }
327 subset.reset(image->newSubset(bounds.roundOut()));
328 image = subset;
329 }
330
331 auto paintWithShader = paint ? *paint : SkPaint();
332 SkAutoTUnref<SkShader> shader(
333 image->newShader(SkShader::kClamp_TileMode, SkShader::kClamp_Til eMode, &matrix));
334 paintWithShader.setShader(shader);
335
336 this->onDrawRect(dst, paintWithShader);
337 }
338
339 void onDrawBitmapNine(const SkBitmap& bitmap,
340 const SkIRect& center,
341 const SkRect& dst,
342 const SkPaint* paint) override {
343 SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(bitmap));
344 this->onDrawImageNine(image, center, dst, paint);
345 }
346
347 void onDrawImageNine(const SkImage* image,
348 const SkIRect& center,
349 const SkRect& dst,
350 const SkPaint* paint) override {
351 SkNinePatchIter iter(image->width(), image->height(), center, dst);
352 SkRect s,d;
353 while (iter.next(&s, &d)) {
354 this->onDrawImageRect(image, &s, d, paint, kStrict_SrcRectConstr aint);
355 }
356 }
357
358 void onDrawTextBlob(const SkTextBlob* text,
359 SkScalar x,
360 SkScalar y,
361 const SkPaint& paint) override {
362 SkPoint offset{x,y};
363 auto t = this->id(text);
364 auto common = this->commonIDs(paint);
365
366 if (paint.getStyle() == SkPaint::kFill_Style) {
367 fEncoder->fillText(t, offset, common);
368 } else {
369 // TODO: handle kStrokeAndFill_Style
370 fEncoder->strokeText(t, offset, common, this->id(Stroke::CreateF rom(paint)));
371 }
372 }
373
374 void onDrawText(const void* text, size_t byteLength,
375 SkScalar x, SkScalar y, const SkPaint& paint) override {
376 // Text-as-paths is a temporary hack.
377 // TODO: send SkTextBlobs and SkTypefaces
378 SkPath path;
379 paint.getTextPath(text, byteLength, x, y, &path);
380 this->onDrawPath(path, paint);
381 }
382
383 void onDrawPosText(const void* text, size_t byteLength,
384 const SkPoint pos[], const SkPaint& paint) override {
385 // Text-as-paths is a temporary hack.
386 // TODO: send SkTextBlobs and SkTypefaces
387 SkPath path;
388 paint.getPosTextPath(text, byteLength, pos, &path);
389 this->onDrawPath(path, paint);
390 }
391
392 void onDrawPosTextH(const void* text, size_t byteLength,
393 const SkScalar xpos[], SkScalar constY, const SkPain t& paint) override {
394 size_t length = paint.countText(text, byteLength);
395 SkAutoTArray<SkPoint> pos(length);
396 for(size_t i = 0; i < length; ++i) {
397 pos[i].set(xpos[i], constY);
398 }
399 this->onDrawPosText(text, byteLength, &pos[0], paint);
400 }
401
402 // All clip calls need to call their parent method or we'll not get any quick rejects.
403 void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeS tyle) override {
404 this->INHERITED::onClipRect(rect, op, edgeStyle);
405 SkPath path;
406 path.addRect(rect);
407 this->onClipPath(path, op, edgeStyle);
408 }
409
410 void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle ed geStyle) override {
411 this->INHERITED::onClipRRect(rrect, op, edgeStyle);
412 SkPath path;
413 path.addRRect(rrect);
414 this->onClipPath(path, op, edgeStyle);
415 }
416
417 void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeS tyle) override {
418 this->INHERITED::onClipPath(path, op, edgeStyle);
419 fEncoder->clipPath(this->id(path), op, edgeStyle == kSoft_ClipEdgeSt yle);
420 }
421
422 void onClipRegion(const SkRegion& region, SkRegion::Op op) override {
423 this->INHERITED::onClipRegion(region, op);
424 // TODO
425 }
426
427 Encoder* fEncoder;
428 typedef SkCanvas INHERITED;
429 };
430
431 SkCanvas* NewCanvas(Encoder* encoder) { return new Canvas(encoder); }
432
433 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
434
435 class Decoder final : public Encoder {
436 public:
437 explicit Decoder(SkCanvas* canvas) : fCanvas(canvas) {}
438
439 private:
440 template <typename Map, typename T>
441 ID define(Type type, Map* map, const T& val) {
442 ID id(type, fNextID++);
443 map->set(id, val);
444 return id;
445 }
446
447 #define O override
448 ID define(const SkMatrix& v)O{return this->define(Type::kMatrix, &fMatrix, v);}
449 ID define(const Misc& v)O{return this->define(Type::kMisc, &fMisc, v);}
450 ID define(const SkPath& v)O{return this->define(Type::kPath, &fPath, v);}
451 ID define(const Stroke& v)O{return this->define(Type::kStroke, &fStroke, v);}
452 ID define(const SkTextBlob* v)O{return this->define(Type::kTextBlob, &fTextBlob, v);}
453 ID define(SkPathEffect* v)O{return this->define(Type::kPathEffect, &fPathEffect, v);}
454 ID define(SkShader* v)O{return this->define(Type::kShader, &fShader, v);}
455 ID define(SkXfermode* v)O{return this->define(Type::kXfermode, &fXfermode, v);}
456 ID define(SkMaskFilter* v)O{return this->define(Type::kMaskFilter, &fMaskFilter, v);}
457 ID define(SkColorFilter* v)O{return this->define(Type::kColorFilter, &fColorFilter, v);}
458 ID define(SkRasterizer* v)O{return this->define(Type::kRasterizer, &fRasterizer, v);}
459 ID define(SkDrawLooper* v)O{return this->define(Type::kDrawLooper, &fDrawLooper, v);}
460 ID define(SkImageFilter* v)O{return this->define(Type::kImageFilter, &fImageFilter, v);}
461 #undef O
462
463
464 void undefine(ID id) override {
465 switch(id.type()) {
466 case Type::kMatrix: return fMatrix .remove(id);
467 case Type::kMisc: return fMisc .remove(id);
468 case Type::kPath: return fPath .remove(id);
469 case Type::kStroke: return fStroke .remove(id);
470 case Type::kTextBlob: return fTextBlob .remove(id);
471 case Type::kPathEffect: return fPathEffect .remove(id);
472 case Type::kShader: return fShader .remove(id);
473 case Type::kXfermode: return fXfermode .remove(id);
474 case Type::kMaskFilter: return fMaskFilter .remove(id);
475 case Type::kColorFilter: return fColorFilter.remove(id);
476 case Type::kRasterizer: return fRasterizer .remove(id);
477 case Type::kDrawLooper: return fDrawLooper .remove(id);
478 case Type::kImageFilter: return fImageFilter.remove(id);
479 };
480 }
481
482 void applyCommon(const CommonIDs& common, SkPaint* paint) const {
483 fMisc.find(common.misc).applyTo(paint);
484 paint->setPathEffect (fPathEffect .find(common.patheffect));
485 paint->setShader (fShader .find(common.shader));
486 paint->setXfermode (fXfermode .find(common.xfermode));
487 paint->setMaskFilter (fMaskFilter .find(common.maskfilter));
488 paint->setColorFilter(fColorFilter.find(common.colorfilter));
489 paint->setRasterizer (fRasterizer .find(common.rasterizer));
490 paint->setLooper (fDrawLooper .find(common.looper));
491 paint->setImageFilter(fImageFilter.find(common.imagefilter));
492 }
493
494 void save() override { fCanvas->save(); }
495 void restore() override { fCanvas->restore(); }
496 void saveLayer(ID bounds, CommonIDs common, SkCanvas::SaveLayerFlags fla gs) override {
497 SkPaint paint;
498 this->applyCommon(common, &paint);
499 SkRect rect;
500
501 fCanvas->saveLayer({ fPath.find(bounds).isRect(&rect) ? &rect : null ptr,
502 &paint, flags });
503 }
504
505 void setMatrix(ID matrix) override { fCanvas->setMatrix(fMatrix.find(mat rix)); }
506
507 void clipPath(ID path, SkRegion::Op op, bool aa) override {
508 fCanvas->clipPath(fPath.find(path), op, aa);
509 }
510 void fillPath(ID path, CommonIDs common) override {
511 SkPaint paint;
512 paint.setStyle(SkPaint::kFill_Style);
513 this->applyCommon(common, &paint);
514 fCanvas->drawPath(fPath.find(path), paint);
515 }
516 void strokePath(ID path, CommonIDs common, ID stroke) override {
517 SkPaint paint;
518 paint.setStyle(SkPaint::kStroke_Style);
519 this->applyCommon(common, &paint);
520 fStroke.find(stroke).applyTo(&paint);
521 fCanvas->drawPath(fPath.find(path), paint);
522 }
523 void fillText(ID text, SkPoint offset, CommonIDs common) override {
524 SkPaint paint;
525 paint.setStyle(SkPaint::kFill_Style);
526 this->applyCommon(common, &paint);
527 fCanvas->drawTextBlob(fTextBlob.find(text), offset.x(), offset.y(), paint);
528 }
529 void strokeText(ID text, SkPoint offset, CommonIDs common, ID stroke) ov erride {
530 SkPaint paint;
531 this->applyCommon(common, &paint);
532 fStroke.find(stroke).applyTo(&paint);
533 fCanvas->drawTextBlob(fTextBlob.find(text), offset.x(), offset.y(), paint);
534 }
535
536 // Maps ID -> T.
537 template <typename T, Type kType>
538 class IDMap {
539 public:
540 ~IDMap() {
541 // A well-behaved client always cleans up its definitions.
542 SkASSERT(fMap.count() == 0);
543 }
544
545 void set(const ID& id, const T& val) {
546 SkASSERT(id.type() == kType);
547 fMap.set(id, val);
548 }
549
550 void remove(const ID& id) {
551 SkASSERT(id.type() == kType);
552 fMap.remove(id);
553 }
554
555 const T& find(const ID& id) const {
556 SkASSERT(id.type() == kType);
557 T* val = fMap.find(id);
558 SkASSERT(val != nullptr);
559 return *val;
560 }
561
562 private:
563 SkTHashMap<ID, T> fMap;
564 };
565
566 // Maps ID -> T*, and keeps the T alive by reffing it.
567 template <typename T, Type kType>
568 class ReffedIDMap {
569 public:
570 ReffedIDMap() {}
571 ~ReffedIDMap() {
572 // A well-behaved client always cleans up its definitions.
573 SkASSERT(fMap.count() == 0);
574 }
575
576 void set(const ID& id, T* val) {
577 SkASSERT(id.type() == kType);
578 fMap.set(id, SkSafeRef(val));
579 }
580
581 void remove(const ID& id) {
582 SkASSERT(id.type() == kType);
583 T** val = fMap.find(id);
584 SkASSERT(val);
585 SkSafeUnref(*val);
586 fMap.remove(id);
587 }
588
589 T* find(const ID& id) const {
590 SkASSERT(id.type() == kType);
591 T** val = fMap.find(id);
592 SkASSERT(val);
593 return *val;
594 }
595
596 private:
597 SkTHashMap<ID, T*> fMap;
598 };
599
600
601 IDMap<SkMatrix , Type::kMatrix > fMatrix;
602 IDMap<Misc , Type::kMisc > fMisc;
603 IDMap<SkPath , Type::kPath > fPath;
604 IDMap<Stroke , Type::kStroke > fStroke;
605 ReffedIDMap<const SkTextBlob, Type::kTextBlob > fTextBlob;
606 ReffedIDMap<SkPathEffect , Type::kPathEffect > fPathEffect;
607 ReffedIDMap<SkShader , Type::kShader > fShader;
608 ReffedIDMap<SkXfermode , Type::kXfermode > fXfermode;
609 ReffedIDMap<SkMaskFilter , Type::kMaskFilter > fMaskFilter;
610 ReffedIDMap<SkColorFilter , Type::kColorFilter> fColorFilter;
611 ReffedIDMap<SkRasterizer , Type::kRasterizer > fRasterizer;
612 ReffedIDMap<SkDrawLooper , Type::kDrawLooper > fDrawLooper;
613 ReffedIDMap<SkImageFilter , Type::kImageFilter> fImageFilter;
614
615 SkCanvas* fCanvas;
616 uint64_t fNextID = 0;
617 };
618
619 Encoder* NewDecoder(SkCanvas* canvas) { return new Decoder(canvas); }
620
621 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
622
623 class CachingEncoder final : public Encoder {
624 public:
625 explicit CachingEncoder(Encoder* wrapped) : fWrapped(wrapped) {}
626
627 private:
628 struct Undef {
629 Encoder* fEncoder;
630 template <typename T>
631 void operator()(const T&, ID* id) const { fEncoder->undefine(*id); }
632 };
633
634 ~CachingEncoder() override {
635 Undef undef{fWrapped};
636 fMatrix .foreach(undef);
637 fMisc .foreach(undef);
638 fPath .foreach(undef);
639 fStroke .foreach(undef);
640 fTextBlob .foreach(undef);
641 fPathEffect .foreach(undef);
642 fShader .foreach(undef);
643 fXfermode .foreach(undef);
644 fMaskFilter .foreach(undef);
645 fColorFilter.foreach(undef);
646 fRasterizer .foreach(undef);
647 fDrawLooper .foreach(undef);
648 fImageFilter.foreach(undef);
649 }
650
651 template <typename Map, typename T>
652 ID define(Map* map, const T& v) {
653 if (const ID* id = map->find(v)) {
654 return *id;
655 }
656 ID id = fWrapped->define(v);
657 map->set(v, id);
658 return id;
659 }
660
661 ID define(const SkMatrix& v) override { return this->define(&fMatrix , v); }
662 ID define(const Misc& v) override { return this->define(&fMisc , v); }
663 ID define(const SkPath& v) override { return this->define(&fPath , v); }
664 ID define(const Stroke& v) override { return this->define(&fStroke , v); }
665 ID define(const SkTextBlob* v) override { return this->define(&fTextBlob , v); }
666 ID define(SkPathEffect* v) override { return this->define(&fPathEffe ct , v); }
667 ID define(SkShader* v) override { return this->define(&fShader , v); }
668 ID define(SkXfermode* v) override { return this->define(&fXfermode , v); }
669 ID define(SkMaskFilter* v) override { return this->define(&fMaskFilt er , v); }
670 ID define(SkColorFilter* v) override { return this->define(&fColorFil ter, v); }
671 ID define(SkRasterizer* v) override { return this->define(&fRasteriz er , v); }
672 ID define(SkDrawLooper* v) override { return this->define(&fDrawLoop er , v); }
673 ID define(SkImageFilter* v) override { return this->define(&fImageFil ter, v); }
674
675 void undefine(ID) override {}
676
677 void save() override { fWrapped-> save(); }
678 void restore() override { fWrapped->restore(); }
679 void saveLayer(ID bounds, CommonIDs common, SkCanvas::SaveLayerFlags fla gs) override {
680 fWrapped->saveLayer(bounds, common, flags);
681 }
682
683 void setMatrix(ID matrix) override { fWrapped->setMatrix(matrix); }
684
685 void clipPath(ID path, SkRegion::Op op, bool aa) override {
686 fWrapped->clipPath(path, op, aa);
687 }
688 void fillPath(ID path, CommonIDs common) override {
689 fWrapped->fillPath(path, common);
690 }
691 void strokePath(ID path, CommonIDs common, ID stroke) override {
692 fWrapped->strokePath(path, common, stroke);
693 }
694 void fillText(ID text, SkPoint offset, CommonIDs common) override {
695 fWrapped->fillText(text, offset, common);
696 }
697 void strokeText(ID text, SkPoint offset, CommonIDs common, ID stroke) ov erride {
698 fWrapped->strokeText(text, offset, common, stroke);
699 }
700
701 // Maps const T* -> ID, and refs the key.
702 template <typename T, Type kType>
703 class RefKeyMap {
704 public:
705 RefKeyMap() {}
706 ~RefKeyMap() { fMap.foreach([](const T* key, ID*) { SkSafeUnref(key) ; }); }
707
708 void set(const T* key, ID id) {
709 SkASSERT(id.type() == kType);
710 fMap.set(SkSafeRef(key), id);
711 }
712
713 void remove(const T* key) {
714 fMap.remove(key);
715 SkSafeUnref(key);
716 }
717
718 const ID* find(const T* key) const {
719 return fMap.find(key);
720 }
721
722 template <typename Fn>
723 void foreach(const Fn& fn) {
724 fMap.foreach(fn);
725 }
726 private:
727 SkTHashMap<const T*, ID> fMap;
728 };
729
730 SkTHashMap<SkMatrix, ID> fMatrix;
731 SkTHashMap<Misc, ID, MiscHash> fMisc;
732 SkTHashMap<SkPath, ID> fPath;
733 SkTHashMap<Stroke, ID> fStroke;
734 RefKeyMap<const SkTextBlob, Type::kTextBlob > fTextBlob;
735 RefKeyMap<SkPathEffect , Type::kPathEffect > fPathEffect;
736 RefKeyMap<SkShader , Type::kShader > fShader;
737 RefKeyMap<SkXfermode , Type::kXfermode > fXfermode;
738 RefKeyMap<SkMaskFilter , Type::kMaskFilter > fMaskFilter;
739 RefKeyMap<SkColorFilter , Type::kColorFilter> fColorFilter;
740 RefKeyMap<SkRasterizer , Type::kRasterizer > fRasterizer;
741 RefKeyMap<SkDrawLooper , Type::kDrawLooper > fDrawLooper;
742 RefKeyMap<SkImageFilter , Type::kImageFilter> fImageFilter;
743
744 Encoder* fWrapped;
745 };
746
747 Encoder* NewCachingEncoder(Encoder* wrapped) { return new CachingEncoder(wra pped); }
748
749 } // 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