| /* |
| * 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; |
| }; |
| |
| // 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); |