blob: a2f1bae42ab1d95c9ce1ad8e5fbf5b72cddadb3d [file] [log] [blame]
reedbabc3de2016-07-08 08:43:27 -07001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkDeferredCanvas.h"
9#include "SkDrawable.h"
10#include "SkPath.h"
11#include "SkRRect.h"
12#include "SkSurface.h"
13#include "SkTextBlob.h"
Mike Reedebfce6d2016-12-12 10:02:12 -050014#include "SkClipOpPriv.h"
reedbabc3de2016-07-08 08:43:27 -070015
16bool SkDeferredCanvas::Rec::isConcat(SkMatrix* m) const {
17 switch (fType) {
18 case kTrans_Type:
19 m->setTranslate(fData.fTranslate.x(), fData.fTranslate.y());
20 return true;
21 case kScaleTrans_Type:
22 m->setScaleTranslate(fData.fScaleTrans.fScale.x(),
23 fData.fScaleTrans.fScale.y(),
24 fData.fScaleTrans.fTrans.x(),
25 fData.fScaleTrans.fTrans.y());
26 return true;
27 default:
28 break;
29 }
30 return false;
31}
32
33void SkDeferredCanvas::Rec::setConcat(const SkMatrix& m) {
34 SkASSERT(m.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask));
Herb Derby13569782016-10-06 14:33:43 -040035
reedbabc3de2016-07-08 08:43:27 -070036 if (m.getType() <= SkMatrix::kTranslate_Mask) {
37 fType = kTrans_Type;
38 fData.fTranslate.set(m.getTranslateX(), m.getTranslateY());
39 } else {
40 fType = kScaleTrans_Type;
41 fData.fScaleTrans.fScale.set(m.getScaleX(), m.getScaleY());
42 fData.fScaleTrans.fTrans.set(m.getTranslateX(), m.getTranslateY());
43 }
44}
45
46///////////////////////////////////////////////////////////////////////////////////////////////////
47
48SkDeferredCanvas::SkDeferredCanvas(SkCanvas* canvas)
Florin Malita439ace92016-12-02 12:05:41 -050049 : INHERITED(1, 1) {
Herb Derby13569782016-10-06 14:33:43 -040050 this->reset(canvas);
51}
reedbabc3de2016-07-08 08:43:27 -070052
53SkDeferredCanvas::~SkDeferredCanvas() {}
54
Herb Derby13569782016-10-06 14:33:43 -040055void SkDeferredCanvas::reset(SkCanvas* canvas) {
56 if (fCanvas) {
57 this->flush();
58 fCanvas = nullptr;
59 }
60 fRecs.reset();
61 if (canvas) {
62 this->resetForNextPicture(SkIRect::MakeSize(canvas->getBaseLayerSize()));
63 fCanvas = canvas;
64 }
65}
66
reedbabc3de2016-07-08 08:43:27 -070067void SkDeferredCanvas::push_save() {
68 Rec* r = fRecs.append();
69 r->fType = kSave_Type;
70}
71
72void SkDeferredCanvas::push_cliprect(const SkRect& bounds) {
73 int index = fRecs.count() - 1;
74 if (index >= 0 && fRecs[index].fType == kClipRect_Type) {
75 if (!fRecs[index].fData.fBounds.intersect(bounds)) {
76 fRecs[index].fData.fBounds.setEmpty();
77 }
78 } else {
79 Rec* r = fRecs.append();
80 r->fType = kClipRect_Type;
81 r->fData.fBounds = bounds;
82 }
83}
84
85bool SkDeferredCanvas::push_concat(const SkMatrix& mat) {
86 if (mat.getType() > (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) {
87 return false;
88 }
89 // At the moment, we don't know which ops can scale and which can also flip, so
90 // we reject negative scales for now
91 if (mat.getScaleX() < 0 || mat.getScaleY() < 0) {
92 return false;
93 }
94
95 int index = fRecs.count() - 1;
96 SkMatrix m;
97 if (index >= 0 && fRecs[index].isConcat(&m)) {
98 m.preConcat(mat);
99 fRecs[index].setConcat(m);
100 } else {
101 fRecs.append()->setConcat(mat);
102 }
103 return true;
104}
105
106void SkDeferredCanvas::emit(const Rec& rec) {
107 switch (rec.fType) {
108 case kSave_Type:
109 fCanvas->save();
110 this->INHERITED::willSave();
111 break;
112 case kClipRect_Type:
113 fCanvas->clipRect(rec.fData.fBounds);
114 this->INHERITED::onClipRect(rec.fData.fBounds,
Mike Reedc1f77742016-12-09 09:00:50 -0500115 kIntersect_SkClipOp, kHard_ClipEdgeStyle);
reedbabc3de2016-07-08 08:43:27 -0700116 break;
117 case kTrans_Type:
118 case kScaleTrans_Type: {
119 SkMatrix mat;
120 rec.getConcat(&mat);
121 fCanvas->concat(mat);
122 this->INHERITED::didConcat(mat);
123 } break;
124 }
125}
126
127void SkDeferredCanvas::flush_le(int index) {
128 SkASSERT(index >= -1 && index < fRecs.count());
129
130 int count = index + 1;
131 for (int i = 0; i < count; ++i) {
132 this->emit(fRecs[i]);
133 }
134 fRecs.remove(0, count);
135}
136
137void SkDeferredCanvas::flush_all() {
138 this->flush_le(fRecs.count() - 1);
139}
140
141void SkDeferredCanvas::flush_before_saves() {
142 int i;
143 for (i = fRecs.count() - 1; i >= 0; --i) {
144 if (kSave_Type != fRecs[i].fType) {
145 break;
146 }
147 }
148 this->flush_le(i);
149}
150
151enum Flags {
152 kNoTranslate_Flag = 1 << 0,
153 kNoClip_Flag = 1 << 1,
154 kNoCull_Flag = 1 << 2,
155 kNoScale_Flag = 1 << 3,
156};
157
158void SkDeferredCanvas::flush_check(SkRect* bounds, const SkPaint* paint, unsigned flags) {
159 if (paint) {
160 if (paint->getShader() || paint->getImageFilter()) {
161 flags |= kNoTranslate_Flag | kNoScale_Flag;
162 }
163 // TODO: replace these with code to enlarge the bounds conservatively?
164 if (paint->getStyle() != SkPaint::kFill_Style || paint->getMaskFilter() ||
165 paint->getImageFilter() || paint->getPathEffect())
166 {
167 flags |= kNoCull_Flag | kNoScale_Flag | kNoClip_Flag;
168 }
169 if (paint->getLooper()) {
170 // to be conservative, we disable both, since embedded layers could have shaders
171 // or strokes etc.
172 flags |= kNoTranslate_Flag | kNoCull_Flag | kNoScale_Flag;
173 }
174 }
175 bool canClip = !(flags & kNoClip_Flag);
176 bool canTranslate = !(flags & kNoTranslate_Flag);
177 bool canCull = !(flags & kNoCull_Flag);
178 bool canScale = !(flags & kNoScale_Flag);
179
180 int i;
181 for (i = fRecs.count() - 1; i >= 0; --i) {
182 const Rec& rec = fRecs[i];
183 switch (rec.fType) {
184 case kSave_Type:
185 // continue to the next rec
186 break;
187 case kClipRect_Type:
188 if (!canCull) {
189 goto STOP;
190 }
191 if (canClip) {
192 if (!bounds->intersect(rec.fData.fBounds)) {
193 bounds->setEmpty();
194 return;
195 }
196 // continue to the next rec
197 } else {
198 if (!rec.fData.fBounds.contains(*bounds)) {
199 goto STOP;
200 }
201 // continue to the next rec
202 }
203 break;
204 case kTrans_Type:
205 if (canTranslate) {
206 bounds->offset(rec.fData.fTranslate.x(), rec.fData.fTranslate.y());
207 // continue to the next rec
208 } else {
209 goto STOP;
210 }
211 break;
212 case kScaleTrans_Type:
213 if (canScale) {
214 SkMatrix m;
215 rec.getConcat(&m);
halcanaryc5769b22016-08-10 07:13:21 -0700216 m.mapRectScaleTranslate(bounds, *bounds);
reedbabc3de2016-07-08 08:43:27 -0700217 } else {
218 goto STOP;
219 }
220 break;
221 }
222 }
223STOP:
224 this->flush_le(i);
225}
226
227void SkDeferredCanvas::flush_translate(SkScalar* x, SkScalar* y, const SkRect& bounds,
228 const SkPaint* paint) {
229 SkRect tmp = bounds;
230 this->flush_check(&tmp, paint, kNoClip_Flag | kNoScale_Flag);
231 *x += tmp.x() - bounds.x();
232 *y += tmp.y() - bounds.y();
233}
234
235void SkDeferredCanvas::flush_translate(SkScalar* x, SkScalar* y, const SkPaint& paint) {
236 SkRect tmp = SkRect::MakeXYWH(*x, *y, 1, 1);
237 this->flush_check(&tmp, &paint, kNoClip_Flag | kNoCull_Flag | kNoScale_Flag);
238 *x = tmp.x();
239 *y = tmp.y();
240}
241
242///////////////////////////////////////////////////////////////////////////////////////////////////
243
244void SkDeferredCanvas::willSave() {
245 this->push_save();
246}
247
248SkCanvas::SaveLayerStrategy SkDeferredCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
249 this->flush_all();
250 fCanvas->saveLayer(rec);
251 this->INHERITED::getSaveLayerStrategy(rec);
252 // No need for a layer.
253 return kNoLayer_SaveLayerStrategy;
254}
255
256void SkDeferredCanvas::willRestore() {
257 for (int i = fRecs.count() - 1; i >= 0; --i) {
258 if (kSave_Type == fRecs[i].fType) {
259 fRecs.setCount(i); // pop off everything here and later
260 return;
261 }
262 }
263 for (int i = 0; i < fRecs.count(); ++i) {
264 SkASSERT(kSave_Type != fRecs[i].fType);
265 }
266 fRecs.setCount(0);
267 fCanvas->restore();
268 this->INHERITED::willRestore();
269}
270
271void SkDeferredCanvas::didConcat(const SkMatrix& matrix) {
272 if (matrix.isIdentity()) {
273 return;
274 }
275 if (!this->push_concat(matrix)) {
276 this->flush_all();
277 fCanvas->concat(matrix);
278 this->INHERITED::didConcat(matrix);
279 }
280}
281
282void SkDeferredCanvas::didSetMatrix(const SkMatrix& matrix) {
283 this->flush_all();
284 fCanvas->setMatrix(matrix);
285 this->INHERITED::didSetMatrix(matrix);
286}
287
Mike Reedc1f77742016-12-09 09:00:50 -0500288void SkDeferredCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
289 if (kIntersect_SkClipOp == op) {
reedbabc3de2016-07-08 08:43:27 -0700290 this->push_cliprect(rect);
291 } else {
292 this->flush_all();
293 fCanvas->clipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle);
294 this->INHERITED::onClipRect(rect, op, edgeStyle);
295 }
296}
297
Mike Reedc1f77742016-12-09 09:00:50 -0500298void SkDeferredCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
reedbabc3de2016-07-08 08:43:27 -0700299 this->flush_all();
300 fCanvas->clipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle);
301 this->INHERITED::onClipRRect(rrect, op, edgeStyle);
302}
303
Mike Reedc1f77742016-12-09 09:00:50 -0500304void SkDeferredCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
reedbabc3de2016-07-08 08:43:27 -0700305 this->flush_all();
306 fCanvas->clipPath(path, op, kSoft_ClipEdgeStyle == edgeStyle);
307 this->INHERITED::onClipPath(path, op, edgeStyle);
308}
309
Mike Reedc1f77742016-12-09 09:00:50 -0500310void SkDeferredCanvas::onClipRegion(const SkRegion& deviceRgn, SkClipOp op) {
reedbabc3de2016-07-08 08:43:27 -0700311 this->flush_all();
312 fCanvas->clipRegion(deviceRgn, op);
313 this->INHERITED::onClipRegion(deviceRgn, op);
314}
315
316void SkDeferredCanvas::onDrawPaint(const SkPaint& paint) {
317 // TODO: Can we turn this into drawRect?
318 this->flush_all();
319 fCanvas->drawPaint(paint);
320}
321
322void SkDeferredCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
323 const SkPaint& paint) {
324 this->flush_all();
325 fCanvas->drawPoints(mode, count, pts, paint);
326}
327
328void SkDeferredCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
329 SkRect modRect = rect;
330 this->flush_check(&modRect, &paint);
331 fCanvas->drawRect(modRect, paint);
332}
333
Mike Reedef4ab9d2016-10-05 11:52:51 -0400334void SkDeferredCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
335 this->flush_all(); // can we do better?
336 fCanvas->drawRegion(region, paint);
337}
338
reedbabc3de2016-07-08 08:43:27 -0700339void SkDeferredCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
340 SkRect modRect = rect;
341 this->flush_check(&modRect, &paint, kNoClip_Flag);
342 fCanvas->drawOval(modRect, paint);
343}
344
bsalomonac3aa242016-08-19 11:25:19 -0700345void SkDeferredCanvas::onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
346 bool useCenter, const SkPaint& paint) {
347 SkRect modRect = rect;
348 this->flush_check(&modRect, &paint, kNoClip_Flag);
349 fCanvas->drawArc(modRect, startAngle, sweepAngle, useCenter, paint);
350}
351
reedbabc3de2016-07-08 08:43:27 -0700352static SkRRect make_offset(const SkRRect& src, SkScalar dx, SkScalar dy) {
353 SkRRect dst = src;
354 dst.offset(dx, dy);
355 return dst;
356}
357
358void SkDeferredCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
359 SkRect modRect = rrect.getBounds();
360 this->flush_check(&modRect, &paint, kNoClip_Flag);
361 fCanvas->drawRRect(make_offset(rrect,
362 modRect.x() - rrect.getBounds().x(),
363 modRect.y() - rrect.getBounds().y()), paint);
364}
365
366void SkDeferredCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
367 this->flush_all();
368 fCanvas->drawDRRect(outer, inner, paint);
369}
370
371void SkDeferredCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
372 if (path.isInverseFillType()) {
373 this->flush_before_saves();
374 } else {
375 SkRect modRect = path.getBounds();
376 this->flush_check(&modRect, &paint, kNoClip_Flag | kNoTranslate_Flag | kNoScale_Flag);
377 }
378 fCanvas->drawPath(path, paint);
379}
380
381void SkDeferredCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
382 const SkPaint* paint) {
383 const SkScalar w = SkIntToScalar(bitmap.width());
384 const SkScalar h = SkIntToScalar(bitmap.height());
385 SkRect bounds = SkRect::MakeXYWH(x, y, w, h);
386 this->flush_check(&bounds, paint, kNoClip_Flag);
387 if (bounds.width() == w && bounds.height() == h) {
388 fCanvas->drawBitmap(bitmap, bounds.x(), bounds.y(), paint);
389 } else {
390 fCanvas->drawBitmapRect(bitmap, bounds, paint);
391 }
392}
393
394void SkDeferredCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
395 const SkPaint* paint, SrcRectConstraint constraint) {
396 SkRect modRect = dst;
397 this->flush_check(&modRect, paint, kNoClip_Flag);
398 fCanvas->legacy_drawBitmapRect(bitmap, src, modRect, paint, constraint);
399}
400
401void SkDeferredCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
402 const SkRect& dst, const SkPaint* paint) {
403 SkRect modRect = dst;
404 this->flush_check(&modRect, paint, kNoClip_Flag);
405 fCanvas->drawBitmapNine(bitmap, center, modRect, paint);
406}
407
Mike Reedef4ab9d2016-10-05 11:52:51 -0400408void SkDeferredCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
409 const SkRect& dst, const SkPaint* paint) {
410 SkRect modRect = dst;
411 this->flush_check(&modRect, paint, kNoClip_Flag);
412 fCanvas->drawBitmapLattice(bitmap, lattice, modRect, paint);
413}
414
reedbabc3de2016-07-08 08:43:27 -0700415void SkDeferredCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center,
416 const SkRect& dst, const SkPaint* paint) {
417 SkRect modRect = dst;
418 this->flush_check(&modRect, paint, kNoClip_Flag);
419 fCanvas->drawImageNine(image, center, modRect, paint);
420}
421
422void SkDeferredCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y,
423 const SkPaint* paint) {
424 const SkScalar w = SkIntToScalar(image->width());
425 const SkScalar h = SkIntToScalar(image->height());
426 SkRect bounds = SkRect::MakeXYWH(x, y, w, h);
427 this->flush_check(&bounds, paint, kNoClip_Flag);
428 if (bounds.width() == w && bounds.height() == h) {
429 fCanvas->drawImage(image, bounds.x(), bounds.y(), paint);
430 } else {
431 fCanvas->drawImageRect(image, bounds, paint);
432 }
433}
434
435void SkDeferredCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
436 const SkPaint* paint, SrcRectConstraint constraint) {
437 SkRect modRect = dst;
438 this->flush_check(&modRect, paint, kNoClip_Flag);
439 fCanvas->legacy_drawImageRect(image, src, modRect, paint, constraint);
440}
441
Mike Reedef4ab9d2016-10-05 11:52:51 -0400442void SkDeferredCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice,
443 const SkRect& dst, const SkPaint* paint) {
444 SkRect modRect = dst;
445 this->flush_check(&modRect, paint, kNoClip_Flag);
446 fCanvas->drawImageLattice(image, lattice, modRect, paint);
447}
448
reedbabc3de2016-07-08 08:43:27 -0700449void SkDeferredCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
Herb Derby13569782016-10-06 14:33:43 -0400450 const SkPaint& paint) {
reedbabc3de2016-07-08 08:43:27 -0700451 this->flush_translate(&x, &y, paint);
452 fCanvas->drawText(text, byteLength, x, y, paint);
453}
454
455void SkDeferredCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
456 const SkPaint& paint) {
457 this->flush_before_saves();
458 fCanvas->drawPosText(text, byteLength, pos, paint);
459}
460
461void SkDeferredCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
462 SkScalar constY, const SkPaint& paint) {
463 this->flush_before_saves();
464 fCanvas->drawPosTextH(text, byteLength, xpos, constY, paint);
465}
466
467void SkDeferredCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
468 const SkMatrix* matrix, const SkPaint& paint) {
469 this->flush_before_saves();
470 fCanvas->drawTextOnPath(text, byteLength, path, matrix, paint);
471}
472
473void SkDeferredCanvas::onDrawTextRSXform(const void* text, size_t byteLength,
474 const SkRSXform xform[], const SkRect* cullRect,
475 const SkPaint& paint) {
476 if (cullRect) {
477 SkRect modRect = *cullRect;
478 // only allow culling
479 this->flush_check(&modRect, &paint, kNoClip_Flag | kNoScale_Flag | kNoTranslate_Flag);
480 } else {
481 this->flush_before_saves();
482 }
483 fCanvas->drawTextRSXform(text, byteLength, xform, cullRect, paint);
484}
485
486void SkDeferredCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
487 const SkPaint &paint) {
488 this->flush_translate(&x, &y, blob->bounds(), &paint);
489 fCanvas->drawTextBlob(blob, x, y, paint);
490}
491
492#include "SkPicture.h"
493#include "SkCanvasPriv.h"
494void SkDeferredCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
495 const SkPaint* paint) {
Herb Derby13569782016-10-06 14:33:43 -0400496#if 0
reedbabc3de2016-07-08 08:43:27 -0700497 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
498 picture->playback(this);
499#else
500 this->flush_before_saves();
501 fCanvas->drawPicture(picture, matrix, paint);
502#endif
503}
504
505void SkDeferredCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
506 // TODO: investigate culling and applying concat to the matrix
Herb Derby13569782016-10-06 14:33:43 -0400507#if 0
reedbabc3de2016-07-08 08:43:27 -0700508 drawable->draw(this, matrix);
509#else
510 this->flush_before_saves();
511 fCanvas->drawDrawable(drawable, matrix);
512#endif
513}
514
515void SkDeferredCanvas::onDrawAtlas(const SkImage* image, const SkRSXform xform[],
516 const SkRect rects[], const SkColor colors[],
Mike Reedfaba3712016-11-03 14:45:31 -0400517 int count, SkBlendMode bmode,
reedbabc3de2016-07-08 08:43:27 -0700518 const SkRect* cull, const SkPaint* paint) {
519 this->flush_before_saves();
Mike Reedfaba3712016-11-03 14:45:31 -0400520 fCanvas->drawAtlas(image, xform, rects, colors, count, bmode, cull, paint);
reedbabc3de2016-07-08 08:43:27 -0700521}
522
523void SkDeferredCanvas::onDrawVertices(VertexMode vmode, int vertexCount,
524 const SkPoint vertices[], const SkPoint texs[],
Mike Reedfaba3712016-11-03 14:45:31 -0400525 const SkColor colors[], SkBlendMode bmode,
reedbabc3de2016-07-08 08:43:27 -0700526 const uint16_t indices[], int indexCount,
527 const SkPaint& paint) {
528 this->flush_before_saves();
Mike Reedfaba3712016-11-03 14:45:31 -0400529 fCanvas->drawVertices(vmode, vertexCount, vertices, texs, colors, bmode,
reedbabc3de2016-07-08 08:43:27 -0700530 indices, indexCount, paint);
531}
532
533void SkDeferredCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
Mike Reedfaba3712016-11-03 14:45:31 -0400534 const SkPoint texCoords[4], SkBlendMode bmode,
reedbabc3de2016-07-08 08:43:27 -0700535 const SkPaint& paint) {
536 this->flush_before_saves();
Mike Reedfaba3712016-11-03 14:45:31 -0400537 fCanvas->drawPatch(cubics, colors, texCoords, bmode, paint);
reedbabc3de2016-07-08 08:43:27 -0700538}
539
540void SkDeferredCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* data) {
Herb Derby13569782016-10-06 14:33:43 -0400541 SkRect modRect = rect;
542 this->flush_check(&modRect, nullptr, kNoClip_Flag);
543 fCanvas->drawAnnotation(modRect, key, data);
reedbabc3de2016-07-08 08:43:27 -0700544}
545
546#ifdef SK_SUPPORT_LEGACY_DRAWFILTER
547SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
548 fCanvas->setDrawFilter(filter);
549 return this->INHERITED::setDrawFilter(filter);
550}
551#endif
552
553///////////////////////////////////////////////////////////////////////////////////////////////////
554
555sk_sp<SkSurface> SkDeferredCanvas::onNewSurface(const SkImageInfo& info,
556 const SkSurfaceProps& props) {
557 return fCanvas->makeSurface(info, &props);
558}
559SkISize SkDeferredCanvas::getBaseLayerSize() const { return fCanvas->getBaseLayerSize(); }
Mike Reed42e8c532017-01-23 14:09:13 -0500560SkRect SkDeferredCanvas::onGetLocalClipBounds() const {
561 return fCanvas->getLocalClipBounds();
reedbabc3de2016-07-08 08:43:27 -0700562}
Mike Reed42e8c532017-01-23 14:09:13 -0500563SkIRect SkDeferredCanvas::onGetDeviceClipBounds() const {
564 return fCanvas->getDeviceClipBounds();
reedbabc3de2016-07-08 08:43:27 -0700565}
566bool SkDeferredCanvas::isClipEmpty() const { return fCanvas->isClipEmpty(); }
567bool SkDeferredCanvas::isClipRect() const { return fCanvas->isClipRect(); }
568bool SkDeferredCanvas::onPeekPixels(SkPixmap* pixmap) { return fCanvas->peekPixels(pixmap); }
569bool SkDeferredCanvas::onAccessTopLayerPixels(SkPixmap* pixmap) {
570 SkImageInfo info;
571 size_t rowBytes;
572 SkIPoint* origin = nullptr;
573 void* addr = fCanvas->accessTopLayerPixels(&info, &rowBytes, origin);
574 if (addr) {
575 *pixmap = SkPixmap(info, addr, rowBytes);
576 return true;
577 }
578 return false;
579}
580SkImageInfo SkDeferredCanvas::onImageInfo() const { return fCanvas->imageInfo(); }
581bool SkDeferredCanvas::onGetProps(SkSurfaceProps* props) const { return fCanvas->getProps(props); }
582void SkDeferredCanvas::onFlush() {
583 this->flush_all();
584 return fCanvas->flush();
585}