/* * Copyright 2012 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkBenchmark.h" #include "SkDeferredCanvas.h" #include "SkDevice.h" #include "SkString.h" class DeferredCanvasBench : public SkBenchmark { public: DeferredCanvasBench(void* param, const char name[]) : INHERITED(param) { fName.printf("deferred_canvas_%s", name); } enum { N = SkBENCHLOOP(25), // number of times to create the picture CANVAS_WIDTH = 200, CANVAS_HEIGHT = 200, }; protected: virtual const char* onGetName() { return fName.c_str(); } virtual void onDraw(SkCanvas* canvas) { SkDevice *device = canvas->getDevice()->createCompatibleDevice( SkBitmap::kARGB_8888_Config, CANVAS_WIDTH, CANVAS_HEIGHT, false); SkDeferredCanvas deferredCanvas(device); device->unref(); initDeferredCanvas(deferredCanvas); for (int i = 0; i < N; i++) { drawInDeferredCanvas(deferredCanvas); } finalizeDeferredCanvas(deferredCanvas); deferredCanvas.flush(); } virtual void initDeferredCanvas(SkDeferredCanvas& canvas) = 0; virtual void drawInDeferredCanvas(SkDeferredCanvas& canvas) = 0; virtual void finalizeDeferredCanvas(SkDeferredCanvas& canvas) = 0; SkString fName; private: typedef SkBenchmark INHERITED; }; class SimpleNotificationClient : public SkDeferredCanvas::NotificationClient { public: SimpleNotificationClient() : fDummy(false) {} //bogus virtual implementations that just do something small virtual void prepareForDraw() SK_OVERRIDE {fDummy = true;} virtual void storageAllocatedForRecordingChanged(size_t) SK_OVERRIDE {fDummy = false;} virtual void flushedDrawCommands() SK_OVERRIDE {fDummy = !fDummy;} private: bool fDummy; typedef SkDeferredCanvas::NotificationClient INHERITED; }; // Test that records very simple draw operations. // This benchmark aims to capture performance fluctuations in the recording // overhead of SkDeferredCanvas class DeferredRecordBench : public DeferredCanvasBench { public: DeferredRecordBench(void* param) : INHERITED(param, "record") { } enum { M = SkBENCHLOOP(700), // number of individual draws in each loop }; protected: virtual void initDeferredCanvas(SkDeferredCanvas& canvas) SK_OVERRIDE { canvas.setNotificationClient(&fNotificationClient); } virtual void drawInDeferredCanvas(SkDeferredCanvas& canvas) SK_OVERRIDE { SkRect rect; rect.setXYWH(0, 0, 10, 10); SkPaint paint; for (int i = 0; i < M; i++) { canvas.save(SkCanvas::kMatrixClip_SaveFlag); canvas.translate(SkIntToScalar(i * 27 % CANVAS_WIDTH), SkIntToScalar(i * 13 % CANVAS_HEIGHT)); canvas.drawRect(rect, paint); canvas.restore(); } } virtual void finalizeDeferredCanvas(SkDeferredCanvas& canvas) SK_OVERRIDE { canvas.clear(0x0); canvas.setNotificationClient(NULL); } private: typedef DeferredCanvasBench INHERITED; SimpleNotificationClient fNotificationClient; }; /////////////////////////////////////////////////////////////////////////////// static SkBenchmark* Fact0(void* p) { return new DeferredRecordBench(p); } static BenchRegistry gReg0(Fact0);