Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 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" | |
| 14 | |
| 15 bool SkDeferredCanvas::Rec::isConcat(SkMatrix* m) const { | |
| 16 switch (fType) { | |
| 17 case kTrans_Type: | |
| 18 m->setTranslate(fData.fTranslate.x(), fData.fTranslate.y()); | |
| 19 return true; | |
| 20 case kScaleTrans_Type: | |
| 21 m->setScaleTranslate(fData.fScaleTrans.fScale.x(), | |
| 22 fData.fScaleTrans.fScale.y(), | |
| 23 fData.fScaleTrans.fTrans.x(), | |
| 24 fData.fScaleTrans.fTrans.y()); | |
| 25 return true; | |
| 26 default: | |
| 27 break; | |
| 28 } | |
| 29 return false; | |
| 30 } | |
| 31 | |
| 32 void SkDeferredCanvas::Rec::setConcat(const SkMatrix& m) { | |
| 33 SkASSERT(m.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) ; | |
| 34 | |
| 35 if (m.getType() <= SkMatrix::kTranslate_Mask) { | |
| 36 fType = kTrans_Type; | |
| 37 fData.fTranslate.set(m.getTranslateX(), m.getTranslateY()); | |
| 38 } else { | |
| 39 fType = kScaleTrans_Type; | |
| 40 fData.fScaleTrans.fScale.set(m.getScaleX(), m.getScaleY()); | |
| 41 fData.fScaleTrans.fTrans.set(m.getTranslateX(), m.getTranslateY()); | |
| 42 } | |
| 43 } | |
| 44 | |
| 45 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 46 | |
| 47 SkDeferredCanvas::SkDeferredCanvas(SkCanvas* canvas) | |
| 48 : INHERITED(canvas->getBaseLayerSize().width(), canvas->getBaseLayerSize().h eight()) | |
| 49 , fCanvas(canvas) | |
| 50 { | |
| 51 fSaveCount = 0; | |
|
f(malita)
2016/07/08 13:12:02
Nit: fSaveCount(0)
reed1
2016/07/08 13:33:16
Removed.
| |
| 52 } | |
| 53 | |
| 54 SkDeferredCanvas::~SkDeferredCanvas() { | |
| 55 } | |
| 56 | |
| 57 void SkDeferredCanvas::push_save() { | |
| 58 Rec* r = fRecs.append(); | |
| 59 r->fType = kSave_Type; | |
| 60 r->fData.fSaveCount = ++fSaveCount; | |
| 61 } | |
| 62 | |
| 63 void SkDeferredCanvas::push_cliprect(const SkRect& bounds) { | |
| 64 int index = fRecs.count() - 1; | |
| 65 if (index >= 0 && fRecs[index].fType == kClipRect_Type) { | |
| 66 if (!fRecs[index].fData.fBounds.intersect(bounds)) { | |
| 67 fRecs[index].fData.fBounds.setEmpty(); | |
| 68 } | |
| 69 } else { | |
| 70 Rec* r = fRecs.append(); | |
| 71 r->fType = kClipRect_Type; | |
| 72 r->fData.fBounds = bounds; | |
| 73 } | |
| 74 } | |
| 75 | |
| 76 bool SkDeferredCanvas::push_concat(const SkMatrix& mat) { | |
| 77 if (mat.getType() > (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) { | |
| 78 return false; | |
| 79 } | |
| 80 // At the moment, we don't know which ops can scale and which can also flip, so | |
| 81 // we reject negative scales for now | |
| 82 if (mat.getScaleX() < 0 || mat.getScaleY() < 0) { | |
| 83 return false; | |
| 84 } | |
| 85 | |
| 86 int index = fRecs.count() - 1; | |
| 87 SkMatrix m; | |
| 88 if (index >= 0 && fRecs[index].isConcat(&m)) { | |
| 89 m.preConcat(mat); | |
| 90 fRecs[index].setConcat(m); | |
| 91 } else { | |
| 92 fRecs.append()->setConcat(mat); | |
| 93 } | |
| 94 return true; | |
| 95 } | |
| 96 | |
| 97 void SkDeferredCanvas::emit(const Rec& rec) { | |
| 98 switch (rec.fType) { | |
| 99 case kSave_Type: | |
| 100 fCanvas->save(); | |
| 101 this->INHERITED::willSave(); | |
|
f(malita)
2016/07/08 13:12:02
So deferring the proxy canvas ops (and not just th
reed1
2016/07/08 13:32:32
It is, just to cut down on the cost of executing c
f(malita)
2016/07/08 13:42:44
SGTM as a targeted experiment.
But I think we sho
| |
| 102 break; | |
| 103 case kClipRect_Type: | |
| 104 fCanvas->clipRect(rec.fData.fBounds); | |
| 105 this->INHERITED::onClipRect(rec.fData.fBounds, | |
| 106 SkRegion::kIntersect_Op, kHard_ClipEdgeS tyle); | |
| 107 break; | |
| 108 case kTrans_Type: | |
| 109 case kScaleTrans_Type: { | |
| 110 SkMatrix mat; | |
| 111 rec.getConcat(&mat); | |
| 112 fCanvas->concat(mat); | |
| 113 this->INHERITED::didConcat(mat); | |
| 114 } break; | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 void SkDeferredCanvas::flush_le(int index) { | |
| 119 SkASSERT(index >= -1 && index < fRecs.count()); | |
| 120 | |
| 121 int count = index + 1; | |
| 122 for (int i = 0; i < count; ++i) { | |
| 123 this->emit(fRecs[i]); | |
| 124 } | |
| 125 fRecs.remove(0, count); | |
| 126 } | |
| 127 | |
| 128 void SkDeferredCanvas::flush_all() { | |
| 129 this->flush_le(fRecs.count() - 1); | |
| 130 } | |
| 131 | |
| 132 void SkDeferredCanvas::flush_before_saves() { | |
| 133 int i; | |
| 134 for (i = fRecs.count() - 1; i >= 0; --i) { | |
| 135 if (kSave_Type != fRecs[i].fType) { | |
| 136 break; | |
| 137 } | |
| 138 } | |
| 139 this->flush_le(i); | |
| 140 } | |
| 141 | |
| 142 enum Flags { | |
| 143 kNoTranslate_Flag = 1 << 0, | |
| 144 kNoClip_Flag = 1 << 1, | |
| 145 kNoCull_Flag = 1 << 2, | |
| 146 kNoScale_Flag = 1 << 3, | |
| 147 }; | |
| 148 | |
| 149 void SkDeferredCanvas::flush_check(SkRect* bounds, const SkPaint* paint, unsigne d flags) { | |
| 150 if (paint) { | |
| 151 if (paint->getShader() || paint->getImageFilter()) { | |
| 152 flags |= kNoTranslate_Flag | kNoScale_Flag; | |
| 153 } | |
| 154 // TODO: replace these with code to enlarge the bounds conservatively? | |
| 155 if (paint->getStyle() != SkPaint::kFill_Style || paint->getMaskFilter() || | |
| 156 paint->getImageFilter() || paint->getPathEffect()) | |
| 157 { | |
| 158 flags |= kNoCull_Flag | kNoScale_Flag; | |
| 159 } | |
| 160 if (paint->getLooper()) { | |
| 161 // to be conservative, we disable both, since embedded layers could have shaders | |
| 162 // or strokes etc. | |
| 163 flags |= kNoTranslate_Flag | kNoCull_Flag | kNoScale_Flag; | |
| 164 } | |
| 165 } | |
| 166 bool canClip = !(flags & kNoClip_Flag); | |
| 167 bool canTranslate = !(flags & kNoTranslate_Flag); | |
| 168 bool canCull = !(flags & kNoCull_Flag); | |
| 169 bool canScale = !(flags & kNoScale_Flag); | |
| 170 | |
| 171 int i; | |
| 172 for (i = fRecs.count() - 1; i >= 0; --i) { | |
| 173 const Rec& rec = fRecs[i]; | |
| 174 switch (rec.fType) { | |
| 175 case kSave_Type: | |
| 176 // continue to the next rec | |
| 177 break; | |
| 178 case kClipRect_Type: | |
| 179 if (!canCull) { | |
| 180 goto STOP; | |
| 181 } | |
| 182 if (canClip) { | |
| 183 if (!bounds->intersect(rec.fData.fBounds)) { | |
| 184 bounds->setEmpty(); | |
| 185 return; | |
| 186 } | |
| 187 // continue to the next rec | |
| 188 } else { | |
| 189 if (rec.fData.fBounds.contains(*bounds)) { | |
|
f(malita)
2016/07/08 13:12:02
Nit: invert the check to avoid empty branch?
reed1
2016/07/08 13:32:32
Done.
| |
| 190 // continue to the next rec | |
| 191 } else { | |
| 192 goto STOP; | |
| 193 } | |
| 194 } | |
| 195 break; | |
| 196 case kTrans_Type: | |
| 197 if (canTranslate) { | |
| 198 bounds->offset(rec.fData.fTranslate.x(), rec.fData.fTranslat e.y()); | |
| 199 // continue to the next rec | |
| 200 } else { | |
| 201 goto STOP; | |
| 202 } | |
| 203 break; | |
| 204 case kScaleTrans_Type: | |
| 205 if (canScale) { | |
| 206 SkMatrix m; | |
| 207 rec.getConcat(&m); | |
| 208 m.mapRectScaleTranslate(bounds, *bounds); | |
| 209 } else { | |
| 210 goto STOP; | |
| 211 } | |
| 212 break; | |
| 213 } | |
| 214 } | |
| 215 STOP: | |
| 216 this->flush_le(i); | |
| 217 } | |
| 218 | |
| 219 void SkDeferredCanvas::flush_translate(SkScalar* x, SkScalar* y, const SkRect& b ounds, | |
| 220 const SkPaint* paint) { | |
| 221 SkRect tmp = bounds; | |
| 222 this->flush_check(&tmp, paint, kNoClip_Flag | kNoScale_Flag); | |
| 223 *x += tmp.x() - bounds.x(); | |
| 224 *y += tmp.y() - bounds.y(); | |
| 225 } | |
| 226 | |
| 227 void SkDeferredCanvas::flush_translate(SkScalar* x, SkScalar* y, const SkPaint& paint) { | |
| 228 SkRect tmp = SkRect::MakeXYWH(*x, *y, 1, 1); | |
| 229 this->flush_check(&tmp, &paint, kNoClip_Flag | kNoCull_Flag | kNoScale_Flag) ; | |
| 230 *x = tmp.x(); | |
| 231 *y = tmp.y(); | |
| 232 } | |
| 233 | |
| 234 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 235 | |
| 236 void SkDeferredCanvas::willSave() { | |
| 237 this->push_save(); | |
| 238 } | |
| 239 | |
| 240 SkCanvas::SaveLayerStrategy SkDeferredCanvas::getSaveLayerStrategy(const SaveLay erRec& rec) { | |
| 241 this->flush_all(); | |
| 242 fSaveCount += 1; | |
| 243 fCanvas->saveLayer(rec); | |
| 244 this->INHERITED::getSaveLayerStrategy(rec); | |
| 245 // No need for a layer. | |
| 246 return kNoLayer_SaveLayerStrategy; | |
| 247 } | |
| 248 | |
| 249 void SkDeferredCanvas::willRestore() { | |
| 250 SkDEBUGCODE(const int restoreCount = fSaveCount--;) | |
| 251 | |
| 252 for (int i = fRecs.count() - 1; i >= 0; --i) { | |
| 253 if (kSave_Type == fRecs[i].fType) { | |
| 254 SkASSERT(fRecs[i].fData.fSaveCount == restoreCount); | |
| 255 fRecs.setCount(i); // pop off everything here and later | |
| 256 return; | |
| 257 } | |
| 258 } | |
| 259 for (int i = 0; i < fRecs.count(); ++i) { | |
| 260 SkASSERT(kSave_Type != fRecs[i].fType); | |
| 261 } | |
| 262 fRecs.setCount(0); | |
| 263 fCanvas->restore(); | |
| 264 this->INHERITED::willRestore(); | |
| 265 } | |
| 266 | |
| 267 void SkDeferredCanvas::didConcat(const SkMatrix& matrix) { | |
| 268 if (matrix.isIdentity()) { | |
| 269 return; | |
| 270 } | |
| 271 if (!this->push_concat(matrix)) { | |
| 272 this->flush_all(); | |
| 273 fCanvas->concat(matrix); | |
| 274 this->INHERITED::didConcat(matrix); | |
| 275 } | |
| 276 } | |
| 277 | |
| 278 void SkDeferredCanvas::didSetMatrix(const SkMatrix& matrix) { | |
| 279 this->flush_all(); | |
| 280 fCanvas->setMatrix(matrix); | |
| 281 this->INHERITED::didSetMatrix(matrix); | |
| 282 } | |
| 283 | |
| 284 void SkDeferredCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeS tyle edgeStyle) { | |
| 285 if (SkRegion::kIntersect_Op == op) { | |
| 286 this->push_cliprect(rect); | |
| 287 } else { | |
| 288 this->flush_all(); | |
| 289 fCanvas->clipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle); | |
| 290 this->INHERITED::onClipRect(rect, op, edgeStyle); | |
| 291 } | |
| 292 } | |
| 293 | |
| 294 void SkDeferredCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEd geStyle edgeStyle) { | |
| 295 this->flush_all(); | |
| 296 fCanvas->clipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle); | |
| 297 this->INHERITED::onClipRRect(rrect, op, edgeStyle); | |
| 298 } | |
| 299 | |
| 300 void SkDeferredCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeS tyle edgeStyle) { | |
| 301 this->flush_all(); | |
| 302 fCanvas->clipPath(path, op, kSoft_ClipEdgeStyle == edgeStyle); | |
| 303 this->INHERITED::onClipPath(path, op, edgeStyle); | |
| 304 } | |
| 305 | |
| 306 void SkDeferredCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { | |
| 307 this->flush_all(); | |
| 308 fCanvas->clipRegion(deviceRgn, op); | |
| 309 this->INHERITED::onClipRegion(deviceRgn, op); | |
| 310 } | |
| 311 | |
| 312 void SkDeferredCanvas::onDrawPaint(const SkPaint& paint) { | |
| 313 // TODO: Can we turn this into drawRect? | |
| 314 this->flush_all(); | |
| 315 fCanvas->drawPaint(paint); | |
| 316 } | |
| 317 | |
| 318 void SkDeferredCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], | |
| 319 const SkPaint& paint) { | |
| 320 this->flush_all(); | |
| 321 fCanvas->drawPoints(mode, count, pts, paint); | |
| 322 } | |
| 323 | |
| 324 void SkDeferredCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { | |
| 325 SkRect modRect = rect; | |
| 326 this->flush_check(&modRect, &paint); | |
| 327 fCanvas->drawRect(modRect, paint); | |
| 328 } | |
| 329 | |
| 330 void SkDeferredCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { | |
| 331 SkRect modRect = rect; | |
| 332 this->flush_check(&modRect, &paint, kNoClip_Flag); | |
| 333 fCanvas->drawOval(modRect, paint); | |
| 334 } | |
| 335 | |
| 336 static SkRRect make_offset(const SkRRect& src, SkScalar dx, SkScalar dy) { | |
| 337 SkRRect dst = src; | |
| 338 dst.offset(dx, dy); | |
| 339 return dst; | |
| 340 } | |
| 341 | |
| 342 void SkDeferredCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { | |
| 343 SkRect modRect = rrect.getBounds(); | |
| 344 this->flush_check(&modRect, &paint, kNoClip_Flag); | |
| 345 fCanvas->drawRRect(make_offset(rrect, | |
| 346 modRect.x() - rrect.getBounds().x(), | |
| 347 modRect.y() - rrect.getBounds().y()), paint); | |
| 348 } | |
| 349 | |
| 350 void SkDeferredCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) { | |
| 351 this->flush_all(); | |
| 352 fCanvas->drawDRRect(outer, inner, paint); | |
| 353 } | |
| 354 | |
| 355 void SkDeferredCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { | |
| 356 if (path.isInverseFillType()) { | |
| 357 this->flush_before_saves(); | |
| 358 } else { | |
| 359 SkRect modRect = path.getBounds(); | |
| 360 this->flush_check(&modRect, &paint, kNoClip_Flag | kNoTranslate_Flag | k NoScale_Flag); | |
| 361 } | |
| 362 fCanvas->drawPath(path, paint); | |
| 363 } | |
| 364 | |
| 365 void SkDeferredCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, | |
| 366 const SkPaint* paint) { | |
| 367 const SkScalar w = SkIntToScalar(bitmap.width()); | |
| 368 const SkScalar h = SkIntToScalar(bitmap.height()); | |
| 369 SkRect bounds = SkRect::MakeXYWH(x, y, w, h); | |
| 370 this->flush_check(&bounds, paint, kNoClip_Flag); | |
| 371 if (bounds.width() == w && bounds.height() == h) { | |
| 372 fCanvas->drawBitmap(bitmap, bounds.x(), bounds.y(), paint); | |
| 373 } else { | |
| 374 fCanvas->drawBitmapRect(bitmap, bounds, paint); | |
| 375 } | |
| 376 } | |
| 377 | |
| 378 void SkDeferredCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* sr c, const SkRect& dst, | |
| 379 const SkPaint* paint, SrcRectConstraint cons traint) { | |
| 380 SkRect modRect = dst; | |
| 381 this->flush_check(&modRect, paint, kNoClip_Flag); | |
| 382 fCanvas->legacy_drawBitmapRect(bitmap, src, modRect, paint, constraint); | |
| 383 } | |
| 384 | |
| 385 void SkDeferredCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& c enter, | |
| 386 const SkRect& dst, const SkPaint* paint) { | |
| 387 SkRect modRect = dst; | |
| 388 this->flush_check(&modRect, paint, kNoClip_Flag); | |
| 389 fCanvas->drawBitmapNine(bitmap, center, modRect, paint); | |
| 390 } | |
| 391 | |
| 392 void SkDeferredCanvas::onDrawImageNine(const SkImage* image, const SkIRect& cent er, | |
| 393 const SkRect& dst, const SkPaint* paint) { | |
| 394 SkRect modRect = dst; | |
| 395 this->flush_check(&modRect, paint, kNoClip_Flag); | |
| 396 fCanvas->drawImageNine(image, center, modRect, paint); | |
| 397 } | |
| 398 | |
| 399 void SkDeferredCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, | |
| 400 const SkPaint* paint) { | |
| 401 const SkScalar w = SkIntToScalar(image->width()); | |
| 402 const SkScalar h = SkIntToScalar(image->height()); | |
| 403 SkRect bounds = SkRect::MakeXYWH(x, y, w, h); | |
| 404 this->flush_check(&bounds, paint, kNoClip_Flag); | |
| 405 if (bounds.width() == w && bounds.height() == h) { | |
| 406 fCanvas->drawImage(image, bounds.x(), bounds.y(), paint); | |
| 407 } else { | |
| 408 fCanvas->drawImageRect(image, bounds, paint); | |
| 409 } | |
| 410 } | |
| 411 | |
| 412 void SkDeferredCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, | |
| 413 const SkPaint* paint, SrcRectConstraint const raint) { | |
| 414 SkRect modRect = dst; | |
| 415 this->flush_check(&modRect, paint, kNoClip_Flag); | |
| 416 fCanvas->legacy_drawImageRect(image, src, modRect, paint, constraint); | |
| 417 } | |
| 418 | |
| 419 void SkDeferredCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, | |
| 420 const SkPaint& paint) { | |
| 421 this->flush_translate(&x, &y, paint); | |
| 422 fCanvas->drawText(text, byteLength, x, y, paint); | |
| 423 } | |
| 424 | |
| 425 void SkDeferredCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], | |
| 426 const SkPaint& paint) { | |
| 427 this->flush_before_saves(); | |
| 428 fCanvas->drawPosText(text, byteLength, pos, paint); | |
| 429 } | |
| 430 | |
| 431 void SkDeferredCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], | |
| 432 SkScalar constY, const SkPaint& paint) { | |
| 433 this->flush_before_saves(); | |
| 434 fCanvas->drawPosTextH(text, byteLength, xpos, constY, paint); | |
| 435 } | |
| 436 | |
| 437 void SkDeferredCanvas::onDrawTextOnPath(const void* text, size_t byteLength, con st SkPath& path, | |
| 438 const SkMatrix* matrix, const SkPaint& paint ) { | |
| 439 this->flush_before_saves(); | |
| 440 fCanvas->drawTextOnPath(text, byteLength, path, matrix, paint); | |
| 441 } | |
| 442 | |
| 443 void SkDeferredCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScal ar y, | |
| 444 const SkPaint &paint) { | |
| 445 this->flush_translate(&x, &y, blob->bounds(), &paint); | |
| 446 fCanvas->drawTextBlob(blob, x, y, paint); | |
| 447 } | |
| 448 | |
| 449 #include "SkPicture.h" | |
| 450 #include "SkCanvasPriv.h" | |
| 451 void SkDeferredCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* m atrix, | |
| 452 const SkPaint* paint) { | |
| 453 #if 1 | |
| 454 SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); | |
| 455 picture->playback(this); | |
| 456 #else | |
| 457 this->flush_before_saves(); | |
| 458 fCanvas->drawPicture(picture, matrix, paint); | |
| 459 #endif | |
| 460 } | |
| 461 | |
| 462 void SkDeferredCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matr ix) { | |
| 463 // TODO: investigate culling and applying concat to the matrix | |
| 464 #if 1 | |
| 465 drawable->draw(this, matrix); | |
| 466 #else | |
| 467 this->flush_before_saves(); | |
| 468 fCanvas->drawDrawable(drawable, matrix); | |
| 469 #endif | |
| 470 } | |
| 471 | |
| 472 void SkDeferredCanvas::onDrawAtlas(const SkImage* image, const SkRSXform xform[] , | |
| 473 const SkRect rects[], const SkColor colors[], | |
| 474 int count, SkXfermode::Mode mode, | |
| 475 const SkRect* cull, const SkPaint* paint) { | |
| 476 this->flush_before_saves(); | |
| 477 fCanvas->drawAtlas(image, xform, rects, colors, count, mode, cull, paint); | |
| 478 } | |
| 479 | |
| 480 void SkDeferredCanvas::onDrawVertices(VertexMode vmode, int vertexCount, | |
| 481 const SkPoint vertices[], const SkPoint texs[] , | |
| 482 const SkColor colors[], SkXfermode* xmode, | |
| 483 const uint16_t indices[], int indexCount, | |
| 484 const SkPaint& paint) { | |
| 485 this->flush_before_saves(); | |
| 486 fCanvas->drawVertices(vmode, vertexCount, vertices, texs, colors, xmode, | |
| 487 indices, indexCount, paint); | |
| 488 } | |
| 489 | |
| 490 void SkDeferredCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor color s[4], | |
| 491 const SkPoint texCoords[4], SkXfermode* xmode, | |
| 492 const SkPaint& paint) { | |
| 493 this->flush_before_saves(); | |
| 494 fCanvas->drawPatch(cubics, colors, texCoords, xmode, paint); | |
| 495 } | |
| 496 | |
| 497 void SkDeferredCanvas::onDrawAnnotation(const SkRect& rect, const char key[], Sk Data* data) { | |
| 498 this->flush_all(); | |
| 499 fCanvas->drawAnnotation(rect, key, data); | |
| 500 } | |
| 501 | |
| 502 #ifdef SK_SUPPORT_LEGACY_DRAWFILTER | |
| 503 SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) { | |
| 504 fCanvas->setDrawFilter(filter); | |
| 505 return this->INHERITED::setDrawFilter(filter); | |
| 506 } | |
| 507 #endif | |
| 508 | |
| 509 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 510 | |
| 511 sk_sp<SkSurface> SkDeferredCanvas::onNewSurface(const SkImageInfo& info, | |
| 512 const SkSurfaceProps& props) { | |
| 513 return fCanvas->makeSurface(info, &props); | |
| 514 } | |
| 515 SkISize SkDeferredCanvas::getBaseLayerSize() const { return fCanvas->getBaseLaye rSize(); } | |
| 516 bool SkDeferredCanvas::getClipBounds(SkRect* bounds) const { | |
| 517 return fCanvas->getClipBounds(bounds); | |
| 518 } | |
| 519 bool SkDeferredCanvas::getClipDeviceBounds(SkIRect* bounds) const { | |
| 520 return fCanvas->getClipDeviceBounds(bounds); | |
| 521 } | |
| 522 bool SkDeferredCanvas::isClipEmpty() const { return fCanvas->isClipEmpty(); } | |
| 523 bool SkDeferredCanvas::isClipRect() const { return fCanvas->isClipRect(); } | |
| 524 bool SkDeferredCanvas::onPeekPixels(SkPixmap* pixmap) { return fCanvas->peekPixe ls(pixmap); } | |
| 525 bool SkDeferredCanvas::onAccessTopLayerPixels(SkPixmap* pixmap) { | |
| 526 SkImageInfo info; | |
| 527 size_t rowBytes; | |
| 528 SkIPoint* origin = nullptr; | |
| 529 void* addr = fCanvas->accessTopLayerPixels(&info, &rowBytes, origin); | |
| 530 if (addr) { | |
| 531 *pixmap = SkPixmap(info, addr, rowBytes); | |
| 532 return true; | |
| 533 } | |
| 534 return false; | |
| 535 } | |
| 536 SkImageInfo SkDeferredCanvas::onImageInfo() const { return fCanvas->imageInfo(); } | |
| 537 bool SkDeferredCanvas::onGetProps(SkSurfaceProps* props) const { return fCanvas- >getProps(props); } | |
| 538 void SkDeferredCanvas::onFlush() { return fCanvas->flush(); } | |
|
f(malita)
2016/07/08 13:12:02
Should this also flush all deferred ops?
reed1
2016/07/08 13:32:32
Good catch (tho calling flush when you're unbalanc
| |
| OLD | NEW |