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

Side by Side Diff: src/core/SkRemote.cpp

Issue 1412223002: SkRemote: add xfermodes (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase 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') | src/core/SkRemote_protocol.h » ('j') | 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 "SkPath.h" 8 #include "SkPath.h"
9 #include "SkRect.h" 9 #include "SkRect.h"
10 #include "SkRemote.h" 10 #include "SkRemote.h"
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 private: 90 private:
91 Cache* fCache; 91 Cache* fCache;
92 Encoder* fEncoder; 92 Encoder* fEncoder;
93 SkSTArray<4, ID> fToUndefine; 93 SkSTArray<4, ID> fToUndefine;
94 }; 94 };
95 95
96 96
97 Cache* Cache::CreateNeverCache() { 97 Cache* Cache::CreateNeverCache() {
98 struct NeverCache final : public Cache { 98 struct NeverCache final : public Cache {
99 NeverCache() 99 NeverCache()
100 : fNextMatrix(Type::kMatrix) 100 : fNextMatrix (Type::kMatrix)
101 , fNextMisc (Type::kMisc) 101 , fNextMisc (Type::kMisc)
102 , fNextPath (Type::kPath) 102 , fNextPath (Type::kPath)
103 , fNextStroke(Type::kStroke) 103 , fNextStroke (Type::kStroke)
104 , fNextXfermode(Type::kXfermode)
104 {} 105 {}
105 void cleanup(Encoder*) override {} 106 void cleanup(Encoder*) override {}
106 107
107 static bool Helper(ID* next, ID* id, LookupScope* ls) { 108 static bool Helper(ID* next, ID* id, LookupScope* ls) {
108 *id = (*next)++; 109 *id = ++(*next);
109 ls->undefineWhenDone(*id); 110 ls->undefineWhenDone(*id);
110 return false; 111 return false;
111 } 112 }
112 113
113 bool lookup(const SkMatrix&, ID* id, LookupScope* ls) override { 114 bool lookup(const SkMatrix&, ID* id, LookupScope* ls) override {
114 return Helper(&fNextMatrix, id, ls); 115 return Helper(&fNextMatrix, id, ls);
115 } 116 }
116 bool lookup(const Misc&, ID* id, LookupScope* ls) override { 117 bool lookup(const Misc&, ID* id, LookupScope* ls) override {
117 return Helper(&fNextMisc, id, ls); 118 return Helper(&fNextMisc, id, ls);
118 } 119 }
119 bool lookup(const SkPath&, ID* id, LookupScope* ls) override { 120 bool lookup(const SkPath&, ID* id, LookupScope* ls) override {
120 return Helper(&fNextPath, id, ls); 121 return Helper(&fNextPath, id, ls);
121 } 122 }
122 bool lookup(const Stroke&, ID* id, LookupScope* ls) override { 123 bool lookup(const Stroke&, ID* id, LookupScope* ls) override {
123 return Helper(&fNextStroke, id, ls); 124 return Helper(&fNextStroke, id, ls);
124 } 125 }
126 bool lookup(const SkXfermode* xfermode, ID* id, LookupScope* ls) ove rride {
127 if (!xfermode) {
128 *id = ID(Type::kXfermode);
129 return true; // Null IDs are always defined.
130 }
131 return Helper(&fNextXfermode, id, ls);
132 }
125 133
126 ID fNextMatrix, 134 ID fNextMatrix,
127 fNextMisc, 135 fNextMisc,
128 fNextPath, 136 fNextPath,
129 fNextStroke; 137 fNextStroke,
138 fNextXfermode;
130 }; 139 };
131 return new NeverCache; 140 return new NeverCache;
132 } 141 }
133 142
134 // Can't be declared locally inside AlwaysCache because of the templating. :( 143 // These can't be declared locally inside AlwaysCache because of the templat ing. :(
135 template <typename T, typename Map> 144 namespace {
136 static bool always_cache_helper(const T& val, Map* map, ID* next, ID* id) { 145 template <typename T, typename Map>
137 if (ID* found = map->find(val)) { 146 static bool always_cache_lookup(const T& val, Map* map, ID* next, ID* id ) {
138 *id = *found; 147 if (const ID* found = map->find(val)) {
139 return true; 148 *id = *found;
149 return true;
150 }
151 *id = ++(*next);
152 map->set(val, *id);
153 return false;
140 } 154 }
141 *id = (*next)++; 155
142 map->set(val, *id); 156 struct Undefiner {
143 return false; 157 Encoder* fEncoder;
144 } 158
159 template <typename T>
160 void operator()(const T&, ID* id) const { fEncoder->undefine(*id); }
161 };
162
163 // Maps const T* -> ID, and refs the key. nullptr always maps to ID(kTy pe).
164 template <typename T, Type kType>
165 class RefKeyMap {
166 public:
167 RefKeyMap() {}
168 ~RefKeyMap() { fMap.foreach([](const T* key, ID*) { key->unref(); }) ; }
169
170 void set(const T* key, const ID& id) {
171 SkASSERT(key && id.type() == kType);
172 fMap.set(SkRef(key), id);
173 }
174
175 void remove(const T* key) {
176 SkASSERT(key);
177 fMap.remove(key);
178 key->unref();
179 }
180
181 const ID* find(const T* key) const {
182 static const ID nullID(kType);
183 return key ? fMap.find(key) : &nullID;
184 }
185
186 template <typename Fn>
187 void foreach(const Fn& fn) { fMap.foreach(fn); }
188 private:
189 SkTHashMap<const T*, ID> fMap;
190 };
191 } // namespace
145 192
146 Cache* Cache::CreateAlwaysCache() { 193 Cache* Cache::CreateAlwaysCache() {
147 struct AlwaysCache final : public Cache { 194 struct AlwaysCache final : public Cache {
148 AlwaysCache() 195 AlwaysCache()
149 : fNextMatrix(Type::kMatrix) 196 : fNextMatrix (Type::kMatrix)
150 , fNextMisc (Type::kMisc) 197 , fNextMisc (Type::kMisc)
151 , fNextPath (Type::kPath) 198 , fNextPath (Type::kPath)
152 , fNextStroke(Type::kStroke) 199 , fNextStroke (Type::kStroke)
200 , fNextXfermode(Type::kXfermode)
153 {} 201 {}
154 202
155 void cleanup(Encoder* encoder) override { 203 void cleanup(Encoder* encoder) override {
156 fMatrix.foreach([=](const SkMatrix&, ID* id) { encoder->undefine (*id); }); 204 Undefiner undef{encoder};
157 fMisc .foreach([=](const Misc&, ID* id) { encoder->undefine (*id); }); 205 fMatrix .foreach(undef);
158 fPath .foreach([=](const SkPath&, ID* id) { encoder->undefine (*id); }); 206 fMisc .foreach(undef);
159 fStroke.foreach([=](const Stroke&, ID* id) { encoder->undefine (*id); }); 207 fPath .foreach(undef);
208 fStroke .foreach(undef);
209 fXfermode.foreach(undef);
160 } 210 }
161 211
162 212
163 bool lookup(const SkMatrix& matrix, ID* id, LookupScope*) override { 213 bool lookup(const SkMatrix& matrix, ID* id, LookupScope*) override {
164 return always_cache_helper(matrix, &fMatrix, &fNextMatrix, id); 214 return always_cache_lookup(matrix, &fMatrix, &fNextMatrix, id);
165 } 215 }
166 bool lookup(const Misc& misc, ID* id, LookupScope*) override { 216 bool lookup(const Misc& misc, ID* id, LookupScope*) override {
167 return always_cache_helper(misc, &fMisc, &fNextMisc, id); 217 return always_cache_lookup(misc, &fMisc, &fNextMisc, id);
168 } 218 }
169 bool lookup(const SkPath& path, ID* id, LookupScope*) override { 219 bool lookup(const SkPath& path, ID* id, LookupScope*) override {
170 return always_cache_helper(path, &fPath, &fNextPath, id); 220 return always_cache_lookup(path, &fPath, &fNextPath, id);
171 } 221 }
172 bool lookup(const Stroke& stroke, ID* id, LookupScope*) override { 222 bool lookup(const Stroke& stroke, ID* id, LookupScope*) override {
173 return always_cache_helper(stroke, &fStroke, &fNextStroke, id); 223 return always_cache_lookup(stroke, &fStroke, &fNextStroke, id);
224 }
225 bool lookup(const SkXfermode* xfermode, ID* id, LookupScope*) overri de {
226 return always_cache_lookup(xfermode, &fXfermode, &fNextXfermode, id);
174 } 227 }
175 228
176 SkTHashMap<SkMatrix, ID> fMatrix; 229 SkTHashMap<SkMatrix, ID> fMatrix;
177 SkTHashMap<Misc, ID, MiscHash> fMisc; 230 SkTHashMap<Misc, ID, MiscHash> fMisc;
178 SkTHashMap<SkPath, ID> fPath; 231 SkTHashMap<SkPath, ID> fPath;
179 SkTHashMap<Stroke, ID> fStroke; 232 SkTHashMap<Stroke, ID> fStroke;
233 RefKeyMap<SkXfermode, Type::kXfermode> fXfermode;
234
180 ID fNextMatrix, 235 ID fNextMatrix,
181 fNextMisc, 236 fNextMisc,
182 fNextPath, 237 fNextPath,
183 fNextStroke; 238 fNextStroke,
239 fNextXfermode;
184 }; 240 };
185 return new AlwaysCache; 241 return new AlwaysCache;
186 } 242 }
187 243
188 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 244 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
189 245
190 Client::Client(Cache* cache, Encoder* encoder) 246 Client::Client(Cache* cache, Encoder* encoder)
191 : SkCanvas(1,1) 247 : SkCanvas(1,1)
192 , fCache(cache) 248 , fCache(cache)
193 , fEncoder(encoder) 249 , fEncoder(encoder)
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 const SkPaint& paint) { 285 const SkPaint& paint) {
230 SkPath path; 286 SkPath path;
231 path.addRRect(outside); 287 path.addRRect(outside);
232 path.addRRect(inside, SkPath::kCCW_Direction); 288 path.addRRect(inside, SkPath::kCCW_Direction);
233 this->onDrawPath(path, paint); 289 this->onDrawPath(path, paint);
234 } 290 }
235 291
236 void Client::onDrawPath(const SkPath& path, const SkPaint& paint) { 292 void Client::onDrawPath(const SkPath& path, const SkPaint& paint) {
237 LookupScope ls(fCache, fEncoder); 293 LookupScope ls(fCache, fEncoder);
238 ID p = ls.lookup(path), 294 ID p = ls.lookup(path),
239 m = ls.lookup(Misc::CreateFrom(paint)); 295 m = ls.lookup(Misc::CreateFrom(paint)),
296 x = ls.lookup(paint.getXfermode());
240 297
241 if (paint.getStyle() == SkPaint::kFill_Style) { 298 if (paint.getStyle() == SkPaint::kFill_Style) {
242 fEncoder->fillPath(p, m); 299 fEncoder->fillPath(p, m, x);
243 } else { 300 } else {
244 // TODO: handle kStrokeAndFill_Style 301 // TODO: handle kStrokeAndFill_Style
245 fEncoder->strokePath(p, m, ls.lookup(Stroke::CreateFrom(paint))); 302 fEncoder->strokePath(p, m, x, ls.lookup(Stroke::CreateFrom(paint)));
246 } 303 }
247 } 304 }
248 305
249 void Client::onDrawPaint(const SkPaint& paint) { 306 void Client::onDrawPaint(const SkPaint& paint) {
250 SkPath path; 307 SkPath path;
251 path.setFillType(SkPath::kInverseWinding_FillType); // Either inverse F illType works fine. 308 path.setFillType(SkPath::kInverseWinding_FillType); // Either inverse F illType works fine.
252 this->onDrawPath(path, paint); 309 this->onDrawPath(path, paint);
253 } 310 }
254 311
255 void Client::onDrawText(const void* text, size_t byteLength, SkScalar x, 312 void Client::onDrawText(const void* text, size_t byteLength, SkScalar x,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 352
296 void Client::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle e dgeStyle) { 353 void Client::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle e dgeStyle) {
297 LookupScope ls(fCache, fEncoder); 354 LookupScope ls(fCache, fEncoder);
298 fEncoder->clipPath(ls.lookup(path), op, edgeStyle == kSoft_ClipEdgeStyle ); 355 fEncoder->clipPath(ls.lookup(path), op, edgeStyle == kSoft_ClipEdgeStyle );
299 } 356 }
300 357
301 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 358 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
302 359
303 Server::Server(SkCanvas* canvas) : fCanvas(canvas) {} 360 Server::Server(SkCanvas* canvas) : fCanvas(canvas) {}
304 361
305 void Server::define(ID id, const SkMatrix& v) { fMatrix.set(id, v); } 362 void Server::define(ID id, const SkMatrix& v) { fMatrix .set(id, v); }
306 void Server::define(ID id, const Misc& v) { fMisc .set(id, v); } 363 void Server::define(ID id, const Misc& v) { fMisc .set(id, v); }
307 void Server::define(ID id, const SkPath& v) { fPath .set(id, v); } 364 void Server::define(ID id, const SkPath& v) { fPath .set(id, v); }
308 void Server::define(ID id, const Stroke& v) { fStroke.set(id, v); } 365 void Server::define(ID id, const Stroke& v) { fStroke .set(id, v); }
366 void Server::define(ID id, SkXfermode* v) { fXfermode.set(id, v); }
309 367
310 void Server::undefine(ID id) { 368 void Server::undefine(ID id) {
311 switch(id.type()) { 369 switch(id.type()) {
312 case Type::kMatrix: return fMatrix.remove(id); 370 case Type::kMatrix: return fMatrix .remove(id);
313 case Type::kMisc: return fMisc .remove(id); 371 case Type::kMisc: return fMisc .remove(id);
314 case Type::kPath: return fPath .remove(id); 372 case Type::kPath: return fPath .remove(id);
315 case Type::kStroke: return fStroke.remove(id); 373 case Type::kStroke: return fStroke .remove(id);
374 case Type::kXfermode: return fXfermode.remove(id);
316 375
317 case Type::kNone: SkASSERT(false); 376 case Type::kNone: SkASSERT(false);
318 }; 377 };
319 } 378 }
320 379
321 void Server:: save() { fCanvas->save(); } 380 void Server:: save() { fCanvas->save(); }
322 void Server::restore() { fCanvas->restore(); } 381 void Server::restore() { fCanvas->restore(); }
323 382
324 void Server::setMatrix(ID matrix) { fCanvas->setMatrix(fMatrix.find(matrix)) ; } 383 void Server::setMatrix(ID matrix) { fCanvas->setMatrix(fMatrix.find(matrix)) ; }
325 384
326 void Server::clipPath(ID path, SkRegion::Op op, bool aa) { 385 void Server::clipPath(ID path, SkRegion::Op op, bool aa) {
327 fCanvas->clipPath(fPath.find(path), op, aa); 386 fCanvas->clipPath(fPath.find(path), op, aa);
328 } 387 }
329 void Server::fillPath(ID path, ID misc) { 388 void Server::fillPath(ID path, ID misc, ID xfermode) {
330 SkPaint paint; 389 SkPaint paint;
331 paint.setStyle(SkPaint::kFill_Style); 390 paint.setStyle(SkPaint::kFill_Style);
332 fMisc.find(misc).applyTo(&paint); 391 fMisc.find(misc).applyTo(&paint);
392 paint.setXfermode(fXfermode.find(xfermode));
333 fCanvas->drawPath(fPath.find(path), paint); 393 fCanvas->drawPath(fPath.find(path), paint);
334 } 394 }
335 void Server::strokePath(ID path, ID misc, ID stroke) { 395 void Server::strokePath(ID path, ID misc, ID xfermode, ID stroke) {
336 SkPaint paint; 396 SkPaint paint;
337 paint.setStyle(SkPaint::kStroke_Style); 397 paint.setStyle(SkPaint::kStroke_Style);
338 fMisc .find(misc ).applyTo(&paint); 398 fMisc .find(misc ).applyTo(&paint);
339 fStroke.find(stroke).applyTo(&paint); 399 fStroke.find(stroke).applyTo(&paint);
400 paint.setXfermode(fXfermode.find(xfermode));
340 fCanvas->drawPath(fPath.find(path), paint); 401 fCanvas->drawPath(fPath.find(path), paint);
341 } 402 }
342 403
343 } // namespace SkRemote 404 } // namespace SkRemote
OLDNEW
« no previous file with comments | « src/core/SkRemote.h ('k') | src/core/SkRemote_protocol.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698