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

Unified Diff: src/core/SkRemote.cpp

Issue 1409113005: SkRemote: more refactoring (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: forward declares 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkRemote.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkRemote.cpp
diff --git a/src/core/SkRemote.cpp b/src/core/SkRemote.cpp
index 21fbdf3d978a078077f2bcba953545f11874d5c7..ff658ff20d146f92158d0b6eb00678bbc31124f7 100644
--- a/src/core/SkRemote.cpp
+++ b/src/core/SkRemote.cpp
@@ -5,9 +5,12 @@
* found in the LICENSE file.
*/
+#include "SkCanvas.h"
#include "SkPath.h"
#include "SkRect.h"
#include "SkRemote.h"
+#include "SkShader.h"
+#include "SkTHash.h"
namespace SkRemote {
@@ -72,6 +75,278 @@ namespace SkRemote {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
+ 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;
+ };
+
+ template <typename T>
+ AutoID id(const T& val) { return AutoID(fEncoder, val); }
+
+ void willSave() override { fEncoder-> save(); }
+ void didRestore() override { fEncoder->restore(); }
+
+ 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 p = this->id(path),
+ m = this->id(Misc::CreateFrom(paint)),
+ s = this->id(paint.getShader()),
+ x = this->id(paint.getXfermode());
+
+ if (paint.getStyle() == SkPaint::kFill_Style) {
+ fEncoder->fillPath(p, m, s, x);
+ } else {
+ // TODO: handle kStrokeAndFill_Style
+ fEncoder->strokePath(p, m, s, x, 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 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);
+ }
+
+ void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) override {
+ SkPath path;
+ path.addRect(rect);
+ this->onClipPath(path, op, edgeStyle);
+ }
+
+ void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) override {
+ SkPath path;
+ path.addRRect(rrect);
+ this->onClipPath(path, op, edgeStyle);
+ }
+
+ void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) override {
+ fEncoder->clipPath(this->id(path), op, edgeStyle == kSoft_ClipEdgeStyle);
+ }
+
+ Encoder* fEncoder;
+ };
+
+ 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;
+ }
+
+ ID define(const SkMatrix& v) override {return this->define(Type::kMatrix, &fMatrix, v);}
+ ID define(const Misc& v) override {return this->define(Type::kMisc, &fMisc, v);}
+ ID define(const SkPath& v) override {return this->define(Type::kPath, &fPath, v);}
+ ID define(const Stroke& v) override {return this->define(Type::kStroke, &fStroke, v);}
+ ID define(SkShader* v) override {return this->define(Type::kShader, &fShader, v);}
+ ID define(SkXfermode* v) override {return this->define(Type::kXfermode, &fXfermode, v);}
+
+ 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::kShader: return fShader .remove(id);
+ case Type::kXfermode: return fXfermode.remove(id);
+ };
+ }
+
+ void save() override { fCanvas->save(); }
+ void restore() override { fCanvas->restore(); }
+
+ 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, ID misc, ID shader, ID xfermode) override {
+ SkPaint paint;
+ paint.setStyle(SkPaint::kFill_Style);
+ fMisc.find(misc).applyTo(&paint);
+ paint.setShader (fShader .find(shader));
+ paint.setXfermode(fXfermode.find(xfermode));
+ fCanvas->drawPath(fPath.find(path), paint);
+ }
+ void strokePath(ID path, ID misc, ID shader, ID xfermode, ID stroke) override {
+ SkPaint paint;
+ paint.setStyle(SkPaint::kStroke_Style);
+ fMisc .find(misc ).applyTo(&paint);
+ fStroke.find(stroke).applyTo(&paint);
+ paint.setShader (fShader .find(shader));
+ paint.setXfermode(fXfermode.find(xfermode));
+ fCanvas->drawPath(fPath.find(path), 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<SkShader , Type::kShader> fShader;
+ ReffedIDMap<SkXfermode, Type::kXfermode> fXfermode;
+
+ 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) {}
@@ -166,194 +441,6 @@ namespace SkRemote {
Encoder* fWrapped;
};
- Encoder* Encoder::CreateCachingEncoder(Encoder* wrapped) { return new CachingEncoder(wrapped); }
-
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
-
- // Calls Encoder::define() when created, Encoder::undefine() when destroyed.
- class Client::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;
- };
-
- template <typename T>
- Client::AutoID Client::id(const T& val) { return AutoID(fEncoder, val); }
-
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
-
- Client::Client(Encoder* encoder)
- : SkCanvas(1,1)
- , fEncoder(encoder)
- {}
-
- void Client::willSave() { fEncoder->save(); }
- void Client::didRestore() { fEncoder->restore(); }
-
- void Client::didConcat (const SkMatrix&) { this->didSetMatrix(this->getTotalMatrix()); }
- void Client::didSetMatrix(const SkMatrix& matrix) {
- fEncoder->setMatrix(this->id(matrix));
- }
-
- void Client::onDrawOval(const SkRect& oval, const SkPaint& paint) {
- SkPath path;
- path.addOval(oval);
- this->onDrawPath(path, paint);
- }
-
- void Client::onDrawRect(const SkRect& rect, const SkPaint& paint) {
- SkPath path;
- path.addRect(rect);
- this->onDrawPath(path, paint);
- }
-
- void Client::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
- SkPath path;
- path.addRRect(rrect);
- this->onDrawPath(path, paint);
- }
-
- void Client::onDrawDRRect(const SkRRect& outside,
- const SkRRect& inside,
- const SkPaint& paint) {
- SkPath path;
- path.addRRect(outside);
- path.addRRect(inside, SkPath::kCCW_Direction);
- this->onDrawPath(path, paint);
- }
-
- void Client::onDrawPath(const SkPath& path, const SkPaint& paint) {
- auto p = this->id(path),
- m = this->id(Misc::CreateFrom(paint)),
- s = this->id(paint.getShader()),
- x = this->id(paint.getXfermode());
-
- if (paint.getStyle() == SkPaint::kFill_Style) {
- fEncoder->fillPath(p, m, s, x);
- } else {
- // TODO: handle kStrokeAndFill_Style
- fEncoder->strokePath(p, m, s, x, this->id(Stroke::CreateFrom(paint)));
- }
- }
-
- void Client::onDrawPaint(const SkPaint& paint) {
- SkPath path;
- path.setFillType(SkPath::kInverseWinding_FillType); // Either inverse FillType works fine.
- this->onDrawPath(path, paint);
- }
-
- void Client::onDrawText(const void* text, size_t byteLength, SkScalar x,
- SkScalar y, const SkPaint& paint) {
- // 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 Client::onDrawPosText(const void* text, size_t byteLength,
- const SkPoint pos[], const SkPaint& paint) {
- // 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 Client::onDrawPosTextH(const void* text, size_t byteLength,
- const SkScalar xpos[], SkScalar constY,
- const SkPaint& paint) {
- 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);
- }
-
- void Client::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
- SkPath path;
- path.addRect(rect);
- this->onClipPath(path, op, edgeStyle);
- }
-
- void Client::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
- SkPath path;
- path.addRRect(rrect);
- this->onClipPath(path, op, edgeStyle);
- }
-
- void Client::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
- fEncoder->clipPath(this->id(path), op, edgeStyle == kSoft_ClipEdgeStyle);
- }
-
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
-
- Server::Server(SkCanvas* canvas) : fCanvas(canvas) {}
-
- template <typename Map, typename T>
- ID Server::define(Type type, Map* map, const T& val) {
- ID id(type, fNextID++);
- map->set(id, val);
- return id;
- }
-
- ID Server::define(const SkMatrix& v) { return this->define(Type::kMatrix, &fMatrix, v); }
- ID Server::define(const Misc& v) { return this->define(Type::kMisc, &fMisc, v); }
- ID Server::define(const SkPath& v) { return this->define(Type::kPath, &fPath, v); }
- ID Server::define(const Stroke& v) { return this->define(Type::kStroke, &fStroke, v); }
- ID Server::define(SkShader* v) { return this->define(Type::kShader, &fShader, v); }
- ID Server::define(SkXfermode* v) { return this->define(Type::kXfermode, &fXfermode, v); }
-
- void Server::undefine(ID id) {
- 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::kShader: return fShader .remove(id);
- case Type::kXfermode: return fXfermode.remove(id);
- };
- }
-
- void Server:: save() { fCanvas->save(); }
- void Server::restore() { fCanvas->restore(); }
-
- void Server::setMatrix(ID matrix) { fCanvas->setMatrix(fMatrix.find(matrix)); }
-
- void Server::clipPath(ID path, SkRegion::Op op, bool aa) {
- fCanvas->clipPath(fPath.find(path), op, aa);
- }
- void Server::fillPath(ID path, ID misc, ID shader, ID xfermode) {
- SkPaint paint;
- paint.setStyle(SkPaint::kFill_Style);
- fMisc.find(misc).applyTo(&paint);
- paint.setShader (fShader .find(shader));
- paint.setXfermode(fXfermode.find(xfermode));
- fCanvas->drawPath(fPath.find(path), paint);
- }
- void Server::strokePath(ID path, ID misc, ID shader, ID xfermode, ID stroke) {
- SkPaint paint;
- paint.setStyle(SkPaint::kStroke_Style);
- fMisc .find(misc ).applyTo(&paint);
- fStroke.find(stroke).applyTo(&paint);
- paint.setShader (fShader .find(shader));
- paint.setXfermode(fXfermode.find(xfermode));
- fCanvas->drawPath(fPath.find(path), paint);
- }
+ Encoder* NewCachingEncoder(Encoder* wrapped) { return new CachingEncoder(wrapped); }
} // namespace SkRemote
« no previous file with comments | « src/core/SkRemote.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698