15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2012 Google Inc.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * found in the LICENSE file.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Benchmark.h"
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "SkDeferredCanvas.h"
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "SkDevice.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "SkString.h"
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DeferredCanvasBench : public Benchmark {
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)public:
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeferredCanvasBench(const char name[])  {
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        fName.printf("deferred_canvas_%s", name);
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    enum {
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        CANVAS_WIDTH = 200,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CANVAS_HEIGHT = 200,
210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    };
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protected:
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual const char* onGetName() {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return fName.c_str();
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void onDraw(const int loops, SkCanvas* canvas) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0   // what specifically are we interested in timing here?
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkBaseDevice *device = canvas->getDevice()->createCompatibleDevice(
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            SkBitmap::kARGB_8888_Config, CANVAS_WIDTH, CANVAS_HEIGHT, false);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkAutoTUnref<SkDeferredCanvas> deferredCanvas(SkDeferredCanvas::Create(device));
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        device->unref();
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        initDeferredCanvas(deferredCanvas);
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        drawInDeferredCanvas(loops, deferredCanvas);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        finalizeDeferredCanvas(deferredCanvas);
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        deferredCanvas->flush();
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void initDeferredCanvas(SkDeferredCanvas* canvas) = 0;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void drawInDeferredCanvas(const int loops, SkDeferredCanvas* canvas) = 0;
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    virtual void finalizeDeferredCanvas(SkDeferredCanvas* canvas) = 0;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkString fName;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)private:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef Benchmark INHERITED;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SimpleNotificationClient : public SkDeferredCanvas::NotificationClient {
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdochpublic:
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SimpleNotificationClient() : fDummy(false) {}
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    //bogus virtual implementations that just do something small
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    virtual void prepareForDraw() SK_OVERRIDE {fDummy = true;}
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    virtual void storageAllocatedForRecordingChanged(size_t) SK_OVERRIDE {fDummy = false;}
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    virtual void flushedDrawCommands() SK_OVERRIDE {fDummy = !fDummy;}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool fDummy;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef SkDeferredCanvas::NotificationClient INHERITED;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that records very simple draw operations.
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This benchmark aims to capture performance fluctuations in the recording
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// overhead of SkDeferredCanvas
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DeferredRecordBench : public DeferredCanvasBench {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public:
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DeferredRecordBench()
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        : INHERITED("record") {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protected:
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    virtual void initDeferredCanvas(SkDeferredCanvas* canvas) SK_OVERRIDE {
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        canvas->setNotificationClient(&fNotificationClient);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void drawInDeferredCanvas(const int loops, SkDeferredCanvas* canvas) SK_OVERRIDE {
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        SkRect rect;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rect.setXYWH(0, 0, 10, 10);
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        SkPaint paint;
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        for (int i = 0; i < loops; i++) {
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            canvas->save();
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            canvas->translate(SkIntToScalar(i * 27 % CANVAS_WIDTH), SkIntToScalar(i * 13 % CANVAS_HEIGHT));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->drawRect(rect, paint);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            canvas->restore();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void finalizeDeferredCanvas(SkDeferredCanvas* canvas) SK_OVERRIDE {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        canvas->clear(0x0);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        canvas->setNotificationClient(NULL);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef DeferredCanvasBench INHERITED;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleNotificationClient fNotificationClient;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch///////////////////////////////////////////////////////////////////////////////
105ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
106ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochDEF_BENCH( return new DeferredRecordBench(); )
107ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch