DEF_TEST(RecordDraw_drawImage, r){ class SkCanvasMock : public SkCanvas { public: SkCanvasMock(int width, int height) : SkCanvas(width, height) { this->resetTestValues(); } void onDrawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint) override { fDrawImageCalled = true; } void onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint) override { fDrawImageRectCalled = true; } void resetTestValues() { fDrawImageCalled = fDrawImageRectCalled = false; } bool fDrawImageCalled; bool fDrawImageRectCalled; }; auto surface(SkSurface::MakeRasterN32Premul(10, 10)); surface->getCanvas()->clear(SK_ColorGREEN); sk_sp<SkImage> image(surface->makeImageSnapshot()); SkCanvasMock canvas(10, 10); { SkRecord record; SkRecorder recorder(&record, 10, 10); recorder.drawImage(image, 0, 0); SkRecordDraw(record, &canvas, nullptr, nullptr, 0, nullptr, 0); } REPORTER_ASSERT(r, canvas.fDrawImageCalled); canvas.resetTestValues(); { SkRecord record; SkRecorder recorder(&record, 10, 10); recorder.drawImageRect(image, SkRect::MakeWH(10, 10), nullptr); SkRecordDraw(record, &canvas, nullptr, nullptr, 0, nullptr, 0); } REPORTER_ASSERT(r, canvas.fDrawImageRectCalled); }
void SkRecordedDrawable::flatten(SkWriteBuffer& buffer) const { // Write the bounds. buffer.writeRect(fBounds); // Create an SkPictureRecord to record the draw commands. SkPictInfo info; SkPictureRecord pictureRecord(SkISize::Make(fBounds.width(), fBounds.height()), 0); // If the query contains the whole picture, don't bother with the bounding box hierarchy. SkRect clipBounds; pictureRecord.getClipBounds(&clipBounds); SkBBoxHierarchy* bbh; if (clipBounds.contains(fBounds)) { bbh = nullptr; } else { bbh = fBBH.get(); } // Record the draw commands. pictureRecord.beginRecording(); SkRecordDraw(*fRecord, &pictureRecord, nullptr, fDrawableList->begin(), fDrawableList->count(), bbh, nullptr); pictureRecord.endRecording(); // Flatten the recorded commands and drawables. SkPictureData pictureData(pictureRecord, info); pictureData.flatten(buffer); }
DEF_TEST(RecordDraw_SetMatrixClobber, r) { // Set up an SkRecord that just scales by 2x,3x. SkRecord scaleRecord; SkRecorder scaleCanvas(&scaleRecord, W, H); SkMatrix scale; scale.setScale(2, 3); scaleCanvas.setMatrix(scale); // Set up an SkRecord with an initial +20, +20 translate. SkRecord translateRecord; SkRecorder translateCanvas(&translateRecord, W, H); SkMatrix translate; translate.setTranslate(20, 20); translateCanvas.setMatrix(translate); SkRecordDraw(scaleRecord, &translateCanvas, nullptr, nullptr, 0, nullptr/*bbh*/, nullptr/*callback*/); REPORTER_ASSERT(r, 4 == translateRecord.count()); assert_type<SkRecords::SetMatrix>(r, translateRecord, 0); assert_type<SkRecords::Save> (r, translateRecord, 1); assert_type<SkRecords::SetMatrix>(r, translateRecord, 2); assert_type<SkRecords::Restore> (r, translateRecord, 3); // When we look at translateRecord now, it should have its first +20,+20 translate, // then a 2x,3x scale that's been concatted with that +20,+20 translate. const SkRecords::SetMatrix* setMatrix; setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 0); REPORTER_ASSERT(r, setMatrix->matrix == translate); setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 2); SkMatrix expected = scale; expected.postConcat(translate); REPORTER_ASSERT(r, setMatrix->matrix == expected); }
void SkRecordedDrawable::onDraw(SkCanvas* canvas) { SkDrawable* const* drawables = nullptr; int drawableCount = 0; if (fDrawableList) { drawables = fDrawableList->begin(); drawableCount = fDrawableList->count(); } SkRecordDraw(*fRecord, canvas, nullptr, drawables, drawableCount, fBBH, nullptr/*callback*/); }
void onDraw(SkCanvas* canvas) override { SkDrawable* const* drawables = NULL; int drawableCount = 0; if (fDrawableList) { drawables = fDrawableList->begin(); drawableCount = fDrawableList->count(); } SkRecordDraw(*fRecord, canvas, NULL, drawables, drawableCount, fBBH, NULL/*callback*/); }
int tool_main(int argc, char** argv) { SkCommandLineFlags::Parse(argc, argv); for (int i = 0; i < FLAGS_skps.count(); i++) { if (SkCommandLineFlags::ShouldSkip(FLAGS_match, FLAGS_skps[i])) { continue; } SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(FLAGS_skps[i])); if (!stream) { SkDebugf("Could not read %s.\n", FLAGS_skps[i]); return 1; } sk_sp<SkPicture> src(SkPicture::MakeFromStream(stream)); if (!src) { SkDebugf("Could not read %s as an SkPicture.\n", FLAGS_skps[i]); return 1; } if (FLAGS_defer) { SkPictureRecorder recorder; SkDeferredCanvas deferred(recorder.beginRecording(src->cullRect())); src->playback(&deferred); src = recorder.finishRecordingAsPicture(); } const int w = SkScalarCeilToInt(src->cullRect().width()); const int h = SkScalarCeilToInt(src->cullRect().height()); SkRecord record; SkRecorder canvas(&record, w, h); src->playback(&canvas); if (FLAGS_optimize) { SkRecordOptimize(&record); } if (FLAGS_optimize2) { SkRecordOptimize2(&record); } dump(FLAGS_skps[i], w, h, record); if (FLAGS_write.count() > 0) { SkPictureRecorder r; SkRecordDraw(record, r.beginRecording(SkRect::MakeIWH(w, h)), nullptr, nullptr, 0, nullptr, nullptr); sk_sp<SkPicture> dst(r.finishRecordingAsPicture()); SkFILEWStream ostream(FLAGS_write[0]); dst->serialize(&ostream); } } return 0; }
void SkPictureRecorder::partialReplay(SkCanvas* canvas) const { if (NULL == canvas) { return; } int drawableCount = 0; SkDrawable* const* drawables = NULL; SkDrawableList* drawableList = fRecorder->getDrawableList(); if (drawableList) { drawableCount = drawableList->count(); drawables = drawableList->begin(); } SkRecordDraw(*fRecord, canvas, NULL, drawables, drawableCount, NULL/*bbh*/, NULL/*callback*/); }
DEF_TEST(RecordDraw_Unbalanced, r) { SkRecord record; SkRecorder recorder(&record, W, H); recorder.save(); // We won't balance this, but SkRecordDraw will for us. recorder.scale(2, 2); SkRecord rerecord; SkRecorder canvas(&rerecord, W, H); SkRecordDraw(record, &canvas, nullptr, nullptr, 0, nullptr/*bbh*/, nullptr/*callback*/); int save_count = count_instances_of_type<SkRecords::Save>(rerecord); int restore_count = count_instances_of_type<SkRecords::Save>(rerecord); REPORTER_ASSERT(r, save_count == restore_count); }
void SkPictureRecorder::partialReplay(SkCanvas* canvas) const { if (NULL == canvas) { return; } if (NULL != fRecorder) { SkRecordDraw(*fRecord, canvas); } if (NULL != fPictureRecord) { const bool deepCopyOps = true; SkPicture picture(fWidth, fHeight, *fPictureRecord, deepCopyOps); picture.draw(canvas); } }
void SkPictureRecorder::partialReplay(SkCanvas* canvas) const { if (NULL == canvas) { return; } if (fRecord.get()) { SkRecordDraw(*fRecord, canvas, NULL/*bbh*/, NULL/*callback*/); } if (fPictureRecord.get()) { const bool deepCopyOps = true; SkPicture picture(fCullWidth, fCullHeight, *fPictureRecord.get(), deepCopyOps); picture.playback(canvas); } }
void SkBigPicture::playback(SkCanvas* canvas, AbortCallback* callback) const { SkASSERT(canvas); // If the query contains the whole picture, don't bother with the BBH. SkRect clipBounds = { 0, 0, 0, 0 }; (void)canvas->getClipBounds(&clipBounds); const bool useBBH = !clipBounds.contains(this->cullRect()); SkRecordDraw(*fRecord, canvas, this->drawablePicts(), nullptr, this->drawableCount(), useBBH ? fBBH.get() : nullptr, callback); }
DEF_TEST(RecordDraw_Abort, r) { // Record two commands. SkRecord record; SkRecorder recorder(&record, W, H); recorder.drawRect(SkRect::MakeWH(200, 300), SkPaint()); recorder.clipRect(SkRect::MakeWH(100, 200)); SkRecord rerecord; SkRecorder canvas(&rerecord, W, H); JustOneDraw callback; SkRecordDraw(record, &canvas, nullptr, nullptr, 0, nullptr/*bbh*/, &callback); REPORTER_ASSERT(r, 1 == count_instances_of_type<SkRecords::DrawRect>(rerecord)); REPORTER_ASSERT(r, 0 == count_instances_of_type<SkRecords::ClipRect>(rerecord)); }
void SkPlayback::draw(SkCanvas* canvas) const { SkASSERT(fRecord.get() != NULL); SkRecordDraw(*fRecord, canvas, NULL/*bbh*/, NULL/*callback*/); }
// Rerecord into another SkRecord using full SkCanvas semantics, // tracking clips and allowing SkRecordDraw's quickReject() calls to work. static void record_clipped(const SkRecord& record, SkRect clip, SkRecord* clipped) { SkRecorder recorder(clipped, W, H); recorder.clipRect(clip); SkRecordDraw(record, &recorder); }