Index: src/core/SkRemote.cpp |
diff --git a/src/core/SkRemote.cpp b/src/core/SkRemote.cpp |
deleted file mode 100644 |
index 9b0383d4063bfe20fe3b2a67dfd1915e3500cfb1..0000000000000000000000000000000000000000 |
--- a/src/core/SkRemote.cpp |
+++ /dev/null |
@@ -1,749 +0,0 @@ |
-/* |
- * Copyright 2015 Google Inc. |
- * |
- * Use of this source code is governed by a BSD-style license that can be |
- * found in the LICENSE file. |
- */ |
- |
-#include "SkCanvas.h" |
-#include "SkColorFilter.h" |
-#include "SkDrawLooper.h" |
-#include "SkImage.h" |
-#include "SkImageFilter.h" |
-#include "SkMaskFilter.h" |
-#include "SkNinePatchIter.h" |
-#include "SkPath.h" |
-#include "SkPathEffect.h" |
-#include "SkRasterizer.h" |
-#include "SkRect.h" |
-#include "SkRemote.h" |
-#include "SkShader.h" |
-#include "SkTHash.h" |
-#include "SkTextBlob.h" |
- |
-namespace SkRemote { |
- |
- Misc Misc::CreateFrom(const SkPaint& paint) { |
- Misc misc = { |
- paint.getColor(), |
- paint.getFilterQuality(), |
- paint.isAntiAlias(), |
- paint.isDither(), |
- }; |
- return misc; |
- } |
- |
- void Misc::applyTo(SkPaint* paint) const { |
- paint->setColor (fColor); |
- paint->setFilterQuality(fFilterQuality); |
- paint->setAntiAlias (fAntiAlias); |
- paint->setDither (fDither); |
- } |
- |
- static bool operator==(const Misc& a, const Misc& b) { |
- return a.fColor == b.fColor |
- && a.fFilterQuality == b.fFilterQuality |
- && a.fAntiAlias == b.fAntiAlias |
- && a.fDither == b.fDither; |
- } |
- |
- // Misc carries 10 bytes of data in a 12 byte struct, so we need a custom hash. |
- static_assert(sizeof(Misc) > offsetof(Misc, fDither) + sizeof(Misc().fDither), ""); |
- struct MiscHash { |
- uint32_t operator()(const Misc& misc) { |
- return SkChecksum::Murmur3(&misc, offsetof(Misc, fDither) + sizeof(Misc().fDither)); |
- } |
- }; |
- |
- Stroke Stroke::CreateFrom(const SkPaint& paint) { |
- Stroke stroke = { |
- paint.getStrokeWidth(), |
- paint.getStrokeMiter(), |
- paint.getStrokeCap(), |
- paint.getStrokeJoin(), |
- }; |
- return stroke; |
- } |
- |
- void Stroke::applyTo(SkPaint* paint) const { |
- paint->setStrokeWidth(fWidth); |
- paint->setStrokeMiter(fMiter); |
- paint->setStrokeCap (fCap); |
- paint->setStrokeJoin (fJoin); |
- } |
- |
- static bool operator==(const Stroke& a, const Stroke& b) { |
- return a.fWidth == b.fWidth |
- && a.fMiter == b.fMiter |
- && a.fCap == b.fCap |
- && a.fJoin == b.fJoin; |
- } |
- |
- // The default SkGoodHash works fine for Stroke, as it's dense. |
- static_assert(sizeof(Stroke) == offsetof(Stroke, fJoin) + sizeof(Stroke().fJoin), ""); |
- |
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // |
- |
- class Canvas final : public SkCanvas { |
- public: |
- explicit Canvas(Encoder* encoder) |
- : SkCanvas(1,1) |
- , fEncoder(encoder) {} |
- |
- private: |
- // Calls Encoder::define() when created, Encoder::undefine() when destroyed. |
- class AutoID : ::SkNoncopyable { |
- public: |
- template <typename T> |
- explicit AutoID(Encoder* encoder, const T& val) |
- : fEncoder(encoder) |
- , fID(encoder->define(val)) {} |
- ~AutoID() { if (fEncoder) fEncoder->undefine(fID); } |
- |
- AutoID(AutoID&& o) : fEncoder(o.fEncoder), fID(o.fID) { |
- o.fEncoder = nullptr; |
- } |
- AutoID& operator=(AutoID&&) = delete; |
- |
- operator ID () const { return fID; } |
- |
- private: |
- Encoder* fEncoder; |
- const ID fID; |
- }; |
- |
- // Like AutoID, but for CommonIDs. |
- class AutoCommonIDs : ::SkNoncopyable { |
- public: |
- explicit AutoCommonIDs(Encoder* encoder, const SkPaint& paint) |
- : fEncoder(encoder) { |
- fIDs.misc = fEncoder->define(Misc::CreateFrom(paint)); |
- fIDs.patheffect = fEncoder->define(paint.getPathEffect()); |
- fIDs.shader = fEncoder->define(paint.getShader()); |
- fIDs.xfermode = fEncoder->define(paint.getXfermode()); |
- fIDs.maskfilter = fEncoder->define(paint.getMaskFilter()); |
- fIDs.colorfilter = fEncoder->define(paint.getColorFilter()); |
- fIDs.rasterizer = fEncoder->define(paint.getRasterizer()); |
- fIDs.looper = fEncoder->define(paint.getLooper()); |
- fIDs.imagefilter = fEncoder->define(paint.getImageFilter()); |
- } |
- ~AutoCommonIDs() { |
- if (fEncoder) { |
- fEncoder->undefine(fIDs.misc); |
- fEncoder->undefine(fIDs.patheffect); |
- fEncoder->undefine(fIDs.shader); |
- fEncoder->undefine(fIDs.xfermode); |
- fEncoder->undefine(fIDs.maskfilter); |
- fEncoder->undefine(fIDs.colorfilter); |
- fEncoder->undefine(fIDs.rasterizer); |
- fEncoder->undefine(fIDs.looper); |
- fEncoder->undefine(fIDs.imagefilter); |
- } |
- } |
- |
- AutoCommonIDs(AutoCommonIDs&& o) : fEncoder(o.fEncoder), fIDs(o.fIDs) { |
- o.fEncoder = nullptr; |
- } |
- AutoID& operator=(AutoID&&) = delete; |
- |
- operator Encoder::CommonIDs () const { return fIDs; } |
- |
- private: |
- Encoder* fEncoder; |
- Encoder::CommonIDs fIDs; |
- }; |
- |
- template <typename T> |
- AutoID id(const T& val) { return AutoID(fEncoder, val); } |
- |
- AutoCommonIDs commonIDs(const SkPaint& paint) { return AutoCommonIDs(fEncoder, paint); } |
- |
- void willSave() override { fEncoder-> save(); } |
- void didRestore() override { fEncoder->restore(); } |
- SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override { |
- SkPath path; |
- if (rec.fBounds) { |
- path.addRect(*rec.fBounds); |
- } |
- const SkPaint defaultPaint; |
- const SkPaint* paint = rec.fPaint; |
- if (!paint) { |
- paint = &defaultPaint; |
- } |
- fEncoder->saveLayer(this->id(path), this->commonIDs(*paint), rec.fSaveLayerFlags); |
- return kNoLayer_SaveLayerStrategy; |
- } |
- |
- void didConcat(const SkMatrix&) override { this->didSetMatrix(this->getTotalMatrix()); } |
- void didSetMatrix(const SkMatrix& matrix) override { |
- fEncoder->setMatrix(this->id(matrix)); |
- } |
- |
- void onDrawOval(const SkRect& oval, const SkPaint& paint) override { |
- SkPath path; |
- path.addOval(oval); |
- this->onDrawPath(path, paint); |
- } |
- |
- void onDrawRect(const SkRect& rect, const SkPaint& paint) override { |
- SkPath path; |
- path.addRect(rect); |
- this->onDrawPath(path, paint); |
- } |
- |
- void onDrawRRect(const SkRRect& rrect, const SkPaint& paint) override { |
- SkPath path; |
- path.addRRect(rrect); |
- this->onDrawPath(path, paint); |
- } |
- |
- void onDrawDRRect(const SkRRect& outside, const SkRRect& inside, |
- const SkPaint& paint) override { |
- SkPath path; |
- path.addRRect(outside); |
- path.addRRect(inside, SkPath::kCCW_Direction); |
- this->onDrawPath(path, paint); |
- } |
- |
- void onDrawPath(const SkPath& path, const SkPaint& paint) override { |
- auto common = this->commonIDs(paint); |
- auto p = this->id(path); |
- |
- if (paint.getStyle() == SkPaint::kFill_Style) { |
- fEncoder->fillPath(p, common); |
- } else { |
- // TODO: handle kStrokeAndFill_Style |
- fEncoder->strokePath(p, common, this->id(Stroke::CreateFrom(paint))); |
- } |
- } |
- |
- void onDrawPaint(const SkPaint& paint) override { |
- SkPath path; |
- path.setFillType(SkPath::kInverseWinding_FillType); // Either inverse FillType is fine. |
- this->onDrawPath(path, paint); |
- } |
- |
- void onDrawPoints(PointMode mode, |
- size_t count, |
- const SkPoint pts[], |
- const SkPaint& paint) override { |
- // TODO |
- } |
- |
- void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override { |
- // TODO |
- this->INHERITED::onDrawDrawable(drawable, matrix); |
- } |
- |
- void onDrawPicture(const SkPicture* pic, |
- const SkMatrix* matrix, |
- const SkPaint* paint) override { |
- // TODO |
- this->INHERITED::onDrawPicture(pic, matrix, paint); |
- } |
- |
- void 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) override { |
- // TODO |
- } |
- |
- void onDrawPatch(const SkPoint cubics[12], |
- const SkColor colors[4], |
- const SkPoint texCoords[4], |
- SkXfermode* xmode, |
- const SkPaint& paint) override { |
- // TODO |
- } |
- |
- void onDrawAtlas(const SkImage* atlas, |
- const SkRSXform xform[], |
- const SkRect tex[], |
- const SkColor colors[], |
- int count, |
- SkXfermode::Mode mode, |
- const SkRect* cull, |
- const SkPaint* paint) override { |
- // TODO |
- } |
- |
- void onDrawBitmap(const SkBitmap& bitmap, |
- SkScalar left, |
- SkScalar top, |
- const SkPaint* paint) override { |
- auto src = SkRect::MakeWH(bitmap.width(), bitmap.height()), |
- dst = src.makeOffset(left, top); |
- this->onDrawBitmapRect(bitmap, &src, dst, paint, kStrict_SrcRectConstraint); |
- } |
- |
- void onDrawBitmapRect(const SkBitmap& bitmap, |
- const SkRect* src, |
- const SkRect& dst, |
- const SkPaint* paint, |
- SrcRectConstraint constraint) override { |
- SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(bitmap)); |
- this->onDrawImageRect(image, src, dst, paint, constraint); |
- } |
- |
- void onDrawImage(const SkImage* image, |
- SkScalar left, |
- SkScalar top, |
- const SkPaint* paint) override { |
- if (!image) { |
- return; |
- } |
- auto src = SkRect::MakeWH(image->width(), image->height()), |
- dst = src.makeOffset(left, top); |
- this->onDrawImageRect(image, &src, dst, paint, kStrict_SrcRectConstraint); |
- } |
- |
- void onDrawImageRect(const SkImage* image, |
- const SkRect* src, |
- const SkRect& dst, |
- const SkPaint* paint, |
- SrcRectConstraint constraint) override { |
- // TODO: this is all a (likely buggy) hack to get images drawing quickly. |
- if (!image) { |
- return; |
- } |
- |
- auto bounds = SkRect::MakeWH(image->width(), image->height()); |
- if (!src) { |
- src = &bounds; |
- } |
- auto matrix = SkMatrix::MakeRectToRect(*src, dst, SkMatrix::kFill_ScaleToFit); |
- |
- SkAutoTUnref<SkImage> subset; |
- if (src) { |
- if (!bounds.intersect(*src)) { |
- return; |
- } |
- subset.reset(image->newSubset(bounds.roundOut())); |
- image = subset; |
- } |
- |
- auto paintWithShader = paint ? *paint : SkPaint(); |
- SkAutoTUnref<SkShader> shader( |
- image->newShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &matrix)); |
- paintWithShader.setShader(shader); |
- |
- this->onDrawRect(dst, paintWithShader); |
- } |
- |
- void onDrawBitmapNine(const SkBitmap& bitmap, |
- const SkIRect& center, |
- const SkRect& dst, |
- const SkPaint* paint) override { |
- SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(bitmap)); |
- this->onDrawImageNine(image, center, dst, paint); |
- } |
- |
- void onDrawImageNine(const SkImage* image, |
- const SkIRect& center, |
- const SkRect& dst, |
- const SkPaint* paint) override { |
- SkNinePatchIter iter(image->width(), image->height(), center, dst); |
- SkRect s,d; |
- while (iter.next(&s, &d)) { |
- this->onDrawImageRect(image, &s, d, paint, kStrict_SrcRectConstraint); |
- } |
- } |
- |
- void onDrawTextBlob(const SkTextBlob* text, |
- SkScalar x, |
- SkScalar y, |
- const SkPaint& paint) override { |
- SkPoint offset{x,y}; |
- auto t = this->id(text); |
- auto common = this->commonIDs(paint); |
- |
- if (paint.getStyle() == SkPaint::kFill_Style) { |
- fEncoder->fillText(t, offset, common); |
- } else { |
- // TODO: handle kStrokeAndFill_Style |
- fEncoder->strokeText(t, offset, common, this->id(Stroke::CreateFrom(paint))); |
- } |
- } |
- |
- void onDrawText(const void* text, size_t byteLength, |
- SkScalar x, SkScalar y, const SkPaint& paint) override { |
- // Text-as-paths is a temporary hack. |
- // TODO: send SkTextBlobs and SkTypefaces |
- SkPath path; |
- paint.getTextPath(text, byteLength, x, y, &path); |
- this->onDrawPath(path, paint); |
- } |
- |
- void onDrawPosText(const void* text, size_t byteLength, |
- const SkPoint pos[], const SkPaint& paint) override { |
- // Text-as-paths is a temporary hack. |
- // TODO: send SkTextBlobs and SkTypefaces |
- SkPath path; |
- paint.getPosTextPath(text, byteLength, pos, &path); |
- this->onDrawPath(path, paint); |
- } |
- |
- void onDrawPosTextH(const void* text, size_t byteLength, |
- const SkScalar xpos[], SkScalar constY, const SkPaint& paint) override { |
- size_t length = paint.countText(text, byteLength); |
- SkAutoTArray<SkPoint> pos(length); |
- for(size_t i = 0; i < length; ++i) { |
- pos[i].set(xpos[i], constY); |
- } |
- this->onDrawPosText(text, byteLength, &pos[0], paint); |
- } |
- |
- // All clip calls need to call their parent method or we'll not get any quick rejects. |
- void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) override { |
- this->INHERITED::onClipRect(rect, op, edgeStyle); |
- SkPath path; |
- path.addRect(rect); |
- this->onClipPath(path, op, edgeStyle); |
- } |
- |
- void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) override { |
- this->INHERITED::onClipRRect(rrect, op, edgeStyle); |
- SkPath path; |
- path.addRRect(rrect); |
- this->onClipPath(path, op, edgeStyle); |
- } |
- |
- void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) override { |
- this->INHERITED::onClipPath(path, op, edgeStyle); |
- fEncoder->clipPath(this->id(path), op, edgeStyle == kSoft_ClipEdgeStyle); |
- } |
- |
- void onClipRegion(const SkRegion& region, SkRegion::Op op) override { |
- this->INHERITED::onClipRegion(region, op); |
- // TODO |
- } |
- |
- Encoder* fEncoder; |
- typedef SkCanvas INHERITED; |
- }; |
- |
- SkCanvas* NewCanvas(Encoder* encoder) { return new Canvas(encoder); } |
- |
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // |
- |
- class Decoder final : public Encoder { |
- public: |
- explicit Decoder(SkCanvas* canvas) : fCanvas(canvas) {} |
- |
- private: |
- template <typename Map, typename T> |
- ID define(Type type, Map* map, const T& val) { |
- ID id(type, fNextID++); |
- map->set(id, val); |
- return id; |
- } |
- |
- #define O override |
- ID define(const SkMatrix& v)O{return this->define(Type::kMatrix, &fMatrix, v);} |
- ID define(const Misc& v)O{return this->define(Type::kMisc, &fMisc, v);} |
- ID define(const SkPath& v)O{return this->define(Type::kPath, &fPath, v);} |
- ID define(const Stroke& v)O{return this->define(Type::kStroke, &fStroke, v);} |
- ID define(const SkTextBlob* v)O{return this->define(Type::kTextBlob, &fTextBlob, v);} |
- ID define(SkPathEffect* v)O{return this->define(Type::kPathEffect, &fPathEffect, v);} |
- ID define(SkShader* v)O{return this->define(Type::kShader, &fShader, v);} |
- ID define(SkXfermode* v)O{return this->define(Type::kXfermode, &fXfermode, v);} |
- ID define(SkMaskFilter* v)O{return this->define(Type::kMaskFilter, &fMaskFilter, v);} |
- ID define(SkColorFilter* v)O{return this->define(Type::kColorFilter, &fColorFilter, v);} |
- ID define(SkRasterizer* v)O{return this->define(Type::kRasterizer, &fRasterizer, v);} |
- ID define(SkDrawLooper* v)O{return this->define(Type::kDrawLooper, &fDrawLooper, v);} |
- ID define(SkImageFilter* v)O{return this->define(Type::kImageFilter, &fImageFilter, v);} |
- #undef O |
- |
- |
- void undefine(ID id) override { |
- switch(id.type()) { |
- case Type::kMatrix: return fMatrix .remove(id); |
- case Type::kMisc: return fMisc .remove(id); |
- case Type::kPath: return fPath .remove(id); |
- case Type::kStroke: return fStroke .remove(id); |
- case Type::kTextBlob: return fTextBlob .remove(id); |
- case Type::kPathEffect: return fPathEffect .remove(id); |
- case Type::kShader: return fShader .remove(id); |
- case Type::kXfermode: return fXfermode .remove(id); |
- case Type::kMaskFilter: return fMaskFilter .remove(id); |
- case Type::kColorFilter: return fColorFilter.remove(id); |
- case Type::kRasterizer: return fRasterizer .remove(id); |
- case Type::kDrawLooper: return fDrawLooper .remove(id); |
- case Type::kImageFilter: return fImageFilter.remove(id); |
- }; |
- } |
- |
- void applyCommon(const CommonIDs& common, SkPaint* paint) const { |
- fMisc.find(common.misc).applyTo(paint); |
- paint->setPathEffect (fPathEffect .find(common.patheffect)); |
- paint->setShader (fShader .find(common.shader)); |
- paint->setXfermode (fXfermode .find(common.xfermode)); |
- paint->setMaskFilter (fMaskFilter .find(common.maskfilter)); |
- paint->setColorFilter(fColorFilter.find(common.colorfilter)); |
- paint->setRasterizer (fRasterizer .find(common.rasterizer)); |
- paint->setLooper (fDrawLooper .find(common.looper)); |
- paint->setImageFilter(fImageFilter.find(common.imagefilter)); |
- } |
- |
- void save() override { fCanvas->save(); } |
- void restore() override { fCanvas->restore(); } |
- void saveLayer(ID bounds, CommonIDs common, SkCanvas::SaveLayerFlags flags) override { |
- SkPaint paint; |
- this->applyCommon(common, &paint); |
- SkRect rect; |
- |
- fCanvas->saveLayer({ fPath.find(bounds).isRect(&rect) ? &rect : nullptr, |
- &paint, flags }); |
- } |
- |
- void setMatrix(ID matrix) override { fCanvas->setMatrix(fMatrix.find(matrix)); } |
- |
- void clipPath(ID path, SkRegion::Op op, bool aa) override { |
- fCanvas->clipPath(fPath.find(path), op, aa); |
- } |
- void fillPath(ID path, CommonIDs common) override { |
- SkPaint paint; |
- paint.setStyle(SkPaint::kFill_Style); |
- this->applyCommon(common, &paint); |
- fCanvas->drawPath(fPath.find(path), paint); |
- } |
- void strokePath(ID path, CommonIDs common, ID stroke) override { |
- SkPaint paint; |
- paint.setStyle(SkPaint::kStroke_Style); |
- this->applyCommon(common, &paint); |
- fStroke.find(stroke).applyTo(&paint); |
- fCanvas->drawPath(fPath.find(path), paint); |
- } |
- void fillText(ID text, SkPoint offset, CommonIDs common) override { |
- SkPaint paint; |
- paint.setStyle(SkPaint::kFill_Style); |
- this->applyCommon(common, &paint); |
- fCanvas->drawTextBlob(fTextBlob.find(text), offset.x(), offset.y(), paint); |
- } |
- void strokeText(ID text, SkPoint offset, CommonIDs common, ID stroke) override { |
- SkPaint paint; |
- this->applyCommon(common, &paint); |
- fStroke.find(stroke).applyTo(&paint); |
- fCanvas->drawTextBlob(fTextBlob.find(text), offset.x(), offset.y(), paint); |
- } |
- |
- // Maps ID -> T. |
- template <typename T, Type kType> |
- class IDMap { |
- public: |
- ~IDMap() { |
- // A well-behaved client always cleans up its definitions. |
- SkASSERT(fMap.count() == 0); |
- } |
- |
- void set(const ID& id, const T& val) { |
- SkASSERT(id.type() == kType); |
- fMap.set(id, val); |
- } |
- |
- void remove(const ID& id) { |
- SkASSERT(id.type() == kType); |
- fMap.remove(id); |
- } |
- |
- const T& find(const ID& id) const { |
- SkASSERT(id.type() == kType); |
- T* val = fMap.find(id); |
- SkASSERT(val != nullptr); |
- return *val; |
- } |
- |
- private: |
- SkTHashMap<ID, T> fMap; |
- }; |
- |
- // Maps ID -> T*, and keeps the T alive by reffing it. |
- template <typename T, Type kType> |
- class ReffedIDMap { |
- public: |
- ReffedIDMap() {} |
- ~ReffedIDMap() { |
- // A well-behaved client always cleans up its definitions. |
- SkASSERT(fMap.count() == 0); |
- } |
- |
- void set(const ID& id, T* val) { |
- SkASSERT(id.type() == kType); |
- fMap.set(id, SkSafeRef(val)); |
- } |
- |
- void remove(const ID& id) { |
- SkASSERT(id.type() == kType); |
- T** val = fMap.find(id); |
- SkASSERT(val); |
- SkSafeUnref(*val); |
- fMap.remove(id); |
- } |
- |
- T* find(const ID& id) const { |
- SkASSERT(id.type() == kType); |
- T** val = fMap.find(id); |
- SkASSERT(val); |
- return *val; |
- } |
- |
- private: |
- SkTHashMap<ID, T*> fMap; |
- }; |
- |
- |
- IDMap<SkMatrix , Type::kMatrix > fMatrix; |
- IDMap<Misc , Type::kMisc > fMisc; |
- IDMap<SkPath , Type::kPath > fPath; |
- IDMap<Stroke , Type::kStroke > fStroke; |
- ReffedIDMap<const SkTextBlob, Type::kTextBlob > fTextBlob; |
- ReffedIDMap<SkPathEffect , Type::kPathEffect > fPathEffect; |
- ReffedIDMap<SkShader , Type::kShader > fShader; |
- ReffedIDMap<SkXfermode , Type::kXfermode > fXfermode; |
- ReffedIDMap<SkMaskFilter , Type::kMaskFilter > fMaskFilter; |
- ReffedIDMap<SkColorFilter , Type::kColorFilter> fColorFilter; |
- ReffedIDMap<SkRasterizer , Type::kRasterizer > fRasterizer; |
- ReffedIDMap<SkDrawLooper , Type::kDrawLooper > fDrawLooper; |
- ReffedIDMap<SkImageFilter , Type::kImageFilter> fImageFilter; |
- |
- SkCanvas* fCanvas; |
- uint64_t fNextID = 0; |
- }; |
- |
- Encoder* NewDecoder(SkCanvas* canvas) { return new Decoder(canvas); } |
- |
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // |
- |
- class CachingEncoder final : public Encoder { |
- public: |
- explicit CachingEncoder(Encoder* wrapped) : fWrapped(wrapped) {} |
- |
- private: |
- struct Undef { |
- Encoder* fEncoder; |
- template <typename T> |
- void operator()(const T&, ID* id) const { fEncoder->undefine(*id); } |
- }; |
- |
- ~CachingEncoder() override { |
- Undef undef{fWrapped}; |
- fMatrix .foreach(undef); |
- fMisc .foreach(undef); |
- fPath .foreach(undef); |
- fStroke .foreach(undef); |
- fTextBlob .foreach(undef); |
- fPathEffect .foreach(undef); |
- fShader .foreach(undef); |
- fXfermode .foreach(undef); |
- fMaskFilter .foreach(undef); |
- fColorFilter.foreach(undef); |
- fRasterizer .foreach(undef); |
- fDrawLooper .foreach(undef); |
- fImageFilter.foreach(undef); |
- } |
- |
- template <typename Map, typename T> |
- ID define(Map* map, const T& v) { |
- if (const ID* id = map->find(v)) { |
- return *id; |
- } |
- ID id = fWrapped->define(v); |
- map->set(v, id); |
- return id; |
- } |
- |
- ID define(const SkMatrix& v) override { return this->define(&fMatrix , v); } |
- ID define(const Misc& v) override { return this->define(&fMisc , v); } |
- ID define(const SkPath& v) override { return this->define(&fPath , v); } |
- ID define(const Stroke& v) override { return this->define(&fStroke , v); } |
- ID define(const SkTextBlob* v) override { return this->define(&fTextBlob , v); } |
- ID define(SkPathEffect* v) override { return this->define(&fPathEffect , v); } |
- ID define(SkShader* v) override { return this->define(&fShader , v); } |
- ID define(SkXfermode* v) override { return this->define(&fXfermode , v); } |
- ID define(SkMaskFilter* v) override { return this->define(&fMaskFilter , v); } |
- ID define(SkColorFilter* v) override { return this->define(&fColorFilter, v); } |
- ID define(SkRasterizer* v) override { return this->define(&fRasterizer , v); } |
- ID define(SkDrawLooper* v) override { return this->define(&fDrawLooper , v); } |
- ID define(SkImageFilter* v) override { return this->define(&fImageFilter, v); } |
- |
- void undefine(ID) override {} |
- |
- void save() override { fWrapped-> save(); } |
- void restore() override { fWrapped->restore(); } |
- void saveLayer(ID bounds, CommonIDs common, SkCanvas::SaveLayerFlags flags) override { |
- fWrapped->saveLayer(bounds, common, flags); |
- } |
- |
- void setMatrix(ID matrix) override { fWrapped->setMatrix(matrix); } |
- |
- void clipPath(ID path, SkRegion::Op op, bool aa) override { |
- fWrapped->clipPath(path, op, aa); |
- } |
- void fillPath(ID path, CommonIDs common) override { |
- fWrapped->fillPath(path, common); |
- } |
- void strokePath(ID path, CommonIDs common, ID stroke) override { |
- fWrapped->strokePath(path, common, stroke); |
- } |
- void fillText(ID text, SkPoint offset, CommonIDs common) override { |
- fWrapped->fillText(text, offset, common); |
- } |
- void strokeText(ID text, SkPoint offset, CommonIDs common, ID stroke) override { |
- fWrapped->strokeText(text, offset, common, stroke); |
- } |
- |
- // Maps const T* -> ID, and refs the key. |
- template <typename T, Type kType> |
- class RefKeyMap { |
- public: |
- RefKeyMap() {} |
- ~RefKeyMap() { fMap.foreach([](const T* key, ID*) { SkSafeUnref(key); }); } |
- |
- void set(const T* key, ID id) { |
- SkASSERT(id.type() == kType); |
- fMap.set(SkSafeRef(key), id); |
- } |
- |
- void remove(const T* key) { |
- fMap.remove(key); |
- SkSafeUnref(key); |
- } |
- |
- const ID* find(const T* key) const { |
- return fMap.find(key); |
- } |
- |
- template <typename Fn> |
- void foreach(const Fn& fn) { |
- fMap.foreach(fn); |
- } |
- private: |
- SkTHashMap<const T*, ID> fMap; |
- }; |
- |
- SkTHashMap<SkMatrix, ID> fMatrix; |
- SkTHashMap<Misc, ID, MiscHash> fMisc; |
- SkTHashMap<SkPath, ID> fPath; |
- SkTHashMap<Stroke, ID> fStroke; |
- RefKeyMap<const SkTextBlob, Type::kTextBlob > fTextBlob; |
- RefKeyMap<SkPathEffect , Type::kPathEffect > fPathEffect; |
- RefKeyMap<SkShader , Type::kShader > fShader; |
- RefKeyMap<SkXfermode , Type::kXfermode > fXfermode; |
- RefKeyMap<SkMaskFilter , Type::kMaskFilter > fMaskFilter; |
- RefKeyMap<SkColorFilter , Type::kColorFilter> fColorFilter; |
- RefKeyMap<SkRasterizer , Type::kRasterizer > fRasterizer; |
- RefKeyMap<SkDrawLooper , Type::kDrawLooper > fDrawLooper; |
- RefKeyMap<SkImageFilter , Type::kImageFilter> fImageFilter; |
- |
- Encoder* fWrapped; |
- }; |
- |
- Encoder* NewCachingEncoder(Encoder* wrapped) { return new CachingEncoder(wrapped); } |
- |
-} // namespace SkRemote |