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