Remove SkRecorder's kWriteOnly mode.
I'm soon going to have SkRecorder start calling getTotalMatrix(), which would be broken in write-only mode. That change is big and nebulous, but it's clear kWriteOnly needs to go, so we might as well kill it now. My notes in bench_playback about kWriteOnly mode being important were probably overly cautious. I now think this is a fair enough comparison even re-recording into a read-write canvas. BUG=skia:2378 R=fmalita@chromium.org, mtklein@google.com Author: mtklein@chromium.org Review URL: https://codereview.chromium.org/290653004 git-svn-id: http://skia.googlecode.com/svn/trunk@14963 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
cac02e52cd
commit
a095041f51
@ -30,8 +30,7 @@ RecordTask::RecordTask(const Task& parent, SkPicture* pic, SkBitmap reference, M
|
||||
void RecordTask::draw() {
|
||||
// Record into an SkRecord.
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record,
|
||||
fReference.width(), fReference.height());
|
||||
SkRecorder recorder(&record, fReference.width(), fReference.height());
|
||||
|
||||
if (fGM.get()) {
|
||||
recorder.concat(fGM->getInitialTransform());
|
||||
|
@ -9,8 +9,8 @@
|
||||
#include "SkPicture.h"
|
||||
|
||||
// SkCanvas will fail in mysterious ways if it doesn't know the real width and height.
|
||||
SkRecorder::SkRecorder(SkRecorder::Mode mode, SkRecord* record, int width, int height)
|
||||
: SkCanvas(width, height), fMode(mode), fRecord(record) {}
|
||||
SkRecorder::SkRecorder(SkRecord* record, int width, int height)
|
||||
: SkCanvas(width, height), fRecord(record) {}
|
||||
|
||||
void SkRecorder::forgetRecord() {
|
||||
fRecord = NULL;
|
||||
@ -20,8 +20,8 @@ void SkRecorder::forgetRecord() {
|
||||
#define APPEND(T, ...) \
|
||||
SkNEW_PLACEMENT_ARGS(fRecord->append<SkRecords::T>(), SkRecords::T, (__VA_ARGS__))
|
||||
|
||||
// For methods which must call back into SkCanvas in kReadWrite_Mode.
|
||||
#define INHERITED(method, ...) if (fMode == kReadWrite_Mode) this->SkCanvas::method(__VA_ARGS__)
|
||||
// For methods which must call back into SkCanvas.
|
||||
#define INHERITED(method, ...) this->SkCanvas::method(__VA_ARGS__)
|
||||
|
||||
// The structs we're creating all copy their constructor arguments. Given the way the SkRecords
|
||||
// framework works, sometimes they happen to technically be copied twice, which is fine and elided
|
||||
|
@ -16,17 +16,8 @@
|
||||
|
||||
class SkRecorder : public SkCanvas {
|
||||
public:
|
||||
// SkRecorder can work in two modes:
|
||||
// write-only: only a core subset of SkCanvas operations (save/restore, clip, transform, draw)
|
||||
// are supported, and all of the readback methods on SkCanvas will probably fail or lie.
|
||||
//
|
||||
// read-write: all methods should behave with similar semantics to SkCanvas.
|
||||
//
|
||||
// Write-only averages 10-20% faster, but you can't sensibly inspect the canvas while recording.
|
||||
enum Mode { kWriteOnly_Mode, kReadWrite_Mode };
|
||||
|
||||
// Does not take ownership of the SkRecord.
|
||||
SkRecorder(Mode mode, SkRecord*, int width, int height);
|
||||
SkRecorder(SkRecord*, int width, int height);
|
||||
|
||||
// Make SkRecorder forget entirely about its SkRecord*; all calls to SkRecorder will fail.
|
||||
void forgetRecord();
|
||||
@ -114,7 +105,6 @@ private:
|
||||
template <typename T>
|
||||
T* copy(const T[], unsigned count);
|
||||
|
||||
const Mode fMode;
|
||||
SkRecord* fRecord;
|
||||
};
|
||||
|
||||
|
@ -25,7 +25,7 @@ void SkPlayback::draw(SkCanvas* canvas) const {
|
||||
|
||||
SkRecording::SkRecording(int width, int height)
|
||||
: fRecord(SkNEW(SkRecord))
|
||||
, fRecorder(SkNEW_ARGS(SkRecorder, (SkRecorder::kReadWrite_Mode, fRecord.get(), width, height)))
|
||||
, fRecorder(SkNEW_ARGS(SkRecorder, (fRecord.get(), width, height)))
|
||||
{}
|
||||
|
||||
SkPlayback* SkRecording::releasePlayback() {
|
||||
|
@ -29,14 +29,14 @@ static void draw_pos_text_h(SkCanvas* canvas, const char* text, SkScalar y) {
|
||||
// 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(SkRecorder::kReadWrite_Mode, clipped, W, H);
|
||||
SkRecorder recorder(clipped, W, H);
|
||||
recorder.clipRect(clip);
|
||||
SkRecordDraw(record, &recorder);
|
||||
}
|
||||
|
||||
DEF_TEST(RecordDraw_PosTextHQuickReject, r) {
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
|
||||
SkRecorder recorder(&record, W, H);
|
||||
|
||||
draw_pos_text_h(&recorder, "This will draw.", 20);
|
||||
draw_pos_text_h(&recorder, "This won't.", 5000);
|
||||
@ -53,7 +53,7 @@ DEF_TEST(RecordDraw_PosTextHQuickReject, r) {
|
||||
DEF_TEST(RecordDraw_Culling, r) {
|
||||
// Record these 7 drawing commands verbatim.
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
|
||||
SkRecorder recorder(&record, W, H);
|
||||
|
||||
recorder.pushCull(SkRect::MakeWH(100, 100));
|
||||
recorder.drawRect(SkRect::MakeWH(10, 10), SkPaint());
|
||||
@ -78,14 +78,14 @@ DEF_TEST(RecordDraw_Culling, r) {
|
||||
DEF_TEST(RecordDraw_SetMatrixClobber, r) {
|
||||
// Set up an SkRecord that just scales by 2x,3x.
|
||||
SkRecord scaleRecord;
|
||||
SkRecorder scaleCanvas(SkRecorder::kReadWrite_Mode, &scaleRecord, W, H);
|
||||
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(SkRecorder::kReadWrite_Mode, &translateRecord, W, H);
|
||||
SkRecorder translateCanvas(&translateRecord, W, H);
|
||||
SkMatrix translate;
|
||||
translate.setTranslate(20, 20);
|
||||
translateCanvas.setMatrix(translate);
|
||||
|
@ -18,7 +18,7 @@ static const int W = 1920, H = 1080;
|
||||
|
||||
DEF_TEST(RecordOpts_Culling, r) {
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
|
||||
SkRecorder recorder(&record, W, H);
|
||||
|
||||
recorder.drawRect(SkRect::MakeWH(1000, 10000), SkPaint());
|
||||
|
||||
@ -38,7 +38,7 @@ DEF_TEST(RecordOpts_Culling, r) {
|
||||
|
||||
DEF_TEST(RecordOpts_NoopCulls, r) {
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
|
||||
SkRecorder recorder(&record, W, H);
|
||||
|
||||
// All should be nooped.
|
||||
recorder.pushCull(SkRect::MakeWH(200, 200));
|
||||
@ -77,7 +77,7 @@ static void draw_pos_text(SkCanvas* canvas, const char* text, bool constantY) {
|
||||
|
||||
DEF_TEST(RecordOpts_StrengthReduction, r) {
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
|
||||
SkRecorder recorder(&record, W, H);
|
||||
|
||||
// We can convert a drawPosText into a drawPosTextH when all the Ys are the same.
|
||||
draw_pos_text(&recorder, "This will be reduced to drawPosTextH.", true);
|
||||
@ -91,7 +91,7 @@ DEF_TEST(RecordOpts_StrengthReduction, r) {
|
||||
|
||||
DEF_TEST(RecordOpts_TextBounding, r) {
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
|
||||
SkRecorder recorder(&record, W, H);
|
||||
|
||||
// First, get a drawPosTextH. Here's a handy way. Its text size will be the default (12).
|
||||
draw_pos_text(&recorder, "This will be reduced to drawPosTextH.", true);
|
||||
@ -114,7 +114,7 @@ DEF_TEST(RecordOpts_TextBounding, r) {
|
||||
|
||||
DEF_TEST(RecordOpts_NoopDrawSaveRestore, r) {
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
|
||||
SkRecorder recorder(&record, W, H);
|
||||
|
||||
// The save and restore are pointless if there's only draw commands in the middle.
|
||||
recorder.save();
|
||||
@ -136,7 +136,7 @@ DEF_TEST(RecordOpts_NoopDrawSaveRestore, r) {
|
||||
|
||||
DEF_TEST(RecordOpts_SingleNoopSaveRestore, r) {
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
|
||||
SkRecorder recorder(&record, W, H);
|
||||
|
||||
recorder.save();
|
||||
recorder.clipRect(SkRect::MakeWH(200, 200));
|
||||
@ -150,7 +150,7 @@ DEF_TEST(RecordOpts_SingleNoopSaveRestore, r) {
|
||||
|
||||
DEF_TEST(RecordOpts_NoopSaveRestores, r) {
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
|
||||
SkRecorder recorder(&record, W, H);
|
||||
|
||||
// The second pass will clean up this pair after the first pass noops all the innards.
|
||||
recorder.save();
|
||||
@ -187,7 +187,7 @@ static void assert_savelayer_restore(skiatest::Reporter* r,
|
||||
|
||||
DEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) {
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, W, H);
|
||||
SkRecorder recorder(&record, W, H);
|
||||
|
||||
SkRect bounds = SkRect::MakeWH(100, 200);
|
||||
SkRect draw = SkRect::MakeWH(50, 60);
|
||||
|
@ -17,7 +17,7 @@ DEF_TEST(RecordPattern_Simple, r) {
|
||||
SkRecord record;
|
||||
REPORTER_ASSERT(r, !pattern.match(&record, 0));
|
||||
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, 1920, 1200);
|
||||
SkRecorder recorder(&record, 1920, 1200);
|
||||
|
||||
// Build up a save-clip-restore block. The pattern will match only it's complete.
|
||||
recorder.save();
|
||||
@ -37,7 +37,7 @@ DEF_TEST(RecordPattern_StartingIndex, r) {
|
||||
SaveClipRectRestore pattern;
|
||||
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, 1920, 1200);
|
||||
SkRecorder recorder(&record, 1920, 1200);
|
||||
|
||||
// There will be two save-clipRect-restore blocks [0,3) and [3,6).
|
||||
for (int i = 0; i < 2; i++) {
|
||||
@ -60,7 +60,7 @@ DEF_TEST(RecordPattern_DontMatchSubsequences, r) {
|
||||
SaveClipRectRestore pattern;
|
||||
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, 1920, 1200);
|
||||
SkRecorder recorder(&record, 1920, 1200);
|
||||
|
||||
recorder.save();
|
||||
recorder.clipRect(SkRect::MakeWH(300, 200));
|
||||
@ -74,7 +74,7 @@ DEF_TEST(RecordPattern_Star, r) {
|
||||
Pattern3<Is<Save>, Star<Is<ClipRect> >, Is<Restore> > pattern;
|
||||
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, 1920, 1200);
|
||||
SkRecorder recorder(&record, 1920, 1200);
|
||||
|
||||
recorder.save();
|
||||
recorder.restore();
|
||||
@ -96,7 +96,7 @@ DEF_TEST(RecordPattern_IsDraw, r) {
|
||||
Pattern3<Is<Save>, IsDraw, Is<Restore> > pattern;
|
||||
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, 1920, 1200);
|
||||
SkRecorder recorder(&record, 1920, 1200);
|
||||
|
||||
recorder.save();
|
||||
recorder.clipRect(SkRect::MakeWH(300, 200));
|
||||
@ -135,7 +135,7 @@ DEF_TEST(RecordPattern_Complex, r) {
|
||||
Is<Restore> > pattern;
|
||||
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, 1920, 1200);
|
||||
SkRecorder recorder(&record, 1920, 1200);
|
||||
|
||||
recorder.save();
|
||||
recorder.restore();
|
||||
@ -192,7 +192,7 @@ DEF_TEST(RecordPattern_SaveLayerIsNotADraw, r) {
|
||||
Pattern1<IsDraw> pattern;
|
||||
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, 1920, 1200);
|
||||
SkRecorder recorder(&record, 1920, 1200);
|
||||
recorder.saveLayer(NULL, NULL);
|
||||
|
||||
REPORTER_ASSERT(r, !pattern.match(&record, 0));
|
||||
|
@ -40,7 +40,7 @@ private:
|
||||
|
||||
DEF_TEST(Recorder, r) {
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, 1920, 1080);
|
||||
SkRecorder recorder(&record, 1920, 1080);
|
||||
|
||||
recorder.drawRect(SkRect::MakeWH(10, 10), SkPaint());
|
||||
|
||||
@ -62,7 +62,7 @@ DEF_TEST(Recorder_RefLeaking, r) {
|
||||
REPORTER_ASSERT(r, paint.getShader()->unique());
|
||||
{
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, 1920, 1080);
|
||||
SkRecorder recorder(&record, 1920, 1080);
|
||||
recorder.saveLayer(&bounds, &paint);
|
||||
REPORTER_ASSERT(r, !paint.getShader()->unique());
|
||||
}
|
||||
|
@ -12,9 +12,7 @@
|
||||
#include "SkOSFile.h"
|
||||
#include "SkPicture.h"
|
||||
#include "SkPictureRecorder.h"
|
||||
#include "SkRecordDraw.h"
|
||||
#include "SkRecordOpts.h"
|
||||
#include "SkRecorder.h"
|
||||
#include "SkRecording.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkString.h"
|
||||
|
||||
@ -33,14 +31,28 @@ static double scale_time(double ms) {
|
||||
return ms;
|
||||
}
|
||||
|
||||
static void bench(SkPMColor* scratch, SkPicture& src, const char* name) {
|
||||
// We don't use the public SkRecording interface here because we need kWriteOnly_Mode.
|
||||
// (We don't want SkPicturePlayback to be able to optimize playing into our SkRecord.)
|
||||
SkRecord record;
|
||||
SkRecorder recorder(SkRecorder::kWriteOnly_Mode, &record, src.width(), src.height());
|
||||
src.draw(&recorder);
|
||||
static SkPicture* rerecord_with_tilegrid(SkPicture& src) {
|
||||
SkTileGridFactory::TileGridInfo info;
|
||||
info.fTileInterval.set(FLAGS_tile, FLAGS_tile);
|
||||
info.fMargin.setEmpty();
|
||||
info.fOffset.setZero();
|
||||
SkTileGridFactory factory(info);
|
||||
|
||||
SkRecordOptimize(&record);
|
||||
SkPictureRecorder recorder;
|
||||
src.draw(recorder.beginRecording(src.width(), src.height(), &factory,
|
||||
SkPicture::kUsePathBoundsForClip_RecordingFlag));
|
||||
return recorder.endRecording();
|
||||
}
|
||||
|
||||
static EXPERIMENTAL::SkPlayback* rerecord_with_skr(SkPicture& src) {
|
||||
EXPERIMENTAL::SkRecording recording(src.width(), src.height());
|
||||
src.draw(recording.canvas());
|
||||
return recording.releasePlayback();
|
||||
}
|
||||
|
||||
static void bench(SkPMColor* scratch, SkPicture& src, const char* name) {
|
||||
SkAutoTUnref<SkPicture> picture(rerecord_with_tilegrid(src));
|
||||
SkAutoTDelete<EXPERIMENTAL::SkPlayback> record(rerecord_with_skr(src));
|
||||
|
||||
SkAutoTDelete<SkCanvas> canvas(SkCanvas::NewRasterDirectN32(src.width(),
|
||||
src.height(),
|
||||
@ -52,9 +64,9 @@ static void bench(SkPMColor* scratch, SkPicture& src, const char* name) {
|
||||
timer.start();
|
||||
for (int i = 0; i < FLAGS_loops; i++) {
|
||||
if (FLAGS_skr) {
|
||||
SkRecordDraw(record, canvas.get());
|
||||
record->draw(canvas.get());
|
||||
} else {
|
||||
src.draw(canvas.get());
|
||||
picture->draw(canvas.get());
|
||||
}
|
||||
}
|
||||
timer.end();
|
||||
@ -102,21 +114,7 @@ int tool_main(int argc, char** argv) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Rerecord into a picture using a tile grid.
|
||||
SkTileGridFactory::TileGridInfo info;
|
||||
info.fTileInterval.set(FLAGS_tile, FLAGS_tile);
|
||||
info.fMargin.setEmpty();
|
||||
info.fOffset.setZero();
|
||||
SkTileGridFactory factory(info);
|
||||
|
||||
SkPictureRecorder recorder;
|
||||
SkCanvas* canvas = recorder.beginRecording(src->width(), src->height(),
|
||||
&factory,
|
||||
SkPicture::kUsePathBoundsForClip_RecordingFlag);
|
||||
src->draw(canvas);
|
||||
SkAutoTUnref<SkPicture> replay(recorder.endRecording());
|
||||
|
||||
bench(scratch.get(), *replay, filename.c_str());
|
||||
bench(scratch.get(), *src, filename.c_str());
|
||||
}
|
||||
return failed ? 1 : 0;
|
||||
}
|
||||
|
@ -60,10 +60,9 @@ int tool_main(int argc, char** argv) {
|
||||
const int w = src->width(), h = src->height();
|
||||
|
||||
SkRecord record;
|
||||
SkRecorder canvas(SkRecorder::kWriteOnly_Mode, &record, w, h);
|
||||
SkRecorder canvas(&record, w, h);
|
||||
src->draw(&canvas);
|
||||
|
||||
|
||||
if (FLAGS_optimize) {
|
||||
SkRecordOptimize(&record);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user