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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « src/core/SkRemote.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkCanvas.h"
8 #include "SkPath.h" 9 #include "SkPath.h"
9 #include "SkRect.h" 10 #include "SkRect.h"
10 #include "SkRemote.h" 11 #include "SkRemote.h"
12 #include "SkShader.h"
13 #include "SkTHash.h"
11 14
12 namespace SkRemote { 15 namespace SkRemote {
13 16
14 Misc Misc::CreateFrom(const SkPaint& paint) { 17 Misc Misc::CreateFrom(const SkPaint& paint) {
15 Misc misc = { 18 Misc misc = {
16 paint.getColor(), 19 paint.getColor(),
17 paint.getFilterQuality(), 20 paint.getFilterQuality(),
18 paint.isAntiAlias(), 21 paint.isAntiAlias(),
19 paint.isDither(), 22 paint.isDither(),
20 }; 23 };
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 && a.fMiter == b.fMiter 68 && a.fMiter == b.fMiter
66 && a.fCap == b.fCap 69 && a.fCap == b.fCap
67 && a.fJoin == b.fJoin; 70 && a.fJoin == b.fJoin;
68 } 71 }
69 72
70 // The default SkGoodHash works fine for Stroke, as it's dense. 73 // The default SkGoodHash works fine for Stroke, as it's dense.
71 static_assert(sizeof(Stroke) == offsetof(Stroke, fJoin) + sizeof(Stroke().fJ oin), ""); 74 static_assert(sizeof(Stroke) == offsetof(Stroke, fJoin) + sizeof(Stroke().fJ oin), "");
72 75
73 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 76 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
74 77
78 class Canvas final : public SkCanvas {
79 public:
80 explicit Canvas(Encoder* encoder)
81 : SkCanvas(1,1)
82 , fEncoder(encoder) {}
83
84 private:
85 // Calls Encoder::define() when created, Encoder::undefine() when destro yed.
86 class AutoID : ::SkNoncopyable {
87 public:
88 template <typename T>
89 explicit AutoID(Encoder* encoder, const T& val)
90 : fEncoder(encoder)
91 , fID(encoder->define(val)) {}
92 ~AutoID() { if (fEncoder) fEncoder->undefine(fID); }
93
94 AutoID(AutoID&& o) : fEncoder(o.fEncoder), fID(o.fID) {
95 o.fEncoder = nullptr;
96 }
97 AutoID& operator=(AutoID&&) = delete;
98
99 operator ID () const { return fID; }
100
101 private:
102 Encoder* fEncoder;
103 const ID fID;
104 };
105
106 template <typename T>
107 AutoID id(const T& val) { return AutoID(fEncoder, val); }
108
109 void willSave() override { fEncoder-> save(); }
110 void didRestore() override { fEncoder->restore(); }
111
112 void didConcat(const SkMatrix&) override { this->didSetMatrix(this->g etTotalMatrix()); }
113 void didSetMatrix(const SkMatrix& matrix) override {
114 fEncoder->setMatrix(this->id(matrix));
115 }
116
117 void onDrawOval(const SkRect& oval, const SkPaint& paint) override {
118 SkPath path;
119 path.addOval(oval);
120 this->onDrawPath(path, paint);
121 }
122
123 void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
124 SkPath path;
125 path.addRect(rect);
126 this->onDrawPath(path, paint);
127 }
128
129 void onDrawRRect(const SkRRect& rrect, const SkPaint& paint) override {
130 SkPath path;
131 path.addRRect(rrect);
132 this->onDrawPath(path, paint);
133 }
134
135 void onDrawDRRect(const SkRRect& outside, const SkRRect& inside,
136 const SkPaint& paint) override {
137 SkPath path;
138 path.addRRect(outside);
139 path.addRRect(inside, SkPath::kCCW_Direction);
140 this->onDrawPath(path, paint);
141 }
142
143 void onDrawPath(const SkPath& path, const SkPaint& paint) override {
144 auto p = this->id(path),
145 m = this->id(Misc::CreateFrom(paint)),
146 s = this->id(paint.getShader()),
147 x = this->id(paint.getXfermode());
148
149 if (paint.getStyle() == SkPaint::kFill_Style) {
150 fEncoder->fillPath(p, m, s, x);
151 } else {
152 // TODO: handle kStrokeAndFill_Style
153 fEncoder->strokePath(p, m, s, x, this->id(Stroke::CreateFrom(pai nt)));
154 }
155 }
156
157 void onDrawPaint(const SkPaint& paint) override {
158 SkPath path;
159 path.setFillType(SkPath::kInverseWinding_FillType); // Either inver se FillType is fine.
160 this->onDrawPath(path, paint);
161 }
162
163 void onDrawText(const void* text, size_t byteLength,
164 SkScalar x, SkScalar y, const SkPaint& paint) override {
165 // Text-as-paths is a temporary hack.
166 // TODO: send SkTextBlobs and SkTypefaces
167 SkPath path;
168 paint.getTextPath(text, byteLength, x, y, &path);
169 this->onDrawPath(path, paint);
170 }
171
172 void onDrawPosText(const void* text, size_t byteLength,
173 const SkPoint pos[], const SkPaint& paint) override {
174 // Text-as-paths is a temporary hack.
175 // TODO: send SkTextBlobs and SkTypefaces
176 SkPath path;
177 paint.getPosTextPath(text, byteLength, pos, &path);
178 this->onDrawPath(path, paint);
179 }
180
181 void onDrawPosTextH(const void* text, size_t byteLength,
182 const SkScalar xpos[], SkScalar constY, const SkPain t& paint) override {
183 size_t length = paint.countText(text, byteLength);
184 SkAutoTArray<SkPoint> pos(length);
185 for(size_t i = 0; i < length; ++i) {
186 pos[i].set(xpos[i], constY);
187 }
188 this->onDrawPosText(text, byteLength, &pos[0], paint);
189 }
190
191 void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeS tyle) override {
192 SkPath path;
193 path.addRect(rect);
194 this->onClipPath(path, op, edgeStyle);
195 }
196
197 void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle ed geStyle) override {
198 SkPath path;
199 path.addRRect(rrect);
200 this->onClipPath(path, op, edgeStyle);
201 }
202
203 void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeS tyle) override {
204 fEncoder->clipPath(this->id(path), op, edgeStyle == kSoft_ClipEdgeSt yle);
205 }
206
207 Encoder* fEncoder;
208 };
209
210 SkCanvas* NewCanvas(Encoder* encoder) { return new Canvas(encoder); }
211
212 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
213
214 class Decoder final : public Encoder {
215 public:
216 explicit Decoder(SkCanvas* canvas) : fCanvas(canvas) {}
217
218 private:
219 template <typename Map, typename T>
220 ID define(Type type, Map* map, const T& val) {
221 ID id(type, fNextID++);
222 map->set(id, val);
223 return id;
224 }
225
226 ID define(const SkMatrix& v) override {return this->define(Type::kMatrix , &fMatrix, v);}
227 ID define(const Misc& v) override {return this->define(Type::kMisc, &fMisc, v);}
228 ID define(const SkPath& v) override {return this->define(Type::kPath, &fPath, v);}
229 ID define(const Stroke& v) override {return this->define(Type::kStroke , &fStroke, v);}
230 ID define(SkShader* v) override {return this->define(Type::kShader , &fShader, v);}
231 ID define(SkXfermode* v) override {return this->define(Type::kXfermo de, &fXfermode, v);}
232
233 void undefine(ID id) override {
234 switch(id.type()) {
235 case Type::kMatrix: return fMatrix .remove(id);
236 case Type::kMisc: return fMisc .remove(id);
237 case Type::kPath: return fPath .remove(id);
238 case Type::kStroke: return fStroke .remove(id);
239 case Type::kShader: return fShader .remove(id);
240 case Type::kXfermode: return fXfermode.remove(id);
241 };
242 }
243
244 void save() override { fCanvas->save(); }
245 void restore() override { fCanvas->restore(); }
246
247 void setMatrix(ID matrix) override { fCanvas->setMatrix(fMatrix.find(mat rix)); }
248
249 void clipPath(ID path, SkRegion::Op op, bool aa) override {
250 fCanvas->clipPath(fPath.find(path), op, aa);
251 }
252 void fillPath(ID path, ID misc, ID shader, ID xfermode) override {
253 SkPaint paint;
254 paint.setStyle(SkPaint::kFill_Style);
255 fMisc.find(misc).applyTo(&paint);
256 paint.setShader (fShader .find(shader));
257 paint.setXfermode(fXfermode.find(xfermode));
258 fCanvas->drawPath(fPath.find(path), paint);
259 }
260 void strokePath(ID path, ID misc, ID shader, ID xfermode, ID stroke) ove rride {
261 SkPaint paint;
262 paint.setStyle(SkPaint::kStroke_Style);
263 fMisc .find(misc ).applyTo(&paint);
264 fStroke.find(stroke).applyTo(&paint);
265 paint.setShader (fShader .find(shader));
266 paint.setXfermode(fXfermode.find(xfermode));
267 fCanvas->drawPath(fPath.find(path), paint);
268 }
269
270 // Maps ID -> T.
271 template <typename T, Type kType>
272 class IDMap {
273 public:
274 ~IDMap() {
275 // A well-behaved client always cleans up its definitions.
276 SkASSERT(fMap.count() == 0);
277 }
278
279 void set(const ID& id, const T& val) {
280 SkASSERT(id.type() == kType);
281 fMap.set(id, val);
282 }
283
284 void remove(const ID& id) {
285 SkASSERT(id.type() == kType);
286 fMap.remove(id);
287 }
288
289 const T& find(const ID& id) const {
290 SkASSERT(id.type() == kType);
291 T* val = fMap.find(id);
292 SkASSERT(val != nullptr);
293 return *val;
294 }
295
296 private:
297 SkTHashMap<ID, T> fMap;
298 };
299
300 // Maps ID -> T*, and keeps the T alive by reffing it.
301 template <typename T, Type kType>
302 class ReffedIDMap {
303 public:
304 ReffedIDMap() {}
305 ~ReffedIDMap() {
306 // A well-behaved client always cleans up its definitions.
307 SkASSERT(fMap.count() == 0);
308 }
309
310 void set(const ID& id, T* val) {
311 SkASSERT(id.type() == kType);
312 fMap.set(id, SkSafeRef(val));
313 }
314
315 void remove(const ID& id) {
316 SkASSERT(id.type() == kType);
317 T** val = fMap.find(id);
318 SkASSERT(val);
319 SkSafeUnref(*val);
320 fMap.remove(id);
321 }
322
323 T* find(const ID& id) const {
324 SkASSERT(id.type() == kType);
325 T** val = fMap.find(id);
326 SkASSERT(val);
327 return *val;
328 }
329
330 private:
331 SkTHashMap<ID, T*> fMap;
332 };
333
334
335 IDMap<SkMatrix , Type::kMatrix> fMatrix;
336 IDMap<Misc , Type::kMisc > fMisc;
337 IDMap<SkPath , Type::kPath > fPath;
338 IDMap<Stroke , Type::kStroke> fStroke;
339 ReffedIDMap<SkShader , Type::kShader> fShader;
340 ReffedIDMap<SkXfermode, Type::kXfermode> fXfermode;
341
342 SkCanvas* fCanvas;
343 uint64_t fNextID = 0;
344 };
345
346 Encoder* NewDecoder(SkCanvas* canvas) { return new Decoder(canvas); }
347
348 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
349
75 class CachingEncoder final : public Encoder { 350 class CachingEncoder final : public Encoder {
76 public: 351 public:
77 explicit CachingEncoder(Encoder* wrapped) : fWrapped(wrapped) {} 352 explicit CachingEncoder(Encoder* wrapped) : fWrapped(wrapped) {}
78 353
79 private: 354 private:
80 struct Undef { 355 struct Undef {
81 Encoder* fEncoder; 356 Encoder* fEncoder;
82 template <typename T> 357 template <typename T>
83 void operator()(const T&, ID* id) const { fEncoder->undefine(*id); } 358 void operator()(const T&, ID* id) const { fEncoder->undefine(*id); }
84 }; 359 };
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 SkTHashMap<SkMatrix, ID> fMatrix; 434 SkTHashMap<SkMatrix, ID> fMatrix;
160 SkTHashMap<Misc, ID, MiscHash> fMisc; 435 SkTHashMap<Misc, ID, MiscHash> fMisc;
161 SkTHashMap<SkPath, ID> fPath; 436 SkTHashMap<SkPath, ID> fPath;
162 SkTHashMap<Stroke, ID> fStroke; 437 SkTHashMap<Stroke, ID> fStroke;
163 RefKeyMap<SkShader, Type::kShader> fShader; 438 RefKeyMap<SkShader, Type::kShader> fShader;
164 RefKeyMap<SkXfermode, Type::kXfermode> fXfermode; 439 RefKeyMap<SkXfermode, Type::kXfermode> fXfermode;
165 440
166 Encoder* fWrapped; 441 Encoder* fWrapped;
167 }; 442 };
168 443
169 Encoder* Encoder::CreateCachingEncoder(Encoder* wrapped) { return new Cachin gEncoder(wrapped); } 444 Encoder* NewCachingEncoder(Encoder* wrapped) { return new CachingEncoder(wra pped); }
170
171 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
172
173 // Calls Encoder::define() when created, Encoder::undefine() when destroyed.
174 class Client::AutoID : ::SkNoncopyable {
175 public:
176 template <typename T>
177 explicit AutoID(Encoder* encoder, const T& val)
178 : fEncoder(encoder)
179 , fID(encoder->define(val)) {}
180 ~AutoID() { if (fEncoder) fEncoder->undefine(fID); }
181
182 AutoID(AutoID&& o) : fEncoder(o.fEncoder), fID(o.fID) {
183 o.fEncoder = nullptr;
184 }
185 AutoID& operator=(AutoID&&) = delete;
186
187 operator ID () const { return fID; }
188
189 private:
190 Encoder* fEncoder;
191 const ID fID;
192 };
193
194 template <typename T>
195 Client::AutoID Client::id(const T& val) { return AutoID(fEncoder, val); }
196
197 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
198
199 Client::Client(Encoder* encoder)
200 : SkCanvas(1,1)
201 , fEncoder(encoder)
202 {}
203
204 void Client::willSave() { fEncoder->save(); }
205 void Client::didRestore() { fEncoder->restore(); }
206
207 void Client::didConcat (const SkMatrix&) { this->didSetMatrix(this->getTot alMatrix()); }
208 void Client::didSetMatrix(const SkMatrix& matrix) {
209 fEncoder->setMatrix(this->id(matrix));
210 }
211
212 void Client::onDrawOval(const SkRect& oval, const SkPaint& paint) {
213 SkPath path;
214 path.addOval(oval);
215 this->onDrawPath(path, paint);
216 }
217
218 void Client::onDrawRect(const SkRect& rect, const SkPaint& paint) {
219 SkPath path;
220 path.addRect(rect);
221 this->onDrawPath(path, paint);
222 }
223
224 void Client::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
225 SkPath path;
226 path.addRRect(rrect);
227 this->onDrawPath(path, paint);
228 }
229
230 void Client::onDrawDRRect(const SkRRect& outside,
231 const SkRRect& inside,
232 const SkPaint& paint) {
233 SkPath path;
234 path.addRRect(outside);
235 path.addRRect(inside, SkPath::kCCW_Direction);
236 this->onDrawPath(path, paint);
237 }
238
239 void Client::onDrawPath(const SkPath& path, const SkPaint& paint) {
240 auto p = this->id(path),
241 m = this->id(Misc::CreateFrom(paint)),
242 s = this->id(paint.getShader()),
243 x = this->id(paint.getXfermode());
244
245 if (paint.getStyle() == SkPaint::kFill_Style) {
246 fEncoder->fillPath(p, m, s, x);
247 } else {
248 // TODO: handle kStrokeAndFill_Style
249 fEncoder->strokePath(p, m, s, x, this->id(Stroke::CreateFrom(paint)) );
250 }
251 }
252
253 void Client::onDrawPaint(const SkPaint& paint) {
254 SkPath path;
255 path.setFillType(SkPath::kInverseWinding_FillType); // Either inverse F illType works fine.
256 this->onDrawPath(path, paint);
257 }
258
259 void Client::onDrawText(const void* text, size_t byteLength, SkScalar x,
260 SkScalar y, const SkPaint& paint) {
261 // Text-as-paths is a temporary hack.
262 // TODO: send SkTextBlobs and SkTypefaces
263 SkPath path;
264 paint.getTextPath(text, byteLength, x, y, &path);
265 this->onDrawPath(path, paint);
266 }
267
268 void Client::onDrawPosText(const void* text, size_t byteLength,
269 const SkPoint pos[], const SkPaint& paint) {
270 // Text-as-paths is a temporary hack.
271 // TODO: send SkTextBlobs and SkTypefaces
272 SkPath path;
273 paint.getPosTextPath(text, byteLength, pos, &path);
274 this->onDrawPath(path, paint);
275 }
276
277 void Client::onDrawPosTextH(const void* text, size_t byteLength,
278 const SkScalar xpos[], SkScalar constY,
279 const SkPaint& paint) {
280 size_t length = paint.countText(text, byteLength);
281 SkAutoTArray<SkPoint> pos(length);
282 for(size_t i = 0; i < length; ++i) {
283 pos[i].set(xpos[i], constY);
284 }
285 this->onDrawPosText(text, byteLength, &pos[0], paint);
286 }
287
288 void Client::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle e dgeStyle) {
289 SkPath path;
290 path.addRect(rect);
291 this->onClipPath(path, op, edgeStyle);
292 }
293
294 void Client::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyl e edgeStyle) {
295 SkPath path;
296 path.addRRect(rrect);
297 this->onClipPath(path, op, edgeStyle);
298 }
299
300 void Client::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle e dgeStyle) {
301 fEncoder->clipPath(this->id(path), op, edgeStyle == kSoft_ClipEdgeStyle) ;
302 }
303
304 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
305
306 Server::Server(SkCanvas* canvas) : fCanvas(canvas) {}
307
308 template <typename Map, typename T>
309 ID Server::define(Type type, Map* map, const T& val) {
310 ID id(type, fNextID++);
311 map->set(id, val);
312 return id;
313 }
314
315 ID Server::define(const SkMatrix& v) { return this->define(Type::kMatrix, &fMatrix, v); }
316 ID Server::define(const Misc& v) { return this->define(Type::kMisc, &fMisc, v); }
317 ID Server::define(const SkPath& v) { return this->define(Type::kPath, &fPath, v); }
318 ID Server::define(const Stroke& v) { return this->define(Type::kStroke, &fStroke, v); }
319 ID Server::define(SkShader* v) { return this->define(Type::kShader, &fShader, v); }
320 ID Server::define(SkXfermode* v) { return this->define(Type::kXfermode, &fXfermode, v); }
321
322 void Server::undefine(ID id) {
323 switch(id.type()) {
324 case Type::kMatrix: return fMatrix .remove(id);
325 case Type::kMisc: return fMisc .remove(id);
326 case Type::kPath: return fPath .remove(id);
327 case Type::kStroke: return fStroke .remove(id);
328 case Type::kShader: return fShader .remove(id);
329 case Type::kXfermode: return fXfermode.remove(id);
330 };
331 }
332
333 void Server:: save() { fCanvas->save(); }
334 void Server::restore() { fCanvas->restore(); }
335
336 void Server::setMatrix(ID matrix) { fCanvas->setMatrix(fMatrix.find(matrix)) ; }
337
338 void Server::clipPath(ID path, SkRegion::Op op, bool aa) {
339 fCanvas->clipPath(fPath.find(path), op, aa);
340 }
341 void Server::fillPath(ID path, ID misc, ID shader, ID xfermode) {
342 SkPaint paint;
343 paint.setStyle(SkPaint::kFill_Style);
344 fMisc.find(misc).applyTo(&paint);
345 paint.setShader (fShader .find(shader));
346 paint.setXfermode(fXfermode.find(xfermode));
347 fCanvas->drawPath(fPath.find(path), paint);
348 }
349 void Server::strokePath(ID path, ID misc, ID shader, ID xfermode, ID stroke) {
350 SkPaint paint;
351 paint.setStyle(SkPaint::kStroke_Style);
352 fMisc .find(misc ).applyTo(&paint);
353 fStroke.find(stroke).applyTo(&paint);
354 paint.setShader (fShader .find(shader));
355 paint.setXfermode(fXfermode.find(xfermode));
356 fCanvas->drawPath(fPath.find(path), paint);
357 }
358 445
359 } // namespace SkRemote 446 } // namespace SkRemote
OLDNEW
« 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