| Index: src/core/SkRemote.cpp
|
| diff --git a/src/core/SkRemote.cpp b/src/core/SkRemote.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ae14a47d187b4b28d2b1acfd8913d57638de60ef
|
| --- /dev/null
|
| +++ b/src/core/SkRemote.cpp
|
| @@ -0,0 +1,269 @@
|
| +/*
|
| + * 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 "SkPath.h"
|
| +#include "SkRect.h"
|
| +#include "SkRemote.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;
|
| + }
|
| +
|
| + 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;
|
| + }
|
| +
|
| + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
| +
|
| + Cache* Cache::CreateNeverCache() {
|
| + struct NeverCache final : public Cache {
|
| + NeverCache()
|
| + : fNextMatrix(Type::kMatrix)
|
| + , fNextMisc (Type::kMisc)
|
| + , fNextPath (Type::kPath)
|
| + , fNextStroke(Type::kStroke)
|
| + {}
|
| + void cleanup(Encoder*) override {}
|
| +
|
| + static bool Helper(ID* next, ID* id, LookupScope* ls) {
|
| + *id = (*next)++;
|
| + ls->undefineWhenDone(*id);
|
| + return false;
|
| + }
|
| +
|
| + bool lookup(const SkMatrix&, ID* id, LookupScope* ls) override {
|
| + return Helper(&fNextMatrix, id, ls);
|
| + }
|
| + bool lookup(const Misc&, ID* id, LookupScope* ls) override {
|
| + return Helper(&fNextMisc, id, ls);
|
| + }
|
| + bool lookup(const SkPath&, ID* id, LookupScope* ls) override {
|
| + return Helper(&fNextPath, id, ls);
|
| + }
|
| + bool lookup(const Stroke&, ID* id, LookupScope* ls) override {
|
| + return Helper(&fNextStroke, id, ls);
|
| + }
|
| +
|
| + ID fNextMatrix,
|
| + fNextMisc,
|
| + fNextPath,
|
| + fNextStroke;
|
| + };
|
| + return new NeverCache;
|
| + }
|
| +
|
| + // Can't be declared locally inside AlwaysCache because of the templating. :(
|
| + template <typename T, typename Map>
|
| + static bool always_cache_helper(const T& val, Map* map, ID* next, ID* id) {
|
| + if (ID* found = map->find(val)) {
|
| + *id = *found;
|
| + return true;
|
| + }
|
| + *id = (*next)++;
|
| + map->set(val, *id);
|
| + return false;
|
| + }
|
| +
|
| + Cache* Cache::CreateAlwaysCache() {
|
| + struct AlwaysCache final : public Cache {
|
| + AlwaysCache()
|
| + : fNextMatrix(Type::kMatrix)
|
| + , fNextMisc (Type::kMisc)
|
| + , fNextPath (Type::kPath)
|
| + , fNextStroke(Type::kStroke)
|
| + {}
|
| +
|
| + void cleanup(Encoder* encoder) override {
|
| + fMatrix.foreach([=](const SkMatrix&, ID* id) { encoder->undefine(*id); });
|
| + fMisc .foreach([=](const Misc&, ID* id) { encoder->undefine(*id); });
|
| + fPath .foreach([=](const SkPath&, ID* id) { encoder->undefine(*id); });
|
| + fStroke.foreach([=](const Stroke&, ID* id) { encoder->undefine(*id); });
|
| + }
|
| +
|
| +
|
| + bool lookup(const SkMatrix& matrix, ID* id, LookupScope*) override {
|
| + return always_cache_helper(matrix, &fMatrix, &fNextMatrix, id);
|
| + }
|
| + bool lookup(const Misc& misc, ID* id, LookupScope*) override {
|
| + return always_cache_helper(misc, &fMisc, &fNextMisc, id);
|
| + }
|
| + bool lookup(const SkPath& path, ID* id, LookupScope*) override {
|
| + return always_cache_helper(path, &fPath, &fNextPath, id);
|
| + }
|
| + bool lookup(const Stroke& stroke, ID* id, LookupScope*) override {
|
| + return always_cache_helper(stroke, &fStroke, &fNextStroke, id);
|
| + }
|
| +
|
| + SkTHashMap<SkMatrix, ID> fMatrix;
|
| + SkTHashMap<Misc, ID> fMisc;
|
| + SkTHashMap<SkPath, ID> fPath;
|
| + SkTHashMap<Stroke, ID> fStroke;
|
| + ID fNextMatrix,
|
| + fNextMisc,
|
| + fNextPath,
|
| + fNextStroke;
|
| + };
|
| + return new AlwaysCache;
|
| + }
|
| +
|
| + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
| +
|
| + Client::Client(Cache* cache, Encoder* encoder)
|
| + : SkCanvas(1,1)
|
| + , fCache(cache)
|
| + , fEncoder(encoder)
|
| + {}
|
| +
|
| + Client::~Client() {
|
| + fCache->cleanup(fEncoder);
|
| + }
|
| +
|
| + template <typename T>
|
| + ID LookupScope::lookup(const T& val) {
|
| + ID id;
|
| + if (!fCache->lookup(val, &id, this)) {
|
| + fEncoder->define(id, val);
|
| + }
|
| + return id;
|
| + }
|
| +
|
| + 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) {
|
| + LookupScope ls(fCache, fEncoder);
|
| + fEncoder->setMatrix(ls.lookup(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::onDrawPath(const SkPath& path, const SkPaint& paint) {
|
| + LookupScope ls(fCache, fEncoder);
|
| + ID p = ls.lookup(path),
|
| + m = ls.lookup(Misc::CreateFrom(paint));
|
| +
|
| + if (paint.getStyle() == SkPaint::kFill_Style) {
|
| + fEncoder->fillPath(p, m);
|
| + } else {
|
| + // TODO: handle kStrokeAndFill_Style
|
| + fEncoder->strokePath(p, m, ls.lookup(Stroke::CreateFrom(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) {
|
| + LookupScope ls(fCache, fEncoder);
|
| + fEncoder->clipPath(ls.lookup(path), op, edgeStyle == kSoft_ClipEdgeStyle);
|
| + }
|
| +
|
| + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
|
| +
|
| + Server::Server(SkCanvas* canvas) : fCanvas(canvas) {}
|
| +
|
| + void Server::define(ID id, const SkMatrix& v) { fMatrix.set(id, v); }
|
| + void Server::define(ID id, const Misc& v) { fMisc .set(id, v); }
|
| + void Server::define(ID id, const SkPath& v) { fPath .set(id, v); }
|
| + void Server::define(ID id, const Stroke& v) { fStroke.set(id, 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::kNone: SkASSERT(false);
|
| + };
|
| + }
|
| +
|
| + 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) {
|
| + SkPaint paint;
|
| + paint.setStyle(SkPaint::kFill_Style);
|
| + fMisc.find(misc).applyTo(&paint);
|
| + fCanvas->drawPath(fPath.find(path), paint);
|
| + }
|
| + void Server::strokePath(ID path, ID misc, ID stroke) {
|
| + SkPaint paint;
|
| + paint.setStyle(SkPaint::kStroke_Style);
|
| + fMisc .find(misc ).applyTo(&paint);
|
| + fStroke.find(stroke).applyTo(&paint);
|
| + fCanvas->drawPath(fPath.find(path), paint);
|
| + }
|
| +
|
| +} // namespace SkRemote
|
|
|